Big progress for People dialog. Phenom work.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7573 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-09-28 20:46:56 +00:00
parent 28277c53df
commit 9efc43f41c
15 changed files with 3630 additions and 133 deletions

View File

@ -106,13 +106,30 @@ class RsGxsCircleDetails
uint32_t mCircleType;
bool mIsExternal;
bool operator ==(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId == rGxsDetails.mCircleId
&& mCircleName == rGxsDetails.mCircleName
&& mCircleType == rGxsDetails.mCircleType
&& mIsExternal == rGxsDetails.mIsExternal
&& mUnknownPeers == rGxsDetails.mUnknownPeers
&& mAllowedPeers == rGxsDetails.mAllowedPeers
);
}
bool operator !=(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId != rGxsDetails.mCircleId
|| mCircleName != rGxsDetails.mCircleName
|| mCircleType != rGxsDetails.mCircleType
|| mIsExternal != rGxsDetails.mIsExternal
|| mUnknownPeers != rGxsDetails.mUnknownPeers
|| mAllowedPeers != rGxsDetails.mAllowedPeers
);
}
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
};
class RsGxsCircles: public RsGxsIfaceHelper
{
public:

View File

@ -55,6 +55,8 @@ public:
}
void operator =(const RsGxsGrpMetaData& rGxsMeta);
bool operator ==(const RsGroupMetaData& rGxsMeta);
bool operator !=(const RsGroupMetaData& rGxsMeta);
RsGxsGroupId mGroupId;
std::string mGroupName;

View File

