Merge branch 'master' into qmlapp_pex_alpha
@ -97,6 +97,7 @@ install:
|
||||
# Install toolchain
|
||||
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain" #Already installed
|
||||
# Install other binutils
|
||||
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-curl mingw-w64-x86_64-curl"
|
||||
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-miniupnpc mingw-w64-x86_64-miniupnpc"
|
||||
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-sqlite3 mingw-w64-x86_64-sqlite3"
|
||||
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-speex mingw-w64-x86_64-speex"
|
||||
|
@ -266,7 +266,7 @@ libs/curl-$(CURL_VERSION): $(DOWNLOAD_PATH)/curl-$(CURL_VERSION).tar.gz
|
||||
sqlcipher: libs/sqlcipher-$(SQLCIPHER_VERSION)
|
||||
|
||||
$(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz:
|
||||
wget http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -O $(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz
|
||||
wget --no-check-certificate http://downloads.sourceforge.net/project/tcl/Tcl/$(TCL_VERSION)/tcl$(TCL_VERSION)-src.tar.gz -O $(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz
|
||||
|
||||
$(DOWNLOAD_PATH)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz:
|
||||
wget --no-check-certificate https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -O $(DOWNLOAD_PATH)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz
|
||||
|
@ -443,8 +443,10 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
|
||||
}
|
||||
}
|
||||
|
||||
if(hidden_port)
|
||||
RsInit::SetHiddenLocation(hidden_address, hidden_port);
|
||||
if(hidden_port) {
|
||||
/// TODO add bob to webui
|
||||
RsInit::SetHiddenLocation(hidden_address, hidden_port, false);
|
||||
}
|
||||
|
||||
std::string ssl_password = RSRandom::random_alphaNumericString(RsInit::getSslPwdLen()) ;
|
||||
|
||||
|
@ -349,7 +349,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
||||
uint32_t sz = _serializer->size(ci);
|
||||
std::vector<uint8_t> data; data.resize(sz);
|
||||
_serializer->serialise(ci, &data[0], &sz);
|
||||
mGxsTransport.sendMail(tId, GxsTransSubServices::P3_CHAT_SERVICE,
|
||||
mGxsTransport.sendData(tId, GxsTransSubServices::P3_CHAT_SERVICE,
|
||||
de.from, de.to, &data[0], sz);
|
||||
}
|
||||
else
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
//#define DEBUG_CHACHA20
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define AEAD_chacha20_poly1305_openssl AEAD_chacha20_poly1305
|
||||
#else
|
||||
#define AEAD_chacha20_poly1305_rs AEAD_chacha20_poly1305
|
||||
@ -386,7 +386,7 @@ void chacha20_encrypt_rs(uint8_t key[32], uint32_t block_counter, uint8_t nonce[
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
void chacha20_encrypt_openssl(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
@ -577,7 +577,7 @@ bool AEAD_chacha20_poly1305_rs(uint8_t key[32], uint8_t nonce[12],uint8_t *data,
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define errorOut {ret = false; goto out;}
|
||||
|
||||
bool AEAD_chacha20_poly1305_openssl(uint8_t key[32], uint8_t nonce[12], uint8_t *data, uint32_t data_size, uint8_t *aad, uint32_t aad_size, uint8_t tag[16], bool encrypt_or_decrypt)
|
||||
@ -667,7 +667,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
||||
|
||||
if(encrypt)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
chacha20_encrypt_rs(key,1,nonce,data,data_size);
|
||||
#else
|
||||
chacha20_encrypt_openssl(key, 1, nonce, data, data_size);
|
||||
@ -676,7 +676,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
||||
uint8_t computed_tag[EVP_MAX_MD_SIZE];
|
||||
unsigned int md_size ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
HMAC_CTX hmac_ctx ;
|
||||
HMAC_CTX_init(&hmac_ctx) ;
|
||||
|
||||
@ -709,7 +709,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
||||
uint8_t computed_tag[EVP_MAX_MD_SIZE];
|
||||
unsigned int md_size ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
HMAC_CTX hmac_ctx ;
|
||||
HMAC_CTX_init(&hmac_ctx) ;
|
||||
|
||||
@ -733,7 +733,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
||||
|
||||
// decrypt
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
chacha20_encrypt_rs(key,1,nonce,data,data_size);
|
||||
#else
|
||||
chacha20_encrypt_openssl(key, 1, nonce, data, data_size);
|
||||
@ -1396,7 +1396,7 @@ bool perform_tests()
|
||||
|
||||
std::cerr << " AEAD/poly1305 own encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
{
|
||||
RsScopeTimer s("AEAD3") ;
|
||||
AEAD_chacha20_poly1305_openssl(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ;
|
||||
|
@ -1624,11 +1624,18 @@ Sha1CheckSum p3GRouter::computeDataItemHash(RsGRouterGenericDataItem *data_item)
|
||||
RsTemporaryMemory mem(total_size) ;
|
||||
|
||||
uint32_t offset = 0 ;
|
||||
signature_serializer.serialise(data_item,mem,&total_size) ;
|
||||
offset += signed_data_size ;
|
||||
uint32_t tmp_size = total_size ;
|
||||
signature_serializer.serialise(data_item,mem,&tmp_size) ;
|
||||
if(tmp_size != signed_data_size)
|
||||
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
||||
|
||||
offset += tmp_size ;
|
||||
|
||||
data_item->signature.SetTlv(mem, total_size,&offset) ;
|
||||
|
||||
if(offset != total_size)
|
||||
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
||||
|
||||
return RsDirUtil::sha1sum(mem,total_size) ;
|
||||
}
|
||||
|
||||
@ -1983,7 +1990,7 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
|
||||
std::cerr << "Created signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key id=" << signing_id << std::endl;
|
||||
//#endif
|
||||
// Check signature
|
||||
RsIdentityUsage::UsageCode info;
|
||||
RsIdentityUsage::UsageCode info = RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CREATION;
|
||||
uint32_t error;
|
||||
|
||||
if(verifySignedDataItem(item,info,error))
|
||||
|
@ -41,7 +41,7 @@ static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE = 256 ;
|
||||
|
||||
static RsGxsId getRsaKeyFingerprint_old_insecure_method(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int lenn = BN_num_bytes(pubkey -> n);
|
||||
|
||||
RsTemporaryMemory tmp(lenn) ;
|
||||
@ -65,7 +65,7 @@ static RsGxsId getRsaKeyFingerprint_old_insecure_method(RSA *pubkey)
|
||||
}
|
||||
static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int lenn = BN_num_bytes(pubkey -> n);
|
||||
int lene = BN_num_bytes(pubkey -> e);
|
||||
|
||||
@ -359,7 +359,7 @@ bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvP
|
||||
ok &= EVP_SignUpdate(mdctx, data, data_len) == 1;
|
||||
|
||||
unsigned int siglen = EVP_PKEY_size(key_priv);
|
||||
unsigned char sigbuf[siglen];
|
||||
unsigned char sigbuf[siglen] = { 0 };
|
||||
ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_priv) == 1;
|
||||
|
||||
// clean up
|
||||
|
@ -1576,11 +1576,20 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req)
|
||||
req->mGroupStatistic.mNumChildMsgsNew = 0;
|
||||
req->mGroupStatistic.mNumChildMsgsUnread = 0;
|
||||
|
||||
std::set<RsGxsMessageId> obsolete_msgs ; // stored message ids that are referred to as older versions of an existing message
|
||||
|
||||
for(uint32_t i = 0; i < msgMetaV.size(); ++i)
|
||||
if(!msgMetaV[i]->mOrigMsgId.isNull() && msgMetaV[i]->mOrigMsgId!=msgMetaV[i]->mMsgId)
|
||||
obsolete_msgs.insert(msgMetaV[i]->mOrigMsgId);
|
||||
|
||||
for(uint32_t i = 0; i < msgMetaV.size(); ++i)
|
||||
{
|
||||
RsGxsMsgMetaData* m = msgMetaV[i];
|
||||
req->mGroupStatistic.mTotalSizeOfMsgs += m->mMsgSize + m->serial_size();
|
||||
|
||||
if(obsolete_msgs.find(m->mMsgId) != obsolete_msgs.end()) // skip obsolete messages.
|
||||
continue;
|
||||
|
||||
if (IS_MSG_NEW(m->mMsgStatus))
|
||||
{
|
||||
if (m->mParentId.isNull())
|
||||
|
@ -16,11 +16,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "gxstrans/p3gxstrans.h"
|
||||
#include "util/stacktrace.h"
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
RsGxsTrans *rsGxsTrans = NULL ;
|
||||
|
||||
p3GxsTrans::~p3GxsTrans()
|
||||
{
|
||||
p3Config::saveConfiguration();
|
||||
@ -31,7 +34,36 @@ p3GxsTrans::~p3GxsTrans()
|
||||
}
|
||||
}
|
||||
|
||||
bool p3GxsTrans::sendMail( RsGxsTransId& mailId,
|
||||
bool p3GxsTrans::getStatistics(GxsTransStatistics& stats)
|
||||
{
|
||||
stats.prefered_group_id = mPreferredGroupId;
|
||||
stats.outgoing_records.clear();
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mOutgoingMutex);
|
||||
|
||||
for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); ++it)
|
||||
{
|
||||
const OutgoingRecord& pr(it->second);
|
||||
|
||||
RsGxsTransOutgoingRecord rec ;
|
||||
rec.status = pr.status ;
|
||||
rec.send_TS = pr.mailItem.meta.mPublishTs ;
|
||||
rec.group_id = pr.mailItem.meta.mGroupId ;
|
||||
rec.trans_id = pr.mailItem.mailId ;
|
||||
rec.recipient = pr.recipient ;
|
||||
rec.data_size = pr.mailData.size();
|
||||
rec.data_hash = RsDirUtil::sha1sum(pr.mailData.data(),pr.mailData.size());
|
||||
rec.client_service = pr.clientService ;
|
||||
|
||||
stats.outgoing_records.push_back(rec) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsTrans::sendData( RsGxsTransId& mailId,
|
||||
GxsTransSubServices service,
|
||||
const RsGxsId& own_gxsid, const RsGxsId& recipient,
|
||||
const uint8_t* data, uint32_t size,
|
||||
@ -55,7 +87,10 @@ bool p3GxsTrans::sendMail( RsGxsTransId& mailId,
|
||||
}
|
||||
|
||||
OutgoingRecord pr( recipient, service, data, size );
|
||||
|
||||
pr.mailItem.clear();
|
||||
pr.mailItem.meta.mAuthorId = own_gxsid;
|
||||
pr.mailItem.meta.mMsgId.clear();
|
||||
pr.mailItem.cryptoType = cm;
|
||||
pr.mailItem.mailId = RSRandom::random_u64();
|
||||
|
||||
@ -120,9 +155,9 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type)
|
||||
&& meta.mGroupId != mPreferredGroupId;
|
||||
|
||||
if(shoudlSubscribe)
|
||||
subscribeToGroup(token, meta.mGroupId, true);
|
||||
RsGenExchange::subscribeToGroup(token, meta.mGroupId, true);
|
||||
else if(shoudlUnSubscribe)
|
||||
subscribeToGroup(token, meta.mGroupId, false);
|
||||
RsGenExchange::subscribeToGroup(token, meta.mGroupId, false);
|
||||
|
||||
#ifdef GXS_MAIL_GRP_DEBUG
|
||||
char buff[30];
|
||||
@ -220,10 +255,113 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type)
|
||||
}
|
||||
}
|
||||
|
||||
void p3GxsTrans::GxsTransIntegrityCleanupThread::run()
|
||||
{
|
||||
// first take out all the groups
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grp;
|
||||
mDs->retrieveNxsGrps(grp, true, true);
|
||||
|
||||
std::cerr << "GxsTransIntegrityCleanupThread::run()" << std::endl;
|
||||
|
||||
// compute hash and compare to stored value, if it fails then simply add it
|
||||
// to list
|
||||
|
||||
GxsMsgReq grps;
|
||||
for(std::map<RsGxsGroupId, RsNxsGrp*>::iterator git = grp.begin(); git != grp.end(); ++git)
|
||||
{
|
||||
RsNxsGrp* grp = git->second;
|
||||
|
||||
// store the group for retrieveNxsMsgs
|
||||
grps[grp->grpId];
|
||||
|
||||
delete grp;
|
||||
}
|
||||
|
||||
// now messages
|
||||
|
||||
std::map<RsGxsTransId,std::pair<RsGxsGroupId,RsGxsMessageId> > stored_msgs ;
|
||||
std::list<RsGxsTransId> received_msgs ;
|
||||
|
||||
GxsMsgResult msgs;
|
||||
mDs->retrieveNxsMsgs(grps, msgs, false, true);
|
||||
|
||||
for(GxsMsgResult::iterator mit = msgs.begin();mit != msgs.end(); ++mit)
|
||||
{
|
||||
std::vector<RsNxsMsg*>& msgV = mit->second;
|
||||
std::vector<RsNxsMsg*>::iterator vit = msgV.begin();
|
||||
|
||||
for(; vit != msgV.end(); ++vit)
|
||||
{
|
||||
RsNxsMsg* msg = *vit;
|
||||
|
||||
RsGxsTransSerializer s ;
|
||||
uint32_t size = msg->msg.bin_len;
|
||||
RsItem *item = s.deserialise(msg->msg.bin_data,&size);
|
||||
RsGxsTransMailItem *mitem ;
|
||||
RsGxsTransPresignedReceipt *pitem ;
|
||||
|
||||
if(item == NULL)
|
||||
std::cerr << " Unrecocognised item type!" << std::endl;
|
||||
else if(NULL != (mitem = dynamic_cast<RsGxsTransMailItem*>(item)))
|
||||
{
|
||||
std::cerr << " " << msg->metaData->mMsgId << ": Mail data with ID " << std::hex << mitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl;
|
||||
|
||||
stored_msgs[mitem->mailId] = std::make_pair(msg->metaData->mGroupId,msg->metaData->mMsgId) ;
|
||||
}
|
||||
else if(NULL != (pitem = dynamic_cast<RsGxsTransPresignedReceipt*>(item)))
|
||||
{
|
||||
std::cerr << " " << msg->metaData->mMsgId << ": Signed rcpt of ID " << std::hex << pitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl;
|
||||
|
||||
received_msgs.push_back(pitem->mailId) ;
|
||||
}
|
||||
else
|
||||
std::cerr << " Unknown item type!" << std::endl;
|
||||
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
|
||||
GxsMsgReq msgsToDel ;
|
||||
|
||||
std::cerr << "Msg removal report:" << std::endl;
|
||||
|
||||
for(std::list<RsGxsTransId>::const_iterator it(received_msgs.begin());it!=received_msgs.end();++it)
|
||||
{
|
||||
std::map<RsGxsTransId,std::pair<RsGxsGroupId,RsGxsMessageId> >::const_iterator it2 = stored_msgs.find(*it) ;
|
||||
|
||||
if(stored_msgs.end() != it2)
|
||||
{
|
||||
msgsToDel[it2->second.first].push_back(it2->second.second);
|
||||
|
||||
std::cerr << " scheduling msg " << std::hex << it2->second.first << "," << it2->second.second << " for deletion." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
mDs->removeMsgs(msgsToDel);
|
||||
}
|
||||
|
||||
void p3GxsTrans::service_tick()
|
||||
{
|
||||
GxsTokenQueue::checkRequests();
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(mLastMsgCleanup + MAX_DELAY_BETWEEN_CLEANUPS < now)
|
||||
{
|
||||
if(!mCleanupThread)
|
||||
mCleanupThread = new GxsTransIntegrityCleanupThread(getDataStore());
|
||||
|
||||
if(mCleanupThread->isRunning())
|
||||
std::cerr << "Cleanup thread is already running. Not running it again!" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cerr << "Starting GxsIntegrity cleanup thread." << std::endl;
|
||||
|
||||
mCleanupThread->start() ;
|
||||
mLastMsgCleanup = now ;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mOutgoingMutex);
|
||||
for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); )
|
||||
@ -337,7 +475,7 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
getTokenService()->requestMsgInfo( token, 0xcaca,
|
||||
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca,
|
||||
opts, msgChange->msgChangeMap );
|
||||
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
||||
|
||||
@ -393,8 +531,8 @@ bool p3GxsTrans::requestGroupsData(const std::list<RsGxsGroupId>* groupIds)
|
||||
// std::cout << "p3GxsTrans::requestGroupsList()" << std::endl;
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
if(!groupIds) getTokenService()->requestGroupInfo(token, 0xcaca, opts);
|
||||
else getTokenService()->requestGroupInfo(token, 0xcaca, opts, *groupIds);
|
||||
if(!groupIds) RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts);
|
||||
else RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts, *groupIds);
|
||||
GxsTokenQueue::queueRequest(token, GROUPS_LIST);
|
||||
return true;
|
||||
}
|
||||
@ -526,6 +664,7 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
|
||||
{
|
||||
pr.mailItem.saltRecipientHint(pr.recipient);
|
||||
pr.mailItem.saltRecipientHint(RsGxsId::random());
|
||||
pr.mailItem.meta.mPublishTs = time(NULL);
|
||||
}
|
||||
case GxsTransSendStatus::PENDING_PREFERRED_GROUP:
|
||||
{
|
||||
@ -608,8 +747,7 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
|
||||
pr.recipient, encryptError, true ) )
|
||||
{
|
||||
pr.mailItem.payload.resize(encryptedSize);
|
||||
memcpy( &pr.mailItem.payload[0], encryptedData,
|
||||
encryptedSize );
|
||||
memcpy( &pr.mailItem.payload[0], encryptedData, encryptedSize );
|
||||
free(encryptedData);
|
||||
break;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "gxstrans/p3gxstransitems.h"
|
||||
#include "services/p3idservice.h" // For p3IdService
|
||||
#include "util/rsthreads.h"
|
||||
#include "retroshare/rsgxstrans.h"
|
||||
|
||||
struct p3GxsTrans;
|
||||
|
||||
@ -76,18 +77,36 @@ struct GxsTransClient
|
||||
* @see GxsTransClient::receiveGxsTransMail(...),
|
||||
* @see GxsTransClient::notifyGxsTransSendStatus(...).
|
||||
*/
|
||||
struct p3GxsTrans : RsGenExchange, GxsTokenQueue, p3Config
|
||||
class p3GxsTrans : public RsGenExchange, public GxsTokenQueue, public p3Config, public RsGxsTrans
|
||||
{
|
||||
public:
|
||||
p3GxsTrans( RsGeneralDataService* gds, RsNetworkExchangeService* nes,
|
||||
p3IdService& identities ) :
|
||||
RsGenExchange( gds, nes, new RsGxsTransSerializer(),
|
||||
RS_SERVICE_TYPE_GXS_TRANS, &identities,
|
||||
AuthenPolicy(), GXS_STORAGE_PERIOD ),
|
||||
GxsTokenQueue(this), mIdService(identities),
|
||||
GxsTokenQueue(this),
|
||||
RsGxsTrans(this),
|
||||
mIdService(identities),
|
||||
mServClientsMutex("p3GxsTrans client services map mutex"),
|
||||
mOutgoingMutex("p3GxsTrans outgoing queue map mutex"),
|
||||
mIngoingMutex("p3GxsTrans ingoing queue map mutex") {}
|
||||
~p3GxsTrans();
|
||||
mIngoingMutex("p3GxsTrans ingoing queue map mutex")
|
||||
{
|
||||
mLastMsgCleanup = time(NULL) - 60; // to be changed into 0
|
||||
mCleanupThread = NULL ;
|
||||
}
|
||||
|
||||
virtual ~p3GxsTrans();
|
||||
|
||||
/*!
|
||||
* \brief getStatistics
|
||||
* Gathers all sorts of statistics about the internals of p3GxsTrans, in order to display info about the running status,
|
||||
* message transport, etc.
|
||||
* \param stats This structure contains all statistics information.
|
||||
* \return true is the call succeeds.
|
||||
*/
|
||||
|
||||
virtual bool getStatistics(GxsTransStatistics& stats);
|
||||
|
||||
/**
|
||||
* Send an email to recipient, in the process author of the email is
|
||||
@ -97,7 +116,7 @@ struct p3GxsTrans : RsGenExchange, GxsTokenQueue, p3Config
|
||||
* This method is part of the public interface of this service.
|
||||
* @return true if the mail will be sent, false if not
|
||||
*/
|
||||
bool sendMail( RsGxsTransId& mailId,
|
||||
bool sendData( RsGxsTransId& mailId,
|
||||
GxsTransSubServices service,
|
||||
const RsGxsId& own_gxsid, const RsGxsId& recipient,
|
||||
const uint8_t* data, uint32_t size,
|
||||
@ -139,7 +158,10 @@ private:
|
||||
* signed acknowledged is received for each of them.
|
||||
* Two weeks seems fair ATM.
|
||||
*/
|
||||
const static uint32_t GXS_STORAGE_PERIOD = 0x127500;
|
||||
static const uint32_t GXS_STORAGE_PERIOD = 0x127500;
|
||||
static const uint32_t MAX_DELAY_BETWEEN_CLEANUPS = 1203; // every 20 mins. Could be less.
|
||||
|
||||
time_t mLastMsgCleanup ;
|
||||
|
||||
/// Define how the backend should handle authentication based on signatures
|
||||
static uint32_t AuthenPolicy();
|
||||
@ -251,5 +273,27 @@ private:
|
||||
uint32_t decrypted_data_size );
|
||||
|
||||
void notifyClientService(const OutgoingRecord& pr);
|
||||
|
||||
/*!
|
||||
* Checks the integrity message and groups
|
||||
*/
|
||||
class GxsTransIntegrityCleanupThread : public RsSingleJobThread
|
||||
{
|
||||
enum CheckState { CheckStart, CheckChecking };
|
||||
|
||||
public:
|
||||
GxsTransIntegrityCleanupThread(RsGeneralDataService *const dataService): mDs(dataService) {}
|
||||
|
||||
bool isDone();
|
||||
void run();
|
||||
|
||||
void getDeletedIds(std::list<RsGxsGroupId>& grpIds, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgIds);
|
||||
|
||||
private:
|
||||
|
||||
RsGeneralDataService* const mDs;
|
||||
};
|
||||
|
||||
GxsTransIntegrityCleanupThread *mCleanupThread ;
|
||||
};
|
||||
|
||||
|
@ -23,41 +23,28 @@
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rstlvidset.h"
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include "retroshare/rsgxstrans.h"
|
||||
#include "retroshare/rsgxscircles.h" // For: GXS_CIRCLE_TYPE_PUBLIC
|
||||
#include "services/p3idservice.h"
|
||||
#include "serialiser/rstypeserializer.h"
|
||||
|
||||
/// Subservices identifiers (like port for TCP)
|
||||
enum class GxsTransSubServices : uint16_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
TEST_SERVICE = 1,
|
||||
P3_MSG_SERVICE = 2,
|
||||
P3_CHAT_SERVICE = 3
|
||||
};
|
||||
|
||||
/// Values must fit into uint8_t
|
||||
enum class GxsTransItemsSubtypes : uint8_t
|
||||
{
|
||||
GXS_TRANS_SUBTYPE_MAIL = 1,
|
||||
GXS_TRANS_SUBTYPE_RECEIPT = 2,
|
||||
GXS_TRANS_SUBTYPE_GROUP = 3,
|
||||
OUTGOING_RECORD_ITEM = 4
|
||||
};
|
||||
|
||||
typedef uint64_t RsGxsTransId;
|
||||
|
||||
struct RsNxsTransPresignedReceipt : RsNxsMsg
|
||||
class RsNxsTransPresignedReceipt : public RsNxsMsg
|
||||
{
|
||||
public:
|
||||
RsNxsTransPresignedReceipt() : RsNxsMsg(RS_SERVICE_TYPE_GXS_TRANS) {}
|
||||
|
||||
virtual ~RsNxsTransPresignedReceipt() {}
|
||||
};
|
||||
|
||||
struct RsGxsTransBaseItem : RsGxsMsgItem
|
||||
class RsGxsTransBaseItem : public RsGxsMsgItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes subtype) :
|
||||
RsGxsMsgItem( RS_SERVICE_TYPE_GXS_TRANS,
|
||||
static_cast<uint8_t>(subtype) ), mailId(0) {}
|
||||
|
||||
virtual ~RsGxsTransBaseItem() {}
|
||||
|
||||
RsGxsTransId mailId;
|
||||
|
||||
void inline clear()
|
||||
@ -71,10 +58,11 @@ struct RsGxsTransBaseItem : RsGxsMsgItem
|
||||
{ RS_REGISTER_SERIAL_MEMBER_TYPED(mailId, uint64_t); }
|
||||
};
|
||||
|
||||
struct RsGxsTransPresignedReceipt : RsGxsTransBaseItem
|
||||
class RsGxsTransPresignedReceipt : public RsGxsTransBaseItem
|
||||
{
|
||||
RsGxsTransPresignedReceipt() :
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT) {}
|
||||
public:
|
||||
RsGxsTransPresignedReceipt() : RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT) {}
|
||||
virtual ~RsGxsTransPresignedReceipt() {}
|
||||
};
|
||||
|
||||
enum class RsGxsTransEncryptionMode : uint8_t
|
||||
@ -84,12 +72,15 @@ enum class RsGxsTransEncryptionMode : uint8_t
|
||||
UNDEFINED_ENCRYPTION = 250
|
||||
};
|
||||
|
||||
struct RsGxsTransMailItem : RsGxsTransBaseItem
|
||||
class RsGxsTransMailItem : public RsGxsTransBaseItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransMailItem() :
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL),
|
||||
cryptoType(RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION) {}
|
||||
|
||||
virtual ~RsGxsTransMailItem() {}
|
||||
|
||||
RsGxsTransEncryptionMode cryptoType;
|
||||
|
||||
/**
|
||||
@ -166,8 +157,9 @@ struct RsGxsTransMailItem : RsGxsTransBaseItem
|
||||
const static uint32_t MAX_SIZE = 10*8*1024*1024;
|
||||
};
|
||||
|
||||
struct RsGxsTransGroupItem : RsGxsGrpItem
|
||||
class RsGxsTransGroupItem : public RsGxsGrpItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransGroupItem() :
|
||||
RsGxsGrpItem( RS_SERVICE_TYPE_GXS_TRANS,
|
||||
static_cast<uint8_t>(
|
||||
@ -177,6 +169,7 @@ struct RsGxsTransGroupItem : RsGxsGrpItem
|
||||
meta.mGroupName = "Mail";
|
||||
meta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC;
|
||||
}
|
||||
virtual ~RsGxsTransGroupItem() {}
|
||||
|
||||
// TODO: Talk with Cyril why there is no RsGxsGrpItem::serial_process
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob /*j*/,
|
||||
@ -188,33 +181,16 @@ struct RsGxsTransGroupItem : RsGxsGrpItem
|
||||
{ return out; }
|
||||
};
|
||||
|
||||
enum class GxsTransSendStatus : uint8_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
PENDING_PROCESSING,
|
||||
PENDING_PREFERRED_GROUP,
|
||||
PENDING_RECEIPT_CREATE,
|
||||
PENDING_RECEIPT_SIGNATURE,
|
||||
PENDING_SERIALIZATION,
|
||||
PENDING_PAYLOAD_CREATE,
|
||||
PENDING_PAYLOAD_ENCRYPT,
|
||||
PENDING_PUBLISH,
|
||||
/** This will be useful so the user can know if the mail reached at least
|
||||
* some friend node, in case of internet connection interruption */
|
||||
//PENDING_TRANSFER,
|
||||
PENDING_RECEIPT_RECEIVE,
|
||||
/// Records with status >= RECEIPT_RECEIVED get deleted
|
||||
RECEIPT_RECEIVED,
|
||||
FAILED_RECEIPT_SIGNATURE = 240,
|
||||
FAILED_ENCRYPTION
|
||||
};
|
||||
|
||||
class RsGxsTransSerializer;
|
||||
struct OutgoingRecord : RsItem
|
||||
|
||||
class OutgoingRecord : public RsItem
|
||||
{
|
||||
public:
|
||||
OutgoingRecord( RsGxsId rec, GxsTransSubServices cs,
|
||||
const uint8_t* data, uint32_t size );
|
||||
|
||||
virtual ~OutgoingRecord() {}
|
||||
|
||||
GxsTransSendStatus status;
|
||||
RsGxsId recipient;
|
||||
/// Don't use a pointer would be invalid after publish
|
||||
@ -234,10 +210,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct RsGxsTransSerializer : public RsServiceSerializer
|
||||
class RsGxsTransSerializer : public RsServiceSerializer
|
||||
{
|
||||
public:
|
||||
RsGxsTransSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_GXS_TRANS) {}
|
||||
~RsGxsTransSerializer() {}
|
||||
virtual ~RsGxsTransSerializer() {}
|
||||
|
||||
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
|
||||
{
|
||||
|
@ -1056,7 +1056,7 @@ bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
|
||||
}
|
||||
|
||||
RsGxsTunnelDHPublicKeyItem *dhitem = new RsGxsTunnelDHPublicKeyItem ;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
dhitem->public_key = BN_dup(dh->pub_key) ;
|
||||
#else
|
||||
const BIGNUM *pub_key=NULL ;
|
||||
@ -1140,7 +1140,7 @@ bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh)
|
||||
return false ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
BN_hex2bn(&dh->p,dh_prime_2048_hex.c_str()) ;
|
||||
BN_hex2bn(&dh->g,"5") ;
|
||||
#else
|
||||
|
@ -140,7 +140,6 @@ PUBLIC_HEADERS = retroshare/rsdisc.h \
|
||||
retroshare/rsversion.h \
|
||||
retroshare/rsservicecontrol.h \
|
||||
|
||||
|
||||
HEADERS += plugins/pluginmanager.h \
|
||||
plugins/dlfcn_win32.h \
|
||||
rsitems/rspluginitems.h \
|
||||
@ -429,6 +428,7 @@ HEADERS += pqi/authssl.h \
|
||||
pqi/pqissl.h \
|
||||
pqi/pqissllistener.h \
|
||||
pqi/pqisslpersongrp.h \
|
||||
pqi/pqissli2pbob.h \
|
||||
pqi/pqissludp.h \
|
||||
pqi/pqisslproxy.h \
|
||||
pqi/pqistore.h \
|
||||
@ -493,7 +493,9 @@ HEADERS += rsitems/rsitem.h \
|
||||
rsitems/rsgxsupdateitems.h \
|
||||
rsitems/rsserviceinfoitems.h \
|
||||
|
||||
HEADERS += services/p3msgservice.h \
|
||||
HEADERS += services/autoproxy/p3i2pbob.h \
|
||||
services/autoproxy/rsautoproxymonitor.h \
|
||||
services/p3msgservice.h \
|
||||
services/p3service.h \
|
||||
services/p3statusservice.h \
|
||||
services/p3banlist.h \
|
||||
@ -518,6 +520,9 @@ HEADERS += util/folderiterator.h \
|
||||
util/rsnet.h \
|
||||
util/extaddrfinder.h \
|
||||
util/dnsresolver.h \
|
||||
util/radix32.h \
|
||||
util/radix64.h \
|
||||
util/rsinitedptr.h \
|
||||
util/rsprint.h \
|
||||
util/rsstring.h \
|
||||
util/rsstd.h \
|
||||
@ -525,7 +530,6 @@ HEADERS += util/folderiterator.h \
|
||||
util/rsversioninfo.h \
|
||||
util/rswin.h \
|
||||
util/rsrandom.h \
|
||||
util/radix64.h \
|
||||
util/pugiconfig.h \
|
||||
util/rsmemcache.h \
|
||||
util/rstickevent.h \
|
||||
@ -580,6 +584,7 @@ SOURCES += pqi/authgpg.cc \
|
||||
pqi/pqissl.cc \
|
||||
pqi/pqissllistener.cc \
|
||||
pqi/pqisslpersongrp.cc \
|
||||
pqi/pqissli2pbob.cpp \
|
||||
pqi/pqissludp.cc \
|
||||
pqi/pqisslproxy.cc \
|
||||
pqi/pqistore.cc \
|
||||
@ -638,7 +643,9 @@ SOURCES += serialiser/rsbaseserial.cc \
|
||||
rsitems/rsgxsupdateitems.cc \
|
||||
rsitems/rsserviceinfoitems.cc \
|
||||
|
||||
SOURCES += services/p3msgservice.cc \
|
||||
SOURCES += services/autoproxy/rsautoproxymonitor.cc \
|
||||
services/autoproxy/p3i2pbob.cc \
|
||||
services/p3msgservice.cc \
|
||||
services/p3service.cc \
|
||||
services/p3statusservice.cc \
|
||||
services/p3banlist.cc \
|
||||
|
@ -245,7 +245,7 @@ sslcert::sslcert(X509 *x509, const RsPeerId& pid)
|
||||
{
|
||||
certificate = x509;
|
||||
id = pid;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
name = getX509CNString(x509->cert_info->subject);
|
||||
org = getX509OrgString(x509->cert_info->subject);
|
||||
location = getX509LocString(x509->cert_info->subject);
|
||||
@ -377,7 +377,7 @@ static int initLib = 0;
|
||||
|
||||
if (dh)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
BN_hex2bn(&dh->p,dh_prime_4096_hex.c_str()) ;
|
||||
BN_hex2bn(&dh->g,"5") ;
|
||||
#else
|
||||
@ -599,7 +599,7 @@ bool AuthSSLimpl::SignData(const void *data, const uint32_t len, std::string &si
|
||||
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
|
||||
unsigned int signlen = EVP_PKEY_size(mOwnPrivateKey);
|
||||
unsigned char signature[signlen];
|
||||
unsigned char signature[signlen] = { 0 };
|
||||
|
||||
if (0 == EVP_SignInit(mdctx, EVP_sha1()))
|
||||
{
|
||||
@ -795,7 +795,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
||||
// The code has been copied in order to use the PGP signing instead of supplying the
|
||||
// private EVP_KEY to ASN1_sign(), which would be another alternative.
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF;
|
||||
X509_ALGOR *algor1 = x509->cert_info->signature;
|
||||
X509_ALGOR *algor2 = x509->sig_alg;
|
||||
@ -824,7 +824,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
||||
/* FIX ALGORITHMS */
|
||||
|
||||
a = const_cast<X509_ALGOR*>(algor1);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter=ASN1_TYPE_new();
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
@ -836,7 +836,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
||||
#endif
|
||||
|
||||
a = const_cast<X509_ALGOR*>(algor2);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter=ASN1_TYPE_new();
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
@ -851,7 +851,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
||||
std::cerr << "Algorithms Fixed" << std::endl;
|
||||
|
||||
/* input buffer */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
unsigned char *p=NULL;
|
||||
@ -874,7 +874,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
||||
}
|
||||
std::cerr << "Buffers Allocated" << std::endl;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
p=buf_in;
|
||||
i2d(data,&p);
|
||||
#endif
|
||||
@ -960,7 +960,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
||||
}
|
||||
|
||||
/* extract CN for peer Id */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId issuer(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId issuer(std::string(getX509CNString(X509_get_issuer_name(x509))));
|
||||
@ -979,7 +979,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
||||
|
||||
/*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF;
|
||||
ASN1_BIT_STRING *signature = x509->signature;
|
||||
X509_CINF *data = x509->cert_info;
|
||||
@ -1000,7 +1000,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
||||
int sigoutl=0;
|
||||
|
||||
/* input buffer */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
unsigned char *p=NULL;
|
||||
@ -1033,7 +1033,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
||||
std::cerr << "Buffers Allocated" << std::endl;
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
p=buf_in;
|
||||
i2d(data,&p);
|
||||
#endif
|
||||
@ -1157,7 +1157,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
|
||||
if(x509 != NULL)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId gpgid (std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId gpgid (std::string(getX509CNString(X509_get_issuer_name(x509))));
|
||||
@ -1165,7 +1165,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
|
||||
if(gpgid.isNull())
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
std::cerr << "verify_x509_callback(): wrong PGP id \"" << std::string(getX509CNString(x509->cert_info->issuer)) << "\"" << std::endl;
|
||||
#else
|
||||
std::cerr << "verify_x509_callback(): wrong PGP id \"" << std::string(getX509CNString(X509_get_issuer_name(x509))) << "\"" << std::endl;
|
||||
@ -1173,7 +1173,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
return false ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
std::string sslcn = getX509CNString(x509->cert_info->subject);
|
||||
#else
|
||||
std::string sslcn = getX509CNString(X509_get_subject_name(x509));
|
||||
@ -1262,7 +1262,7 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
|
||||
return false;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(X509_STORE_CTX_get_current_cert(ctx)))));
|
||||
@ -1339,7 +1339,7 @@ bool AuthSSLimpl::encrypt(void *&out, int &outlen, const void *in, int inlen,
|
||||
#endif
|
||||
return false;
|
||||
} else {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
public_key = mCerts[peerId]->certificate->cert_info->key->pkey;
|
||||
#else
|
||||
public_key = X509_get0_pubkey(mCerts[peerId]->certificate) ;
|
||||
@ -1586,20 +1586,26 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const RsPgpId& gpgid,
|
||||
|
||||
switch(auth_diagnostic)
|
||||
{
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
|
||||
default:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING:
|
||||
RsServer::notify()->notifyConnectionWithoutCert();
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
|
||||
default:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
}
|
||||
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
|
@ -237,6 +237,7 @@ void p3Notify::notifyOwnStatusMessageChanged()
|
||||
void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; }
|
||||
void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; }
|
||||
void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;}
|
||||
void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); }
|
||||
|
||||
void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; }
|
||||
void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; }
|
||||
|
@ -112,6 +112,7 @@ class p3Notify: public RsNotify
|
||||
void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ;
|
||||
void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ;
|
||||
void notifyGxsChange (const RsGxsChanges& /* changes */);
|
||||
void notifyConnectionWithoutCert ();
|
||||
|
||||
void notifyPeerStatusChangedSummary () ;
|
||||
void notifyDiscInfoChanged () ;
|
||||
|
@ -521,12 +521,14 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
pqiconnect *pqi = it->second;
|
||||
|
||||
#ifdef PERSON_DEBUG
|
||||
std::cerr << "pqiperson::connect() resetting for new connection attempt" << std::endl;
|
||||
#endif
|
||||
|
||||
/* set the parameters */
|
||||
(it->second)->reset();
|
||||
pqi->reset();
|
||||
|
||||
#ifdef PERSON_DEBUG
|
||||
std::cerr << "pqiperson::connect() clearing rate cap" << std::endl;
|
||||
@ -538,22 +540,22 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
|
||||
#endif
|
||||
|
||||
// These two are universal.
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
|
||||
|
||||
// these 5 are only used by UDP connections.
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
|
||||
|
||||
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
|
||||
(it->second)->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
|
||||
pqi->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
|
||||
pqi->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
|
||||
|
||||
// These are used by Proxy/Hidden
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
|
||||
|
||||
(it->second)->connect(raddr);
|
||||
pqi->connect(raddr);
|
||||
|
||||
// flag if we started a new connectionAttempt.
|
||||
inConnectAttempt = true;
|
||||
|
@ -361,7 +361,7 @@ void pqissl::getCryptoParams(RsPeerCryptoParams& params)
|
||||
|
||||
bool pqissl::actAsServer()
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
return (bool)ssl_connection->server;
|
||||
#else
|
||||
return (bool)SSL_is_server(ssl_connection);
|
||||
@ -1230,7 +1230,7 @@ int pqissl::Extract_Failed_SSL_Certificate()
|
||||
RsPeerId sslid ;
|
||||
getX509id(peercert, sslid) ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId gpgid(getX509CNString(peercert->cert_info->issuer));
|
||||
std::string sslcn = getX509CNString(peercert->cert_info->subject);
|
||||
#else
|
||||
|
31
libretroshare/src/pqi/pqissli2pbob.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "pqissli2pbob.h"
|
||||
|
||||
bool pqissli2pbob::connect_parameter(uint32_t type, const std::string &value)
|
||||
{
|
||||
if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS)
|
||||
{
|
||||
RS_STACK_MUTEX(mSslMtx);
|
||||
// a new line must be appended!
|
||||
mI2pAddr = value + '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
return pqissl::connect_parameter(type, value);
|
||||
}
|
||||
|
||||
int pqissli2pbob::Basic_Connection_Complete()
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pqissl::Basic_Connection_Complete()) != 1)
|
||||
{
|
||||
// basic connection not complete.
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send addr. (new line is already appended)
|
||||
ret = send(sockfd, mI2pAddr.c_str(), mI2pAddr.length(), 0);
|
||||
if (ret != (int)mI2pAddr.length())
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
31
libretroshare/src/pqi/pqissli2pbob.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef PQISSLI2PBOB_H
|
||||
#define PQISSLI2PBOB_H
|
||||
|
||||
#include "pqi/pqissl.h"
|
||||
|
||||
/*
|
||||
* This class is a minimal varied version of pqissl to work with I2P BOB tunnels.
|
||||
* The only difference is that the [.b32].i2p addresses must be sent first.
|
||||
*
|
||||
* Everything else is untouched.
|
||||
*/
|
||||
|
||||
class pqissli2pbob : public pqissl
|
||||
{
|
||||
public:
|
||||
pqissli2pbob(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
|
||||
: pqissl(l, parent, lm) {}
|
||||
|
||||
// NetInterface interface
|
||||
public:
|
||||
bool connect_parameter(uint32_t type, const std::string &value);
|
||||
|
||||
// pqissl interface
|
||||
protected:
|
||||
int Basic_Connection_Complete();
|
||||
|
||||
private:
|
||||
std::string mI2pAddr;
|
||||
};
|
||||
|
||||
#endif // PQISSLI2PBOB_H
|
@ -493,7 +493,7 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
|
||||
#endif
|
||||
if(x509 != NULL)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
incoming_connexion_info.sslcn = getX509CNString(x509->cert_info->subject);
|
||||
#else
|
||||
@ -892,7 +892,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
||||
AuthSSL::getAuthSSL()->CheckCertificate(newPeerId, peercert);
|
||||
|
||||
/* now need to get GPG id too */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId pgpid(std::string(getX509CNString(peercert->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(peercert))));
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "serialiser/rsserializer.h"
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
#include "pqi/pqisslpersongrp.h"
|
||||
@ -49,6 +50,7 @@ static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersong
|
||||
#endif
|
||||
|
||||
#include "pqi/pqisslproxy.h"
|
||||
#include "pqi/pqissli2pbob.h"
|
||||
|
||||
pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr)
|
||||
{
|
||||
@ -76,29 +78,34 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
|
||||
/* construct the serialiser ....
|
||||
* Needs:
|
||||
* * FileItem
|
||||
* * FileData
|
||||
* * ServiceGeneric
|
||||
*/
|
||||
// Use pqicI2PBOB for I2P
|
||||
pqiconnect *pqicSOCKSProxy, *pqicI2PBOB;
|
||||
{
|
||||
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
pqicSOCKSProxy = new pqiconnect(pqip, rss, pqis);
|
||||
}
|
||||
if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PBOB))
|
||||
{
|
||||
pqissli2pbob *pqis = new pqissli2pbob((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
|
||||
pqicI2PBOB = new pqiconnect(pqip, rss, pqis);
|
||||
} else {
|
||||
pqicI2PBOB = pqicSOCKSProxy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
|
||||
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
||||
|
||||
/* first select type based on peer */
|
||||
uint32_t typePeer = mPeerMgr->getHiddenType(id);
|
||||
switch (typePeer) {
|
||||
case RS_HIDDEN_TYPE_TOR:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
|
||||
break;
|
||||
case RS_HIDDEN_TYPE_I2P:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
|
||||
break;
|
||||
default:
|
||||
/* peer is not a hidden one but we are */
|
||||
@ -106,7 +113,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
||||
uint32_t typeOwn = mPeerMgr->getHiddenType(AuthSSL::getAuthSSL()->OwnId());
|
||||
switch (typeOwn) {
|
||||
case RS_HIDDEN_TYPE_I2P:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
|
||||
break;
|
||||
default:
|
||||
/* this case shouldn't happen! */
|
||||
@ -117,7 +124,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
||||
std::cerr << " - hidden types: peer=" << typePeer << " own=" << typeOwn << std::endl;
|
||||
std::cerr << " --> falling back to Tor" << std::endl;
|
||||
case RS_HIDDEN_TYPE_TOR:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ private:
|
||||
uint32_t mProxyState;
|
||||
|
||||
std::string mDomainAddress;
|
||||
uint16_t mRemotePort;
|
||||
uint16_t mRemotePort;
|
||||
};
|
||||
|
||||
#endif // MRK_PQI_SSL_PROXY_HEADER
|
||||
|
@ -602,7 +602,7 @@ bool getX509id(X509 *x509, RsPeerId& xid)
|
||||
}
|
||||
|
||||
// get the signature from the cert, and copy to the array.
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_BIT_STRING *signature = x509->signature;
|
||||
#else
|
||||
const ASN1_BIT_STRING *signature = NULL ;
|
||||
@ -700,7 +700,7 @@ int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &locat
|
||||
if (valid)
|
||||
{
|
||||
// extract the name.
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
issuerName = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
location = getX509LocString(x509->cert_info->subject);
|
||||
#else
|
||||
|
@ -60,6 +60,8 @@ public:
|
||||
|
||||
public:
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
std::set<RsGxsMessageId> mOlderVersions ;
|
||||
std::string mMsg; // UTF8 encoded.
|
||||
|
||||
std::list<RsGxsFile> mFiles;
|
||||
|
103
libretroshare/src/retroshare/rsgxstrans.h
Normal file
@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include "retroshare/rstokenservice.h"
|
||||
#include "retroshare/rsgxsifacehelper.h"
|
||||
#include "retroshare/rsgxscommon.h"
|
||||
|
||||
/// Subservices identifiers (like port for TCP)
|
||||
enum class GxsTransSubServices : uint16_t
|
||||
{
|
||||
UNKNOWN = 0x00,
|
||||
TEST_SERVICE = 0x01,
|
||||
P3_MSG_SERVICE = 0x02,
|
||||
P3_CHAT_SERVICE = 0x03
|
||||
};
|
||||
|
||||
/// Values must fit into uint8_t
|
||||
enum class GxsTransItemsSubtypes : uint8_t
|
||||
{
|
||||
GXS_TRANS_SUBTYPE_MAIL = 0x01,
|
||||
GXS_TRANS_SUBTYPE_RECEIPT = 0x02,
|
||||
GXS_TRANS_SUBTYPE_GROUP = 0x03,
|
||||
OUTGOING_RECORD_ITEM = 0x04
|
||||
};
|
||||
|
||||
enum class GxsTransSendStatus : uint8_t
|
||||
{
|
||||
UNKNOWN = 0x00,
|
||||
PENDING_PROCESSING = 0x01,
|
||||
PENDING_PREFERRED_GROUP = 0x02,
|
||||
PENDING_RECEIPT_CREATE = 0x03,
|
||||
PENDING_RECEIPT_SIGNATURE = 0x04,
|
||||
PENDING_SERIALIZATION = 0x05,
|
||||
PENDING_PAYLOAD_CREATE = 0x06,
|
||||
PENDING_PAYLOAD_ENCRYPT = 0x07,
|
||||
PENDING_PUBLISH = 0x08,
|
||||
/** This will be useful so the user can know if the mail reached at least
|
||||
* some friend node, in case of internet connection interruption */
|
||||
//PENDING_TRANSFER,
|
||||
PENDING_RECEIPT_RECEIVE = 0x09,
|
||||
/// Records with status >= RECEIPT_RECEIVED get deleted
|
||||
RECEIPT_RECEIVED = 0x0a,
|
||||
FAILED_RECEIPT_SIGNATURE = 0xf0,
|
||||
FAILED_ENCRYPTION = 0xf1
|
||||
};
|
||||
|
||||
typedef uint64_t RsGxsTransId;
|
||||
|
||||
class RsGxsTransGroup
|
||||
{
|
||||
public:
|
||||
RsGroupMetaData mMeta;
|
||||
};
|
||||
|
||||
class RsGxsTransMsg
|
||||
{
|
||||
public:
|
||||
RsGxsTransMsg() : size(0),data(NULL) {}
|
||||
virtual ~RsGxsTransMsg() { free(data) ; }
|
||||
|
||||
public:
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
uint32_t size ;
|
||||
uint8_t *data ;
|
||||
};
|
||||
|
||||
struct RsGxsTransOutgoingRecord
|
||||
{
|
||||
GxsTransSendStatus status;
|
||||
RsGxsId recipient;
|
||||
RsGxsTransId trans_id;
|
||||
|
||||
GxsTransSubServices client_service;
|
||||
|
||||
uint32_t data_size ;
|
||||
Sha1CheckSum data_hash ;
|
||||
uint32_t send_TS ;
|
||||
RsGxsGroupId group_id ;
|
||||
};
|
||||
|
||||
class RsGxsTrans: public RsGxsIfaceHelper
|
||||
{
|
||||
public:
|
||||
class GxsTransStatistics
|
||||
{
|
||||
public:
|
||||
GxsTransStatistics() {}
|
||||
|
||||
RsGxsGroupId prefered_group_id ;
|
||||
std::vector<RsGxsTransOutgoingRecord> outgoing_records;
|
||||
};
|
||||
|
||||
RsGxsTrans(RsGxsIface *gxs) : RsGxsIfaceHelper(gxs) {}
|
||||
|
||||
virtual ~RsGxsTrans() {}
|
||||
|
||||
virtual bool getStatistics(GxsTransStatistics& stats)=0;
|
||||
|
||||
// virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsTransGroup> &groups) = 0;
|
||||
// virtual bool getPostData(const uint32_t &token, std::vector<RsGxsTransMsg> &posts) = 0;
|
||||
};
|
||||
|
||||
extern RsGxsTrans *rsGxsTrans ;
|
@ -78,7 +78,7 @@ class RsInit
|
||||
/*!
|
||||
* Setup Hidden Location;
|
||||
*/
|
||||
static bool SetHiddenLocation(const std::string& hiddenaddress, uint16_t port);
|
||||
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
|
||||
|
||||
static bool LoadPassword(const std::string& passwd) ;
|
||||
|
||||
|
@ -228,6 +228,7 @@ class NotifyClient
|
||||
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
|
||||
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
|
||||
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
|
||||
virtual void notifyConnectionWithoutCert () {}
|
||||
|
||||
/* one or more peers has changed the states */
|
||||
virtual void notifyPeerStatusChangedSummary () {}
|
||||
|
@ -45,6 +45,8 @@ const int p3facemsgzone = 11453;
|
||||
// TO SHUTDOWN THREADS.
|
||||
#ifdef RS_ENABLE_GXS
|
||||
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
|
||||
#include "services/p3idservice.h"
|
||||
#include "services/p3gxscircles.h"
|
||||
#include "services/p3wiki.h"
|
||||
@ -89,6 +91,8 @@ void RsServer::rsGlobalShutDown()
|
||||
|
||||
mNetMgr->shutdown(); /* Handles UPnP */
|
||||
|
||||
rsAutoProxyMonitor::instance()->stopAllRSShutdown();
|
||||
|
||||
fullstop() ;
|
||||
|
||||
// kill all registered service threads
|
||||
|
@ -46,6 +46,7 @@
|
||||
|
||||
class p3heartbeat;
|
||||
class p3discovery2;
|
||||
class p3I2pBob;
|
||||
|
||||
/* GXS Classes - just declare the classes.
|
||||
so we don't have to totally recompile to switch */
|
||||
@ -129,7 +130,7 @@ class RsServer: public RsControl, public RsTickingThread
|
||||
* This function is responsible for ensuring Retroshare exits in a legal state:
|
||||
* i.e. releases all held resources and saves current configuration
|
||||
*/
|
||||
virtual void rsGlobalShutDown( );
|
||||
virtual void rsGlobalShutDown( );
|
||||
|
||||
/****************************************/
|
||||
|
||||
@ -164,6 +165,7 @@ class RsServer: public RsControl, public RsTickingThread
|
||||
p3ChatService *chatSrv;
|
||||
p3StatusService *mStatusSrv;
|
||||
p3GxsTunnelService *mGxsTunnels;
|
||||
p3I2pBob *mI2pBob;
|
||||
|
||||
// This list contains all threaded services. It will be used to shut them down properly.
|
||||
|
||||
|
@ -125,6 +125,8 @@ class RsInitConfig
|
||||
std::string hiddenNodeAddress;
|
||||
uint16_t hiddenNodePort;
|
||||
|
||||
bool hiddenNodeI2PBOB;
|
||||
|
||||
/* Logging */
|
||||
bool haveLogFile;
|
||||
bool outStderr;
|
||||
@ -794,13 +796,13 @@ void RsInit::setAutoLogin(bool autoLogin){
|
||||
}
|
||||
|
||||
/* Setup Hidden Location; */
|
||||
bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port)
|
||||
void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob)
|
||||
{
|
||||
/* parse the bugger (todo) */
|
||||
rsInitConfig->hiddenNodeSet = true;
|
||||
rsInitConfig->hiddenNodeAddress = hiddenaddress;
|
||||
rsInitConfig->hiddenNodePort = port;
|
||||
return true;
|
||||
rsInitConfig->hiddenNodeI2PBOB = useBob;
|
||||
}
|
||||
|
||||
|
||||
@ -854,7 +856,10 @@ RsGRouter *rsGRouter = NULL ;
|
||||
#include "upnp/upnphandler_miniupnp.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "services/autoproxy/p3i2pbob.h"
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
|
||||
#include "services/p3gxsreputation.h"
|
||||
#include "services/p3serviceinfo.h"
|
||||
#include "services/p3heartbeat.h"
|
||||
@ -1046,8 +1051,11 @@ int RsServer::StartupRetroShare()
|
||||
|
||||
mPeerMgr->setManagers(mLinkMgr, mNetMgr);
|
||||
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
|
||||
|
||||
|
||||
|
||||
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
|
||||
mI2pBob = new p3I2pBob(mPeerMgr);
|
||||
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
|
||||
|
||||
//load all the SSL certs as friends
|
||||
// std::list<std::string> sslIds;
|
||||
// AuthSSL::getAuthSSL()->getAuthenticatedList(sslIds);
|
||||
@ -1261,12 +1269,6 @@ int RsServer::StartupRetroShare()
|
||||
|
||||
rsFiles = ftserver;
|
||||
|
||||
|
||||
/* create Cache Services */
|
||||
std::string config_dir = rsAccounts->PathAccountDirectory();
|
||||
std::string localcachedir = config_dir + "/cache/local";
|
||||
std::string remotecachedir = config_dir + "/cache/remote";
|
||||
|
||||
std::vector<std::string> plugins_directories ;
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -1694,6 +1696,7 @@ int RsServer::StartupRetroShare()
|
||||
//mConfigMgr->addConfiguration("photo.cfg", photo_ns);
|
||||
//mConfigMgr->addConfiguration("wire.cfg", wire_ns);
|
||||
#endif
|
||||
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
|
||||
|
||||
mPluginsManager->addConfigurations(mConfigMgr) ;
|
||||
|
||||
@ -1739,12 +1742,46 @@ int RsServer::StartupRetroShare()
|
||||
{
|
||||
mPeerMgr->setOwnNetworkMode(RS_NET_MODE_EXT);
|
||||
mPeerMgr->setOwnVisState(RS_VS_DISC_FULL, RS_VS_DHT_FULL);
|
||||
|
||||
}
|
||||
|
||||
if (rsInitConfig->hiddenNodeSet)
|
||||
{
|
||||
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
|
||||
std::cout << "RsServer::StartupRetroShare setting up hidden locations" << std::endl;
|
||||
|
||||
if (rsInitConfig->hiddenNodeI2PBOB) {
|
||||
std::cout << "RsServer::StartupRetroShare setting up BOB" << std::endl;
|
||||
|
||||
// we need a local port!
|
||||
mNetMgr->checkNetAddress();
|
||||
|
||||
// add i2p proxy
|
||||
// bob will use this address
|
||||
sockaddr_storage i2pInstance;
|
||||
sockaddr_storage_ipv4_aton(i2pInstance, rsInitConfig->hiddenNodeAddress.c_str());
|
||||
mPeerMgr->setProxyServerAddress(RS_HIDDEN_TYPE_I2P, i2pInstance);
|
||||
|
||||
std::string addr; // will be set by auto proxy service
|
||||
uint16_t port = rsInitConfig->hiddenNodePort; // unused by bob
|
||||
|
||||
bool r = autoProxy->initialSetup(autoProxyType::I2PBOB, addr, port);
|
||||
|
||||
if (r && !addr.empty()) {
|
||||
mPeerMgr->setupHiddenNode(addr, port);
|
||||
|
||||
// now enable bob
|
||||
bobSettings bs;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
|
||||
bs.enableBob = true;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
|
||||
} else {
|
||||
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
|
||||
/// TODO add notify for failed bob setup
|
||||
}
|
||||
} else {
|
||||
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
|
||||
}
|
||||
|
||||
std::cout << "RsServer::StartupRetroShare hidden location set up" << std::endl;
|
||||
}
|
||||
else if (isHiddenNode)
|
||||
{
|
||||
@ -1753,15 +1790,27 @@ int RsServer::StartupRetroShare()
|
||||
|
||||
mNetMgr -> checkNetAddress();
|
||||
|
||||
if (rsInitConfig->hiddenNodeSet) {
|
||||
// newly created location
|
||||
// mNetMgr->checkNetAddress() will setup ports for us
|
||||
// trigger updates for auto proxy services
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
|
||||
// i2p bob need to rebuild its command map
|
||||
types.push_back(autoProxyType::I2PBOB);
|
||||
|
||||
rsAutoProxyMonitor::taskSync(types, autoProxyTask::reloadConfig);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* startup (stuff dependent on Ids/peers is after this point) */
|
||||
/**************************************************************************/
|
||||
|
||||
autoProxy->startAll();
|
||||
|
||||
pqih->init_listener();
|
||||
mNetMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* load caches and secondary data */
|
||||
/**************************************************************************/
|
||||
@ -1788,8 +1837,10 @@ int RsServer::StartupRetroShare()
|
||||
/* Start up Threads */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
// auto proxy threads
|
||||
startServiceThread(mI2pBob, "I2P-BOB");
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
// Must Set the GXS pointers before starting threads.
|
||||
rsIdentity = mGxsIdService;
|
||||
rsGxsCircles = mGxsCircles;
|
||||
@ -1799,6 +1850,8 @@ int RsServer::StartupRetroShare()
|
||||
rsPosted = mPosted;
|
||||
rsGxsForums = mGxsForums;
|
||||
rsGxsChannels = mGxsChannels;
|
||||
rsGxsTrans = mGxsTrans;
|
||||
|
||||
//rsPhoto = mPhoto;
|
||||
//rsWire = mWire;
|
||||
|
||||
|
1115
libretroshare/src/services/autoproxy/p3i2pbob.cc
Normal file
250
libretroshare/src/services/autoproxy/p3i2pbob.h
Normal file
@ -0,0 +1,250 @@
|
||||
#ifndef P3I2PBOB_H
|
||||
#define P3I2PBOB_H
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#ifndef WINDOWS_SYS
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
|
||||
/*
|
||||
* This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS
|
||||
* to automatically remote control I2P to setup the needed tunnel.
|
||||
* BOB is a simple text-based interface: https://geti2p.net/en/docs/api/bob
|
||||
*
|
||||
* Note 1:
|
||||
* One tunnel is enough even for hidden locations since it can be used
|
||||
* bidirectional. (In contrast to what RS I2P users had to set up manually.)
|
||||
*
|
||||
* Note 2:
|
||||
* BOB tunnels are no SOCKS tunnel. Therefore pqissli2pbob implements a simplified
|
||||
* proxy specially for BOB tunnels.
|
||||
*
|
||||
* Note 3:
|
||||
* BOB needs a unique name as an ID for each tunnel.
|
||||
* We use 'RetroShare-' + 8 base32 characters.
|
||||
*
|
||||
* Design:
|
||||
* The service uses three state machines to manage its task:
|
||||
* int stateMachineBOB();
|
||||
* mBOBState
|
||||
* int stateMachineController();
|
||||
* mState
|
||||
* mTask
|
||||
*
|
||||
* stateMachineBOB:
|
||||
* This state machine manages the low level communication with BOB. It basically has a linked
|
||||
* list (currently a implemented as a std::map) that contains a command and the next
|
||||
* state.
|
||||
* Each high level operation (start up / shut down / get keys) is represented by a
|
||||
* chain of states. E.g. the chain to retrieve new keys:
|
||||
* mCommands[bobState::setnickN] = {setnick, bobState::newkeysN};
|
||||
* mCommands[bobState::newkeysN] = {newkeys, bobState::getkeys};
|
||||
* mCommands[bobState::getkeys] = {getkeys, bobState::clear};
|
||||
* mCommands[bobState::clear] = {clear, bobState::quit};
|
||||
* mCommands[bobState::quit] = {quit, bobState::cleared};
|
||||
*
|
||||
* stateMachineController:
|
||||
* This state machone manages the high level tasks.
|
||||
* It is controlled by mState and mTask.
|
||||
*
|
||||
* mTast:
|
||||
* Tracks the high level operation (like start up).
|
||||
* It will keep its value even when a task is done to track
|
||||
* the requested BOB state.
|
||||
* When other operations are performed like a conection check
|
||||
* the last task gets backed up and is later restored again
|
||||
*
|
||||
* mState:
|
||||
* This state lives only for one operation an manages the communication
|
||||
* with the BOB instance. This is basically connecting, starting BOB
|
||||
* protocol and disconnecting
|
||||
*
|
||||
* How a task looks like:
|
||||
* 1) RS sets task using the ticket system
|
||||
* 2) stateMachineController connects to BOBs control port, sets mBobState to a lists head
|
||||
* 3) stateMachineBOB processes command chain
|
||||
* 4) stateMachineBOB is done and sets mBobState to cleared signaling that the connection
|
||||
* is cleared and can be closed
|
||||
* 5) stateMachineController disconnects from BOBs control port and updates mState
|
||||
*/
|
||||
|
||||
///
|
||||
/// \brief The controllerState enum
|
||||
/// States for the controller to keep track of what he is currently doing
|
||||
enum controllerState {
|
||||
csIdel,
|
||||
csDoConnect,
|
||||
csConnected,
|
||||
csWaitForBob,
|
||||
csDoDisconnect,
|
||||
csDisconnected,
|
||||
csError
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The controllerTask enum
|
||||
/// This state tracks the controllers tast (e.g. setup a BOB tunnel or shut down
|
||||
/// an existing one).
|
||||
enum controllerTask {
|
||||
ctIdle,
|
||||
ctRunSetUp,
|
||||
ctRunShutDown,
|
||||
ctRunGetKeys,
|
||||
ctRunCheck
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobState enum
|
||||
/// One state for each message
|
||||
///
|
||||
enum bobState {
|
||||
bsCleared,
|
||||
bsSetnickC, // chain head for only client tunnel
|
||||
bsSetnickN, // chain head for getting new (server) keys
|
||||
bsSetnickS, // chain head for client and server tunnel
|
||||
bsGetnick,
|
||||
bsNewkeysC, // part of chain for only client tunnel
|
||||
bsNewkeysN, // part of chain for getting new (server) keys
|
||||
bsGetkeys,
|
||||
bsSetkeys,
|
||||
bsInhost,
|
||||
bsOuthost,
|
||||
bsInport,
|
||||
bsOutport,
|
||||
bsInlength,
|
||||
bsOutlength,
|
||||
bsInvariance,
|
||||
bsOutvariance,
|
||||
bsInquantity,
|
||||
bsOutquantity,
|
||||
bsQuiet,
|
||||
bsStart,
|
||||
bsStop,
|
||||
bsClear,
|
||||
bsList, // chain head for 'list' command
|
||||
bsQuit
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobStateInfo struct
|
||||
/// State machine with commands
|
||||
/// \todo This could be replaced by a linked list instead of a map
|
||||
struct bobStateInfo {
|
||||
std::string command;
|
||||
bobState nextState;
|
||||
};
|
||||
|
||||
struct bobSettings {
|
||||
bool enableBob; ///< This field is used by the pqi subsystem to determinine whether SOCKS proxy or BOB is used for I2P connections
|
||||
std::string keys; ///< (optional) server keys
|
||||
std::string addr; ///< (optional) hidden service addr. in base32 form
|
||||
|
||||
int8_t inLength;
|
||||
int8_t inQuantity;
|
||||
int8_t inVariance;
|
||||
|
||||
int8_t outLength;
|
||||
int8_t outQuantity;
|
||||
int8_t outVariance;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobStates struct
|
||||
/// This container struct is used to pass all states.
|
||||
/// Additionally, the tunnel name is included to to show it in the GUI.
|
||||
/// The advantage of a struct is that it can be forward declared.
|
||||
struct bobStates {
|
||||
bobState bs;
|
||||
controllerState cs;
|
||||
controllerTask ct;
|
||||
|
||||
std::string tunnelName;
|
||||
};
|
||||
|
||||
class p3PeerMgr;
|
||||
|
||||
class p3I2pBob : public RsTickingThread, public p3Config, public autoProxyService
|
||||
{
|
||||
public:
|
||||
p3I2pBob(p3PeerMgr *peerMgr);
|
||||
|
||||
// autoProxyService interface
|
||||
public:
|
||||
bool isEnabled();
|
||||
bool initialSetup(std::string &addr, uint16_t &);
|
||||
void processTaskAsync(taskTicket *ticket);
|
||||
void processTaskSync(taskTicket *ticket);
|
||||
|
||||
static std::string keyToBase32Addr(const std::string &key);
|
||||
|
||||
// RsTickingThread interface
|
||||
public:
|
||||
void data_tick();
|
||||
|
||||
private:
|
||||
int stateMachineBOB();
|
||||
int stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo ¤tState);
|
||||
|
||||
int stateMachineController();
|
||||
int stateMachineController_locked_idle();
|
||||
int stateMachineController_locked_connected();
|
||||
int stateMachineController_locked_disconnected();
|
||||
int stateMachineController_locked_error();
|
||||
|
||||
// p3Config interface
|
||||
protected:
|
||||
RsSerialiser *setupSerialiser();
|
||||
bool saveList(bool &cleanup, std::list<RsItem *> &lst);
|
||||
bool loadList(std::list<RsItem *> &load);
|
||||
|
||||
private:
|
||||
// helpers
|
||||
void getBOBSettings(bobSettings *settings);
|
||||
void setBOBSettings(const bobSettings *settings);
|
||||
void getStates(bobStates *bs);
|
||||
|
||||
std::string executeCommand(const std::string &command);
|
||||
bool connectI2P();
|
||||
bool disconnectI2P();
|
||||
|
||||
void finalizeSettings_locked();
|
||||
void updateSettings_locked();
|
||||
|
||||
std::string recv();
|
||||
|
||||
// states for state machines
|
||||
controllerState mState;
|
||||
controllerTask mTask;
|
||||
// used to store old state when in error state
|
||||
// mStateOld is also used as a flag when an error occured in BOB protocol
|
||||
controllerState mStateOld;
|
||||
// mTaskOld is used to keep the previous task (start up / shut down) when requesting keys or checking the connection
|
||||
controllerTask mTaskOld;
|
||||
bobSettings mSetting;
|
||||
bobState mBOBState;
|
||||
|
||||
// used variables
|
||||
p3PeerMgr *mPeerMgr;
|
||||
bool mConfigLoaded;
|
||||
int mSocket;
|
||||
time_t mLastProxyCheck;
|
||||
sockaddr_storage mI2PProxyAddr;
|
||||
std::map<bobState, bobStateInfo> mCommands;
|
||||
std::string mErrorMsg;
|
||||
std::string mTunnelName;
|
||||
|
||||
std::queue<taskTicket *> mPending;
|
||||
taskTicket *mProcessing;
|
||||
|
||||
// mutex
|
||||
RsMutex mLock;
|
||||
};
|
||||
|
||||
#endif // P3I2PBOB_H
|
303
libretroshare/src/services/autoproxy/rsautoproxymonitor.cc
Normal file
@ -0,0 +1,303 @@
|
||||
#include "rsautoproxymonitor.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
|
||||
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
|
||||
|
||||
rsAutoProxyMonitor::rsAutoProxyMonitor()
|
||||
: mRSShutDown(false), mLock("rs auto proxy monitor")
|
||||
{
|
||||
mProxies.clear();
|
||||
}
|
||||
|
||||
rsAutoProxyMonitor *rsAutoProxyMonitor::instance()
|
||||
{
|
||||
if (mInstance == NULL)
|
||||
mInstance = new rsAutoProxyMonitor();
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
if (mProxies.find(type) != mProxies.end())
|
||||
std::cerr << "sAutoProxyMonitor::addProxy type " << type << " already added - OVERWRITING" << std::endl;
|
||||
|
||||
mProxies[type] = service;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::startAll()
|
||||
{
|
||||
// create ticket
|
||||
taskTicket *tt = getTicket();
|
||||
tt->cb = this;
|
||||
tt->task = autoProxyTask::start;
|
||||
|
||||
{
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
|
||||
// fill types
|
||||
RS_STACK_MUTEX(mLock);
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it)
|
||||
if (it->second->isEnabled())
|
||||
tt->types.push_back(it->first);
|
||||
}
|
||||
|
||||
task(tt);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::stopAll()
|
||||
{
|
||||
// create ticket
|
||||
taskTicket *tt = getTicket();
|
||||
tt->cb = this;
|
||||
tt->task = autoProxyTask::stop;
|
||||
|
||||
{
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
|
||||
// fill types
|
||||
RS_STACK_MUTEX(mLock);
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it)
|
||||
if (it->second->isEnabled())
|
||||
tt->types.push_back(it->first);
|
||||
}
|
||||
|
||||
task(tt);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::stopAllRSShutdown()
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
mRSShutDown = true;
|
||||
|
||||
// remove disabled services
|
||||
std::vector<autoProxyType::autoProxyType_enum> toRemove;
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it) {
|
||||
if (!it->second->isEnabled()) {
|
||||
toRemove.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it2;
|
||||
for (it2 = toRemove.begin(); it2 != toRemove.end(); ++it2) {
|
||||
mProxies.erase(*it2);
|
||||
}
|
||||
}
|
||||
|
||||
// stop all remaining
|
||||
stopAll();
|
||||
|
||||
// wait for shutdown of all services
|
||||
uint32_t t = 0, timeout = 15;
|
||||
do {
|
||||
usleep(1000 * 1000);
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::cout << "(II) waiting for auto proxy service(s) to shut down " << t << "/" << timeout << " (remaining: " << mProxies.size() << ")" << std::endl;
|
||||
if (mProxies.empty())
|
||||
break;
|
||||
t++;
|
||||
} while (t < timeout );
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::isEnabled(autoProxyType::autoProxyType_enum t)
|
||||
{
|
||||
autoProxyService *s = lookUpService(t);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
return s->isEnabled();
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port)
|
||||
{
|
||||
autoProxyService *s = lookUpService(t);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
return s->initialSetup(addr, port);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||
{
|
||||
// sanity checks
|
||||
if (!ticket->async && ticket->types.size() > 1) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task synchronous call to multiple services. This can cause problems!" << std::endl;
|
||||
}
|
||||
if (ticket->async && !ticket->cb && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task asynchronous call with data but no callback. This will likely causes memory leak!" << std::endl;
|
||||
}
|
||||
if (ticket->types.size() > 1 && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task call with data to multiple services. This will likely causes memory leak!" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it;
|
||||
|
||||
for (it = ticket->types.begin(); it != ticket->types.end(); ++it) {
|
||||
autoProxyService* s = lookUpService(*it);
|
||||
if (s == NULL)
|
||||
continue;
|
||||
|
||||
if (ticket->async) {
|
||||
// copy ticket
|
||||
taskTicket *tt = new taskTicket();
|
||||
*tt = *ticket;
|
||||
tt->types.clear();
|
||||
tt->types.push_back(*it);
|
||||
s->processTaskAsync(tt);
|
||||
} else {
|
||||
s->processTaskSync(ticket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
|
||||
{
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
types.push_back(type);
|
||||
taskAsync(types, task, cb, data);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
|
||||
{
|
||||
if (!isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskAsync called with a synchronous task!" << std::endl;
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
tt->task = task;
|
||||
tt->types = types;
|
||||
if (cb)
|
||||
tt->cb = cb;
|
||||
if (data)
|
||||
tt->data = data;
|
||||
|
||||
instance()->task(tt);
|
||||
// tickets were copied, clean up
|
||||
delete tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskSync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data)
|
||||
{
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
types.push_back(type);
|
||||
taskSync(types, task, data);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskSync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data)
|
||||
{
|
||||
if (isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskSync called with an asynchronous task!" << std::endl;
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
tt->async = false;
|
||||
tt->task = task;
|
||||
tt->types = types;
|
||||
if (data)
|
||||
tt->data = data;
|
||||
|
||||
instance()->task(tt);
|
||||
// call done, clean up
|
||||
delete tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskError(taskTicket *t)
|
||||
{
|
||||
taskDone(t, autoProxyStatus::error);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status)
|
||||
{
|
||||
bool cleanUp = false;
|
||||
|
||||
t->result = status;
|
||||
if (t->cb) {
|
||||
t->cb->taskFinished(t);
|
||||
if (t != NULL) {
|
||||
// callack did not clean up properly
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish callback did not clean up!" << std::endl;
|
||||
cleanUp = true;
|
||||
}
|
||||
} else if (t->async){
|
||||
// async and no callback
|
||||
// we must take care of deleting
|
||||
cleanUp = true;
|
||||
if(t->data)
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish async call with data attached but no callback set!" << std::endl;
|
||||
}
|
||||
|
||||
if (cleanUp) {
|
||||
if (t->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish will try to delete void pointer!" << std::endl;
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete t->data;
|
||||
#pragma GCC diagnostic pop
|
||||
t->data = NULL;
|
||||
}
|
||||
delete t;
|
||||
t = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
taskTicket *rsAutoProxyMonitor::getTicket()
|
||||
{
|
||||
taskTicket *tt = new taskTicket();
|
||||
tt->cb = NULL;
|
||||
tt->data = NULL;
|
||||
tt->async = true;
|
||||
tt->result = autoProxyStatus::undefined;
|
||||
return tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
if (mRSShutDown && ticket->task == autoProxyTask::stop) {
|
||||
mProxies.erase(ticket->types.front());
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
if (ticket->data) {
|
||||
std::cerr << "rsAutoProxyMonitor::taskFinished data set. Will try to delete void pointer" << std::endl;
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete ticket->data;
|
||||
#pragma GCC diagnostic pop
|
||||
ticket->data = NULL;
|
||||
}
|
||||
delete ticket;
|
||||
ticket = NULL;
|
||||
}
|
||||
|
||||
autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType_enum t)
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator itService;
|
||||
if ((itService = mProxies.find(t)) != mProxies.end()) {
|
||||
return itService->second;
|
||||
}
|
||||
std::cerr << "sAutoProxyMonitor::lookUpService no service for type " << t << " found!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::isAsyncTask(autoProxyTask::autoProxyTask_enum t)
|
||||
{
|
||||
switch (t) {
|
||||
case autoProxyTask::start:
|
||||
case autoProxyTask::stop:
|
||||
case autoProxyTask::receiveKey:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
216
libretroshare/src/services/autoproxy/rsautoproxymonitor.h
Normal file
@ -0,0 +1,216 @@
|
||||
#ifndef RSAUTOPROXYMONITOR_H
|
||||
#define RSAUTOPROXYMONITOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <util/rsthreads.h>
|
||||
|
||||
class autoProxyCallback;
|
||||
|
||||
namespace autoProxyType {
|
||||
enum autoProxyType_enum {
|
||||
I2PBOB
|
||||
};
|
||||
}
|
||||
|
||||
namespace autoProxyTask {
|
||||
enum autoProxyTask_enum {
|
||||
/* async tasks */
|
||||
start, ///< start up proxy
|
||||
stop, ///< shut down proxy
|
||||
receiveKey, ///< renew proxy key (if any)
|
||||
proxyStatusCheck, ///< use to check if the proxy is still running
|
||||
/* sync tasks */
|
||||
status, ///< get status from auto proxy
|
||||
getSettings, ///< get setting from auto proxy
|
||||
setSettings, ///< set setting of auto proxy
|
||||
reloadConfig, ///< signal config reload/rebuild
|
||||
getErrorInfo ///< get error information from auto proxy
|
||||
};
|
||||
}
|
||||
|
||||
namespace autoProxyStatus {
|
||||
enum autoProxyStatus_enum {
|
||||
undefined, ///< undefined - usually not yet set
|
||||
disabled, ///< used when a task cannot be done (e.g. a disabled service cannot be startet or stopped)
|
||||
offline, ///< proxy is not set up
|
||||
online, ///< proxy is set up
|
||||
ok, ///< generic ok
|
||||
error ///< generic error
|
||||
};
|
||||
}
|
||||
|
||||
struct taskTicket {
|
||||
///
|
||||
/// \brief types auto proxy service types that should get the ticket
|
||||
///
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
|
||||
///
|
||||
/// \brief task the task to satisfy
|
||||
///
|
||||
autoProxyTask::autoProxyTask_enum task;
|
||||
|
||||
///
|
||||
/// \brief cb (optional) callback that gets called once the task is done
|
||||
///
|
||||
autoProxyCallback *cb;
|
||||
|
||||
///
|
||||
/// \brief result (optional) result
|
||||
///
|
||||
autoProxyStatus::autoProxyStatus_enum result;
|
||||
|
||||
///
|
||||
/// \brief data (optional) service dependent data
|
||||
///
|
||||
/// Needs to be allocated and freed by caller!
|
||||
///
|
||||
void *data;
|
||||
|
||||
///
|
||||
/// \brief async is the call Asynchronous
|
||||
///
|
||||
/// Will create a copy of the ticket for each
|
||||
/// service and delete the original ticket.
|
||||
///
|
||||
bool async;
|
||||
};
|
||||
|
||||
class autoProxyCallback {
|
||||
public:
|
||||
///
|
||||
/// \brief taskFinished called when a task is finished
|
||||
/// \param ticket
|
||||
///
|
||||
/// Remove everything: ticket and attached data if any!
|
||||
///
|
||||
virtual void taskFinished(taskTicket *&ticket) = 0;
|
||||
};
|
||||
|
||||
class autoProxyService {
|
||||
public:
|
||||
///
|
||||
/// \brief isEnabled must be provided to directly get a result without going through the ticket system
|
||||
/// \return whether the auto proxy service is enabled or not
|
||||
///
|
||||
virtual bool isEnabled() = 0;
|
||||
|
||||
///
|
||||
/// \brief initialSetup used when creating a node
|
||||
/// \param addr new address for the hidden service
|
||||
/// \param port new port for the hidden service
|
||||
/// \return true on success
|
||||
///
|
||||
/// This function is used to do an initial setup when creating a new hidden node.
|
||||
/// Nothing has been set up at this point to the auto proxy service must take care
|
||||
/// of everything (e.g. starting (and stoping) of needed threads)
|
||||
///
|
||||
virtual bool initialSetup(std::string &addr, uint16_t &port) = 0;
|
||||
|
||||
///
|
||||
/// \brief processTaskAsync adds a ticket to the auto proxies task list
|
||||
/// \param ticket
|
||||
///
|
||||
/// Don't call the callback in this function as this can cause dead locks!
|
||||
///
|
||||
virtual void processTaskAsync(taskTicket *ticket) = 0;
|
||||
|
||||
///
|
||||
/// \brief processTaskSync taskTicket must be satisfied immediately
|
||||
/// \param ticket
|
||||
///
|
||||
virtual void processTaskSync(taskTicket *ticket) = 0;
|
||||
};
|
||||
|
||||
class rsAutoProxyMonitor : autoProxyCallback
|
||||
{
|
||||
public:
|
||||
static rsAutoProxyMonitor *instance();
|
||||
|
||||
///
|
||||
/// \brief addProxy adds a new auto proxy service to the monitor
|
||||
/// \param type type of the new auto proxy service
|
||||
/// \param service pointer to the service
|
||||
///
|
||||
void addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service);
|
||||
|
||||
// global functions
|
||||
void startAll();
|
||||
void stopAll();
|
||||
void stopAllRSShutdown();
|
||||
bool isEnabled(autoProxyType::autoProxyType_enum t);
|
||||
// use this when creating a new node
|
||||
bool initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port);
|
||||
|
||||
///
|
||||
/// \brief task Sends a task to all requested services
|
||||
/// \param ticket Ticket containing required information
|
||||
///
|
||||
/// There are two kind of tasks: asyn and sync.
|
||||
/// All tasks that involve communication with the target program (e.g. I2P or Tor) are asynchronous.
|
||||
/// All other task are synchronous (e.g. getting settings)
|
||||
///
|
||||
///
|
||||
/// Synchronous:
|
||||
/// When you want to get the settings from a service you can call task() with a ticket only listing
|
||||
/// one service and data pointing to the service's settings class/struct. Set async to false so
|
||||
/// that the service gets your original ticket. Ther service will process the request (get settings)
|
||||
/// immediately and when the call to task() is done you can access the settings from your ticket.
|
||||
///
|
||||
/// When additionally a call back is set the service will also call it. This can cause deadlocks!
|
||||
///
|
||||
///
|
||||
/// Asynchronous:
|
||||
/// When you want to start up all services or request new keys for all services you can call task() with a list
|
||||
/// of services and set async to true. When each service has fullfilled the resquest he will
|
||||
/// use the callback. The original caller ticket will be copied and each call to the callback
|
||||
/// will use its copy of the original ticket. The attached data is not copied so each service gets
|
||||
/// the same pointer!
|
||||
///
|
||||
///
|
||||
/// Note:
|
||||
/// Services should not delet or allocate anything unless no call back is provided and it is an
|
||||
/// async call. In that case the service should delete the ticket and the attacked data.
|
||||
/// Otherwise the caller must take care of cleaning up.
|
||||
/// This class provides two wrappers to take care of this that should be used: taskError and taskDone
|
||||
///
|
||||
/// Note2:
|
||||
/// This function is private so that each user must use the wrappers taskAsync and taskSync that include
|
||||
/// more sanity checks
|
||||
///
|
||||
private:
|
||||
void task(taskTicket *ticket);
|
||||
|
||||
public:
|
||||
static void taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
|
||||
static void taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
|
||||
static void taskSync (autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
|
||||
static void taskSync (std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
|
||||
|
||||
// usefull helpers
|
||||
static void taskError(taskTicket *t);
|
||||
static void taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status);
|
||||
static taskTicket *getTicket();
|
||||
|
||||
// autoProxyCallback interface
|
||||
public:
|
||||
void taskFinished(taskTicket *&ticket);
|
||||
|
||||
private:
|
||||
rsAutoProxyMonitor();
|
||||
|
||||
autoProxyService *lookUpService(autoProxyType::autoProxyType_enum t);
|
||||
static bool isAsyncTask(autoProxyTask::autoProxyTask_enum t);
|
||||
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*> mProxies;
|
||||
bool mRSShutDown;
|
||||
RsMutex mLock;
|
||||
|
||||
static rsAutoProxyMonitor *mInstance;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RSAUTOPROXYMONITOR_H
|
@ -2259,7 +2259,7 @@ void p3MsgService::sendDistantMsgItem(RsMsgItem *msgitem)
|
||||
msg_serialized_data, msg_serialized_rssize,
|
||||
signing_key_id, grouter_message_id );
|
||||
RsGxsTransId gxsMailId;
|
||||
mGxsTransServ.sendMail( gxsMailId, GxsTransSubServices::P3_MSG_SERVICE,
|
||||
mGxsTransServ.sendData( gxsMailId, GxsTransSubServices::P3_MSG_SERVICE,
|
||||
signing_key_id, destination_key_id,
|
||||
msg_serialized_data, msg_serialized_rssize );
|
||||
|
||||
|
@ -90,7 +90,7 @@ static int clear_tou_socket_error(int s);
|
||||
|
||||
#include "tou.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
//static void BIO_set_shutdown(BIO *a,int s) { a->shutdown=s; }
|
||||
|
||||
static int BIO_get_shutdown(BIO *a) { return a->shutdown; }
|
||||
|
50
libretroshare/src/util/radix32.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef RADIX32_H
|
||||
#define RADIX32_H
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
class Radix32
|
||||
{
|
||||
public:
|
||||
static std::string encode(const std::vector<uint8_t> &in) {
|
||||
return encode(in.data(), in.size());
|
||||
}
|
||||
|
||||
static std::string encode(const uint8_t *data, size_t len) {
|
||||
std::string out = "";
|
||||
|
||||
size_t pos = 1;
|
||||
uint8_t bits = 8, index;
|
||||
uint16_t tmp = data[0]; // need min. 16 bits here
|
||||
while (bits > 0 || pos < len) {
|
||||
if (bits < 5) {
|
||||
if (pos < len) {
|
||||
tmp <<= 8;
|
||||
tmp |= data[pos++] & 0xFF;
|
||||
bits += 8;
|
||||
} else { // last byte
|
||||
tmp <<= (5 - bits);
|
||||
bits = 5;
|
||||
}
|
||||
}
|
||||
|
||||
bits -= 5;
|
||||
index = (tmp >> bits) & 0x1F;
|
||||
out.push_back(bintoasc()[index]);
|
||||
}
|
||||
|
||||
// append padding
|
||||
while(out.length() % 4 != 0)
|
||||
out.push_back('=');
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
static const inline char *bintoasc() { static const char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; return bta ; }
|
||||
};
|
||||
|
||||
#endif // RADIX32_H
|
@ -57,6 +57,10 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifndef __GLIBC__
|
||||
#define canonicalize_file_name(p) realpath(p, NULL)
|
||||
#endif
|
||||
|
||||
/****
|
||||
* #define RSDIR_DEBUG 1
|
||||
****/
|
||||
|
@ -126,3 +126,24 @@ std::string RsUtil::HashId(const std::string &id, bool reverse)
|
||||
// out << std::setprecision(15) << getCurrentTS();
|
||||
// return out.str();
|
||||
//}
|
||||
|
||||
std::vector<uint8_t> RsUtil::BinToSha256(const std::vector<uint8_t> &in)
|
||||
{
|
||||
std::vector<uint8_t> out;
|
||||
|
||||
SHA256_CTX *sha_ctx = new SHA256_CTX;
|
||||
uint8_t sha_hash[SHA256_DIGEST_LENGTH] = {0};
|
||||
|
||||
SHA256_Init(sha_ctx);
|
||||
SHA256_Update(sha_ctx, in.data(), in.size());
|
||||
SHA256_Final(sha_hash, sha_ctx);
|
||||
|
||||
for(uint16_t i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
out.push_back(sha_hash[i]);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
delete sha_ctx;
|
||||
return out;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace RsUtil {
|
||||
|
||||
@ -38,6 +39,7 @@ std::string BinToHex(const char *arr, const uint32_t len);
|
||||
std::string BinToHex(const unsigned char *arr, const uint32_t len);
|
||||
std::string NumberToString(uint64_t n, bool hex=false);
|
||||
std::string HashId(const std::string &id, bool reverse = false);
|
||||
std::vector<uint8_t> BinToSha256(const std::vector<uint8_t> &in);
|
||||
|
||||
//std::string AccurateTimeString();
|
||||
|
||||
|
@ -508,7 +508,7 @@ bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
|
||||
|
||||
std::string RsRecogn::getRsaKeyId(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int len = BN_num_bytes(pubkey -> n);
|
||||
unsigned char tmp[len];
|
||||
BN_bn2bin(pubkey -> n, tmp);
|
||||
|
@ -61,6 +61,16 @@ int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) {
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
void RsThread::go()
|
||||
{
|
||||
mShouldStopSemaphore.set(0) ;
|
||||
mHasStoppedSemaphore.set(0) ;
|
||||
|
||||
runloop();
|
||||
|
||||
mHasStoppedSemaphore.set(1);
|
||||
mShouldStopSemaphore.set(0);
|
||||
}
|
||||
void *RsThread::rsthread_init(void* p)
|
||||
{
|
||||
RsThread *thread = (RsThread *) p;
|
||||
@ -76,7 +86,7 @@ void *RsThread::rsthread_init(void* p)
|
||||
std::cerr << "[Thread ID:" << std::hex << pthread_self() << std::dec << "] thread is started. Calling runloop()..." << std::endl;
|
||||
#endif
|
||||
|
||||
thread -> runloop();
|
||||
thread->go();
|
||||
return NULL;
|
||||
}
|
||||
RsThread::RsThread()
|
||||
@ -216,14 +226,11 @@ RsTickingThread::RsTickingThread()
|
||||
|
||||
void RsSingleJobThread::runloop()
|
||||
{
|
||||
mHasStoppedSemaphore.set(0) ;
|
||||
run() ;
|
||||
}
|
||||
|
||||
void RsTickingThread::runloop()
|
||||
{
|
||||
mHasStoppedSemaphore.set(0) ; // first time we are 100% the thread is actually running.
|
||||
|
||||
#ifdef DEBUG_THREADS
|
||||
THREAD_DEBUG << "RsTickingThread::runloop(). Setting stopped=0" << std::endl;
|
||||
#endif
|
||||
@ -235,7 +242,6 @@ void RsTickingThread::runloop()
|
||||
#ifdef DEBUG_THREADS
|
||||
THREAD_DEBUG << "pqithreadstreamer::runloop(): asked to stop. setting hasStopped=1, and returning. Thread ends." << std::endl;
|
||||
#endif
|
||||
mHasStoppedSemaphore.set(1);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -263,6 +263,7 @@ class RsThread
|
||||
|
||||
protected:
|
||||
virtual void runloop() =0; /* called once the thread is started. Should be overloaded by subclasses. */
|
||||
void go() ; // this one calls runloop and also sets the flags correctly when the thread is finished running.
|
||||
|
||||
RsSemaphore mHasStoppedSemaphore;
|
||||
RsSemaphore mShouldStopSemaphore;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#if defined(__linux__) && defined(__GLIBC__)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <execinfo.h>
|
||||
@ -110,13 +110,13 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames
|
||||
free(symbollist);
|
||||
}
|
||||
|
||||
#else // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#else // defined(__linux__) && defined(__GLIBC__)
|
||||
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63)
|
||||
{
|
||||
(void) max_frames;
|
||||
|
||||
fprintf(out, "TODO: 2016/01/01 print_stacktrace not implemented yet for WINDOWS_SYS and ANDROID\n");
|
||||
}
|
||||
#endif // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#endif // defined(__linux__) && defined(__GLIBC__)
|
||||
|
||||
#endif // _STACKTRACE_H_
|
||||
|
@ -45,7 +45,7 @@ void test_secret_key(const ops_secret_key_t *skey)
|
||||
{
|
||||
RSA* test=RSA_new();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
test->n=BN_dup(skey->public_key.key.rsa.n);
|
||||
test->e=BN_dup(skey->public_key.key.rsa.e);
|
||||
test->d=BN_dup(skey->key.rsa.d);
|
||||
@ -402,7 +402,7 @@ ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
|
||||
|
||||
osig=DSA_SIG_new();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
osig->r=sig->r;
|
||||
osig->s=sig->s;
|
||||
#else
|
||||
@ -417,7 +417,7 @@ ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
|
||||
already_said=ops_true ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
osig->r=NULL; // in this case, the values are not copied.
|
||||
osig->s=NULL;
|
||||
#endif
|
||||
@ -427,7 +427,7 @@ ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
|
||||
}
|
||||
|
||||
odsa=DSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
odsa->p=dsa->p;
|
||||
odsa->q=dsa->q;
|
||||
odsa->g=dsa->g;
|
||||
@ -471,7 +471,7 @@ ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
|
||||
return ops_false ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
osig->r=NULL;
|
||||
osig->s=NULL;
|
||||
|
||||
@ -503,7 +503,7 @@ int ops_rsa_public_decrypt(unsigned char *out,const unsigned char *in,
|
||||
int n;
|
||||
|
||||
orsa=RSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=rsa->n;
|
||||
orsa->e=rsa->e;
|
||||
#else
|
||||
@ -512,7 +512,7 @@ int ops_rsa_public_decrypt(unsigned char *out,const unsigned char *in,
|
||||
|
||||
n=RSA_public_decrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=orsa->e=NULL;
|
||||
#endif
|
||||
RSA_free(orsa);
|
||||
@ -538,7 +538,7 @@ int ops_rsa_private_encrypt(unsigned char *out,const unsigned char *in,
|
||||
int n;
|
||||
|
||||
orsa=RSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=rsa->n; // XXX: do we need n?
|
||||
orsa->d=srsa->d;
|
||||
orsa->p=srsa->q;
|
||||
@ -564,7 +564,7 @@ int ops_rsa_private_encrypt(unsigned char *out,const unsigned char *in,
|
||||
|
||||
n=RSA_private_encrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=orsa->d=orsa->p=orsa->q=NULL;
|
||||
orsa->e=NULL;
|
||||
#endif
|
||||
@ -592,7 +592,7 @@ int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in,
|
||||
char errbuf[1024];
|
||||
|
||||
orsa=RSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=rsa->n; // XXX: do we need n?
|
||||
orsa->d=srsa->d;
|
||||
orsa->p=srsa->q;
|
||||
@ -618,7 +618,7 @@ int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in,
|
||||
ERR_error_string(err,&errbuf[0]);
|
||||
fprintf(stderr,"openssl error : %s\n",errbuf);
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=orsa->d=orsa->p=orsa->q=NULL;
|
||||
orsa->e=NULL;
|
||||
#endif
|
||||
@ -644,7 +644,7 @@ int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in,
|
||||
// printf("ops_rsa_public_encrypt: length=%ld\n", length);
|
||||
|
||||
orsa=RSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=rsa->n;
|
||||
orsa->e=rsa->e;
|
||||
#else
|
||||
@ -664,7 +664,7 @@ int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in,
|
||||
BIO_free(fd_out) ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
orsa->n=orsa->e=NULL;
|
||||
#endif
|
||||
RSA_free(orsa);
|
||||
@ -744,7 +744,7 @@ ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e,
|
||||
skey->public_key.days_valid=0;
|
||||
skey->public_key.algorithm= OPS_PKA_RSA;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
skey->public_key.key.rsa.n=BN_dup(rsa->n);
|
||||
skey->public_key.key.rsa.e=BN_dup(rsa->e);
|
||||
skey->key.rsa.d=BN_dup(rsa->d);
|
||||
@ -766,7 +766,7 @@ ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e,
|
||||
skey->octet_count=0;
|
||||
skey->checksum=0;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
skey->key.rsa.p=BN_dup(rsa->p);
|
||||
skey->key.rsa.q=BN_dup(rsa->q);
|
||||
skey->key.rsa.u=BN_mod_inverse(NULL,rsa->p, rsa->q, ctx);
|
||||
@ -888,7 +888,7 @@ DSA_SIG* ops_dsa_sign(unsigned char* hashbuf, unsigned hashsize, const ops_dsa_s
|
||||
DSA_SIG *dsasig;
|
||||
|
||||
odsa=DSA_new();
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
odsa->p=dsa->p;
|
||||
odsa->q=dsa->q;
|
||||
odsa->g=dsa->g;
|
||||
@ -901,7 +901,7 @@ DSA_SIG* ops_dsa_sign(unsigned char* hashbuf, unsigned hashsize, const ops_dsa_s
|
||||
|
||||
dsasig=DSA_do_sign(hashbuf,hashsize,odsa);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL;
|
||||
#endif
|
||||
DSA_free(odsa);
|
||||
|
@ -298,7 +298,7 @@ static ops_boolean_t dsa_sign(ops_hash_t *hash, const ops_dsa_public_key_t *dsa,
|
||||
dsasig=ops_dsa_sign(hashbuf, hashsize, sdsa, dsa);
|
||||
|
||||
// convert and write the sig out to memory
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ops_write_mpi(dsasig->r, cinfo);
|
||||
ops_write_mpi(dsasig->s, cinfo);
|
||||
#else
|
||||
|
@ -149,6 +149,8 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent)
|
||||
connect(ui.node_input, SIGNAL(textChanged(QString)), this, SLOT(updateCheckLabels()));
|
||||
connect(ui.reuse_existing_node_CB, SIGNAL(toggled(bool)), this, SLOT(updateCheckLabels()));
|
||||
|
||||
connect(ui.cbUseBob, SIGNAL(clicked(bool)), this, SLOT(useBobChecked(bool)));;
|
||||
|
||||
entropy_timer = new QTimer ;
|
||||
entropy_timer->start(20) ;
|
||||
QObject::connect(entropy_timer,SIGNAL(timeout()),this,SLOT(grabMouse())) ;
|
||||
@ -161,12 +163,12 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent)
|
||||
ui.keylength_comboBox->addItem("Very high (4096 bits)", QVariant(4096));
|
||||
|
||||
#if QT_VERSION >= 0x040700
|
||||
ui.node_input->setPlaceholderText(tr("[Required] Examples: Home, Laptop,...(Visible to friends).")) ;
|
||||
ui.hiddenaddr_input->setPlaceholderText(tr("[Optional] Tor/I2P address (Example: xa76giaf6ifda7ri63i263.onion)")) ;
|
||||
ui.name_input->setPlaceholderText(tr("[Required] Visible to friends, and friends of friends."));
|
||||
ui.nickname_input->setPlaceholderText(tr("[Optional] Used to write in chat rooms and forums. Can be set later."));
|
||||
ui.password_input->setPlaceholderText(tr("[Required] This password protects your data. Dont forget it!"));
|
||||
ui.password_input_2->setPlaceholderText(tr("[Required] Type the same password again here."));
|
||||
ui.node_input->setPlaceholderText(tr("Node name")) ;
|
||||
ui.hiddenaddr_input->setPlaceholderText(tr("Tor/I2P address")) ;
|
||||
ui.name_input->setPlaceholderText(tr("Username"));
|
||||
ui.nickname_input->setPlaceholderText(tr("Identity name"));
|
||||
ui.password_input->setPlaceholderText(tr("Password"));
|
||||
ui.password_input_2->setPlaceholderText(tr("Password again"));
|
||||
#endif
|
||||
|
||||
ui.nickname_input->setMaxLength(RSID_MAXIMUM_NICKNAME_SIZE);
|
||||
@ -240,7 +242,7 @@ void GenCertDialog::mouseMoveEvent(QMouseEvent *e)
|
||||
|
||||
void GenCertDialog::setupState()
|
||||
{
|
||||
bool adv_state = ui.adv_checkbox->isChecked();
|
||||
bool adv_state = ui.adv_checkbox->isChecked();
|
||||
|
||||
if(!adv_state)
|
||||
{
|
||||
@ -294,12 +296,13 @@ void GenCertDialog::setupState()
|
||||
ui.entropy_bar->setVisible(true);
|
||||
|
||||
ui.genButton->setVisible(true);
|
||||
ui.genButton->setText(generate_new?tr("Generate new profile and node"):tr("Generate new node"));
|
||||
ui.genButton->setText(generate_new?tr("Generate"):tr("Generate"));
|
||||
|
||||
ui.hiddenaddr_input->setVisible(hidden_state);
|
||||
ui.hiddenaddr_label->setVisible(hidden_state);
|
||||
ui.hiddenport_label->setVisible(hidden_state);
|
||||
ui.hiddenport_spinBox->setVisible(hidden_state);
|
||||
ui.cbUseBob->setVisible(hidden_state);
|
||||
|
||||
if(mEntropyOk && mAllFieldsOk)
|
||||
{
|
||||
@ -379,7 +382,22 @@ void GenCertDialog::updateCheckLabels()
|
||||
else
|
||||
ui.randomness_check_LB->setPixmap(QPixmap(IMAGE_BAD)) ;
|
||||
|
||||
setupState();
|
||||
setupState();
|
||||
}
|
||||
|
||||
void GenCertDialog::useBobChecked(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with BOB enabled"));
|
||||
ui.hiddenaddr_label->setText(tr("I2P instance address"));
|
||||
|
||||
ui.hiddenport_spinBox->setEnabled(false);
|
||||
} else {
|
||||
ui.hiddenaddr_input->setPlaceholderText(tr("hidden service address"));
|
||||
ui.hiddenaddr_label->setText(tr("hidden address"));
|
||||
|
||||
ui.hiddenport_spinBox->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool GenCertDialog::importIdentity()
|
||||
@ -454,15 +472,13 @@ void GenCertDialog::genPerson()
|
||||
{
|
||||
std::string hl = ui.hiddenaddr_input->text().toStdString();
|
||||
uint16_t port = ui.hiddenport_spinBox->value();
|
||||
if (!RsInit::SetHiddenLocation(hl, port)) /* parses it */
|
||||
{
|
||||
/* Message Dialog */
|
||||
QMessageBox::warning(this,
|
||||
tr("Invalid hidden node"),
|
||||
tr("Please enter a valid address of the form: 31769173498.onion:7800 or [52 characters].b32.i2p"),
|
||||
QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
bool useBob = ui.cbUseBob->isChecked();
|
||||
|
||||
if (useBob && hl.empty())
|
||||
hl = "127.0.0.1";
|
||||
|
||||
RsInit::SetHiddenLocation(hl, port, useBob); /* parses it */
|
||||
|
||||
isHiddenLoc = true;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ private slots:
|
||||
void switchReuseExistingNode();
|
||||
void grabMouse();
|
||||
void updateCheckLabels();
|
||||
void useBobChecked(bool checked);
|
||||
|
||||
private:
|
||||
void initKeyList();
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>533</width>
|
||||
<height>544</height>
|
||||
<width>520</width>
|
||||
<height>541</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -34,13 +34,16 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<widget class="QFrame" name="profileframe">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
@ -48,13 +51,16 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="images.qrc">:/images/logo/logo_spash2.png</pixmap>
|
||||
<pixmap resource="images.qrc">:/images/logo/logo_web_nobackground.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
@ -105,19 +111,63 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="profile_frame">
|
||||
<widget class="QGroupBox" name="profile_groupBox">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="profilGLayout">
|
||||
<item row="14" column="2">
|
||||
<widget class="QComboBox" name="keylength_comboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>PGP Key Length</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<widget class="QLabel" name="randomness_label_">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/randomness.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLabel" name="password_check_LB">
|
||||
<property name="text">
|
||||
@ -125,17 +175,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="keylength_label">
|
||||
<property name="text">
|
||||
<string>PGP key length</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<item row="8" column="2">
|
||||
<widget class="QLineEdit" name="password_input_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
@ -163,42 +203,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="password_label">
|
||||
<property name="toolTip">
|
||||
<string>This password is for PGP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QComboBox" name="keylength_comboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="password_label_2">
|
||||
<property name="toolTip">
|
||||
<string>This password is for PGP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Password (check)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="2">
|
||||
<widget class="QProgressBar" name="entropy_bar">
|
||||
<property name="sizePolicy">
|
||||
@ -229,7 +233,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<item row="15" column="2">
|
||||
<widget class="QComboBox" name="nodeType_CB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@ -271,16 +275,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="node_label">
|
||||
<property name="text">
|
||||
<string>Node name</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="profile_name_check_LB">
|
||||
<property name="text">
|
||||
@ -365,7 +359,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<item row="8" column="3">
|
||||
<widget class="QLabel" name="password2_check_LB">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@ -394,46 +388,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="name_label">
|
||||
<property name="text">
|
||||
<string>Profile name</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Randomness</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_nodeType">
|
||||
<property name="text">
|
||||
<string>Node type</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="hiddenaddr_label">
|
||||
<property name="text">
|
||||
<string>hidden address</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="2">
|
||||
<layout class="QHBoxLayout" name="hiddenInfoHLayout">
|
||||
<property name="spacing">
|
||||
@ -496,22 +450,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUseBob">
|
||||
<property name="text">
|
||||
<string>Use BOB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="nickname_label">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Chat identity</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<item row="9" column="2">
|
||||
<widget class="QLineEdit" name="nickname_input">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@ -564,6 +512,191 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="name_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/person.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="nickname_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/chat-lobbies.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="node_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/network.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLabel" name="keylength_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/keyring.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="password_label_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This password is for PGP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/password.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="password_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This password is for PGP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/password.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<widget class="QLabel" name="hiddenaddr_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/hidden.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QLabel" name="label_nodeType">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/netgraph.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1403,7 +1403,7 @@ void NewsFeed::openChat(const RsPeerId &peerId)
|
||||
ChatDialog::chatFriend(ChatId(peerId));
|
||||
}
|
||||
|
||||
void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const RsGxsMessageId &/*msgId*/, const QString &/*title*/)
|
||||
void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const QVector<RsGxsMessageId>& versions,const RsGxsMessageId &/*msgId*/, const QString &/*title*/)
|
||||
{
|
||||
std::cerr << "NewsFeed::openComments() Not Handled Yet";
|
||||
std::cerr << std::endl;
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
virtual QScrollArea *getScrollArea();
|
||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
||||
virtual void openChat(const RsPeerId& peerId);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
static void testFeeds(uint notifyFlags);
|
||||
static void testFeed(FeedNotify *feedNotify);
|
||||
|
@ -411,7 +411,13 @@ void PostedItem::loadComments()
|
||||
if (mFeedHolder)
|
||||
{
|
||||
QString title = QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
|
||||
mFeedHolder->openComments(0, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, title);
|
||||
|
||||
#warning (csoler) Posted item versions not handled yet. When it is the case, start here.
|
||||
|
||||
QVector<RsGxsMessageId> post_versions ;
|
||||
post_versions.push_back(mPost.mMeta.mMsgId) ;
|
||||
|
||||
mFeedHolder->openComments(0, mPost.mMeta.mGroupId, post_versions,mPost.mMeta.mMsgId, title);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,9 +139,9 @@ void PostedListWidget::openChat(const RsPeerId & /*peerId*/)
|
||||
return;
|
||||
}
|
||||
|
||||
void PostedListWidget::openComments(uint32_t /*feed_type*/, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title)
|
||||
void PostedListWidget::openComments(uint32_t /*feed_type*/, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title)
|
||||
{
|
||||
emit loadComment(groupId, msgId, title);
|
||||
emit loadComment(groupId, versions,msgId, title);
|
||||
}
|
||||
|
||||
void PostedListWidget::newPost()
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
virtual QScrollArea *getScrollArea();
|
||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
||||
virtual void openChat(const RsPeerId& peerId);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &versions, const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
/* GXS functions */
|
||||
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>516</width>
|
||||
<height>569</height>
|
||||
<width>440</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -17,7 +17,10 @@
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="StartDialogVLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -31,296 +34,324 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="mainGLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
<widget class="QFrame" name="loginframe">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<layout class="QGridLayout" name="topGLayout">
|
||||
<item row="0" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="rsTopLogo">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>85</red>
|
||||
<green>170</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>85</red>
|
||||
<green>170</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>118</red>
|
||||
<green>116</green>
|
||||
<blue>108</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="images.qrc">:/images/logo/logo_spash2.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="2" rowspan="2">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QGroupBox" name="profilGBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<layout class="QGridLayout" name="loginframeGLayout">
|
||||
<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>9</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<layout class="QGridLayout" name="topGLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<spacer name="topLHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Profile - Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="maximumSize">
|
||||
<widget class="QLabel" name="rsTopLogo">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>85</red>
|
||||
<green>170</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>85</red>
|
||||
<green>170</green>
|
||||
<blue>255</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>118</red>
|
||||
<green>116</green>
|
||||
<blue>108</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/person.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="loadName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/password.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="password_input">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="autologin_checkbox">
|
||||
<property name="text">
|
||||
<string>Remember Password</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Log In</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="images.qrc">:/images/logo/logo_web_nobackground.png</pixmap>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="topRHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="2" rowspan="2">
|
||||
<spacer name="profileRHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<spacer name="mainVSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<spacer name="profileLHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QGroupBox" name="profilGBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="profilGBoxGLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="loadName_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/person.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="loadName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="password_label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="icons.qrc">:/icons/svg/password.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="password_input">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="autologin_checkbox">
|
||||
<property name="text">
|
||||
<string>Remember Password</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Log In</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="newHLayout">
|
||||
<item>
|
||||
<spacer name="newHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelProfile">
|
||||
<property name="toolTip">
|
||||
<string>Opens a dialog for creating a new profile or
|
||||
adding locations to an existing profile.
|
||||
The current identities/locations will not be affected.</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="Create new Profile..."><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">New Profile/Node</span></a></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelProfile">
|
||||
<property name="toolTip">
|
||||
<string>Opens a dialog for creating a new profile or
|
||||
adding locations to an existing profile.
|
||||
The current identities/locations will not be affected.</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="Create new Profile..."><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">Manage profiles and nodes...</span></a></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -73,7 +73,7 @@
|
||||
*****/
|
||||
|
||||
ChatWidget::ChatWidget(QWidget *parent) :
|
||||
QWidget(parent), ui(new Ui::ChatWidget)
|
||||
QWidget(parent), sendingBlocked(false), ui(new Ui::ChatWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -416,9 +416,20 @@ ChatWidget::ChatType ChatWidget::chatType()
|
||||
return CHATTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
void ChatWidget::blockSending(QString msg) { ui->sendButton->setToolTip(msg); }
|
||||
void ChatWidget::blockSending(QString msg)
|
||||
{
|
||||
#ifndef RS_ASYNC_CHAT
|
||||
sendingBlocked = true;
|
||||
ui->sendButton->setEnabled(false);
|
||||
#endif
|
||||
ui->sendButton->setToolTip(msg);
|
||||
}
|
||||
|
||||
void ChatWidget::unblockSending() { updateLenOfChatTextEdit(); }
|
||||
void ChatWidget::unblockSending()
|
||||
{
|
||||
sendingBlocked = false;
|
||||
updateLenOfChatTextEdit();
|
||||
}
|
||||
|
||||
void ChatWidget::processSettings(bool load)
|
||||
{
|
||||
@ -1130,6 +1141,8 @@ void ChatWidget::updateStatusTyping()
|
||||
|
||||
void ChatWidget::updateLenOfChatTextEdit()
|
||||
{
|
||||
if(sendingBlocked) return;
|
||||
|
||||
QTextEdit *chatWidget = ui->chatTextEdit;
|
||||
QString text;
|
||||
RsHtml::optimizeHtml(chatWidget, text);
|
||||
@ -1429,7 +1442,8 @@ void ChatWidget::colorChanged()
|
||||
void ChatWidget::chooseFont()
|
||||
{
|
||||
bool ok;
|
||||
QFont font = QFontDialog::getFont(&ok, currentFont, this);
|
||||
//Use NULL as parent as with this QFontDialog don't take care of title nether options.
|
||||
QFont font = QFontDialog::getFont(&ok, currentFont, NULL, tr("Choose your font."),QFontDialog::DontUseNativeDialog);
|
||||
if (ok) {
|
||||
currentFont = font;
|
||||
setFont();
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <retroshare/rsfiles.h>
|
||||
#include <util/rsdeprecate.h>
|
||||
|
||||
class QAction;
|
||||
class QTextEdit;
|
||||
@ -79,8 +78,9 @@ public:
|
||||
ChatId getChatId();
|
||||
ChatType chatType();
|
||||
|
||||
RS_DEPRECATED void blockSending(QString msg);
|
||||
RS_DEPRECATED void unblockSending();
|
||||
// allow/disallow sendng of messages
|
||||
void blockSending(QString msg);
|
||||
void unblockSending();
|
||||
|
||||
bool hasNewMessages() { return newMessages; }
|
||||
bool isTyping() { return typing; }
|
||||
@ -216,6 +216,8 @@ private:
|
||||
bool typing;
|
||||
int peerStatus;
|
||||
|
||||
bool sendingBlocked;
|
||||
|
||||
time_t lastStatusSendTime;
|
||||
|
||||
ChatStyle chatStyle;
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
virtual QScrollArea *getScrollArea() = 0;
|
||||
virtual void deleteFeedItem(QWidget *item, uint32_t type) = 0;
|
||||
virtual void openChat(const RsPeerId& peerId) = 0;
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title) = 0;
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title)=0;
|
||||
|
||||
// Workaround for QTBUG-3372
|
||||
void lockLayout(QWidget *feedItem, bool lock);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "util/HandleRichText.h"
|
||||
#include "util/DateTime.h"
|
||||
#include "util/stringutil.h"
|
||||
#include "gui/gxschannels/CreateGxsChannelMsg.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -63,9 +64,25 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId,
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
QVector<RsGxsMessageId> v;
|
||||
bool self = false;
|
||||
|
||||
for(std::set<RsGxsMessageId>::const_iterator it(post.mOlderVersions.begin());it!=post.mOlderVersions.end();++it)
|
||||
{
|
||||
if(*it == post.mMeta.mMsgId)
|
||||
self = true ;
|
||||
|
||||
v.push_back(*it) ;
|
||||
}
|
||||
if(!self)
|
||||
v.push_back(post.mMeta.mMsgId);
|
||||
|
||||
setMessageVersions(v) ;
|
||||
|
||||
setup();
|
||||
|
||||
setGroup(group, false);
|
||||
//setGroup(group, false);
|
||||
requestGroup();
|
||||
setPost(post);
|
||||
requestComment();
|
||||
}
|
||||
@ -127,6 +144,7 @@ void GxsChannelPostItem::setup()
|
||||
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
|
||||
|
||||
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void)));
|
||||
connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void)));
|
||||
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
|
||||
|
||||
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
|
||||
@ -166,6 +184,12 @@ bool GxsChannelPostItem::setGroup(const RsGxsChannelGroup &group, bool doFill)
|
||||
|
||||
mGroup = group;
|
||||
|
||||
// if not publisher, hide the edit button. Without the publish key, there's no way to edit a message.
|
||||
|
||||
std::cerr << "Group subscribe flags = " << std::hex << mGroup.mMeta.mSubscribeFlags << std::dec << std::endl;
|
||||
if(!IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags))
|
||||
ui->editButton->hide();
|
||||
|
||||
if (doFill) {
|
||||
fill();
|
||||
}
|
||||
@ -301,7 +325,7 @@ void GxsChannelPostItem::loadComment(const uint32_t &token)
|
||||
if (comNb == 1) {
|
||||
sComButText = sComButText.append("(1)");
|
||||
} else if (comNb > 1) {
|
||||
sComButText = tr("Comments").append("(%1)").arg(comNb);
|
||||
sComButText = tr("Comments ").append("(%1)").arg(comNb);
|
||||
}
|
||||
ui->commentButton->setText(sComButText);
|
||||
}
|
||||
@ -690,6 +714,12 @@ void GxsChannelPostItem::download()
|
||||
updateItem();
|
||||
}
|
||||
|
||||
void GxsChannelPostItem::edit()
|
||||
{
|
||||
CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(mGroup.mMeta.mGroupId,mPost.mMeta.mMsgId);
|
||||
msgDialog->show();
|
||||
}
|
||||
|
||||
void GxsChannelPostItem::play()
|
||||
{
|
||||
std::list<SubFileItem *>::iterator it;
|
||||
|
@ -78,6 +78,7 @@ private slots:
|
||||
void readAndClearItem();
|
||||
void download();
|
||||
void play();
|
||||
void edit();
|
||||
void loadComments();
|
||||
|
||||
void readToggled(bool checked);
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>840</width>
|
||||
<height>180</height>
|
||||
<width>1052</width>
|
||||
<height>338</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gxsChannelPostItem_GLayout">
|
||||
@ -332,6 +332,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="editButton">
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -97,11 +97,12 @@ SubFileItem::SubFileItem(const RsFileHash &hash, const std::string &name, const
|
||||
|
||||
void SubFileItem::Setup()
|
||||
{
|
||||
connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( play ( void ) ) );
|
||||
connect( downloadButton, SIGNAL( clicked( void ) ), this, SLOT( download ( void ) ) );
|
||||
connect( cancelButton, SIGNAL( clicked( void ) ), this, SLOT( cancel ( void ) ) );
|
||||
connect( copyLinkButton, SIGNAL( clicked( void ) ), this, SLOT( copyLink ( void ) ) );
|
||||
connect( saveButton, SIGNAL( clicked( void ) ), this, SLOT( save ( void ) ) );
|
||||
connect( playButton, SIGNAL( clicked( ) ), this, SLOT( play ( ) ) );
|
||||
connect( downloadButton, SIGNAL( clicked( ) ), this, SLOT( download ( ) ) );
|
||||
connect( cancelButton, SIGNAL( clicked( ) ), this, SLOT( cancel( ) ) );
|
||||
connect( deleteButton, SIGNAL( clicked( ) ), this, SLOT( del( ) ) );
|
||||
connect( copyLinkButton, SIGNAL( clicked( ) ), this, SLOT( copyLink ( ) ) );
|
||||
connect( saveButton, SIGNAL( clicked( ) ), this, SLOT( save ( ) ) );
|
||||
|
||||
/* once off check - if remote, check if we have it
|
||||
* NB: This check might be expensive - and it'll happen often!
|
||||
@ -129,12 +130,21 @@ void SubFileItem::Setup()
|
||||
}
|
||||
}
|
||||
|
||||
deleteButton->setVisible(mFlag & SFI_FLAG_ALLOW_DELETE);
|
||||
downloadButton->setVisible(mMode < SFI_STATE_LOCAL);
|
||||
cancelButton->setVisible(mMode < SFI_STATE_LOCAL);
|
||||
|
||||
smaller();
|
||||
updateItemStatic();
|
||||
updateItem();
|
||||
}
|
||||
|
||||
|
||||
void SubFileItem::del()
|
||||
{
|
||||
emit wantsToBeDeleted();
|
||||
}
|
||||
|
||||
bool SubFileItem::done()
|
||||
{
|
||||
return (mMode >= SFI_STATE_LOCAL);
|
||||
@ -176,7 +186,7 @@ void SubFileItem::updateItemStatic()
|
||||
}
|
||||
|
||||
/* get full path for local file */
|
||||
if ((mMode == SFI_STATE_LOCAL) || (mMode == SFI_STATE_UPLOAD))
|
||||
if (((mMode == SFI_STATE_LOCAL) || (mMode == SFI_STATE_UPLOAD)))
|
||||
{
|
||||
#ifdef DEBUG_ITEM
|
||||
std::cerr << "SubFileItem::updateItemStatic() STATE=Local/Upload checking path";
|
||||
@ -190,7 +200,10 @@ void SubFileItem::updateItemStatic()
|
||||
/* look up path */
|
||||
if (!rsFiles->FileDetails(mFileHash, hintflags, fi))
|
||||
{
|
||||
mMode = SFI_STATE_ERROR;
|
||||
if(mFlag & SFI_FLAG_ASSUME_FILE_READY)
|
||||
mMode = SFI_STATE_REMOTE;
|
||||
else
|
||||
mMode = SFI_STATE_ERROR;
|
||||
#ifdef DEBUG_ITEM
|
||||
std::cerr << "SubFileItem::updateItemStatic() STATE=>Error No Details";
|
||||
std::cerr << std::endl;
|
||||
@ -241,6 +254,7 @@ void SubFileItem::updateItemStatic()
|
||||
case SFI_STATE_REMOTE:
|
||||
playButton->setEnabled(false);
|
||||
downloadButton->setEnabled(true);
|
||||
downloadButton->setVisible(true);
|
||||
cancelButton->setEnabled(false);
|
||||
|
||||
progressBar->setValue(0);
|
||||
|
@ -40,7 +40,9 @@ const uint32_t SFI_STATE_UPLOAD = 0x0006;
|
||||
const uint32_t SFI_TYPE_CHANNEL = 0x0010;
|
||||
const uint32_t SFI_TYPE_ATTACH = 0x0020;
|
||||
|
||||
const uint32_t SFI_FLAG_CREATE = 0x1000;
|
||||
const uint32_t SFI_FLAG_CREATE = 0x1000;
|
||||
const uint32_t SFI_FLAG_ALLOW_DELETE = 0x2000;
|
||||
const uint32_t SFI_FLAG_ASSUME_FILE_READY = 0x4000;
|
||||
|
||||
|
||||
//! This create a gui widget that allows users to access files shared by user
|
||||
@ -86,10 +88,14 @@ private slots:
|
||||
void toggle();
|
||||
|
||||
void cancel();
|
||||
void del();
|
||||
void save();
|
||||
|
||||
void updateItem();
|
||||
|
||||
signals:
|
||||
void wantsToBeDeleted();
|
||||
|
||||
private:
|
||||
void Setup();
|
||||
|
||||
|
@ -6,12 +6,21 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>464</width>
|
||||
<height>71</height>
|
||||
<width>547</width>
|
||||
<height>128</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@ -26,27 +35,6 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="fileLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">File Name</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
@ -210,6 +198,41 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="toolTip">
|
||||
<string>Remove this item</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/denied16.png</normaloff>:/images/denied16.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="fileLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">File Name</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -54,7 +54,7 @@ void GxsCommentContainer::setup()
|
||||
ui.tabWidget->hideCloseButton(index);
|
||||
}
|
||||
|
||||
void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title)
|
||||
void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title)
|
||||
{
|
||||
QString comments = title;
|
||||
if (title.length() > MAX_COMMENT_TITLE)
|
||||
@ -68,7 +68,7 @@ void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const RsGxsMess
|
||||
QWidget *commentHeader = createHeaderWidget(grpId, msgId);
|
||||
commentDialog->setCommentHeader(commentHeader);
|
||||
|
||||
commentDialog->commentLoad(grpId, msgId);
|
||||
commentDialog->commentLoad(grpId, msg_versions, msgId);
|
||||
|
||||
ui.tabWidget->addTab(commentDialog, comments);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
GxsCommentContainer(QWidget *parent = 0);
|
||||
void setup();
|
||||
|
||||
void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title);
|
||||
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
virtual GxsServiceDialog *createServiceDialog() = 0;
|
||||
virtual QString getServiceName() = 0;
|
||||
@ -67,9 +67,9 @@ public:
|
||||
|
||||
virtual ~GxsServiceDialog() { return; }
|
||||
|
||||
void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title)
|
||||
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title)
|
||||
{
|
||||
mContainer->commentLoad(grpId, msgId, title);
|
||||
mContainer->commentLoad(grpId, msg_versions,msgId, title);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -59,20 +59,16 @@ GxsCommentDialog::~GxsCommentDialog()
|
||||
delete(ui);
|
||||
}
|
||||
|
||||
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId)
|
||||
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId)
|
||||
{
|
||||
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", " << msgId << ")";
|
||||
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
mGrpId = grpId;
|
||||
mMsgId = msgId;
|
||||
mMostRecentMsgId = most_recent_msgId;
|
||||
mMsgVersions = msg_versions;
|
||||
|
||||
RsGxsGrpMsgIdPair threadId;
|
||||
|
||||
threadId.first = grpId;
|
||||
threadId.second = msgId;
|
||||
|
||||
ui->treeWidget->requestComments(threadId);
|
||||
ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId);
|
||||
}
|
||||
|
||||
void GxsCommentDialog::refresh()
|
||||
@ -80,7 +76,7 @@ void GxsCommentDialog::refresh()
|
||||
std::cerr << "GxsCommentDialog::refresh()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
commentLoad(mGrpId, mMsgId);
|
||||
commentLoad(mGrpId, mMsgVersions,mMostRecentMsgId);
|
||||
}
|
||||
|
||||
void GxsCommentDialog::idChooserReady()
|
||||
|
@ -39,10 +39,10 @@ public:
|
||||
virtual ~GxsCommentDialog();
|
||||
|
||||
void setCommentHeader(QWidget *header);
|
||||
void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId);
|
||||
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &most_recent_msgId);
|
||||
|
||||
RsGxsGroupId groupId() { return mGrpId; }
|
||||
RsGxsMessageId messageId() { return mMsgId; }
|
||||
RsGxsMessageId messageId() { return mMostRecentMsgId; }
|
||||
|
||||
private slots:
|
||||
void refresh();
|
||||
@ -51,7 +51,8 @@ private slots:
|
||||
|
||||
private:
|
||||
RsGxsGroupId mGrpId;
|
||||
RsGxsMessageId mMsgId;
|
||||
RsGxsMessageId mMostRecentMsgId;
|
||||
std::set<RsGxsMessageId> mMsgVersions;
|
||||
|
||||
/* UI - from Designer */
|
||||
Ui::GxsCommentDialog *ui;
|
||||
|
@ -22,8 +22,12 @@
|
||||
*/
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QTextDocument>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
#include "gui/common/RSElidedItemDelegate.h"
|
||||
#include "gui/gxs/GxsCommentTreeWidget.h"
|
||||
@ -46,11 +50,73 @@
|
||||
|
||||
#define COMMENT_VOTE_ACK 0x001234
|
||||
|
||||
#define POST_CELL_SIZE_ROLE (Qt::UserRole+1)
|
||||
#define POST_COLOR_ROLE (Qt::UserRole+2)
|
||||
|
||||
/* Images for context menu icons */
|
||||
#define IMAGE_MESSAGE ":/images/folder-draft.png"
|
||||
#define IMAGE_VOTEUP ":/images/vote_up.png"
|
||||
#define IMAGE_VOTEDOWN ":/images/vote_down.png"
|
||||
#define IMAGE_VOTEUP ":/images/vote_up.png"
|
||||
#define IMAGE_VOTEDOWN ":/images/vote_down.png"
|
||||
|
||||
// This class allows to draw the item using an appropriate size
|
||||
|
||||
class MultiLinesCommentDelegate: public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
MultiLinesCommentDelegate(QFontMetricsF f) : qf(f){}
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return index.data(POST_CELL_SIZE_ROLE).toSize() ;
|
||||
}
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
Q_ASSERT(index.isValid());
|
||||
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
// disable default icon
|
||||
opt.icon = QIcon();
|
||||
opt.text = QString();
|
||||
// draw default item
|
||||
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
|
||||
|
||||
const QRect r = option.rect;
|
||||
|
||||
QTextDocument td ;
|
||||
td.setHtml("<html>"+index.data(Qt::DisplayRole).toString()+"</html>");
|
||||
QSizeF s = td.documentLayout()->documentSize();
|
||||
|
||||
int m = QFontMetricsF(QFont()).height();
|
||||
|
||||
QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m);
|
||||
|
||||
QPixmap px(full_area.width(),full_area.height());
|
||||
px.fill();
|
||||
QPainter p(&px) ;
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QPainterPath path ;
|
||||
path.addRoundedRect(QRectF(m/4.0,m/4.0,s.width()+m/2.0,s.height()+m/2.0),m,m) ;
|
||||
QPen pen(Qt::gray,m/7.0f);
|
||||
p.setPen(pen);
|
||||
p.fillPath(path,QColor::fromHsv( index.data(POST_COLOR_ROLE).toInt()/255.0*360,40,220)); // varies the color according to the post author
|
||||
p.drawPath(path);
|
||||
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
ctx.clip = QRectF(0,0,s.width(),s.height());
|
||||
p.translate(QPointF(m/2.0,m/2.0));
|
||||
td.documentLayout()->draw( &p, ctx );
|
||||
|
||||
painter->drawPixmap(r.topLeft(),px);
|
||||
|
||||
const_cast<QAbstractItemModel*>(index.model())->setData(index,px.size(),POST_CELL_SIZE_ROLE);
|
||||
}
|
||||
|
||||
private:
|
||||
QFontMetricsF qf;
|
||||
};
|
||||
|
||||
GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||
:QTreeWidget(parent), mTokenQueue(NULL), mRsTokenService(NULL), mCommentService(NULL)
|
||||
@ -62,6 +128,9 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||
itemDelegate->setSpacing(QSize(0, 2));
|
||||
setItemDelegate(itemDelegate);
|
||||
setWordWrap(true);
|
||||
|
||||
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ;
|
||||
|
||||
// QFont font = QFont("ARIAL", 10);
|
||||
// font.setBold(true);
|
||||
|
||||
@ -85,14 +154,14 @@ GxsCommentTreeWidget::~GxsCommentTreeWidget()
|
||||
}
|
||||
}
|
||||
|
||||
void GxsCommentTreeWidget::setCurrentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||
void GxsCommentTreeWidget::setCurrentCommentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||
{
|
||||
|
||||
Q_UNUSED(previous);
|
||||
|
||||
if(current)
|
||||
{
|
||||
mCurrentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString());
|
||||
mCurrentCommentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,9 +169,9 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& /*point*/)
|
||||
{
|
||||
QMenu contextMnu( this );
|
||||
QAction* action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Reply to Comment"), this, SLOT(replyToComment()));
|
||||
action->setDisabled(mCurrentMsgId.isNull());
|
||||
action->setDisabled(mCurrentCommentMsgId.isNull());
|
||||
action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment()));
|
||||
action->setDisabled(mThreadId.first.isNull());
|
||||
action->setDisabled(mMsgVersions.empty());
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
@ -112,7 +181,7 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& /*point*/)
|
||||
action->setDisabled(mVoterId.isNull());
|
||||
|
||||
|
||||
if (!mCurrentMsgId.isNull())
|
||||
if (!mCurrentCommentMsgId.isNull())
|
||||
{
|
||||
// not implemented yet
|
||||
/*
|
||||
@ -138,7 +207,8 @@ void GxsCommentTreeWidget::voteUp()
|
||||
{
|
||||
std::cerr << "GxsCommentTreeWidget::voteUp()";
|
||||
std::cerr << std::endl;
|
||||
vote(mThreadId.first, mThreadId.second, mCurrentMsgId, mVoterId, true);
|
||||
|
||||
vote(mGroupId, mLatestMsgId, mCurrentCommentMsgId, mVoterId, true);
|
||||
}
|
||||
|
||||
|
||||
@ -146,7 +216,8 @@ void GxsCommentTreeWidget::voteDown()
|
||||
{
|
||||
std::cerr << "GxsCommentTreeWidget::voteDown()";
|
||||
std::cerr << std::endl;
|
||||
vote(mThreadId.first, mThreadId.second, mCurrentMsgId, mVoterId, false);
|
||||
|
||||
vote(mGroupId, mLatestMsgId, mCurrentCommentMsgId, mVoterId, false);
|
||||
}
|
||||
|
||||
void GxsCommentTreeWidget::setVoteId(const RsGxsId &voterId)
|
||||
@ -216,16 +287,16 @@ void GxsCommentTreeWidget::banUser()
|
||||
|
||||
void GxsCommentTreeWidget::makeComment()
|
||||
{
|
||||
GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, mThreadId, mThreadId.second, this);
|
||||
GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, std::make_pair(mGroupId,mLatestMsgId), mLatestMsgId, this);
|
||||
pcc.exec();
|
||||
}
|
||||
|
||||
void GxsCommentTreeWidget::replyToComment()
|
||||
{
|
||||
RsGxsGrpMsgIdPair msgId;
|
||||
msgId.first = mThreadId.first;
|
||||
msgId.second = mCurrentMsgId;
|
||||
GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, msgId, mThreadId.second, this);
|
||||
msgId.first = mGroupId;
|
||||
msgId.second = mCurrentCommentMsgId;
|
||||
GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, msgId, mLatestMsgId, this);
|
||||
pcc.exec();
|
||||
}
|
||||
|
||||
@ -235,36 +306,44 @@ void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentServ
|
||||
mCommentService = comment_service;
|
||||
mTokenQueue = new TokenQueue(token_service, this);
|
||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint)));
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentMsgId(QTreeWidgetItem*, QTreeWidgetItem*)));
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentCommentMsgId(QTreeWidgetItem*, QTreeWidgetItem*)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Load Comments */
|
||||
void GxsCommentTreeWidget::requestComments(const RsGxsGrpMsgIdPair& threadId)
|
||||
void GxsCommentTreeWidget::requestComments(const RsGxsGroupId& group, const std::set<RsGxsMessageId>& message_versions,const RsGxsMessageId& most_recent_message)
|
||||
{
|
||||
/* request comments */
|
||||
|
||||
mThreadId = threadId;
|
||||
service_requestComments(threadId);
|
||||
mGroupId = group ;
|
||||
mMsgVersions = message_versions ;
|
||||
mLatestMsgId = most_recent_message;
|
||||
|
||||
service_requestComments(group,message_versions);
|
||||
}
|
||||
|
||||
void GxsCommentTreeWidget::service_requestComments(const RsGxsGrpMsgIdPair& threadId)
|
||||
void GxsCommentTreeWidget::service_requestComments(const RsGxsGroupId& group_id,const std::set<RsGxsMessageId> & msgIds)
|
||||
{
|
||||
/* request comments */
|
||||
std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId.second << ")";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "GxsCommentTreeWidget::service_requestComments for group " << group_id << std::endl;
|
||||
|
||||
std::vector<RsGxsGrpMsgIdPair> ids_to_ask;
|
||||
|
||||
for(std::set<RsGxsMessageId>::const_iterator it(msgIds.begin());it!=msgIds.end();++it)
|
||||
{
|
||||
std::cerr << " asking for msg " << *it << std::endl;
|
||||
|
||||
ids_to_ask.push_back(std::make_pair(group_id,*it));
|
||||
}
|
||||
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA;
|
||||
opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST;
|
||||
|
||||
std::vector<RsGxsGrpMsgIdPair> msgIds;
|
||||
msgIds.push_back(threadId);
|
||||
|
||||
uint32_t token;
|
||||
mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD);
|
||||
mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids_to_ask, GXSCOMMENTS_LOADTHREAD);
|
||||
}
|
||||
|
||||
|
||||
@ -317,7 +396,7 @@ void GxsCommentTreeWidget::completeItems()
|
||||
|
||||
parent->addChild(pit->second);
|
||||
}
|
||||
else if (parentId == mThreadId.second)
|
||||
else if (mMsgVersions.find(parentId) != mMsgVersions.end())
|
||||
{
|
||||
std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems";
|
||||
std::cerr << std::endl;
|
||||
@ -391,7 +470,7 @@ void GxsCommentTreeWidget::acknowledgeComment(const uint32_t &token)
|
||||
mCommentService->acknowledgeComment(token, msgId);
|
||||
|
||||
// simply reload data
|
||||
service_requestComments(mThreadId);
|
||||
service_requestComments(mGroupId,mMsgVersions);
|
||||
}
|
||||
|
||||
|
||||
@ -401,7 +480,7 @@ void GxsCommentTreeWidget::acknowledgeVote(const uint32_t &token)
|
||||
if (mCommentService->acknowledgeVote(token, msgId))
|
||||
{
|
||||
// reload data if vote was added.
|
||||
service_requestComments(mThreadId);
|
||||
service_requestComments(mGroupId,mMsgVersions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,6 +520,7 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
|
||||
|
||||
RsGxsId authorId = comment.mMeta.mAuthorId;
|
||||
item->setId(authorId, PCITEM_COLUMN_AUTHOR, false);
|
||||
item->setData(PCITEM_COLUMN_COMMENT,POST_COLOR_ROLE,QVariant(authorId.toByteArray()[1]));
|
||||
|
||||
text = QString::number(comment.mScore);
|
||||
item->setText(PCITEM_COLUMN_SCORE, text);
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
~GxsCommentTreeWidget();
|
||||
void setup(RsTokenService *token_service, RsGxsCommentService *comment_service);
|
||||
|
||||
void requestComments(const RsGxsGrpMsgIdPair& threadId);
|
||||
void requestComments(const RsGxsGroupId& group, const std::set<RsGxsMessageId> &message_versions, const RsGxsMessageId &most_recent_message);
|
||||
void getCurrentMsgId(RsGxsMessageId& parentId);
|
||||
void applyRankings(std::map<RsGxsMessageId, uint32_t>& positions);
|
||||
|
||||
@ -49,7 +49,7 @@ public:
|
||||
protected:
|
||||
|
||||
/* to be overloaded */
|
||||
virtual void service_requestComments(const RsGxsGrpMsgIdPair& threadId);
|
||||
virtual void service_requestComments(const RsGxsGroupId &group_id, const std::set<RsGxsMessageId> &msgIds);
|
||||
virtual void service_loadThread(const uint32_t &token);
|
||||
virtual QTreeWidgetItem *service_createMissingItem(const RsGxsMessageId& parent);
|
||||
|
||||
@ -65,7 +65,7 @@ protected:
|
||||
|
||||
public slots:
|
||||
void customPopUpMenu(const QPoint& point);
|
||||
void setCurrentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous);
|
||||
void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous);
|
||||
|
||||
|
||||
void makeComment();
|
||||
@ -85,8 +85,10 @@ protected:
|
||||
const RsGxsMessageId &parentId, const RsGxsId &authorId, bool up);
|
||||
|
||||
/* Data */
|
||||
RsGxsGrpMsgIdPair mThreadId;
|
||||
RsGxsMessageId mCurrentMsgId;
|
||||
RsGxsGroupId mGroupId;
|
||||
std::set<RsGxsMessageId> mMsgVersions;
|
||||
RsGxsMessageId mLatestMsgId;
|
||||
RsGxsMessageId mCurrentCommentMsgId;
|
||||
RsGxsId mVoterId;
|
||||
|
||||
std::map<RsGxsMessageId, QTreeWidgetItem *> mLoadingMap;
|
||||
|
@ -64,7 +64,10 @@ void GxsFeedItem::comments(const QString &title)
|
||||
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mFeedHolder->openComments(feedId(), groupId(), messageId(), title);
|
||||
if(mMessageVersions.empty())
|
||||
mFeedHolder->openComments(feedId(), groupId(),QVector<RsGxsMessageId>(1,messageId()), messageId(), title);
|
||||
else
|
||||
mFeedHolder->openComments(feedId(), groupId(),mMessageVersions, messageId(), title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,12 +156,12 @@ void GxsFeedItem::requestComment()
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA;
|
||||
opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST;
|
||||
|
||||
RsGxsGrpMsgIdPair msgIdPair;
|
||||
msgIdPair.first = groupId();
|
||||
msgIdPair.second = messageId();
|
||||
|
||||
std::vector<RsGxsGrpMsgIdPair> msgIds;
|
||||
msgIds.push_back(msgIdPair);
|
||||
|
||||
for(uint32_t i=0;i<mMessageVersions.size();++i)
|
||||
msgIds.push_back(std::make_pair(groupId(),mMessageVersions[i]));
|
||||
|
||||
msgIds.push_back(std::make_pair(groupId(),messageId()));
|
||||
|
||||
uint32_t token;
|
||||
mLoadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeComment);
|
||||
|
@ -35,9 +35,12 @@ public:
|
||||
GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate);
|
||||
virtual ~GxsFeedItem();
|
||||
|
||||
RsGxsMessageId messageId() { return mMessageId; }
|
||||
RsGxsMessageId messageId() const { return mMessageId; }
|
||||
const QVector<RsGxsMessageId>& messageVersions() const { return mMessageVersions ; }
|
||||
|
||||
//To be able to update with thread message when comment is received.
|
||||
void setMessageId( RsGxsMessageId id) {mMessageId = id;}
|
||||
void setMessageVersions( const QVector<RsGxsMessageId>& v) { mMessageVersions = v;}
|
||||
|
||||
protected:
|
||||
/* load message data */
|
||||
@ -61,6 +64,7 @@ protected slots:
|
||||
|
||||
private:
|
||||
RsGxsMessageId mMessageId;
|
||||
QVector<RsGxsMessageId> mMessageVersions ;
|
||||
uint32_t mTokenTypeMessage;
|
||||
uint32_t mTokenTypeComment;
|
||||
};
|
||||
|
@ -45,8 +45,8 @@ public:
|
||||
GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate);
|
||||
virtual ~GxsGroupFeedItem();
|
||||
|
||||
RsGxsGroupId groupId() { return mGroupId; }
|
||||
uint32_t feedId() { return mFeedId; }
|
||||
RsGxsGroupId groupId() const { return mGroupId; }
|
||||
uint32_t feedId() const { return mFeedId; }
|
||||
|
||||
protected:
|
||||
uint32_t nextTokenType() { return ++mNextTokenType; }
|
||||
|
@ -525,7 +525,7 @@ void GxsGroupFrameDialog::sharePublishKey()
|
||||
shareUi.exec();
|
||||
}
|
||||
|
||||
void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title)
|
||||
void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const QVector<RsGxsMessageId>& msg_versions, const RsGxsMessageId &most_recent_msgId, const QString &title)
|
||||
{
|
||||
RsGxsCommentService *commentService = getCommentService();
|
||||
if (!commentService) {
|
||||
@ -533,7 +533,8 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMess
|
||||
return;
|
||||
}
|
||||
|
||||
GxsCommentDialog *commentDialog = commentWidget(msgId);
|
||||
GxsCommentDialog *commentDialog = commentWidget(most_recent_msgId);
|
||||
|
||||
if (!commentDialog) {
|
||||
QString comments = title;
|
||||
if (title.length() > MAX_COMMENT_TITLE)
|
||||
@ -544,12 +545,16 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMess
|
||||
|
||||
commentDialog = new GxsCommentDialog(this, mInterface->getTokenService(), commentService);
|
||||
|
||||
QWidget *commentHeader = createCommentHeaderWidget(grpId, msgId);
|
||||
QWidget *commentHeader = createCommentHeaderWidget(grpId, most_recent_msgId);
|
||||
if (commentHeader) {
|
||||
commentDialog->setCommentHeader(commentHeader);
|
||||
}
|
||||
|
||||
commentDialog->commentLoad(grpId, msgId);
|
||||
std::set<RsGxsMessageId> msgv;
|
||||
for(int i=0;i<msg_versions.size();++i)
|
||||
msgv.insert(msg_versions[i]);
|
||||
|
||||
commentDialog->commentLoad(grpId, msgv,most_recent_msgId);
|
||||
|
||||
int index = ui->messageTabWidget->addTab(commentDialog, comments);
|
||||
ui->messageTabWidget->setTabIcon(index, QIcon(IMAGE_COMMENT));
|
||||
@ -620,12 +625,12 @@ GxsMessageFrameWidget *GxsGroupFrameDialog::createMessageWidget(const RsGxsGroup
|
||||
|
||||
connect(msgWidget, SIGNAL(groupChanged(QWidget*)), this, SLOT(messageTabInfoChanged(QWidget*)));
|
||||
connect(msgWidget, SIGNAL(waitingChanged(QWidget*)), this, SLOT(messageTabWaitingChanged(QWidget*)));
|
||||
connect(msgWidget, SIGNAL(loadComment(RsGxsGroupId,RsGxsMessageId,QString)), this, SLOT(loadComment(RsGxsGroupId,RsGxsMessageId,QString)));
|
||||
connect(msgWidget, SIGNAL(loadComment(RsGxsGroupId,QVector<RsGxsMessageId>,RsGxsMessageId,QString)), this, SLOT(loadComment(RsGxsGroupId,QVector<RsGxsMessageId>,RsGxsMessageId,QString)));
|
||||
|
||||
return msgWidget;
|
||||
}
|
||||
|
||||
GxsCommentDialog *GxsGroupFrameDialog::commentWidget(const RsGxsMessageId &msgId)
|
||||
GxsCommentDialog *GxsGroupFrameDialog::commentWidget(const RsGxsMessageId& msgId)
|
||||
{
|
||||
int tabCount = ui->messageTabWidget->count();
|
||||
for (int index = 0; index < tabCount; ++index) {
|
||||
|
@ -126,7 +126,7 @@ private slots:
|
||||
|
||||
void sharePublishKey();
|
||||
|
||||
void loadComment(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title);
|
||||
void loadComment(const RsGxsGroupId &grpId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &most_recent_msgId, const QString &title);
|
||||
|
||||
private:
|
||||
virtual QString text(TextType type) = 0;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
signals:
|
||||
void groupChanged(QWidget *widget);
|
||||
void waitingChanged(QWidget *widget);
|
||||
void loadComment(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title);
|
||||
void loadComment(const RsGxsGroupId &groupId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
protected:
|
||||
virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0;
|
||||
|
@ -38,11 +38,15 @@
|
||||
|
||||
//#define ENABLE_GENERATE
|
||||
|
||||
#define CREATEMSG_CHANNELINFO 0x002
|
||||
#define CREATEMSG_CHANNELINFO 0x002
|
||||
#define CREATEMSG_CHANNEL_POST_INFO 0x003
|
||||
|
||||
// #define DEBUG_CREATE_GXS_MSG
|
||||
|
||||
/** Constructor */
|
||||
CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId)
|
||||
: QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mChannelId(cId) ,mCheckAttachment(true), mAutoMediaThumbNail(false)
|
||||
CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId existing_post)
|
||||
: QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
|
||||
mChannelId(cId) , mOrigPostId(existing_post),mCheckAttachment(true), mAutoMediaThumbNail(false)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
setupUi(this);
|
||||
@ -50,7 +54,11 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId)
|
||||
mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this);
|
||||
|
||||
headerFrame->setHeaderImage(QPixmap(":/images/channels.png"));
|
||||
headerFrame->setHeaderText(tr("New Channel Post"));
|
||||
|
||||
if(!existing_post.isNull())
|
||||
headerFrame->setHeaderText(tr("Edit Channel Post"));
|
||||
else
|
||||
headerFrame->setHeaderText(tr("New Channel Post"));
|
||||
|
||||
setAttribute ( Qt::WA_DeleteOnClose, true );
|
||||
|
||||
@ -337,43 +345,63 @@ void CreateGxsChannelMsg::parseRsFileListAttachments(const std::string &attachLi
|
||||
}
|
||||
|
||||
|
||||
void CreateGxsChannelMsg::addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId)
|
||||
void CreateGxsChannelMsg::addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId, bool assume_file_ready)
|
||||
{
|
||||
/* add a SubFileItem to the attachment section */
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::addAttachment()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* add widget in for new destination */
|
||||
|
||||
uint32_t flags = SFI_TYPE_CHANNEL;
|
||||
uint32_t flags = SFI_TYPE_CHANNEL | SFI_FLAG_ALLOW_DELETE ;
|
||||
|
||||
if(assume_file_ready)
|
||||
flags |= SFI_FLAG_ASSUME_FILE_READY;
|
||||
|
||||
if (local)
|
||||
{
|
||||
flags |= SFI_STATE_LOCAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= SFI_STATE_REMOTE;
|
||||
}
|
||||
|
||||
SubFileItem *file = new SubFileItem(hash, fname, "", size, flags, srcId); // destroyed when fileFrame (this subfileitem) is destroyed
|
||||
|
||||
connect(file,SIGNAL(wantsToBeDeleted()),this,SLOT(deleteAttachment())) ;
|
||||
|
||||
mAttachments.push_back(file);
|
||||
QLayout *layout = fileFrame->layout();
|
||||
layout->addWidget(file);
|
||||
|
||||
if (mCheckAttachment)
|
||||
{
|
||||
checkAttachmentReady();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
void CreateGxsChannelMsg::deleteAttachment()
|
||||
{
|
||||
// grab the item who sent the request
|
||||
|
||||
SubFileItem *file_item = qobject_cast<SubFileItem *>(QObject::sender());
|
||||
|
||||
for(std::list<SubFileItem*>::iterator it(mAttachments.begin());it!=mAttachments.end();)
|
||||
if(*it == file_item)
|
||||
{
|
||||
SubFileItem *item = *it ;
|
||||
it = mAttachments.erase(it) ;
|
||||
fileFrame->layout()->removeWidget(file_item) ;
|
||||
delete item ;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
void CreateGxsChannelMsg::addExtraFile()
|
||||
{
|
||||
/* add a SubFileItem to the attachment section */
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::addExtraFile() opening file dialog";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
QStringList files;
|
||||
if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) {
|
||||
@ -386,8 +414,10 @@ void CreateGxsChannelMsg::addExtraFile()
|
||||
void CreateGxsChannelMsg::addAttachment(const std::string &path)
|
||||
{
|
||||
/* add a SubFileItem to the attachment section */
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::addAttachment()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if(mAutoMediaThumbNail)
|
||||
setThumbNail(path, 2000);
|
||||
@ -522,8 +552,10 @@ void CreateGxsChannelMsg::checkAttachmentReady()
|
||||
|
||||
void CreateGxsChannelMsg::cancelMsg()
|
||||
{
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::cancelMsg() :"
|
||||
<< "Deleting EXTRA attachments" << std::endl;
|
||||
#endif
|
||||
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -555,6 +587,15 @@ void CreateGxsChannelMsg::newChannelMsg()
|
||||
|
||||
uint32_t token;
|
||||
mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEMSG_CHANNELINFO);
|
||||
|
||||
if(!mOrigPostId.isNull())
|
||||
{
|
||||
GxsMsgReq message_ids;
|
||||
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
message_ids[mChannelId].push_back(mOrigPostId);
|
||||
mChannelQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, message_ids, CREATEMSG_CHANNEL_POST_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,8 +610,10 @@ void CreateGxsChannelMsg::saveChannelInfo(const RsGroupMetaData &meta)
|
||||
|
||||
void CreateGxsChannelMsg::sendMsg()
|
||||
{
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::sendMsg()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* construct message bits */
|
||||
std::string subject = std::string(misc::removeNewLine(subjectEdit->text()).toUtf8());
|
||||
@ -628,6 +671,7 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str
|
||||
post.mMeta.mThreadId.clear() ;
|
||||
post.mMeta.mMsgId.clear() ;
|
||||
|
||||
post.mMeta.mOrigMsgId = mOrigPostId;
|
||||
post.mMeta.mMsgName = subject;
|
||||
post.mMsg = msg;
|
||||
post.mFiles = files;
|
||||
@ -686,10 +730,47 @@ void CreateGxsChannelMsg::addThumbnail()
|
||||
thumbnail_label->setPixmap(picture);
|
||||
}
|
||||
|
||||
void CreateGxsChannelMsg::loadChannelPostInfo(const uint32_t &token)
|
||||
{
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
rsGxsChannels->getPostData(token, posts);
|
||||
|
||||
if (posts.size() != 1)
|
||||
{
|
||||
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID Number of posts in request" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
// now populate the widget with the channel post data.
|
||||
const RsGxsChannelPost& post = posts[0];
|
||||
|
||||
if(post.mMeta.mGroupId != mChannelId || post.mMeta.mMsgId != mOrigPostId)
|
||||
{
|
||||
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID post ID or channel ID" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
subjectEdit->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())) ;
|
||||
msgEdit->setText(QString::fromUtf8(post.mMsg.c_str())) ;
|
||||
|
||||
for(std::list<RsGxsFile>::const_iterator it(post.mFiles.begin());it!=post.mFiles.end();++it)
|
||||
addAttachment(it->mHash,it->mName,it->mSize,true,RsPeerId(),true);
|
||||
|
||||
picture.loadFromData(post.mThumbnail.mData,post.mThumbnail.mSize,"PNG");
|
||||
thumbnail_label->setPixmap(picture);
|
||||
}
|
||||
|
||||
void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token)
|
||||
{
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::loadChannelInfo()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::list<RsGroupMetaData> groupInfo;
|
||||
rsGxsChannels->getGroupSummary(token, groupInfo);
|
||||
@ -708,8 +789,10 @@ void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token)
|
||||
|
||||
void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req)
|
||||
{
|
||||
#ifdef DEBUG_CREATE_GXS_MSG
|
||||
std::cerr << "CreateGxsChannelMsg::loadRequest() UserType: " << req.mUserType;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (queue == mChannelQueue)
|
||||
{
|
||||
@ -719,6 +802,9 @@ void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenReques
|
||||
case CREATEMSG_CHANNELINFO:
|
||||
loadChannelInfo(req.mToken);
|
||||
break;
|
||||
case CREATEMSG_CHANNEL_POST_INFO:
|
||||
loadChannelPostInfo(req.mToken);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "CreateGxsChannelMsg::loadRequest() UNKNOWN UserType ";
|
||||
std::cerr << std::endl;
|
||||
|
@ -38,13 +38,13 @@ class CreateGxsChannelMsg : public QDialog, public TokenResponse, private Ui::Cr
|
||||
|
||||
public:
|
||||
/** Default Constructor */
|
||||
CreateGxsChannelMsg(const RsGxsGroupId& cId);
|
||||
CreateGxsChannelMsg(const RsGxsGroupId& cId, RsGxsMessageId existing_post = RsGxsMessageId());
|
||||
|
||||
/** Default Destructor */
|
||||
~CreateGxsChannelMsg();
|
||||
|
||||
void addAttachment(const std::string &path);
|
||||
void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId);
|
||||
void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId,bool assume_file_ready = false);
|
||||
|
||||
void newChannelMsg();
|
||||
|
||||
@ -60,6 +60,7 @@ protected:
|
||||
private slots:
|
||||
void addExtraFile();
|
||||
void checkAttachmentReady();
|
||||
void deleteAttachment();
|
||||
|
||||
void cancelMsg();
|
||||
void sendMsg();
|
||||
@ -71,6 +72,7 @@ private slots:
|
||||
|
||||
private:
|
||||
void loadChannelInfo(const uint32_t &token);
|
||||
void loadChannelPostInfo(const uint32_t &token);
|
||||
void saveChannelInfo(const RsGroupMetaData &group);
|
||||
|
||||
void parseRsFileListAttachments(const std::string &attachList);
|
||||
@ -78,7 +80,9 @@ private:
|
||||
bool setThumbNail(const std::string& path, int frame);
|
||||
|
||||
RsGxsGroupId mChannelId;
|
||||
RsGxsMessageId mOrigPostId;
|
||||
RsGroupMetaData mChannelMeta;
|
||||
RsMsgMetaData mOrigMeta;
|
||||
bool mChannelMetaLoaded;
|
||||
|
||||
std::list<SubFileItem *> mAttachments;
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>581</width>
|
||||
<height>479</height>
|
||||
<width>875</width>
|
||||
<height>659</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
@ -60,7 +60,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="channelPostTab">
|
||||
<attribute name="title">
|
||||
@ -302,8 +302,8 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>523</width>
|
||||
<height>24</height>
|
||||
<width>767</width>
|
||||
<height>42</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -207,9 +207,9 @@ void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/)
|
||||
}
|
||||
|
||||
// Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog,
|
||||
void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title)
|
||||
void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title)
|
||||
{
|
||||
emit loadComment(groupId, msgId, title);
|
||||
emit loadComment(groupId, msg_versions,msgId, title);
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidget::createMsg()
|
||||
@ -398,7 +398,27 @@ void GxsChannelPostsWidget::filterChanged(int filter)
|
||||
void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost &post, bool related)
|
||||
{
|
||||
GxsChannelPostItem *item = NULL;
|
||||
if (related) {
|
||||
|
||||
if(!post.mMeta.mOrigMsgId.isNull())
|
||||
{
|
||||
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mOrigMsgId);
|
||||
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
||||
|
||||
if(item)
|
||||
{
|
||||
ui->feedWidget->removeFeedItem(item) ;
|
||||
RsGxsChannelGroup dummyGroup;
|
||||
dummyGroup.mMeta.mGroupId = groupId();
|
||||
dummyGroup.mMeta.mSubscribeFlags = 0xffffffff;
|
||||
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, dummyGroup, post, true, false);
|
||||
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs));
|
||||
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
if (related)
|
||||
{
|
||||
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mMsgId);
|
||||
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
||||
}
|
||||
@ -438,8 +458,6 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost> &po
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<RsGxsChannelPost>::const_reverse_iterator it;
|
||||
|
||||
int count = posts.size();
|
||||
int pos = 0;
|
||||
|
||||
@ -447,18 +465,127 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost> &po
|
||||
ui->feedWidget->setSortingEnabled(false);
|
||||
}
|
||||
|
||||
for (it = posts.rbegin(); it != posts.rend(); ++it)
|
||||
{
|
||||
if (thread && thread->stopped()) {
|
||||
break;
|
||||
}
|
||||
// collect new versions of posts if any
|
||||
|
||||
if (thread) {
|
||||
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
|
||||
} else {
|
||||
createPostItem(*it, related);
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << "Inserting channel posts" << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<uint32_t> new_versions ;
|
||||
for (uint32_t i=0;i<posts.size();++i)
|
||||
{
|
||||
if(posts[i].mMeta.mOrigMsgId == posts[i].mMeta.mMsgId)
|
||||
posts[i].mMeta.mOrigMsgId.clear();
|
||||
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " " << i << ": msg_id=" << posts[i].mMeta.mMsgId << ": orig msg id = " << posts[i].mMeta.mOrigMsgId << std::endl;
|
||||
#endif
|
||||
|
||||
if(!posts[i].mMeta.mOrigMsgId.isNull())
|
||||
new_versions.push_back(i) ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << "New versions: " << new_versions.size() << std::endl;
|
||||
#endif
|
||||
|
||||
if(!new_versions.empty())
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " New versions present. Replacing them..." << std::endl;
|
||||
std::cerr << " Creating search map." << std::endl;
|
||||
#endif
|
||||
|
||||
// make a quick search map
|
||||
std::map<RsGxsMessageId,uint32_t> search_map ;
|
||||
for (uint32_t i=0;i<posts.size();++i)
|
||||
search_map[posts[i].mMeta.mMsgId] = i ;
|
||||
|
||||
for(uint32_t i=0;i<new_versions.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " Taking care of new version at index " << new_versions[i] << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t current_index = new_versions[i] ;
|
||||
uint32_t source_index = new_versions[i] ;
|
||||
RsGxsMessageId source_msg_id = posts[source_index].mMeta.mMsgId ;
|
||||
|
||||
// What we do is everytime we find a replacement post, we climb up the replacement graph until we find the original post
|
||||
// (or the most recent version of it). When we reach this post, we replace it with the data of the source post.
|
||||
// In the mean time, all other posts have their MsgId cleared, so that the posts are removed from the list.
|
||||
|
||||
std::vector<uint32_t> versions ;
|
||||
std::map<RsGxsMessageId,uint32_t>::const_iterator vit ;
|
||||
|
||||
while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId)))
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ;
|
||||
#endif
|
||||
|
||||
// Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple
|
||||
// times. In this case, we only need to replace the post with the newest version
|
||||
|
||||
uint32_t prev_index = current_index ;
|
||||
current_index = vit->second ;
|
||||
|
||||
if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further.
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " already erased. Stopping." << std::endl;
|
||||
#endif
|
||||
break ;
|
||||
}
|
||||
|
||||
if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs)
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " and is more recent => following" << std::endl;
|
||||
#endif
|
||||
for(std::set<RsGxsMessageId>::const_iterator itt(posts[current_index].mOlderVersions.begin());itt!=posts[current_index].mOlderVersions.end();++itt)
|
||||
posts[source_index].mOlderVersions.insert(*itt);
|
||||
|
||||
posts[source_index].mOlderVersions.insert(posts[current_index].mMeta.mMsgId);
|
||||
posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored
|
||||
}
|
||||
#ifdef DEBUG_CHANNEL
|
||||
else
|
||||
std::cerr << " but is older -> Stopping" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << "Now adding posts..." << std::endl;
|
||||
#endif
|
||||
|
||||
for (std::vector<RsGxsChannelPost>::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it)
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " adding post: " << (*it).mMeta.mMsgId ;
|
||||
#endif
|
||||
|
||||
if(!(*it).mMeta.mMsgId.isNull())
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL
|
||||
std::cerr << " added" << std::endl;
|
||||
#endif
|
||||
|
||||
if (thread && thread->stopped())
|
||||
break;
|
||||
|
||||
if (thread)
|
||||
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
|
||||
else
|
||||
createPostItem(*it, related);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_CHANNEL
|
||||
else
|
||||
std::cerr << " skipped" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!thread) {
|
||||
ui->feedWidget->setSortingEnabled(true);
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
virtual QScrollArea *getScrollArea();
|
||||
virtual void deleteFeedItem(QWidget *item, uint32_t type);
|
||||
virtual void openChat(const RsPeerId& peerId);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title);
|
||||
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
protected:
|
||||
/* GxsMessageFramePostWidget */
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>793</width>
|
||||
<height>465</height>
|
||||
<width>880</width>
|
||||
<height>557</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
@ -454,7 +454,7 @@
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
|
@ -1,5 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/svg/hidden.svg</file>
|
||||
<file>icons/svg/randomness.svg</file>
|
||||
<file>icons/svg/password.svg</file>
|
||||
<file>icons/stars/star0.png</file>
|
||||
<file>icons/stars/star1.png</file>
|
||||
@ -11,6 +13,12 @@
|
||||
<file>icons/anonymous_blue_128.png</file>
|
||||
<file>icons/anonymous_green_128.png</file>
|
||||
<file>icons/aol.png</file>
|
||||
<file>icons/transport128.png</file>
|
||||
<file>icons/bandwidth128.png</file>
|
||||
<file>icons/RTT128.png</file>
|
||||
<file>icons/DHT128.png</file>
|
||||
<file>icons/turtle128.png</file>
|
||||
<file>icons/GRouter128.png</file>
|
||||
<file>icons/avatar_128.png</file>
|
||||
<file>icons/avatar_grey_128.png</file>
|
||||
<file>icons/biohazard_red.png</file>
|
||||
|
BIN
retroshare-gui/src/gui/icons/DHT128.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
retroshare-gui/src/gui/icons/GRouter128.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
retroshare-gui/src/gui/icons/RTT128.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
retroshare-gui/src/gui/icons/bandwidth128.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
71
retroshare-gui/src/gui/icons/svg/hidden.svg
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg4155"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
xml:space="preserve"
|
||||
width="80"
|
||||
height="80"
|
||||
viewBox="0 0 80 80"
|
||||
sodipodi:docname="hidden.svg"><metadata
|
||||
id="metadata4161"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs4159"><linearGradient
|
||||
id="linearGradient5584"
|
||||
osb:paint="solid"><stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5586" /></linearGradient></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="706"
|
||||
id="namedview4157"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.6195029"
|
||||
inkscape:cx="37.953819"
|
||||
inkscape:cy="49.057609"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g4163" /><g
|
||||
id="g4163"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
transform="matrix(1.25,0,0,-1.25,0,80)"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4167"
|
||||
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><g
|
||||
transform="matrix(0.47818792,0,0,-0.47818794,8.3042308,56.181608)"
|
||||
id="g3"><g
|
||||
id="g5"><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 69.322,44.716 49.715,64.323 C 60.438,64.072 69.071,55.438 69.322,44.716 Z"
|
||||
id="path7" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 97.204,45.789 C 96.755,45.26 90.959,38.559 81.802,32.235 l -6.2,6.2 c 5.99,3.954 10.559,8.275 13.011,10.806 -5.378,5.554 -20.913,19.728 -39.372,19.728 -1.334,0 -2.651,-0.082 -3.952,-0.222 l -7.439,7.438 c 3.639,0.91 7.449,1.451 11.391,1.451 26.426,0 47.098,-23.927 47.964,-24.946 1.701,-1.998 1.701,-4.9 -0.001,-6.901 z"
|
||||
id="path9" /><path
|
||||
style="fill:#ffffff"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 90.651,15.901 c 0,-0.266 -0.104,-0.52 -0.293,-0.707 l -7.071,-7.07 c -0.391,-0.391 -1.022,-0.391 -1.414,0 L 66.045,23.952 C 60.843,22.059 55.19,20.844 49.241,20.844 22.814,20.844 2.143,44.77 1.276,45.79 c -1.701,2 -1.701,4.902 10e-4,6.903 0.517,0.606 8.083,9.354 19.707,16.319 l -12.86,12.86 c -0.188,0.188 -0.293,0.441 -0.293,0.707 0,0.267 0.105,0.521 0.293,0.707 l 7.071,7.07 c 0.195,0.194 0.451,0.293 0.707,0.293 0.256,0 0.512,-0.099 0.707,-0.293 l 73.75,-73.75 c 0.187,-0.185 0.292,-0.439 0.292,-0.705 z M 9.869,49.241 C 13.5,45.49 21.767,37.812 32.436,33.22 c -2.081,3.166 -3.301,6.949 -3.301,11.021 0,4.665 1.601,8.945 4.27,12.352 l -6.124,6.123 C 19.129,58.196 12.89,52.361 9.869,49.241 Z"
|
||||
id="path11" /></g></g></g></svg>
|
After Width: | Height: | Size: 3.6 KiB |
197
retroshare-gui/src/gui/icons/svg/randomness.svg
Normal file
@ -0,0 +1,197 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg4155"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
xml:space="preserve"
|
||||
width="80"
|
||||
height="80"
|
||||
viewBox="0 0 80 80"
|
||||
sodipodi:docname="randomness.svg"><metadata
|
||||
id="metadata4161"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs4159" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="706"
|
||||
id="namedview4157"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.11875"
|
||||
inkscape:cx="54.735476"
|
||||
inkscape:cy="40.772004"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g4163" /><g
|
||||
id="g4163"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
transform="matrix(1.25,0,0,-1.25,0,80)"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4167"
|
||||
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><g
|
||||
transform="matrix(1.4341283,-0.03685349,-0.03685349,-1.4341283,6.7291558,58.393566)"
|
||||
id="g3"><g
|
||||
id="g5"><polygon
|
||||
style="fill:#ffffff"
|
||||
points="11.78,8.598 7.526,6.141 7.526,11.054 "
|
||||
id="polygon7" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="11.78,14.738 7.526,12.282 7.526,17.193 "
|
||||
id="polygon9" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="11.78,27.02 7.526,24.562 7.526,29.475 "
|
||||
id="polygon11" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="12.135,27.635 7.881,30.09 12.135,32.546 "
|
||||
id="polygon13" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="12.135,15.352 7.881,17.809 12.135,20.266 "
|
||||
id="polygon15" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="12.135,9.211 7.881,11.668 12.135,14.124 "
|
||||
id="polygon17" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="12.135,3.071 7.881,5.527 12.135,7.983 "
|
||||
id="polygon19" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.099,5.527 12.844,3.071 12.844,7.983 "
|
||||
id="polygon21" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.099,11.668 12.844,9.211 12.844,14.124 "
|
||||
id="polygon23" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.099,17.809 12.844,15.352 12.844,20.266 "
|
||||
id="polygon25" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.099,23.949 12.844,21.493 12.844,26.405 "
|
||||
id="polygon27" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.099,30.09 12.844,27.635 12.844,32.546 "
|
||||
id="polygon29" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.453,30.704 13.199,33.16 17.453,35.616 "
|
||||
id="polygon31" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.453,24.562 13.199,27.02 17.453,29.475 "
|
||||
id="polygon33" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.453,18.422 13.199,20.879 17.453,23.335 "
|
||||
id="polygon35" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.453,12.282 13.199,14.738 17.453,17.193 "
|
||||
id="polygon37" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="17.453,0 13.199,2.456 17.453,4.913 "
|
||||
id="polygon39" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.462,11.668 2.208,9.211 2.208,14.124 "
|
||||
id="polygon41" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.462,17.809 2.208,15.352 2.208,20.266 "
|
||||
id="polygon43" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.462,23.949 2.208,21.493 2.208,26.405 "
|
||||
id="polygon45" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.817,24.562 2.562,27.02 6.817,29.475 "
|
||||
id="polygon47" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.817,18.422 2.562,20.879 6.817,23.335 "
|
||||
id="polygon49" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.817,12.282 2.562,14.738 6.817,17.193 "
|
||||
id="polygon51" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="6.817,6.141 2.562,8.598 6.817,11.054 "
|
||||
id="polygon53" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.416,2.456 18.162,0 18.162,4.913 "
|
||||
id="polygon55" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.416,14.738 18.162,12.282 18.162,17.193 "
|
||||
id="polygon57" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.416,20.879 18.162,18.422 18.162,23.335 "
|
||||
id="polygon59" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.416,27.02 18.162,24.562 18.162,29.475 "
|
||||
id="polygon61" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.416,33.16 18.162,30.704 18.162,35.616 "
|
||||
id="polygon63" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.771,27.635 18.517,30.09 22.771,32.546 "
|
||||
id="polygon65" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.771,21.493 18.517,23.949 22.771,26.405 "
|
||||
id="polygon67" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.771,15.352 18.517,17.809 22.771,20.266 "
|
||||
id="polygon69" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.771,9.211 18.517,11.668 22.771,14.124 "
|
||||
id="polygon71" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="22.771,3.071 18.517,5.527 22.771,7.983 "
|
||||
id="polygon73" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="27.735,5.527 23.479,3.071 23.479,7.983 "
|
||||
id="polygon75" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="27.735,11.668 23.479,9.211 23.479,14.124 "
|
||||
id="polygon77" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="27.735,17.809 23.479,15.352 23.479,20.266 "
|
||||
id="polygon79" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="27.735,30.09 23.479,27.635 23.479,32.546 "
|
||||
id="polygon81" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="28.089,24.562 23.835,27.02 28.089,29.475 "
|
||||
id="polygon83" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="28.089,12.282 23.835,14.738 28.089,17.193 "
|
||||
id="polygon85" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="28.089,6.141 23.835,8.598 28.089,11.054 "
|
||||
id="polygon87" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.052,8.598 28.798,6.141 28.798,11.054 "
|
||||
id="polygon89" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.052,14.738 28.798,12.282 28.798,17.193 "
|
||||
id="polygon91" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.052,20.879 28.798,18.422 28.798,23.335 "
|
||||
id="polygon93" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.052,27.02 28.798,24.562 28.798,29.475 "
|
||||
id="polygon95" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.408,21.493 29.153,23.949 33.408,26.405 "
|
||||
id="polygon97" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.408,15.352 29.153,17.809 33.408,20.266 "
|
||||
id="polygon99" /><polygon
|
||||
style="fill:#ffffff"
|
||||
points="33.408,9.211 29.153,11.668 33.408,14.124 "
|
||||
id="polygon101" /></g></g></g></svg>
|
After Width: | Height: | Size: 8.1 KiB |
BIN
retroshare-gui/src/gui/icons/transport128.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
retroshare-gui/src/gui/icons/turtle128.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
@ -1,5 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>images/logo/background.png</file>
|
||||
<file>images/logo/background_lessblue.png</file>
|
||||
<file>images/logo/logo_spash2.png</file>
|
||||
<file>images/network_map.png</file>
|
||||
<file>images/global_switch_on.png</file>
|
||||
@ -349,6 +351,7 @@
|
||||
<file>images/logo/logo_512.png</file>
|
||||
<file>images/logo/logo_info.png</file>
|
||||
<file>images/logo/logo_splash.png</file>
|
||||
<file>images/logo/logo_web_nobackground.png</file>
|
||||
<file>images/logobar/logo_bar_fill.png</file>
|
||||
<file>images/logobar/logo_bar_start.png</file>
|
||||
<file>images/logobar/rslogo.png</file>
|
||||
|
BIN
retroshare-gui/src/gui/images/logo/background.png
Normal file
After Width: | Height: | Size: 422 KiB |
BIN
retroshare-gui/src/gui/images/logo/background_lessblue.png
Normal file
After Width: | Height: | Size: 405 KiB |
BIN
retroshare-gui/src/gui/images/logo/logo_web_nobackground.png
Normal file
After Width: | Height: | Size: 13 KiB |
184
retroshare-gui/src/gui/images/logo/logo_web_nobackground.svg
Normal file
@ -0,0 +1,184 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="144.40031"
|
||||
height="31.875484"
|
||||
id="svg6043"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.1 r"
|
||||
viewBox="0 0 144.40032 31.875486"
|
||||
sodipodi:docname="logo_web_nobackground.svg"
|
||||
inkscape:export-filename="/home/phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/images/logo/logo_web_nobackground.png"
|
||||
inkscape:export-xdpi="265.03128"
|
||||
inkscape:export-ydpi="265.03128">
|
||||
<defs
|
||||
id="defs6045">
|
||||
<linearGradient
|
||||
id="linearGradient4183"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop4185"
|
||||
offset="0"
|
||||
style="stop-color:#abe3ff;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop4187"
|
||||
offset="1"
|
||||
style="stop-color:#0e8ecb;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4183"
|
||||
id="linearGradient4170"
|
||||
x1="-707.36493"
|
||||
y1="878.20923"
|
||||
x2="-694.01666"
|
||||
y2="892.13776"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4183"
|
||||
id="linearGradient4172"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="2.3214316"
|
||||
y1="9.6272764"
|
||||
x2="15.030971"
|
||||
y2="22.573706" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4183"
|
||||
id="linearGradient4213"
|
||||
x1="28.660715"
|
||||
y1="6.0267878"
|
||||
x2="10.758928"
|
||||
y2="10.982145"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4183"
|
||||
id="linearGradient4221"
|
||||
x1="18.392859"
|
||||
y1="30.714291"
|
||||
x2="23.035715"
|
||||
y2="12.991074"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:cx="53.37166"
|
||||
inkscape:cy="7.2519486"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="texts"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1832"
|
||||
inkscape:window-height="966"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6048">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="black_circle"
|
||||
transform="translate(8.2538928e-6,2.2345076)"
|
||||
style="display:inline">
|
||||
<circle
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.29999995;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4140"
|
||||
cx="16.250002"
|
||||
cy="13.122637"
|
||||
r="15.357144" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="symbol"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(709.10597,-869.59315)"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:url(#linearGradient4213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:60.50111771;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 24.779297,2.2382812 A 5.0549051,5.0549051 0 0 0 23.277344,2.40625 5.0549051,5.0549051 0 0 0 19.552734,6.8925781 l -9.482422,2.5410157 c 0.59171,0.9617502 0.910617,2.0899062 0.878907,3.2539062 l 9.474609,-2.539062 a 5.0549051,5.0549051 0 0 0 5.470703,2.023437 5.0549051,5.0549051 0 0 0 3.574219,-6.1914062 5.0549051,5.0549051 0 0 0 -4.689453,-3.7421876 z"
|
||||
transform="translate(-709.10597,869.59315)"
|
||||
id="path4148"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:url(#linearGradient4221);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:60.50111771;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 21.496094,12.3125 -2.539063,9.472656 a 5.0549085,5.0549051 0 0 0 -0.912109,0.152344 5.0549085,5.0549051 0 0 0 -3.576172,6.191406 5.0549085,5.0549051 0 0 0 6.191406,3.574219 5.0549085,5.0549051 0 0 0 3.574219,-6.191406 5.0549085,5.0549051 0 0 0 -2.021484,-2.853516 l 2.539062,-9.480469 C 23.623173,13.209234 22.488304,12.922 21.496094,12.3125 Z"
|
||||
transform="translate(-709.10597,869.59315)"
|
||||
id="bottom"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="left"
|
||||
style="fill:#abe3ff;fill-opacity:1">
|
||||
<g
|
||||
id="g4156"
|
||||
style="fill:url(#linearGradient4170);fill-opacity:1">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:url(#linearGradient4172);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:60.50111771;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 5.2480469,7.4707031 A 5.0549051,5.0549051 0 0 0 3.7460938,7.640625 5.0549051,5.0549051 0 0 0 0.171875,13.830078 5.0549051,5.0549051 0 0 0 6.3632812,17.40625 5.0549051,5.0549051 0 0 0 7.2304688,17.082031 l 6.9394532,6.9375 c 0.53707,-0.9933 1.354986,-1.832209 2.378906,-2.386719 L 9.6152344,14.699219 A 5.0549051,5.0549051 0 0 0 9.9375,11.214844 5.0549051,5.0549051 0 0 0 5.2480469,7.4707031 Z"
|
||||
transform="translate(-709.10597,869.59315)"
|
||||
id="path4146"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="texts">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
x="-673.66925"
|
||||
y="887.26001"
|
||||
id="RETROSHARE"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4502"
|
||||
x="-673.66925"
|
||||
y="887.26001"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5eb9e5;fill-opacity:1"
|
||||
id="tspan4510">RETRO</tspan><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
|
||||
id="tspan4522">SHARE</tspan></tspan></text>
|
||||
<text
|
||||
transform="scale(1.0202219,0.98017888)"
|
||||
id="secure"
|
||||
y="911.17212"
|
||||
x="-659.19342"
|
||||
style="font-style:normal;font-weight:normal;font-size:39.57231903px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.98930794px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.8611412px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.98930794px"
|
||||
y="911.17212"
|
||||
x="-659.19342"
|
||||
id="tspan4506"
|
||||
sodipodi:role="line">secure communication for everyone</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
@ -487,6 +487,20 @@ void NotifyQt::notifyChatLobbyTimeShift(int shift)
|
||||
emit chatLobbyTimeShift(shift) ;
|
||||
}
|
||||
|
||||
void NotifyQt::notifyConnectionWithoutCert()
|
||||
{
|
||||
{
|
||||
QMutexLocker m(&_mutex) ;
|
||||
if(!_enabled)
|
||||
return ;
|
||||
}
|
||||
|
||||
#ifdef NOTIFY_DEBUG
|
||||
std::cerr << "notifyQt: Received notifyConnectionWithoutCert" << std::endl;
|
||||
#endif
|
||||
emit connectionWithoutCert();
|
||||
}
|
||||
|
||||
void NotifyQt::handleChatLobbyTimeShift(int /*shift*/)
|
||||
{
|
||||
return ; // we say nothing. The help dialog of lobbies explains this already.
|
||||
|
@ -52,6 +52,7 @@ class NotifyQt: public QObject, public NotifyClient
|
||||
virtual void notifyOwnAvatarChanged() ;
|
||||
virtual void notifyChatLobbyEvent(uint64_t /* lobby id */, uint32_t /* event type */, const RsGxsId & /*nickname*/, const std::string& /* any string */) ;
|
||||
virtual void notifyChatLobbyTimeShift(int time_shift) ;
|
||||
void notifyConnectionWithoutCert();
|
||||
|
||||
virtual void notifyOwnStatusMessageChanged() ;
|
||||
virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ;
|
||||
@ -143,6 +144,7 @@ class NotifyQt: public QObject, public NotifyClient
|
||||
void chatLobbyInviteReceived() ;
|
||||
void deferredSignatureHandlingRequested() ;
|
||||
void chatLobbyTimeShift(int time_shift) ;
|
||||
void connectionWithoutCert();
|
||||
|
||||
/* Notify from GUI */
|
||||
void chatFontChanged();
|
||||
|
@ -519,6 +519,21 @@ ServerPage QPlainTextEdit#plainTextEdit {
|
||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
|
||||
}
|
||||
|
||||
ServerPage QPlainTextEdit#hiddenpageInHelpPlainTextEdit {
|
||||
border: 1px solid #DCDC41;
|
||||
border-radius: 6px;
|
||||
background: #FFFFD7;
|
||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
|
||||
}
|
||||
|
||||
ServerPage QPlainTextEdit#pteBobSimple {
|
||||
border: 1px solid #DCDC41;
|
||||
border-radius: 6px;
|
||||
background: #FFFFD7;
|
||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
|
||||
}
|
||||
|
||||
|
||||
/* ProfileManager */
|
||||
|
||||
ProfileManager > QFrame#headerFrame {
|
||||
@ -665,49 +680,49 @@ IdEditDialog QLabel#info_label
|
||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
|
||||
}
|
||||
GenCertDialog QComboBox#genPGPuser {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QSpinBox#hiddenport_spinBox {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#hiddenaddr_input {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#password_input_2 {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#password_input {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#nickname_input {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#node_input {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
}
|
||||
GenCertDialog QLineEdit#name_input {
|
||||
border: 4px solid #0099cc;
|
||||
border: 2px solid #0099cc;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
font: bold;
|
||||
@ -772,4 +787,14 @@ StartDialog QPushButton#loadButton {
|
||||
|
||||
StartDialog QPushButton#loadButton:hover {
|
||||
border-image: url(:/images/btn_blue_hover.png) 4;
|
||||
}
|
||||
}
|
||||
|
||||
StartDialog QFrame#loginframe{
|
||||
border-image: url(:/images/logo/background_lessblue.png) 0 0 0 0 stretch stretch;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
GenCertDialog QFrame#profileframe{
|
||||
background-image: url(:/images/logo/background.png);
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|