mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge branch 'master' of https://github.com/RetroShare/RetroShare
This commit is contained in:
commit
217c9b9538
@ -1454,24 +1454,9 @@ int RsDataService::resetDataStore()
|
|||||||
std::cerr << "resetDataStore() " << std::endl;
|
std::cerr << "resetDataStore() " << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<RsGxsGroupId, RsNxsGrp*> grps;
|
|
||||||
|
|
||||||
retrieveNxsGrps(grps, false, false);
|
|
||||||
std::map<RsGxsGroupId, RsNxsGrp*>::iterator mit
|
|
||||||
= grps.begin();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mDbMutex);
|
RsStackMutex stack(mDbMutex);
|
||||||
|
|
||||||
// remove all grp msgs files from service dir
|
|
||||||
for(; mit != grps.end(); ++mit){
|
|
||||||
std::string file = mServiceDir + "/" + mit->first.toStdString();
|
|
||||||
std::string msgFile = file + "-msgs";
|
|
||||||
remove(file.c_str()); // remove group file
|
|
||||||
remove(msgFile.c_str()); // and remove messages file
|
|
||||||
delete mit->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDb->execSQL("DROP INDEX " + MSG_INDEX_GRPID);
|
mDb->execSQL("DROP INDEX " + MSG_INDEX_GRPID);
|
||||||
mDb->execSQL("DROP TABLE " + DATABASE_RELEASE_TABLE_NAME);
|
mDb->execSQL("DROP TABLE " + DATABASE_RELEASE_TABLE_NAME);
|
||||||
mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME);
|
mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME);
|
||||||
|
@ -27,7 +27,9 @@
|
|||||||
#include <QWidgetAction>
|
#include <QWidgetAction>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QtXml>
|
||||||
|
|
||||||
|
#include "rsserver/rsaccounts.h"
|
||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
|
|
||||||
#include "GroupDefs.h"
|
#include "GroupDefs.h"
|
||||||
@ -128,6 +130,8 @@ FriendList::FriendList(QWidget *parent) :
|
|||||||
connect(ui->actionHideOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setHideUnconnected(bool)));
|
connect(ui->actionHideOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setHideUnconnected(bool)));
|
||||||
connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)));
|
connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)));
|
||||||
connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)));
|
connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)));
|
||||||
|
connect(ui->actionExportFriendlist, SIGNAL(triggered()), this, SLOT(exportFriendlistClicked()));
|
||||||
|
connect(ui->actionImportFriendlist, SIGNAL(triggered()), this, SLOT(importFriendlistClicked()));
|
||||||
|
|
||||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
|
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
|
||||||
|
|
||||||
@ -1744,6 +1748,413 @@ void FriendList::removeGroup()
|
|||||||
rsPeers->removeGroup(groupId);
|
rsPeers->removeGroup(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FriendList::exportFriendlistClicked()
|
||||||
|
{
|
||||||
|
QString fileName;
|
||||||
|
if(!importExportFriendlistFileDialog(fileName, false))
|
||||||
|
// error was already shown - just return
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!exportFriendlist(fileName))
|
||||||
|
// error was already shown - just return
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Information);
|
||||||
|
mbox.setText(tr("Done!"));
|
||||||
|
mbox.setInformativeText(tr("Your friendlist is stored at:\n") + fileName +
|
||||||
|
tr("\n(keep in mind that the file is unencrypted!)"));
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FriendList::importFriendlistClicked()
|
||||||
|
{
|
||||||
|
QString fileName;
|
||||||
|
if(!importExportFriendlistFileDialog(fileName, true))
|
||||||
|
// error was already shown - just return
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool errorPeers, errorGroups;
|
||||||
|
if(importFriendlist(fileName, errorPeers, errorGroups)) {
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Information);
|
||||||
|
mbox.setText(tr("Done!"));
|
||||||
|
mbox.setInformativeText(tr("Your friendlist was imported from:\n") + fileName);
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
} else {
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Warning);
|
||||||
|
mbox.setText(tr("Done - but errors happened!"));
|
||||||
|
mbox.setInformativeText(tr("Your friendlist was imported from:\n") + fileName +
|
||||||
|
(errorPeers ? tr("\nat least one peer was not added") : "") +
|
||||||
|
(errorGroups ? tr("\nat least one peer was not added to a group") : "")
|
||||||
|
);
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief opens a file dialog to select a file containing a friendlist
|
||||||
|
* @param fileName file containing a friendlist
|
||||||
|
* @param import show dialog for importing (true) or exporting (false) friendlist
|
||||||
|
* @return success or failure
|
||||||
|
*
|
||||||
|
* This function also shows an error message when no valid file was selected
|
||||||
|
*/
|
||||||
|
bool FriendList::importExportFriendlistFileDialog(QString &fileName, bool import)
|
||||||
|
{
|
||||||
|
if(!misc::getSaveFileName(this,
|
||||||
|
RshareSettings::LASTDIR_CERT,
|
||||||
|
(import ? tr("Select file for importing yoour friendlist from") :
|
||||||
|
tr("Select a file for exporting your friendlist to")),
|
||||||
|
tr("XML File (*.xml);;All Files (*)"),
|
||||||
|
fileName,
|
||||||
|
NULL,
|
||||||
|
(import ? QFileDialog::DontConfirmOverwrite : (QFileDialog::Options)0)
|
||||||
|
)) {
|
||||||
|
// show error to user
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Warning);
|
||||||
|
mbox.setText(tr("Error"));
|
||||||
|
mbox.setInformativeText(tr("Failed to get a file!"));
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief exports friendlist to a given file
|
||||||
|
* @param fileName file for storing friendlist
|
||||||
|
* @return success or failure
|
||||||
|
*
|
||||||
|
* This function also shows an error message when the selected file is invalid/not writable
|
||||||
|
*/
|
||||||
|
bool FriendList::exportFriendlist(QString &fileName)
|
||||||
|
{
|
||||||
|
QDomDocument doc("FriendListWithGroups");
|
||||||
|
QDomElement root = doc.createElement("root");
|
||||||
|
doc.appendChild(root);
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
|
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
||||||
|
// show error to user
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Warning);
|
||||||
|
mbox.setText(tr("Error"));
|
||||||
|
mbox.setInformativeText(tr("File is not writeable!\n") + fileName);
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<RsPgpId> gpg_ids;
|
||||||
|
rsPeers->getGPGAcceptedList(gpg_ids);
|
||||||
|
|
||||||
|
std::list<RsGroupInfo> group_info_list;
|
||||||
|
rsPeers->getGroupInfoList(group_info_list);
|
||||||
|
|
||||||
|
QDomElement pgpIDs = doc.createElement("pgpIDs");
|
||||||
|
RsPeerDetails detailPGP;
|
||||||
|
for(std::list<RsPgpId>::iterator list_iter = gpg_ids.begin(); list_iter != gpg_ids.end(); list_iter++) {
|
||||||
|
rsPeers->getGPGDetails(*list_iter, detailPGP);
|
||||||
|
QDomElement pgpID = doc.createElement("pgpID");
|
||||||
|
// these values aren't used and just stored for better human readability
|
||||||
|
pgpID.setAttribute("id", QString::fromStdString(detailPGP.gpg_id.toStdString()));
|
||||||
|
pgpID.setAttribute("name", QString::fromUtf8(detailPGP.name.c_str()));
|
||||||
|
|
||||||
|
std::list<RsPeerId> ssl_ids;
|
||||||
|
rsPeers->getAssociatedSSLIds(*list_iter, ssl_ids);
|
||||||
|
for(std::list<RsPeerId>::iterator list_iter = ssl_ids.begin(); list_iter != ssl_ids.end(); list_iter++) {
|
||||||
|
RsPeerDetails detailSSL;
|
||||||
|
if (!rsPeers->getPeerDetails(*list_iter, detailSSL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string certificate = rsPeers->GetRetroshareInvite(detailSSL.id, true);
|
||||||
|
// remove \n from certificate
|
||||||
|
certificate.erase(std::remove(certificate.begin(), certificate.end(), '\n'), certificate.end());
|
||||||
|
|
||||||
|
QDomElement sslID = doc.createElement("sslID");
|
||||||
|
// these values aren't used and just stored for better human readability
|
||||||
|
sslID.setAttribute("sslID", QString::fromStdString(detailSSL.id.toStdString()));
|
||||||
|
if(!detailSSL.location.empty())
|
||||||
|
sslID.setAttribute("location", QString::fromUtf8(detailSSL.location.c_str()));
|
||||||
|
|
||||||
|
// required values
|
||||||
|
sslID.setAttribute("certificate", QString::fromStdString(certificate));
|
||||||
|
sslID.setAttribute("service_perm_flags", detailSSL.service_perm_flags.toUInt32());
|
||||||
|
|
||||||
|
pgpID.appendChild(sslID);
|
||||||
|
}
|
||||||
|
pgpIDs.appendChild(pgpID);
|
||||||
|
}
|
||||||
|
root.appendChild(pgpIDs);
|
||||||
|
|
||||||
|
QDomElement groups = doc.createElement("groups");
|
||||||
|
for(std::list<RsGroupInfo>::iterator list_iter = group_info_list.begin(); list_iter != group_info_list.end(); list_iter++) {
|
||||||
|
RsGroupInfo group_info = *list_iter;
|
||||||
|
|
||||||
|
//skip groups without peers
|
||||||
|
if(group_info.peerIds.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QDomElement group = doc.createElement("group");
|
||||||
|
// id is not needed since it may differ between locatiosn / pgp ids (groups are identified by name)
|
||||||
|
group.setAttribute("name", QString::fromUtf8(group_info.name.c_str()));
|
||||||
|
group.setAttribute("flag", group_info.flag);
|
||||||
|
|
||||||
|
for(std::set<RsPgpId>::iterator i = group_info.peerIds.begin(); i != group_info.peerIds.end(); i++) {
|
||||||
|
QDomElement pgpID = doc.createElement("pgpID");
|
||||||
|
std::string pid = i->toStdString();
|
||||||
|
pgpID.setAttribute("id", QString::fromStdString(pid));
|
||||||
|
group.appendChild(pgpID);
|
||||||
|
}
|
||||||
|
groups.appendChild(group);
|
||||||
|
}
|
||||||
|
root.appendChild(groups);
|
||||||
|
|
||||||
|
QTextStream ts(&file);
|
||||||
|
ts.setCodec("UTF-8");
|
||||||
|
ts << doc.toString();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief helper function to show a message box
|
||||||
|
*/
|
||||||
|
void showXMLParsingError()
|
||||||
|
{
|
||||||
|
// show error to user
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Warning);
|
||||||
|
mbox.setText(QObject::tr("Error"));
|
||||||
|
mbox.setInformativeText(QObject::tr("unable to parse XML file!"));
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Imports friends from a given file
|
||||||
|
* @param fileName file to load friends from
|
||||||
|
* @param errorPeers an error occured while adding a peer
|
||||||
|
* @param errorGroups an error occured while adding a peer to a group
|
||||||
|
* @return success or failure (an error can also happen when adding a peer and/or adding a peer to a group fails at least once)
|
||||||
|
*/
|
||||||
|
bool FriendList::importFriendlist(QString &fileName, bool &errorPeers, bool &errorGroups)
|
||||||
|
{
|
||||||
|
QDomDocument doc;
|
||||||
|
// load from file
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
// show error to user
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setIcon(QMessageBox::Warning);
|
||||||
|
mbox.setText(tr("Error"));
|
||||||
|
mbox.setInformativeText(tr("File is not readable!\n") + fileName);
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.exec();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = doc.setContent(&file);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if(!ok) {
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomElement root = doc.documentElement();
|
||||||
|
if(root.tagName() != "root") {
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorPeers = false;
|
||||||
|
errorGroups = false;
|
||||||
|
|
||||||
|
uint32_t error_code;
|
||||||
|
std::string error_string;
|
||||||
|
RsPeerDetails rsPeerDetails;
|
||||||
|
RsPeerId rsPeerID;
|
||||||
|
RsPgpId rsPgpID;
|
||||||
|
|
||||||
|
// lock all events for faster processing
|
||||||
|
RsAutoUpdatePage::lockAllEvents();
|
||||||
|
|
||||||
|
// pgp and ssl IDs
|
||||||
|
QDomElement pgpIDs;
|
||||||
|
{
|
||||||
|
QDomNodeList nodes = root.elementsByTagName("pgpIDs");
|
||||||
|
if(nodes.isEmpty() || nodes.size() != 1){
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pgpIDs = nodes.item(0).toElement();
|
||||||
|
if(pgpIDs.isNull()){
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomNode pgpIDElem = pgpIDs.firstChildElement("pgpID");
|
||||||
|
while (!pgpIDElem.isNull()) {
|
||||||
|
QDomElement sslIDElem = pgpIDElem.firstChildElement("sslID");
|
||||||
|
while (!sslIDElem.isNull()) {
|
||||||
|
rsPeerID.clear();
|
||||||
|
rsPgpID.clear();
|
||||||
|
|
||||||
|
// load everything needed from the pubkey string
|
||||||
|
std::string pubkey = sslIDElem.attribute("certificate").toStdString();
|
||||||
|
if(rsPeers->loadDetailsFromStringCert(pubkey, rsPeerDetails, error_code)) {
|
||||||
|
if(rsPeers->loadCertificateFromString(pubkey, rsPeerID, rsPgpID, error_string)) {
|
||||||
|
ServicePermissionFlags service_perm_flags(sslIDElem.attribute("service_perm_flags").toInt());
|
||||||
|
|
||||||
|
// everything is loaded - start setting things
|
||||||
|
if (!rsPeerDetails.id.isNull() && !rsPeerDetails.gpg_id.isNull()) {
|
||||||
|
// pgp and ssl ID are available
|
||||||
|
rsPeers->addFriend(rsPeerDetails.id, rsPeerDetails.gpg_id, service_perm_flags);
|
||||||
|
if(rsPeerDetails.isHiddenNode) {
|
||||||
|
// for hidden notes
|
||||||
|
if (!rsPeerDetails.hiddenNodeAddress.empty() && rsPeerDetails.hiddenNodePort)
|
||||||
|
rsPeers->setHiddenNode(rsPeerDetails.id, rsPeerDetails.hiddenNodeAddress, rsPeerDetails.hiddenNodePort);
|
||||||
|
} else {
|
||||||
|
// for normal nodes
|
||||||
|
if (!rsPeerDetails.extAddr.empty() && rsPeerDetails.extPort)
|
||||||
|
rsPeers->setExtAddress(rsPeerDetails.id, rsPeerDetails.extAddr, rsPeerDetails.extPort);
|
||||||
|
if (!rsPeerDetails.localAddr.empty() && rsPeerDetails.localPort)
|
||||||
|
rsPeers->setLocalAddress(rsPeerDetails.id, rsPeerDetails.localAddr, rsPeerDetails.localPort);
|
||||||
|
if (!rsPeerDetails.dyndns.empty())
|
||||||
|
rsPeers->setDynDNS(rsPeerDetails.id, rsPeerDetails.dyndns);
|
||||||
|
if (!rsPeerDetails.location.empty())
|
||||||
|
rsPeers->setLocation(rsPeerDetails.id, rsPeerDetails.location);
|
||||||
|
}
|
||||||
|
} else if (!rsPeerDetails.gpg_id.isNull()) {
|
||||||
|
// only pgp id is avaiable
|
||||||
|
RsPeerId pid;
|
||||||
|
rsPeers->addFriend(pid, rsPeerDetails.gpg_id, service_perm_flags);
|
||||||
|
} else {
|
||||||
|
errorPeers = true;
|
||||||
|
std::cerr << "FriendList::importFriendlist(): error while processing SSL id: " << sslIDElem.attribute("sslID", "invalid").toStdString() << std::endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorPeers = true;
|
||||||
|
std::cerr << "FriendList::importFriendlist(): failed to get peer detaisl from public key (SSL id: " << sslIDElem.attribute("sslID", "invalid").toStdString() << " - error: " << error_string << ")" << std::endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorPeers = true;
|
||||||
|
std::cerr << "FriendList::importFriendlist(): failed to get peer detaisl from public key (SSL id: " << sslIDElem.attribute("sslID", "invalid").toStdString() << " - error: " << error_code << ")" << std::endl;
|
||||||
|
}
|
||||||
|
sslIDElem = sslIDElem.nextSiblingElement("sslID");
|
||||||
|
}
|
||||||
|
pgpIDElem = pgpIDElem.nextSiblingElement("pgpID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// groups
|
||||||
|
QDomElement groups;
|
||||||
|
{
|
||||||
|
QDomNodeList nodes = root.elementsByTagName("groups");
|
||||||
|
if(nodes.isEmpty() || nodes.size() != 1){
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
groups = nodes.item(0).toElement();
|
||||||
|
if(groups.isNull()){
|
||||||
|
showXMLParsingError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomElement group = groups.firstChildElement("group");
|
||||||
|
while (!group.isNull()) {
|
||||||
|
// get name and flags and try to get the group ID
|
||||||
|
std::string groupName = group.attribute("name").toStdString();
|
||||||
|
uint32_t flag = group.attribute("flag").toInt();
|
||||||
|
std::string groupId;
|
||||||
|
if(getOrCreateGroup(groupName, flag, groupId)) {
|
||||||
|
// group id found!
|
||||||
|
QDomElement pgpID = group.firstChildElement("pgpID");
|
||||||
|
while (!pgpID.isNull()) {
|
||||||
|
// add pgp id to group
|
||||||
|
RsPgpId rsPgpId(pgpID.attribute("id").toStdString());
|
||||||
|
if(rsPgpID.isNull() || !rsPeers->assignPeerToGroup(groupId, rsPgpId, true)) {
|
||||||
|
errorGroups = true;
|
||||||
|
std::cerr << "FriendList::importFriendlist(): failed to add '" << rsPeers->getGPGName(rsPgpId) << "'' to group '" << groupName << "'" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
pgpID = pgpID.nextSiblingElement("pgpID");
|
||||||
|
}
|
||||||
|
pgpID = pgpID.nextSiblingElement("pgpID");
|
||||||
|
} else {
|
||||||
|
errorGroups = true;
|
||||||
|
std::cerr << "FriendList::importFriendlist(): failed to find/create group '" << groupName << "'" << std::endl;
|
||||||
|
}
|
||||||
|
group = group.nextSiblingElement("group");
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlock events
|
||||||
|
RsAutoUpdatePage::unlockAllEvents();
|
||||||
|
|
||||||
|
return !(errorPeers || errorGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the groups ID for a given group name
|
||||||
|
* @param name group name to search for
|
||||||
|
* @param id groupd id for the given name
|
||||||
|
* @return success or fail
|
||||||
|
*/
|
||||||
|
bool FriendList::getGroupIdByName(const std::string &name, std::string &id)
|
||||||
|
{
|
||||||
|
std::list<RsGroupInfo> grpList;
|
||||||
|
if(!rsPeers->getGroupInfoList(grpList))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (const RsGroupInfo &grp, grpList) {
|
||||||
|
if(grp.name == name) {
|
||||||
|
id = grp.id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the groups ID for a given group name. If no groupd was it will create one
|
||||||
|
* @param name group name to search for
|
||||||
|
* @param flag flag to use when creating the group
|
||||||
|
* @param id groupd id
|
||||||
|
* @return success or failure
|
||||||
|
*/
|
||||||
|
bool FriendList::getOrCreateGroup(const std::string &name, const uint &flag, std::string &id)
|
||||||
|
{
|
||||||
|
if(getGroupIdByName(name, id))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// -> create one
|
||||||
|
RsGroupInfo grp;
|
||||||
|
grp.id = "0"; // RS will generate an ID
|
||||||
|
grp.name = name;
|
||||||
|
grp.flag = flag;
|
||||||
|
|
||||||
|
if(!rsPeers->addGroup(grp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// try again
|
||||||
|
return getGroupIdByName(name, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FriendList::setHideUnconnected(bool hidden)
|
void FriendList::setHideUnconnected(bool hidden)
|
||||||
{
|
{
|
||||||
if (mHideUnconnected != hidden) {
|
if (mHideUnconnected != hidden) {
|
||||||
@ -1878,6 +2289,8 @@ void FriendList::createDisplayMenu()
|
|||||||
displayMenu->addAction(ui->actionHideOfflineFriends);
|
displayMenu->addAction(ui->actionHideOfflineFriends);
|
||||||
displayMenu->addAction(ui->actionShowState);
|
displayMenu->addAction(ui->actionShowState);
|
||||||
displayMenu->addAction(ui->actionShowGroups);
|
displayMenu->addAction(ui->actionShowGroups);
|
||||||
|
displayMenu->addAction(ui->actionExportFriendlist);
|
||||||
|
displayMenu->addAction(ui->actionImportFriendlist);
|
||||||
|
|
||||||
ui->displayButton->setMenu(displayMenu);
|
ui->displayButton->setMenu(displayMenu);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,13 @@ private:
|
|||||||
QTreeWidgetItem *getCurrentPeer() const;
|
QTreeWidgetItem *getCurrentPeer() const;
|
||||||
void getSslIdsFromItem(QTreeWidgetItem *item, std::list<RsPeerId> &sslIds);
|
void getSslIdsFromItem(QTreeWidgetItem *item, std::list<RsPeerId> &sslIds);
|
||||||
|
|
||||||
|
bool getOrCreateGroup(const std::string &name, const uint &flag, std::string &id);
|
||||||
|
bool getGroupIdByName(const std::string &name, std::string &id);
|
||||||
|
|
||||||
|
bool importExportFriendlistFileDialog(QString &fileName, bool import);
|
||||||
|
bool exportFriendlist(QString &fileName);
|
||||||
|
bool importFriendlist(QString &fileName, bool &errorPeers, bool &errorGroups);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void groupsChanged();
|
void groupsChanged();
|
||||||
void insertPeers();
|
void insertPeers();
|
||||||
@ -160,6 +167,9 @@ private slots:
|
|||||||
void editGroup();
|
void editGroup();
|
||||||
void removeGroup();
|
void removeGroup();
|
||||||
|
|
||||||
|
void exportFriendlistClicked();
|
||||||
|
void importFriendlistClicked();
|
||||||
|
|
||||||
// void inviteToLobby();
|
// void inviteToLobby();
|
||||||
// void createchatlobby();
|
// void createchatlobby();
|
||||||
// void unsubscribeToLobby();
|
// void unsubscribeToLobby();
|
||||||
|
@ -14,7 +14,16 @@
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</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>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@ -29,7 +38,16 @@
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<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>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@ -95,7 +113,7 @@
|
|||||||
<string>Friend nodes</string>
|
<string>Friend nodes</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textAlignment">
|
<property name="textAlignment">
|
||||||
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
|
<set>AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
<column>
|
<column>
|
||||||
@ -141,6 +159,22 @@
|
|||||||
<string>Show Groups</string>
|
<string>Show Groups</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionExportFriendlist">
|
||||||
|
<property name="text">
|
||||||
|
<string>export friendlist</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>export your friendlist including groups</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionImportFriendlist">
|
||||||
|
<property name="text">
|
||||||
|
<string>import friendlist</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>import your friendlist including groups</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -73,6 +73,7 @@ GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *p
|
|||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
mInitialized = false;
|
mInitialized = false;
|
||||||
|
mInFill = false;
|
||||||
mCountChildMsgs = false;
|
mCountChildMsgs = false;
|
||||||
mYourGroups = NULL;
|
mYourGroups = NULL;
|
||||||
mSubscribedGroups = NULL;
|
mSubscribedGroups = NULL;
|
||||||
@ -555,6 +556,10 @@ GxsCommentDialog *GxsGroupFrameDialog::commentWidget(const RsGxsMessageId &msgId
|
|||||||
|
|
||||||
void GxsGroupFrameDialog::changedGroup(const QString &groupId)
|
void GxsGroupFrameDialog::changedGroup(const QString &groupId)
|
||||||
{
|
{
|
||||||
|
if (mInFill) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mGroupId = RsGxsGroupId(groupId.toStdString());
|
mGroupId = RsGxsGroupId(groupId.toStdString());
|
||||||
if (mGroupId.isNull()) {
|
if (mGroupId.isNull()) {
|
||||||
return;
|
return;
|
||||||
@ -689,6 +694,8 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list<RsGroupMetaData> &gro
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInFill = true;
|
||||||
|
|
||||||
std::list<RsGroupMetaData>::const_iterator it;
|
std::list<RsGroupMetaData>::const_iterator it;
|
||||||
|
|
||||||
QList<GroupItemInfo> adminList;
|
QList<GroupItemInfo> adminList;
|
||||||
@ -752,6 +759,8 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list<RsGroupMetaData> &gro
|
|||||||
ui->groupTreeWidget->fillGroupItems(mPopularGroups, popList);
|
ui->groupTreeWidget->fillGroupItems(mPopularGroups, popList);
|
||||||
ui->groupTreeWidget->fillGroupItems(mOtherGroups, otherList);
|
ui->groupTreeWidget->fillGroupItems(mOtherGroups, otherList);
|
||||||
|
|
||||||
|
mInFill = false;
|
||||||
|
|
||||||
/* Re-fill group */
|
/* Re-fill group */
|
||||||
if (!ui->groupTreeWidget->activateId(QString::fromStdString(mGroupId.toStdString()), true)) {
|
if (!ui->groupTreeWidget->activateId(QString::fromStdString(mGroupId.toStdString()), true)) {
|
||||||
mGroupId.clear();
|
mGroupId.clear();
|
||||||
|
@ -175,6 +175,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
|
bool mInFill;
|
||||||
QString mSettingsName;
|
QString mSettingsName;
|
||||||
RsGxsGroupId mGroupId;
|
RsGxsGroupId mGroupId;
|
||||||
RsGxsIfaceHelper *mInterface;
|
RsGxsIfaceHelper *mInterface;
|
||||||
|
Loading…
Reference in New Issue
Block a user