@ -53,6 +53,52 @@
this->mParentGrpId = rGxsMeta.mParentGrpId;
}
bool RsGroupMetaData::operator ==(const RsGroupMetaData& rGxsMeta)
{
return ( this->mGroupId == rGxsMeta.mGroupId
&& this->mGroupName == rGxsMeta.mGroupName
&& this->mGroupFlags == rGxsMeta.mGroupFlags
&& this->mSignFlags == rGxsMeta.mSignFlags
&& this->mPublishTs == rGxsMeta.mPublishTs
&& this->mAuthorId == rGxsMeta.mAuthorId
&& this->mCircleId == rGxsMeta.mCircleId
&& this->mCircleType == rGxsMeta.mCircleType
&& this->mAuthenFlags == rGxsMeta.mAuthenFlags
&& this->mParentGrpId == rGxsMeta.mParentGrpId
&& this->mSubscribeFlags == rGxsMeta.mSubscribeFlags
&& this->mPop == rGxsMeta.mPop
&& this->mMsgCount == rGxsMeta.mMsgCount
&& this->mLastPost == rGxsMeta.mLastPost
&& this->mGroupStatus == rGxsMeta.mGroupStatus
&& this->mServiceString == rGxsMeta.mServiceString
&& this->mOriginator == rGxsMeta.mOriginator
&& this->mInternalCircle == rGxsMeta.mInternalCircle
);
}
bool RsGroupMetaData::operator !=(const RsGroupMetaData &rGxsMeta)
{
return ( this->mGroupId != rGxsMeta.mGroupId
|| this->mGroupName != rGxsMeta.mGroupName
|| this->mGroupFlags != rGxsMeta.mGroupFlags
|| this->mSignFlags != rGxsMeta.mSignFlags
|| this->mPublishTs != rGxsMeta.mPublishTs
|| this->mAuthorId != rGxsMeta.mAuthorId
|| this->mCircleId != rGxsMeta.mCircleId
|| this->mCircleType != rGxsMeta.mCircleType
|| this->mAuthenFlags != rGxsMeta.mAuthenFlags
|| this->mParentGrpId != rGxsMeta.mParentGrpId
|| this->mSubscribeFlags != rGxsMeta.mSubscribeFlags
|| this->mPop != rGxsMeta.mPop
|| this->mMsgCount != rGxsMeta.mMsgCount
|| this->mLastPost != rGxsMeta.mLastPost
|| this->mGroupStatus != rGxsMeta.mGroupStatus
|| this->mServiceString != rGxsMeta.mServiceString
|| this->mOriginator != rGxsMeta.mOriginator
|| this->mInternalCircle != rGxsMeta.mInternalCircle
);
}
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
{

View File

@ -75,7 +75,7 @@ CreateCircleDialog::CreateCircleDialog()
QString headerText = headerItem->text(RSCIRCLEID_COL_NICKNAME);
ui.IdFilter->addFilter(QIcon(), headerText, RSCIRCLEID_COL_NICKNAME, QString("%1 %2").arg(tr("Search"), headerText));
headerText = headerItem->text(RSCIRCLEID_COL_KEYID);
ui.IdFilter->addFilter(QIcon(), headerItem->text(RSCIRCLEID_COL_KEYID), RSCIRCLEID_COL_KEYID, QString("%1 %2").arg(tr("Search"), headerText));
ui.IdFilter->addFilter(QIcon(), headerText, RSCIRCLEID_COL_KEYID, QString("%1 %2").arg(tr("Search"), headerText));
ui.removeButton->setEnabled(false);
ui.addButton->setEnabled(false);
@ -87,6 +87,7 @@ CreateCircleDialog::CreateCircleDialog()
mIsExistingCircle = false;
mIsExternalCircle = true;
mClearList = true;
ui.idChooser->loadIds(0,RsGxsId());
ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, RsGxsCircleId());
@ -98,13 +99,14 @@ CreateCircleDialog::~CreateCircleDialog()
delete(mIdQueue);
}
void CreateCircleDialog::editExistingId(const RsGxsGroupId& circleId)
void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool &clearList /*= true*/)
{
std::cerr << "CreateCircleDialog::editExistingId() : " << circleId;
std::cerr << std::endl;
/* load this circle */
mIsExistingCircle = true;
mClearList = clearList;
requestCircle(circleId);
ui.headerFrame->setHeaderText(tr("Edit Circle"));
@ -178,10 +180,7 @@ void CreateCircleDialog::selectedMember(QTreeWidgetItem *current, QTreeWidgetIte
void CreateCircleDialog::addMember()
{
QTreeWidgetItem *item = ui.treeWidget_IdList->currentItem();
if (!item)
{
return;
}
if (!item) return;
/* check that its not there already */
QString keyId = item->text(RSCIRCLEID_COL_KEYID);
@ -191,21 +190,32 @@ void CreateCircleDialog::addMember()
addMember(keyId, idtype, nickname);
}
void CreateCircleDialog::addMember(const RsGxsIdGroup &idGroup)
{
QString keyId = QString::fromStdString(idGroup.mMeta.mGroupId.toStdString());
QString nickname = QString::fromUtf8(idGroup.mMeta.mGroupName.c_str());
QString idtype = tr("Anon Id");
if (idGroup.mPgpKnown){
RsPeerDetails details;
rsPeers->getGPGDetails(idGroup.mPgpId, details);
idtype = QString::fromUtf8(details.name.c_str());
}//if (idGroup.mPgpKnown)
addMember(keyId, idtype, nickname);
}
void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype, const QString& nickname )
{
QTreeWidget *tree = ui.treeWidget_membership;
int count = tree->topLevelItemCount();
for(int i = 0; i < count; i++)
{
for(int i = 0; i < count; i++){
QTreeWidgetItem *item = tree->topLevelItem(i);
if (keyId == item->text(RSCIRCLEID_COL_KEYID))
{
if (keyId == item->text(RSCIRCLEID_COL_KEYID)) {
std::cerr << "CreateCircleDialog::addMember() Already is a Member: " << keyId.toStdString();
std::cerr << std::endl;
return;
}
}
}//if (keyId == item->text(RSCIRCLEID_COL_KEYID))
}//for(int i = 0; i < count; i++)
QTreeWidgetItem *member = new QTreeWidgetItem();
member->setText(RSCIRCLEID_COL_NICKNAME, nickname);
@ -215,16 +225,59 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
tree->addTopLevelItem(member);
}
/** Maybe we can use RsGxsCircleGroup instead of RsGxsCircleDetails ??? (TODO)**/
void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
{
typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = cirDetails.mUnknownPeers.begin()
; it != cirDetails.mUnknownPeers.end()
; ++it) {
RsGxsId gxs_id = *it;
RsIdentityDetails gxs_details ;
if(!gxs_id.isNull() && rsIdentity->getIdDetails(gxs_id,gxs_details)) {
QString keyId = QString::fromStdString(gxs_id.toStdString());
QString nickname = QString::fromUtf8(gxs_details.mNickname.c_str());
QString idtype = tr("Anon Id");
/** Can we have known peers on mUnknownPeers (TODO)
if (gxs_details.mPgpKnown) {
RsPeerDetails details;
rsPeers->getGPGDetails(gxs_details.mPgpId, details);
idtype = QString::fromUtf8(details.name.c_str());
}else{
idtype = tr("PGP Linked Id");
}//if (gxs_details.mPgpKnown)*/
addMember(keyId, idtype, nickname);
}//if(!gxs_id.isNull() && rsIdentity->getIdDetails(gxs_id,gxs_details))
}//for (itUnknownPeers it = cirDetails.mUnknownPeers.begin()
typedef std::map<RsPgpId, std::list<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = cirDetails.mAllowedPeers.begin()
; it != cirDetails.mAllowedPeers.end()
; ++it ) {
RsPgpId gpg_id = it->first;
RsPeerDetails details ;
if(!gpg_id.isNull() && rsPeers->getGPGDetails(gpg_id,details)) {
QString keyId = QString::fromStdString(details.gpg_id.toStdString());
QString nickname = QString::fromUtf8(details.name.c_str());
QString idtype = tr("PGP Identity");
addMember(keyId, idtype, nickname);
}//if(!gpg_id.isNull() && rsPeers->getGPGDetails(gpg_id,details))
}//for (itAllowedPeers it = cirDetails.mAllowedPeers.begin()
}
void CreateCircleDialog::removeMember()
{
QTreeWidgetItem *item = ui.treeWidget_membership->currentItem();
if (!item)
{
return;
}
if (!item) return;
// does this just work?
// does this just work? (TODO)
delete(item);
}
@ -234,7 +287,6 @@ void CreateCircleDialog::createCircle()
std::cerr << std::endl;
QString name = ui.circleName->text();
//QString desc;
if(name.isEmpty()) {
/* error message */
@ -280,7 +332,7 @@ void CreateCircleDialog::createCircle()
circle.mLocalFriends.push_back(RsPgpId(keyId.toStdString()));
std::cerr << "CreateCircleDialog::createCircle() Inserting Friend: " << keyId.toStdString();
std::cerr << std::endl;
}//if (mIsExternalCircle)
}//else (mIsExternalCircle)
}//for(int i = 0; i < count; i++)
@ -329,11 +381,11 @@ void CreateCircleDialog::createCircle()
QMessageBox::warning(this, tr("RetroShare"),tr("No Restriction Circle Selected"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//if (ui.circleComboBox->getChosenCircle(chosenId))
}//else (ui.circleComboBox->getChosenCircle(chosenId))
} else { //if (ui.radioButton_Public->isChecked())
QMessageBox::warning(this, tr("RetroShare"),tr("No Circle Limitations Selected"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//if (ui.radioButton_Public->isChecked())
}//else (ui.radioButton_Public->isChecked())
} else {//if (mIsExternalCircle)
std::cerr << "CreateCircleDialog::createCircle() Personal Circle";
std::cerr << std::endl;
@ -341,7 +393,7 @@ void CreateCircleDialog::createCircle()
// set personal distribution
circle.mMeta.mCircleId.clear() ;
circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_LOCAL;
}//if (mIsExternalCircle)
}//else (mIsExternalCircle)
std::cerr << "CreateCircleDialog::createCircle() : mCircleType: " << circle.mMeta.mCircleType;
std::cerr << std::endl;
@ -356,7 +408,6 @@ void CreateCircleDialog::createCircle()
close();
}
void CreateCircleDialog::updateCircleGUI()
{
std::cerr << "CreateCircleDialog::updateCircleGUI()";
@ -367,57 +418,53 @@ void CreateCircleDialog::updateCircleGUI()
bool isExternal = true;
std::cerr << "CreateCircleDialog::updateCircleGUI() : CIRCLETYPE: " << mCircleGroup.mMeta.mCircleType;
std::cerr << std::endl;
switch(mCircleGroup.mMeta.mCircleType)
{
switch(mCircleGroup.mMeta.mCircleType) {
case GXS_CIRCLE_TYPE_LOCAL:
std::cerr << "CreateCircleDialog::updateCircleGUI() : LOCAL CIRCLETYPE";
std::cerr << std::endl;
isExternal = false;
break;
case GXS_CIRCLE_TYPE_PUBLIC:
std::cerr << "CreateCircleDialog::updateCircleGUI() : PUBLIC CIRCLETYPE";
std::cerr << std::endl;
ui.radioButton_Public->setChecked(true);
break;
case GXS_CIRCLE_TYPE_EXT_SELF:
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXT_SELF CIRCLE (fallthrough)";
std::cerr << std::endl;
case GXS_CIRCLE_TYPE_EXTERNAL:
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXTERNAL CIRCLETYPE";
std::cerr << std::endl;
if (mCircleGroup.mMeta.mCircleId.toStdString() == mCircleGroup.mMeta.mGroupId.toStdString())
{
if (mCircleGroup.mMeta.mCircleId.toStdString() == mCircleGroup.mMeta.mGroupId.toStdString()) {
ui.radioButton_Restricted->setChecked(true);
}
}//if (mCircleGroup.mMeta.mCircleId.toStdString() == mCircleGroup.mMeta.mGroupId.toStdString())
ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, mCircleGroup.mMeta.mCircleId);
break;
default:
std::cerr << "CreateCircleDialog::updateCircleGUI() INVALID mCircleType";
std::cerr << std::endl;
break;
}
}//switch(mCircleGroup.mMeta.mCircleType)
// set preferredId.
ui.idChooser->loadIds(0,mCircleGroup.mMeta.mAuthorId);
/* setup personal or external circle */
if (isExternal)
{
if (isExternal) {
setupForExternalCircle();
}
else
{
} else {//if (isExternal)
setupForPersonalCircle();
}
}//else (isExternal)
}
void CreateCircleDialog::requestCircle(const RsGxsGroupId &groupId)
{
RsTokReqOptions opts;
@ -440,25 +487,20 @@ void CreateCircleDialog::loadCircle(uint32_t token)
QTreeWidget *tree = ui.treeWidget_membership;
tree->clear();
std::list<std::string> ids;
std::list<std::string>::iterator it;
if (!mClearList) tree->clear();
std::vector<RsGxsCircleGroup> groups;
if (!rsGxsCircles->getGroupData(token, groups))
{
if (!rsGxsCircles->getGroupData(token, groups)) {
std::cerr << "CreateCircleDialog::loadCircle() Error getting GroupData";
std::cerr << std::endl;
return;
}
}//if (!rsGxsCircles->getGroupData(token, groups))
if (groups.size() != 1)
{
if (groups.size() != 1) {
std::cerr << "CreateCircleDialog::loadCircle() Error Group.size() != 1";
std::cerr << std::endl;
return;
}
}//if (groups.size() != 1)
std::cerr << "CreateCircleDialog::loadCircle() LoadedGroup.meta: " << mCircleGroup.mMeta;
std::cerr << std::endl;
@ -479,8 +521,7 @@ void CreateCircleDialog::getPgpIdentities()
std::list<RsPgpId>::iterator it;
rsPeers->getGPGAcceptedList(ids);
for(it = ids.begin(); it != ids.end(); it++)
{
for(it = ids.begin(); it != ids.end(); it++) {
RsPeerDetails details;
rsPeers->getGPGDetails(*it, details);
@ -496,18 +537,16 @@ void CreateCircleDialog::getPgpIdentities()
tree->addTopLevelItem(item);
// Local Circle.
if (mIsExistingCircle)
{
if (mIsExistingCircle) {
// check if its in the circle.
std::list<RsPgpId>::const_iterator it;
it = std::find(mCircleGroup.mLocalFriends.begin(), mCircleGroup.mLocalFriends.end(), details.gpg_id);
if (it != mCircleGroup.mLocalFriends.end())
{
if (it != mCircleGroup.mLocalFriends.end()) {
/* found it */
addMember(keyId, idtype, nickname);
}
}
}
}//if (it != mCircleGroup.mLocalFriends.end())
}//if (mIsExistingCircle)
}//for(it = ids.begin(); it != ids.end(); it++)
filterIds();
}
@ -534,66 +573,51 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
tree->clear();
std::list<std::string> ids;
std::list<std::string>::iterator it;
bool acceptAnonymous = ui.radioButton_ListAll->isChecked();
bool acceptAllPGP = ui.radioButton_ListAllPGP->isChecked();
bool acceptKnownPGP = ui.radioButton_ListKnownPGP->isChecked();
//bool acceptKnownPGP = ui.radioButton_ListKnownPGP->isChecked();
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
std::vector<RsGxsIdGroup>::iterator vit;
if (!rsIdentity->getGroupData(token, datavector))
{
if (!rsIdentity->getGroupData(token, datavector)) {
std::cerr << "CreateCircleDialog::insertIdentities() Error getting GroupData";
std::cerr << std::endl;
return;
}
}//if (!rsIdentity->getGroupData(token, datavector))
for(vit = datavector.begin(); vit != datavector.end(); vit++)
{
for(vit = datavector.begin(); vit != datavector.end(); vit++) {
data = (*vit);
/* do filtering */
bool ok = false;
{
if (acceptAnonymous)
if (acceptAnonymous) {
ok = true;
else if (acceptAllPGP)
{
} else if (acceptAllPGP) {
ok = data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
}
else if (data.mPgpKnown)
{
} else if (data.mPgpKnown) {
ok = data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
}
}
}//else if (data.mPgpKnown)
if (!ok)
{
if (!ok) {
std::cerr << "CreateCircleDialog::insertIdentities() Skipping ID: " << data.mMeta.mGroupId;
std::cerr << std::endl;
continue;
}
}//if (!ok)
QString keyId = QString::fromStdString(data.mMeta.mGroupId.toStdString());
QString nickname = QString::fromUtf8(data.mMeta.mGroupName.c_str());
QString idtype = tr("Anon Id");
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
{
if (data.mPgpKnown)
{
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) {
if (data.mPgpKnown) {
RsPeerDetails details;
rsPeers->getGPGDetails(data.mPgpId, details);
idtype = QString::fromUtf8(details.name.c_str());
}
else
{
} else {
idtype = tr("PGP Linked Id");
}
}
}//else (data.mPgpKnown)
}//if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setText(RSCIRCLEID_COL_NICKNAME, nickname);
@ -602,8 +626,7 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
tree->addTopLevelItem(item);
// External Circle.
if (mIsExistingCircle)
{
if (mIsExistingCircle) {
// check if its in the circle.
std::list<RsGxsId>::const_iterator it;
@ -611,13 +634,12 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
//
it = std::find(mCircleGroup.mInvitedMembers.begin(), mCircleGroup.mInvitedMembers.end(), RsGxsId(data.mMeta.mGroupId));
if (it != mCircleGroup.mInvitedMembers.end())
{
if (it != mCircleGroup.mInvitedMembers.end()) {
/* found it */
addMember(keyId, idtype, nickname);
}
}
}
}//if (it != mCircleGroup.mInvitedMembers.end())
}//if (mIsExistingCircle)
}//for(vit = datavector.begin(); vit != datavector.end(); vit++)
}
void CreateCircleDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
@ -625,37 +647,36 @@ void CreateCircleDialog::loadRequest(const TokenQueue *queue, const TokenRequest
std::cerr << "CreateCircleDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
if (queue == mCircleQueue)
{
if (queue == mCircleQueue) {
/* now switch on req */
switch(req.mUserType)
{
switch(req.mUserType) {
case CREATECIRCLEDIALOG_CIRCLEINFO:
loadCircle(req.mToken);
break;
default:
std::cerr << "CreateCircleDialog::loadRequest() UNKNOWN UserType ";
std::cerr << std::endl;
}
}
}//switch(req.mUserType)
}//if (queue == mCircleQueue)
if (queue == mIdQueue)
{
if (queue == mIdQueue) {
/* now switch on req */
switch(req.mUserType)
{
switch(req.mUserType) {
case CREATECIRCLEDIALOG_IDINFO:
loadIdentities(req.mToken);
break;
default:
std::cerr << "CreateCircleDialog::loadRequest() UNKNOWN UserType ";
std::cerr << std::endl;
}
}
}//switch(req.mUserType)
}//if (queue == mIdQueue)
}
void CreateCircleDialog::filterChanged(const QString& /*text*/)
void CreateCircleDialog::filterChanged(const QString &text)
{
Q_UNUSED(text);
filterIds();
}

View File

@ -40,7 +40,10 @@ public:
~CreateCircleDialog();
void editNewId(bool isExternal);
void editExistingId(const RsGxsGroupId& circleId);
void editExistingId(const RsGxsGroupId &circleId, const bool &clearList = true);
void addMember(const QString &keyId, const QString &idtype, const QString &nickname );
void addMember(const RsGxsIdGroup &idGroup);
void addCircle(const RsGxsCircleDetails &cirDetails);
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
@ -58,7 +61,6 @@ private slots:
private:
void updateCircleGUI();
void addMember(const QString& keyId, const QString& idtype, const QString& nickname );
void setupForPersonalCircle();
void setupForExternalCircle();
@ -79,6 +81,7 @@ private:
TokenQueue *mIdQueue;
RsGxsCircleGroup mCircleGroup; // for editting existing Circles.
bool mClearList;
/** Qt Designer generated object */
Ui::CreateCircleDialog ui;

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CircleWidget</class>
<widget class="QWidget" name="CircleWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>202</width>
<height>217</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>200.000000000000000</width>
<height>200.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IdentityWidget</class>
<widget class="QWidget" name="IdentityWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>100.000000000000000</width>
<height>100.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelName">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelKeyId">
<property name="text">
<string>KeyId</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -24,13 +24,19 @@
#include <QMessageBox>
#include "PeopleDialog.h"
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
#include "gui/common/FlowLayout.h"
#include "gui/common/UIStateHelper.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsidentity.h>
#include <retroshare/rsgxscircles.h>
#include "retroshare/rsgxsflags.h"
//#include "IdentityItem.h"
//#include "CircleItem.h"
#include <iostream>
/******
@ -61,12 +67,43 @@
#define RSID_FILTER_PSEUDONYMS 0x0008
#define RSID_FILTER_ALL 0xffff
const uint32_t PeopleDialog::PD_IDLIST = 0x0001 ;
const uint32_t PeopleDialog::PD_IDDETAILS = 0x0002 ;
const uint32_t PeopleDialog::PD_REFRESH = 0x0003 ;
const uint32_t PeopleDialog::PD_CIRCLES = 0x0004 ;
/** Constructor */
PeopleDialog::PeopleDialog(QWidget *parent)
: RsGxsUpdateBroadcastPage(rsIdentity, parent)
{
setupUi(this);
mStateHelper = new UIStateHelper(this);
mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
//need erase QtCreator Layout first(for Win)
delete id->layout();
//QT Designer don't accept Custom Layout, maybe on QT5
_flowLayout = new FlowLayout(id);
//First Get Item created in Qt Designer
int count = id->children().count();
for (int curs = 0; curs < count; ++curs){
QObject *obj = id->children().at(curs);
QWidget *wid = qobject_cast<QWidget *>(obj);
if (wid) _flowLayout->addWidget(wid);
}//for (int curs = 0; curs < count; ++curs)
pictureFlowWidget->setAcceptDrops(true);
QObject::connect(pictureFlowWidget, SIGNAL(centerIndexChanged(int)), this, SLOT(pf_centerIndexChanged(int)));
QObject::connect(pictureFlowWidget, SIGNAL(mouseMoveOverSlideEvent(QMouseEvent*,int)), this, SLOT(pf_mouseMoveOverSlideEvent(QMouseEvent*,int)));
QObject::connect(pictureFlowWidget, SIGNAL(dragEnterEventOccurs(QDragEnterEvent*)), this, SLOT(pf_dragEnterEventOccurs(QDragEnterEvent*)));
QObject::connect(pictureFlowWidget, SIGNAL(dragMoveEventOccurs(QDragMoveEvent*)), this, SLOT(pf_dragMoveEventOccurs(QDragMoveEvent*)));
QObject::connect(pictureFlowWidget, SIGNAL(dropEventOccurs(QDropEvent*)), this, SLOT(pf_dropEventOccurs(QDropEvent*)));
pictureFlowWidget->setMinimumHeight(60);
pictureFlowWidget->setSlideSizeRatio(4/4.0);
#if 0
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -159,13 +196,507 @@ PeopleDialog::PeopleDialog(QWidget *parent)
#endif
}
void PeopleDialog::updateDisplay(bool /*complete*/)
void PeopleDialog::updateDisplay(bool complete)
{
Q_UNUSED(complete);
/* Update identity list */
circles_view->requestIdList();
circles_view->requestCirclesList();
requestIdList();
requestCirclesList();
/* grab all ids */
std::list<RsPgpId> friend_pgpIds;
std::list<RsPgpId> all_pgpIds;
std::list<RsPgpId>::iterator it;
std::set<RsPgpId> friend_set;
rsPeers->getGPGAcceptedList(friend_pgpIds);
rsPeers->getGPGAllList(all_pgpIds);
for(it = friend_pgpIds.begin(); it != friend_pgpIds.end(); ++it) {
friend_set.insert(*it);
}//for(it = friend_pgpIds.begin(); it != friend_pgpIds.end(); ++it)
for(it = all_pgpIds.begin(); it != all_pgpIds.end(); ++it) {
if (friend_set.find(*it) != friend_set.end()) continue;// already added as a friend.
friend_set.insert(*it);
}//for(it = all_pgpIds.begin(); it != all_pgpIds.end(); ++it)
for(std::set<RsPgpId>::iterator it = friend_set.begin()
; it != friend_set.end()
;++it){
RsPeerDetails details;
if (rsPeers->getGPGDetails(*it, details)) {
std::map<RsPgpId,IdentityWidget *>::iterator itFound;
if((itFound=_pgp_identity_widgets.find(*it)) == _pgp_identity_widgets.end()) {
std::cerr << "Loading pgp identity ID = " << it->toStdString() << std::endl;
IdentityWidget *new_item = new IdentityWidget(details) ;
_pgp_identity_widgets[*it] = new_item ;
QObject::connect(new_item, SIGNAL(flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)), this, SLOT(fl_flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)));
_flowLayout->addWidget(new_item);
}//if((itFound=_pgp_identity_widgets.find(*it)) == _pgp_identity_widgets.end())
}//if (rsPeers->getGPGDetails(*it, details))
}//for(std::set<RsPgpId>::iterator it = friend_set.begin()
}
void PeopleDialog::insertIdList(uint32_t token)
{
std::cerr << "**** In insertIdList() ****" << std::endl;
mStateHelper->setLoading(PD_IDLIST, false);
std::vector<RsGxsIdGroup> gdataVector;
std::vector<RsGxsIdGroup>::iterator gdIt;
if (!rsIdentity->getGroupData(token, gdataVector)) {
std::cerr << "PeopleDialog::insertIdList() Error getting GroupData";
std::cerr << std::endl;
mStateHelper->setLoading(PD_IDDETAILS, false);
mStateHelper->setLoading(PD_CIRCLES, false);
mStateHelper->setActive(PD_IDLIST, false);
mStateHelper->setActive(PD_IDDETAILS, false);
mStateHelper->setActive(PD_CIRCLES, false);
mStateHelper->clear(PD_IDLIST);
mStateHelper->clear(PD_IDDETAILS);
mStateHelper->clear(PD_CIRCLES);
return;
}//if (!rsIdentity->getGroupData(token, gdataVector))
mStateHelper->setActive(PD_IDLIST, true);
//RsPgpId ownPgpId = rsPeers->getGPGOwnId();
/* Insert items */
int i=0 ;
for (gdIt = gdataVector.begin(); gdIt != gdataVector.end(); ++gdIt){
RsGxsIdGroup gdItem = (*gdIt);
std::map<RsGxsId,IdentityWidget *>::iterator itFound;
if((itFound=_gxs_identity_widgets.find(RsGxsId(gdItem.mMeta.mGroupId))) == _gxs_identity_widgets.end()) {
std::cerr << "Loading data vector identity ID = " << gdItem.mMeta.mGroupId << ", i="<< i << std::endl;
IdentityWidget *new_item = new IdentityWidget(gdItem) ;
_gxs_identity_widgets[RsGxsId(gdItem.mMeta.mGroupId)] = new_item ;
QObject::connect(new_item, SIGNAL(flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)), this, SLOT(fl_flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)));
_flowLayout->addWidget(new_item);
++i ;
} else {//if((itFound=_identity_widgets.find(gdItem.mMeta.mGroupId)) == _identity_widgets.end())
std::cerr << "Updating data vector identity ID = " << gdItem.mMeta.mGroupId << std::endl;
//TODO
IdentityWidget *idWidget = itFound->second;
idWidget->setName("TODO updated");
//RsGxsIdGroup idGroup = gdIt;
//idWidget->update(idGroup);
}//else (_identity_widgets.find((*vit).mMeta.mGroupId) == _identity_widgets.end())
}//for (gdIt = gdataVector.begin(); gdIt != gdataVector.end(); ++gdIt)
}
void PeopleDialog::insertCircles(uint32_t token)
{
std::cerr << "PeopleDialog::insertCircles(token==" << token << ")" << std::endl;
mStateHelper->setLoading(PD_CIRCLES, false);
std::list<RsGroupMetaData> gSummaryList;
std::list<RsGroupMetaData>::iterator gsIt;
if (!rsGxsCircles->getGroupSummary(token,gSummaryList)) {
std::cerr << "PeopleDialog::insertCircles() Error getting GroupSummary";
std::cerr << std::endl;
mStateHelper->setActive(PD_CIRCLES, false);
return;
}//if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
mStateHelper->setActive(PD_CIRCLES, true);
/* add the top level item */
for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); gsIt++) {
RsGroupMetaData gsItem = (*gsIt);
RsGxsCircleDetails details ;
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details)){
std::cerr << "(EE) Cannot get details for circle id " << gsItem.mGroupId << ". Circle item is not created!" << std::endl;
continue ;
}//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details))
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
if((itFound=_circles_widgets.find(gsItem.mGroupId)) == _circles_widgets.end()) {
std::cerr << "PeopleDialog::insertCircles() add new GroupId: " << gsItem.mGroupId;
std::cerr << " GroupName: " << gsItem.mGroupName;
std::cerr << std::endl;
CircleWidget *gitem = new CircleWidget() ;
QObject::connect(gitem, SIGNAL(flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)), this, SLOT(fl_flowLayoutItemDropped(QList<FlowLayoutItem*>,bool&)));
QObject::connect(gitem, SIGNAL(askForGXSIdentityWidget(RsGxsId)), this, SLOT(cw_askForGXSIdentityWidget(RsGxsId)));
QObject::connect(gitem, SIGNAL(askForPGPIdentityWidget(RsGxsId)), this, SLOT(cw_askForPGPIdentityWidget(RsPgpId)));
gitem->updateData( gsItem, details );
_circles_widgets[gsItem.mGroupId] = gitem ;
_flowLayout->addWidget(gitem);
QPixmap pixmap = gitem->getImage();
pictureFlowWidget->addSlide( pixmap );
_listCir << gitem;
} else {//if((itFound=_circles_widgets.find(gsItem.mGroupId)) == _circles_widgets.end())
std::cerr << "PeopleDialog::insertCircles() Update GroupId: " << gsItem.mGroupId;
std::cerr << " GroupName: " << gsItem.mGroupName;
std::cerr << std::endl;
//TODO
CircleWidget *cirWidget = itFound->second;
cirWidget->setName("TODO updated");
//cirWidget->update(gsItem, details);
int index = _listCir.indexOf(cirWidget);
QPixmap pixmap = cirWidget->getImage();
pictureFlowWidget->setSlide(index, pixmap);
}//if((item=_circles_items.find(gsItem.mGroupId)) == _circles_items.end())
}//for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); gsIt++)
}
void PeopleDialog::requestIdList()
{
std::cerr << "Requesting ID list..." << std::endl;
if (!mIdentityQueue) return;
mStateHelper->setLoading(PD_IDLIST, true);
//mStateHelper->setLoading(PD_IDDETAILS, true);
//mStateHelper->setLoading(PD_REPLIST, true);
mIdentityQueue->cancelActiveRequestTokens(PD_IDLIST);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
mIdentityQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, PD_IDLIST);
}
void PeopleDialog::requestCirclesList()
{
std::cerr << "Requesting Circles list..." << std::endl;
if (!mCirclesQueue) return;
mStateHelper->setLoading(PD_CIRCLES, true);
//mStateHelper->setLoading(PD_IDDETAILS, true);
//mStateHelper->setLoading(PD_REPLIST, true);
mCirclesQueue->cancelActiveRequestTokens(PD_CIRCLES);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token;
mCirclesQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, PD_CIRCLES);
}
void PeopleDialog::loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req)
{
std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
switch(req.mUserType) {
case PD_IDLIST:
insertIdList(req.mToken);
break;
case PD_IDDETAILS:
//insertIdDetails(req.mToken);
break;
case PD_CIRCLES:
insertCircles(req.mToken);
break;
case PD_REFRESH:
updateDisplay(true);
break;
default:
std::cerr << "IdDialog::loadRequest() ERROR";
std::cerr << std::endl;
break;
}//switch(req.mUserType)
}
void PeopleDialog::cw_askForGXSIdentityWidget(RsGxsId gxs_id)
{
CircleWidget *dest =
qobject_cast<CircleWidget *>(QObject::sender());
if (dest) {
std::map<RsGxsId,IdentityWidget *>::iterator itFound;
if((itFound=_gxs_identity_widgets.find(gxs_id)) != _gxs_identity_widgets.end()) {
IdentityWidget *idWidget = itFound->second;
dest->addIdent(idWidget);
}//if((itFound=_gxs_identity_widgets.find(gxs_id)) != _gxs_identity_widgets.end()) {
}//if (dest)
}
void PeopleDialog::cw_askForPGPIdentityWidget(RsPgpId pgp_id)
{
CircleWidget *dest =
qobject_cast<CircleWidget *>(QObject::sender());
if (dest) {
std::map<RsPgpId,IdentityWidget *>::iterator itFound;
if((itFound=_pgp_identity_widgets.find(pgp_id)) != _pgp_identity_widgets.end()) {
IdentityWidget *idWidget = itFound->second;
dest->addIdent(idWidget);
}//if((itFound=_pgp_identity_widgets.find(gxs_id)) != _pgp_identity_widgets.end()) {
}//if (dest)
}
void PeopleDialog::fl_flowLayoutItemDropped(QList<FlowLayoutItem *>flListItem, bool &bAccept)
{
bAccept=false;
bool bCreateNewCircle=false;
bool bIsExternal=false;//External if one at least is unknow or external
bool bDestCirIsLocal=false;
FlowLayoutItem *dest =
qobject_cast<FlowLayoutItem *>(QObject::sender());
if (dest) {
CreateCircleDialog dlg;
CircleWidget* cirDest = qobject_cast<CircleWidget*>(dest);
if (cirDest) {
bDestCirIsLocal = (cirDest->groupInfo().mCircleType == GXS_CIRCLE_TYPE_LOCAL);
bIsExternal |= ! bDestCirIsLocal;
dlg.addCircle(cirDest->circleDetails());
} else {//if (cirDest)
bCreateNewCircle=true;
}//else (cirDest)
IdentityWidget* idDest = qobject_cast<IdentityWidget*>(dest);
if (idDest) {
if (idDest->isGXS()){
bIsExternal |= ! idDest->groupInfo().mPgpKnown;
dlg.addMember(idDest->groupInfo());
} else {//if (idDest->isGXS())
///TODO: How to get RSGxsIdGrop from pgp???
//dlg.addMember(idDest->details().id);
}//else (idDest->isGXS())
}//if (idDest)
typedef QList<FlowLayoutItem *>::Iterator itList;
for (itList listCurs = flListItem.begin()
; listCurs != flListItem.end()
; ++listCurs) {
FlowLayoutItem *flCurs = *listCurs;
CircleWidget* cirDropped = qobject_cast<CircleWidget*>(flCurs);
//Create new circle if circle dropped in circle or ident
if (cirDropped) {
bCreateNewCircle = true;
bIsExternal |= (cirDropped->groupInfo().mCircleType != GXS_CIRCLE_TYPE_LOCAL);
dlg.addCircle(cirDropped->circleDetails());
} else {//if (cirDropped)
IdentityWidget* idDropped = qobject_cast<IdentityWidget*>(flCurs);
if (idDropped){
bIsExternal |= ! idDropped->groupInfo().mPgpKnown;
dlg.addMember(idDropped->groupInfo());
}//if (idDropped)
}//else (cirDropped)
}//for (itList listCurs = flListItem.begin()
bCreateNewCircle |= (bIsExternal && bDestCirIsLocal);
if (bCreateNewCircle){
dlg.editNewId(bIsExternal);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId);
}//else (bCreateNewCircle)
dlg.exec();
bAccept=true;
}//if (dest)
}
void PeopleDialog::pf_centerIndexChanged(int index)
{
Q_UNUSED(index)
}
void PeopleDialog::pf_mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex)
{
Q_UNUSED(event)
Q_UNUSED(slideIndex)
}
void PeopleDialog::pf_dragEnterEventOccurs(QDragEnterEvent *event)
{
FlowLayoutItem *flItem =
qobject_cast<FlowLayoutItem *>(event->source());
if (flItem) {
event->setDropAction(Qt::CopyAction);
event->accept();
return;
}//if (flItem)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = 0;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
event->setDropAction(Qt::CopyAction);
event->accept();
return;
}//if (layout)
}
void PeopleDialog::pf_dragMoveEventOccurs(QDragMoveEvent *event)
{
FlowLayoutItem *flItem =
qobject_cast<FlowLayoutItem *>(event->source());
if (flItem) {
event->setDropAction(Qt::CopyAction);
event->accept();
return;
}//if (flItem)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = 0;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
event->setDropAction(Qt::CopyAction);
event->accept();
return;
}//if (layout)
}
void PeopleDialog::pf_dropEventOccurs(QDropEvent *event)
{
bool bCreateNewCircle=false;
bool bIsExternal=false;//External if one at least is unknow or external
bool bDestCirIsLocal=false;
bool atLeastOne = false;
int index = pictureFlowWidget->centerIndex();
CircleWidget* cirDest = _listCir[index];
if (cirDest) {
CreateCircleDialog dlg;
bDestCirIsLocal = (cirDest->groupInfo().mCircleType == GXS_CIRCLE_TYPE_LOCAL);
bIsExternal |= ! bDestCirIsLocal;
dlg.addCircle(cirDest->circleDetails());
{//Test if source is only one FlowLayoutItem
FlowLayoutItem *flCurs =
qobject_cast<FlowLayoutItem *>(event->source());
if (flCurs) {
CircleWidget* cirDropped = qobject_cast<CircleWidget*>(flCurs);
//Create new circle if circle dropped in circle or ident
if (cirDropped) {
bCreateNewCircle = true;
bIsExternal |= (cirDropped->groupInfo().mCircleType != GXS_CIRCLE_TYPE_LOCAL);
dlg.addCircle(cirDropped->circleDetails());
atLeastOne = true;
} else {//if (cirDropped)
IdentityWidget* idDropped = qobject_cast<IdentityWidget*>(flCurs);
if (idDropped){
if (idDropped->isGXS()){
bIsExternal |= ! idDropped->groupInfo().mPgpKnown;
dlg.addMember(idDropped->groupInfo());
atLeastOne = true;
} else {//if (idDropped->isGXS())
///TODO: How to get RSGxsIdGrop from pgp???
//dlg.addMember(idDropped->details().id);
//atLeastOne = true;
}//else (idDropped->isGXS())
}//if (idDropped)
}//else (cirDropped)
}//if (flCurs)
}//End Test if source is only one IdentityWidget
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
QList<QLayoutItem *> list = layout->selectionList();
int count = list.count();
for (int curs = 0; curs < count; ++curs){
QLayoutItem *layoutItem = list.at(curs);
if (layoutItem){
FlowLayoutItem *flCurs =
qobject_cast<FlowLayoutItem *>(layoutItem->widget());
if (flCurs){
CircleWidget* cirDropped = qobject_cast<CircleWidget*>(flCurs);
//Create new circle if circle dropped in circle or ident
if (cirDropped) {
bCreateNewCircle = true;
bIsExternal |= (cirDropped->groupInfo().mCircleType != GXS_CIRCLE_TYPE_LOCAL);
dlg.addCircle(cirDropped->circleDetails());
atLeastOne = true;
} else {//if (cirDropped)
IdentityWidget* idDropped = qobject_cast<IdentityWidget*>(flCurs);
if (idDropped){
bIsExternal |= ! idDropped->groupInfo().mPgpKnown;
dlg.addMember(idDropped->groupInfo());
atLeastOne = true;
}//if (idDropped)
}//else (cirDropped)
}//if (flCurs)
}//if (layoutItem)
}//for (int curs = 0; curs < count; ++curs)
}//if (layout)
if (atLeastOne) {
bCreateNewCircle |= (bIsExternal && bDestCirIsLocal);
if (bCreateNewCircle){
dlg.editNewId(bIsExternal);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId);
}//else (bCreateNewCircle)
dlg.exec();
event->setDropAction(Qt::CopyAction);
event->accept();
}//if (atLeastOne)
}//if (cirDest)
}
void PeopleDialog::populatePictureFlow()
{
std::map<RsGxsGroupId,CircleWidget *>::iterator it;
for (it=_circles_widgets.begin(); it!=_circles_widgets.end(); ++it) {
CircleWidget *item = it->second;
QPixmap pixmap = item->getImage();
pictureFlowWidget->addSlide( pixmap );
}//for (it=_circles_items.begin(); it!=_circles_items.end(); ++it)
pictureFlowWidget->setSlideSizeRatio(4/4.0);
}
#if 0
void IdDialog::todo()
{

View File

@ -27,26 +27,70 @@
#include <retroshare/rsidentity.h>
#include "gui/People/CircleWidget.h"
#include "gui/People/IdentityWidget.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "util/TokenQueue.h"
#include "ui_PeopleDialog.h"
#define IMAGE_IDENTITY ":/images/identity/identities_32.png"
class UIStateHelper;
//class IdentityItem ;
//class CircleItem ;
class PeopleDialog : public RsGxsUpdateBroadcastPage, public Ui::PeopleDialog
class PeopleDialog : public RsGxsUpdateBroadcastPage, public Ui::PeopleDialog, public TokenResponse
{
Q_OBJECT
public:
static const uint32_t PD_IDLIST ;
static const uint32_t PD_IDDETAILS ;
static const uint32_t PD_REFRESH ;
static const uint32_t PD_CIRCLES ;
PeopleDialog(QWidget *parent = 0);
virtual QIcon iconPixmap() const { return QIcon(IMAGE_IDENTITY) ; } //MainPage
virtual QString pageName() const { return tr("People") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
// Derives from RsGxsUpdateBroadcastPage
// virtual void updateDisplay(bool) ;
void loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req) ;
void requestIdList() ;
void requestCirclesList() ;
void insertIdList(uint32_t token) ;
void insertCircles(uint32_t token) ;
protected:
virtual void updateDisplay(bool complete);
private slots:
void cw_askForGXSIdentityWidget(RsGxsId gxs_id);
void cw_askForPGPIdentityWidget(RsPgpId pgp_id);
void fl_flowLayoutItemDropped(QList<FlowLayoutItem *> flListItem, bool &bAccept);
void pf_centerIndexChanged(int index);
void pf_mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex);
void pf_dragEnterEventOccurs(QDragEnterEvent *event);
void pf_dragMoveEventOccurs(QDragMoveEvent *event);
void pf_dropEventOccurs(QDropEvent *event);
private:
void populatePictureFlow();
TokenQueue *mIdentityQueue;
TokenQueue *mCirclesQueue;
UIStateHelper *mStateHelper;
FlowLayout *_flowLayout;
std::map<RsPgpId,IdentityWidget *> _pgp_identity_widgets ;
std::map<RsGxsId,IdentityWidget *> _gxs_identity_widgets ;
std::map<RsGxsGroupId,CircleWidget *> _circles_widgets ;
//QList<IdentityWidget*> listId;
QList<CircleWidget*> _listCir;
};

View File

@ -90,7 +90,32 @@
</widget>
</item>
<item>
<widget class="GroupListView" name="circles_view"/>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="FlowLayoutWidget" name="id">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>891</width>
<height>373</height>
</rect>
</property>
<layout class="QVBoxLayout"/>
</widget>
</widget>
<widget class="PictureFlow" name="pictureFlowWidget" native="true">
<property name="widgetResizable" stdset="0">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</item>
@ -98,9 +123,16 @@
</widget>
<customwidgets>
<customwidget>
<class>GroupListView</class>
<extends>QGraphicsView</extends>
<header>gui/People/GroupListView.h</header>
<class>PictureFlow</class>
<extends>QWidget</extends>
<header location="global">gui/common/PictureFlow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>FlowLayoutWidget</class>
<extends>QWidget</extends>
<header location="global">gui/common/FlowLayout.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>

View File

@ -0,0 +1,755 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "gui/common/FlowLayout.h"
#include <QApplication>
#include <QtGui>
#include <QDebug>
//*** FlowLayoutItem **********************************************************
void FlowLayoutItem::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_startPos = event->pos();
}//if (event->button() == Qt::LeftButton)
QWidget::mousePressEvent(event);
}
void FlowLayoutItem::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
int distance = (event->pos() - m_startPos).manhattanLength();
if (distance >= QApplication::startDragDistance())
performDrag();
}//if (event->buttons() & Qt::LeftButton)
QWidget::mouseMoveEvent(event);
}
void FlowLayoutItem::performDrag()
{
QMimeData *mimeData = new QMimeData;
mimeData->setText(m_myName);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
QPixmap pixmap=getDragImage();
drag->setPixmap(pixmap.scaled(50,50,Qt::KeepAspectRatio, Qt::SmoothTransformation));
/// Warning On Windows, Drag Pixmap size cannot exceed 50*50. ///
drag->setHotSpot(QPoint(0, 0));
Qt::DropAction dropAction = drag->exec(Qt::CopyAction);
qDebug()<<dropAction;
}
void FlowLayoutItem::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
QWidget::mouseReleaseEvent(event);
}
void FlowLayoutItem::dragEnterEvent(QDragEnterEvent *event)
{
FlowLayoutItem *source =
qobject_cast<FlowLayoutItem *>(event->source());
if (source && source != this) {
event->setDropAction(Qt::CopyAction);
event->acceptProposedAction();
return;
}//if (source && source != this)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = 0;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
event->setDropAction(Qt::CopyAction);
event->acceptProposedAction();
return;
}//if (layout)
}
void FlowLayoutItem::dragMoveEvent(QDragMoveEvent *event)
{
FlowLayoutItem *source =
qobject_cast<FlowLayoutItem *>(event->source());
if (source && source != this) {
event->setDropAction(Qt::CopyAction);
event->acceptProposedAction();
return;
}//if (source && source != this)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = 0;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
event->setDropAction(Qt::CopyAction);
event->acceptProposedAction();
return;
}//if (layout)
}
void FlowLayoutItem::dropEvent(QDropEvent *event)
{
QList <FlowLayoutItem*> list;
FlowLayoutItem *source =
qobject_cast<FlowLayoutItem *>(event->source());
if (source && source != this) {
event->setDropAction(Qt::CopyAction);
list << source;
} else {//if (source && source != this)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
QList<QLayoutItem *> listSel = layout->selectionList();
int count = listSel.count();
for (int curs = 0; curs < count; ++curs){
QLayoutItem *layoutItem = listSel.at(curs);
FlowLayoutItem *flItem = 0;
if (layoutItem) flItem = qobject_cast<FlowLayoutItem*>(layoutItem->widget());
if (flItem) list << flItem;
}//for (int curs = 0; curs < count; ++curs)
}//if (layout)
}//else (source && source != this)
if (!list.isEmpty()) {
event->setDropAction(Qt::CopyAction);
bool bAccept=true;
emit flowLayoutItemDropped(list, bAccept);
if (bAccept) event->acceptProposedAction();
}//if (!list.empty())
}
//*** FlowLayoutWidget **********************************************************
FlowLayoutWidget::FlowLayoutWidget(QWidget *parent, int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
: QWidget(parent)
{
FlowLayoutWidget(margin, hSpacing, vSpacing);
}
FlowLayoutWidget::FlowLayoutWidget(int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
{
FlowLayout *fl = new FlowLayout(this, margin, hSpacing, vSpacing);
Q_UNUSED(fl)
this->installEventFilter(this);
this->setMouseTracking(true);
this->setAcceptDrops(true);
m_saParent = 0;
m_sbVertical = 0;
}
FlowLayoutWidget::~FlowLayoutWidget()
{
}
bool FlowLayoutWidget::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "FlowLayoutWidget:: obj type:" << obj->metaObject()->className() << " event type:" << event->type();
updateParent();
if (event->type() == QEvent::DragEnter) {
QDragEnterEvent *dragEnterEvent = static_cast<QDragEnterEvent *>(event);
if (dragEnterEvent){
dragEnterEvent->setDropAction(Qt::IgnoreAction);
dragEnterEvent->accept();
}//if (dragEnterEvent)
}//if (event->type() == QEvent::DragEnter)
if (event->type() == QEvent::DragMove) {
QDragMoveEvent *dragMoveEvent = static_cast<QDragMoveEvent *>(event);
const int border = 20;
if (obj==this && dragMoveEvent){
if (m_sbVertical){
int maxY = m_sbVertical->maximum();
int currentY = m_sbVertical->value();
int height = m_saParent->height();
int topBorder = currentY + border;
int bottomBorder = currentY + height - border;
int dragY = dragMoveEvent->pos().y();
qDebug() <<"Drag event:" << dragY ;
int dY = (dragY<topBorder)?dragY - topBorder:((dragY>bottomBorder)?dragY - bottomBorder:0);
qDebug() << "dY:" << dY << " m_lastYPos:" << m_lastYPos << "(dragY-m_lastYPos)*dY:" << (dragY-m_lastYPos)*dY;
int newValue=currentY+dY;
if ((abs(dY)<border) && ((dragY-m_lastYPos)*dY >= 0)){
if (newValue>maxY) newValue=maxY;
if (newValue<0) newValue=0;
m_sbVertical->setValue(newValue);
} else {
newValue=currentY;
}//if ((abs(dY)<border) && ((dragY-m_lastYPos)*dY >= 0))
m_lastYPos = dragY+(newValue-currentY);
}//if (sbVertical)
}//if (obj==this && dragMoveEvent)
if (obj==m_sbVertical && dragMoveEvent){
if (m_sbVertical->isVisible()){
int maxY = m_sbVertical->maximum();
double height = m_sbVertical->height()*1.0;
double scale = (maxY/height);
int dragY = dragMoveEvent->pos().y();
qDebug() << "Drag maxY:" << maxY << "height:" << height << "scale:" << scale << "dragY:" << dragY;
m_sbVertical->setValue(dragY*scale);
}//if (sbVertical->isVisible())
}//if (obj==this && dragMoveEvent)
}//if (event->type() == QEvent::DragMove)
// standard event processing
return QObject::eventFilter(obj, event);
}
void FlowLayoutWidget::updateParent()
{
if (parent()){
if (!m_saParent){
if (parent()->objectName() == "qt_scrollarea_viewport"){
m_saParent = qobject_cast<QScrollArea*>(parent()->parent());
} else {
m_saParent = qobject_cast<QScrollArea*>(parent());
}//if (parent()->objectName() == "qt_scrollarea_viewport")
if (m_saParent){
m_saParent->installEventFilter(this);
m_saParent->setAcceptDrops(true);
m_saParent->setMouseTracking(true);
}//if (saParent)
}//if (!saParent)
if (m_saParent && !m_sbVertical){
m_sbVertical= m_saParent->verticalScrollBar();
if (m_sbVertical){
m_sbVertical->installEventFilter(this);
m_sbVertical->setAcceptDrops(true);
m_sbVertical->setMouseTracking(true);
}//if (sbVertical)
}//if (saParent && !sbVertical)
}//if (parent())
}
//*** FlowLayout **********************************************************
FlowLayout::FlowLayout(QWidget *parent, int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
this->installEventFilter(this);
}
FlowLayout::FlowLayout(int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
this->installEventFilter(this);
}
FlowLayout::~FlowLayout()
{
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;
}
bool FlowLayout::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "FlowLayout::obj type:" << obj->metaObject()->className() << " event type:" << event->type();
if (event->type() == QEvent::MouseButtonPress) {
m_startPos = QCursor::pos();
}//if (event->type() == QEvent::MouseButtonPress)
if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
int distance = (QCursor::pos() - m_startPos).manhattanLength();
if (distance < QApplication::startDragDistance()){
unsetCurrent();
m_currentIndex=indexAtGlobal(QCursor::pos());
setCurrent();
bool invert = (mouseEvent->modifiers() &= Qt::ControlModifier);
if (mouseEvent->modifiers() &= Qt::ShiftModifier){
m_selStartIndex=(m_selStartIndex<m_currentIndex)?m_selStartIndex:m_currentIndex;
m_selStopIndex=(m_selStopIndex>m_currentIndex)?m_selStopIndex:m_currentIndex;
} else {
m_selStartIndex=m_selStopIndex=m_currentIndex;
if (mouseEvent->modifiers() != Qt::ControlModifier){
foreach (QLayoutItem *item, m_selectionList) {
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
if (fli) fli->setIsSelected(false);
m_selectionList.removeOne(item);
}
}//if (mouseEvent->modifiers() != Qt::ControlModifier)
}//if (mouseEvent->modifiers()
addSelection(invert);
setCurrent();
}//if (distance < QApplication::startDragDistance())
doLayout(geometry(),false);
}//if (event->type() == QEvent::MouseButtonRelease)
if (event->type() == QEvent::MouseMove) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->buttons() & Qt::LeftButton) {
int distance = (QCursor::pos() - m_startPos).manhattanLength();
if (distance >= QApplication::startDragDistance()){
if (!m_selectionList.isEmpty()) {
QLayoutItem *item=itemAtGlobal(m_startPos);
if (item) {
if (m_selectionList.contains(item)){
performDrag();
return true; // eat event
}//if (m_selectionList.contains(item))
}//if (item)
}//if (!m_selectionList.isEmpty())
}//if (distance >= QApplication::startDragDistance())
}//if (mouseEvent->buttons() & Qt::LeftButton)
}//if (event->type() == QEvent::MouseMove)
if (event->type() == QEvent::KeyRelease) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if ((keyEvent->key()==Qt::Key_A) && (keyEvent->modifiers() &= Qt::ControlModifier)){
int count = m_itemList.count();
int selected = m_selectionList.count();
if (count != selected){
for (int curs=0; curs<count; ++curs){
QLayoutItem *item=itemAt(curs);
if (item) {
if (!m_selectionList.contains(item)){
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
if (fli) fli->setIsSelected(true);
m_selectionList.append(item);
}//if (!m_selectionList.contains(item))
}//if (item)
}//for (int curs=0; curs<count; ++curs)
} else {
foreach (QLayoutItem *item, m_selectionList) {
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
if (fli) fli->setIsSelected(false);
m_selectionList.removeOne(item);
}
}//if (count != selected)
doLayout(geometry(),false);
event->accept();
}//if ((keyEvent->key()==Qt::Key_A) && (keyEvent->modifiers() &= Qt::ControlModifier))
if ((keyEvent->key()==Qt::Key_Space)){
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
doLayout(geometry(),false);
m_selStartIndex = m_selStopIndex = m_currentIndex;
event->accept();
}//if ((keyEvent->key()==Qt::Key_Space))
if ((keyEvent->key()==Qt::Key_Left)){
unsetCurrent();
if (m_currentIndex>0) m_currentIndex-=1;
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
m_selStartIndex=m_currentIndex;
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
doLayout(geometry(),false);
m_selStartIndex = m_selStopIndex = m_currentIndex;
event->accept();
setCurrent();
}//if ((keyEvent->key()==Qt::Key_Left))
if ((keyEvent->key()==Qt::Key_Right)){
unsetCurrent();
if (m_currentIndex<(m_itemList.count()-1)) m_currentIndex+=1;
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
m_selStopIndex=m_currentIndex;
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
doLayout(geometry(),false);
m_selStartIndex = m_selStopIndex = m_currentIndex;
event->accept();
setCurrent();
}//if ((keyEvent->key()==Qt::Key_Right))
if ((keyEvent->key()==Qt::Key_Up)){
unsetCurrent();
QLayoutItem* item = currentItem();
if (item) {
QRect loc = item->geometry();
int vSpace = verticalSpacing();
QPoint pos = QPoint(loc.left()+loc.width()/2, loc.top()-vSpace-2);
int index = -1;
while ((pos.y()>0) && (index < 0)){
index = indexAtParent(pos);
pos.setY(pos.y()-2);
}//while ((pos.y()>0) && (index < 0))
m_currentIndex = (index>0)?index:0;
m_currentIndex = (index<=m_itemList.count())?index:m_itemList.count();
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
m_selStopIndex = m_currentIndex;
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
doLayout(geometry(),false);
m_selStartIndex = m_selStopIndex = m_currentIndex;
event->accept();
}//if (wid)
setCurrent();
}//if ((keyEvent->key()==Qt::Key_Right))
if ((keyEvent->key()==Qt::Key_Down)){
unsetCurrent();
QLayoutItem* item = currentItem();
if (item){
QRect loc = item->geometry();
int vSpace = verticalSpacing();
QPoint pos = QPoint(loc.left()+loc.width()/2, loc.bottom()+vSpace+2);
int index = -1;
while ((pos.y()<geometry().bottom()) && (index < 0)){
index = indexAtParent(pos);
pos.setY(pos.y()+2);
}//while ((pos.y()<geometry().bottom()) && (index < 0))
m_currentIndex = (index>0)?index:0;
m_currentIndex = (index<=m_itemList.count())?index:m_itemList.count();
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
m_selStopIndex = m_currentIndex;
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
doLayout(geometry(),false);
m_selStartIndex = m_selStopIndex = m_currentIndex;
event->accept();
}//if (wid)
setCurrent();
}//if ((keyEvent->key()==Qt::Key_Right))
}//if (event->type() == QEvent::KeyRelease)
// standard event processing
return QObject::eventFilter(obj, event);
}
void FlowLayout::unsetCurrent()
{
QLayoutItem *oldItem = currentItem();
if (oldItem) {
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(oldItem->widget());
if (fli) fli->setIsCurrent(false);
}//if (oldItem)
}
void FlowLayout::setCurrent()
{
QLayoutItem *newItem = currentItem();
if (newItem) {
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(newItem->widget());
if (fli) fli->setIsCurrent(true);
}//if (newItem)
}
void FlowLayout::addItem(QLayoutItem *item)
{
m_itemList.append(item);
item->widget()->installEventFilter(this);
}
void FlowLayout::addItem(FlowLayoutItem *item)
{
QWidget *widget = qobject_cast<QWidget *>(item);
addWidget(widget);
}
int FlowLayout::horizontalSpacing() const
{
if (m_hSpace >= 0) {
return m_hSpace;
} else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}//if (m_hSpace >= 0)
}
void FlowLayout::setHorizontalSpacing(int &h)
{
if (h>=0) {
m_hSpace = h;
} else {
m_hSpace = -1;
}//if (h>=0)
doLayout(geometry(), false);
}
int FlowLayout::verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
} else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}//if (m_vSpace >= 0)
}
void FlowLayout::setVerticalSpacing(int &v)
{
if (v>=0) {
m_vSpace = v;
} else {
m_vSpace = -1;
}//if (v>=0)
doLayout(geometry(), false);
}
int FlowLayout::count() const
{
return m_itemList.size();
}
QLayoutItem *FlowLayout::itemAt(int index) const
{
return m_itemList.value(index);
}
QLayoutItem *FlowLayout::itemAtGlobal(const QPoint &p) const
{
return m_itemList.value(indexAtGlobal(p));
}
QLayoutItem *FlowLayout::itemAtParent(const QPoint &p) const
{
return m_itemList.value(indexAtParent(p));
}
int FlowLayout::indexAtGlobal(const QPoint &p) const
{
int count = m_itemList.size();
for(int curs=0; curs<count; ++curs){
QWidget *widget = m_itemList.value(curs)->widget();
if(widget) {
QPoint pos = widget->mapFromGlobal(p);
if((pos.x()>0) && (pos.x()<widget->width()))
if((pos.y()>0) && (pos.y()<widget->height()))
return curs;
}//if(widget)
}//for(int curs=0; curs<count; ++curs)
return -1;
}
int FlowLayout::indexAtParent(const QPoint &p) const
{
int count = m_itemList.size();
for(int curs=0; curs<count; ++curs){
QWidget *widget = m_itemList.value(curs)->widget();
if(widget) {
QPoint pos = widget->mapFromParent(p);
if((pos.x()>=0) && (pos.x()<=widget->width()))
if((pos.y()>=0) && (pos.y()<=widget->height()))
return curs;
if (pos.y()<0) break;//In line below so don't check other item.
}//if(widget)
}//for(int curs=0; curs<count; ++curs)
return -1;
}
QLayoutItem *FlowLayout::takeAt(int index)
{
if (index >= 0 && index < m_itemList.size())
return m_itemList.takeAt(index);
else
return 0;
}
Qt::Orientations FlowLayout::expandingDirections() const
{
return Qt::Horizontal;
}
bool FlowLayout::hasHeightForWidth() const
{
return true;
}
int FlowLayout::heightForWidth(int width) const
{
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
}
void FlowLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize FlowLayout::sizeHint() const
{
return minimumSize();
}
QSize FlowLayout::minimumSize() const
{
QSize size;
QLayoutItem *item;
foreach (item, m_itemList)
size = size.expandedTo(item->minimumSize());
size += QSize(2*margin(), 2*margin());
return size;
}
void FlowLayout::addSelection(bool invert){
for (int curs=m_selStartIndex; curs<=m_selStopIndex; ++curs){
QLayoutItem *item=itemAt(curs);
if (item) {
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
if (invert && m_selectionList.contains(item)){
if (fli) fli->setIsSelected(false);
m_selectionList.removeOne(item);
} else {
if (fli) fli->setIsSelected(true);
m_selectionList.append(item);
}//if (m_selectionList.contains(item))
}//if (item)
}//for (int curs=m_selStartIndex; curs<=m_selStopIndex; ++curs)
}
void FlowLayout::performDrag()
{
QPixmap dragPixmap;
bool atLeastOnePixmap = false;
int count = m_selectionList.count();
for (int curs=0; curs<count; ++curs){
QLayoutItem *layoutItem = m_selectionList.at(curs);
if (layoutItem){
QWidget *widget = layoutItem->widget();
if (widget) {
QPixmap itemPixmap;
FlowLayoutItem *item = qobject_cast<FlowLayoutItem *>(widget);
if (item){
itemPixmap = item->getDragImage();
} else {
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
itemPixmap = widget->grab();//QT5
#else
itemPixmap = QPixmap::grabWidget(widget);
#endif
}//if (item)
itemPixmap = itemPixmap.scaled(50,50,Qt::KeepAspectRatio, Qt::SmoothTransformation);
/// Warning On Windows, Drag Pixmap size cannot exceed 50*50. ///
if (curs==0) dragPixmap = itemPixmap;
QPixmap oldPixmap = dragPixmap;
if (curs!=0) dragPixmap = QPixmap(oldPixmap.width() + 20 , oldPixmap.height());
dragPixmap.fill(widget->palette().background().color());
QPainter painter(&dragPixmap);
painter.drawPixmap(0, 0, oldPixmap);
if (curs!=0) painter.drawPixmap((20 * curs), 0, itemPixmap);
atLeastOnePixmap = true;
}//if (widget)
}//if (layoutItem)
}//for (int curs=0; curs<count; ++curs)
if (atLeastOnePixmap) {
QMimeData *mimeData = new QMimeData;
mimeData->setText("");
QDrag *drag = new QDrag(this->parentWidget());
drag->setMimeData(mimeData);
drag->setPixmap(dragPixmap);
drag->setHotSpot(QPoint(0, 0));
drag->exec(Qt::CopyAction);
}//if (atLeastOnePixmap)
}
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
int count = m_itemList.size();
for (int curs=0; curs<count; ++curs) {
QLayoutItem *item=m_itemList.value(curs);
QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}//if (nextX - spaceX > effectiveRect.right() && lineHeight > 0)
if (!testOnly){
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
bool selected = m_selectionList.contains(item);
bool isCurrent = (curs==currentIndex());
QString solid = isCurrent?"dot-dash":"inset";
QString color = selected?"blue":isCurrent?"gray":"";
QString border = (selected||isCurrent)?QString("border: 1px %1 %2").arg(solid).arg(color):"";
QString widName = wid->objectName();
QString style;
if (widName.isEmpty()){
style=border;
} else {
//For Custom QWidget, change paintEvent as FlowLayoutItem. cf:http://qt-project.org/doc/qt-4.8/stylesheet-reference.html
style = QString("QWidget#%1\n{\n%2\n}\n").arg(wid->objectName(),border);
}//if (widName.isEmpty())
///Warning: Test if != to not ask a new redraw all time ///
if (wid->styleSheet()!=style) wid->setStyleSheet(style);
}//if (!testOnly)
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}//for (curs=0; curs<count; ++curs)
return y + lineHeight - rect.y() + bottom;
}
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{
QObject *parent = this->parent();
if (!parent) {
return -1;
} else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent);
return pw->style()->pixelMetric(pm, 0, pw);
} else {
return static_cast<QLayout *>(parent)->spacing();
}//if (!parent)
}

View File

@ -0,0 +1,344 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
/** WARNING: QT Designer don't accept Custom Layout, maybe on QT5
*You can get widget's children like this:
* FlowLayout *flowLayout = new FlowLayout;
* //First Get Item in Qt Designer
* int count = ui->id->children().count();
* for (int curs = 0; curs < count; ++curs){
* QObject *obj = ui->id->children().at(curs);
* QWidget *wid = qobject_cast<QWidget *>(obj);
* if (wid) flowLayout->addWidget(wid);
* }//for (int curs = 0; curs < count; ++curs)
*/
#ifndef FLOWLAYOUT_H
#define FLOWLAYOUT_H
#include <QKeyEvent>
#include <QLayout>
#include <QPainter>
#include <QRect>
#include <QScrollArea>
#include <QStyle>
#include <QStyleOption>
#include <QWidget>
#include <QWidgetItem>
/// \class FlowLayoutItem
/// \brief The FlowLayoutItem class
///FlowLayoutItem represents FlowLayout item.
///Derivatives from it to make a custom widget
///and to get Drag and Drop better.
class FlowLayoutItem : public QWidget
{
Q_OBJECT
public:
FlowLayoutItem(QString name=QString(), QWidget *parent=0) : QWidget(parent), m_myName(name){
setFocusPolicy(Qt::StrongFocus);
setAcceptDrops(true);
}
~FlowLayoutItem(){}
/// \brief getImage
/// \return Image to represent your widget (not necessary all the widget).
virtual const QPixmap getImage() =0;
/// \brief getDragImage
/// \return Image to represent your widget when dragged (not necessary all the widget).
virtual const QPixmap getDragImage() =0;
/// \brief setName
/// \param value
virtual void setName(QString value) {m_myName=value;}
/// \brief getName
/// \return the name of your widget;
virtual const QString getName() const {return m_myName;}
/// \brief setIsSelected
/// \param value
virtual void setIsSelected(bool value) {m_isSelected=value;}
/// \brief getSelected
/// \return if item is selected
virtual bool isSelected() const {return m_isSelected;}
/// \brief setCurrent
/// \param value
virtual void setIsCurrent(bool value) {m_isCurrent=value;}
/// \brief isCurrent
/// \return if item is the current one
virtual bool isCurrent() const {return m_isCurrent;}
/// \brief paintEvent
///To get Style working on widget and not on all children.
void paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
signals:
/// \brief flowLayoutItemDropped
/// \param listItem: QList with all item dropped.
/// \param bAccept: set it to true to accept drop event.
///Signales when the widget is dropped.
void flowLayoutItemDropped(QList <FlowLayoutItem*> listItem, bool &bAccept);
protected:
void keyPressEvent(QKeyEvent *event){event->ignore();}
void keyReleaseEvent(QKeyEvent *event){event->ignore();}
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
QString m_myName;
bool m_isSelected;
bool m_isCurrent;
private:
void performDrag();
private:
QPoint m_startPos;
};
/// \class FlowLayout
/// \brief The FlowLayout class
///Class FlowLayout arranges child widgets from left to right
///and top to bottom in a top-level widget.
///The items are first laid out horizontally and
///then vertically when each line in the layout runs out of space.
class FlowLayout : public QLayout
{
Q_OBJECT
Q_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
Q_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
Q_PROPERTY(Qt::Orientations expandingDirections READ expandingDirections)
Q_PROPERTY(int count READ count)
Q_PROPERTY(QSize minimumSize READ minimumSize)
Q_PROPERTY(QLayoutItem *currentItem READ currentItem)
Q_PROPERTY(int currentIndex READ currentIndex)
public:
FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayout();
///
/// \brief addItem QLayoutItem
/// \param item
///to add a new item. (normally called by addWidget)
void addItem(QLayoutItem *item);
///
/// \brief addItem FlowLayoutItem
/// \param item
///To add a new FlowLayoutItem item.
void addItem(FlowLayoutItem *item);
///
/// \brief horizontalSpacing
/// \return int
///Returns the horizontal spacing of items in the layout.
int horizontalSpacing() const;
///
/// \brief setHorizontalSpacing
/// \param h
///To set the horizontal spacing of items in the layout.
void setHorizontalSpacing(int &h);
///
/// \brief verticalSpacing
/// \return int
///Returns the vertical spacing of items in the layout.
int verticalSpacing() const;
///
/// \brief setVerticalSpacing
/// \param v
///To set the horizontal spacing of items in the layout.
void setVerticalSpacing(int &v);
///
/// \brief expandingDirections
/// \return Qt::Orientations
///Returns the Qt::Orientations in which the layout can make
/// use of more space than its sizeHint().
Qt::Orientations expandingDirections() const;
///
/// \brief hasHeightForWidth
/// \return bool
///Indicates if heightForWidth() is implemented.
bool hasHeightForWidth() const;
///
/// \brief heightForWidth
/// \return int
///To adjust to widgets of which height is dependent on width.
int heightForWidth(int) const;
///
/// \brief count
/// \return int
///Returns items count.
int count() const;
///
/// \brief itemAt
/// \param index
/// \return QLayoutItem*
///Returns item at index position.
QLayoutItem *itemAt(int index) const;
///
/// \brief itemAtGlobal
/// \param p
/// \return QLayoutItem*
///Returns item at position indicate with p. This position is on global screen coordinates.
QLayoutItem *itemAtGlobal(const QPoint &p) const;
///
/// \brief itemAtParent
/// \param p
/// \return QLayoutItem*
///Returns item at position indicate with p. This position is on parent screen coordinates.
QLayoutItem *itemAtParent(const QPoint &p) const;
///
/// \brief indexAtGlobal
/// \param p
/// \return int
///Returns index of item at position indicate with p. This position is on global screen coordinates.
int indexAtGlobal(const QPoint &p) const;
///
/// \brief indexAtParent
/// \param p
/// \return int
///Returns index of item at position indicate with p. This position is on parent screen coordinates.
int indexAtParent(const QPoint &p) const;
///
/// \brief minimumSize
/// \return QSize
///Returns the minimum size of all child items.
QSize minimumSize() const;
///
/// \brief setGeometry
/// \param rect
///Set the geometry of the layout relative to its parent and excluding the window frame.
///It's for redraw item list when it was resized.
void setGeometry(const QRect &rect);
///
/// \brief sizeHint
/// \return QSize
///Returns recommended (minimum) size.
QSize sizeHint() const;
///
/// \brief takeAt
/// \param index
/// \return QLayoutItem*
///Take an item in list (erase it).
QLayoutItem *takeAt(int index);
///
/// \brief selectionList
/// \return QList<QLayoutItem *>
///Returns the list of selected items.
QList<QLayoutItem *> selectionList() const { return m_selectionList;}
///
/// \brief currentItem
/// \return QLayoutItem *
///Returns the current (only one) item.
QLayoutItem *currentItem() const { return m_itemList.value(m_currentIndex);}
///
/// \brief currentIndex
/// \return int
///Returns index of current item.
int currentIndex() const { return m_currentIndex;}
protected:
bool eventFilter(QObject *obj, QEvent *event);
void unsetCurrent();
void setCurrent();
private:
// Redraw all the layout
int doLayout(const QRect &rect, bool testOnly) const;
//To get the default spacing for either the top-level layouts or the sublayouts.
//The default spacing for top-level layouts, when the parent is a QWidget,
//will be determined by querying the style.
//The default spacing for sublayouts, when the parent is a QLayout,
//will be determined by querying the spacing of the parent layout.
int smartSpacing(QStyle::PixelMetric pm) const;
//Execute drag action.
void performDrag();
//Update selection with m_selStartIndex and m_selStopIndex.
//If invert, item selection is toggled.
void addSelection(bool invert);
QList<QLayoutItem *> m_itemList;
QList<QLayoutItem *> m_selectionList;
int m_selStartIndex;
int m_selStopIndex;
int m_currentIndex;
QPoint m_startPos;
int m_hSpace;
int m_vSpace;
};
///
/// \brief The FlowLayoutWidget class
///Class FlowLayoutWidget provide a simple widget with FlowLayout as layout.
///This could be integrate on QtDesigner
class FlowLayoutWidget : public QWidget
{
Q_OBJECT
public:
FlowLayoutWidget(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
FlowLayoutWidget(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayoutWidget();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
void updateParent();
QScrollArea *m_saParent;
QScrollBar *m_sbVertical;
int m_lastYPos;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,263 @@
/*From version of May 16 2010
ORIGINAL COPYRIGHT HEADER
PictureFlow - animated image show widget
http://pictureflow.googlecode.com
Copyright (C) 2008 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef PICTUREFLOW_H
#define PICTUREFLOW_H
#include <QWidget>
class PictureFlowPrivate;
/// \class PictureFlow
/// \brief The PictureFlow class
///Class PictureFlow implements an image show widget with animation effect
///like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
///of slides, one main slide is shown at the center with few slides on
///the left and right sides of the center slide. When the next or previous
///slide is brought to the front, the whole slides flow to the right or
///the right with smooth animation effect; until the new slide is finally
///placed at the center.
class PictureFlow : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
Q_PROPERTY(QSize slideSize READ slideSize)
Q_PROPERTY(float slideSizeRatio READ slideSizeRatio WRITE setSlideSizeRatio)
Q_PROPERTY(int slideCount READ slideCount)
Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex)
public:
enum ReflectionEffect
{
NoReflection,
PlainReflection,
BlurredReflection
};
///
/// \brief PictureFlow
/// \param parent
///Creates a new PictureFlow widget.
PictureFlow(QWidget* parent = 0);
///
/// \brief ~PictureFlow
///Destroys the widget.
~PictureFlow();
///
/// \brief backgroundColor
/// \return QColor
///Returns the background color.
QColor backgroundColor() const;
///
/// \brief setBackgroundColor
/// \param c
///Sets the background color. By default it is black.
void setBackgroundColor(const QColor& c);
/*!
Returns the dimension of each slide (in pixels).
*/
///
/// \brief slideSize
/// \return QSize
///Returns the dimension of each slide (in pixels).
QSize slideSize() const;
///
/// \brief slideSizeRatio
/// \return float
///Returns the ratio dimension of each slide (Height/Width).
float slideSizeRatio() const;
///
/// \brief setSlideSizeRatio
/// \param ratio
///Sets the ratio of dimension of each slide (in pixels).
void setSlideSizeRatio(float ratio);
///
/// \brief slideCount
/// \return int
///Returns the total number of slides.
int slideCount() const;
///
/// \brief slide
/// \param index
/// \return QImage
///Returns QImage of specified slide.
QImage slide(int index) const;
///
/// \brief slideAt
/// \param point
/// \return int
///Returns QImage of specified slide.
int slideAt(QPoint point) const;
///
/// \brief centerIndex
/// \return int
///Returns the index of slide currently shown in the middle of the viewport.
int centerIndex() const;
///
/// \brief reflectionEffect
/// \return ReflectionEffect
///Returns the effect applied to the reflection.
ReflectionEffect reflectionEffect() const;
///
/// \brief setReflectionEffect
/// \param effect
///Sets the effect applied to the reflection. The default is PlainReflection.
void setReflectionEffect(ReflectionEffect effect);
public slots:
///
/// \brief addSlide
/// \param image QImage of slide
///Adds a new slide.
void addSlide(const QImage& image);
///
/// \brief addSlide
/// \param pixmap QPixmap of slide
///Adds a new slide.
void addSlide(const QPixmap& pixmap);
///
/// \brief setSlide
/// \param index index of slide
/// \param image QImage of slide
///Sets an image for specified slide. If the slide already exists,
///it will be replaced.
void setSlide(int index, const QImage& image);
///
/// \brief setSlide
/// \param index index of slide
/// \param pixmap QPixmap of slide
///Sets a pixmap for specified slide. If the slide already exists,
///it will be replaced.
void setSlide(int index, const QPixmap& pixmap);
///
/// \brief setCenterIndex
/// \param index Index of slide to center
///Sets slide to be shown in the middle of the viewport. No animation
///effect will be produced, unlike using showSlide.
void setCenterIndex(int index);
///
/// \brief clear
///Clears all slides.
void clear();
///
/// \brief showPrevious
///Shows previous slide using animation effect.
void showPrevious();
///
/// \brief showNext
///Shows next slide using animation effect.
void showNext();
///
/// \brief showSlide
/// \param index
///Go to specified slide using animation effect.
void showSlide(int index);
///
/// \brief render
///Rerender the widget. Normally this function will be automatically invoked
///whenever necessary, e.g. during the transition animation.
void render();
///
/// \brief triggerRender
///Schedules a rendering update. Unlike render(), this function does not cause
///immediate rendering.
void triggerRender();
signals:
///
/// \brief centerIndexChanged
/// \param index
///Signals when index was changed.
void centerIndexChanged(int index);
///
/// \brief mouseMoveOverSlideEvent
/// \param event
/// \param slideIndex
///Signals when mouse move over a slide.
void mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex);
///
/// \brief dragEnterEventOccurs
/// \param event
///Signals when a drag enters on a slide.
void dragEnterEventOccurs(QDragEnterEvent *event);
///
/// \brief dragMoveEventOccurs
/// \param event
///Signals when a drag move over a slide.
void dragMoveEventOccurs(QDragMoveEvent *event);
///
/// \brief dropEventOccurs
/// \param event
///Signals when something is dropped on slide.
void dropEventOccurs(QDropEvent *event);
protected:
void paintEvent(QPaintEvent* event);
void keyPressEvent(QKeyEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void resizeEvent(QResizeEvent* event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
private slots:
void updateAnimation();
private:
PictureFlowPrivate* d;
QPoint dragMoveLastPos;
};
#endif // PICTUREFLOW_H

View File

@ -4,8 +4,8 @@ CONFIG += qt gui uic qrc resources idle bitdht
# Plz never commit the .pro with these flags enabled.
# Use this flag when developping new features only.
#
# CONFIG += unfinished
# CONFIG += debug
#CONFIG += unfinished
#CONFIG += debug
#QMAKE_CFLAGS += -fmudflap
#LIBS *= /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflap.a /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflapth.a
@ -474,6 +474,8 @@ HEADERS += rshare.h \
gui/common/UIStateHelper.h \
gui/common/FloatingHelpBrowser.h \
gui/common/SubscribeToolButton.h \
gui/common/FlowLayout.h \
gui/common/PictureFlow.h \
gui/style/RSStyle.h \
gui/style/StyleDialog.h \
gui/MessagesDialog.h \
@ -771,6 +773,8 @@ SOURCES += main.cpp \
gui/common/UIStateHelper.cpp \
gui/common/FloatingHelpBrowser.cpp \
gui/common/SubscribeToolButton.cpp \
gui/common/FlowLayout.cpp \
gui/common/PictureFlow.cpp \
gui/style/RSStyle.cpp \
gui/style/StyleDialog.cpp \
gui/settings/rsharesettings.cpp \
@ -1105,16 +1109,6 @@ gxsthewire {
}
HEADERS += gui/People/PeopleDialog.h
HEADERS += gui/People/IdentityItem.h
HEADERS += gui/People/CircleItem.h
HEADERS += gui/People/GroupListView.h
FORMS += gui/People/PeopleDialog.ui
SOURCES += gui/People/PeopleDialog.cpp
SOURCES += gui/People/GroupListView.cpp
SOURCES += gui/People/IdentityItem.cpp
SOURCES += gui/People/CircleItem.cpp
identities {
HEADERS += \
@ -1143,7 +1137,27 @@ gxscircles {
SOURCES += \
gui/Circles/CirclesDialog.cpp \
gui/Circles/CreateCircleDialog.cpp \
HEADERS += gui/People/PeopleDialog.h
HEADERS += gui/People/CircleWidget.h
HEADERS += gui/People/IdentityWidget.h
FORMS += gui/People/PeopleDialog.ui
FORMS += gui/People/CircleWidget.ui
FORMS += gui/People/IdentityWidget.ui
SOURCES += gui/People/PeopleDialog.cpp
SOURCES += gui/People/CircleWidget.cpp
SOURCES += gui/People/IdentityWidget.cpp
#HEADERS += gui/People/IdentityItem.h
#HEADERS += gui/People/CircleItem.h
#HEADERS += gui/People/GroupListView.h
#SOURCES += gui/People/GroupListView.cpp
#SOURCES += gui/People/IdentityItem.cpp
#SOURCES += gui/People/CircleItem.cpp
}