From a7cda5167ded9851f3886e075d0edba79b395828 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Fri, 23 Oct 2020 22:28:35 +0200 Subject: [PATCH 001/697] Fix: additional / when combining file paths --- libretroshare/src/ft/ftcontroller.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 29494f189..1dc0b1dad 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -735,8 +735,7 @@ bool ftController::completeFile(const RsFileHash& hash) RsDirUtil::splitDirFromFile(fc->mDestination,dst_dir,dst_file) ; // We use this intermediate file in case the destination directory is not available, so as to not keep the partial file name. - - std::string intermediate_file_name = src_dir+'/'+dst_file ; + std::string intermediate_file_name = RsDirUtil::makePath(src_dir, dst_file); // I don't know how the size can be zero, but believe me, this happens, // and it causes an error on linux because then the file may not even exist. From b461d3c782e603b3b7923f4e5654326a6fc9d52b Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 20 Feb 2021 14:24:59 +0100 Subject: [PATCH 002/697] Added Edit Identity button to People view --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 8 ++++++-- retroshare-gui/src/gui/Identity/IdDialog.ui | 11 +++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 84f6ab2a3..016a8cb27 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -252,10 +252,12 @@ IdDialog::IdDialog(QWidget *parent) connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); + connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editIdentity())); connect( ui->idTreeWidget, &RSTreeWidget::itemDoubleClicked, this, &IdDialog::chatIdentityItem ); + ui->editButton->hide(); ui->avlabel_Circles->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/circles.png")); @@ -1810,7 +1812,8 @@ void IdDialog::loadIdentity(RsGxsIdGroup data) // ui->editIdentity->setEnabled(true); // ui->removeIdentity->setEnabled(true); ui->chatIdentity->setEnabled(false); - ui->inviteButton->setEnabled(false); + ui->inviteButton->hide(); + ui->editButton->show(); } else { @@ -1820,7 +1823,8 @@ void IdDialog::loadIdentity(RsGxsIdGroup data) // ui->editIdentity->setEnabled(false); // ui->removeIdentity->setEnabled(false); ui->chatIdentity->setEnabled(true); - ui->inviteButton->setEnabled(true); + ui->inviteButton->show(); + ui->editButton->hide(); } ui->autoBanIdentities_CB->setChecked(rsReputations->isNodeBanned(data.mPgpId)); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index d785dbc4c..256849509 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -6,7 +6,7 @@ 0 0 - 987 + 800 584 @@ -287,7 +287,7 @@ - 0 + -155 0 634 523 @@ -609,6 +609,13 @@ border-image: url(:/images/closepressed.png) + + + + Edit Identity + + + From 9d4bc677bbb1f25c386a84ca60258464646e1f11 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 20 Feb 2021 16:14:27 +0100 Subject: [PATCH 003/697] Fixed to hide unwanted labels and buttons on a ssl request --- retroshare-gui/src/gui/feeds/SecurityItem.cpp | 23 +++++++++++++----- retroshare-gui/src/gui/icons.qrc | 1 + retroshare-gui/src/gui/icons/ssl.png | Bin 0 -> 3860 bytes 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 retroshare-gui/src/gui/icons/ssl.png diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.cpp b/retroshare-gui/src/gui/feeds/SecurityItem.cpp index b2bbc2cf3..68419ee94 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityItem.cpp @@ -138,6 +138,7 @@ void SecurityItem::updateItemStatic() title = tr("Missing/Damaged certificate. Not a real Retroshare user."); requestLabel->hide(); } + avatar->setDefaultAvatar(":icons/ssl.png"); break; case RS_FEED_ITEM_SEC_INTERNAL_ERROR: title = tr("Certificate caused an internal error."); @@ -186,7 +187,7 @@ void SecurityItem::updateItem() */ /* set peer name */ - peerNameLabel->setText(tr("A unknown peer")); + //peerNameLabel->setText(tr("A unknown peer")); nameLabel->setText(tr("Unknown") + " (" + tr("Profile ID: ") + QString::fromStdString(mGpgId.toStdString()) + ")"); idLabel->setText(QString::fromStdString(mSslId.toStdString())); @@ -205,15 +206,25 @@ void SecurityItem::updateItem() connLeftLabel->hide(); chatButton->hide(); - //quickmsgButton->hide(); - requestLabel->hide(); removeFriendButton->setEnabled(false); removeFriendButton->hide(); peerDetailsButton->setEnabled(false); - - friendRequesttoolButton->show(); - requestLabel->show(); + + if(mType == RS_FEED_ITEM_SEC_BAD_CERTIFICATE) + { + peerNameLabel->setText(tr("SSL request")); + friendRequesttoolButton->hide(); + requestLabel->hide(); + peerDetailsButton->hide; + } + else + { + peerNameLabel->setText(tr("A unknown peer")); + friendRequesttoolButton->show(); + requestLabel->show(); + peerDetailsButton->show(); + } return; } diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index c9a4f33c8..995157b69 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -63,6 +63,7 @@ icons/logo_2_connected_128.png icons/outlook.png icons/question.png + icons/ssl.png icons/plugins_128.png icons/png/add.png icons/png/add-identity.png diff --git a/retroshare-gui/src/gui/icons/ssl.png b/retroshare-gui/src/gui/icons/ssl.png new file mode 100644 index 0000000000000000000000000000000000000000..ca16866164407faa31b2465d6f8c718264a13727 GIT binary patch literal 3860 zcmbVP_cI(0u)jM;&LL{FAc$zuB|&m(E?Si2I6;Ubdhe%&L)0J_y+(+f8qo<6>#c z(@XRqYDDMx&b;>zywA*McRo9_GrRl4&TiB*9W@##I}`u_&}gW`5mz4bA0ZT1mY`tX zbLGGuDjNEbD+E9+Bd;{2tGbZ~06ARwY@SaHJ@s6yJ<;awRsb{_EoSHJ z;PKkr)k@68-6mrT#tr~n|DXX^*7wQ$ljWbtG@6BJdWkeWPyZ-D*7?|%y7M*#$byMd z6>o+14Lc~O;A@$m$ZR#GwV7zG%<%XJeo@(lH)S*>78&)gWWvYjXvDkH7egbW%l2d~ zS}~DuIBQ~>IhVZj4ASe6mNhSJD<{9WzQMl!XVWMDt?k+M)6qsRmzjEUh5y5y2tjXP zba#C_lwo(bGg-0Rv!%;|C7(4h6L5kfMNzna#9Ao0l4;XK+bYCTgBMk3Z_ydgr*v6) z>GHlsZdNddT!=SYvpw%489^jzQ>m!6kAD^d2Lm47kIgkwq2)|4MtvT<;gfi}9>-Gh zgB%wG-Lcpg97WjNZVSNHg77gx89EpyFoL!QB7cO-T_f_Zcbs+a?lFJ3;Au8s8|tqi z0<1rGk|U%PHmXu?aNj8Wtw9grQl|NVdOLD|S{`>Nf}w$88(LQGgcVK;#qML|lzesE zP6U;pDoPR~k?hmX1;4VNDY~PbgQFwRU_*gXC2j>HVN!rlYJ??JCvh$gkivbx@hSNB zDgC4$LFAP7r##=5`aEpG8A!_dY7p8jf_hK}VBPfLx(>yLft?YNwB)IlHf=rZaewyM~Q9D z#xKp^SukFR(Uz|=DB=A)UYpx##@K+$oHbBhyj1UI(FNrpjbo2Z;4$Mo`fIhl%30g7 z`D8ZmhHp>LbumV6avpA0J37Dl<-FX>L@O_UPGZZT?aiqOLBoS)UZ9y9EKtF<@@f(X z&l(2)%EY3U{B>f5If}Wh^rkd4>=U*ZdFCY4DAGu6kUxxcu(KsnG zBNU>?gy)J4aabp9bfKbR-KewR6sX`Pu|G*g0VNZsJ4gSg&uomuWo#u7?gZrPCV0O- zT8i7WH**qblm|Yj(xH>+GN8WoG7@f+SRG-#ls=mbDB?ZqMg!SN( zr6D}mR??#o!_}Q*eFhXSj;dC9W0+(cgY3a0)Uzv{~tLRZ3=h<*JtHK z7EnVLaCwrzjs<3^p1;wUjcaQ$oF>{s4EI_Sez+CIirwCyr75CYgLAx$ygki`RE21b~F?qt!0YG{rR z4s>;oDe{6|G~_JsqJS!!HVRzl zWGM$+Hc6*12h_gzTxHyTgO>*BlY?KnQ137AZN58;#hcx81sMjJMoxuW&aKf<7P4G? z#dR6%_kK%ZBXYDT#*MNuZ~3;TGqBh5aat4a1=*f25T+t*r(sHej@2-{VBWr=6P@Cq zzx$29(i|{Pi6(k2hqD_Czh7%SB$`!f#|VjV;mR!yG3|LvgR}{3!(=dDkuF+v)`}M4 zdu)rq=vyN>Uv4u_Iu&xR$<^{VWbVz3pf#w8Z`VZAVocX-wFIH;#xeWd&_l+v`E&St zRp!N!z1bMgb=wk$TSfJmr-{`#pRj zRF@<0)o!c!fO$({|Hy@p>$4qFFQk@s@L9#qye-VjQ5^FE7hxn{7@zKX;t-0sssQj~ ze85912x+)8UCnd7FWU980Px|}y4%yo#Nt*d?VYSab8j)$zNh=D9@<{A+T9niHejD6 z_4t3(l`gk$LoYABa0g}HSnkjHE$$HL3+uY}=eNyKUSdq7AS`IZ^<$cRh-(n*oK=)f z++TwCyEgxN^?wzFEi86^qL8P?L>$s$H+hR?*41hX5vo29 z8kW|j1eE1ZSnSovK0WkuFJqy{83>oKe?2@pOSs;Z-870X$>MZ8hgCul#<2Syw(Z-e zR38}u{o0^&q5wrgZJW`L+62X#FD$=YRKZelbTvWF?i>Brx8{bmQnW7BB$EQ?pgstU zvk2ve4y)D#vu@hKhP98O#DmFG9)&} zvX_I3BfqP9MHfeZn}>%FWt6RYs0E&N6gqzW4#b*dxR(}BhpYx zbErDWKx*fB~W*I_`CyxDu#LkZC@UAJE0Dt$bOr>7Aajg9k*?moG18cKz$ zD+F4ZYGznhP{nOmnaaxe5zT5f#-`ed1$e%tfzvv=x_+KTPo?BIerdp_dL&XfBpTj5 zA_w9DJIpC2l$)Sqiss{<|7HpEWR1UeC{uRvne>y>F?bhFRd$=;>ZGD&K8uRAL(1Qs zi{H_`M$Bq#NH3{kRIjc_seBI?E8$9_-T9XWrrG^CMm|AD0{3+2uO`-DeN-@W0rord zIpB#>!acsTnFiAz-mfwVPRvjLc@NoJHZ?B}>vYw=lJov`Y0a)IrY13yem~_GB@n;` zOGKS)xRJ8&t#!MaTWcJh+a=sId%r(YJ|cZsD?r2V6uZAv&ezw~n`B2BW)oNA)`Pok zlG)c)htHsS<4?Pk{C;NUEVNH1Trk79=`NqHEHc$G$}Ys=?hRE{rXnxp3?8{z9^ZzE zCC{;CqP}Ucn-%o)XQ&K#s<7;#-J1H|(5}Jk!->;J=@jAj{)+TF_JrtqY$}{YMWl3~hk49QYO$%J`F(yQY-8@nVbUFPpM#;7E!5x>$3bGVBAvU1Cj zLnF!Ahk895*Y=yY^c)|0KM>!|Y92LJ(qe=uie}b!6J=D4OODr3MWI`!p6lyo|8PKI z!Z3_x=}unN(Td?=KcwCm<35IdHu0R%eLJ|$7?Ty7yz0^cBMF@*utUW}e%V@GuT>mAgqCzFAnE`bsViyz0?3>laiv5RlAg9v7GE|Qtq{+C&VRXo^ zF}fDgle*h__;5Q|$fv<5Lj|K;`(%29Zf|nYKI8PS&lk!ySbl*#ApA|m#ON##-$cn49!9tPxE1LX;LQTq>@{w zoDF(ECJ>owE;2ol*41y!TF8_N1g+NEX+RL*uklB!X_7mxG?{$ypaDEH#7 ztJ+}qGe@AxAO-J-rUyUoTl-5^pxX$ClPfhw$#;VIQ5JY<@pu4Yn30#`{6o3L*?Ndg zAbqKiL~E+qzap=q&ASZc47NhvzI#{Q6plL^7>qDC?BVZ-DnZ4o%yR5Ww88#DZ$FVc z0^tRlwo)cFk^ZWjg6iQ$^9sOz#_<^$ip0su%|p7n*whbCRp`ykS7HRwr6H zz*u7m9^UdGH$N{O$sJ1;?Df~mo7L~E8TTt6Rpx4T3tx;e5gbk)FF#ha2O@lO&Y?)@ zAnFBYF#%r#Q4GfQZy7yAJU6gcxug3x=p-L7;|P11pL6#0t(DRV%h>@xCRej%uo3(h z`D$y`|8o%4K%bt}CmOr#D68`?Ocv012Mjwm5`e56_*-ckObb`?7ZWDae5UKRN>h!`fNZz&pu+|3!4$CE1grQn_Iha+a$P7NGG&2VSaz3i%(| C!b%kY literal 0 HcmV?d00001 From 78f63d4d7fc3682187ba63439d28cb734b040175 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 20 Feb 2021 17:39:06 +0100 Subject: [PATCH 004/697] fixed compile --- retroshare-gui/src/gui/feeds/SecurityItem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.cpp b/retroshare-gui/src/gui/feeds/SecurityItem.cpp index 68419ee94..584eee212 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityItem.cpp @@ -216,11 +216,11 @@ void SecurityItem::updateItem() peerNameLabel->setText(tr("SSL request")); friendRequesttoolButton->hide(); requestLabel->hide(); - peerDetailsButton->hide; + peerDetailsButton->hide(); } else { - peerNameLabel->setText(tr("A unknown peer")); + peerNameLabel->setText(tr("An unknown peer")); friendRequesttoolButton->show(); requestLabel->show(); peerDetailsButton->show(); From 5f705686fa6a5c4c286d707f09aac48eec380a8e Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 21 Feb 2021 20:18:29 +0100 Subject: [PATCH 005/697] removed connections to notifyQt in NewFriendList since they are now handled by rsEvents --- retroshare-gui/src/gui/common/NewFriendList.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 561f7b524..43a26ba42 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -40,7 +40,6 @@ #include "gui/connect/ConnectFriendWizard.h" #include "gui/groups/CreateGroup.h" #include "gui/msgs/MessageComposer.h" -#include "gui/notifyqt.h" #include "gui/RetroShareLink.h" #include "retroshare-gui/RsAutoUpdatePage.h" #ifdef UNFINISHED_FD @@ -242,8 +241,8 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par // Using Queued connections here is pretty important since the notifications may come from a different thread. - connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); + // connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); + // connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool))); connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) ); From 335650904424abb8ec6b35c58a753bacbb090586 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 21 Feb 2021 20:55:38 +0100 Subject: [PATCH 006/697] removed regular update of node info in friend list model as it does not seem to be needed --- .../src/gui/common/FriendListModel.cpp | 41 +++++++++++-------- .../src/gui/common/NewFriendList.cpp | 10 ----- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index a7cfb8f0d..8155e72ae 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -54,7 +54,7 @@ static const uint16_t UNDEFINED_PROFILE_INDEX_VALUE = (sizeof(uintptr_t)==4)?0xf const QString RsFriendListModel::FilterString("filtered"); const uint32_t MAX_INTERNAL_DATA_UPDATE_DELAY = 300 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. -const uint32_t MAX_NODE_UPDATE_DELAY = 1 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. +const uint32_t MAX_NODE_UPDATE_DELAY = 10 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. static const uint32_t NODE_DETAILS_UPDATE_DELAY = 5; // update each node every 5 secs. @@ -768,24 +768,29 @@ void RsFriendListModel::checkInternalData(bool force) { rstime_t now = time(NULL); - if(mLastInternalDataUpdate + MAX_INTERNAL_DATA_UPDATE_DELAY < now || force) + if( (mLastInternalDataUpdate + MAX_INTERNAL_DATA_UPDATE_DELAY < now) || force) updateInternalData(); - - if(mLastNodeUpdate + MAX_NODE_UPDATE_DELAY < now) - { - for(uint32_t i=0;igetPeerDetails(id,mLocations[i].node_info); - mLocations[i].last_update_ts = now; - } - - mLastNodeUpdate = now; - } +// else +// { +// preMods(); +// +// if(mLastNodeUpdate + MAX_NODE_UPDATE_DELAY < now) +// { +// for(uint32_t i=0;igetPeerDetails(id,mLocations[i].node_info); +// mLocations[i].last_update_ts = now; +// } +// +// mLastNodeUpdate = now; +// } +// postMods(); +// } } const RsFriendListModel::HierarchicalGroupInformation *RsFriendListModel::getGroupInfo(const EntryIndex& e) const diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 43a26ba42..16f356957 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -239,11 +239,6 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par connect(mActionSortByState, SIGNAL(toggled(bool)), this, SLOT(toggleSortByState(bool))); connect(ui->peerTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(peerTreeWidgetCustomPopupMenu())); - // Using Queued connections here is pretty important since the notifications may come from a different thread. - - // connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - // connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool))); connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) ); connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)) ); @@ -1030,11 +1025,6 @@ void NewFriendList::forceUpdateDisplay() checkInternalData(true); } -// void NewFriendList::updateDisplay() -// { -// checkInternalData(false); -// } - void NewFriendList::moveToGroup() { RsFriendListModel::RsProfileDetails pinfo; From b8b3d7515c6f16dbdd3966d5d94079d746e565b7 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Mon, 22 Feb 2021 09:04:33 +0100 Subject: [PATCH 007/697] add missing mutex locks around free_pend calls in pqistreamer.cc --- libretroshare/src/pqi/pqistreamer.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/pqi/pqistreamer.cc b/libretroshare/src/pqi/pqistreamer.cc index f5d61ab9f..db38bfde2 100644 --- a/libretroshare/src/pqi/pqistreamer.cc +++ b/libretroshare/src/pqi/pqistreamer.cc @@ -304,17 +304,13 @@ int pqistreamer::tick_bio() int pqistreamer::tick_recv(uint32_t timeout) { -// Apart from a few exceptions that are atomic (mLastIncomingTs, mIncomingSize), only this pqi thread reads/writes mIncoming queue and related counters. -// The lock of pqistreamer mutex is thus not needed here. -// The mutex lock is still needed before calling locked_addTrafficClue because this method is also used by the thread pushing packets in mOutPkts. -// Locks around rates are provided internally. - if (mBio->moretoread(timeout)) { handleincoming(); } if(!(mBio->isactive())) { + RsStackMutex stack(mStreamerMtx); free_pend(); } return 1; @@ -325,6 +321,7 @@ int pqistreamer::tick_send(uint32_t timeout) /* short circuit everything if bio isn't active */ if (!(mBio->isactive())) { + RsStackMutex stack(mStreamerMtx); free_pend(); return 0; } @@ -720,6 +717,7 @@ int pqistreamer::handleincoming() if(!(mBio->isactive())) { + RsStackMutex stack(mStreamerMtx); mReading_state = reading_state_initial ; free_pend(); return 0; From 1a4585cceeb80d19d929e338d01032939521b444 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 24 Feb 2021 11:26:15 +0100 Subject: [PATCH 008/697] added dump of icon cache --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 69 ++++++++++++++++----- retroshare-gui/src/gui/gxs/GxsIdDetails.h | 3 +- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index a7d050dd5..60187e628 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -405,6 +405,9 @@ const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id, AvatarSize size) // now look for the icon + if(id.isNull()) + std::cerr << "Weird: null ID" << std::endl; + QMutexLocker lock(&mIconCacheMutex); auto& it = mDefaultIconCache[id]; @@ -432,6 +435,31 @@ const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id, AvatarSize size) return image; } +void GxsIdDetails::debug_dumpImagesCache() +{ + QMutexLocker lock(&mIconCacheMutex); + + std::cerr << "Current icon cache:" << std::endl; + + for(auto it:mDefaultIconCache) + { + std::cerr << " Identity " << it.first << ":" << std::endl; + + for(uint32_t i=0;i<4;++i) + { + std::cerr << " Size #" << i << ": " ; + + if(it.second[i].first>0) + { + int s = it.second[i].second.width()*it.second[i].second.height()*4; + std::cerr << " Present. Size=" << s << " bytes. Age: " << time(nullptr)-it.second[i].first << " secs. ago. Used: " << !it.second[i].second.isDetached() << std::endl; + } + else + std::cerr << " None." << std::endl; + } + } +} + void GxsIdDetails::checkCleanImagesCache() { time_t now = time(NULL); @@ -450,26 +478,35 @@ void GxsIdDetails::checkCleanImagesCache() for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();) { bool all_empty = true ; + std::cerr << " Examining pixmaps sizes for " << it->first << "." << std::endl; for(int i=0;i<4;++i) - if(it->second[i].first + ICON_CACHE_STORAGE_TIME < now && it->second[i].second.isDetached()) - { - int s = it->second[i].second.width()*it->second[i].second.height()*4; - - std::cerr << "Deleting pixmap " << it->first << " size " << i << " " << s << " bytes." << std::endl; - - it->second[i].second = QPixmap(); - ++nb_deleted; - size_deleted += s; - } - else + if(it->second[i].first>0) { - all_empty = false; - total_size += it->second[i].second.width()*it->second[i].second.height()*4; + if(it->second[i].first + ICON_CACHE_STORAGE_TIME < now && it->second[i].second.isDetached()) + { + int s = it->second[i].second.width()*it->second[i].second.height()*4; + + std::cerr << " Deleting pixmap " << it->first << " size " << i << " " << s << " bytes." << std::endl; + + it->second[i].second = QPixmap(); + it->second[i].first = 0; + ++nb_deleted; + size_deleted += s; + } + else + { + all_empty = false; + total_size += it->second[i].second.width()*it->second[i].second.height()*4; + std::cerr << " Keeking " << it->first << " size " << i << std::endl; + } } if(all_empty) - it = mDefaultIconCache.erase(it); + { + std::cerr << " Deleting entry " << it->first << " because no pixmaps are stored here. " << std::endl; + it = mDefaultIconCache.erase(it); + } else ++it; } @@ -490,10 +527,14 @@ bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len, Sha1CheckSum chksum = RsDirUtil::sha1sum(data,data_len); RsGxsId id(chksum.toByteArray()); + if(id.isNull()) + std::cerr << "Weird: null ID" << std::endl; + // We use a cache for images. QImage has its own smart pointer system, but it does not prevent // the same image to be allocated many times. We do this using a cache. The cache is also cleaned-up // on a regular time basis so as to get rid of unused images. + debug_dumpImagesCache(); checkCleanImagesCache(); // now look for the icon diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 3c04c46eb..05568aa3a 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -113,7 +113,8 @@ public: static const QPixmap makeDefaultIcon(const RsGxsId& id, AvatarSize size = MEDIUM); static bool loadPixmapFromData(const unsigned char *data, size_t data_len, QPixmap& pix, AvatarSize size = MEDIUM); - static void checkCleanImagesCache(); + static void checkCleanImagesCache(); + static void debug_dumpImagesCache(); /* Processing */ static void enableProcess(bool enable); From d62506479e4fb15c3654c8b2aab4d17336f3b43c Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 24 Feb 2021 20:55:42 +0100 Subject: [PATCH 009/697] fixed bug in debug dump of GxsIdDetails icon cache --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 60187e628..7ec21aa96 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -441,7 +441,7 @@ void GxsIdDetails::debug_dumpImagesCache() std::cerr << "Current icon cache:" << std::endl; - for(auto it:mDefaultIconCache) + for(const auto& it:mDefaultIconCache) // the & is important here, otherwise pairs are copied and isDetached() is always false! { std::cerr << " Identity " << it.first << ":" << std::endl; From f4bc964ac547db8611b0a7aaa0138800f12f30c3 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 25 Feb 2021 17:52:43 +0100 Subject: [PATCH 010/697] simplified the code in feeds GxsForumItem, making sure that group msg and parent msg data are all loaded correctly (avoids blank feed items) --- .../src/gui/feeds/GxsForumMsgItem.cpp | 191 ++++++++---------- .../src/gui/feeds/GxsForumMsgItem.h | 7 +- 2 files changed, 87 insertions(+), 111 deletions(-) diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index a1a17448c..af80babd5 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -125,16 +125,6 @@ void GxsForumMsgItem::setup() ui->parentFrame->hide(); } -bool GxsForumMsgItem::isTop() -{ -// if (mMessage.mMeta.mMsgId == mMessage.mMeta.mThreadId || mMessage.mMeta.mThreadId.isNull()) { - if (mMessage.mMeta.mParentId.isNull()) { - return true; - } - - return false; -} - bool GxsForumMsgItem::setGroup(const RsGxsForumGroup &group, bool doFill) { if (groupId() != group.mMeta.mGroupId) { @@ -145,9 +135,8 @@ bool GxsForumMsgItem::setGroup(const RsGxsForumGroup &group, bool doFill) mGroup = group; - if (doFill) { - fill(); - } + if (doFill) + fillGroup(); return true; } @@ -162,10 +151,11 @@ bool GxsForumMsgItem::setMessage(const RsGxsForumMsg &msg, bool doFill) mMessage = msg; - if (!isTop()) - loadParentMessage(mMessage.mMeta.mParentId); - else if(doFill) - fill(); + if(! mMessage.mMeta.mParentId.isNull()) + loadParentMessage(mMessage.mMeta.mParentId); + + if(doFill) + fillMessage(); return true; } @@ -299,112 +289,97 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg) * after a blocking call to RetroShare API complete */ mParentMessage = msg; - fill(); + fillParentMessage(); }, this ); }); } - -void GxsForumMsgItem::fill() +void GxsForumMsgItem::fillParentMessage() { - /* fill in */ + mInFill = true; -// if (isLoading()) { -// /* Wait for all requests */ -// return; -// } + ui->parentFrame->hide(); + RetroShareLink linkParent = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mParentMessage.mMeta.mGroupId, mParentMessage.mMeta.mMsgId, QString::fromUtf8(mParentMessage.mMeta.mMsgName.c_str())); + ui->parentSubLabel->setText(linkParent.toHtml()); + ui->parentMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mParentMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + ui->parentNameLabel->setId(mParentMessage.mMeta.mAuthorId); + + RsIdentityDetails idDetails ; + rsIdentity->getIdDetails(mParentMessage.mMeta.mAuthorId,idDetails); + + QPixmap pixmap ; + + if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(mParentMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); + + ui->parentAvatar->setPixmap(pixmap); + + mInFill = false; +} +void GxsForumMsgItem::fillMessage() +{ #ifdef DEBUG_ITEM - std::cerr << "GxsForumMsgItem::fill()"; - std::cerr << std::endl; + std::cerr << "GxsForumMsgItem::fill()"; + std::cerr << std::endl; #endif + mInFill = true; + + if(!mIsHome && mCloseOnRead && !IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) + removeItem(); + + QString title = tr("Forum Feed") + ": "; + RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, groupName()); + title += link.toHtml(); + ui->titleLabel->setText(title); + + setReadStatus(IS_MSG_NEW(mMessage.mMeta.mMsgStatus), IS_MSG_UNREAD(mMessage.mMeta.mMsgStatus) || IS_MSG_NEW(mMessage.mMeta.mMsgStatus)); + + if (!mIsHome && IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) + mCloseOnRead = true; + + RsIdentityDetails idDetails ; + rsIdentity->getIdDetails(mMessage.mMeta.mAuthorId,idDetails); + + QPixmap pixmap ; + + if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(mMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); + + ui->avatar->setPixmap(pixmap); + + ui->nameLabel->setId(mMessage.mMeta.mAuthorId); + + RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, mMessage.mMeta.mMsgId, messageName()); + ui->subLabel->setText(msgLink.toHtml()); + if (wasExpanded() || ui->expandFrame->isVisible()) + fillExpandFrame(); + + ui->timestamplabel->setText(DateTime::formatLongDateTime(mMessage.mMeta.mPublishTs)); + + /* header stuff */ + ui->subjectLabel->setText(msgLink.toHtml()); + + if (mIsHome) + { + /* disable buttons */ + ui->clearButton->setEnabled(false); + ui->clearButton->hide(); + } + + mInFill = false; +} +void GxsForumMsgItem::fillGroup() +{ mInFill = true; - if (!mIsHome) - { - if (mCloseOnRead && !IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) { - removeItem(); - } - } + ui->unsubscribeButton->setEnabled(IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags)) ; - QString title = tr("Forum Feed") + ": "; - RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, groupName()); - title += link.toHtml(); - ui->titleLabel->setText(title); - - if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags)) { - ui->unsubscribeButton->setEnabled(true); - - setReadStatus(IS_MSG_NEW(mMessage.mMeta.mMsgStatus), IS_MSG_UNREAD(mMessage.mMeta.mMsgStatus) || IS_MSG_NEW(mMessage.mMeta.mMsgStatus)); - } else { - ui->unsubscribeButton->setEnabled(false); - } - - if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) { + if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) ui->iconLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); - } else { + else ui->iconLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums-default.png")); - } - - if (!mIsHome) { - if (IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) { - mCloseOnRead = true; - } - } - - RsIdentityDetails idDetails ; - rsIdentity->getIdDetails(mMessage.mMeta.mAuthorId,idDetails); - - QPixmap pixmap ; - - if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) - pixmap = GxsIdDetails::makeDefaultIcon(mMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); - - ui->avatar->setPixmap(pixmap); - - ui->nameLabel->setId(mMessage.mMeta.mAuthorId); - - RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, mMessage.mMeta.mMsgId, messageName()); - ui->subLabel->setText(msgLink.toHtml()); - if (wasExpanded() || ui->expandFrame->isVisible()) { - fillExpandFrame(); - } - - ui->timestamplabel->setText(DateTime::formatLongDateTime(mMessage.mMeta.mPublishTs)); - - if (isTop()) { - ui->parentFrame->hide(); - } else { - - RetroShareLink linkParent = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mParentMessage.mMeta.mGroupId, mParentMessage.mMeta.mMsgId, QString::fromUtf8(mParentMessage.mMeta.mMsgName.c_str())); - ui->parentSubLabel->setText(linkParent.toHtml()); - ui->parentMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mParentMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); - - ui->parentNameLabel->setId(mParentMessage.mMeta.mAuthorId); - - RsIdentityDetails idDetails ; - rsIdentity->getIdDetails(mParentMessage.mMeta.mAuthorId,idDetails); - - QPixmap pixmap ; - - if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) - pixmap = GxsIdDetails::makeDefaultIcon(mParentMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); - - ui->parentAvatar->setPixmap(pixmap); - - } - - /* header stuff */ - ui->subjectLabel->setText(msgLink.toHtml()); - - if (mIsHome) - { - /* disable buttons */ - ui->clearButton->setEnabled(false); - - ui->clearButton->hide(); - } mInFill = false; } diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h index 410a97931..17287ada1 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h @@ -77,11 +77,12 @@ signals: private: void setup(); - void fill(); - void fillExpandFrame(); + void fillGroup(); + void fillMessage(); + void fillParentMessage(); + void fillExpandFrame(); void setReadStatus(bool isNew, bool isUnread); void setAsRead(); - bool isTop(); private: bool mInFill; From dc90b49496c0ae24606fc84ef482d592f32751b9 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 25 Feb 2021 21:43:46 +0100 Subject: [PATCH 011/697] Fixing margins for comments feeds --- retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui | 4 ++-- retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui index 65d76e355..5b244fe90 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui @@ -369,7 +369,7 @@ 3 - 3 + 0 9 @@ -427,7 +427,7 @@ Name - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui index c1eec128c..c686adb3c 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui @@ -254,7 +254,7 @@ 3 - 3 + 0 9 @@ -312,7 +312,7 @@ Name - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop From 7ab7f226e1359b4a857b36ba41f9600ab6c9b690 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 25 Feb 2021 22:48:21 +0100 Subject: [PATCH 012/697] updated translation files --- retroshare-gui/src/lang/retroshare_af.ts | 1804 +++++++++++------- retroshare-gui/src/lang/retroshare_bg.ts | 1798 +++++++++++------- retroshare-gui/src/lang/retroshare_ca_ES.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_cs.ts | 1822 +++++++++++------- retroshare-gui/src/lang/retroshare_da.ts | 1808 +++++++++++------- retroshare-gui/src/lang/retroshare_de.ts | 1860 ++++++++++++------- retroshare-gui/src/lang/retroshare_el.ts | 1846 +++++++++++------- retroshare-gui/src/lang/retroshare_en.ts | 1804 +++++++++++------- retroshare-gui/src/lang/retroshare_es.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_fi.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_fr.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_hu.ts | 1848 ++++++++++++------ retroshare-gui/src/lang/retroshare_it.ts | 1836 ++++++++++++------ retroshare-gui/src/lang/retroshare_ja_JP.ts | 1798 +++++++++++------- retroshare-gui/src/lang/retroshare_ko.ts | 1806 +++++++++++------- retroshare-gui/src/lang/retroshare_nl.ts | 1846 +++++++++++------- retroshare-gui/src/lang/retroshare_pl.ts | 1834 +++++++++++------- retroshare-gui/src/lang/retroshare_pt.ts | 1804 +++++++++++------- retroshare-gui/src/lang/retroshare_ru.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_sl.ts | 1798 +++++++++++------- retroshare-gui/src/lang/retroshare_sr.ts | 1790 +++++++++++------- retroshare-gui/src/lang/retroshare_sv.ts | 1848 +++++++++++------- retroshare-gui/src/lang/retroshare_tr.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_zh_CN.ts | 1857 ++++++++++++------ retroshare-gui/src/lang/retroshare_zh_TW.ts | 1800 +++++++++++------- 25 files changed, 29937 insertions(+), 15812 deletions(-) diff --git a/retroshare-gui/src/lang/retroshare_af.ts b/retroshare-gui/src/lang/retroshare_af.ts index 450f45326..8848041e8 100644 --- a/retroshare-gui/src/lang/retroshare_af.ts +++ b/retroshare-gui/src/lang/retroshare_af.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: - + Location: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13794,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13806,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13884,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13964,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14049,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14138,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14149,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14159,7 @@ Do you want to save message ? - + from @@ -13829,6 +14168,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14472,7 @@ Reported error: - + Groups @@ -14158,19 +14502,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14524,7 @@ Reported error: - + Show Items @@ -14379,18 +14723,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14772,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14786,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14797,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14858,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14894,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14941,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15021,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15031,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15158,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15218,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15242,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15252,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15277,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15343,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15375,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15420,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15627,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15644,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15776,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15812,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15840,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15854,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15939,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15979,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16203,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16539,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16670,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16686,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16707,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16722,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16783,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16442,13 +16806,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16458,60 +16816,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16522,7 +16870,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16591,7 +16939,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16626,7 +16979,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16742,8 +17095,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17011,12 +17374,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17031,17 +17389,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17066,10 +17439,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17079,13 +17462,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17097,10 +17515,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17108,44 +17534,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17155,17 +17581,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17175,7 +17601,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17198,7 +17624,7 @@ and use the import button to load it - + follow Parent Group @@ -17208,7 +17634,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17233,7 +17659,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17269,29 +17695,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17369,7 +17795,7 @@ and use the import button to load it QObject - + Confirmation @@ -17608,7 +18034,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17643,7 +18069,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17781,7 +18207,7 @@ Reported error is: - + TR up @@ -17826,7 +18252,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17842,7 +18268,7 @@ Reported error is: - + %1 seconds ago @@ -17926,7 +18352,7 @@ Security: no anonymous IDs - + Error @@ -18316,11 +18742,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18654,7 +19075,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18876,18 +19297,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19324,7 +19766,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19339,7 +19781,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19387,7 +19829,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19402,7 +19844,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19417,12 +19859,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19669,7 +20111,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19689,7 +20131,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19702,10 +20144,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19717,7 +20164,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19755,7 +20202,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19763,7 +20210,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19823,7 +20270,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20177,7 +20624,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20256,7 +20703,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20276,7 +20723,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20381,12 +20828,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20396,7 +20843,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20659,13 +21106,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21131,7 +21578,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21159,7 +21606,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21256,7 +21703,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21291,12 +21738,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21961,7 +22408,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22003,7 +22450,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22059,7 +22506,7 @@ This choice can be reverted in settings. - + DHT @@ -22591,7 +23038,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22601,13 +23048,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22616,6 +23062,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22889,27 +23360,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22917,7 +23383,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22928,7 +23394,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23135,7 +23601,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23229,7 +23695,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23361,7 +23827,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23372,7 +23838,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23382,7 +23848,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23392,7 +23858,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23407,7 +23873,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23649,7 +24115,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23745,7 +24211,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24113,7 +24579,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24207,8 +24673,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24219,7 +24685,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24244,12 +24710,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24269,7 +24735,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24307,7 +24773,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24317,12 +24783,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24357,12 +24818,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24392,7 +24853,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24402,7 +24863,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24414,7 +24875,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24422,7 +24883,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24503,8 +24964,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24533,6 +24994,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24645,7 +25111,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_bg.ts b/retroshare-gui/src/lang/retroshare_bg.ts index d912bc552..86615025a 100644 --- a/retroshare-gui/src/lang/retroshare_bg.ts +++ b/retroshare-gui/src/lang/retroshare_bg.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -128,12 +128,12 @@ - + Search Criteria - + Add a further search criterion. @@ -178,7 +178,7 @@ AlbumDialog - + Album @@ -297,7 +297,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -340,8 +340,8 @@ p, li { white-space: pre-wrap; } ФормулÑÑ€ - - + + TextLabel @@ -408,7 +408,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -433,7 +433,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -458,7 +458,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -533,7 +533,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -548,7 +548,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -614,13 +614,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -629,25 +634,30 @@ p, li { white-space: pre-wrap; } Премахване на - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -655,7 +665,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -675,44 +685,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings ÐаÑтройки + TextLabel + + + + Reset Връщане - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -722,30 +741,23 @@ p, li { white-space: pre-wrap; } - Save - Запазване + Запазване - Cancel - ОтмÑна + ОтмÑна - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -767,7 +779,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -901,7 +913,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -979,6 +991,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + РазширÑване + + + + Set as read and remove item + Задай като четене и премахване на елемент + + + + Remove Item + Премахни елемент + + + + Name + Име + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Скрий + + BwCtrlWindow @@ -1114,6 +1205,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + По подразбиране + + + + Dark + + ChannelPage @@ -1166,6 +1267,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + РазширÑване + + + + Set as read and remove item + Задай като четене и премахване на елемент + + + + Remove Item + Премахни елемент + + + + Name + Име + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Скрий + + ChatLobbyDialog @@ -1374,22 +1554,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1403,11 +1583,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1832,13 +2007,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1903,17 +2072,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1934,11 +2098,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1999,11 +2164,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2142,8 +2313,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2312,7 +2498,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2329,12 +2515,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2406,7 +2592,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2442,12 +2628,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2463,7 +2649,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2483,7 +2669,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2641,12 +2827,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2657,12 +2843,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2678,31 +2864,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2718,22 +2914,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2768,13 +2964,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2789,7 +2990,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2800,17 +3001,22 @@ Double click on it to add his name on text writer. без - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2820,7 +3026,7 @@ Double click on it to add his name on text writer. - + with @@ -2904,32 +3110,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Име: - + Location: - + Options ÐаÑтройки - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2939,7 +3145,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2964,12 +3170,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2989,32 +3195,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3060,17 +3266,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3090,12 +3296,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3143,7 +3349,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3187,12 +3423,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3222,7 +3458,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3280,12 +3516,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3360,7 +3596,12 @@ even if you don't make friends. - + + Status + Ð¡Ñ‚Ð°Ñ‚ÑƒÑ + + + <!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; } @@ -3782,7 +4023,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3926,7 +4167,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3941,7 +4182,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3957,7 +4198,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3973,12 +4214,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4000,7 +4241,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4126,7 +4367,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4172,7 +4413,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4182,7 +4423,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4209,17 +4450,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4250,12 +4511,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4275,7 +4536,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4363,7 +4624,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4778,7 +5039,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5781,7 +6042,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6272,7 +6533,7 @@ at least one peer was not added to a group - + Mark all @@ -6286,7 +6547,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6390,7 +6651,7 @@ at least one peer was not added to a group - + Network @@ -6455,7 +6716,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6486,7 +6747,7 @@ at least one peer was not added to a group - + Node name @@ -6745,12 +7006,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7113,7 +7374,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7178,7 +7439,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7201,7 +7462,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7402,7 +7663,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Заглавие @@ -7412,13 +7673,30 @@ p, li { white-space: pre-wrap; } ТърÑене в заглавието - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7428,42 +7706,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7478,40 +7721,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Име - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7660,7 +7894,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7681,12 +7915,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8083,7 +8317,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8183,12 +8417,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8199,18 +8433,18 @@ p, li { white-space: pre-wrap; } - + Feeds Информационни канали - - + + Click to switch to list view - + Show unread posts only @@ -8220,12 +8454,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8285,7 +8519,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8300,12 +8534,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8381,23 +8615,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8419,11 +8666,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8908,17 +9150,17 @@ before you can comment - + Search forums ТърÑене Форуми - + New Thread - + Threaded View @@ -8928,19 +9170,19 @@ before you can comment - - + + Title Заглавие - - + + Date Дата - + Author Ðвтор @@ -8955,7 +9197,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9000,23 +9252,23 @@ before you can comment ТърÑене на автор - + No name ÐÑма име - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9054,12 +9306,12 @@ before you can comment Маркирай като непрочетено - + Copy RetroShare Link - + Hide Скрий @@ -9068,7 +9320,7 @@ before you can comment РазширÑване - + [unknown] @@ -9098,8 +9350,8 @@ before you can comment - - + + Distribution @@ -9186,12 +9438,12 @@ before you can comment - + New thread - + Edit Редактиране @@ -9247,7 +9499,7 @@ before you can comment - + Author's reputation @@ -9267,7 +9519,7 @@ before you can comment - + <b>Loading...<b> @@ -9307,6 +9559,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9374,7 +9631,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9406,11 +9663,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9816,7 +10068,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9831,7 +10083,7 @@ This message is missing. You should receive it later. ОтварÑне в нов раздел - + Remove this search @@ -9841,12 +10093,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9913,12 +10165,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9933,7 +10185,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10447,7 +10699,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10456,7 +10708,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10482,7 +10734,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10556,49 +10808,55 @@ p, li { white-space: pre-wrap; } ФормулÑÑ€ - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10646,17 +10904,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10671,7 +10924,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10936,14 +11194,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10953,12 +11211,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11102,7 +11360,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11174,7 +11432,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11189,24 +11447,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11221,7 +11479,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11280,13 +11538,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11346,7 +11609,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11394,7 +11657,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11403,12 +11666,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11420,12 +11683,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11541,17 +11804,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11708,8 +11971,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11720,7 +11983,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11730,7 +11993,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11790,7 +12053,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11800,7 +12063,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11838,7 +12101,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11855,14 +12118,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11873,24 +12136,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11910,12 +12176,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11925,7 +12216,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11935,7 +12226,12 @@ These identities will soon be not supported anymore. Тип - + + Choose image... + + + + @@ -11975,12 +12271,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11990,7 +12281,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12095,7 +12386,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12254,7 +12545,7 @@ These identities will soon be not supported anymore. - + Options ÐаÑтройки @@ -12286,12 +12577,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12420,7 +12711,7 @@ These identities will soon be not supported anymore. Показване - + Make sure this link has not been forged to drag you to a malicious website. @@ -12465,7 +12756,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12494,7 +12785,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12596,7 +12887,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12691,12 +12982,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12726,7 +13017,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12752,12 +13048,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12768,7 +13064,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -13022,7 +13318,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13036,6 +13332,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13048,7 +13359,7 @@ Do you want to save message ? От: - + Bullet list (disc) @@ -13088,13 +13399,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13233,8 +13544,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13246,12 +13572,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13326,12 +13652,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13392,18 +13724,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13418,7 +13765,7 @@ Do you want to save message ? - + Load images always for this message @@ -13527,7 +13874,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13543,14 +13890,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13621,7 +13968,7 @@ Do you want to save message ? - + Subject @@ -13701,7 +14048,7 @@ Do you want to save message ? - + Open in a new window @@ -13786,7 +14133,7 @@ Do you want to save message ? - + Drafts @@ -13875,7 +14222,7 @@ Do you want to save message ? - + Delete Message @@ -13886,7 +14233,7 @@ Do you want to save message ? - + Expand РазширÑване @@ -13896,7 +14243,7 @@ Do you want to save message ? Премахни елемент - + from @@ -13905,6 +14252,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14204,7 +14556,7 @@ Reported error: - + Groups @@ -14234,19 +14586,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14256,7 +14608,7 @@ Reported error: - + Show Items @@ -14455,18 +14807,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14504,7 +14856,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14518,7 +14870,7 @@ at least one peer was not added to a group - + Newest on top @@ -14529,20 +14881,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14575,22 +14942,22 @@ at least one peer was not added to a group - + Test ТеÑÑ‚ - + Chat Room - + Systray Icon - + Message @@ -14611,12 +14978,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14663,27 +15025,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14733,7 +15105,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14747,7 +15119,7 @@ at least one peer was not added to a group ЕмиÑÐ¸Ñ - + Systray @@ -14874,17 +15246,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14939,22 +15306,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14968,7 +15330,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14978,22 +15340,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15013,7 +15365,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15079,27 +15431,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15111,7 +15463,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15156,27 +15508,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15347,8 +15715,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15365,7 +15732,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15504,7 +15871,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15540,7 +15907,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15572,6 +15939,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment Добави коментар + + + Album + + PhotoItem @@ -15581,12 +15953,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.ФормулÑÑ€ - + TextLabel - + <!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; } @@ -15666,7 +16038,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15706,7 +16078,7 @@ requesting to edit it! - + Stop @@ -15930,17 +16302,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16266,7 +16638,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16397,13 +16769,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16413,7 +16785,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16434,12 +16806,12 @@ p, li { white-space: pre-wrap; } - + Hide Скрий - + Vote up @@ -16449,7 +16821,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item Задай като четене и премахване на елемент @@ -16510,7 +16882,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16556,13 +16928,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16572,60 +16938,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown непознат - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16636,7 +16992,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16705,7 +17061,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16740,7 +17101,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16856,8 +17217,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17125,12 +17496,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17145,17 +17511,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + От: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17180,10 +17561,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17193,13 +17584,48 @@ and use the import button to load it - + + Post + + + + Cancel ОтмÑна - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17222,10 +17648,18 @@ and use the import button to load it ФормулÑÑ€ - - - - + + + + + Click to view picture + + + + + + + Image @@ -17233,44 +17667,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17280,17 +17714,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17300,7 +17734,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17308,7 +17742,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17323,7 +17757,7 @@ and use the import button to load it - + follow Parent Group @@ -17333,7 +17767,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17358,7 +17792,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17394,29 +17828,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17494,7 +17928,7 @@ and use the import button to load it QObject - + Confirmation @@ -17733,7 +18167,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17768,7 +18202,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17906,7 +18340,7 @@ Reported error is: - + TR up @@ -17951,7 +18385,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17967,7 +18401,7 @@ Reported error is: - + %1 seconds ago @@ -18051,7 +18485,7 @@ Security: no anonymous IDs - + Error @@ -18441,11 +18875,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18779,7 +19208,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19001,18 +19430,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19449,7 +19899,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19464,7 +19914,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19512,7 +19962,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Запазване - + Collection Editor @@ -19527,7 +19977,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19542,12 +19992,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19794,7 +20244,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Име @@ -19814,7 +20264,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19827,10 +20277,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Заглавие + + + UnRead + + Date @@ -19842,7 +20297,7 @@ If you believe it is correct, remove the corresponding line from the file and re Ðвтор - + Information for this identity is currently missing. @@ -19880,7 +20335,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19888,7 +20343,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Дата @@ -19948,7 +20403,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20302,7 +20757,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20381,7 +20836,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20401,7 +20856,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20506,12 +20961,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20521,7 +20976,7 @@ prevents the message to be forwarded to your friends. - + Expand РазширÑване @@ -20784,13 +21239,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21256,7 +21711,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21284,7 +21739,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Ð¡Ñ‚Ð°Ñ‚ÑƒÑ @@ -21381,7 +21836,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21416,12 +21871,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22086,7 +22541,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22128,7 +22583,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22184,7 +22639,7 @@ This choice can be reverted in settings. - + DHT @@ -22716,7 +23171,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22726,13 +23181,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22741,6 +23195,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23014,27 +23493,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23042,7 +23516,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23053,7 +23527,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Име @@ -23260,7 +23734,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23354,7 +23828,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23486,7 +23960,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23497,7 +23971,7 @@ p, li { white-space: pre-wrap; } - + Path Пътека @@ -23507,7 +23981,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23517,7 +23991,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23532,7 +24006,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23774,7 +24248,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23870,7 +24344,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24238,7 +24712,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24332,8 +24806,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24344,7 +24818,7 @@ p, li { white-space: pre-wrap; } - + Preview Преглед @@ -24369,12 +24843,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24394,7 +24868,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24432,7 +24906,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24442,12 +24916,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24482,12 +24955,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24521,7 +24994,7 @@ p, li { white-space: pre-wrap; } Ðов - + Yourself @@ -24531,7 +25004,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24543,7 +25016,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24551,7 +25024,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24632,8 +25105,8 @@ p, li { white-space: pre-wrap; } ФормулÑÑ€ - - + + Avatar @@ -24662,6 +25135,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24774,7 +25252,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ca_ES.ts b/retroshare-gui/src/lang/retroshare_ca_ES.ts index 70582e0b4..fe57c6488 100644 --- a/retroshare-gui/src/lang/retroshare_ca_ES.ts +++ b/retroshare-gui/src/lang/retroshare_ca_ES.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare versió @@ -79,7 +79,7 @@ Passa-t'ho bé ;-) - + Only Hidden Node Només node ocult @@ -128,12 +128,12 @@ RetroShare: Cerca Avançada - + Search Criteria Criteris de Cerca - + Add a further search criterion. Afegeix un altre criteri de cerca. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Àlbum @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Formulari - - + + TextLabel EtiquetaTexte @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Barra d'eines - + Icon Only Només icones @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } Escull l'estil dels botons de les eines. - + Icon Size = 8x8 Mida icona = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Mida Icona = 128x128 - + Status Bar Barra d'estat @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } Deshabilitar consells sobre l'àrea de notificació - + Main page items: Elements de la pàgina principal: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } Llista d'elements - + Icon Size = 32x32 Mida icona = 32x32 @@ -827,14 +827,23 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Canvia l'avatar - + + TextLabel + + + + Your Avatar Picture La fotografia del teu avatar - + + Browse... + + + Add Avatar - Afegir avatar + Afegir avatar @@ -842,25 +851,34 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Treure - + Set your Avatar picture Tria la fotografia del teu avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Carrega avatar + Carrega avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Feu clic per canviar l'avatar @@ -868,7 +886,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem RetroShare Bandwidth Usage Ús d'ampla de banda del RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostra la configuració + TextLabel + + + + Reset Restablir - Receive Rate - Taxa de Recepció + Taxa de Recepció - Send Rate - Taxa d'enviament + Taxa d'enviament - + Always on Top Sempre per damunt - Style - Estil + Estil - + Changes the transparency of the Bandwidth Graph Canvia la transparència de la gràfica d'ample de banda - + 100 100 @@ -935,30 +974,27 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem % Opac - Save - Desa + Desa - Cancel - Cancel·la + Cancel·la - + Since: Des de: - Hide Settings - Amagar opcions + Amagar opcions BandwidthStatsWidget - + Sum Suma @@ -980,7 +1016,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Comptador - + Average Mitjana @@ -1114,7 +1150,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem - + Comments Comentaris @@ -1192,6 +1228,85 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem + + BoardsCommentsItem + + + I like this + M'agrada + + + + 0 + 0 + + + + I dislike this + No m'agrada + + + + Toggle Message Read Status + Canvia l'estat dels missatges llegits + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copia l'enllaç RetroShare + + + + + Expand + Ampliar + + + + Set as read and remove item + Marcar com llegit i eliminar l'element + + + + Remove Item + Eliminar l'element + + + + Name + Nom + + + + Comm value + + + + + Comment + Comentari + + + + Comments + Comentaris + + + + Hide + Amagar + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Log scale Escala logaritmica + + + Default + Per defecte + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + M'agrada + + + + 0 + 0 + + + + I dislike this + No m'agrada + + + + Toggle Message Read Status + Canvia l'estat dels missatges llegits + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copia l'enllaç RetroShare + + + + + Expand + Ampliar + + + + Set as read and remove item + Marcar com llegit i eliminar l'element + + + + Remove Item + Eliminar l'element + + + + Name + Nom + + + + Comm value + + + + + Comment + Comentari + + + + Comments + Comentaris + + + + Hide + Amagar + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to Xats - You have %1 new messages - Tens %1 nous missatges + Tens %1 nous missatges + + + You have %1 new message + Tens %1 nou missatge + + + %1 new messages + %1 missatges nous + + + %1 new message + %1 missatges nous + + + + You have %1 mentions + - You have %1 new message - Tens %1 nou missatge + You have %1 mention + - %1 new messages - %1 missatges nous + %1 mentions + - %1 new message - %1 missatges nous + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Suprimeix-ho tot - - - mention(s) - - ChatLobbyWidget @@ -2119,13 +2334,11 @@ Fes doble clic a les sales per entrar-hi i xatejar. Variant: - Group chat - Xat en grup + Xat en grup - - + Private chat Xat privat @@ -2190,17 +2403,16 @@ Fes doble clic a les sales per entrar-hi i xatejar. /me està enviant un missatge amb /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">En aquesta pestanya pots modificar quants missatges de xat el RetroShare mantindrà emmagatzemats en disc i quantes de les converses prèvies mostrarà pels diferents sistemes de xat. El període màxim d'emmagatzematge et permet descartar missatges vells i impedeix que l'historial de xat s'ompli amb xats esporàdics (per ex. sales de xat i xats distants).</p></body></html> - Chatlobbies - Salesxat + Salesxat - + Enabled: Activat: @@ -2221,11 +2433,12 @@ Fes doble clic a les sales per entrar-hi i xatejar. + Chat rooms Sales de xat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Marca'l si identitats i texts a la part superior han de coincidir en majúscules/minúscules pel comptador. @@ -2286,11 +2499,17 @@ Fes doble clic a les sales per entrar-hi i xatejar. + Broadcast Difusió - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Missatges emmagatzemats (0 = il·limitat): @@ -2437,8 +2656,23 @@ Fes doble clic a les sales per entrar-hi i xatejar. Xat privat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2611,7 +2845,7 @@ Fes doble clic a les sales per entrar-hi i xatejar. - + is typing... està escrivint... @@ -2630,12 +2864,12 @@ after HTML conversion. després de convertir a HTML. - + Choose your font. Escull el tipus de lletra - + Do you really want to physically delete the history? Segur que vols eliminar físicament l'historial? @@ -2707,7 +2941,7 @@ després de convertir a HTML. No deixis de colorejar fins trobar X elements (Necessita més UCP) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trobar anterior </b><br/><i>Ctrl+Shift+G</i> @@ -2747,12 +2981,12 @@ després de convertir a HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marca el text seleccionat</b><br><i>Ctrl+M</i> - + Person id: Id de la persona: @@ -2769,7 +3003,7 @@ Doble clic per afegir el seu nom al text escrit. No signat - + items found. Elements trobats. @@ -2789,7 +3023,7 @@ Doble clic per afegir el seu nom al text escrit. Escriu un missatge aquí - + Don't stop to color after No t'aturis a colorejar després de @@ -2947,12 +3181,12 @@ Doble clic per afegir el seu nom al text escrit. ConfCertDialog - + Details Detalls - + Local Address Adreça local @@ -2963,12 +3197,12 @@ Doble clic per afegir el seu nom al text escrit. Adreça externa - + Node info: Informació de node: - + Current address: Adreça actual: @@ -2984,31 +3218,36 @@ Doble clic per afegir el seu nom al text escrit. Port - + Include signatures Inclou les signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: no es poden obtenir detalls del contacte. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3024,22 +3263,27 @@ Doble clic per afegir el seu nom al text escrit. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Encriptació - + Not connected No connectat - + Retroshare node details Detalls del node de RetroShare - + Node name : Nom del node : @@ -3074,13 +3318,18 @@ Doble clic per afegir el seu nom al text escrit. Missatge d'estat: - + + Connectivity + + + + List of known addresses: Llista d'adreces conegudes: - - + + Retroshare Certificate Certificat RetroShare @@ -3095,7 +3344,7 @@ Doble clic per afegir el seu nom al text escrit. - + Hidden Address Adreça oculta @@ -3106,11 +3355,12 @@ Doble clic per afegir el seu nom al text escrit. cap + <p>This certificate contains: - <p>Aquest certificat conté: + <p>Aquest certificat conté: - + <li>a <b>node ID</b> and <b>name</b> <li>un<b>ID de node</b> i <b>nom</b> @@ -3123,12 +3373,12 @@ Doble clic per afegir el seu nom al text escrit. una <b>adreça IP</b> i <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Pots utilitzar aquest certificat per fer nous amics. Envia'l per correu o entrega'l en ma.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Aquesta és la ID del node <span style=" font-weight:600;">OpenSSL</span> certifcat, signat pels a sobre llistats <span style=" font-weight:600;">clau</span> PGP. </p></body></html> @@ -3138,7 +3388,7 @@ Doble clic per afegir el seu nom al text escrit. <html><head/><body><p>Aquest és el mètode d'encriptat utilitzat per <span style=" font-weight:600;">OpenSSL</span>. La conexió cap a nodes amics</p><p>és sempre forta i si hi ha DHE disponible la conexió a més a més utilitza</p><p>&quot;perfect forward secrecy&quot;.</p></body></html> - + with amb @@ -3344,12 +3594,12 @@ Doble clic per afegir el seu nom al text escrit. Detalls sobre la petició - + Peer details Detalls del contacte - + Name: Nom: @@ -3367,12 +3617,12 @@ resources. Si us plau, tingues en compte que RetroShare necessitarà una quantitat excessiva d'ample de banda, memòria i CPU si afegeixes masses amics. Pots afegir tants amics com vulguis, però més de 40 serà probablement excessiu. - + Location: Ubicació: - + Options Opcions @@ -3409,12 +3659,12 @@ resources. Enganxar certificat - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Aquesta casella espera el certificat de Retroshare del teu amic. AVÃS: No és el mateix que la clau del perfil del teu amic. No enganxis la clau del perfil del teu amic aquí (Ni tan sols part d'ella). No funcionarà.</p></body></html> - + Add friend to group: Afegir amic al grup: @@ -3424,7 +3674,7 @@ resources. Autentica amic (Signa clau PGP) - + Please paste below your friend's Retroshare ID @@ -3449,7 +3699,7 @@ resources. - + Add as friend to connect with Afegir com amic amb qui connectar @@ -3458,7 +3708,7 @@ resources. Per acceptar la petició de l'amic, clica al botó acabar. - + Sorry, some error appeared Ho sentim, ha aparegut algun error @@ -3478,32 +3728,32 @@ resources. Detalls sobre el teu amic: - + Key validity: Validesa de la clau: - + Profile ID: - + Signers Signants - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Les signatures a sota testimonien criptogràficament que els propietaris de les claus llistades reconeixen la clau PGP com autèntica. </span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Aquest contacte ja és a la llista d'amics. Afegir-lo potser només actualitzi la seva adreça IP. - + To accept the Friend Request, click the Accept button. @@ -3549,7 +3799,7 @@ resources. - + Certificate Load Failed Càrrega de certificat fallida @@ -3586,12 +3836,12 @@ resources. El certificat sembla vàlid - + Not a valid Retroshare certificate! No és un certificat de Retroshare vàlid! - + RetroShare Invitation Invitació al RetroShare @@ -3613,12 +3863,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Aquest és el teu certificat! No vols fer-te amic amb tu mateix, oi? - + @@ -3666,7 +3916,37 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Tens una petició d'amic de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3754,12 +4034,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Utilitza com a font directa quan estigui disponible - + IP-Addr: Adreça IP: - + IP-Address Adreça IP: @@ -3825,7 +4105,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Afegeix clau al clauer - + This key is already in your keyring Aquesta claus ja és al clauer @@ -3886,12 +4166,12 @@ encara que no sigueu amics. <p>Aquest certificat no té IP. Només podràs utilitzar descobriment i DHT per trobar-lo. Com que és necessari que estigui a la llista blanca d'IPs el contacte provocarà un avís a la pestanya de Novetats. Des d'allí podràs afegir la IP a la llista blanca.</p> - + [Unknown] [Desconegut] - + Added with certificate from %1 Afegit amb el certificat de %1 @@ -3978,7 +4258,12 @@ encara que no sigueu amics. Resultat UDP - + + Status + Estat + + + <!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; } @@ -4408,7 +4693,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4560,7 +4845,7 @@ p, li { white-space: pre-wrap; } No s'ha seleccionat cap cercle de limitacions - + [Unknown] [Desconegut] @@ -4575,7 +4860,7 @@ p, li { white-space: pre-wrap; } Treure - + Search Cercar @@ -4595,7 +4880,7 @@ p, li { white-space: pre-wrap; } Signat per nodes coneguts - + Edit Circle Editar cercle @@ -4615,12 +4900,12 @@ p, li { white-space: pre-wrap; } Id anonima - + Circle name Nom del cercle - + Update Actualitza @@ -4646,7 +4931,7 @@ p, li { white-space: pre-wrap; } Id enllaç PGP - + Add Member Afegir Membre @@ -4790,7 +5075,7 @@ p, li { white-space: pre-wrap; } - + Attachments Adjunts @@ -4836,7 +5121,7 @@ p, li { white-space: pre-wrap; } Arrossegar i deixar arxius dels resultats de la cerca - + Paste RetroShare Links Enganxar enllaços RetroShare @@ -4846,7 +5131,7 @@ p, li { white-space: pre-wrap; } Enganxa l'enllaç RetroShare - + Drop file error. Error al deixar l'arxiu. @@ -4873,17 +5158,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Arxiu ja afegit i hash calculat + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Arxiu ja afegit i hash calculat + + + Please add a Subject Si us plau, afegeix un assumpte @@ -4914,12 +5223,12 @@ p, li { white-space: pre-wrap; } Segur que vols generar %1 missatges? - + You are about to add files you're not actually sharing. Do you still want this to happen? Estàs a punt d'afegir arxius que ara mateix no comparteixes. Segur que ho vols fer? - + Edit Channel Post Editar publicació al canal @@ -4939,7 +5248,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Apunt de publicar arxius no propis a un canal. @@ -5031,7 +5340,7 @@ p, li { white-space: pre-wrap; } - + No Forum Sense fòrum @@ -5490,7 +5799,7 @@ i utilitzar el botó d'importació per carregar-lo DHTGraphSource - + users usuaris @@ -6497,7 +6806,7 @@ i utilitzar el botó d'importació per carregar-lo FlatStyle_RDM - + Friends Directories Directoris dels amics @@ -7003,7 +7312,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Busca als amics - + Mark all Marcar tots/es @@ -7017,7 +7326,7 @@ com a mínim un dels contactes no s'ha afegit a un grup FriendsDialog - + Edit status message Editar missatge d'estat @@ -7121,7 +7430,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Xat de difusió del RetroShare: Els missatges són enviats a tots els amics connectats. - + Network Xarxa @@ -7186,7 +7495,7 @@ com a mínim un dels contactes no s'ha afegit a un grup El camp node és necessari amb un mínim de 3 caràcters - + Failed to generate your new certificate, maybe PGP password is wrong! Ha fallat la generació del teu nou certificat, potser la contrasenya PGP sigui incorrecta! @@ -7229,7 +7538,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Tornar a utilitzar un perfil existent - + Node name Nom del node @@ -7496,12 +7805,12 @@ i utilitzar el botó d'importació per carregar-lo - + Profile generation failure Generació de perfil fallat - + Missing PGP certificate Falta certificat PGP @@ -7920,7 +8229,7 @@ p, li { white-space: pre-wrap; } Estadístiques d'encaminador - + GroupBox Selecció de grup @@ -7985,7 +8294,7 @@ p, li { white-space: pre-wrap; } Factor de ramificació - + Details Detalls @@ -8008,7 +8317,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Claus administrades @@ -8218,7 +8527,7 @@ Nota: No es poden revocar els permisos d'administrador publicats GroupTreeWidget - + Title Títol @@ -8228,13 +8537,30 @@ Nota: No es poden revocar els permisos d'administrador publicatsCerca títol - - + + + + Description Descripció - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Descripció de cerca @@ -8244,42 +8570,35 @@ Nota: No es poden revocar els permisos d'administrador publicats - Sort Descending Order - Ordena en ordre descendent + Ordena en ordre descendent - Sort Ascending Order - Ordena en ordre ascendent + Ordena en ordre ascendent - Sort by Name - Ordena per nom + Ordena per nom - Sort by Popularity - Ordena per popularitat + Ordena per popularitat - Sort by Last Post - Ordena per darrer missatge + Ordena per darrer missatge - Sort by Number of Posts - Ordenar per nombre de publicacións + Ordenar per nombre de publicacións - Sort by Unread - Ordena per no llegit + Ordena per no llegit - + You are admin (modify names and description using Edit menu) Ets l'administrador (Modifica noms i descripció utilitzant el menú Editar) @@ -8294,40 +8613,35 @@ Nota: No es poden revocar els permisos d'administrador publicatsId - - + + Last Post Darrera publicació - + + Name Nom - - Unread - - - - + Popularity Popularitat - - + + Never Mai - Display - Mostra + Mostra - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8476,7 +8790,7 @@ Nota: No es poden revocar els permisos d'administrador publicats GxsChannelDialog - + Channels Canals @@ -8501,12 +8815,12 @@ Nota: No es poden revocar els permisos d'administrador publicats<h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Canals</h1> <p>Canals et permet publicar dades (Ex: pel·lícules, música) que es propagaran per la xarxa</p> <p>Pots veure els canals als que tens amics subscrits i tu faràs el mateix amb els teus. Això promociona els canals populars dins la xarxa.</p> <p>Només el creador del canal pot publicar en un canal. Els altres contactes a la xarxa només poden llegir el canal, a no ser que el canal sigui privat. No obstant, pots compartir els drets de publicació o lectura amb nodes de Retroshare amics.</p> <p>Els canals poden ser anònims o associats a una identitat de Retroshare per tal que els lectors puguin contactar amb tu si volen. Activa "Permetre comentaris" si vols permetre que els usuaris facin comentaris sobre el que publiques.</p><p>Les entrades publicades es mantenen durant %1 dies, i es sincronitzen pels últims %2 dies, a no ser que ho canviïs.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canals subscrits @@ -9031,7 +9345,7 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Add new post Afegir nova publicació @@ -9131,12 +9445,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Files Arxius - + Comments Comentaris @@ -9147,18 +9461,18 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Feeds Fonts - - + + Click to switch to list view - + Show unread posts only @@ -9168,12 +9482,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + No files in the channel, or no channel selected - + No text to display @@ -9233,7 +9547,7 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Download this file: @@ -9248,12 +9562,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Comments (%1) - + [No name] @@ -9329,23 +9643,36 @@ Nota: No es poden revocar els permisos d'administrador publicats + Copy Retroshare link + + + + Subscribed Subscrit - - Subscribe Subscriure's - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected No hi ha canal seleccionat @@ -9367,11 +9694,6 @@ Nota: No es poden revocar els permisos d'administrador publicatsChannel Post Entrada al canal - - - new message(s) - - GxsCircleItem @@ -9905,7 +10227,7 @@ abans de poder comentar Comença nova conversa al fòrum seleccionat - + Search forums Cercar fòrums @@ -9914,12 +10236,12 @@ abans de poder comentar Darrer missatge - + New Thread Nova conversa - + Threaded View Vista per conversa @@ -9929,19 +10251,19 @@ abans de poder comentar Vista plana - - + + Title Títol - - + + Date Data - + Author Autor @@ -9956,7 +10278,17 @@ abans de poder comentar Carregant - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10017,23 +10349,23 @@ abans de poder comentar <p>Subscriure's al fòrum buscarà les entrades publicades disponibles dels teus amics subscrits, i farà el fòrum visible a tots els teus altres amics.</p><p>Després podràs des-subscriure't des del menú contextual de la llista de fòrums a l'esquerra.</p> - + No name Sense nom - - + + Reply Resposta - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10071,12 +10403,12 @@ abans de poder comentar Marca com no llegit - + Copy RetroShare Link Copia l'enllaç RetroShare - + Hide Amagar @@ -10089,7 +10421,7 @@ abans de poder comentar [Expulsat] - + [unknown] [desconegut] @@ -10119,8 +10451,8 @@ abans de poder comentar Només per tu - - + + Distribution Distribució @@ -10223,7 +10555,7 @@ abans de poder comentar Missatge original - + New thread Nova conversa @@ -10232,7 +10564,7 @@ abans de poder comentar Estat de lectura - + Edit Editar @@ -10288,7 +10620,7 @@ abans de poder comentar Mostrar autor a la pestanya de gent - + Author's reputation Reputació de l'autor @@ -10308,7 +10640,7 @@ abans de poder comentar - + <b>Loading...<b> @@ -10348,6 +10680,11 @@ abans de poder comentar Storage Emmagatzematge + + + Last seen at friends: + + Moderators @@ -10438,7 +10775,7 @@ prevents the message to be forwarded to your friends. A %1, %2 va escriure: - + Forum name Nom del fòrum @@ -10470,11 +10807,6 @@ prevents the message to be forwarded to your friends. Forum Post Entrada al fòrum - - - new message(s) - - GxsForumsDialog @@ -10923,7 +11255,7 @@ prevents the message to be forwarded to your friends. PreviaImpressió - + Unsubscribe Donar de baixa @@ -10938,7 +11270,7 @@ prevents the message to be forwarded to your friends. Obrir en una pestanya nova - + Remove this search @@ -10948,12 +11280,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details Mostra detalls @@ -11020,7 +11352,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -11029,7 +11361,7 @@ prevents the message to be forwarded to your friends. Compartir permisos de publicació - + Copy RetroShare Link Copia l'enllaç RetroShare @@ -11044,7 +11376,7 @@ prevents the message to be forwarded to your friends. Marca tot com no llegit - + AUTHD AUTHD @@ -11661,7 +11993,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11670,7 +12002,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11696,6 +12028,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11707,7 +12056,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11789,27 +12138,32 @@ p, li { white-space: pre-wrap; } Formulari - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11831,6 +12185,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11839,7 +12194,7 @@ p, li { white-space: pre-wrap; } El text a sota és el teu certificat de Retroshare. Envia'l als teus amic - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11855,12 +12210,12 @@ private and secure decentralized communication platform. Necessites ajuda amb el RetroShare? - + Open Web Help Ajuda a la web oberta - + Copy your Cert to Clipboard Copiar el teu certificat al porta-retalls @@ -11909,7 +12264,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11918,7 +12273,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12211,14 +12566,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tot - + Reputation Reputació @@ -12228,12 +12583,12 @@ p, li { white-space: pre-wrap; } Cerca - + Anonymous Id Id anònim - + Create new Identity Crear nova identitat @@ -12377,7 +12732,7 @@ p, li { white-space: pre-wrap; } Id d'identitat - + Send message Enviar missatge @@ -12469,7 +12824,7 @@ p, li { white-space: pre-wrap; } Global: - + Anonymous Anònim @@ -12484,24 +12839,24 @@ p, li { white-space: pre-wrap; } ID cerca - + This identity is owned by you Aquesta identitat és propietat teva - - + + My own identities Les meves identitats - - + + My contacts Els meus contactes - + Show Items Mostrar elements @@ -12516,7 +12871,7 @@ p, li { white-space: pre-wrap; } Associat al meu node - + Other circles Altres cercles @@ -12575,13 +12930,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). Subscrit (Envia/reenvia peticions de pertinença d'altres i llista d'invitats) + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). No subscrit (Només rep la llista d'invitats). - + Your status: El teu estat: @@ -12641,7 +13001,7 @@ p, li { white-space: pre-wrap; } Membre - + Edit Circle Editar cercle @@ -12689,7 +13049,7 @@ p, li { white-space: pre-wrap; } Permet pertinença - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12701,12 +13061,12 @@ Aquestes identitats deixaran de ser suportades en breu. - + [Unknown node] [Node desconegut] - + Unverified signature from node Signatura no verificada del node @@ -12718,12 +13078,12 @@ Aquestes identitats deixaran de ser suportades en breu. Signatura no comprovada - + [unverified] [no verificat] - + Identity owned by you, linked to your Retroshare node Identitat propietat teva, enllaçat amb el teu node de RetroShare @@ -12847,12 +13207,12 @@ Aquestes identitats deixaran de ser suportades en breu. Estàs segur de voler enviar una invitació amb el teu certificat? - + Banned Expulsat - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identitats</h1><p>En aquesta pestanya pots crear/editar identitats <b>pseudo-anònimes</b> i <b>cercles</b>.</p><p>Les <b>Identitats</b> s'utilitzen per identificar les teves dades: signar missatges publicats a les sales de xat, fòrums i canals, rebre comentaris utilitzant el sistema intern de correu electrònic o publicar-ne a entrades dels canals, xatejar utilitzant túnels segurs, etc.</p> <p>Les identitats poden estar <b>signades</b> pel certificat del seu node de Rertoshare. És més fàcil confiar en identitats signades però es poden seguir fàcilment fins a la IP del node al que pertanyen.</p> <p>Les <b>identitats anònimes</b> et permetran interactuar amb altres usuaris de forma anònima. No es poden falsificar, però ningú pot provar qui té en realitat una determinada identitat.</p> <p>Els <b>cercles</b> són grups d'identitats (anònimes o signades) que són compartides a certa distancia, salts entre nodes, per la xarxa. Es poden utilitzar per restringir la visibilitat de fòrums, canals, etc. </p> <p>Un <b>cercle</b> pot estar restringit a un altre cercle, limitant la visibilitat als membres d'aquest cercle o inclús es pot auto-restringir, que vol dir que només es visible a membres invitats.</p> @@ -12861,7 +13221,7 @@ Aquestes identitats deixaran de ser suportades en breu. ID desconegut: - + positive positiu @@ -13046,8 +13406,8 @@ Aquestes identitats deixaran de ser suportades en breu. - - + + People Gent @@ -13058,7 +13418,7 @@ Aquestes identitats deixaran de ser suportades en breu. El teu avatar - + Linked to neighbor nodes Associat a nodes veïns @@ -13068,7 +13428,7 @@ Aquestes identitats deixaran de ser suportades en breu. Associat a nodes distants - + Linked to a friend Retroshare node Associat a un node de RetroShare d'un amic @@ -13128,7 +13488,7 @@ Aquestes identitats deixaran de ser suportades en breu. Propietat de - + Node name: Nom del node: @@ -13138,7 +13498,7 @@ Aquestes identitats deixaran de ser suportades en breu. ID node : - + Really delete? Segur que vols esborrar? @@ -13176,7 +13536,22 @@ Aquestes identitats deixaran de ser suportades en breu. Pseudònim - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nova identitat @@ -13193,14 +13568,14 @@ Aquestes identitats deixaran de ser suportades en breu. - + N/A N/A - + Edit identity Editar identitat @@ -13211,24 +13586,27 @@ Aquestes identitats deixaran de ser suportades en breu. Actualitza - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13247,17 +13625,27 @@ Aquestes identitats deixaran de ser suportades en breu. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Error obtenint clau! - + Error KeyID invalid Error de IDClau invàlida - + Unknown GpgId IdGPG desconegut @@ -13267,7 +13655,7 @@ Aquestes identitats deixaran de ser suportades en breu. Nom real desconegut - + Create New Identity Crear nova identitat @@ -13277,7 +13665,12 @@ Aquestes identitats deixaran de ser suportades en breu. Tipus - + + Choose image... + + + + @@ -13317,12 +13710,11 @@ Aquestes identitats deixaran de ser suportades en breu. El teu avatar - Set Avatar - Escull avatar + Escull avatar - + Linked to your profile Associat al teu perfil @@ -13332,7 +13724,7 @@ Aquestes identitats deixaran de ser suportades en breu. Pots tindre una o més identitats. S'utilitzen quan escrius en sales de xat, fòrums i comentes en canals. Funcionen també com a destinataris en xats distants i en el sistema de correu distant de RetroShare. - + The nickname is too short. Please input at least %1 characters. El sobrenom és massa curt. Si us plau, introdueix com a mínim %1 caràcters. @@ -13441,8 +13833,12 @@ Aquestes identitats deixaran de ser suportades en breu. + Quote + Cita + + Send - Enviar + Enviar @@ -13600,7 +13996,7 @@ Aquestes identitats deixaran de ser suportades en breu. - + Options Opcions @@ -13632,12 +14028,12 @@ Aquestes identitats deixaran de ser suportades en breu. Auxiliar d'inici ràpid - + RetroShare %1 a secure decentralized communication platform RetroShare %1 és una plataforma de comunicació segura descentralitzada - + Unfinished Inacabat @@ -13768,7 +14164,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Mostra - + Make sure this link has not been forged to drag you to a malicious website. Assegura't de que aquest enllaç no ha estat modificat per portar-te a un lloc web malicios. @@ -13813,7 +14209,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Taula de permisos dels serveis - + Statistics Estadístiques @@ -13842,7 +14238,7 @@ Si us plau, allibera una mica d'espai i clica Ok. MessageComposer - + Compose Redacta @@ -13944,7 +14340,7 @@ Si us plau, allibera una mica d'espai i clica Ok. - + Tags Etiquetes @@ -14039,12 +14435,12 @@ Si us plau, allibera una mica d'espai i clica Ok. Afegir citació - + Send To: Enviar a: - + &Left &Esquerra @@ -14078,7 +14474,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Els meus contactes - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hola,<br>Et recomano un bon amic meu; pots confiar en ell si confies en mi. <br> @@ -14104,12 +14500,12 @@ Si us plau, allibera una mica d'espai i clica Ok. - + Save Message Desar el missatge - + Message has not been Sent. Do you want to save message to draft box? El missatge no s'ha enviat. @@ -14121,7 +14517,7 @@ Vols desar el missatge a la bústia d'esborranys? Enganxa l'enllaç RetroShare - + Add to "To" Afegir a "A" @@ -14376,7 +14772,7 @@ Voleu desar el missatge? Afegir arxiu extra - + Hi,<br>I want to be friends with you on RetroShare.<br> Hola,<br> vull ser amic amb tu en el RetroShare.<br> @@ -14385,12 +14781,27 @@ Voleu desar el missatge? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Tens una petició d'amistat - + Respond now: Respondre ara: @@ -14406,11 +14817,12 @@ Voleu desar el missatge? De: + Friend Nodes - Nodes de l'amic + Nodes de l'amic - + Bullet list (disc) Llista amb símbol (disc) @@ -14450,13 +14862,13 @@ Voleu desar el missatge? Llista ordenada (romanic ascendent) - - + + Thanks, <br> Gràcies, <br> - + Distant identity: Identitat distant: @@ -14595,8 +15007,23 @@ Voleu desar el missatge? Missatge - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14608,12 +15035,12 @@ Voleu desar el missatge? Arxius recomanats - + Download all Recommended Files Descarregar tots els arxius recomanats - + Subject: Assumpte: @@ -14688,12 +15115,18 @@ Voleu desar el missatge? Envia invitació - + + Message Size: + + + + File Name Nom d'arxiu - + + Size Mida @@ -14754,10 +15187,25 @@ Voleu desar el missatge? Descarregar - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Enviar invitació? @@ -14768,12 +15216,12 @@ Voleu desar el missatge? - + Download all Descarregar tot - + Print Document Imprimir document @@ -14788,7 +15236,7 @@ Voleu desar el missatge? Arxius-HTML (*.htm *.html);;Tots els arxius (*) - + Load images always for this message Carregar sempre les imatges per aquest missatge @@ -14929,7 +15377,7 @@ Voleu desar el missatge? MessagesDialog - + New Message Missatge nou @@ -14985,14 +15433,14 @@ Voleu desar el missatge? - + Tags Etiquetes - + Inbox Safata d'entrada @@ -15087,7 +15535,7 @@ Voleu desar el missatge? Reenviar missatge - + Subject Assumpte @@ -15199,7 +15647,7 @@ Voleu desar el missatge? - + Open in a new window Obrir en una finestra nova @@ -15284,7 +15732,7 @@ Voleu desar el missatge? - + Drafts Esborranys @@ -15413,7 +15861,7 @@ Voleu desar el missatge? Respondre missatge - + Delete Message Esborrar missatge @@ -15424,7 +15872,7 @@ Voleu desar el missatge? - + Expand Ampliar @@ -15434,7 +15882,7 @@ Voleu desar el missatge? Eliminar l'element - + from des de @@ -15443,6 +15891,11 @@ Voleu desar el missatge? Reply to invite Respondre a la invitació + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15764,7 +16217,7 @@ Error reportat: - + Groups Grups @@ -15794,19 +16247,19 @@ Error reportat: importar la teva llista d'amics, incloent els grups - - + + Search - + ID ID - + Search ID ID cerca @@ -15816,7 +16269,7 @@ Error reportat: - + Show Items Mostrar elements @@ -16020,19 +16473,19 @@ com a mínim un dels contactes no s'ha afegit a un grup - + Error Error - + File is not writeable! L'arxiu no es pot escriure! - + File is not readable! L'arxiu no es pot llegir! @@ -16070,9 +16523,13 @@ com a mínim un dels contactes no s'ha afegit a un grup NewsFeed - Log entries - Entrades en el registre + Entrades en el registre + + + + Activity Stream + @@ -16089,7 +16546,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Això és un test. - + Newest on top El més nou a dalt @@ -16100,21 +16557,44 @@ com a mínim un dels contactes no s'ha afegit a un grup + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Novetats</h1> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Novetats</h1> <p>La font de noticies mostra els últims esdeveniments a la xarxa ordenats per hora de recepció. Això et proporciona un resum de l'activitat dels teus amics. Pots triar quins esdeveniments es mostren a <b>Opcions</b>. </p> <p>Els esdeveniments mostrats són: <ul> <li>Intents de connexió (útil per fer amics amb gent nova i controlar qui està intentant connectar-te)</li> <li>Publicacions a canals i fòrums</li> <li>Nous canals i fòrums als que et pots subscriure</li> <li>Missatges privats dels teus amics</li> </ul> </p> - Log - Registre + Registre + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16151,22 +16631,22 @@ com a mínim un dels contactes no s'ha afegit a un grup - + Test Test - + Chat Room Sala de xat - + Systray Icon Icona de l'àrea de notificació - + Message Missatge @@ -16191,12 +16671,11 @@ com a mínim un dels contactes no s'ha afegit a un grup Seguretat Ip - Log - Registre + Registre - + Friend Connected Amic connectat @@ -16210,7 +16689,12 @@ com a mínim un dels contactes no s'ha afegit a un grup Enllaços - + + Activity + + + + Mails Correus @@ -16247,7 +16731,12 @@ com a mínim un dels contactes no s'ha afegit a un grup Xat en grup - + + Toaster position + + + + Chat rooms Sales de xat @@ -16272,22 +16761,22 @@ com a mínim un dels contactes no s'ha afegit a un grup Diferenciar majúscules/minúscules - + Position Posició - + X Margin Marge X - + Y Margin Marge Y - + Systray message Missatge de l'area de notificació @@ -16338,7 +16827,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Notificar - + Disable All Toasters Deshabilitar totes les notificacions @@ -16352,7 +16841,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Font - + Systray Àrea de notificació @@ -16498,17 +16987,16 @@ Tràfic baix: 10 %s del tràfic estàndard i PENDENT: posar en pausa totes les t PGPKeyDialog - Dialog - Diàleg + Diàleg - + Profile info Informació del perfil - + Name : Nom : @@ -16563,22 +17051,21 @@ Tràfic baix: 10 %s del tràfic estàndard i PENDENT: posar en pausa totes les t Definitiu - + This profile has signed your own profile key Aquest perfil ha signat la clau del teu perfil - Key signatures : - Signatures de la clau : + Signatures de la clau : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Les signatures a sota testimonien criptogràficament que els propietaris de les claus llistades reconeixen la clau PGP com autèntica. </span></p></body></html> - + <!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; } @@ -16596,7 +17083,7 @@ p, li { white-space: pre-wrap; } Signa aquesta clau - + PGP key Clau PGP @@ -16606,22 +17093,20 @@ p, li { white-space: pre-wrap; } Aquestes opcions s'apliquen a tots els nodes del perfil: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Els ajudarà a decidir si volen acceptar o no connexions d'aquesta clau basant-se en la teva confiança. Signar una clau és completament opcional i no es pot desfer, fes-ho amb cura.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Els ajudarà a decidir si volen acceptar o no connexions d'aquesta clau basant-se en la teva confiança. Signar una clau és completament opcional i no es pot desfer, fes-ho amb cura.</span></p></body></html> - + Keysigning: - Sign PGP key - Signa clau PGP + Signa clau PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Fes clic aquí si vols rebutjar les connexions a nodes autenticats per aquesta clau.</p></body></html> @@ -16641,7 +17126,7 @@ p, li { white-space: pre-wrap; } Acceptar connexions - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. A sota teniu la clau del perfil del node en format PGP ASCII. Identifica tots els nodes del mateix perfil. Un "certificat de Retroshare" que pots intercanviar per fer amics, és a "detalls" de cada node. @@ -16711,28 +17196,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: no es poden obtenir detalls del contacte. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algorisme de la clau proporcionada no és suportada pel RetroShare (Només suporta claus RSA per ara) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16746,7 +17231,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. El nivell de confiança és una forma d'expressar la teva confiança en aquesta clau. No s'utilitza pel programa ni es comparteix, però et pot ser útil per recordar claus bones/dolentes. @@ -16791,27 +17276,47 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir No estàs permetent connexions de nodes de Retroshare signats amb aquesta clau. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Fracàs en la signatura - - Maybe password is wrong - Potser la contrasenya sigui incorrecta + + Check the password! + - + Maybe password is wrong + Potser la contrasenya sigui incorrecta + + + You haven't set a trust level for this key. No has establert un nivell de confiança per aquesta clau. - + + Retroshare profile Perfil de Retroshare - + This is your own PGP key, and it is signed by : Aquesta és la teva clau PGP i està signada per : @@ -16990,8 +17495,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir PeopleDialog - - + People Gent @@ -17008,7 +17512,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Interna - + Chat with this person Xat amb aquesta persona @@ -17159,7 +17663,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Foto - + TextLabel EtiquetaTexte @@ -17203,8 +17707,8 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir - <N> Comments >> - + Comments + Comentaris @@ -17239,6 +17743,11 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Write a comment... Escriure un comentari... + + + Album + Àlbum + PhotoItem @@ -17248,12 +17757,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Formulari - + TextLabel EtiquetaTexte - + <!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; } @@ -17349,7 +17858,7 @@ p, li { white-space: pre-wrap; } Veure foto - + PhotoShare PhotoShare @@ -17390,7 +17899,7 @@ abans de demanar editar-lo! - + Stop Atura @@ -17618,12 +18127,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autoritzar tots els complements - + Plugin look-up directories Directoris on buscar complements @@ -17683,7 +18192,7 @@ modificats. <h1><img width="24" src=":/images/help_64.png">&nbsp;&nbsp;Complements</h1> <p>Els complements es carreguen dels directoris del llistat inferior.</p> <p> Per raons de seguretat, els complements acceptats es carreguen automàticament mentre l'executable principal del Retroshare o els complements no canviïn. En tal cas, l'usuari haurà de confirmar-ho altre cop. Un cop el programa s'ha iniciat, pots habilitar un complement manualment fent clic al botó "Activa" i després reiniciant el Retroshare.</p> <p>Si vols desenvolupar els teus propis complements contacta amb els desenvolupadors i estaran contents d'ajudar-te!</p> - + Plugins Complements @@ -18081,7 +18590,7 @@ modificats. Enllaços - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18252,13 +18761,13 @@ modificats. Lloc - - + + Comments Comentaris - + Copy RetroShare Link Copia l'enllaç RetroShare @@ -18268,7 +18777,7 @@ modificats. Mostrar autor a la pestanya de gent - + Comment Comentari @@ -18289,12 +18798,12 @@ modificats. - + Hide Amagar - + Vote up Votar positiu @@ -18308,7 +18817,7 @@ modificats. \/ - + Set as read and remove item Marcar com llegit i eliminar l'element @@ -18369,7 +18878,7 @@ modificats. - + Loading Carregant @@ -18459,13 +18968,7 @@ modificats. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18475,60 +18978,50 @@ modificats. Administrador: - - - + + + unknown desconegut - + Distribution: Distribució: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Publicacions @@ -18539,7 +19032,7 @@ modificats. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18608,7 +19101,12 @@ modificats. - + + Empty + Buit + + + Copy RetroShare Link Copia l'enllaç RetroShare @@ -18643,7 +19141,7 @@ modificats. - + [No name] @@ -18771,8 +19269,18 @@ modificats. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19051,9 +19559,8 @@ i utilitzar el botó d'importació per carregar-lo PulseAddDialog - Post From: - Entrada de: + Entrada de: Account 1 @@ -19068,7 +19575,7 @@ i utilitzar el botó d'importació per carregar-lo Compte 3 - + Add to Pulse Afegir al Pols @@ -19091,17 +19598,32 @@ i utilitzar el botó d'importació per carregar-lo URL - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19126,10 +19648,20 @@ i utilitzar el botó d'importació per carregar-lo Negatiu - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19139,14 +19671,53 @@ i utilitzar el botó d'importació per carregar-lo - + + Post + + + + Cancel Cancel·la - Post Pulse to Wire - Publica Pols a Wire + Publica Pols a Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19172,10 +19743,18 @@ i utilitzar el botó d'importació per carregar-lo Formulari - - - - + + + + + Click to view picture + + + + + + + Image Imatge @@ -19183,44 +19762,44 @@ i utilitzar el botó d'importació per carregar-lo PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19230,17 +19809,17 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19250,7 +19829,7 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19258,7 +19837,7 @@ i utilitzar el botó d'importació per carregar-lo PulseTopLevel - + retweeted @@ -19273,7 +19852,7 @@ i utilitzar el botó d'importació per carregar-lo - + follow Parent Group @@ -19283,7 +19862,7 @@ i utilitzar el botó d'importació per carregar-lo ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19308,7 +19887,7 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19344,29 +19923,29 @@ i utilitzar el botó d'importació per carregar-lo - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19444,7 +20023,7 @@ i utilitzar el botó d'importació per carregar-lo QObject - + Confirmation Confirmació @@ -19686,7 +20265,7 @@ Els caràcters <b>",|,/,\,&lt;&gt;,*,?</b> es substitui Resultat - + Unable to make path Incapaç de crear ruta @@ -19721,7 +20300,7 @@ Els caràcters <b>",|,/,\,&lt;&gt;,*,?</b> es substitui Petició d'arxiu cancel·lada - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Aquesta versió de RetroShare utilitza l'OpenPGP-SDK. Com a efecte secundari no utilitza el clauer PGP del sistema, sinó un clauer compartit per totes les instancies de RetroShare. <br><br>No sembla que tinguis aquest clauer, tot i que tens claus PGP als comptes existents de RetroShare, probablement perquè acabes de canviar a aquesta nova versió del programa. @@ -19876,7 +20455,7 @@ L'error reportat és: seg - + TR up TR pujats @@ -19921,7 +20500,7 @@ L'error reportat és: desactivat - + Move IP %1 to whitelist Mou la IP %1 a la llista blanca @@ -19937,7 +20516,7 @@ L'error reportat és: - + %1 seconds ago fa %1 segons @@ -20022,7 +20601,7 @@ Seguretat: IDs anònimes no - + Error Error @@ -20413,9 +20992,8 @@ Seguretat: IDs anònimes no Clica per continuar amb el càlcul de hash - <p>This certificate contains: - <p>Aquest certificat conté: + <p>Aquest certificat conté: @@ -20789,7 +21367,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 kB @@ -21011,19 +21589,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Opcions de la vista d'arbre - Show column... - Mostrar columna... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Ordena en ordre descendent + + + + Sort Ascending Order + Ordena en ordre ascendent + + + + + [no title] + + + + + Show column … + + + + Show column... + Mostrar columna... - [no title] - [sense títol] + [sense títol] @@ -21459,7 +22066,7 @@ p, li { white-space: pre-wrap; } Descarrega! - + File Arxiu @@ -21474,7 +22081,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned S'han netejat noms d'arxiu no permesos @@ -21524,7 +22131,7 @@ Els arxius afectats es llisten en vermell. Desa - + Collection Editor Editor de col·lecció @@ -21539,7 +22146,7 @@ Els arxius afectats es llisten en vermell. Comptador d'arxius - + Real Size: Waiting child... Mida real: Esperant pels fills... @@ -21554,12 +22161,12 @@ Els arxius afectats es llisten en vermell. Això és un directori. Doble clic per desplegar-lo. - + Download files Descarregar arxius - + Specify... Especificar... @@ -21808,7 +22415,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a RsFriendListModel - + Name Nom @@ -21828,7 +22435,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a IP - + Profile ID @@ -21841,10 +22448,15 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a RsGxsForumModel - + Title Títol + + + UnRead + + Date @@ -21856,7 +22468,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a Autor - + Information for this identity is currently missing. No hi ha informació per aquesta identitat @@ -21894,7 +22506,7 @@ prevents the message to be forwarded to your friends. [Desconegut] - + [ ... Missing Message ... ] [ ... Missatge perdut ... ] @@ -21902,7 +22514,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -21962,7 +22574,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22321,7 +22933,7 @@ prevents the message to be forwarded to your friends. Nom d'arxiu - + Download Descarregar @@ -22400,7 +23012,7 @@ prevents the message to be forwarded to your friends. Obrir directori - + Create Collection... Crear col·lecció... @@ -22420,7 +23032,7 @@ prevents the message to be forwarded to your friends. Descarregar d'arxiu de col·lecció... - + Collection Col·lecció @@ -22525,12 +23137,12 @@ prevents the message to be forwarded to your friends. Detalls del contacte - + Deny friend Negar l'amic - + Chat Xat @@ -22540,7 +23152,7 @@ prevents the message to be forwarded to your friends. Inicia xat - + Expand Ampliar @@ -22810,13 +23422,13 @@ d'un tallafocs o una VPN. Descobriment activat (Recomanat) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. S'ha configurat Tor automàticament per part de Retroshare. No hauria de fer falta que canviessis res aquí. - + Discovery Off Descobriment desactivat @@ -23311,7 +23923,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< <p>En qualsevol cas, un node de Retroshare funcionant com a repetidor no pot veure el tràfic que repeteix, ja que està encriptat i autenticat pels dos nodes interessats.</p> - + Network Xarxa @@ -23339,7 +23951,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< - + Status Estat @@ -23436,7 +24048,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< - + Service Address Adreça del servei @@ -23471,12 +24083,12 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< Si us plau, escriu una adreça de servei - + IP Range Rang IP - + Reported by DHT for IP masquerading Anunciat per DHT per enmascarament IP @@ -24156,7 +24768,7 @@ p, li { white-space: pre-wrap; } Falta certificat PGP - + Wrong password Contrasenya incorrecta @@ -24210,7 +24822,7 @@ Això es pot canviar a les opcions de configuració. StatisticsWindow - + Add Friend Afegeix amic @@ -24266,7 +24878,7 @@ Això es pot canviar a les opcions de configuració. Taula de permisos dels serveis - + DHT DHT @@ -24806,7 +25418,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24820,13 +25432,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor és fora de línia - + Tor is OK Tor està OK @@ -24835,6 +25446,31 @@ p, li { white-space: pre-wrap; } No tor configuration Sense configuració Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25130,35 +25766,46 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - You have %1 completed downloads - Tens %1 descarregues completes + You have %1 completed transfers + - You have %1 completed download - Tens %1 descarrega completa + You have %1 completed transfer + - %1 completed downloads - %1 descarregues completades + %1 completed transfers + - %1 completed download - %1 descarrega completada + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Tens %1 descarregues completes + + + You have %1 completed download + Tens %1 descarrega completa + + + %1 completed downloads + %1 descarregues completades + + + %1 completed download + %1 descarrega completada TransfersDialog - + Downloads Descarregues @@ -25169,7 +25816,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Pujades - + Name i.e: file name Nom @@ -25380,7 +26027,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú <h1><img width="32" src=":/images/help_64.png">&nbsp;&nbsp;Transferència d'arxiu</h1> <p>Retroshare contempla dues formes de fer això: transferències directes dels teus amics, i transferències distants amb túnels anònims. A més amés, les transferències d'arxius són multi-origen i permet fer-les en eixam (pots ser origen mentre descarregues)</p> <p>Pots compartir arxius amb <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> la icona de la barra lateral esquerra. Aquests arxius es llistaran a la pestanya els meus arxius. Pots triar per cada grup d'amics si poden o no veure'l a la pestanya arxius d'amics.</p> <p>La pestanya cerca dona resultats pels arxius del teus amics i arxius que es poden accedir distants anònimament utilitzant el sistema de túnels multi-salt.</p> - + Move in Queue... Moure a la cua... @@ -25474,7 +26121,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Si us plau, introdueix un nou--i vàlid--nom d'arxiu - + Expand all Expandeix tot @@ -25606,7 +26253,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Columns Columnes @@ -25617,7 +26264,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Transferències d'arxius - + Path Ruta @@ -25627,7 +26274,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Mostra columna de ruta - + Could not delete preview file No s'ha pogut esborrar l'arxiu de previsualització @@ -25637,7 +26284,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Tornar-ho a intentar? - + Create Collection... Crear col·lecció... @@ -25652,7 +26299,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Veure col·lecció... - + Collection Col·lecció @@ -25898,7 +26545,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Unknown Peer Contacte desconegut @@ -25994,7 +26641,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú UserNotify - + You have %1 new messages Tens %1 nous missatges @@ -26378,7 +27025,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Crear grup - + Subscribe to Group Subscriure's al grup @@ -26472,8 +27119,8 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - - + + Show Edit History Mostra historial d'edició @@ -26484,7 +27131,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Preview Visualització prèvia @@ -26509,12 +27156,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Amagar l'historial d'edició - + Edit Page Editar pàgina - + Create New Wiki Page Crear nova pàgina wiki @@ -26534,7 +27181,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú WikiGroupDialog - + Create New Wiki Group Crear nou grup wiki @@ -26576,7 +27223,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Rang de temps - + Create Account @@ -26586,12 +27233,11 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - ... - ... + ... - + Refresh Refrescar @@ -26626,12 +27272,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + > - + Most Recent @@ -26701,7 +27347,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Mostrant: - + Yourself Tu mateix @@ -26739,7 +27385,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Publica Pols a Wire - + RetroShare RetroShare @@ -26751,7 +27397,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + The Wire The Wire @@ -26759,7 +27405,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú WireGroupDialog - + Create New Wire @@ -26840,8 +27486,8 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Formulari - - + + Avatar Avatar @@ -26870,6 +27516,11 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Sub/Un + + + Edit Profile + + misc @@ -26982,8 +27633,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Imatges (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Imatges (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_cs.ts b/retroshare-gui/src/lang/retroshare_cs.ts index 00397da2c..24f243cde 100644 --- a/retroshare-gui/src/lang/retroshare_cs.ts +++ b/retroshare-gui/src/lang/retroshare_cs.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: rozšířené hledání - + Search Criteria Kritéria pro vyhledávání - + Add a further search criterion. PÅ™idat další kriterium pro vyhledávání @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulář - - + + TextLabel Textový popisek @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Pozice ovládacích prvků - + Icon Only Pouze ikony @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Zvol styl ovládacích prvků - + Icon Size = 8x8 Ikona 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Velikost ikony = 128x128 - + Status Bar Stavový řádek @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Deaktivovat upozornÄ›ní v systémové liÅ¡tÄ› - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Ikona 32x32 @@ -828,14 +828,23 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo ZmÄ›nit fotku - + + TextLabel + Textový popisek + + + Your Avatar Picture Tvá fotka - + + Browse... + + + Add Avatar - PÅ™idat fotku + PÅ™idat fotku @@ -843,25 +852,34 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo Odebrat - + Set your Avatar picture Zobrazit fotku - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - NaÄíst fotku + NaÄíst fotku AvatarWidget - - Choose avatar - - - - + Click to change your avatar KliknÄ›te pro zmÄ›nu svého avatara @@ -869,7 +887,7 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo RetroShare Bandwidth Usage Využití pÅ™enosové rychlosti + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Zobrazit nastavení + TextLabel + Textový popisek + + + Reset Reset - Receive Rate - Rychlost stahování + Rychlost stahování - Send Rate - Rychlost odesílání + Rychlost odesílání - + Always on Top Podržet nad ostatními - Style - Styl + Styl - + Changes the transparency of the Bandwidth Graph ZmÄ›ní průhlednost grafu rychlosti pÅ™ipojení - + 100 100 @@ -936,30 +975,27 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo % Opaque - Save - Uložit + Uložit - Cancel - ZruÅ¡it + ZruÅ¡it - + Since: Od: - Hide Settings - Skrýt nastavení + Skrýt nastavení BandwidthStatsWidget - + Sum Suma @@ -981,7 +1017,7 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo PoÄet - + Average PrůmÄ›r @@ -1115,7 +1151,7 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo Textový popisek - + Comments Komentáře @@ -1193,6 +1229,85 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo Textový popisek + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + OznaÄit zprávu za pÅ™eÄtenou + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopírovat RetroShare odkaz + + + + + Expand + Rozbalit + + + + Set as read and remove item + OznaÄit za pÅ™eÄtené a odstranit položku + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + Komentáře + + + + Comments + + + + + Hide + Skrýt + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Ale mÄ›j na pamÄ›ti, že veÅ¡kerá zdejší nastavení se mohou zmÄ›nit s každo Log scale Logaritmické měřítko + + + Default + Výchozí + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + OznaÄit zprávu za pÅ™eÄtenou + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopírovat RetroShare odkaz + + + + + Expand + Rozbalit + + + + Set as read and remove item + OznaÄit za pÅ™eÄtené a odstranit položku + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + Komentáře + + + + Comments + + + + + Hide + Skrýt + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to - You have %1 new messages - Máte %1 nových zpráv + Máte %1 nových zpráv + + + You have %1 new message + Máte %1 novou zprávu + + + %1 new messages + %1 nových zpráv + + + %1 new message + %1 nová zpráva + + + + You have %1 mentions + - You have %1 new message - Máte %1 novou zprávu + You have %1 mention + - %1 new messages - %1 nových zpráv + %1 mentions + - %1 new message - %1 nová zpráva + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Smazat vÅ¡e - - - mention(s) - - ChatLobbyWidget @@ -2114,13 +2329,11 @@ Double click a chat room to enter and chat. - Group chat - Skupinový chat + Skupinový chat - - + Private chat Soukromý chat @@ -2185,17 +2398,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Zde se nastavuje uchovávání historie na vaÅ¡em HDD pro různé druhy chatu. Zprávy staršího data budou smazány, aby nedoÅ¡lo k pÅ™esycení sítÄ› (napÅ™. pro konverzaÄní místnosti a vzdálený chat).</p></body></html> - Chatlobbies - KonverzaÄní místnosti + KonverzaÄní místnosti - + Enabled: Aktivováno: @@ -2216,11 +2428,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2281,11 +2494,17 @@ Double click a chat room to enter and chat. + Broadcast Rozhlas - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Uložené zprávy (0 = bez omezení) @@ -2432,8 +2651,23 @@ Double click a chat room to enter and chat. Soukromá konverzace - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2602,7 +2836,7 @@ Double click a chat room to enter and chat. - + is typing... píše... @@ -2619,12 +2853,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Chcete opravdu vymazati historii z poÄítaÄe? @@ -2696,7 +2930,7 @@ after HTML conversion. Nezastavovat vybarvování po X nálezech (vyšší zátěž CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Hledat pÅ™edchozí </b><br/><i>Ctrl+Shift+G</i> @@ -2736,12 +2970,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>OznaÄ vybraný text</b><br><i>Ctrl+M</i> - + Person id: @@ -2757,7 +2991,7 @@ Double click on it to add his name on text writer. - + items found. Nalezeno. @@ -2777,7 +3011,7 @@ Double click on it to add his name on text writer. Zde napiÅ¡ zprávu... - + Don't stop to color after Nezastavovat vybarvování po @@ -2935,12 +3169,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaily - + Local Address Lokální adresa @@ -2951,12 +3185,12 @@ Double click on it to add his name on text writer. Externí adresa - + Node info: - + Current address: @@ -2972,31 +3206,36 @@ Double click on it to add his name on text writer. Port - + Include signatures Zahrnout podpisy - + RetroShare RetroShare - + - + Error : cannot get peer details. Chyba : nemohu získat údaje kontaktu - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3012,22 +3251,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Å ifrování - + Not connected Nespojen - + Retroshare node details Detaily o uzlu - + Node name : Jméno uzlu : @@ -3062,13 +3306,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Certifikát @@ -3083,7 +3332,7 @@ Double click on it to add his name on text writer. - + Hidden Address Skrytá adresa @@ -3094,11 +3343,12 @@ Double click on it to add his name on text writer. žádný + <p>This certificate contains: - <p>Tento certifikát obsahuje + <p>Tento certifikát obsahuje - + <li>a <b>node ID</b> and <b>name</b> <li>a <b>ID uzlu</b> a <b>jméno</b> @@ -3111,12 +3361,12 @@ Double click on it to add his name on text writer. an <b>IP adresa</b> a <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Tento certifikát musíš pÅ™edat svým budoucím kontaktům. Použij emailu nebo jiné komunikaÄní platformy.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Toto je ID<span style=" font-weight:600;">OpenSSL</span> certifikátu uzlu, který podepsán výše uvedeným <span style=" font-weight:600;">PGP</span> klíÄem. </p></body></html> @@ -3126,7 +3376,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Å ifrovcí metoda použitá <span style=" font-weight:600;">OpenSSL</span>. Spojení s kontakty</p><p>je vždy silnÄ› Å¡ifrováno a pokud je použito DHE, spojení navíc využívá</p><p>&quot;zabezpeÄené pÅ™eposílání&quot;.</p></body></html> - + with s @@ -3318,12 +3568,12 @@ Double click on it to add his name on text writer. Podrobnosti požadavku - + Peer details Podrobnosti o kontaktu - + Name: Jméno: @@ -3336,22 +3586,22 @@ Double click on it to add his name on text writer. Uzel: - + Location: UmístÄ›ní: - + Options Možnosti - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: PÅ™idat do skupiny: @@ -3361,7 +3611,7 @@ Double click on it to add his name on text writer. Autentizovat kontakt (podepsat PGP klíÄ), potvrzuje vaÅ¡i plnou důvÄ›ru,nelze vzít zpÄ›t! - + Please paste below your friend's Retroshare ID @@ -3386,7 +3636,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with PÅ™idat jako kontakt pro přímé spojení @@ -3395,7 +3645,7 @@ Double click on it to add his name on text writer. Klikni na "Finish" pro pÅ™idání kontaktu - + Sorry, some error appeared Je to smutné, ale doÅ¡lo k nÄ›jaké chybÄ› @@ -3415,32 +3665,32 @@ Double click on it to add his name on text writer. Detaily vaÅ¡eho kontaktu: - + Key validity: Validita klíÄe: - + Profile ID: - + Signers Podepsali - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Tento protÄ›jÅ¡ek se již nachází ve vaÅ¡em seznamu kontaktů. Jeho opÄ›tovné pÅ™idání může nanejvýš nastavit jeho novou IP adresu. - + To accept the Friend Request, click the Accept button. @@ -3486,7 +3736,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed NaÄítání certifikátu selhalo @@ -3519,12 +3769,12 @@ Double click on it to add his name on text writer. ID protÄ›jÅ¡ku - + Not a valid Retroshare certificate! - + RetroShare Invitation Pozvánka do RetroShare - sociální P2P sítÄ› zaměřené pÅ™edevším na sdílení souborů. @@ -3544,12 +3794,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3597,7 +3847,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Žádost o pÅ™idání do kontaktu od: - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3693,12 +3973,12 @@ RetroShare neaspiruje na to být nejlepší sociální sítí, má své mouchy a Stahovat přímo od pokud možno - + IP-Addr: - + IP-Address @@ -3756,7 +4036,7 @@ RetroShare neaspiruje na to být nejlepší sociální sítí, má své mouchy a PÅ™idat klÃ­Ä do klíÄenky - + This key is already in your keyring Tento klÃ­Ä je již v klíÄence @@ -3817,12 +4097,12 @@ které nemáte přímo v kontaktech. <p>V certifikátu není IP adresa. Discovery a DHT se ji pokusí najít. Po jejím nalezení se v Událostech objeví bezpeÄnostní upozornÄ›ní, pomocí kterého můžete tuto adresu pÅ™idat do whitelist pro úspěšné spojení.</p> - + [Unknown] - + Added with certificate from %1 PÅ™idán s certifikátem od %1 @@ -3909,7 +4189,12 @@ které nemáte přímo v kontaktech. UDP výsledek - + + Status + Status + + + <!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; } @@ -4331,7 +4616,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4479,7 +4764,7 @@ p, li { white-space: pre-wrap; } Nevybrány žádné limity Kruhu - + [Unknown] @@ -4494,7 +4779,7 @@ p, li { white-space: pre-wrap; } Odstranit - + Search Hledat @@ -4514,7 +4799,7 @@ p, li { white-space: pre-wrap; } Podepsáno známými uzly - + Edit Circle Upravit Kruh @@ -4534,12 +4819,12 @@ p, li { white-space: pre-wrap; } Anonymní ID - + Circle name - + Update @@ -4565,7 +4850,7 @@ p, li { white-space: pre-wrap; } PGP link ID - + Add Member @@ -4709,7 +4994,7 @@ p, li { white-space: pre-wrap; } - + Attachments Přílohy @@ -4755,7 +5040,7 @@ p, li { white-space: pre-wrap; } PÅ™etáhnÄ›te soubory z výsledků vyhledávání - + Paste RetroShare Links Vložit RetroShare odkazy @@ -4765,7 +5050,7 @@ p, li { white-space: pre-wrap; } Vložit RetroShare odkaz - + Drop file error. Nastala chyba pÅ™i pÅ™etahování souboru. @@ -4792,17 +5077,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Soubor je již pÅ™idán a zatřídÄ›n + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Soubor je již pÅ™idán a zatřídÄ›n + + + Please add a Subject Prosím zadejte pÅ™edmÄ›t @@ -4833,12 +5142,12 @@ p, li { white-space: pre-wrap; } Opravdu chcete vygenerovat %1 zpráv? - + You are about to add files you're not actually sharing. Do you still want this to happen? Chcete pÅ™idat soubory, které vÅ¡ak přímo nesdílíte. Opravdu? - + Edit Channel Post @@ -4858,7 +5167,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. OhlednÄ› vkládání nevlastnÄ›ných souborů do kanálu @@ -4950,7 +5259,7 @@ p, li { white-space: pre-wrap; } - + No Forum Žádné fórum @@ -5405,7 +5714,7 @@ tam ji importujte. DHTGraphSource - + users uživatelé @@ -6408,7 +6717,7 @@ tam ji importujte. FlatStyle_RDM - + Friends Directories Sdílené soubory a složky mých kontaktů @@ -6903,7 +7212,7 @@ at least one peer was not added to a group Hledat kontakty - + Mark all OznaÄit vÅ¡e @@ -6917,7 +7226,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Editovat status @@ -7021,7 +7330,7 @@ at least one peer was not added to a group RetroShare rozhlas: zpráva je odeslána vÅ¡em pÅ™ipojeným kontaktům. - + Network Síť @@ -7086,7 +7395,7 @@ at least one peer was not added to a group Jméno node musí obsahovat alespoň 3 znaky - + Failed to generate your new certificate, maybe PGP password is wrong! Nemůžu vygenerovat nový certifikát, možná jste Å¡patnÄ› napsali PGP heslo! @@ -7117,7 +7426,7 @@ at least one peer was not added to a group - + Node name @@ -7384,12 +7693,12 @@ a vytvoÅ™it nový node využívající stejný profil. - + Profile generation failure - + Missing PGP certificate @@ -7765,7 +8074,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne Statistiky smÄ›rovaÄe - + GroupBox @@ -7830,7 +8139,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Details Detaily @@ -7853,7 +8162,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne GlobalRouterStatisticsWidget - + Managed keys @@ -8054,7 +8363,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne GroupTreeWidget - + Title Nadpis @@ -8064,13 +8373,30 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne Hledat podle jména fóra - - + + + + Description Popis - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -8080,42 +8406,19 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - SeÅ™adit podle jména + SeÅ™adit podle jména - Sort by Popularity - SeÅ™adit podle oblíbenosti + SeÅ™adit podle oblíbenosti - Sort by Last Post - SeÅ™adit podle posledního příspÄ›vku + SeÅ™adit podle posledního příspÄ›vku - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8130,40 +8433,35 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - - + + Last Post Poslední příspÄ›vek - + + Name - - Unread - - - - + Popularity Popularita - - + + Never - Display - Zobrazit + Zobrazit - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8312,7 +8610,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne GxsChannelDialog - + Channels Kanály @@ -8333,12 +8631,12 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne Moje kanály - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Odebírané kanály @@ -8783,7 +9081,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Add new post @@ -8883,12 +9181,12 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Files Soubory - + Comments Komentáře @@ -8899,18 +9197,18 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Feeds Kanály - - + + Click to switch to list view - + Show unread posts only @@ -8920,12 +9218,12 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + No files in the channel, or no channel selected - + No text to display @@ -8985,7 +9283,7 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Download this file: @@ -9000,12 +9298,12 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne - + Comments (%1) - + [No name] @@ -9081,23 +9379,36 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne + Copy Retroshare link + + + + Subscribed PÅ™ihlášen - - Subscribe Odebírat - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Není vybrán žádný kanál @@ -9119,11 +9430,6 @@ PÅ™i používání sítÄ› proto pokud možno používejte pouhou pÅ™ezdívku, ne Channel Post Zpráva - - - new message(s) - - GxsCircleItem @@ -9616,7 +9922,7 @@ before you can comment Založit nové vlákno ve vybraném fóru - + Search forums Hledat ve fórech @@ -9625,12 +9931,12 @@ before you can comment Poslední příspÄ›vek - + New Thread - + Threaded View podle vláken @@ -9640,19 +9946,19 @@ before you can comment VÅ¡e za sebou - - + + Title Nadpis - - + + Date Datum - + Author Autor @@ -9667,7 +9973,17 @@ before you can comment NaÄítám - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9724,23 +10040,23 @@ before you can comment Hledat v obsahu zprávy - + No name Bez jména - - + + Reply OdpovÄ›dÄ›t - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9778,12 +10094,12 @@ before you can comment OznaÄit za nepÅ™eÄtené - + Copy RetroShare Link Kopírovat RetroShare odkaz - + Hide Skrýt @@ -9792,7 +10108,7 @@ before you can comment Rozbalit - + [unknown] @@ -9822,8 +10138,8 @@ before you can comment - - + + Distribution @@ -9922,12 +10238,12 @@ before you can comment Původní zpráva - + New thread - + Edit Editovat @@ -9983,7 +10299,7 @@ before you can comment - + Author's reputation @@ -10003,7 +10319,7 @@ before you can comment - + <b>Loading...<b> @@ -10043,6 +10359,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -10110,7 +10431,7 @@ This message is missing. You should receive it later. Na %1, %2 odpovÄ›dÄ›l: - + Forum name @@ -10142,11 +10463,6 @@ This message is missing. You should receive it later. Forum Post Zpráva - - - new message(s) - - GxsForumsDialog @@ -10575,7 +10891,7 @@ This message is missing. You should receive it later. Náhled tisku - + Unsubscribe Neodebírat @@ -10590,7 +10906,7 @@ This message is missing. You should receive it later. Otevřít v nové kartÄ› - + Remove this search @@ -10600,12 +10916,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10672,12 +10988,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -10692,7 +11008,7 @@ This message is missing. You should receive it later. OznaÄit vÅ¡e za nepÅ™eÄtené - + AUTHD AUTHD @@ -11214,7 +11530,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11223,7 +11539,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11249,7 +11565,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11323,49 +11639,55 @@ p, li { white-space: pre-wrap; } Formulář - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopírovat váš certifikát do schránky @@ -11413,17 +11735,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11438,7 +11755,12 @@ new short format Pozvánka do RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Uložit jako... @@ -11703,14 +12025,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All VÅ¡e - + Reputation @@ -11720,12 +12042,12 @@ p, li { white-space: pre-wrap; } Hledat - + Anonymous Id - + Create new Identity VytvoÅ™it novou identitu @@ -11869,7 +12191,7 @@ p, li { white-space: pre-wrap; } - + Send message Odeslat zprávu @@ -11941,7 +12263,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonymní sdílení @@ -11956,24 +12278,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11988,7 +12310,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12047,13 +12369,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12113,7 +12440,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Upravit Kruh @@ -12161,7 +12488,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12170,12 +12497,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12187,12 +12514,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12308,17 +12635,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12475,8 +12802,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12487,7 +12814,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12497,7 +12824,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12557,7 +12884,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12567,7 +12894,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12605,7 +12932,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12622,14 +12949,14 @@ These identities will soon be not supported anymore. - + N/A nedostupné - + Edit identity @@ -12640,24 +12967,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12677,12 +13007,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12692,7 +13047,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12702,7 +13057,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12742,12 +13102,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12757,7 +13112,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12862,8 +13217,12 @@ These identities will soon be not supported anymore. + Quote + Citovat + + Send - Odeslat + Odeslat @@ -13021,7 +13380,7 @@ These identities will soon be not supported anymore. - + Options Nastavení @@ -13053,12 +13412,12 @@ These identities will soon be not supported anymore. Průvodce nastavením - + RetroShare %1 a secure decentralized communication platform RetroShare %1 - bezpeÄná decentralizovaná komunikaÄní platforma - + Unfinished NedokonÄeno @@ -13187,7 +13546,7 @@ These identities will soon be not supported anymore. Zobrazit - + Make sure this link has not been forged to drag you to a malicious website. UjistÄ›te se, že tento odkaz nebyl zfalÅ¡ován za úÄelem dostat vás na Å¡kodlivé webové stránky. @@ -13232,7 +13591,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -13261,7 +13620,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose Napsat zprávu @@ -13363,7 +13722,7 @@ These identities will soon be not supported anymore. - + Tags Å títky @@ -13458,12 +13817,12 @@ These identities will soon be not supported anymore. Odsadí citaci - + Send To: Odeslat komu: - + &Left Zarovnat v&levo @@ -13493,7 +13852,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Ahoj,<br>doporuÄuji ti tento kontakt. Když důvěřujeÅ¡ mÄ›, můžeÅ¡ důvěřovat také tomuto kontaktu. <br> @@ -13519,12 +13883,12 @@ These identities will soon be not supported anymore. - + Save Message Uložit zprávu - + Message has not been Sent. Do you want to save message to draft box? Zpráva nebyla odeslána. @@ -13536,7 +13900,7 @@ Chcete ji uložit jako koncept? Vložit RetroShare odkaz - + Add to "To" PÅ™idat do "Komu" @@ -13790,7 +14154,7 @@ Do you want to save message ? PÅ™idat další soubor - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13804,6 +14168,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13816,7 +14195,7 @@ Do you want to save message ? Od: - + Bullet list (disc) @@ -13856,13 +14235,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -14001,8 +14380,23 @@ Do you want to save message ? Zpráva - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14014,12 +14408,12 @@ Do you want to save message ? DoporuÄené soubory - + Download all Recommended Files Stáhnou vÅ¡echny doporuÄené soubory - + Subject: PÅ™edmÄ›t: @@ -14094,12 +14488,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name Jméno souboru - + + Size Velikost @@ -14160,18 +14560,33 @@ Do you want to save message ? Stáhnout - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Stáhnout vÅ¡e - + Print Document Vytisknout dokument @@ -14186,7 +14601,7 @@ Do you want to save message ? HTML soubory (*.htm *.html);;VÅ¡echny soubory (*) - + Load images always for this message @@ -14327,7 +14742,7 @@ Do you want to save message ? MessagesDialog - + New Message Nová zpráva @@ -14383,14 +14798,14 @@ Do you want to save message ? - + Tags Å títky - + Inbox Příchozí @@ -14465,7 +14880,7 @@ Do you want to save message ? PÅ™eposlat zprávu - + Subject PÅ™edmÄ›t @@ -14577,7 +14992,7 @@ Do you want to save message ? - + Open in a new window Otevřít v novém oknÄ› @@ -14662,7 +15077,7 @@ Do you want to save message ? - + Drafts Koncepty @@ -14771,7 +15186,7 @@ Do you want to save message ? OdpovÄ›dÄ›t - + Delete Message Smazat zprávu @@ -14782,7 +15197,7 @@ Do you want to save message ? - + Expand Rozbalit @@ -14792,7 +15207,7 @@ Do you want to save message ? Odstranit položku - + from @@ -14801,6 +15216,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15107,7 +15527,7 @@ Reported error: - + Groups Skupiny @@ -15137,19 +15557,19 @@ Reported error: - - + + Search - + ID ID - + Search ID @@ -15159,7 +15579,7 @@ Reported error: - + Show Items @@ -15358,18 +15778,18 @@ at least one peer was not added to a group - + Error Chyba - + File is not writeable! - + File is not readable! @@ -15407,7 +15827,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15425,7 +15845,7 @@ at least one peer was not added to a group Toto je test. - + Newest on top @@ -15436,20 +15856,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15486,22 +15921,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon - + Message Zpráva @@ -15526,12 +15961,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected se pÅ™ipojil. @@ -15578,27 +16008,37 @@ at least one peer was not added to a group Skupinová konverzace - + + Toaster position + + + + Chat rooms - + Position Pozice - + + Activity + + + + X Margin Okraj X - + Y Margin Okraj Y - + Systray message @@ -15648,7 +16088,7 @@ at least one peer was not added to a group Oznámení - + Disable All Toasters @@ -15662,7 +16102,7 @@ at least one peer was not added to a group Kanál - + Systray @@ -15801,17 +16241,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : Jméno : @@ -15866,22 +16301,17 @@ at least one peer was not added to a group Absolutní - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15895,7 +16325,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15905,22 +16335,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Podepsat PGP klÃ­Ä + Podepsat PGP klÃ­Ä - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15940,7 +16364,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16006,27 +16430,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Chyba : nemohu získat údaje kontaktu - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16038,7 +16462,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16083,27 +16507,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Podepisování selhalo - - Maybe password is wrong - Možná že bylo Å¡patnÄ› zadané heslo + + Check the password! + - + Maybe password is wrong + Možná že bylo Å¡patnÄ› zadané heslo + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16282,8 +16726,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16300,7 +16743,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16439,7 +16882,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel Textový popisek @@ -16483,8 +16926,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Komentáře @@ -16515,6 +16958,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment PÅ™idat komentář + + + Album + Album + PhotoItem @@ -16524,12 +16972,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulář - + TextLabel Textový popisek - + <!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; } @@ -16613,7 +17061,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -16653,7 +17101,7 @@ requesting to edit it! - + Stop @@ -16877,17 +17325,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Povolit vÅ¡echny pluginy - + Plugin look-up directories Adresář se zásuvnými moduly - + Plugins Zásuvné moduly @@ -17217,7 +17665,7 @@ p, li { white-space: pre-wrap; } Odeslané odkazy - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17352,13 +17800,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments Komentáře - + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -17368,7 +17816,7 @@ p, li { white-space: pre-wrap; } - + Comment Komentáře @@ -17389,12 +17837,12 @@ p, li { white-space: pre-wrap; } - + Hide Skrýt - + Vote up @@ -17404,7 +17852,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item OznaÄit za pÅ™eÄtené a odstranit položku @@ -17465,7 +17913,7 @@ p, li { white-space: pre-wrap; } Textový popisek - + Loading Nahrávám @@ -17511,13 +17959,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17527,60 +17969,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown neznámé - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Textový popisek - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17591,7 +18023,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17660,7 +18092,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -17695,7 +18132,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17811,8 +18248,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18084,12 +18531,7 @@ tam ji importujte. PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -18104,17 +18546,32 @@ tam ji importujte. - + GroupLabel - + IDLabel - + + From: + Od: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18139,10 +18596,20 @@ tam ji importujte. - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18152,13 +18619,48 @@ tam ji importujte. - + + Post + + + + Cancel ZruÅ¡it - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -18185,10 +18687,18 @@ tam ji importujte. Formulář - - - - + + + + + Click to view picture + + + + + + + Image @@ -18196,44 +18706,44 @@ tam ji importujte. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18243,17 +18753,17 @@ tam ji importujte. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18263,7 +18773,7 @@ tam ji importujte. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18271,7 +18781,7 @@ tam ji importujte. PulseTopLevel - + retweeted @@ -18286,7 +18796,7 @@ tam ji importujte. - + follow Parent Group @@ -18296,7 +18806,7 @@ tam ji importujte. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18321,7 +18831,7 @@ tam ji importujte. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18357,29 +18867,29 @@ tam ji importujte. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18457,7 +18967,7 @@ tam ji importujte. QObject - + Confirmation Potvrzení @@ -18696,7 +19206,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Výsledek - + Unable to make path @@ -18731,7 +19241,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Požadavek o stáhnutí souboru byl zruÅ¡en. - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18869,7 +19379,7 @@ Reported error is: - + TR up @@ -18914,7 +19424,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18930,7 +19440,7 @@ Reported error is: - + %1 seconds ago @@ -19014,7 +19524,7 @@ Security: no anonymous IDs - + Error Chyba @@ -19405,9 +19915,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Tento certifikát obsahuje + <p>Tento certifikát obsahuje @@ -19752,7 +20261,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -19974,18 +20483,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20422,7 +20952,7 @@ p, li { white-space: pre-wrap; } Stáhnout! - + File Soubor @@ -20437,7 +20967,7 @@ p, li { white-space: pre-wrap; } Kontrolní souÄet - + Bad filenames have been cleaned @@ -20485,7 +21015,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Uložit - + Collection Editor @@ -20500,7 +21030,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -20515,12 +21045,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... Zvolit... @@ -20767,7 +21297,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -20787,7 +21317,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -20800,10 +21330,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Nadpis + + + UnRead + + Date @@ -20815,7 +21350,7 @@ If you believe it is correct, remove the corresponding line from the file and re Autor - + Information for this identity is currently missing. @@ -20853,7 +21388,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... chybÄ›jící zpráva ... ] @@ -20861,7 +21396,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -20921,7 +21456,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21276,7 +21811,7 @@ Vysoká pravdÄ›podobnost že soubor bude nalezen Jméno souboru - + Download Stáhnout @@ -21355,7 +21890,7 @@ Vysoká pravdÄ›podobnost že soubor bude nalezen Otevřít složku - + Create Collection... @@ -21375,7 +21910,7 @@ Vysoká pravdÄ›podobnost že soubor bude nalezen Stáhnou podle souboru kolekce... - + Collection Kolekce @@ -21480,12 +22015,12 @@ Vysoká pravdÄ›podobnost že soubor bude nalezen Podrobnosti o kontaktu - + Deny friend Odmítnout kontakt - + Chat Konverzace @@ -21495,7 +22030,7 @@ Vysoká pravdÄ›podobnost že soubor bude nalezen Konverzovat - + Expand Rozbalit @@ -21762,13 +22297,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22234,7 +22769,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Síť @@ -22262,7 +22797,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22359,7 +22894,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22394,12 +22929,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23066,7 +23601,7 @@ p, li { white-space: pre-wrap; } Chybí PGP certifikát - + Wrong password @@ -23108,7 +23643,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend PÅ™idat mezi kontakty @@ -23164,7 +23699,7 @@ This choice can be reverted in settings. - + DHT DHT @@ -23696,7 +24231,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23706,13 +24241,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23721,6 +24255,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23994,27 +24553,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -24022,7 +24576,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads Stahování @@ -24033,7 +24587,7 @@ p, li { white-space: pre-wrap; } Odesílání - + Name i.e: file name Jméno @@ -24240,7 +24794,7 @@ p, li { white-space: pre-wrap; } Zvolit... - + Move in Queue... PÅ™esunout do fronty... @@ -24334,7 +24888,7 @@ p, li { white-space: pre-wrap; } Prosím vložte nové--a platné--jméno souboru - + Expand all Rozbalit vÅ¡e @@ -24466,7 +25020,7 @@ p, li { white-space: pre-wrap; } - + Columns Sloupce @@ -24477,7 +25031,7 @@ p, li { white-space: pre-wrap; } - + Path Cesta @@ -24487,7 +25041,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24497,7 +25051,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -24512,7 +25066,7 @@ p, li { white-space: pre-wrap; } - + Collection Kolekce @@ -24754,7 +25308,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Neznámý Peer @@ -24850,7 +25404,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Máte %1 nových zpráv @@ -25222,7 +25776,7 @@ p, li { white-space: pre-wrap; } VytvoÅ™it skupinu - + Subscribe to Group @@ -25316,8 +25870,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -25328,7 +25882,7 @@ p, li { white-space: pre-wrap; } - + Preview Náhled @@ -25353,12 +25907,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -25378,7 +25932,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -25416,7 +25970,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -25426,12 +25980,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -25466,12 +26019,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25505,7 +26058,7 @@ p, li { white-space: pre-wrap; } Nový - + Yourself @@ -25519,7 +26072,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -25531,7 +26084,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -25539,7 +26092,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25620,8 +26173,8 @@ p, li { white-space: pre-wrap; } Formulář - - + + Avatar Avatar @@ -25650,6 +26203,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25762,7 +26320,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_da.ts b/retroshare-gui/src/lang/retroshare_da.ts index 9a05b487d..41f99845c 100644 --- a/retroshare-gui/src/lang/retroshare_da.ts +++ b/retroshare-gui/src/lang/retroshare_da.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Indstillinger + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,19 @@ p, li { white-space: pre-wrap; } - - Save - - - - Cancel - Annuller + Annuller - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +887,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +965,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Navn + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1179,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1241,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Navn + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1528,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1557,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1981,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2046,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2072,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2138,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2287,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2472,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2489,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2566,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2602,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2623,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2643,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2801,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaljer - + Local Address Lokale Adresse @@ -2635,12 +2817,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2838,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2888,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2938,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2964,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2975,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +3000,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3084,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Navn: - + Location: - + Options Indstillinger - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3119,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3144,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3169,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3240,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3270,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3323,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3397,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3432,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3490,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3570,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3997,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4137,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4152,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4168,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4184,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4211,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4337,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4383,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4393,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4420,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4481,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4506,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4594,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5009,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6012,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6503,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6517,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6621,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6686,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6717,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6976,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7344,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7409,7 @@ p, li { white-space: pre-wrap; } - + Details Detaljer @@ -7175,7 +7432,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7633,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7643,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7676,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7691,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Navn - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7864,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7885,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8253,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8353,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8369,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8390,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8455,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8470,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8551,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8602,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9086,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9106,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9133,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9188,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -8994,17 +9242,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9282,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9366,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9427,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9447,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9487,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9559,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9591,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9996,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10011,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10021,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10093,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10113,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10627,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10636,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10662,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10736,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10832,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10852,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11122,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11139,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11288,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11360,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11375,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11407,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11466,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11537,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11585,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11594,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11611,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11732,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11899,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11911,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11921,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11981,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11991,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12029,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12046,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12064,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12104,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12144,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12154,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12199,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12209,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12314,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12473,7 @@ These identities will soon be not supported anymore. - + Options Indstillinger @@ -12218,12 +12505,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12639,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12684,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12713,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12815,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12910,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12945,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12976,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12992,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13246,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13260,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13287,7 @@ Do you want to save message ? Fra: - + Bullet list (disc) @@ -13020,13 +13327,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13472,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13500,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13580,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13652,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13693,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13798,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13810,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13888,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13968,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14053,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14142,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14153,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14163,7 @@ Do you want to save message ? - + from @@ -13829,6 +14172,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14476,7 @@ Reported error: - + Groups @@ -14158,19 +14506,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14528,7 @@ Reported error: - + Show Items @@ -14379,18 +14727,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14776,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14790,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14801,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14862,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14898,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14945,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15025,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15035,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15162,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15222,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15246,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15256,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15281,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15347,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15379,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15424,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong - MÃ¥ske password er forkert + + Check the password! + - + Maybe password is wrong + MÃ¥ske password er forkert + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15652,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15784,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15820,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15848,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15947,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15987,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16211,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16547,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16678,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16694,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16715,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16730,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16791,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16449,13 +16821,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16465,60 +16831,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16529,7 +16885,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16598,7 +16954,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16633,7 +16994,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16749,8 +17110,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17018,12 +17389,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17038,17 +17404,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + Fra: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17073,10 +17454,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17086,13 +17477,48 @@ and use the import button to load it - + + Post + + + + Cancel Annuller - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17104,10 +17530,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17115,44 +17549,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17162,17 +17596,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17182,7 +17616,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17190,7 +17624,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17205,7 +17639,7 @@ and use the import button to load it - + follow Parent Group @@ -17215,7 +17649,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17240,7 +17674,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17276,29 +17710,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17376,7 +17810,7 @@ and use the import button to load it QObject - + Confirmation @@ -17615,7 +18049,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17650,7 +18084,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17788,7 +18222,7 @@ Reported error is: - + TR up @@ -17833,7 +18267,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17849,7 +18283,7 @@ Reported error is: - + %1 seconds ago @@ -17933,7 +18367,7 @@ Security: no anonymous IDs - + Error @@ -18323,11 +18757,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18661,7 +19090,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18883,18 +19312,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19331,7 +19781,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19346,7 +19796,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19394,7 +19844,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19409,7 +19859,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19424,12 +19874,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19676,7 +20126,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Navn @@ -19696,7 +20146,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19709,10 +20159,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19724,7 +20179,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19762,7 +20217,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19770,7 +20225,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19830,7 +20285,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20184,7 +20639,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20263,7 +20718,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20283,7 +20738,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20388,12 +20843,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20403,7 +20858,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20666,13 +21121,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21138,7 +21593,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21166,7 +21621,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21263,7 +21718,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21298,12 +21753,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21968,7 +22423,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22010,7 +22465,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22066,7 +22521,7 @@ This choice can be reverted in settings. - + DHT @@ -22598,7 +23053,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22608,13 +23063,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22623,6 +23077,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22896,27 +23375,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22924,7 +23398,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22935,7 +23409,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Navn @@ -23142,7 +23616,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23236,7 +23710,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23368,7 +23842,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23379,7 +23853,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23389,7 +23863,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23399,7 +23873,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23414,7 +23888,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23656,7 +24130,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23752,7 +24226,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24120,7 +24594,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24214,8 +24688,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24226,7 +24700,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24251,12 +24725,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24276,7 +24750,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24314,7 +24788,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24324,12 +24798,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24364,12 +24833,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24399,7 +24868,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24409,7 +24878,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24421,7 +24890,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24429,7 +24898,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24510,8 +24979,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24540,6 +25009,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24652,7 +25126,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_de.ts b/retroshare-gui/src/lang/retroshare_de.ts index ec5c0cd1b..4fa1bb85b 100644 --- a/retroshare-gui/src/lang/retroshare_de.ts +++ b/retroshare-gui/src/lang/retroshare_de.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare-Version @@ -79,7 +79,7 @@ Viel Spaß ;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Erweiterte Suche - + Search Criteria Suchkriterien - + Add a further search criterion. Ein weiteres Suchkriterium hinzufügen. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formular - - + + TextLabel TextLabel @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Werkzeugleiste - + Icon Only Nur Symbole @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Wähle den Stil für die Werkzeugschaltflächen - + Icon Size = 8x8 Symbolgröße = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Symbolgröße = 128x128 - + Status Bar Statusleiste @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Symbolgröße = 32x32 @@ -828,14 +828,23 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Avatar wechseln - + + TextLabel + TextLabel + + + Your Avatar Picture Dein Avatarbild - + + Browse... + + + Add Avatar - Avatar hinzufügen + Avatar hinzufügen @@ -843,25 +852,34 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Entfernen - + Set your Avatar picture Dein Avatarbild festlegen - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatar laden + Avatar laden AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klick zum Ändern deines Avatars @@ -869,7 +887,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto RetroShare Bandwidth Usage RetroShare Bandbreitennutzung + + + PushButton + + - + Up + Hoch + + + + Down + Herunter + + + + Clears the graph + + + + Show Settings Einstellungen anzeigen + TextLabel + TextLabel + + + Reset Zurücksetzen - Receive Rate - Empfangsrate + Empfangsrate - Send Rate - Senderate + Senderate - + Always on Top Immer im Vordergrund - Style - Stil + Stil - + Changes the transparency of the Bandwidth Graph Ändert die Transparenz des Bandbreiten-Graphen - + 100 100 @@ -936,30 +975,27 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto % undurchsichtig - Save - Speichern + Speichern - Cancel - Abbrechen + Abbrechen - + Since: Seit: - Hide Settings - Einstellungen verbergen + Einstellungen verbergen BandwidthStatsWidget - + Sum Summe @@ -981,7 +1017,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Anzahl - + Average Durchschnitt @@ -1115,7 +1151,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto TextLabel - + Comments Kommentare @@ -1193,6 +1229,85 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto TextLabel + + BoardsCommentsItem + + + I like this + Das gefällt mir + + + + 0 + 0 + + + + I dislike this + Das gefällt mir nicht + + + + Toggle Message Read Status + Lesestatus der Nachricht umschalten + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + RetroShare-Link kopieren + + + + + Expand + Erweitern + + + + Set as read and remove item + Als gelesen markieren und Eintrag entfernen + + + + Remove Item + + + + + Name + Name + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Verbergen + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Log scale + + + Default + Standard + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Das gefällt mir + + + + 0 + 0 + + + + I dislike this + Das gefällt mir nicht + + + + Toggle Message Read Status + Lesestatus der Nachricht umschalten + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + RetroShare-Link kopieren + + + + + Expand + Erweitern + + + + Set as read and remove item + Als gelesen markieren und Eintrag entfernen + + + + Remove Item + + + + + Name + Name + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Verbergen + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chats - You have %1 new messages - Du hast %1 neue Nachrichten + Du hast %1 neue Nachrichten + + + You have %1 new message + Du hast %1 neue Nachricht + + + %1 new messages + %1 neue Nachrichten + + + %1 new message + %1 neue Nachricht + + + + You have %1 mentions + - You have %1 new message - Du hast %1 neue Nachricht + You have %1 mention + - %1 new messages - %1 neue Nachrichten + %1 mentions + - %1 new message - %1 neue Nachricht + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Alle entfernen - - - mention(s) - - ChatLobbyWidget @@ -2114,13 +2329,11 @@ Double click a chat room to enter and chat. Variante: - Group chat - Gruppenchat + Gruppenchat - - + Private chat Privater Chat @@ -2185,17 +2398,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">In diesem Tab kannst du für die verschiedenen Chatsysteme festlegen, wieviele Nachrichten RetroShare auf Festplatte gespeichert hält, und wieviel der vorangehenden Unterhaltung angezeigt wird. Die maximale Speicherzeit erlaubt das Verwerfen alter Nachrichten und verhindert das unberechenbare Füllen des Unterhaltungsverlaufs (z. B. Chatlobbys und Fernchat).</p></body></html> - Chatlobbies - Chatlobbys + Chatlobbys - + Enabled: Aktiviert: @@ -2216,11 +2428,12 @@ Double click a chat room to enter and chat. + Chat rooms Chaträume - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2281,11 +2494,17 @@ Double click a chat room to enter and chat. + Broadcast Rundschreiben - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Gespeicherte Nachrichten (0 = unbegrenzt) @@ -2432,8 +2651,23 @@ Double click a chat room to enter and chat. Privater Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2602,7 +2836,7 @@ Double click a chat room to enter and chat. - + is typing... tippt... @@ -2620,12 +2854,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Möchtest du wirklich den Nachrichtenverlauf löschen? @@ -2697,7 +2931,7 @@ after HTML conversion. Nach Finden von X Elementen mit dem Einfärben nicht aufhören (benötigt mehr CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Vorherige finden </b><br/><i>Strg+Umschalt+G</i> @@ -2737,12 +2971,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Markiere diesen ausgewählten Text</b><br><i>Strg+M</i> - + Person id: @@ -2758,7 +2992,7 @@ Double click on it to add his name on text writer. - + items found. Elemente gefunden. @@ -2778,7 +3012,7 @@ Double click on it to add his name on text writer. Hier eine Nachricht eingeben - + Don't stop to color after Nach Finden von @@ -2936,12 +3170,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Details - + Local Address Lokale Adresse @@ -2952,12 +3186,12 @@ Double click on it to add his name on text writer. Externe Adresse - + Node info: - + Current address: @@ -2973,31 +3207,36 @@ Double click on it to add his name on text writer. Port - + Include signatures Signaturen einschließen - + RetroShare RetroShare - + - + Error : cannot get peer details. Fehler: Kann Nachbardetails nicht ermitteln. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3013,22 +3252,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Verschlüsselung - + Not connected Nicht verbunden - + Retroshare node details RetroShare-Netzknotendetails - + Node name : Netzknotenname : @@ -3063,13 +3307,18 @@ Double click on it to add his name on text writer. Statusnachricht: - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate RetroShare-Zertifikat @@ -3084,7 +3333,7 @@ Double click on it to add his name on text writer. - + Hidden Address Versteckte Adresse @@ -3095,11 +3344,12 @@ Double click on it to add his name on text writer. keine + <p>This certificate contains: - <p>Dieses Zertifikat enthält: + <p>Dieses Zertifikat enthält: - + <li>a <b>node ID</b> and <b>name</b> <li>eine <b>Netzknoten-ID</b> und <b>Name</b> @@ -3112,12 +3362,12 @@ Double click on it to add his name on text writer. eine <b>IP-Adresse</b> und <b>Port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> Du kannst dieses Zertifikat zum Schließen von neuen Freundschaften verwenden. Versende es per E-Mail oder gib es von Hand zu Hand. - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Dies ist die ID des <span style=" font-weight:600;">OpenSSL</span>-Zertifikates des Netzknotens, welches mit obigem <span style=" font-weight:600;">PGP</span>-Schlüssel signiert wurde.</p></body></html> @@ -3127,7 +3377,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Dies ist die Verschlüsselungsmethode die von <span style=" font-weight:600;">OpenSSL</span> benutzt wird. Die Verbindung zu befreundeten Netzknoten ist immer stark verschlüsselt.</p><p>Und wenn DHE vorhanden ist dann verwendet die Verbindung noch dazu</p><p>&quot;Perfect Forward Secrecy&quot;.</p></body></html> - + with mit @@ -3319,12 +3569,12 @@ Double click on it to add his name on text writer. Details der Anfrage - + Peer details Nachbardetails - + Name: Name: @@ -3337,12 +3587,12 @@ Double click on it to add his name on text writer. Netzknoten: - + Location: Ort: - + Options Optionen @@ -3367,12 +3617,12 @@ Double click on it to add his name on text writer. Zertifikat einfügen - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Freund zur Gruppe hinzufügen: @@ -3382,7 +3632,7 @@ Double click on it to add his name on text writer. Freund authentifizieren (PGP-Schlüssel unterzeichnen) - + Please paste below your friend's Retroshare ID @@ -3407,7 +3657,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Als Freund hinzufügen, zu dem verbunden wird @@ -3416,7 +3666,7 @@ Double click on it to add his name on text writer. Abschließen-Knopf anklicken, um die Anfrage zu akzeptieren - + Sorry, some error appeared Entschuldigung, es trat ein Fehler auf @@ -3436,32 +3686,32 @@ Double click on it to add his name on text writer. Details über deinen Freund: - + Key validity: Schlüssel-Gültigkeit: - + Profile ID: - + Signers Unterzeichner - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Dieser Nachbar ist bereits in deiner Freundliste vorhanden. Das nochmalige Hinzufügen ändert nur seine IP. - + To accept the Friend Request, click the Accept button. @@ -3507,7 +3757,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Das Zertifikat konnte nicht geladen werden @@ -3544,12 +3794,12 @@ Double click on it to add his name on text writer. Zertifikat scheint gültig zu sein - + Not a valid Retroshare certificate! Kein gültiges RetroShare-Zertifikat! - + RetroShare Invitation RetroShare-Einladung @@ -3569,12 +3819,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3622,7 +3872,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du hast eine Freundschaftsanfrage von - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3710,12 +3990,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Wenn verfügbar als direkte Quelle nutzen - + IP-Addr: IP-Adr.: - + IP-Address IP-Adresse @@ -3773,7 +4053,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Schlüssel zum Schlüsselbund hinzufügen. - + This key is already in your keyring Schlüssel ist bereits in deinem Schlüsselbund. @@ -3833,12 +4113,12 @@ Das Zertifikat hat die falsche Versionsnummer. Beachte, dass v0.6- und v0.5-Netz <p>Dieses Zertifikat enthält keine IP. Du wirst auf Discovery und DHT angewiesen sein un sie herauszufinden. Da du Whitelist-Freigabe forderst wird der Nachbar eine Sicherheitswarnung im Neuigkeitenreiter auslösen. Von dort kannst die die IP freigeben.</p> - + [Unknown] [Unbekannt] - + Added with certificate from %1 Hinzugefügt mit Zertifikat von %1 @@ -3925,7 +4205,12 @@ Das Zertifikat hat die falsche Versionsnummer. Beachte, dass v0.6- und v0.5-Netz UDP-Ergebnis - + + Status + Status + + + <!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; } @@ -4347,7 +4632,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4499,7 +4784,7 @@ p, li { white-space: pre-wrap; } Keine Einschränkungen für Kreis gewählt - + [Unknown] [Unbekannt] @@ -4514,7 +4799,7 @@ p, li { white-space: pre-wrap; } Entfernen - + Search Suchen @@ -4534,7 +4819,7 @@ p, li { white-space: pre-wrap; } Von bekannten Netzknoten unterzeichnet - + Edit Circle Kreis bearbeiten @@ -4554,12 +4839,12 @@ p, li { white-space: pre-wrap; } Anonyme ID - + Circle name Kreisname - + Update Aktualisieren @@ -4585,7 +4870,7 @@ p, li { white-space: pre-wrap; } PGP-verknüpfte ID - + Add Member Mitglied hinzufügen @@ -4729,7 +5014,7 @@ p, li { white-space: pre-wrap; } - + Attachments Anhänge @@ -4775,7 +5060,7 @@ p, li { white-space: pre-wrap; } Drag'n'Drop Dateien aus den Suchergebnissen - + Paste RetroShare Links RetroShare-Links einfügen @@ -4785,7 +5070,7 @@ p, li { white-space: pre-wrap; } RetroShare-Link einfügen - + Drop file error. Dateifehler bei Drag'n'Drop. @@ -4812,17 +5097,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Datei wurde schon hinzugefügt und gehasht + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Datei wurde schon hinzugefügt und gehasht + + + Please add a Subject Bitte einen Betreff hinzufügen @@ -4853,12 +5162,12 @@ p, li { white-space: pre-wrap; } Möchtest du wirklich %1 Nachrichten erzeugen? - + You are about to add files you're not actually sharing. Do you still want this to happen? Du bist dabei, Dateien hinzuzufügen, die du nicht freigegeben hast. Willst du das wirklich tun? - + Edit Channel Post @@ -4878,7 +5187,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Du willst Dateien zu einem Kanal hinzufügen, die dir nicht gehören. @@ -4970,7 +5279,7 @@ p, li { white-space: pre-wrap; } - + No Forum Kein Forum @@ -5425,7 +5734,7 @@ und den Import zum Laden verwenden DHTGraphSource - + users Benutzer @@ -6428,7 +6737,7 @@ und den Import zum Laden verwenden FlatStyle_RDM - + Friends Directories Dateien von Freunden @@ -6927,7 +7236,7 @@ at least one peer was not added to a group Freunde suchen - + Mark all Alle markieren @@ -6941,7 +7250,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Statusnachricht bearbeiten @@ -7045,7 +7354,7 @@ at least one peer was not added to a group RetroShare-Rundschreiben: Nachrichten werden an alle verbundenen Freunde gesendet. - + Network Netzwerk @@ -7110,7 +7419,7 @@ at least one peer was not added to a group Das Feld Netzknoten ist mit min. 3 Zeichen zu versehen - + Failed to generate your new certificate, maybe PGP password is wrong! Das Erzeugen deines neuen Zertifikats ist fehlgeschlagen. Vielleicht ist das PGP-Passwort falsch? @@ -7145,7 +7454,7 @@ at least one peer was not added to a group - + Node name Knotenname @@ -7412,12 +7721,12 @@ und den Import zum Laden verwenden - + Profile generation failure Profilerzeugung fehlgeschlagen - + Missing PGP certificate Fehlendes PGP-Zertifikat @@ -7789,7 +8098,7 @@ p, li { white-space: pre-wrap; } Routerstatistiken - + GroupBox @@ -7854,7 +8163,7 @@ p, li { white-space: pre-wrap; } - + Details Details @@ -7877,7 +8186,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Verwaltete Schlüssel @@ -8086,7 +8395,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8096,13 +8405,30 @@ p, li { white-space: pre-wrap; } Titel durchsuchen - - + + + + Description Beschreibung - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Beschreibung durchsuchen @@ -8112,42 +8438,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Nach Name sortieren + Nach Name sortieren - Sort by Popularity - Nach Beliebtheit sortieren + Nach Beliebtheit sortieren - Sort by Last Post - Nach letztem Beitrag sortieren + Nach letztem Beitrag sortieren - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8162,40 +8465,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post Letzter Beitrag - + + Name Name - - Unread - - - - + Popularity Beliebtheit - - + + Never Nie - Display - Anzeigen + Anzeigen - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8344,7 +8642,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanäle @@ -8365,12 +8663,12 @@ p, li { white-space: pre-wrap; } Eigene Kanäle - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Abonnierte Kanäle @@ -8887,7 +9185,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8987,12 +9285,12 @@ p, li { white-space: pre-wrap; } - + Files Dateien - + Comments Kommentare @@ -9003,18 +9301,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -9024,12 +9322,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9089,7 +9387,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9104,12 +9402,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9185,23 +9483,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Abonniert - - Subscribe Abonnieren - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Keinen Kanal gewählt @@ -9223,11 +9534,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanalbeitrag - - - new message(s) - - GxsCircleItem @@ -9745,7 +10051,7 @@ bevor du kommentieren kannst. Ein neues Thema im ausgewählten Forum starten - + Search forums Foren durchsuchen @@ -9754,12 +10060,12 @@ bevor du kommentieren kannst. Letzter Beitrag - + New Thread Neues Thema - + Threaded View Hierarchische Ansicht @@ -9769,19 +10075,19 @@ bevor du kommentieren kannst. Ebene Ansicht - - + + Title Titel - - + + Date Datum - + Author Autor @@ -9796,7 +10102,17 @@ bevor du kommentieren kannst. Lade - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9853,23 +10169,23 @@ bevor du kommentieren kannst. Inhalt durchsuchen - + No name Kein Name - - + + Reply Antwort - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9907,12 +10223,12 @@ bevor du kommentieren kannst. Als ungelesen markieren - + Copy RetroShare Link RetroShare-Link kopieren - + Hide Verbergen @@ -9925,7 +10241,7 @@ bevor du kommentieren kannst. [Gebannt] - + [unknown] [unbekannt] @@ -9955,8 +10271,8 @@ bevor du kommentieren kannst. Nur Ihre Augen - - + + Distribution Verteilung @@ -10059,12 +10375,12 @@ bevor du kommentieren kannst. Ursprüngliche Nachricht - + New thread - + Edit Bearbeiten @@ -10120,7 +10436,7 @@ bevor du kommentieren kannst. - + Author's reputation @@ -10140,7 +10456,7 @@ bevor du kommentieren kannst. - + <b>Loading...<b> @@ -10180,6 +10496,11 @@ bevor du kommentieren kannst. Storage Speicherung + + + Last seen at friends: + + Moderators @@ -10247,7 +10568,7 @@ This message is missing. You should receive it later. Am %1, schrieb %2: - + Forum name Forumsname @@ -10279,11 +10600,6 @@ This message is missing. You should receive it later. Forum Post Forumsbeitrag - - - new message(s) - - GxsForumsDialog @@ -10732,7 +11048,7 @@ This message is missing. You should receive it later. Druckvorschau - + Unsubscribe Abbestellen @@ -10747,7 +11063,7 @@ This message is missing. You should receive it later. In neuem Reiter öffnen - + Remove this search @@ -10757,12 +11073,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Details anzeigen @@ -10829,12 +11145,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link RetroShare-Link kopieren @@ -10849,7 +11165,7 @@ This message is missing. You should receive it later. Alle als ungelesen markieren - + AUTHD AUTHD @@ -11422,7 +11738,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11431,7 +11747,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11457,7 +11773,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11535,27 +11851,22 @@ p, li { white-space: pre-wrap; } Formular - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11565,23 +11876,34 @@ p, li { white-space: pre-wrap; } + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help Webhilfe öffnen - + Copy your Cert to Clipboard Dein Zertifikat in die Zwischenablage kopieren @@ -11629,17 +11951,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11654,7 +11971,12 @@ new short format RetroShare-Einladung - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Speichern als... @@ -11919,14 +12241,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alle - + Reputation Reputation @@ -11936,12 +12258,12 @@ p, li { white-space: pre-wrap; } Suchen - + Anonymous Id Anonyme ID - + Create new Identity Neue Identität erstellen @@ -12085,7 +12407,7 @@ p, li { white-space: pre-wrap; } Identitäts-ID - + Send message Nachricht senden @@ -12157,7 +12479,7 @@ p, li { white-space: pre-wrap; } Insgesamt: - + Anonymous Anonym @@ -12172,24 +12494,24 @@ p, li { white-space: pre-wrap; } Kennung suchen - + This identity is owned by you Diese Identität gehört dir - - + + My own identities Meine eigenen Identitäten - - + + My contacts Meine Kontakte - + Show Items @@ -12204,7 +12526,7 @@ p, li { white-space: pre-wrap; } - + Other circles Andere Kreise @@ -12263,13 +12585,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: Ihr Status: @@ -12329,7 +12656,7 @@ p, li { white-space: pre-wrap; } Mitglied - + Edit Circle Kreis bearbeiten @@ -12377,7 +12704,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12386,12 +12713,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [Unbekannter Knoten] - + Unverified signature from node @@ -12403,12 +12730,12 @@ These identities will soon be not supported anymore. Ungeprüfte Signatur - + [unverified] [unbestätigt] - + Identity owned by you, linked to your Retroshare node Dir gehörende, mit deinem RetroShare-Netzknoten verknüpfte Identität @@ -12524,17 +12851,17 @@ These identities will soon be not supported anymore. - + Banned Gebannt - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive positiv @@ -12707,8 +13034,8 @@ These identities will soon be not supported anymore. - - + + People Leute @@ -12719,7 +13046,7 @@ These identities will soon be not supported anymore. Dein Avatar - + Linked to neighbor nodes Mit Nachbarknoten verknüpft @@ -12729,7 +13056,7 @@ These identities will soon be not supported anymore. Mit entfernten Netzknoten verknüpft - + Linked to a friend Retroshare node Mit befreundetem RetroShare-Netzknoten verknüpft @@ -12789,7 +13116,7 @@ These identities will soon be not supported anymore. Im Besitz von - + Node name: Netzknotenname: @@ -12799,7 +13126,7 @@ These identities will soon be not supported anymore. Netzknoten-ID : - + Really delete? Wirklich löschen? @@ -12837,7 +13164,22 @@ These identities will soon be not supported anymore. Pseudonym - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Neue Identität @@ -12854,14 +13196,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity Identität bearbeiten @@ -12872,24 +13214,27 @@ These identities will soon be not supported anymore. Aktualisieren - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12908,17 +13253,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Fehler beim Holen des Schlüssels! - + Error KeyID invalid Fehler Schlüssel-ID ungültig - + Unknown GpgId Unbekannte PGP-ID @@ -12928,7 +13283,7 @@ These identities will soon be not supported anymore. Unbekannter Klarname - + Create New Identity Neue Identität erstellen @@ -12938,7 +13293,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12978,12 +13338,11 @@ These identities will soon be not supported anymore. Dein Avatar - Set Avatar - Avatar festlegen + Avatar festlegen - + Linked to your profile Mit deinem Profil verknüpft @@ -12993,7 +13352,7 @@ These identities will soon be not supported anymore. Du kannst eine oder mehrere Identitäten haben. Sie werden genutzt, um in Chatlobbys, Foren und Kanalkommentaren zu schreiben. Sie dienen als Zieladresse für Fernchat und das RetroShare-Fernnachrichtensystem. - + The nickname is too short. Please input at least %1 characters. Der Spitzname ist zu kurz. Bitte mindestens %1 Zeichen eingeben. @@ -13102,8 +13461,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - Senden + Senden @@ -13261,7 +13624,7 @@ These identities will soon be not supported anymore. - + Options Optionen @@ -13293,12 +13656,12 @@ These identities will soon be not supported anymore. Schnellstart-Assistent - + RetroShare %1 a secure decentralized communication platform RetroShare %1 - eine sichere und dezentralisierte Kommunikationsplattform - + Unfinished unfertig @@ -13431,7 +13794,7 @@ Bitte gib etwas Speicher frei und drücke OK. Anzeigen - + Make sure this link has not been forged to drag you to a malicious website. Vergewissere dich, dass dieser Link nicht gefälscht ist, um dich auf eine bösartige Webseite zu locken. @@ -13476,7 +13839,7 @@ Bitte gib etwas Speicher frei und drücke OK. Serviceberechtigungsmatrix - + Statistics Statistiken @@ -13505,7 +13868,7 @@ Bitte gib etwas Speicher frei und drücke OK. MessageComposer - + Compose Verfassen @@ -13607,7 +13970,7 @@ Bitte gib etwas Speicher frei und drücke OK. - + Tags Schlagwörter @@ -13702,12 +14065,12 @@ Bitte gib etwas Speicher frei und drücke OK. Blockquote hinzufügen - + Send To: Senden an: - + &Left &Links @@ -13741,7 +14104,7 @@ Bitte gib etwas Speicher frei und drücke OK. Meine Kontakte - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hallo, <br> ich empfehle dir einen guten Freund von mir. Du kannst ihm vertrauen, wenn du mir vertraust. <br> @@ -13767,12 +14130,12 @@ Bitte gib etwas Speicher frei und drücke OK. - + Save Message Nachricht speichern - + Message has not been Sent. Do you want to save message to draft box? Nachricht wurde noch nicht gesendet. @@ -13784,7 +14147,7 @@ Möchtest du die Nachricht in den Entwürfen speichern? RetroShare Link einfügen - + Add to "To" Zu "An" hinzufügen @@ -14039,7 +14402,7 @@ Möchtest du die Nachricht speichern ? Zusätzliche Datei hinzufügen - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -14053,6 +14416,21 @@ Möchtest du die Nachricht speichern ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -14065,11 +14443,12 @@ Möchtest du die Nachricht speichern ? Von: + Friend Nodes - Befreundete Netzknoten + Befreundete Netzknoten - + Bullet list (disc) Ungeordnete Liste (Punkt) @@ -14109,13 +14488,13 @@ Möchtest du die Nachricht speichern ? Geordnete Liste (Römisch groß) - - + + Thanks, <br> Danke, <br> - + Distant identity: Fernidentität: @@ -14254,8 +14633,23 @@ Möchtest du die Nachricht speichern ? Nachricht - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14267,12 +14661,12 @@ Möchtest du die Nachricht speichern ? Empfohlene Dateien - + Download all Recommended Files Alle Dateien herunterladen - + Subject: Betreff: @@ -14347,12 +14741,18 @@ Möchtest du die Nachricht speichern ? Einladung senden - + + Message Size: + + + + File Name Dateiname - + + Size Größe @@ -14413,18 +14813,33 @@ Möchtest du die Nachricht speichern ? Herunterladen - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Alle herunterladen - + Print Document Dokument drucken @@ -14439,7 +14854,7 @@ Möchtest du die Nachricht speichern ? HTML-Dateien (*.htm *.html);;Alle Dateien (*) - + Load images always for this message Bilde für diese Nachricht immer laden @@ -14580,7 +14995,7 @@ Möchtest du die Nachricht speichern ? MessagesDialog - + New Message Neue Nachricht @@ -14636,14 +15051,14 @@ Möchtest du die Nachricht speichern ? - + Tags Schlagwörter - + Inbox Posteingang @@ -14738,7 +15153,7 @@ Möchtest du die Nachricht speichern ? Weiterleiten - + Subject Betreff @@ -14850,7 +15265,7 @@ Möchtest du die Nachricht speichern ? - + Open in a new window In neuem Fenster öffnen @@ -14935,7 +15350,7 @@ Möchtest du die Nachricht speichern ? - + Drafts Entwürfe @@ -15064,7 +15479,7 @@ Möchtest du die Nachricht speichern ? Auf Nachricht antworten - + Delete Message Nachricht löschen @@ -15075,7 +15490,7 @@ Möchtest du die Nachricht speichern ? - + Expand Erweitern @@ -15085,7 +15500,7 @@ Möchtest du die Nachricht speichern ? Element entfernen - + from von @@ -15094,6 +15509,11 @@ Möchtest du die Nachricht speichern ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15409,7 +15829,7 @@ Reported error: - + Groups Gruppen @@ -15439,19 +15859,19 @@ Reported error: - - + + Search Suchen - + ID - + Search ID Kennung suchen @@ -15461,7 +15881,7 @@ Reported error: - + Show Items @@ -15662,19 +16082,19 @@ at least one peer was not added to a group - + Error Fehler - + File is not writeable! Datei ist nicht schreibbar! - + File is not readable! Datei ist nicht lesbar! @@ -15712,9 +16132,13 @@ at least one peer was not added to a group NewsFeed - Log entries - Protokolleinträge + Protokolleinträge + + + + Activity Stream + @@ -15731,7 +16155,7 @@ at least one peer was not added to a group Dies ist ein Test. - + Newest on top Neueste oben @@ -15742,20 +16166,39 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log - Protokoll + Protokoll + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15792,22 +16235,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room Chatraum - + Systray Icon Systray Icon - + Message Nachricht @@ -15832,9 +16275,13 @@ at least one peer was not added to a group IP-Sicherheit - Log - Protokoll + Protokoll + + + + Activity + @@ -15884,7 +16331,12 @@ at least one peer was not added to a group Gruppenchat - + + Toaster position + + + + Chat rooms Chaträume @@ -15893,22 +16345,22 @@ at least one peer was not added to a group Chaträume - + Position Position - + X Margin Abstand X - + Y Margin Abstand Y - + Systray message Nachricht im Systemabschnitt @@ -15958,7 +16410,7 @@ at least one peer was not added to a group Meldungen - + Disable All Toasters Alle Hinweise deaktivieren @@ -15972,7 +16424,7 @@ at least one peer was not added to a group Neuigkeiten - + Systray Benachrichtigungsfeld @@ -16118,17 +16570,16 @@ Minimalmodus: 10% vom Standarddatenaufkommen und (unfertig) pausiert alle Datei PGPKeyDialog - Dialog - Dialog + Dialog - + Profile info Profilinfo - + Name : Name : @@ -16183,22 +16634,21 @@ Minimalmodus: 10% vom Standarddatenaufkommen und (unfertig) pausiert alle Datei Ultimativ - + This profile has signed your own profile key - Key signatures : - Schlüsselsignaturen : + Schlüsselsignaturen : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -16212,7 +16662,7 @@ p, li { white-space: pre-wrap; } Diesen Schlüssel signieren - + PGP key PGP-Schlüssel @@ -16222,22 +16672,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - PGP-Schlüssel unterzeichnen + PGP-Schlüssel unterzeichnen - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16257,7 +16701,7 @@ p, li { white-space: pre-wrap; } Verbindungen annehmen - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16323,28 +16767,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Fehler: Kann Nachbardetails nicht ermitteln. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Der angegebene Schlüsselalgorithmus wird von RetroShare nicht unterstützt. (Im Moment werden nur RSA-Schlüssel unterstützt) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16356,7 +16800,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Das Vertrauensniveau drückt dein eigenes Vertrauen in diesen Schlüssel aus. Es wird weder von der Software genutzt noch geteilt, kann aber zum Merken guter bzw. schlechter Schlüssel nützlich sein. @@ -16401,27 +16845,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du erlaubst momentan keine mit diesem Schlüssel signierte Verbindungen von RetroShare-Netzknoten. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Signaturfehler - - Maybe password is wrong - Vielleicht ist das Passwort falsch + + Check the password! + - + Maybe password is wrong + Vielleicht ist das Passwort falsch + + + You haven't set a trust level for this key. Sie haben für diesen Schlüssel kein Vertrauensniveau festgelegt. - + + Retroshare profile RetroShare-Profil - + This is your own PGP key, and it is signed by : Dies ist dein eigener PGP-Schlüssel und er wurde signiert von: @@ -16600,8 +17064,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Leute @@ -16618,7 +17081,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Intern - + Chat with this person Mit dieser Person chatten @@ -16765,7 +17228,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel TextLabel @@ -16809,8 +17272,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Kommentare @@ -16845,6 +17308,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Schreibe einen Kommentar... + + + Album + Album + PhotoItem @@ -16854,12 +17322,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formular - + TextLabel TextLabel - + <!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; } @@ -16955,7 +17423,7 @@ p, li { white-space: pre-wrap; } Foto ansehen - + PhotoShare Fotofreigabe @@ -16996,7 +17464,7 @@ kannst musst du eines auswählen! - + Stop Stop @@ -17224,12 +17692,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Alle Plug-ins erlauben - + Plugin look-up directories Plug-in Ordner @@ -17279,7 +17747,7 @@ schützt dich aber eine Ãœberprüfung des Prüfsumme vor schädlichem Verhalten von Plug-ins. - + Plugins Plug-ins @@ -17661,7 +18129,7 @@ schädlichem Verhalten von Plug-ins. Andere Themen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17832,13 +18300,13 @@ schädlichem Verhalten von Plug-ins. Site - - + + Comments Kommentare - + Copy RetroShare Link RetroShare-Link kopieren @@ -17848,7 +18316,7 @@ schädlichem Verhalten von Plug-ins. - + Comment Kommentar @@ -17869,12 +18337,12 @@ schädlichem Verhalten von Plug-ins. - + Hide Verbergen - + Vote up Daumen hoch @@ -17888,7 +18356,7 @@ schädlichem Verhalten von Plug-ins. \/ - + Set as read and remove item Als gelesen markieren und Eintrag entfernen @@ -17949,7 +18417,7 @@ schädlichem Verhalten von Plug-ins. TextLabel - + Loading Lade @@ -18039,13 +18507,7 @@ schädlichem Verhalten von Plug-ins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18055,60 +18517,50 @@ schädlichem Verhalten von Plug-ins. Administrator: - - - + + + unknown unbekannt - + Distribution: Verteilung: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Beiträge @@ -18119,7 +18571,7 @@ schädlichem Verhalten von Plug-ins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18188,7 +18640,12 @@ schädlichem Verhalten von Plug-ins. - + + Empty + + + + Copy RetroShare Link RetroShare-Link kopieren @@ -18223,7 +18680,7 @@ schädlichem Verhalten von Plug-ins. - + [No name] @@ -18347,8 +18804,18 @@ schädlichem Verhalten von Plug-ins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18620,9 +19087,8 @@ und den Import zum Laden verwenden PulseAddDialog - Post From: - Beitrag von: + Beitrag von: Account 1 @@ -18637,7 +19103,7 @@ und den Import zum Laden verwenden Konto 3 - + Add to Pulse Zu Puls hinzufügen @@ -18660,17 +19126,32 @@ und den Import zum Laden verwenden URL - + GroupLabel - + IDLabel - + + From: + Von: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18695,10 +19176,20 @@ und den Import zum Laden verwenden Negativ - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18708,14 +19199,53 @@ und den Import zum Laden verwenden - + + Post + + + + Cancel Abbrechen - Post Pulse to Wire - Puls an Wire senden + Puls an Wire senden + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18741,10 +19271,18 @@ und den Import zum Laden verwenden Formular - - - - + + + + + Click to view picture + + + + + + + Image Bild @@ -18752,44 +19290,44 @@ und den Import zum Laden verwenden PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18799,17 +19337,17 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18819,7 +19357,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18827,7 +19365,7 @@ und den Import zum Laden verwenden PulseTopLevel - + retweeted @@ -18842,7 +19380,7 @@ und den Import zum Laden verwenden - + follow Parent Group @@ -18852,7 +19390,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18877,7 +19415,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18913,29 +19451,29 @@ und den Import zum Laden verwenden - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19013,7 +19551,7 @@ und den Import zum Laden verwenden QObject - + Confirmation Bestätigung @@ -19255,7 +19793,7 @@ Die Zeichen <b>",|,/,\,&lt;,&gt;,*,?</b> werden durch & Ergebnis - + Unable to make path Konnte Ordner nicht erstellen @@ -19290,7 +19828,7 @@ Die Zeichen <b>",|,/,\,&lt;,&gt;,*,?</b> werden durch & Dateianforderung abgebrochen - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Diese Version von RetroShare benutzt das OpenPGP-SDK. Der Schlüsselring des Systems wird nicht mehr verwendet, sondern ein eigener Schlüsselring für alle laufenden Instanzen.<br><br>Du scheinst keinen solchen Schlüsselring zu besitzen, obwohl Schlüssel von existierenden RetroShare-Accounts benötigt werden. Vielleicht hast du auch gerade zu dieser Version gewechselt. @@ -19433,7 +19971,7 @@ Der gemeldete Fehler ist: s - + TR up TR rauf @@ -19478,7 +20016,7 @@ Der gemeldete Fehler ist: deaktivert - + Move IP %1 to whitelist IP %1 in Whitelist verschieben @@ -19494,7 +20032,7 @@ Der gemeldete Fehler ist: - + %1 seconds ago Vor %1 Sekunden @@ -19579,7 +20117,7 @@ Sicherheit: keine anonymen Kennungen - + Error Fehler @@ -19970,9 +20508,8 @@ Sicherheit: keine anonymen Kennungen - <p>This certificate contains: - <p>Dieses Zertifikat enthält: + <p>Dieses Zertifikat enthält: @@ -20347,7 +20884,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KiB @@ -20569,19 +21106,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Baumansichtoptionen - Show column... - Spalte anzeigen... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … + + + + Show column... + Spalte anzeigen... - [no title] - [kein Titel] + [kein Titel] @@ -21017,7 +21583,7 @@ p, li { white-space: pre-wrap; } Herunterladen - + File Datei @@ -21032,7 +21598,7 @@ p, li { white-space: pre-wrap; } Prüfsumme - + Bad filenames have been cleaned Fehlerhafte Dateinamen wurden bereinigt @@ -21082,7 +21648,7 @@ Die betroffenen Dateien sind rot markiert Speichern - + Collection Editor Kollektionseditor @@ -21097,7 +21663,7 @@ Die betroffenen Dateien sind rot markiert Anzahl Dateien - + Real Size: Waiting child... Echte Größe: Warte auf Kind... @@ -21112,12 +21678,12 @@ Die betroffenen Dateien sind rot markiert Dies ist ein Verzeichnis. Doppelklicke, um es aufzuklappen. - + Download files - + Specify... @@ -21366,7 +21932,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil RsFriendListModel - + Name Name @@ -21386,7 +21952,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil IP - + Profile ID @@ -21399,10 +21965,15 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil RsGxsForumModel - + Title Titel + + + UnRead + + Date @@ -21414,7 +21985,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil Autor - + Information for this identity is currently missing. @@ -21452,7 +22023,7 @@ prevents the message to be forwarded to your friends. [Unbekannt] - + [ ... Missing Message ... ] [ ... Fehlende Nachricht ... ] @@ -21460,7 +22031,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21520,7 +22091,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21879,7 +22450,7 @@ prevents the message to be forwarded to your friends. Dateiname - + Download Herunterladen @@ -21958,7 +22529,7 @@ prevents the message to be forwarded to your friends. Ordner öffnen - + Create Collection... Kollektion erstellen... @@ -21978,7 +22549,7 @@ prevents the message to be forwarded to your friends. Von Kollektion herunterladen... - + Collection Kollektion @@ -22083,12 +22654,12 @@ prevents the message to be forwarded to your friends. Nachbardetails - + Deny friend Freund blockieren - + Chat Chat @@ -22098,7 +22669,7 @@ prevents the message to be forwarded to your friends. Chat starten - + Expand Erweitern @@ -22368,13 +22939,13 @@ Es hilft auch, wenn du dich hinter einer Firewall/VPN befindest. Discovery Ein (empfohlen) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Discovery Aus @@ -22840,7 +23411,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Netzwerk @@ -22868,7 +23439,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22965,7 +23536,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Dienstadresse @@ -23000,12 +23571,12 @@ If you have issues connecting over Tor check the Tor logs too. Bitte geben Sie eine Dienstadresse ein - + IP Range IP-Bereich - + Reported by DHT for IP masquerading Von DHT für IP-Maskierung gemeldet @@ -23673,7 +24244,7 @@ p, li { white-space: pre-wrap; } Fehlendes PGP-Zertifikat - + Wrong password Falsches Passwort @@ -23727,7 +24298,7 @@ Du kannst die Auswahl in den Optionen zurücksetzen. StatisticsWindow - + Add Friend Freund hinzufügen @@ -23783,7 +24354,7 @@ Du kannst die Auswahl in den Optionen zurücksetzen. Serviceberechtigungsmatrix - + DHT DHT @@ -24323,7 +24894,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24333,13 +24904,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24348,6 +24918,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24621,35 +25216,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Du hast %1 fertige Downloads + You have %1 completed transfers + - You have %1 completed download - Du hast %1 fertigen Download + You have %1 completed transfer + - %1 completed downloads - %1 fertige Downloads + %1 completed transfers + - %1 completed download - %1 fertiger Download + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Du hast %1 fertige Downloads + + + You have %1 completed download + Du hast %1 fertigen Download + + + %1 completed downloads + %1 fertige Downloads + + + %1 completed download + %1 fertiger Download TransfersDialog - + Downloads Downloads @@ -24660,7 +25266,7 @@ p, li { white-space: pre-wrap; } Uploads - + Name i.e: file name Name @@ -24867,7 +25473,7 @@ p, li { white-space: pre-wrap; } Spezifizieren... - + Move in Queue... In Warteschlange verschieben... @@ -24961,7 +25567,7 @@ p, li { white-space: pre-wrap; } Bitte gib einen neuen -- und gültigen -- Dateinamen ein - + Expand all Alle erweitern @@ -25093,7 +25699,7 @@ p, li { white-space: pre-wrap; } - + Columns Spalten @@ -25104,7 +25710,7 @@ p, li { white-space: pre-wrap; } Dateiübertragungen - + Path Pfad @@ -25114,7 +25720,7 @@ p, li { white-space: pre-wrap; } Pfadspalte anzeigen - + Could not delete preview file Konnte Vorschaudatei nicht löschen @@ -25124,7 +25730,7 @@ p, li { white-space: pre-wrap; } Nochmal versuchen? - + Create Collection... Kollektion erstellen... @@ -25139,7 +25745,7 @@ p, li { white-space: pre-wrap; } Kollektion ansehen... - + Collection Kollektion @@ -25385,7 +25991,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Unbekannter Nachbar @@ -25481,7 +26087,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Du hast %1 neue Nachrichten @@ -25861,7 +26467,7 @@ p, li { white-space: pre-wrap; } Gruppe erstellen - + Subscribe to Group Gruppe abonnieren @@ -25955,8 +26561,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Bearbeitungsverlauf anzeigen @@ -25967,7 +26573,7 @@ p, li { white-space: pre-wrap; } - + Preview Vorschau @@ -25992,12 +26598,12 @@ p, li { white-space: pre-wrap; } Bearbeitungsverlauf ausblenden - + Edit Page Seite bearbeiten - + Create New Wiki Page Neue Wiki-Seite erstellen @@ -26017,7 +26623,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Neue Wiki-Gruppe erstellen @@ -26059,7 +26665,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -26069,12 +26675,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh Aktualisieren @@ -26109,12 +26710,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26184,7 +26785,7 @@ p, li { white-space: pre-wrap; } Zeige: - + Yourself Du @@ -26222,7 +26823,7 @@ p, li { white-space: pre-wrap; } Puls an Wire senden - + RetroShare RetroShare @@ -26234,7 +26835,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26242,7 +26843,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26323,8 +26924,8 @@ p, li { white-space: pre-wrap; } Formular - - + + Avatar Avatar @@ -26353,6 +26954,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26465,8 +27071,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Bilder (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Bilder (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_el.ts b/retroshare-gui/src/lang/retroshare_el.ts index d8f599554..a334a32f9 100644 --- a/retroshare-gui/src/lang/retroshare_el.ts +++ b/retroshare-gui/src/lang/retroshare_el.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: ΣÏνθετη Αναζήτηση - + Search Criteria ΚÏιτήÏια αναζήτησης - + Add a further search criterion. ΠÏοσθήκη κÏιτηÏίου αναζήτησης @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; }⎠AlbumDialog - + Album Άλμπουμ @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; }⎠AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; }⎠ΦόÏμα - - + + TextLabel Ετικετα κειμενου @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } ΓÏαμμή εÏγαλείων - + Icon Only Μόνο εικόνα @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Επιλέξτε την εμφάνιση των πλήκτÏων των εÏγαλείων. - + Icon Size = 8x8 Μέγεθος εικόνας = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Μέγεθος Εικόνας = 128x128 - + Status Bar ΓÏαμμή κατάστασης @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Μέγεθος εικόνας = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Αλλαγή Î†Î²Î±Ï„Î±Ï - + + TextLabel + + + + Your Avatar Picture Η μικÏογÏαφία σας - + + Browse... + + + Add Avatar - ΠÏοσθήκη Î†Î²Î±Ï„Î±Ï + ΠÏοσθήκη Î†Î²Î±Ï„Î±Ï @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Μετακινηση - + Set your Avatar picture ΟÏισμός εικόνας Avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - ΜεταφόÏτωση μικÏογÏαφίας + ΜεταφόÏτωση μικÏογÏαφίας AvatarWidget - - Choose avatar - - - - + Click to change your avatar Πατηστε εδω για αλλαγη εικονιδιου @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare ΧÏήση εÏÏους ζώνης + + + PushButton + + - + Up + + + + + Down + Κάτω + + + + Clears the graph + + + + Show Settings Εμφανιση Ïυθμισεων + TextLabel + + + + Reset ΕπαναφοÏά - Receive Rate - Rate ελλειφθει + Rate ελλειφθει - Send Rate - Αποστολη Rate + Αποστολη Rate - + Always on Top Παντα μπÏοστα - Style - Στιλ + Στιλ - + Changes the transparency of the Bandwidth Graph Αλλαγη διαφανειας του ευÏυζωνικου γÏαφικου - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % Αδιαφανεια - Save - Αποθήκευση + Αποθήκευση - Cancel - Διακοπη + Διακοπη - + Since: Από: - Hide Settings - ΑπόκÏυψη Ïυθμίσεων + ΑπόκÏυψη Ïυθμίσεων BandwidthStatsWidget - + Sum ΆθÏοισμα @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } ΚαταμέτÏηση - + Average Μέσος ÏŒÏος @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Μου αÏέσει + + + + 0 + 0 + + + + I dislike this + Δεν μου αÏέσει + + + + Toggle Message Read Status + Αναγνωση καταστασης της εναλλαγης μυνηματος + + + + Avatar + Εικονιδιο + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + ΟÏισμος ως αναγνωσμένο και κατάÏγηση στοιχείου + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + ΠÏοεπιλογή + + + + Dark + + ChannelPage @@ -1380,6 +1505,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Μου αÏέσει + + + + 0 + 0 + + + + I dislike this + Δεν μου αÏέσει + + + + Toggle Message Read Status + Αναγνωση καταστασης της εναλλαγης μυνηματος + + + + Avatar + Εικονιδιο + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + ΟÏισμος ως αναγνωσμένο και κατάÏγηση στοιχείου + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1587,24 +1791,40 @@ into the image, so as to - You have %1 new messages - Έχετε %1 νέα μηνÏματα + Έχετε %1 νέα μηνÏματα + + + You have %1 new message + Έχετε %1 νέο μήνυμα + + + %1 new messages + %1 νέα μηνÏματα + + + %1 new message + %1 νέο μήνυμα + + + + You have %1 mentions + - You have %1 new message - Έχετε %1 νέο μήνυμα + You have %1 mention + - %1 new messages - %1 νέα μηνÏματα + %1 mentions + - %1 new message - %1 νέο μήνυμα + %1 mention + @@ -1617,11 +1837,6 @@ into the image, so as to Remove All ΑφαίÏεση Όλων - - - mention(s) - - ChatLobbyWidget @@ -2098,13 +2313,11 @@ Double click a chat room to enter and chat. - Group chat - Ομαδική συνομιλία + Ομαδική συνομιλία - - + Private chat Ιδιωτική συνομιλία @@ -2169,17 +2382,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2200,11 +2408,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2265,11 +2474,17 @@ Double click a chat room to enter and chat. + Broadcast Ραδιοφωνική μετάδοση - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Αποθηκευμένα μηνÏματα (0 = απεÏιόÏιστο): @@ -2416,8 +2631,23 @@ Double click a chat room to enter and chat. Ιδιωτική συνομιλία - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2586,7 +2816,7 @@ Double click a chat room to enter and chat. - + is typing... γÏάφει... @@ -2603,12 +2833,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Θέλετε Ï€Ïαγματικά να διαγÏάψετε το ιστοÏικό; @@ -2680,7 +2910,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>ΕÏÏεση ΠÏοηγοÏμενου </b><br/><i>Ctrl+Shift+G</i> @@ -2720,12 +2950,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Επισήμανση επιλεγμένου κειμένου</b><br><i>Ctrl+M</i> - + Person id: @@ -2741,7 +2971,7 @@ Double click on it to add his name on text writer. - + items found. στοιχεία βÏέθηκαν. @@ -2761,7 +2991,7 @@ Double click on it to add his name on text writer. ΠληκτÏολογείστε μήνυμα εδώ - + Don't stop to color after @@ -2919,12 +3149,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details ΛεπτομέÏειες - + Local Address Τοπική διεÏθυνση @@ -2935,12 +3165,12 @@ Double click on it to add his name on text writer. ΕξωτεÏική διεÏθυνση - + Node info: - + Current address: @@ -2956,31 +3186,36 @@ Double click on it to add his name on text writer. Υποδοχη - + Include signatures ΠεÏιλαμβάνουν υπογÏαφές - + RetroShare RetroShare - + - + Error : cannot get peer details. Σφάλμα: οι peer λεπτομέÏειες δεν μποÏουν να παÏθουν. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2996,22 +3231,22 @@ Double click on it to add his name on text writer. - + Encryption ΚÏυπτογÏάφηση - + Not connected Μη συνδεδεμένος - + Retroshare node details ΠληÏοφοÏίες κόμβου του Retroshare - + Node name : Όνομα κόμβου: @@ -3046,13 +3281,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3067,7 +3307,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3078,21 +3318,27 @@ Double click on it to add his name on text writer. κανένας + <p>This certificate contains: - <p>Αυτό το πιστοποιητικό πεÏιλαμβάνει: + <p>Αυτό το πιστοποιητικό πεÏιλαμβάνει: - + <li>a <b>node ID</b> and <b>name</b> <li>η <b>ταυτότητα του κόμβου</b> και <b>όνομα</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>ΜποÏείτε να χÏησιμοποιήσετε αυτό το πιστοποιητικό για να κάνετε νέους φίλους. Στείλτε το με email ή δώστε το σε αυτοÏÏ‚ αυτοπÏοσώπως.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3102,7 +3348,7 @@ Double click on it to add his name on text writer. - + with με @@ -3294,12 +3540,12 @@ Double click on it to add his name on text writer. ΛεπτομέÏειες σχετικά με το αίτημα - + Peer details Peer λεπτομέÏειες - + Name: Όνομα: @@ -3312,12 +3558,12 @@ Double click on it to add his name on text writer. Κόμβος: - + Location: Τοποθεσία: - + Options Επιλογές @@ -3326,12 +3572,12 @@ Double click on it to add his name on text writer. Εισάγεται το πιστοποιητικό χειÏονακτικός - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: ΠÏοσθηκη φίλου στην Ομάδα: @@ -3341,7 +3587,7 @@ Double click on it to add his name on text writer. Έλεγχος ταυτότητας φίλου (υπογÏαφη PGP κλειδίου) - + Please paste below your friend's Retroshare ID @@ -3366,7 +3612,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with ΠÏόσθηκη ως φίλο-για να συνδεθείτε με @@ -3375,7 +3621,7 @@ Double click on it to add his name on text writer. Για να αποδεχθείε την αίτηση του φίλου, πατήστε το πλαισιο Τέλος. - + Sorry, some error appeared Συγγνώμη, εμφανίστηκς κάποιο σφαλμα @@ -3395,32 +3641,32 @@ Double click on it to add his name on text writer. ΛεπτομέÏειες σχετικά με τον φίλο σας: - + Key validity: ΙσχÏÏ‚ κλειδιοÏ: - + Profile ID: - + Signers ΥπογÏάφοντες - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Αυτός ο ομότιμος είναι ήδη στην λιστα φιλων. ΠÏοσθέτοντας μποÏεί να Ïυθμιστεί μόνο η διεÏθυνση ip. - + To accept the Friend Request, click the Accept button. @@ -3466,7 +3712,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Η φοÏτωση του πιστοποιητικου απετυχε @@ -3499,12 +3745,12 @@ Double click on it to add his name on text writer. Peer id - + Not a valid Retroshare certificate! - + RetroShare Invitation ΠÏόσκληση RetroShare @@ -3524,12 +3770,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3577,7 +3823,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Έχετε ένα αίτημα φίλιας από - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3665,12 +3941,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Use as direct source, when available - + IP-Addr: - + IP-Address ΔιεÏθυνση IP @@ -3720,7 +3996,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3778,12 +4054,12 @@ even if you don't make friends. - + [Unknown] [Άγνωστο] - + Added with certificate from %1 @@ -3858,7 +4134,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -4280,7 +4561,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4428,7 +4709,7 @@ p, li { white-space: pre-wrap; } Δεν υπάÏχουν πεÏιοÏισμοί επιλεγμένου ΚÏκλου - + [Unknown] [Άγνωστο] @@ -4443,7 +4724,7 @@ p, li { white-space: pre-wrap; } ΑφαίÏεση - + Search Αναζητηση @@ -4459,7 +4740,7 @@ p, li { white-space: pre-wrap; } ΥπέγÏαψε - + Edit Circle ΕπεξεÏγασια κÏκλου @@ -4475,12 +4756,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4502,7 +4783,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4646,7 +4927,7 @@ p, li { white-space: pre-wrap; }⎠- + Attachments Συνημμένα @@ -4692,7 +4973,7 @@ p, li { white-space: pre-wrap; }⎠Drag and Drop τα αÏχεία από τα αποτελέσματα αναζήτησης - + Paste RetroShare Links Επικολλήση των Λινκ @@ -4702,7 +4983,7 @@ p, li { white-space: pre-wrap; }⎠Επικολληση του Λινκ - + Drop file error. Σφάλμα αÏχείου. @@ -4729,17 +5010,41 @@ p, li { white-space: pre-wrap; }⎠- + RetroShare RetroShare - - File already Added and Hashed - Το αÏχείο εχει Ï€Ïοσθέθει και κατακεÏματίζεται + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Το αÏχείο εχει Ï€Ïοσθέθει και κατακεÏματίζεται + + + Please add a Subject ΠαÏακαλείσθε να Ï€Ïοσθέσετε ένα θέμα @@ -4770,12 +5075,12 @@ p, li { white-space: pre-wrap; }⎠- + You are about to add files you're not actually sharing. Do you still want this to happen? Είστε έτοιμοι να Ï€Ïοσθέσετε τα αÏχεία που στην Ï€Ïαγματικότητα δεν μοιÏάζεστε. Είστε βέβαιοι ότι θέλετε να συμβεί αυτό; - + Edit Channel Post @@ -4795,7 +5100,7 @@ p, li { white-space: pre-wrap; }⎠- + About to post un-owned files to a channel. ΠεÏίπου για να τοποθετήθουν τα un-owned αÏχεία σε ένα κανάλι. @@ -4887,7 +5192,7 @@ p, li { white-space: pre-wrap; } - + No Forum Κανενα φόÏουμ @@ -5330,7 +5635,7 @@ and use the import button to load it DHTGraphSource - + users χÏήστες @@ -6333,7 +6638,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Καταλογοι φιλων @@ -6830,7 +7135,7 @@ at least one peer was not added to a group Αναζήτηση φίλων - + Mark all Επισημάνση όλων @@ -6844,7 +7149,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message ΕπεξεÏγασια μήνυματος κατάστασης @@ -6948,7 +7253,7 @@ at least one peer was not added to a group - + Network Δίκτυο @@ -7013,7 +7318,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7044,7 +7349,7 @@ at least one peer was not added to a group - + Node name @@ -7303,12 +7608,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7680,7 +7985,7 @@ p, li { white-space: pre-wrap; } Στατιστικά στοιχεία του δÏομολογητή - + GroupBox @@ -7745,7 +8050,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7768,7 +8073,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7969,7 +8274,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Τίτλος @@ -7979,13 +8284,30 @@ p, li { white-space: pre-wrap; } Αναζήτηση τίτλου - - + + + + Description ΠεÏιγÏαφή - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Αναζήτηση πεÏιγÏαφής @@ -7995,42 +8317,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Ταξινόμηση κατά όνομα + Ταξινόμηση κατά όνομα - Sort by Popularity - Ταξινόμηση κατά δημοτικότητα + Ταξινόμηση κατά δημοτικότητα - Sort by Last Post - Ταξινόμηση κατά το τελευταιο ποσταÏισμα + Ταξινόμηση κατά το τελευταιο ποσταÏισμα - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8045,40 +8344,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity Δημοτικότητα - - + + Never - Display - Εμφάνιση + Εμφάνιση - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8227,7 +8521,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Κανάλια @@ -8248,12 +8542,12 @@ p, li { white-space: pre-wrap; } Τα κανάλια μου - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels ΕγγεγÏαμμένα Κανάλια @@ -8722,7 +9016,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8822,12 +9116,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8838,18 +9132,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8859,12 +9153,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8924,7 +9218,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8939,12 +9233,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9020,23 +9314,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed ΕγγεγÏαμμένος - - Subscribe ΕγγÏαφη - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Δεν υπάÏχει επιλεγμένο κανάλι @@ -9058,11 +9365,6 @@ p, li { white-space: pre-wrap; } Channel Post ΠοσταÏισμα στο καναλι - - - new message(s) - - GxsCircleItem @@ -9571,7 +9873,7 @@ before you can comment ΈναÏξη νέας μηνυματοσειÏάς στο επιλεγμενο φόÏουμ - + Search forums Αναζήτηση στα φόÏουμ @@ -9580,12 +9882,12 @@ before you can comment Τελευταιο ποστ - + New Thread Îέο θεμα - + Threaded View ΠεÏασμένη κλωστή άποψη @@ -9595,19 +9897,19 @@ before you can comment Επίπεδη Ï€Ïοβολή - - + + Title Τίτλος - - + + Date ΗμεÏομηνία - + Author ΔημιουÏγος @@ -9622,7 +9924,17 @@ before you can comment ΦοÏτωση - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9679,23 +9991,23 @@ before you can comment Αναζήτηση πεÏιεχομένου - + No name Δεν υπάÏχει όνομα - - + + Reply Απάντηση - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9733,12 +10045,12 @@ before you can comment ΧαÏακτηÏισμός ως μη αναγνωσμένα - + Copy RetroShare Link ΑντιγÏαφη του Λινκ - + Hide ΑπόκÏυψη @@ -9747,7 +10059,7 @@ before you can comment Επεκταση - + [unknown] @@ -9777,8 +10089,8 @@ before you can comment - - + + Distribution @@ -9877,12 +10189,12 @@ before you can comment ΑÏχικό μήνυμα - + New thread - + Edit ΕπεξεÏγασία @@ -9938,7 +10250,7 @@ before you can comment - + Author's reputation @@ -9958,7 +10270,7 @@ before you can comment - + <b>Loading...<b> @@ -9998,6 +10310,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -10065,7 +10382,7 @@ This message is missing. You should receive it later. Στις % 1, %2 έγÏαψε: - + Forum name Όνομα φόÏουμ @@ -10097,11 +10414,6 @@ This message is missing. You should receive it later. Forum Post ΠοσταÏισμα στο φοÏουμ - - - new message(s) - - GxsForumsDialog @@ -10542,7 +10854,7 @@ This message is missing. You should receive it later. ΠÏοεπισκόπηση εκτÏπωσης - + Unsubscribe ΚαταÏγηση εγγÏαφης @@ -10557,7 +10869,7 @@ This message is missing. You should receive it later. Άνοιγμα σε νέα καÏτέλα - + Remove this search @@ -10567,12 +10879,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Εμφάνιση ΛεπτομεÏειών @@ -10639,12 +10951,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link ΑντιγÏαφή του RetroShare Συνδέσμου @@ -10659,7 +10971,7 @@ This message is missing. You should receive it later. Επισήμανση όλων ως μη αναγνωσμένων - + AUTHD AUTHD @@ -11185,7 +11497,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11194,7 +11506,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11220,7 +11532,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11300,49 +11612,55 @@ p, li { white-space: pre-wrap; }⎠- - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard ΑντιγÏάψετε σας Cert Ï€ÏόχειÏο @@ -11390,17 +11708,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11415,7 +11728,12 @@ new short format ΠÏόσκληση RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -11680,14 +11998,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Όλα - + Reputation Φήμη @@ -11697,12 +12015,12 @@ p, li { white-space: pre-wrap; } Αναζητηση - + Anonymous Id - + Create new Identity ΔημιουÏγια νέας ταυτότητας @@ -11846,7 +12164,7 @@ p, li { white-space: pre-wrap; } - + Send message Αποστολή μηνÏματος @@ -11918,7 +12236,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Ανώνυμος @@ -11933,24 +12251,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11965,7 +12283,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12024,13 +12342,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12090,7 +12413,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -12138,7 +12461,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12147,12 +12470,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12164,12 +12487,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12285,17 +12608,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12452,8 +12775,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12464,7 +12787,7 @@ These identities will soon be not supported anymore. Το Î¬Î²Î±Ï„Î¬Ï ÏƒÎ±Ï‚ - + Linked to neighbor nodes @@ -12474,7 +12797,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12534,7 +12857,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12544,7 +12867,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12582,7 +12905,7 @@ These identities will soon be not supported anymore. Ψευδώνυμο - + New identity Îέα ταυτότητα @@ -12599,14 +12922,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity ΕπεξεÏγασία Ταυτότητας @@ -12617,24 +12940,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12654,12 +12980,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12669,7 +13020,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12679,7 +13030,12 @@ These identities will soon be not supported anymore. Τυπος - + + Choose image... + + + + @@ -12719,12 +13075,7 @@ These identities will soon be not supported anymore. Το Î¬Î²Î±Ï„Î¬Ï ÏƒÎ±Ï‚ - - Set Avatar - - - - + Linked to your profile @@ -12734,7 +13085,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12839,8 +13190,12 @@ These identities will soon be not supported anymore. + Quote + Απόσπασμα + + Send - Αποστολη + Αποστολη @@ -12998,7 +13353,7 @@ These identities will soon be not supported anymore. - + Options Επιλογές @@ -13030,12 +13385,12 @@ These identities will soon be not supported anymore. Οδηγός γÏήγοÏης έναÏξης - + RetroShare %1 a secure decentralized communication platform Το RetroShare %1 ειναι μια πλατφόÏμα ασφαλοÏÏ‚ αποκεντÏωμένης επικοινωνίας - + Unfinished Ημιτελής @@ -13168,7 +13523,7 @@ These identities will soon be not supported anymore. Εμφανιση - + Make sure this link has not been forged to drag you to a malicious website. Βεβαιωθείτε ότι αυτή η σÏνδεση δεν σφυÏηλατήθηκε για να σας σÏÏει σε μια κακόβουλη ιστοσελίδα. @@ -13213,7 +13568,7 @@ These identities will soon be not supported anymore. - + Statistics Στατιστικές @@ -13242,7 +13597,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose Συνθέση @@ -13344,7 +13699,7 @@ These identities will soon be not supported anymore. - + Tags Ετικέτες @@ -13439,12 +13794,12 @@ These identities will soon be not supported anymore. ΠÏοσθέστε Blockquote - + Send To: Αποστολή σε: - + &Left &ΑÏιστεÏά @@ -13474,7 +13829,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Γεια σας, <br>θα ήθελα να σαςσυστήσω ένα καλό φίλο μου, μποÏείτε να τον εμπιστευθείτε πάÏα Ï€Î¿Î»Ï ÏŒÏ„Î±Î½ μποÏείτε και με εμπιστεÏεσται. <br> @@ -13500,12 +13860,12 @@ These identities will soon be not supported anymore. - + Save Message ΑποθηκεÏση μυνηματος - + Message has not been Sent. Do you want to save message to draft box? Μήνυμα δεν έχει σταλεί. @@ -13517,7 +13877,7 @@ Do you want to save message to draft box? Επικολληση του Λινκ - + Add to "To" ΠÏοσθηκη του "Σε" @@ -13772,7 +14132,7 @@ Do you want to save message ? ΠÏοσθηκη επιπλεον αÏχειου - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13786,6 +14146,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13798,7 +14173,7 @@ Do you want to save message ? Από: - + Bullet list (disc) @@ -13838,13 +14213,13 @@ Do you want to save message ? - - + + Thanks, <br> ΕυχαÏιστοÏμε, <br> - + Distant identity: @@ -13983,8 +14358,23 @@ Do you want to save message ? Μυνημα - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13996,12 +14386,12 @@ Do you want to save message ? Συνιστάμενα αÏχεία - + Download all Recommended Files Λυψη ολων των συνιστωμενων αÏχειων - + Subject: Θέμα: @@ -14076,12 +14466,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name Ονομα αÏχειου - + + Size Μεγεθος @@ -14142,18 +14538,33 @@ Do you want to save message ? Λυψη - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Λυψη ολων - + Print Document ΕκτÏπωση εγγÏάφου @@ -14168,7 +14579,7 @@ Do you want to save message ? ΑÏχεία HTML (*.htm * .html)??Όλα τα αÏχεία (*) - + Load images always for this message @@ -14309,7 +14720,7 @@ Do you want to save message ? MessagesDialog - + New Message Îέο μήνυμα @@ -14365,14 +14776,14 @@ Do you want to save message ? - + Tags Ετικέτες - + Inbox "ΕισεÏχόμενα" @@ -14467,7 +14878,7 @@ Do you want to save message ? Μήνυμα Ï€Ïος τα εμπÏός - + Subject Θέμα: @@ -14579,7 +14990,7 @@ Do you want to save message ? - + Open in a new window Άνοιγμα σε νέο παÏάθυÏο @@ -14664,7 +15075,7 @@ Do you want to save message ? - + Drafts Σχέδια @@ -14773,7 +15184,7 @@ Do you want to save message ? Μήνυμα απάντησης - + Delete Message ΔιαγÏαφή μηνÏματος @@ -14784,7 +15195,7 @@ Do you want to save message ? - + Expand Επεκταση @@ -14794,7 +15205,7 @@ Do you want to save message ? ΑπομακÏυνση στοιχειου - + from από @@ -14803,6 +15214,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15116,7 +15532,7 @@ Reported error: - + Groups Ομαδες @@ -15146,19 +15562,19 @@ Reported error: - - + + Search - + ID ID - + Search ID @@ -15168,7 +15584,7 @@ Reported error: - + Show Items @@ -15368,18 +15784,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! Το αÏχείο δεν είναι αναγνώσιμο! @@ -15418,7 +15834,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15436,7 +15852,7 @@ at least one peer was not added to a group Αυτό είναι μια δοκιμη. - + Newest on top @@ -15447,20 +15863,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15497,22 +15928,22 @@ at least one peer was not added to a group - + Test Δοκιμή - + Chat Room - + Systray Icon Εικονίδιο Systray - + Message Μυνημα @@ -15537,12 +15968,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Φίλος συνδεθηκε @@ -15589,27 +16015,37 @@ at least one peer was not added to a group Ομαδικη συνομιλια - + + Toaster position + + + + Chat rooms - + Position Θέση - + + Activity + + + + X Margin X πεÏιθώÏιο - + Y Margin Y πεÏιθώÏιο - + Systray message Μήνυμα Systray @@ -15659,7 +16095,7 @@ at least one peer was not added to a group Κοινοποιηση - + Disable All Toasters @@ -15673,7 +16109,7 @@ at least one peer was not added to a group Feed - + Systray @@ -15815,17 +16251,16 @@ Low Traffic: 10% standard traffic and TODO: pauses all file-transfers PGPKeyDialog - Dialog - Διαλόγος + Διαλόγος - + Profile info - + Name : Όνομα: @@ -15880,22 +16315,17 @@ Low Traffic: 10% standard traffic and TODO: pauses all file-transfersΤελικη - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15909,7 +16339,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15919,22 +16349,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - ΥπογÏαφη PGP κλειδίου + ΥπογÏαφη PGP κλειδίου - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15954,7 +16378,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16020,27 +16444,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Σφάλμα: οι peer λεπτομέÏειες δεν μποÏουν να παÏθουν. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Ο παÏεχόμενος αλγόÏιθμος ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î´ÎµÎ½ υποστηÏίζεται από το RetroShare⎠(κλειδιά RSA μόνο υποστηÏίζονται Ï€Ïος το παÏόν) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16052,7 +16476,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16097,27 +16521,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Αποτυχια υπογÏαφης - - Maybe password is wrong - Μαλλον ο κωδικος ειναι λαθος + + Check the password! + - + Maybe password is wrong + Μαλλον ο κωδικος ειναι λαθος + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16296,8 +16740,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16314,7 +16757,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16457,7 +16900,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.ΦωτογÏαφία - + TextLabel Ετικετα κειμενου @@ -16501,7 +16944,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -16537,6 +16980,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... ΓÏάψτε ένα σχόλιο... + + + Album + Άλμπουμ + PhotoItem @@ -16546,12 +16994,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.ΦοÏμα - + TextLabel Ετικετα κειμενου - + <!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; } @@ -16647,7 +17095,7 @@ p, li { white-space: pre-wrap; }⎠Εμφανιση φωτογÏαφιας - + PhotoShare PhotoShare @@ -16687,7 +17135,7 @@ requesting to edit it! - + Stop Παυση @@ -16915,12 +17363,12 @@ p, li { white-space: pre-wrap; }⎠PluginsPage - + Authorize all plugins ΕπιτÏέπουν όλα τα plugins - + Plugin look-up directories Plugin look-up καταλόγους @@ -16960,7 +17408,7 @@ malicious behavior of crafted plugins. Ελέγξτε αυτό για την ανάπτυξη των plugins. Αυτοί δεν θα ελεγχθεί για τον κατακεÏματισμό. Ωστόσο, υπό κανονικές συνθήκες, έλεγχος hash σας Ï€ÏοστατεÏει από κακόβουλη συμπεÏιφοÏά του δημιουÏγημένο plugins. - + Plugins Plugins @@ -17322,7 +17770,7 @@ malicious behavior of crafted plugins. Άλλα θέματα - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17481,13 +17929,13 @@ malicious behavior of crafted plugins. Τοποθεσία - - + + Comments Σχολια - + Copy RetroShare Link @@ -17497,7 +17945,7 @@ malicious behavior of crafted plugins. - + Comment Σχόλιο @@ -17518,12 +17966,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up @@ -17537,7 +17985,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item ΟÏισμος ως αναγνωσμένο και κατάÏγηση στοιχείου @@ -17598,7 +18046,7 @@ malicious behavior of crafted plugins. - + Loading ΦοÏτωση @@ -17680,13 +18128,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17696,60 +18138,50 @@ malicious behavior of crafted plugins. - - - + + + unknown Άγνωστο - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts ΔημοσιεÏσεις @@ -17760,7 +18192,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17829,7 +18261,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link @@ -17864,7 +18301,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -17984,8 +18421,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18253,9 +18700,8 @@ and use the import button to load it PulseAddDialog - Post From: - ΚαταχώÏηση από: + ΚαταχώÏηση από: Account 1 @@ -18270,7 +18716,7 @@ and use the import button to load it ΛογαÏιασμός 3 - + Add to Pulse ΠÏοσθηκη στο Pulse @@ -18293,17 +18739,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Από: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18328,10 +18789,20 @@ and use the import button to load it ΑÏνητικό - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18341,14 +18812,53 @@ and use the import button to load it - + + Post + + + + Cancel Διακοπη - Post Pulse to Wire - Θέση παλμό για σÏÏμα + Θέση παλμό για σÏÏμα + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18374,10 +18884,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image Εικόνα @@ -18385,44 +18903,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18432,17 +18950,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18452,7 +18970,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18460,7 +18978,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -18475,7 +18993,7 @@ and use the import button to load it - + follow Parent Group @@ -18485,7 +19003,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18510,7 +19028,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18546,29 +19064,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18646,7 +19164,7 @@ and use the import button to load it QObject - + Confirmation Επιβεβαίωση @@ -18887,7 +19405,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Αποτέλεσμα - + Unable to make path Δεν είναι δυνατή η διαδÏομή @@ -18922,7 +19440,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace ΑκυÏώθηκε η αίτηση αÏχειου - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Αυτή η έκδοση του RetroShare χÏησιμοποιεί το OpenPGP-SDK. Ως παÏενέÏγεια, δεν χÏησιμοποιεί το κοινό σÏστημα διαχείÏισης κλειδιών του PGP, αλλά έχει είναι δική ΜΠΡΕΛΟΚ συμμεÏίζονται όλες οι παÏουσίες RetroShare. <br><br>Δεν φαίνεται να έχουν ένα τέτοιο μπÏελόκ, αν και τα κλειδιά του PGP αναφέÏονται από τους υπάÏχοντες λογαÏιασμοÏÏ‚ eMule ομάδα + Ultra, πιθανώς επειδή έχετε αλλάξει μόνο σε αυτήν την νέα έκδοση του λογισμικοÏ. @@ -19062,7 +19580,7 @@ Reported error is: δευτεÏόλεπτα - + TR up @@ -19107,7 +19625,7 @@ Reported error is: απενεÏγοποιημένο - + Move IP %1 to whitelist @@ -19123,7 +19641,7 @@ Reported error is: - + %1 seconds ago %1 δευτεÏόλεπτα Ï€Ïιν @@ -19207,7 +19725,7 @@ Security: no anonymous IDs - + Error Σφάλμα @@ -19598,9 +20116,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Αυτό το πιστοποιητικό πεÏιλαμβάνει: + <p>Αυτό το πιστοποιητικό πεÏιλαμβάνει: @@ -19967,7 +20484,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20189,18 +20706,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20637,7 +21175,7 @@ p, li { white-space: pre-wrap; } Λυψη! - + File ΑÏχειο @@ -20652,7 +21190,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Τα κακα ονόματα αÏχείων έχουν εκκαθαÏιστεί @@ -20702,7 +21240,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Αποθηκευση - + Collection Editor @@ -20717,7 +21255,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -20732,12 +21270,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... ΚαθοÏίσμος... @@ -20984,7 +21522,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -21004,7 +21542,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -21017,10 +21555,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Τίτλος + + + UnRead + + Date @@ -21032,7 +21575,7 @@ If you believe it is correct, remove the corresponding line from the file and re ΔημιουÏγος - + Information for this identity is currently missing. @@ -21070,7 +21613,7 @@ prevents the message to be forwarded to your friends. [Άγνωστο] - + [ ... Missing Message ... ] [ ... Λείπει ενα μήνυμα...] @@ -21078,7 +21621,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date ΗμεÏομηνία @@ -21138,7 +21681,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21492,7 +22035,7 @@ prevents the message to be forwarded to your friends. Ονομα αÏχειου - + Download Λυψη @@ -21571,7 +22114,7 @@ prevents the message to be forwarded to your friends. Άνοιγμα Φακέλου - + Create Collection... ΔημιουÏγία Συλλογής ... @@ -21591,7 +22134,7 @@ prevents the message to be forwarded to your friends. Λυψη απο συλλογη αÏχειων... - + Collection Συλλογή @@ -21696,12 +22239,12 @@ prevents the message to be forwarded to your friends. Peer λεπτομέÏειες - + Deny friend ΑÏνησει φίλου - + Chat Συνομιλια @@ -21711,7 +22254,7 @@ prevents the message to be forwarded to your friends. ΕναÏξη συνομιλιας - + Expand Επεκταση @@ -21978,13 +22521,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22450,7 +22993,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Δίκτυο @@ -22478,7 +23021,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Κατασταση @@ -22575,7 +23118,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22610,12 +23153,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23280,7 +23823,7 @@ p, li { white-space: pre-wrap; } Λείπει το PGP πιστοποιητικό - + Wrong password @@ -23322,7 +23865,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend ΠÏοσθήκη φίλου @@ -23378,7 +23921,7 @@ This choice can be reverted in settings. - + DHT DHT @@ -23918,7 +24461,7 @@ p, li { white-space: pre-wrap; }⎠TorStatus - + Tor @@ -23928,13 +24471,12 @@ p, li { white-space: pre-wrap; }⎠- - + Tor is currently offline - + Tor is OK @@ -23943,6 +24485,31 @@ p, li { white-space: pre-wrap; }⎠No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24216,35 +24783,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Έχετε %1 ολοκληÏώμενη λυψη + You have %1 completed transfers + - You have %1 completed download - Η λήψη %1 ολοκληÏώθηκε + You have %1 completed transfer + - %1 completed downloads - %1 ολοκληÏώμενη λυψη + %1 completed transfers + - %1 completed download - %1 ολοκληÏώμενη λυψη + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Έχετε %1 ολοκληÏώμενη λυψη + + + You have %1 completed download + Η λήψη %1 ολοκληÏώθηκε + + + %1 completed downloads + %1 ολοκληÏώμενη λυψη + + + %1 completed download + %1 ολοκληÏώμενη λυψη TransfersDialog - + Downloads Λήψεις @@ -24255,7 +24833,7 @@ p, li { white-space: pre-wrap; } ΠÏοσθήκες - + Name i.e: file name Ονομα @@ -24462,7 +25040,7 @@ p, li { white-space: pre-wrap; } ΚαθοÏίσμος... - + Move in Queue... Μετακίνηση στην ουÏά... @@ -24556,7 +25134,7 @@ p, li { white-space: pre-wrap; } ΠαÏακαλοÏμε εισάγετε ένα νέο--και έγκυÏο--όνομα αÏχείου - + Expand all Επεκταση ολων @@ -24688,7 +25266,7 @@ p, li { white-space: pre-wrap; } - + Columns Στήλες @@ -24699,7 +25277,7 @@ p, li { white-space: pre-wrap; } - + Path ΔιαδÏομή @@ -24709,7 +25287,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24719,7 +25297,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... ΔημιουÏγία Συλλογής ... @@ -24734,7 +25312,7 @@ p, li { white-space: pre-wrap; } Εμφάνιση Συλλογής ... - + Collection Συλλογή @@ -24976,7 +25554,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Άγνωστο Peer @@ -25072,7 +25650,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Έχετε %1 νεα μυνηματα @@ -25444,7 +26022,7 @@ p, li { white-space: pre-wrap; } ΔημιουÏγία ομάδας - + Subscribe to Group ΕγγÏαφείτε στην ομάδα @@ -25538,8 +26116,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Εμφανιση ιστοÏικόυ @@ -25550,7 +26128,7 @@ p, li { white-space: pre-wrap; } - + Preview ΠÏοεπισκόπηση @@ -25575,12 +26153,12 @@ p, li { white-space: pre-wrap; } ΑπόκÏυψη ιστοÏικόυ - + Edit Page ΕπεξεÏγασια σελίδας - + Create New Wiki Page ΔημιουÏγία νέας σελίδας Wiki @@ -25600,7 +26178,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group ΔημιουÏγία νέας ομάδας Wiki @@ -25642,7 +26220,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -25652,12 +26230,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Ανανέωση @@ -25692,12 +26269,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25767,7 +26344,7 @@ p, li { white-space: pre-wrap; } Εμφανιση: - + Yourself τον εαυτό σας @@ -25805,7 +26382,7 @@ p, li { white-space: pre-wrap; } Θέση παλμό για σÏÏμα - + RetroShare RetroShare @@ -25817,7 +26394,7 @@ p, li { white-space: pre-wrap; } - + The Wire Το σÏÏμα @@ -25825,7 +26402,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25906,8 +26483,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar Εικονιδιο @@ -25936,6 +26513,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26048,8 +26630,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Εικόνες (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Εικόνες (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_en.ts b/retroshare-gui/src/lang/retroshare_en.ts index 9f848eea8..3b670aeaa 100644 --- a/retroshare-gui/src/lang/retroshare_en.ts +++ b/retroshare-gui/src/lang/retroshare_en.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: - + Location: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13794,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13806,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13884,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13964,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14049,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14138,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14149,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14159,7 @@ Do you want to save message ? - + from @@ -13829,6 +14168,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14472,7 @@ Reported error: - + Groups @@ -14158,19 +14502,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14524,7 @@ Reported error: - + Show Items @@ -14379,18 +14723,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14772,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14786,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14797,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14858,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14894,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14941,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15021,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15031,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15158,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15218,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15242,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15252,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15277,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15343,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15375,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15420,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15627,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15644,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15776,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15812,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15840,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15854,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15939,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15979,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16203,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16539,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16670,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16686,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16707,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16722,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16783,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16442,13 +16806,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16458,60 +16816,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16522,7 +16870,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16591,7 +16939,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16626,7 +16979,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16742,8 +17095,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17011,12 +17374,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17031,17 +17389,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17066,10 +17439,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17079,13 +17462,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17097,10 +17515,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17108,44 +17534,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17155,17 +17581,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17175,7 +17601,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17198,7 +17624,7 @@ and use the import button to load it - + follow Parent Group @@ -17208,7 +17634,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17233,7 +17659,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17269,29 +17695,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17369,7 +17795,7 @@ and use the import button to load it QObject - + Confirmation @@ -17608,7 +18034,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17643,7 +18069,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17781,7 +18207,7 @@ Reported error is: - + TR up @@ -17826,7 +18252,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17842,7 +18268,7 @@ Reported error is: - + %1 seconds ago @@ -17926,7 +18352,7 @@ Security: no anonymous IDs - + Error @@ -18316,11 +18742,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18654,7 +19075,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18876,18 +19297,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19324,7 +19766,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19339,7 +19781,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19387,7 +19829,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19402,7 +19844,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19417,12 +19859,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19669,7 +20111,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19689,7 +20131,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19702,10 +20144,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19717,7 +20164,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19755,7 +20202,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19763,7 +20210,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19823,7 +20270,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20177,7 +20624,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20256,7 +20703,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20276,7 +20723,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20381,12 +20828,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20396,7 +20843,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20659,13 +21106,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21131,7 +21578,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21159,7 +21606,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21256,7 +21703,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21291,12 +21738,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21961,7 +22408,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22003,7 +22450,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22059,7 +22506,7 @@ This choice can be reverted in settings. - + DHT @@ -22591,7 +23038,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22601,13 +23048,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22616,6 +23062,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22889,27 +23360,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22917,7 +23383,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22928,7 +23394,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23135,7 +23601,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23229,7 +23695,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23361,7 +23827,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23372,7 +23838,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23382,7 +23848,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23392,7 +23858,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23407,7 +23873,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23649,7 +24115,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23745,7 +24211,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24113,7 +24579,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24207,8 +24673,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24219,7 +24685,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24244,12 +24710,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24269,7 +24735,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24307,7 +24773,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24317,12 +24783,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24357,12 +24818,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24392,7 +24853,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24402,7 +24863,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24414,7 +24875,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24422,7 +24883,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24503,8 +24964,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24533,6 +24994,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24645,7 +25111,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_es.ts b/retroshare-gui/src/lang/retroshare_es.ts index f99b0a44f..3df49a47e 100644 --- a/retroshare-gui/src/lang/retroshare_es.ts +++ b/retroshare-gui/src/lang/retroshare_es.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Versión de RetroShare @@ -79,7 +79,7 @@ Que se divierta ;-) - + Only Hidden Node Sólo nodo oculto @@ -129,12 +129,12 @@ RetroShare: Búsqueda avanzada - + Search Criteria Criterios de búsqueda - + Add a further search criterion. Añadir un criterio de búsqueda adicional. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Ãlbum @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + TextLabel Texto de la etiqueta @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barra de herramientas - + Icon Only Sólo icono @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Elija el estilo de los botones de herramientas. - + Icon Size = 8x8 Tamaño de icono = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Tamaño de icono = 128x128 - + Status Bar Barra de estado @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Deshabilitar sugerencias en bandeja de sistema - + Main page items: Elementos de la página principal: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista de elementos - + Icon Size = 32x32 Tamaño de icono = 32x32 @@ -828,14 +828,23 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro Cambiar avatar - + + TextLabel + + + + Your Avatar Picture La imagen de su avatar - + + Browse... + + + Add Avatar - Añadir avatar + Añadir avatar @@ -843,25 +852,34 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro Eliminar - + Set your Avatar picture Establecer imagen de avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Cargar avatar + Cargar avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Pulse aquí para cambiar su avatar @@ -869,7 +887,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro RetroShare Bandwidth Usage Ancho de banda usado por RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostrar ajustes + TextLabel + + + + Reset Reinicializar - Receive Rate - Tasa de recepción + Tasa de recepción - Send Rate - Tasa de envío + Tasa de envío - + Always on Top Siempre encima - Style - Estilo + Estilo - + Changes the transparency of the Bandwidth Graph Cambia la transparencia de la gráfica de tráfico de red - + 100 100 @@ -936,30 +975,27 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro % Transparencia - Save - Guardar + Guardar - Cancel - Cancelar + Cancelar - + Since: Desde: - Hide Settings - Ocultar ajustes + Ocultar ajustes BandwidthStatsWidget - + Sum Agregado @@ -981,7 +1017,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro Recuento - + Average Media @@ -1115,7 +1151,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro - + Comments Comentarios @@ -1193,6 +1229,85 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro + + BoardsCommentsItem + + + I like this + Esto me gusta + + + + 0 + 0 + + + + I dislike this + Esto no me gusta + + + + Toggle Message Read Status + Cambiar el estado de lectura del mensaje + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copiar enlace de RetroShare + + + + + Expand + + + + + Set as read and remove item + Ajustar como leer y eliminar elemento + + + + Remove Item + + + + + Name + Nombre + + + + Comm value + + + + + Comment + Comentario + + + + Comments + Comentarios + + + + Hide + Ocultar + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Pero recuerde: Todos los datos aquí *SE PERDERÃN* cuando se actualicen los pro Log scale Escala logarítmica + + + Default + + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Esto me gusta + + + + 0 + 0 + + + + I dislike this + Esto no me gusta + + + + Toggle Message Read Status + Cambiar el estado de lectura del mensaje + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copiar enlace de RetroShare + + + + + Expand + + + + + Set as read and remove item + Ajustar como leer y eliminar elemento + + + + Remove Item + + + + + Name + Nombre + + + + Comm value + + + + + Comment + Comentario + + + + Comments + Comentarios + + + + Hide + Ocultar + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chats - You have %1 new messages - Tiene %1 nuevos mensajes + Tiene %1 nuevos mensajes + + + You have %1 new message + Tiene %1 nuevo mensaje + + + %1 new messages + %1 nuevos mensajes + + + %1 new message + %1 nuevo mensaje + + + + You have %1 mentions + - You have %1 new message - Tiene %1 nuevo mensaje + You have %1 mention + - %1 new messages - %1 nuevos mensajes + %1 mentions + - %1 new message - %1 nuevo mensaje + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Borrar todo - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Haga doble clic en una sala de chat para entrar y conversar. Variante: - Group chat - Chat en grupo + Chat en grupo - - + Private chat Chat privado @@ -2191,17 +2404,16 @@ Haga doble clic en una sala de chat para entrar y conversar. /me está enviando un mensaje con /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">En esta pestaña puedes configurar cuantos mensajes guardará en disco RetroShare y cuantas conversaciones previas mostrará para los distintos sistemas de chateo. El periodo máximo de almacenado permite eliminar mensajes viejos y evita que el historial de chateo se llene de conversaciones intrascendentes (salas de chateo y chateo distante)</p></body></html> - Chatlobbies - Salasdechat + Salasdechat - + Enabled: Habilitar: @@ -2222,11 +2434,12 @@ Haga doble clic en una sala de chat para entrar y conversar. + Chat rooms Salas de chat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Márquelo, si las apariciones de la identidad y el texto anterior deben coincidir en mayúsculas y minúsculas para incrementar el recuento. @@ -2287,11 +2500,17 @@ Haga doble clic en una sala de chat para entrar y conversar. + Broadcast Difusión - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Mensajes guardados (0 = ilimitados): @@ -2438,8 +2657,23 @@ Haga doble clic en una sala de chat para entrar y conversar. Chat privado - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Haga doble clic en una sala de chat para entrar y conversar. - + is typing... está escribiendo... @@ -2631,12 +2865,12 @@ after HTML conversion. %1 caracteres tras la conversión a HTML. - + Choose your font. Escoja su fuente. - + Do you really want to physically delete the history? ¿Seguro que quiere borrar el historial? @@ -2708,7 +2942,7 @@ after HTML conversion. No detenerse a colorear después de que X elementos se encontrasen (necesita más CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Buscar anterior</b><br/><i>Ctrl+Mayús+G</i> @@ -2748,12 +2982,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marcar este texto seleccionado</b><br><i>Ctrl+M</i> - + Person id: Identificación persona: @@ -2770,7 +3004,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.No firmado - + items found. elementos encontrados. @@ -2790,7 +3024,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Escriba un mensaje aquí - + Don't stop to color after No parar de colorear tras @@ -2948,12 +3182,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto. ConfCertDialog - + Details Detalles - + Local Address Dirección local @@ -2964,12 +3198,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Dirección externa - + Node info: Información de nodo: - + Current address: Dirección actual: @@ -2985,31 +3219,36 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Puerto - + Include signatures Incluir firmas - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: No se pueden obtener los detalles del vecino. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Cifrado - + Not connected No conectado - + Retroshare node details Detalles del nodo RetroShare - + Node name : Nombre del nodo : @@ -3075,13 +3319,18 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Mensaje de estado: - + + Connectivity + + + + List of known addresses: Lista de direcciones conocidas: - - + + Retroshare Certificate Certificado de RetroShare @@ -3096,7 +3345,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto. - + Hidden Address Dirección oculta @@ -3107,11 +3356,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.ninguno + <p>This certificate contains: - <p>Este certificado contiene: + <p>Este certificado contiene: - + <li>a <b>node ID</b> and <b>name</b> <li>una <b>identificación de nodo</b> y <b>nombre</b> @@ -3124,12 +3374,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.una <b>dirección IP</b> y <b>puerto</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Puede usar este certificado para hacer nuevos amigos. Envíelo por correo electrónico, o proporciónelo en mano.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Este es el certificado <span style=" font-weight:600;">OpenSSL</span> de la identificación (ID) del nodo, que está firmada por la clave <span style=" font-weight:600;">PGP</span> de arriba. </p></body></html> @@ -3139,7 +3389,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.<html><head/><body><p>Este es el método de cifrado usado por <span style=" font-weight:600;">OpenSSL</span>. La conexión a nodos amigos</p><p>siempre se cifra fuertemente, y si está presente el DHE (intercambio de claves Diffie-Hellman)</p><p>la conexión además usa &quot;secreto perfecto hacia delante&quot; (perfect forward secrecy).</p></body></html> - + with con @@ -3345,12 +3595,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Detalles de la solicitud - + Peer details Detalles del vecino - + Name: Nombre: @@ -3369,12 +3619,12 @@ resources. recursos. - + Location: Lugar: - + Options Opciones @@ -3411,12 +3661,12 @@ recursos. Pegar certificado - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Este recuadro espera el certificado de RetroShare de su amigo. ADVERTENCIA: Este es distinto de la clave del perfil de su amigo. No pegue aquí la clave del perfil de su amigo (ni siquiera una parte de ella). No va a funcionar.</p></body></html> - + Add friend to group: Añadir amigo a grupo: @@ -3426,7 +3676,7 @@ recursos. Autenticar amigo (firmar la clave PGP) - + Please paste below your friend's Retroshare ID @@ -3451,7 +3701,7 @@ recursos. - + Add as friend to connect with Añadir como amigo al conectarse con @@ -3460,7 +3710,7 @@ recursos. Para aceptar la solicitud de amigo, pulse en el botón Finalizar. - + Sorry, some error appeared Lo siento, ha ocurrido un error @@ -3480,32 +3730,32 @@ recursos. Detalles acerca de su amigo: - + Key validity: Validez de la clave: - + Profile ID: - + Signers Firmantes - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo a sus otros amigos. Las firmas de debajo atestiguan criptográficamente que los titulares de las claves listadas reconocen como auténtica la clave PGP actual.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Este vecino ya está en su lista de amigos. Añadiendolo sólo podrá establecer su dirección ip. - + To accept the Friend Request, click the Accept button. @@ -3551,7 +3801,7 @@ recursos. - + Certificate Load Failed Error al cargar el certificado @@ -3588,12 +3838,12 @@ recursos. El certificado parece ser válido - + Not a valid Retroshare certificate! ¡No es un certificado RetroShare válido! - + RetroShare Invitation Invitación de RetroShare @@ -3615,12 +3865,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? ¿Este es su propio certificado? No querría hacerse amigo de si mismo. ¿No es así? - + @@ -3668,7 +3918,37 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Tiene una solicitud de amistad de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3756,12 +4036,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Utilizar como fuente directa, cuando esté disponible - + IP-Addr: Dir-IP: - + IP-Address Dirección-IP @@ -3827,7 +4107,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Añadir al grupo de claves ('keyring') - + This key is already in your keyring Esta clave ya está en su grupo de claves ('keyring') @@ -3888,12 +4168,12 @@ incluso si no hace amigos. <p>Este certificado no tiene IP. Dependerá del descubrimiento y la DHT (tabla distribuida de hashes) para encontrarlo. A causa de que usted requiere que se limpie la lista blanca, el vecino generará una advertencia de seguridad en la pestaña de Novedades (feed). Desde allí puede añadir su IP a la lista blanca.</p> - + [Unknown] - + Added with certificate from %1 Añadido con el certificado de %1 @@ -3980,7 +4260,12 @@ incluso si no hace amigos. Resultado UDP - + + Status + Estado + + + <!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; } @@ -4410,7 +4695,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4562,7 +4847,7 @@ p, li { white-space: pre-wrap; } No hay limitaciones en el círculo seleccionado - + [Unknown] @@ -4577,7 +4862,7 @@ p, li { white-space: pre-wrap; } Eliminar - + Search Buscar @@ -4597,7 +4882,7 @@ p, li { white-space: pre-wrap; } Firmado por nodos conocidos - + Edit Circle Editar círculo @@ -4617,12 +4902,12 @@ p, li { white-space: pre-wrap; } Identidad anónima - + Circle name Nombre del círculo - + Update Actualizar @@ -4648,7 +4933,7 @@ p, li { white-space: pre-wrap; } Identidad vinculada a PGP - + Add Member Añadir miembro @@ -4792,7 +5077,7 @@ p, li { white-space: pre-wrap; } - + Attachments Adjuntos @@ -4838,7 +5123,7 @@ p, li { white-space: pre-wrap; } Arrastrar y soltar archivos de los resultados de la búsqueda - + Paste RetroShare Links Pegar enlaces de RetroShare @@ -4848,7 +5133,7 @@ p, li { white-space: pre-wrap; } Pegar enlace de RetroShare - + Drop file error. Error al arrastrar. @@ -4875,17 +5160,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Archivo ya añadido y hash generado + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Archivo ya añadido y hash generado + + + Please add a Subject Por favor, añada un asunto @@ -4916,12 +5225,12 @@ p, li { white-space: pre-wrap; } ¿De veras quiere generar %1 mensajes? - + You are about to add files you're not actually sharing. Do you still want this to happen? Está a punto de añadir archivos que actualmente no está compartiendo. ¿Seguro que quiere continuar? - + Edit Channel Post Editar mensaje del canal @@ -4941,7 +5250,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Está a punto de publicar archivos sin dueño en un canal. @@ -5033,7 +5342,7 @@ p, li { white-space: pre-wrap; } - + No Forum Ningún foro @@ -5493,7 +5802,7 @@ y utilizar el botón Importar para cargarla DHTGraphSource - + users usuarios @@ -6500,7 +6809,7 @@ y utilizar el botón Importar para cargarla FlatStyle_RDM - + Friends Directories Carpetas de amigos @@ -7006,7 +7315,7 @@ al menos un vecino no fue añadido al grupo Buscar a amigos - + Mark all Marcar todo @@ -7020,7 +7329,7 @@ al menos un vecino no fue añadido al grupo FriendsDialog - + Edit status message Editar mensaje de estado @@ -7124,7 +7433,7 @@ al menos un vecino no fue añadido al grupo Chat de difusión de RetroShare: Los mensajes se envían a todos los amigos conectados. - + Network Red @@ -7189,7 +7498,7 @@ al menos un vecino no fue añadido al grupo Se requiere que el campo del nodo tenga un mínimo de 3 caracteres - + Failed to generate your new certificate, maybe PGP password is wrong! ¡Fallo al generar su nuevo certificado, quizá la contraseña PGP está mal! @@ -7232,7 +7541,7 @@ al menos un vecino no fue añadido al grupo Usar perfil existente - + Node name Nombre del nodo @@ -7499,12 +7808,12 @@ y usar el botón Importar para cargarlo - + Profile generation failure Fallo al generar perfil - + Missing PGP certificate Certificado PGP desaparecido @@ -7923,7 +8232,7 @@ p, li { white-space: pre-wrap; } Estadísticas del router - + GroupBox GroupBox @@ -7988,7 +8297,7 @@ p, li { white-space: pre-wrap; } Factor de ramificado - + Details Detalles @@ -8011,7 +8320,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Claves administradas @@ -8220,7 +8529,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Título @@ -8230,13 +8539,30 @@ p, li { white-space: pre-wrap; } Buscar por el título - - + + + + Description Descripción - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Buscar por la descripción @@ -8246,42 +8572,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Ordenar en orden descendente + Ordenar en orden descendente - Sort Ascending Order - Ordenar en orden ascendente + Ordenar en orden ascendente - Sort by Name - Ordenar por nombre + Ordenar por nombre - Sort by Popularity - Ordenar por popularidad + Ordenar por popularidad - Sort by Last Post - Ordenar por última entrada + Ordenar por última entrada - Sort by Number of Posts - Ordenar por número de mensajes + Ordenar por número de mensajes - Sort by Unread - Ordenar por no leídos + Ordenar por no leídos - + You are admin (modify names and description using Edit menu) Usted es administrador (modifique nombres y descripciones usando el menú Editar) @@ -8296,40 +8615,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post Última publicación - + + Name Nombre - - Unread - - - - + Popularity Popularidad - - + + Never Nunca - Display - Mostrar + Mostrar - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8478,7 +8792,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Canales @@ -8503,12 +8817,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Canales</h1> <p>Los canales le permiten publicar datos (ej. películas, música) que se diseminarán por la red</p> <p>Puede ver los canales a los que están suscritos sus amigos, y reenviar automáticamente los canales a los que esté suscrito a sus amigos. Esto promueve buenos canales en la red.</p> <p>Sólo el creador del canal puede publicar en ese canal. Otros vecinos en la red sólo pueden leer de él, a no ser que el canal sea privado. Sin embargo, puede compartir los derechos de publicación o lectura con nodos RetroShare amigos.</p> <p>Los canales pueden hacerse anónimos, o ligados a una identidad de RetroShare de forma que los lectores puedan contactar con usted si lo necesitan. Habilite "Permitir comentarios" si quiere permitir a los usuarios comentar en sus posts.</p> <p>Los posts de canal se conservan durante %1 días, y se sincronizan para los últimos %2 días, a menos que cambie esto.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canales suscritos @@ -9033,7 +9347,7 @@ p, li { white-space: pre-wrap; } - + Add new post Añadir nuevo mensaje @@ -9133,12 +9447,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Comentarios @@ -9149,18 +9463,18 @@ p, li { white-space: pre-wrap; } - + Feeds Novedades (feeds) - - + + Click to switch to list view - + Show unread posts only @@ -9170,12 +9484,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9235,7 +9549,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9250,12 +9564,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9331,23 +9645,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Suscrito - - Subscribe Suscribirse - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Ningún canal seleccionado @@ -9369,11 +9696,6 @@ p, li { white-space: pre-wrap; } Channel Post Mensaje al canal - - - new message(s) - - GxsCircleItem @@ -9902,7 +10224,7 @@ before you can comment Iniciar nuevo tema para el foro seleccionado - + Search forums Buscar foros @@ -9911,12 +10233,12 @@ before you can comment Último mensaje - + New Thread Nuevo hilo - + Threaded View Vista por discusión @@ -9926,19 +10248,19 @@ before you can comment Vista plana - - + + Title Título - - + + Date Fecha - + Author Autor @@ -9953,7 +10275,17 @@ before you can comment Cargando - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10014,23 +10346,23 @@ before you can comment <p>Suscribiendose al foro reunirá los posts disponibles de los amigos a los que esté suscrito, y hará el foro visible al resto de sus amigos.</p><p>Posteriormente puede desuscribirse desde el menú contextual de la lista del foro a la izquierda.</p> - + No name Sin nombre - - + + Reply Responder - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10068,12 +10400,12 @@ before you can comment Marcar como no leído - + Copy RetroShare Link Copiar enlace de RetroShare - + Hide Ocultar @@ -10086,7 +10418,7 @@ before you can comment [Excluido] - + [unknown] [desconocido] @@ -10116,8 +10448,8 @@ before you can comment Sólo para sus ojos - - + + Distribution Distribución @@ -10220,7 +10552,7 @@ before you can comment Mensaje original - + New thread Nuevo hilo @@ -10229,7 +10561,7 @@ before you can comment Estado de lectura - + Edit Editar @@ -10285,7 +10617,7 @@ before you can comment Mostrar autor en la pestaña Personas - + Author's reputation Reputación del autor @@ -10305,7 +10637,7 @@ before you can comment - + <b>Loading...<b> @@ -10345,6 +10677,11 @@ before you can comment Storage Almacenamiento + + + Last seen at friends: + + Moderators @@ -10439,7 +10776,7 @@ reenviado a sus amigos. En %1, %2 escribió: - + Forum name Nombre del foro @@ -10471,11 +10808,6 @@ reenviado a sus amigos. Forum Post Mensaje al foro - - - new message(s) - - GxsForumsDialog @@ -10924,7 +11256,7 @@ reenviado a sus amigos. Vista previa de impresión - + Unsubscribe Anular suscripción @@ -10939,7 +11271,7 @@ reenviado a sus amigos. Abrir en una nueva pestaña - + Remove this search @@ -10949,12 +11281,12 @@ reenviado a sus amigos. - + Request data - + Show Details Mostrar detalles @@ -11021,7 +11353,7 @@ reenviado a sus amigos. - + Search for @@ -11030,7 +11362,7 @@ reenviado a sus amigos. Compartir permisos de publicación - + Copy RetroShare Link Copiar enlace de RetroShare @@ -11045,7 +11377,7 @@ reenviado a sus amigos. Marcar todo como no leído - + AUTHD Autentificado @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11671,7 +12003,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11697,6 +12029,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11708,7 +12057,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11784,27 +12133,32 @@ p, li { white-space: pre-wrap; } Formulario - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11826,6 +12180,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11834,7 +12189,7 @@ p, li { white-space: pre-wrap; } El texto de debajo es su propio certificado de RetroShare. Envíeselo a sus amigos - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11850,12 +12205,12 @@ de código abierto, multi-sistema, privada y segura. ¿Necesita ayuda con RetroShare? - + Open Web Help Ayuda de Open Web - + Copy your Cert to Clipboard Copiar su certificado al portapapeles @@ -11904,7 +12259,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11913,7 +12268,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12206,14 +12561,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Todo - + Reputation Reputación @@ -12223,12 +12578,12 @@ p, li { white-space: pre-wrap; } Buscar - + Anonymous Id ID anónima - + Create new Identity Crear nueva identidad @@ -12372,7 +12727,7 @@ p, li { white-space: pre-wrap; } Identificación de la identidad - + Send message Enviar mensaje @@ -12464,7 +12819,7 @@ p, li { white-space: pre-wrap; } Global: - + Anonymous Anónimo @@ -12479,24 +12834,24 @@ p, li { white-space: pre-wrap; } Buscar identificación - + This identity is owned by you Esta identidad es propiedad de usted - - + + My own identities Mis propias identidades - - + + My contacts Mis contactos - + Show Items Mostrar elementos @@ -12511,7 +12866,7 @@ p, li { white-space: pre-wrap; } Enlazado a mi nodo - + Other circles Otros círculos @@ -12570,13 +12925,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). suscrito (recibe/reenvía peticiones de membresía de otros y recibe la lista de invitaciones). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). no suscrito (sólo recibe la lista de invitaciones). - + Your status: Su estatus: @@ -12636,7 +12996,7 @@ p, li { white-space: pre-wrap; } Miembro - + Edit Circle Editar círculo @@ -12684,7 +13044,7 @@ p, li { white-space: pre-wrap; } Conceder membresía - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12696,12 +13056,12 @@ Estas identidades pronto dejarán de estar soportadas. - + [Unknown node] [Nodo desconocido] - + Unverified signature from node Firma del nodo no verificada @@ -12713,12 +13073,12 @@ Estas identidades pronto dejarán de estar soportadas. Firma no comprobada - + [unverified] [no verificada] - + Identity owned by you, linked to your Retroshare node Identidad propiedad de usted, asociada a su nodo RetroShare @@ -12842,12 +13202,12 @@ Estas identidades pronto dejarán de estar soportadas. ¿Está seguro de que quiere enviar una invitación con su certificado? - + Banned Excluido - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identidades</h1> <p>En esta pestaña puede crear/editar <b>identidades pseudo-anónimas</b>, y <b>círculos</b>.</p> <p>Las <b>identidades</b> se usan para identificar sus datos de forma segura: firmar mensajes en salas de chat, foros y posts en canales, recibir comentarios usando el sistema de correo electrónico integrado de RetroShare, comentarios publicados tras los posts en los canales, chat usando túneles seguros, etc.</p> <p>Las identidades opcionalmente pueden estar <b>firmadas</b> por el certificado de su nodo RetroShare. Es más fácil confiar en las identidades firmadas pero son más fácilmente vinvulables con la dirección IP de su nodo.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> @@ -12856,7 +13216,7 @@ Estas identidades pronto dejarán de estar soportadas. Identidad desconocida: - + positive positivo @@ -13041,8 +13401,8 @@ Estas identidades pronto dejarán de estar soportadas. - - + + People Personas @@ -13053,7 +13413,7 @@ Estas identidades pronto dejarán de estar soportadas. Su avatar - + Linked to neighbor nodes Enlazado hacia nodos vecinos @@ -13063,7 +13423,7 @@ Estas identidades pronto dejarán de estar soportadas. Enlazado hacia nodos distantes - + Linked to a friend Retroshare node Enlazado hacia un nodo de RetroShare amigo @@ -13123,7 +13483,7 @@ Estas identidades pronto dejarán de estar soportadas. Propiedad de - + Node name: Nombre del nodo: @@ -13133,7 +13493,7 @@ Estas identidades pronto dejarán de estar soportadas. Identificación del nodo: - + Really delete? ¿Está seguro de borrar? @@ -13171,7 +13531,22 @@ Estas identidades pronto dejarán de estar soportadas. Seudónimo - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nueva identidad @@ -13188,14 +13563,14 @@ Estas identidades pronto dejarán de estar soportadas. - + N/A N/A - + Edit identity Editar identidad @@ -13206,24 +13581,27 @@ Estas identidades pronto dejarán de estar soportadas. Actualizar - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13242,17 +13620,27 @@ Estas identidades pronto dejarán de estar soportadas. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! ¡Error al obtener la clave! - + Error KeyID invalid Error, ID de la clave no válida - + Unknown GpgId ID PGP desconocida @@ -13262,7 +13650,7 @@ Estas identidades pronto dejarán de estar soportadas. Nombre real desconocido - + Create New Identity Crear nueva identidad @@ -13272,7 +13660,12 @@ Estas identidades pronto dejarán de estar soportadas. Tipo - + + Choose image... + + + + @@ -13312,12 +13705,11 @@ Estas identidades pronto dejarán de estar soportadas. Su avatar - Set Avatar - Establecer avatar + Establecer avatar - + Linked to your profile Enlazado a su perfil @@ -13327,7 +13719,7 @@ Estas identidades pronto dejarán de estar soportadas. Puede tener una o más identidades. Se usan cuando escribe un salas de chat, foros y comentarios de canales. Actúan como el destinatario para conversaciones distantes y el sistema de correo distante de RetroShare. - + The nickname is too short. Please input at least %1 characters. El apodo es demasiado corto. Por favor, introduzca al menos %1 caracteres. @@ -13436,8 +13828,12 @@ Estas identidades pronto dejarán de estar soportadas. + Quote + Citar + + Send - Enviar + Enviar @@ -13595,7 +13991,7 @@ Estas identidades pronto dejarán de estar soportadas. - + Options Opciones @@ -13627,12 +14023,12 @@ Estas identidades pronto dejarán de estar soportadas. Asistente para el inicio rápido - + RetroShare %1 a secure decentralized communication platform RetroShare %1 es una plataforma de comunicación descentralizada y segura - + Unfinished Incompleto @@ -13765,7 +14161,7 @@ Estas identidades pronto dejarán de estar soportadas. Mostrar - + Make sure this link has not been forged to drag you to a malicious website. Asegúrese de que este enlace no ha sido falsificado para arrastrarle a un sitio web malicioso. @@ -13810,7 +14206,7 @@ Estas identidades pronto dejarán de estar soportadas. Matriz de permisos del servicio - + Statistics Estadísticas @@ -13839,7 +14235,7 @@ Estas identidades pronto dejarán de estar soportadas. MessageComposer - + Compose Componer @@ -13941,7 +14337,7 @@ Estas identidades pronto dejarán de estar soportadas. - + Tags Etiquetas @@ -14036,12 +14432,12 @@ Estas identidades pronto dejarán de estar soportadas. Añadir cita - + Send To: Enviar a: - + &Left &Izquierda @@ -14075,7 +14471,7 @@ Estas identidades pronto dejarán de estar soportadas. Mis contactos - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hola,<br>Le recomiendo a un buen amigo mío, puede confiar en él tanto como confía en mí. <br> @@ -14101,12 +14497,12 @@ Estas identidades pronto dejarán de estar soportadas. - + Save Message Guardar mensaje - + Message has not been Sent. Do you want to save message to draft box? El mensaje no se ha enviado. @@ -14118,7 +14514,7 @@ Do you want to save message to draft box? Pegar enlace de RetroShare - + Add to "To" Añadir a "A" @@ -14373,7 +14769,7 @@ Do you want to save message ? Añadir otro archivo - + Hi,<br>I want to be friends with you on RetroShare.<br> Hola,<br>quiero establecer amistad contigo en RetroShare.<br> @@ -14382,12 +14778,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Tiene una invitación de amistad. - + Respond now: Responder ahora: @@ -14403,11 +14814,12 @@ Do you want to save message ? De: + Friend Nodes - Nodos amigos + Nodos amigos - + Bullet list (disc) Lista con puntos (discos) @@ -14447,13 +14859,13 @@ Do you want to save message ? Lista ordenada (números romanos en mayúscula) - - + + Thanks, <br> Gracias, <br> - + Distant identity: Identidad distante: @@ -14592,8 +15004,23 @@ Do you want to save message ? Mensaje - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14605,12 +15032,12 @@ Do you want to save message ? Archivos recomendados - + Download all Recommended Files Descargar todos los archivos recomendados - + Subject: Asunto: @@ -14685,12 +15112,18 @@ Do you want to save message ? Enviar invitación - + + Message Size: + + + + File Name Nombre de archivo - + + Size Tamaño @@ -14751,10 +15184,25 @@ Do you want to save message ? Descargar - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? ¿Enviar invitación? @@ -14765,12 +15213,12 @@ Do you want to save message ? - + Download all Dercargar todo - + Print Document Imprimir documento @@ -14785,7 +15233,7 @@ Do you want to save message ? Archivos HTML (*.htm *.html);;Todos los archivos(*) - + Load images always for this message Cargar siempre imágenes para este mensaje @@ -14926,7 +15374,7 @@ Do you want to save message ? MessagesDialog - + New Message Nuevo mensaje @@ -14982,14 +15430,14 @@ Do you want to save message ? - + Tags Etiquetas - + Inbox Bandeja de entrada @@ -15084,7 +15532,7 @@ Do you want to save message ? Reenviar mensaje - + Subject Asunto @@ -15196,7 +15644,7 @@ Do you want to save message ? - + Open in a new window Abrir en una ventana nueva @@ -15281,7 +15729,7 @@ Do you want to save message ? - + Drafts Borradores @@ -15410,7 +15858,7 @@ Do you want to save message ? Responder a mensaje - + Delete Message Borrar mensaje @@ -15421,7 +15869,7 @@ Do you want to save message ? - + Expand Abrir @@ -15431,7 +15879,7 @@ Do you want to save message ? Quitar objeto - + from de @@ -15440,6 +15888,11 @@ Do you want to save message ? Reply to invite Responder a la invitación + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15762,7 +16215,7 @@ Se informo del error: - + Groups Grupos @@ -15792,19 +16245,19 @@ Se informo del error: importar su lista de amigos incluyendo grupos - - + + Search Buscar - + ID - + Search ID @@ -15814,7 +16267,7 @@ Se informo del error: - + Show Items Mostrar elementos @@ -16018,19 +16471,19 @@ al menos un vecino no fue añadido al grupo - + Error Error - + File is not writeable! ¡El fichero no es escribible! - + File is not readable! ¡El fichero no es legible! @@ -16068,9 +16521,13 @@ al menos un vecino no fue añadido al grupo NewsFeed - Log entries - Entradas de registro (log) + Entradas de registro (log) + + + + Activity Stream + @@ -16087,7 +16544,7 @@ al menos un vecino no fue añadido al grupo Esto es una prueba. - + Newest on top Los más recientes arriba @@ -16098,20 +16555,43 @@ al menos un vecino no fue añadido al grupo + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Suscripción de noticias</h1> <p>La suscripción de registro (log feed) muestra los últimos eventos en su red, ordenados por la hora a la que los recibió. Esto le proporciona un compendio de la actividad de sus amigos. Puede configurar qué eventos mostrar pulsando en <b>Opciones</b>. </p> <p>Los distintos eventos mostrados son: <ul> <li>Intentos de conexión (útil para hacer amigos con nuevas personas y controlar quién está tratando de acceder a usted)</li> <li>Posts de canal y foro</li> <li>Nuevos canales y foros a los que puede suscribirse</li> <li>Mensajes privados de sus amigos</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Suscripción de noticias</h1> <p>La suscripción de registro (log feed) muestra los últimos eventos en su red, ordenados por la hora a la que los recibió. Esto le proporciona un compendio de la actividad de sus amigos. Puede configurar qué eventos mostrar pulsando en <b>Opciones</b>. </p> <p>Los distintos eventos mostrados son: <ul> <li>Intentos de conexión (útil para hacer amigos con nuevas personas y controlar quién está tratando de acceder a usted)</li> <li>Posts de canal y foro</li> <li>Nuevos canales y foros a los que puede suscribirse</li> <li>Mensajes privados de sus amigos</li> </ul> </p> + + + Log + Registro (log) - Log - Registro (log) + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16148,22 +16628,22 @@ al menos un vecino no fue añadido al grupo - + Test Prueba - + Chat Room Sala de chat - + Systray Icon Icono en la Bandeja de sistema - + Message Mensaje @@ -16188,12 +16668,11 @@ al menos un vecino no fue añadido al grupo Seguridad de la IP - Log - Registro (log) + Registro (log) - + Friend Connected Amigo conectado @@ -16207,7 +16686,12 @@ al menos un vecino no fue añadido al grupo Enlaces - + + Activity + + + + Mails Correos @@ -16244,7 +16728,12 @@ al menos un vecino no fue añadido al grupo Chat de grupo - + + Toaster position + + + + Chat rooms Salas de chat @@ -16269,22 +16758,22 @@ al menos un vecino no fue añadido al grupo Distingue mayúsculas y minúsculas - + Position Posición - + X Margin Distancia horizontal - + Y Margin Distancia vertical - + Systray message Mensaje en la bandeja del sistema @@ -16334,7 +16823,7 @@ al menos un vecino no fue añadido al grupo Notificación - + Disable All Toasters Deshabilitar todas las notitificaciones @@ -16348,7 +16837,7 @@ al menos un vecino no fue añadido al grupo Novedades (feed) - + Systray Bandeja del sistema @@ -16494,17 +16983,16 @@ Sin Anonimato D/S: desactiva el reenvío de archivos PGPKeyDialog - Dialog - Diálogo + Diálogo - + Profile info Información del perfil - + Name : Nombre : @@ -16559,22 +17047,21 @@ Sin Anonimato D/S: desactiva el reenvío de archivos Máxima - + This profile has signed your own profile key Este perfil ha firmado su propia clave del perfil - Key signatures : - Firmas de clave : + Firmas de clave : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este al resto de sus amigos. Las firmas de debajo atestiguan criptográficamente que los propietarios de las claves listadas reconocen la clave PGP actual como auténtica.</span></p></body></html> - + <!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; } @@ -16592,7 +17079,7 @@ p, li { white-space: pre-wrap; } Firmar esta clave - + PGP key Clave PGP @@ -16602,22 +17089,20 @@ p, li { white-space: pre-wrap; } Estas opciones se aplican a todos los nodos del perfil: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo al resto de sus amigos. Les ayuda a decidir si permitir conexiones desde esa clave en base a su propia confianza. Firmar una clave es absolutamente opcional y no puede deshacerse, así que hágalo con sabiduría.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo al resto de sus amigos. Les ayuda a decidir si permitir conexiones desde esa clave en base a su propia confianza. Firmar una clave es absolutamente opcional y no puede deshacerse, así que hágalo con sabiduría.</span></p></body></html> - + Keysigning: - Sign PGP key - Firmar clave PGP + Firmar clave PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Haga clic aquí si quiere rechazar conexiones a nodos autentificados por esta clave.</p></body></html> @@ -16637,7 +17122,7 @@ p, li { white-space: pre-wrap; } Aceptar conexiones - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Debajo tiene la clave del perfil del nodo en formato ASCII PGP. Identifica todos los nodos del mismo perfil. Un "certificado de RetroShare" que puede intercambiar para hacer amigos, está en los "detalles" de cada nodo individual. @@ -16707,28 +17192,28 @@ p, li { white-space: pre-wrap; } KB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: No se pueden obtener los detalles del vecino. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) El algoritmo de la clave proporcionada no está soportado por RetroShare (Sólo están soportadas las claves RSA por el momento) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16742,7 +17227,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. El nivel de confianza es una forma de expresar su propia confianza en esta clave. No es utilizado por la aplicación ni se comparte, pero puede serle útil para recordar buenas/malas claves. @@ -16787,27 +17272,47 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Actualmente no está permitiendo conexiones de nodos RetroShare firmadas por esta clave. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Error de firma - - Maybe password is wrong - Probablemente la contraseña es errónea + + Check the password! + - + Maybe password is wrong + Probablemente la contraseña es errónea + + + You haven't set a trust level for this key. No ha establecido una nivel de confianza para esta clave. - + + Retroshare profile Perfil de RetroShare - + This is your own PGP key, and it is signed by : Esta es su propia clave PGP, y está firmada por: @@ -16986,8 +17491,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc PeopleDialog - - + People Personas @@ -17004,7 +17508,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Interno - + Chat with this person Chatear con esta persona @@ -17155,7 +17659,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Fotografía - + TextLabel Texto de la etiqueta @@ -17199,8 +17703,8 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc - <N> Comments >> - + Comments + Comentarios @@ -17235,6 +17739,11 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Write a comment... Escribir un comentario... + + + Album + Ãlbum + PhotoItem @@ -17244,12 +17753,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Formulario - + TextLabel Texto de la etiqueta - + <!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; } @@ -17345,7 +17854,7 @@ p, li { white-space: pre-wrap; } Ver foto - + PhotoShare Compartir fotos @@ -17386,7 +17895,7 @@ solicitar editarlo! - + Stop Detener @@ -17614,12 +18123,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autorizar todos los plugins - + Plugin look-up directories Directorios de búsqueda de plugin @@ -17678,7 +18187,7 @@ de un posible comportamiento malicioso de los plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Complementos</h1> <p>Los complementos (plugins) se cargan desde los directorios que aparecen en la lista del fondo.</p> <p>Por razones de seguridad, los complementos aceptados se cargan automáticamente hasta que el ejecutable principal de RetroShare o la librería del complemento cambian. En tal caso, el usuario necesita confirmarlos de nuevo. Después de que se inicie el programa, puede habilitar un complemento manualmente haciendo clic en el botón "Habilitar", y luego reiniciar RetroShare.</p> <p>Si quiere desarrollar sus propios complementos, contacte con el equipo de desarrolladores ¡ellos estarán contentos de auxiliarle!</p> - + Plugins Plugins @@ -18076,7 +18585,7 @@ de un posible comportamiento malicioso de los plugins. Enlaces - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18247,13 +18756,13 @@ de un posible comportamiento malicioso de los plugins. Lugar - - + + Comments Comentarios - + Copy RetroShare Link Copiar enlace de RetroShare @@ -18263,7 +18772,7 @@ de un posible comportamiento malicioso de los plugins. Mostrar autor en la pestaña Personas - + Comment Comentario @@ -18284,12 +18793,12 @@ de un posible comportamiento malicioso de los plugins. - + Hide Ocultar - + Vote up Votar positivo @@ -18303,7 +18812,7 @@ de un posible comportamiento malicioso de los plugins. \/ - + Set as read and remove item Ajustar como leer y eliminar elemento @@ -18364,7 +18873,7 @@ de un posible comportamiento malicioso de los plugins. - + Loading Cargando @@ -18454,13 +18963,7 @@ de un posible comportamiento malicioso de los plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18470,60 +18973,50 @@ de un posible comportamiento malicioso de los plugins. Administrador: - - - + + + unknown desconocido - + Distribution: Distribución: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Posts @@ -18534,7 +19027,7 @@ de un posible comportamiento malicioso de los plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18603,7 +19096,12 @@ de un posible comportamiento malicioso de los plugins. - + + Empty + Vacío + + + Copy RetroShare Link Copiar enlace de RetroShare @@ -18638,7 +19136,7 @@ de un posible comportamiento malicioso de los plugins. - + [No name] @@ -18766,8 +19264,18 @@ de un posible comportamiento malicioso de los plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19047,9 +19555,8 @@ y utilizar el botón Importar para cargarla PulseAddDialog - Post From: - Entrada de: + Entrada de: Account 1 @@ -19064,7 +19571,7 @@ y utilizar el botón Importar para cargarla Cuenta 3 - + Add to Pulse Añadir a Pulse @@ -19087,17 +19594,32 @@ y utilizar el botón Importar para cargarla URL - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19122,10 +19644,20 @@ y utilizar el botón Importar para cargarla Negativo - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19135,14 +19667,53 @@ y utilizar el botón Importar para cargarla - + + Post + + + + Cancel Cancelar - Post Pulse to Wire - Mensaje de Pulso para Wire + Mensaje de Pulso para Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19168,10 +19739,18 @@ y utilizar el botón Importar para cargarla Formulario - - - - + + + + + Click to view picture + + + + + + + Image Imágen @@ -19179,44 +19758,44 @@ y utilizar el botón Importar para cargarla PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19226,17 +19805,17 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19246,7 +19825,7 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19254,7 +19833,7 @@ y utilizar el botón Importar para cargarla PulseTopLevel - + retweeted @@ -19269,7 +19848,7 @@ y utilizar el botón Importar para cargarla - + follow Parent Group @@ -19279,7 +19858,7 @@ y utilizar el botón Importar para cargarla ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19304,7 +19883,7 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19340,29 +19919,29 @@ y utilizar el botón Importar para cargarla - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19440,7 +20019,7 @@ y utilizar el botón Importar para cargarla QObject - + Confirmation Confirmación @@ -19681,7 +20260,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Resultado - + Unable to make path Incapaz de hacer la ruta @@ -19716,7 +20295,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Solicitud del archivo cancelada - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Esta versión de RetroShare está usando OpenPGP SDK. Como efecto secundario, no está utilizando el juego de claves PGP compartido por el sistema, pero tiene su propio juego de claves compartido por todas las instancias de RetroShare. <br><br>No parece que tenga tal juego de claves, aunque las claves PGP son mencionadas por cuentas existentes de RetroShare, probablemente debido a que acaba de cambiar a esta nueva versión del programa. @@ -19873,7 +20452,7 @@ El error reportado es: segs - + TR up Transferencia de subida @@ -19918,7 +20497,7 @@ El error reportado es: deshabilitado - + Move IP %1 to whitelist Mover IP %1 a la lista blanca @@ -19934,7 +20513,7 @@ El error reportado es: - + %1 seconds ago hace %1 segundos @@ -20019,7 +20598,7 @@ Seguridad: No hay identificaciones anónimas - + Error Error @@ -20410,9 +20989,8 @@ Seguridad: No hay identificaciones anónimas Haz clic para continuar con el proceso de hashing - <p>This certificate contains: - <p>Este certificado contiene: + <p>Este certificado contiene: @@ -20781,7 +21359,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -21003,19 +21581,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Opciones de vista de árbol - Show column... - Mostrar columna... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Ordenar en orden descendente + + + + Sort Ascending Order + Ordenar en orden ascendente + + + + + [no title] + + + + + Show column … + + + + Show column... + Mostrar columna... - [no title] - [sin título] + [sin título] @@ -21451,7 +22058,7 @@ p, li { white-space: pre-wrap; } ¡Descargar! - + File Archivo @@ -21466,7 +22073,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Se han limpiado los nombres de archivo inadecuados @@ -21514,7 +22121,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Guardar - + Collection Editor Editor de colección @@ -21529,7 +22136,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Recuento de archivos - + Real Size: Waiting child... Tamaño real: Esperando descendientes... @@ -21544,12 +22151,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Esto es un directorio. Haga doble-clic para expandirlo. - + Download files Descargar archivos - + Specify... Especificar... @@ -21798,7 +22405,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr RsFriendListModel - + Name Nombre @@ -21818,7 +22425,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr IP - + Profile ID @@ -21831,10 +22438,15 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr RsGxsForumModel - + Title Título + + + UnRead + + Date @@ -21846,7 +22458,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr Autor - + Information for this identity is currently missing. La información para esta identidad actualmente está desaparecida. @@ -21888,7 +22500,7 @@ reenviado a sus amigos. - + [ ... Missing Message ... ] [ ... Mensaje perdido ... ] @@ -21896,7 +22508,7 @@ reenviado a sus amigos. RsMessageModel - + Date Fecha @@ -21956,7 +22568,7 @@ reenviado a sus amigos. - + [Notification] @@ -22315,7 +22927,7 @@ en la red (siempre informar de archivos disponibles) Nombre de archivo - + Download Descargar @@ -22394,7 +23006,7 @@ en la red (siempre informar de archivos disponibles) Abrir carpeta - + Create Collection... Crear colección... @@ -22414,7 +23026,7 @@ en la red (siempre informar de archivos disponibles) Descargar desde archivo de colección... - + Collection Colección @@ -22519,12 +23131,12 @@ en la red (siempre informar de archivos disponibles) Detalles del vecino - + Deny friend Bloquear amigo - + Chat Chat @@ -22534,7 +23146,7 @@ en la red (siempre informar de archivos disponibles) Iniciar chat - + Expand Expandir @@ -22804,13 +23416,13 @@ behind a firewall or a VPN. Descubrimiento activado (recomendado) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor ha sido configurado automáticamente por Retroshare. No deberías necesitar cambiar nada aquí. - + Discovery Off Descubrimiento inactivo @@ -23304,7 +23916,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Network Red @@ -23332,7 +23944,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Status Estado @@ -23429,7 +24041,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Service Address Dirección del servicio @@ -23464,12 +24076,12 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs.Por favor, introduzca una dirección de servicio - + IP Range Rango de IPs - + Reported by DHT for IP masquerading Fue señalado por la DHT (tabla distribuida de hashes) para enmascaramiento de IP (IP masquerading) @@ -24145,7 +24757,7 @@ p, li { white-space: pre-wrap; } Falta el certificado PGP - + Wrong password ¡Contraseña errónea! @@ -24199,7 +24811,7 @@ Esta elección puede revertirse en la configuración. StatisticsWindow - + Add Friend Añadir a amigo @@ -24255,7 +24867,7 @@ Esta elección puede revertirse en la configuración. Matriz de permisos del servicio - + DHT DHT @@ -24795,7 +25407,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24809,13 +25421,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor está actualmente fuera de línea - + Tor is OK Tor está OK @@ -24824,6 +25435,31 @@ p, li { white-space: pre-wrap; } No tor configuration Sin configuración de Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25117,35 +25753,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Tiene %1 descargas completas + You have %1 completed transfers + - You have %1 completed download - Tiene %1 descarga completa + You have %1 completed transfer + - %1 completed downloads - %1 descargas completas + %1 completed transfers + - %1 completed download - %1 descarga completa + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Tiene %1 descargas completas + + + You have %1 completed download + Tiene %1 descarga completa + + + %1 completed downloads + %1 descargas completas + + + %1 completed download + %1 descarga completa TransfersDialog - + Downloads Descargas @@ -25156,7 +25803,7 @@ p, li { white-space: pre-wrap; } Enviando - + Name i.e: file name Nombre @@ -25367,7 +26014,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Transferencia de archivos</h1> <p>RetroShare tiene dos formas de transferir archivos: transferencias directas desde sus amigos, y transferencias distantes anónimas por túnel. Además, la transferencia de archivos es desde múltiples-fuentes y permite comportamiento de enjambre (puede ser fuente a la vez que descarga)</p> <p>Puede compartir archivos usando el <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> icono del lado izquierdo de la barra lateral. Estos archivos se listarán en la pestaña Mis Archivos. Puede decidir para cada grupo de amigos si pueden o no ver estos archivos en su pestaña de Archivos de Amigos</p> <p>La pestaña de búsqueda informa de archivos de las listas de archivos de sus amigos, y de archivos distantes que se pueden alcanzar de forma anónima usando la sistema de tunelización de múltiples-saltos.</p> - + Move in Queue... Mover en la lista de espera... @@ -25461,7 +26108,7 @@ p, li { white-space: pre-wrap; } Por favor, introduzca un nuevo - y válido - nombre de archivo - + Expand all Expandir todo @@ -25593,7 +26240,7 @@ p, li { white-space: pre-wrap; } - + Columns Columnas @@ -25604,7 +26251,7 @@ p, li { white-space: pre-wrap; } Transferencia de archivos - + Path Ruta @@ -25614,7 +26261,7 @@ p, li { white-space: pre-wrap; } Mostrar columna de ruta - + Could not delete preview file No se pudo borrar el archivo de vista previa @@ -25624,7 +26271,7 @@ p, li { white-space: pre-wrap; } ¿Intentarlo de nuevo? - + Create Collection... Crear colección... @@ -25639,7 +26286,7 @@ p, li { white-space: pre-wrap; } Ver colección... - + Collection Colección @@ -25885,7 +26532,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Vecino desconocido @@ -25981,7 +26628,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Tiene %1 nuevos mensajes @@ -26365,7 +27012,7 @@ p, li { white-space: pre-wrap; } Crear grupo - + Subscribe to Group Suscribirse al grupo @@ -26459,8 +27106,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Mostrar historial de ediciones @@ -26471,7 +27118,7 @@ p, li { white-space: pre-wrap; } - + Preview Vista previa @@ -26496,12 +27143,12 @@ p, li { white-space: pre-wrap; } Ocultar historial de ediciones - + Edit Page Editar página - + Create New Wiki Page Crear nueva página de la Wiki @@ -26521,7 +27168,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Crear nuevo grupo Wiki @@ -26563,7 +27210,7 @@ p, li { white-space: pre-wrap; } Intervalo de tiempo - + Create Account @@ -26573,12 +27220,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Refrescar @@ -26613,12 +27259,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26688,7 +27334,7 @@ p, li { white-space: pre-wrap; } Mostrando: - + Yourself Yo mismo @@ -26726,7 +27372,7 @@ p, li { white-space: pre-wrap; } Mensaje de Pulso para Wire - + RetroShare RetroShare @@ -26738,7 +27384,7 @@ p, li { white-space: pre-wrap; } - + The Wire Wire @@ -26746,7 +27392,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26827,8 +27473,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + Avatar Avatar @@ -26857,6 +27503,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26969,8 +27620,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Imágenes (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Imágenes (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_fi.ts b/retroshare-gui/src/lang/retroshare_fi.ts index 753dc6e63..4356c9860 100644 --- a/retroshare-gui/src/lang/retroshare_fi.ts +++ b/retroshare-gui/src/lang/retroshare_fi.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retrosharen versio @@ -79,7 +79,7 @@ Pidä hauskaa ;-) - + Only Hidden Node Ainoastaan piilotettu solmu @@ -128,12 +128,12 @@ Retroshare: tarkennettu haku - + Search Criteria Hakuehdot - + Add a further search criterion. Lisää hakuehto. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Albumi @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Lomake - - + + TextLabel Tekstiselite @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Työkalupalkki - + Icon Only Vain kuvakkeilla @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } Valitse työkalupainikkeiden tyyli. - + Icon Size = 8x8 Kuvakkeiden koko = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Kuvakkeiden koko = 128x128 - + Status Bar Tilarivi @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } Ota ilmaisinalueen työkaluvihje pois käytöstä - + Main page items: Pääsivun nimikkeet: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } Nimikeluettelo - + Icon Size = 32x32 Kuvakkeiden koko = 32x32 @@ -827,14 +827,23 @@ p, li { white-space: pre-wrap; } Vaihda avatar - + + TextLabel + + + + Your Avatar Picture Avatar-kuvasi - + + Browse... + + + Add Avatar - Lisää avatar + Lisää avatar @@ -842,25 +851,34 @@ p, li { white-space: pre-wrap; } Poista - + Set your Avatar picture Aseta avatarkuvasi - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Lataa avatar + Lataa avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Paina vaihtaaksesi avatarkuvasi @@ -868,7 +886,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s kt/s @@ -888,44 +906,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Retrosharen kaistanleveyden käyttö + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Näytä asetukset + TextLabel + + + + Reset Palauta asetukset - Receive Rate - Vastaanottonopeus + Vastaanottonopeus - Send Rate - Lähetysnopeus + Lähetysnopeus - + Always on Top Aina päällimmäisenä - Style - Tyyli + Tyyli - + Changes the transparency of the Bandwidth Graph Muuttaa siirtonopeuskuvaajan läpinäkyvyyttä - + 100 100 @@ -935,30 +974,27 @@ p, li { white-space: pre-wrap; } % näkyvä - Save - Tallenna + Tallenna - Cancel - Peru + Peru - + Since: Alkaen: - Hide Settings - Piilota asetukset + Piilota asetukset BandwidthStatsWidget - + Sum Summa @@ -980,7 +1016,7 @@ p, li { white-space: pre-wrap; } Lkm - + Average Keskiverto @@ -1114,7 +1150,7 @@ p, li { white-space: pre-wrap; } - + Comments Kommentit @@ -1192,6 +1228,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Pidän tästä + + + + 0 + 0 + + + + I dislike this + En pidä tästä + + + + Toggle Message Read Status + Vaihda viestin tila luetuksi tai päinvastoin + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopioi Retroshare-linkki + + + + + Expand + Laajenna + + + + Set as read and remove item + Merkitse luetuksi ja poista kohde + + + + Remove Item + Poista kohde + + + + Name + Nimi + + + + Comm value + + + + + Comment + Kommentti + + + + Comments + Kommentit + + + + Hide + Piilota + + BwCtrlWindow @@ -1327,6 +1442,16 @@ p, li { white-space: pre-wrap; } Log scale Lokin asteikko + + + Default + Oletus + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Pidän tästä + + + + 0 + 0 + + + + I dislike this + En pidä tästä + + + + Toggle Message Read Status + Vaihda viestin tila luetuksi tai päinvastoin + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopioi Retroshare-linkki + + + + + Expand + Laajenna + + + + Set as read and remove item + Merkitse luetuksi ja poista kohde + + + + Remove Item + Poista kohde + + + + Name + Nimi + + + + Comm value + + + + + Comment + Kommentti + + + + Comments + Kommentit + + + + Hide + Piilota + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to Keskustelut - You have %1 new messages - Sinulle on uusia viestejä %1 kpl + Sinulle on uusia viestejä %1 kpl + + + You have %1 new message + Sinulle on %1 uusi viesti + + + %1 new messages + %1 kpl uusia viestejä + + + %1 new message + %1 uusi viesti + + + + You have %1 mentions + - You have %1 new message - Sinulle on %1 uusi viesti + You have %1 mention + - %1 new messages - %1 kpl uusia viestejä + %1 mentions + - %1 new message - %1 uusi viesti + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Poista kaikki - - - mention(s) - - ChatLobbyWidget @@ -2119,13 +2334,11 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. Muunnelma: - Group chat - Ryhmäkeskustelu + Ryhmäkeskustelu - - + Private chat Yksityinen keskustelu @@ -2190,17 +2403,16 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. /me on lähettämässä viestiä /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Tässä välilehdessä voit määrittää, kuinka monta chat-viestiä Retroshare pitää tallennettuna kiintolevylle ja kuinka paljon edellisestä keskustelusta näytetään eri keskustelutoiminnoissa. Säilytyksen enimmäisaika mahdollistaa vanhojen viestien hävittämisen ja estää keskusteluhistorian täyttymisen (esim. keskusteluaulat ja etäiset keskustelut).</p></body></html> - Chatlobbies - Keskusteluaulat + Keskusteluaulat - + Enabled: Käytössä: @@ -2221,11 +2433,12 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. + Chat rooms Keskusteluhuoneet - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2286,11 +2499,17 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. + Broadcast Kuulutus - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Tallennettavien viestien lkm (0 = rajoittamaton): @@ -2437,8 +2656,23 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. Yksityinen keskustelu - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2607,7 +2841,7 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. - + is typing... kirjoittaa... @@ -2626,12 +2860,12 @@ after HTML conversion. iso HTML-muuntamisen jälkeen. - + Choose your font. Valitse kirjasin. - + Do you really want to physically delete the history? Haluatko todella tuhota historian pysyvästi? @@ -2703,7 +2937,7 @@ iso HTML-muuntamisen jälkeen. Älä lopeta värittämistä, kun X kohdetta löydetty (vaatii konetehoa) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Hae edellinen </b><br/><i>Ctrl+Shift+G</i> @@ -2743,12 +2977,12 @@ iso HTML-muuntamisen jälkeen. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Merkitse tämä valittu teksti</b><br><i>Ctrl+M</i> - + Person id: Henkilön tunniste: @@ -2765,7 +2999,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Allekirjoittamaton - + items found. Kohteita löytyi. @@ -2785,7 +3019,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Kirjoita viesti tähän - + Don't stop to color after Älä lopeta värittämistä jälkeen @@ -2943,12 +3177,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. ConfCertDialog - + Details Tiedot - + Local Address Paikallinen osoite @@ -2959,12 +3193,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Ulkoinen osoite - + Node info: Solmun tiedot: - + Current address: Nykyinen osoite: @@ -2980,31 +3214,36 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Portti - + Include signatures Sisällytä allekirjoitukset - + RetroShare Retroshare - + - + Error : cannot get peer details. Virhe: vertaisen yksityiskohtia ei saatu. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3020,22 +3259,27 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Salaus - + Not connected Ei yhteyttä - + Retroshare node details Retroshare solmun tiedot - + Node name : Solmun nimi: @@ -3070,13 +3314,18 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Tilaviesti: - + + Connectivity + + + + List of known addresses: Tunnetut osoitteet: - - + + Retroshare Certificate Retroshare varmenne @@ -3091,7 +3340,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. - + Hidden Address Piilotettu osoite @@ -3102,11 +3351,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.ei mitään + <p>This certificate contains: - <p>Tämä varmenne sisältää: + <p>Tämä varmenne sisältää: - + <li>a <b>node ID</b> and <b>name</b> <li> <b>solmun tunniste</b> ja <b>nimi</b> @@ -3119,12 +3369,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. <b>IP-osoite</b> ja <b>ja</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Voit käyttää tätä varmennetta luodaksesi uusia ystäviä. Lähetä se sähköpostitse tai anna se tavatessanne.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Tämä on solmun <span style=" font-weight:600;">OpenSSL</span> -varmenteen tunniste, joka on allekirjoitettu ylläolevalla <span style=" font-weight:600;">PGP</span> -avaimella. </p></body></html> @@ -3134,7 +3384,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.<html><head/><body><p>Tätä salaus-metodia käyttää <span style=" font-weight:600;">OpenSSL</span>. Yhteys ystäväsolmuihin</p><p>on aina vahvasti salattu ja jos DHE on läsnä yhteys edelleen käyttää</p><p>&quot;täydellistä forward secrecy-ominaisuutta&quot; (salausavaimen murtaminen ei johda aiemmin salattujen viestien tietoturvan vaarantumiseen).</p></body></html> - + with kanssa @@ -3340,12 +3590,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Tietoja pyynnöstä - + Peer details Vertaisen tiedot - + Name: Nimi: @@ -3364,12 +3614,12 @@ resources. resursseja. - + Location: Sijainti: - + Options Asetukset @@ -3406,12 +3656,12 @@ resursseja. Liitä varmenne - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Tämä laatikko vaatii sinun ystäväsi Retroshare-varmenteen. VAROITUS: se on erilainen, kuin ystäväsi profiiliavain. Älä liitä ystäväsi profiiliavainta tähän (edes osaa siitä). Se ei tule toimimaan.</p></body></html> - + Add friend to group: Lisää ystävä ryhmään: @@ -3421,7 +3671,7 @@ resursseja. Varmenna ystävä (allekirjoita PGP-avain) - + Please paste below your friend's Retroshare ID @@ -3446,7 +3696,7 @@ resursseja. - + Add as friend to connect with Lisää ystäväksi, johon otat yhteyden @@ -3455,7 +3705,7 @@ resursseja. Paina Valmis-painiketta hyväksyäksesi ystäväpyynnön - + Sorry, some error appeared Valitettavasti on tapahtunut jokin virhe @@ -3475,32 +3725,32 @@ resursseja. Tietoja ystävästäsi: - + Key validity: Avaimen kelpoisuus: - + Profile ID: - + Signers Allekirjoittajat - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Allekirjoitukset alla kryptograafisesti todistavat, että luettelon avaimien omistajat tunnistavat nykyisen PGP-avaimen aidoksi.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Tämä vertainen on jo ystäväluettelossasi. Hänen lisäämisensä saattaa ainoastaan määrittää uuden IP-osoitteen. - + To accept the Friend Request, click the Accept button. @@ -3546,7 +3796,7 @@ resursseja. - + Certificate Load Failed Varmenteen lataus epäonnistui @@ -3583,12 +3833,12 @@ resursseja. Varmenne näyttää olevan kelvollinen - + Not a valid Retroshare certificate! Ei kelvollinen Retroshare-varmenne! - + RetroShare Invitation Retroshare-kutsu @@ -3610,12 +3860,12 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Tämä on oma varmenteesi! Et haluaisi olla oma ystäväsi. Ethän? - + @@ -3663,7 +3913,37 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Sinulle on ystäväpyyntö, lähettäjä - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3751,12 +4031,12 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Käytä suorana lähteenä, kun saatavilla - + IP-Addr: IP-osoite: - + IP-Address IP-osoite: @@ -3822,7 +4102,7 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Lisää avain avainnippuun - + This key is already in your keyring Tämä avain on jo avainnipussasi @@ -3883,12 +4163,12 @@ vaikkette ystävystyisikään. <p>Varmenteessa ei ole IP-osoitetta. Etsintä ja DHT hakevat osoitteen. Vertainen aiheuttaa tietoturvavaroituksen Uutissyöte-välilehdessä, koska olet määrittänyt sallittujen luettelossa olemisen pakolliseksi. Voit sallia vertaisen IP-osoitteen Uutissyöte-välilehdeltä.</p> - + [Unknown] [Tuntematon] - + Added with certificate from %1 Varmenne lisätty %1 @@ -3975,7 +4255,12 @@ vaikkette ystävystyisikään. UDP:n tulos - + + Status + Tila + + + <!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; } @@ -4405,7 +4690,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4557,7 +4842,7 @@ p, li { white-space: pre-wrap; } Piirien rajoituksia ei valittuna - + [Unknown] [Tuntematon] @@ -4572,7 +4857,7 @@ p, li { white-space: pre-wrap; } Poista - + Search Haku @@ -4592,7 +4877,7 @@ p, li { white-space: pre-wrap; } Tunnettujen solmujen allekirjoittama - + Edit Circle Muokkaa piiriä @@ -4612,12 +4897,12 @@ p, li { white-space: pre-wrap; } Nimetön tunniste - + Circle name Piiri nimi - + Update Päivitä @@ -4643,7 +4928,7 @@ p, li { white-space: pre-wrap; } PGP:n linkitetty tunniste - + Add Member Lisää jäsen @@ -4787,7 +5072,7 @@ p, li { white-space: pre-wrap; } - + Attachments Liitetiedostot @@ -4833,7 +5118,7 @@ p, li { white-space: pre-wrap; } Vedä ja pudota tiedostoja hakutuloksista - + Paste RetroShare Links Liitä Retroshare-linkit @@ -4843,7 +5128,7 @@ p, li { white-space: pre-wrap; } Liitä Retroshare-linkki - + Drop file error. Virhe pudotettaessa tiedostoa. @@ -4870,17 +5155,41 @@ p, li { white-space: pre-wrap; } - + RetroShare Retroshare - - File already Added and Hashed - Tiedosto on jo lisätty ja tiivistetty (hash) + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Tiedosto on jo lisätty ja tiivistetty (hash) + + + Please add a Subject Ole hyvä ja lisää aihe @@ -4911,12 +5220,12 @@ p, li { white-space: pre-wrap; } Haluatko todella luoda %1 viestiä? - + You are about to add files you're not actually sharing. Do you still want this to happen? Olet aikeissa lisätä tiedostoja, joita et todellisuudessa jaa. Haluatko silti tehdä tämän? - + Edit Channel Post Muokkaa kanavakirjoitusta @@ -4936,7 +5245,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Olet aikeissa lähettää kanavalle tiedostoja, jota et omista. @@ -5028,7 +5337,7 @@ p, li { white-space: pre-wrap; } - + No Forum Ei foorumia @@ -5488,7 +5797,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen DHTGraphSource - + users käyttäjät @@ -6495,7 +6804,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen FlatStyle_RDM - + Friends Directories Ystävien hakemistot @@ -7001,7 +7310,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Hae ystäviä - + Mark all Merkitse kaikki @@ -7015,7 +7324,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään FriendsDialog - + Edit status message Muokkaa tilaviestiä @@ -7119,7 +7428,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Retrosharen kuulutus: viestit lähetetään kaikille linjoilla oleville ystäville. - + Network Verkko @@ -7184,7 +7493,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Solmukenttä on pakollinen ja vähintään 3 merkkiä - + Failed to generate your new certificate, maybe PGP password is wrong! Uuden varmenteesi luonti epäonnistui, ehkä PGP-salasanasi oli väärin! @@ -7227,7 +7536,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Käytä olemassaolevaa profiilia - + Node name Solmun nimi @@ -7494,12 +7803,12 @@ ja käyttää tuo-painiketta sen lataamiseen - + Profile generation failure Profiilin luonti epäonnistui - + Missing PGP certificate Puuttuva PGP-varmenne @@ -7918,7 +8227,7 @@ p, li { white-space: pre-wrap; } Reitittimen tilastot - + GroupBox Ryhmälaatikko @@ -7983,7 +8292,7 @@ p, li { white-space: pre-wrap; } Haarautumiskerroin - + Details Tiedot @@ -8006,7 +8315,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Hallitut avaimet @@ -8215,7 +8524,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Otsikko @@ -8225,13 +8534,30 @@ p, li { white-space: pre-wrap; } Hae otsikkoa - - + + + + Description Kuvaus - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Hae kuvausta @@ -8241,42 +8567,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Laskeva järjestys + Laskeva järjestys - Sort Ascending Order - Nouseva järjestys + Nouseva järjestys - Sort by Name - Järjestä nimen mukaan + Järjestä nimen mukaan - Sort by Popularity - Järjestä suosion mukaan + Järjestä suosion mukaan - Sort by Last Post - Järjestä viimeisimmän viestin mukaan + Järjestä viimeisimmän viestin mukaan - Sort by Number of Posts - Järjestä viestien määrän mukaan + Järjestä viestien määrän mukaan - Sort by Unread - Järjestä lukemattomien mukaan + Järjestä lukemattomien mukaan - + You are admin (modify names and description using Edit menu) Olet ylläpitäjä (muokkaa nimiä ja kuvaksia käyttäen Muokkaa-valikkoa) @@ -8291,40 +8610,35 @@ p, li { white-space: pre-wrap; } Tunniste - - + + Last Post Viimeisin viesti - + + Name Nimi - - Unread - - - - + Popularity Suosio - - + + Never Ei koskaan - Display - Näytä + Näytä - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8473,7 +8787,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanavat @@ -8498,12 +8812,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kanavat</h1> <p>Kanavat sallivat sinun lähettää dataa (esim. elokuvia, musiikkia) , jotka leviävät verkostossa.</p> <p>Voit nähdä mitä kanavia ystäväsi tilaavat, ja automaattisesti edelleenlähettää tilatut kanavat ystävillesi. Tämä edistää verkoston hyviä kanavia.</p> <p>Ainoastaan kanavan luoja pystyy lähettämään kyseiselle kanavalle. Muut vertaiset verkostossa pystyvät vain lukemaan sitä, ellei kanava ole yksityinen. Kaikesta huolimatta voit jakaa lähetys- tai luku-oikeuksia ystäviesi Retroshare-solmuille.</p> <p>Kanavista voidaan tehdä nimettömiä, tai niihin voidaan liittää Retroshare-henkilöllisyys, että lukijat voivat yhteyden sinuun tarvittaessa. Salli "Salli kommentit", jos haluat käyttäjien kommentoivan viestejäsi.</p> <p>Kanavan viestit säilyvät %1 päivää, and pidetään ajan tasalla %2 päivän ajan, ellet sinä muuta tätä.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Tilatut kanavat @@ -9028,7 +9342,7 @@ p, li { white-space: pre-wrap; } - + Add new post Lisää uusi kirjoitus @@ -9128,12 +9442,12 @@ p, li { white-space: pre-wrap; } - + Files Tiedostot - + Comments Kommentit @@ -9144,18 +9458,18 @@ p, li { white-space: pre-wrap; } - + Feeds Syötteet - - + + Click to switch to list view - + Show unread posts only @@ -9165,12 +9479,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9230,7 +9544,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9245,12 +9559,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9326,23 +9640,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Tilattu - - Subscribe Aloita tilaus - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Ei kanavaa valittuna @@ -9364,11 +9691,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanavakirjoitus - - - new message(s) - - GxsCircleItem @@ -9902,7 +10224,7 @@ kuin voit kommentoida Aloita uusi viestiketju valitussa foorumissa - + Search forums Hae foorumeista @@ -9911,12 +10233,12 @@ kuin voit kommentoida Viimeisin viesti - + New Thread Uusi viestiketju - + Threaded View Ketjunäkymä @@ -9926,19 +10248,19 @@ kuin voit kommentoida Tasanäkymä - - + + Title Otsikko - - + + Date Päiväys - + Author Kirjoittaja @@ -9953,7 +10275,17 @@ kuin voit kommentoida Ladataan - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10014,23 +10346,23 @@ kuin voit kommentoida <p>Foorumin tilaaminen kerää kaikki saatavilla olevat viestit tilaajaystäviltäsi, ja tekee foorumista näkyvän kaikille muille ystävillesi.</p><p>Myöhemmin voit peruuttaa tilauksen foorumin kontekstivalikosta vasemmalla.</p> - + No name Ei nimeä - - + + Reply Vastaa - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10068,12 +10400,12 @@ kuin voit kommentoida Merkitse lukemattomaksi - + Copy RetroShare Link Kopioi Retroshare-linkki - + Hide Piilota @@ -10086,7 +10418,7 @@ kuin voit kommentoida [Pannassa] - + [unknown] [tuntematon] @@ -10116,8 +10448,8 @@ kuin voit kommentoida Vain silmillesi - - + + Distribution @@ -10220,7 +10552,7 @@ kuin voit kommentoida Alkuperäinen viesti - + New thread Uusi viestiketju @@ -10229,7 +10561,7 @@ kuin voit kommentoida Lue tilaviesti - + Edit Muokkaa @@ -10285,7 +10617,7 @@ kuin voit kommentoida Näytä kirjoittaja Ihmiset-välilehdellä - + Author's reputation Kirjoittajan maine @@ -10305,7 +10637,7 @@ kuin voit kommentoida - + <b>Loading...<b> @@ -10345,6 +10677,11 @@ kuin voit kommentoida Storage + + + Last seen at friends: + + Moderators @@ -10438,7 +10775,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. %1, %2 kirjoitti: - + Forum name Foorumin nimi @@ -10470,11 +10807,6 @@ estää viestin lähettämisen eteenpäin ystävillesi. Forum Post Foorumiviesti - - - new message(s) - - GxsForumsDialog @@ -10923,7 +11255,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Tulostuksen esikatselu - + Unsubscribe Lopeta tilaus @@ -10938,7 +11270,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Avaa uuteen välilehteen - + Remove this search @@ -10948,12 +11280,12 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + Request data - + Show Details Näytä tiedot @@ -11020,7 +11352,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + Search for @@ -11029,7 +11361,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Jaa julkaisuoikeudet - + Copy RetroShare Link Kopioi Retroshare-linkki @@ -11044,7 +11376,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Merkitse kaikki lukemattomiksi - + AUTHD VAHVST @@ -11653,7 +11985,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11688,6 +12020,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11699,7 +12048,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11779,27 +12128,32 @@ p, li { white-space: pre-wrap; } Lomake - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11821,6 +12175,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11829,7 +12184,7 @@ p, li { white-space: pre-wrap; } Teksti alapuolella on Retroshare-varmenteesi. Lähetä se ystävillesi - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11846,12 +12201,12 @@ yksityinen ja turvallinen hajautettu viestintäalusta. Tarvitsetko apua Retrosharen kanssa? - + Open Web Help Avaa verkkotuki (englanniksi) - + Copy your Cert to Clipboard Kopioi varmenteesi leikepöydälle @@ -11900,7 +12255,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11909,7 +12264,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12202,14 +12557,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Kaikki - + Reputation Maine @@ -12219,12 +12574,12 @@ p, li { white-space: pre-wrap; } Haku - + Anonymous Id Nimetön tunniste - + Create new Identity Luo uusi henkilöllisyys @@ -12368,7 +12723,7 @@ p, li { white-space: pre-wrap; } Henkilöllisyystunniste - + Send message Lähetä viesti @@ -12460,7 +12815,7 @@ p, li { white-space: pre-wrap; } Yhteensä: - + Anonymous Nimetön @@ -12475,24 +12830,24 @@ p, li { white-space: pre-wrap; } Hae tunnistetta - + This identity is owned by you Tämä henkilöllisyys on sinun omistamasi - - + + My own identities Minun henkilöllisyyteni - - + + My contacts - + Show Items Näytä kohteet @@ -12507,7 +12862,7 @@ p, li { white-space: pre-wrap; } Linkitetty solmuuni - + Other circles Muut piirit @@ -12566,13 +12921,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). tilattu (Vastaanota/lähetä jäsenyyspyyntöjä toisilta ja kutsuluettelosta) + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). tilauksen peruuttaneet (Vastaanota ainoastaan kutsuluettelo). - + Your status: Sinun tilasi: @@ -12632,7 +12992,7 @@ p, li { white-space: pre-wrap; } Jäsen - + Edit Circle Muokkaa piiriä @@ -12680,7 +13040,7 @@ p, li { white-space: pre-wrap; } Myönnä jäsenyys - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12692,12 +13052,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + [Unknown node] [Tuntematon solmu] - + Unverified signature from node Vahvistamaton allekirjoitus solmulta @@ -12709,12 +13069,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tarkistamaton allekirjoitus - + [unverified] [vahvistamaton] - + Identity owned by you, linked to your Retroshare node Sinun omistama henkilöllisyys linkitettynä Retroshare-solmuusi @@ -12838,12 +13198,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Haluatko todella lähettää kutsun varmenteellasi? - + Banned Pannassa - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> @@ -12852,7 +13212,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tuntematon tunniste: - + positive positiviinen @@ -13037,8 +13397,8 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - - + + People Ihmiset @@ -13049,7 +13409,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinun avatar - + Linked to neighbor nodes Linkitetty naapurisolmuihin @@ -13059,7 +13419,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Linkitetty etäisiin solmuihin - + Linked to a friend Retroshare node Linkitetty ystävä Retroshare-solmuun @@ -13119,7 +13479,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Omistama - + Node name: Solmun nimi: @@ -13129,7 +13489,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Solmun tunniste : - + Really delete? Tuhotaanko? @@ -13167,7 +13527,22 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Nimimerkki - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Uusi henkilöllisyys @@ -13184,14 +13559,14 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + N/A Ei sovellu - + Edit identity Muokkaa henkilöllisyyttä @@ -13202,24 +13577,27 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Päivitä - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13238,17 +13616,27 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Virhe haettaessa avainta! - + Error KeyID invalid Virhe: viallinen avaimen tunniste - + Unknown GpgId Tuntematon GPG-tunniste @@ -13258,7 +13646,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tuntematon oikea nimi - + Create New Identity Luo uusi henkilöllisyys @@ -13268,7 +13656,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tyyppi - + + Choose image... + + + + @@ -13308,12 +13701,11 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinun avatar - Set Avatar - Aseta Avatar + Aseta Avatar - + Linked to your profile Linkitetty profiiliisi @@ -13323,7 +13715,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinulla voi olla yksi tai useampi henkilöllisyys. Niitä käytetään usein kirjoitettaessa keskusteluhuoneisiin, foorumeille ja kanavakommentteihin. Ne toimivat kohteena etäiselle keskustelulle ja Retrosharen etäiselle postijärjestelmälle. - + The nickname is too short. Please input at least %1 characters. Nimimerkki on liian lyhyt. Syötä vähintään %1 merkkiä. @@ -13432,8 +13824,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. + Quote + Lainaa + + Send - Lähetä + Lähetä @@ -13591,7 +13987,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Options Asetukset @@ -13623,12 +14019,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Ohjattu nopea käynnistys - + RetroShare %1 a secure decentralized communication platform Retroshare %1 turvallinen hajautettu viestintäalusta - + Unfinished Kesken @@ -13761,7 +14157,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Näytä - + Make sure this link has not been forged to drag you to a malicious website. Varmista, että tämä linkki ei ole huijaus, joka johtaa haitalliselle sivustolle. @@ -13806,7 +14202,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Palveluiden käyttöoikeudet - + Statistics Tilastot @@ -13835,7 +14231,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. MessageComposer - + Compose Kirjoita viesti @@ -13937,7 +14333,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Tags Merkkaukset @@ -14032,12 +14428,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Lisää lainauslohko (blockquote) - + Send To: Lähetä: - + &Left Tas&aa vasemmalle @@ -14071,7 +14467,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hei,<br>suosittelen ystävääni; voit luottaa häneen, kuten luotat minuun.<br> @@ -14097,12 +14493,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Save Message Tallenna viesti - + Message has not been Sent. Do you want to save message to draft box? Viestiä ei ole lähetetty. @@ -14114,7 +14510,7 @@ Haluatko tallentaa viestin luonnoslaatikkoon? Liitä Retroshare-linkki - + Add to "To" Lisää vastaanottajiin @@ -14369,7 +14765,7 @@ Haluatko tallentaa viestin? Lisää ylimääräinen tiedosto - + Hi,<br>I want to be friends with you on RetroShare.<br> Hei,<br>haluan olla ystäväsi Retrosharessa.<br> @@ -14378,12 +14774,27 @@ Haluatko tallentaa viestin? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Sinulle on ystäväkutsu - + Respond now: Vastaa nyt: @@ -14399,11 +14810,12 @@ Haluatko tallentaa viestin? Lähettäjä: + Friend Nodes - Ystäväsolmut + Ystäväsolmut - + Bullet list (disc) @@ -14443,13 +14855,13 @@ Haluatko tallentaa viestin? - - + + Thanks, <br> Kiitos, <br> - + Distant identity: Etäinen henkilöllisyys: @@ -14588,8 +15000,23 @@ Haluatko tallentaa viestin? Viesti - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14601,12 +15028,12 @@ Haluatko tallentaa viestin? Suositellut tiedostot - + Download all Recommended Files Lataa kaikki suositellut tiedostot - + Subject: Aihe: @@ -14681,12 +15108,18 @@ Haluatko tallentaa viestin? Lähetä kutsu - + + Message Size: + + + + File Name Tiedoston nimi - + + Size Koko @@ -14747,10 +15180,25 @@ Haluatko tallentaa viestin? Lataa - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Lähetä kutsu? @@ -14761,12 +15209,12 @@ Haluatko tallentaa viestin? - + Download all Lataa kaikki - + Print Document Tulosta asiakirja @@ -14781,7 +15229,7 @@ Haluatko tallentaa viestin? HTML-tiedostot (*.htm *.html);;Kaikki tiedostot (*) - + Load images always for this message Lataa kuvat aina tämän viestin osalta @@ -14922,7 +15370,7 @@ Haluatko tallentaa viestin? MessagesDialog - + New Message Uusi viesti @@ -14978,14 +15426,14 @@ Haluatko tallentaa viestin? - + Tags Merkkaukset - + Inbox Saapuneet @@ -15080,7 +15528,7 @@ Haluatko tallentaa viestin? Välitä viesti - + Subject Aihe @@ -15192,7 +15640,7 @@ Haluatko tallentaa viestin? - + Open in a new window Avaa uudessa ikkunassa @@ -15277,7 +15725,7 @@ Haluatko tallentaa viestin? - + Drafts Luonnokset @@ -15406,7 +15854,7 @@ Haluatko tallentaa viestin? Vastaa viestiin - + Delete Message Tuhoa viesti @@ -15417,7 +15865,7 @@ Haluatko tallentaa viestin? - + Expand Laajenna @@ -15427,7 +15875,7 @@ Haluatko tallentaa viestin? Poista kohde - + from alkaen @@ -15436,6 +15884,11 @@ Haluatko tallentaa viestin? Reply to invite Vastaa kutsuun + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15758,7 +16211,7 @@ Raportoitu virhe: - + Groups Ryhmät @@ -15788,19 +16241,19 @@ Raportoitu virhe: tuo ystäväluettelo mukaan lukien ryhmät - - + + Search Haku - + ID Tunniste - + Search ID @@ -15810,7 +16263,7 @@ Raportoitu virhe: - + Show Items Näytä kohteet @@ -16014,19 +16467,19 @@ ainakin yksi vertainen jäi lisäämättä ryhmään - + Error Virhe - + File is not writeable! Tiedostoon ei voi kirjoittaa! - + File is not readable! Tiedostoa ei voi lukea! @@ -16064,9 +16517,13 @@ ainakin yksi vertainen jäi lisäämättä ryhmään NewsFeed - Log entries - Lokimerkinnät + Lokimerkinnät + + + + Activity Stream + @@ -16083,7 +16540,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään This is a test. - + Newest on top Uusin ylimmäisenä @@ -16094,20 +16551,43 @@ ainakin yksi vertainen jäi lisäämättä ryhmään + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Uutissyöte</h1> <p>Lokisyöte näyttää uusimmat tapahtumat verkostossasi vastaanottohetken mukaan järjestettynä. Näin saat yhteenvedon ystäviesi toiminnasta. Voit määrittää näytettävät tapahtumat <b>Asetuksista</b>. </p> <p>Näytettäviä tapahtumia: <ul> <li>Yhteydenottoyritykset (hyödyllisiä ystävien hankkimiseen ja yhteydenottojen hallintaan)</li> <li>Viestit kanaville ja foorumeille</li> <li>Uudet kanavat ja foorumit, jotka ovat tilattavissasi</li> <li>Yksityisviestit ystäviltäsi</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Uutissyöte</h1> <p>Lokisyöte näyttää uusimmat tapahtumat verkostossasi vastaanottohetken mukaan järjestettynä. Näin saat yhteenvedon ystäviesi toiminnasta. Voit määrittää näytettävät tapahtumat <b>Asetuksista</b>. </p> <p>Näytettäviä tapahtumia: <ul> <li>Yhteydenottoyritykset (hyödyllisiä ystävien hankkimiseen ja yhteydenottojen hallintaan)</li> <li>Viestit kanaville ja foorumeille</li> <li>Uudet kanavat ja foorumit, jotka ovat tilattavissasi</li> <li>Yksityisviestit ystäviltäsi</li> </ul> </p> + + + Log + Loki - Log - Loki + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16144,22 +16624,22 @@ ainakin yksi vertainen jäi lisäämättä ryhmään - + Test Test - + Chat Room Keskusteluhuone - + Systray Icon Ilmaisinalueen kuvake - + Message Viesti @@ -16184,12 +16664,11 @@ ainakin yksi vertainen jäi lisäämättä ryhmään IP-tietoturva - Log - Loki + Loki - + Friend Connected Ystävä linjoilla @@ -16203,7 +16682,12 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Linkit - + + Activity + + + + Mails Postit @@ -16240,7 +16724,12 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Ryhmäkeskustelu - + + Toaster position + + + + Chat rooms Keskusteluhuoneet @@ -16253,22 +16742,22 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Huomioi kirjainkoko - + Position Sijainti - + X Margin X-reuna - + Y Margin Y-reuna - + Systray message Ilmaisinalueen viesti @@ -16318,7 +16807,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Huomauta - + Disable All Toasters Estä kaikki ponnahdusviestit @@ -16332,7 +16821,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Syöte - + Systray Ilmaisinalue @@ -16478,17 +16967,16 @@ ainakin yksi vertainen jäi lisäämättä ryhmään PGPKeyDialog - Dialog - Ikkuna + Ikkuna - + Profile info Profiilin tiedot - + Name : Nimi: @@ -16543,22 +17031,21 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Äärimmäinen - + This profile has signed your own profile key Tämä profiili on allekirjoitettu sinun profiiliavaimellasi - Key signatures : - Avain allekirjoitukset: + Avain allekirjoitukset: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Allekirjoitukset alla kryptograafisesti todistavat, että luettelon avaimien omistajat tunnistavat nykyisen PGP-avaimen aidoksi.</span></p></body></html> - + <!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; } @@ -16576,7 +17063,7 @@ p, li { white-space: pre-wrap; } Allekirjoita tämä avain - + PGP key PGP-avain @@ -16586,22 +17073,20 @@ p, li { white-space: pre-wrap; } Nämä vaihtoehdot koskevat kaikkia solmuja profiilissa: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Se auttaa heitä päättämään salliako yhteydet siitä avaimesta perustuen sinun omaan luottamukseen. Avaimen allekirjoittaminen on täysin vapaaehtoista, eikä sitä voi perua, joten tee niin harkiten.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Se auttaa heitä päättämään salliako yhteydet siitä avaimesta perustuen sinun omaan luottamukseen. Avaimen allekirjoittaminen on täysin vapaaehtoista, eikä sitä voi perua, joten tee niin harkiten.</span></p></body></html> - + Keysigning: - Sign PGP key - Allekirjoita PGP-avain + Allekirjoita PGP-avain - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Napsauta tästä, jos haluat kieltäytyä yhteyksistä tämän avaimen todentamiin solmuihin.</p></body></html> @@ -16621,7 +17106,7 @@ p, li { white-space: pre-wrap; } Hyväksy yhteydet - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16691,28 +17176,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare Retroshare - - + + Error : cannot get peer details. Virhe haettaessa vertaisen tietoja. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Retroshare ei tue antamaasi avainalgoritmia (Tällä hetkellä vain RSA-avaimet käyvät) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16726,7 +17211,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Luottamustaso ilmaisee omaa luottamustasi tähän avaimeen. Ohjelma ei käytä sitä eikä sitä jaeta, mutta se voi olla hyödyllinen hyvien sekä huonojen avainten muistamiseen. @@ -16771,27 +17256,47 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Et hyväksy yhteyksiä tämän avaimen allekirjoittamilta Retroshare-solmuilta. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Virhe allekirjoitettaessa - - Maybe password is wrong - Salasana saattaa olla väärin + + Check the password! + - + Maybe password is wrong + Salasana saattaa olla väärin + + + You haven't set a trust level for this key. Et ole asettanut luottamustasoa tälle avaimelle. - + + Retroshare profile Retroshare-profiili - + This is your own PGP key, and it is signed by : Tämä on sinun oma PGP-avain ja sen on allekirjoittanut: @@ -16970,8 +17475,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E PeopleDialog - - + People Ihmiset @@ -16988,7 +17492,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Sisäinen - + Chat with this person Keskustele henkilön kanssa @@ -17139,7 +17643,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Valokuva - + TextLabel TekstiMerkki @@ -17183,8 +17687,8 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E - <N> Comments >> - + Comments + Kommentit @@ -17219,6 +17723,11 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Write a comment... Kirjoita kommentti... + + + Album + Albumi + PhotoItem @@ -17228,12 +17737,12 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Lomake - + TextLabel TekstiMerkki - + <!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; } @@ -17329,7 +17838,7 @@ p, li { white-space: pre-wrap; } Näytä kuva - + PhotoShare PhotoShare @@ -17370,7 +17879,7 @@ yrität muokata sitä! - + Stop Pysäytä @@ -17598,12 +18107,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Hyväksy kaikki lisäosat - + Plugin look-up directories Lisäosien hakemistot @@ -17658,7 +18167,7 @@ tiivisteen tarkistaminen suojelee sinua vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Plugins Lisäosat @@ -18056,7 +18565,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Linkit - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18227,13 +18736,13 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Sivusto - - + + Comments Kommentit - + Copy RetroShare Link Kopioi Retroshare-linkki @@ -18243,7 +18752,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Näytä kirjoittaja Ihmiset-välilehdellä - + Comment Kommentti @@ -18264,12 +18773,12 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Hide Piilota - + Vote up Äänestä ylös @@ -18283,7 +18792,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. \/ - + Set as read and remove item Merkitse luetuksi ja poista kohde @@ -18344,7 +18853,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Loading Ladataan @@ -18434,13 +18943,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18450,60 +18953,50 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Ylläpitäjä: - - - + + + unknown tuntematon - + Distribution: Jakelu: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Viestejä @@ -18514,7 +19007,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18583,7 +19076,12 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + + Empty + Tyhjä + + + Copy RetroShare Link Kopioi Retroshare-linkki @@ -18618,7 +19116,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + [No name] @@ -18746,8 +19244,18 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19019,9 +19527,8 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseAddDialog - Post From: - Lähettäjä + Lähettäjä Account 1 @@ -19036,7 +19543,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Tili 3 - + Add to Pulse Lisää pulssiin @@ -19059,17 +19566,32 @@ ja käyttää "Tuo"-painiketta ladataksesi sen URL - + GroupLabel - + IDLabel - + + From: + Lähettäjä: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19094,10 +19616,20 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Kielteinen - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19107,14 +19639,53 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + + Post + + + + Cancel Peru - Post Pulse to Wire - Lähetä pulssi lennättimeen + Lähetä pulssi lennättimeen + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19140,10 +19711,18 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Lomake - - - - + + + + + Click to view picture + + + + + + + Image Kuva @@ -19151,44 +19730,44 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19198,17 +19777,17 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19218,7 +19797,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19226,7 +19805,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseTopLevel - + retweeted @@ -19241,7 +19820,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + follow Parent Group @@ -19251,7 +19830,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19276,7 +19855,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19312,29 +19891,29 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19412,7 +19991,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen QObject - + Confirmation Vahvistus @@ -19654,7 +20233,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tulos - + Unable to make path Polun luominen epäonnistui @@ -19689,7 +20268,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tiedostopyyntö peruttu - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Tämä Retrosharen versio käyttää OpenPGP-SDK:ta. Tämän takia se ei käytä järjestelmäjaettua PGP-avainketjua, vaan sillä on oma avainketjunsa jaettuna kaikkien käynnissä olevien Retrosharejen kanssa.<br><br>Sinulla ei näytä olevan tällaista avainketjua, vaikka olemassaolevissa Retroshare-tileissä mainitaan PGP-avaimet. Tämä johtuu todennäköisesti siitä, että siirryit juuri ohjelman uudempaan versioon. @@ -19844,7 +20423,7 @@ Virhe: sekuntia - + TR up @@ -19889,7 +20468,7 @@ Virhe: estetty - + Move IP %1 to whitelist Lisää IP %1 sallittujen luetteloon @@ -19905,7 +20484,7 @@ Virhe: - + %1 seconds ago %1 sekuntia sitten @@ -19990,7 +20569,7 @@ Tietoturva: ei nimettömiä tunnisteita - + Error Virhe @@ -20381,9 +20960,8 @@ Tietoturva: ei nimettömiä tunnisteita Napsauta jatkaaksesi tiivisteen laskentaa - <p>This certificate contains: - <p>Tämä varmenne sisältää: + <p>Tämä varmenne sisältää: @@ -20757,7 +21335,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 kt @@ -20979,19 +21557,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... - Näytä sarake... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Laskeva järjestys + + + + Sort Ascending Order + Nouseva järjestys + + + + + [no title] + + + + + Show column … + + + + Show column... + Näytä sarake... - [no title] - [ei otsikkoa] + [ei otsikkoa] @@ -21427,7 +22034,7 @@ p, li { white-space: pre-wrap; } Lataa! - + File Tiedosto @@ -21442,7 +22049,7 @@ p, li { white-space: pre-wrap; } Tiiviste (hash) - + Bad filenames have been cleaned Virheelliset tiedostonimet muutettu @@ -21492,7 +22099,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tallenna - + Collection Editor Kokoelman muokkaus @@ -21507,7 +22114,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tiedostojen määrä - + Real Size: Waiting child... Todellinen koko: Odotetaan alihakemistoja... @@ -21522,12 +22129,12 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tämä on hakemisto. Laajenna se kaksoisnapauttamalla. - + Download files Lataa tiedostot - + Specify... Määritä... @@ -21776,7 +22383,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u RsFriendListModel - + Name Nimi @@ -21796,7 +22403,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u IP - + Profile ID @@ -21809,10 +22416,15 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u RsGxsForumModel - + Title Otsikko + + + UnRead + + Date @@ -21824,7 +22436,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u Kirjoittaja - + Information for this identity is currently missing. Tämän henkilöllisyyden tiedot ovat tällä hetkellä kateissa. @@ -21865,7 +22477,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. [Tuntematon] - + [ ... Missing Message ... ] [ ... Puuttuva viesti ... ] @@ -21873,7 +22485,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. RsMessageModel - + Date Päiväys @@ -21933,7 +22545,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + [Notification] @@ -22292,7 +22904,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Tiedoston nimi - + Download Lataa @@ -22371,7 +22983,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Avaa kansio - + Create Collection... Luo kokoelma... @@ -22391,7 +23003,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Lataa kokoelmatiedostosta... - + Collection Kokoelma @@ -22496,12 +23108,12 @@ estää viestin lähettämisen eteenpäin ystävillesi. Vertaisen tiedot - + Deny friend Torju ystävä - + Chat Keskustelu @@ -22511,7 +23123,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Aloita keskustelu - + Expand Laajenna @@ -22781,13 +23393,13 @@ vähän ystäviä. Tämä auttaa myös, jos olet palomuurin tai VPN:n takana.Etsintä käytössä (suositus) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor on Retrosharen automaattisesti määrittelemä. Sinun ei pitäisi tarvita muuttaa mitään tässä. - + Discovery Off Etsintä ei käytössä @@ -23280,7 +23892,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis <p>Välittäjänä toimiva Retroshare-solmu ei voi nähdä välitettyä liikennettä, koska se on salattu ja kahden välitetyn solmun vahvistama.</p> - + Network Verkko @@ -23308,7 +23920,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis - + Status Tila @@ -23405,7 +24017,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis - + Service Address Palvelun osoite @@ -23440,12 +24052,12 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis Täytä palveluosoite - + IP Range IP-avaruus - + Reported by DHT for IP masquerading DHT raportoi IP:n naamioinnista @@ -24120,7 +24732,7 @@ p, li { white-space: pre-wrap; } Puuttuva PGP-varmenne - + Wrong password Väärä salasana @@ -24162,7 +24774,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Lisää ystävä @@ -24218,7 +24830,7 @@ This choice can be reverted in settings. Palveluiden käyttöoikeudet - + DHT DHT @@ -24758,7 +25370,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24772,13 +25384,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor ei ole nyt linjoilla - + Tor is OK Tor on OK @@ -24787,6 +25398,31 @@ p, li { white-space: pre-wrap; } No tor configuration Ei tor-asetuksia + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25080,35 +25716,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Sinulla on %1 kpl valmiita latauksia + You have %1 completed transfers + - You have %1 completed download - Sinulla on %1 valmis lataus + You have %1 completed transfer + - %1 completed downloads - %1 kpl valmiita latauksia + %1 completed transfers + - %1 completed download - %1 valmis lataus + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Sinulla on %1 kpl valmiita latauksia + + + You have %1 completed download + Sinulla on %1 valmis lataus + + + %1 completed downloads + %1 kpl valmiita latauksia + + + %1 completed download + %1 valmis lataus TransfersDialog - + Downloads Lataukset @@ -25119,7 +25766,7 @@ p, li { white-space: pre-wrap; } Lähetykset - + Name i.e: file name Nimi @@ -25326,7 +25973,7 @@ p, li { white-space: pre-wrap; } Määritä... - + Move in Queue... Siirrä jonossa... @@ -25420,7 +26067,7 @@ p, li { white-space: pre-wrap; } Kirjoita uusi ja validi tiedostonimi - + Expand all Laajenna kaikki @@ -25552,7 +26199,7 @@ p, li { white-space: pre-wrap; } - + Columns Sarakkeet @@ -25563,7 +26210,7 @@ p, li { white-space: pre-wrap; } Tiedostojen siirrot - + Path Polku @@ -25573,7 +26220,7 @@ p, li { white-space: pre-wrap; } Näytä Polku-sarake - + Could not delete preview file Esikatselutiedostoa ei voitu poistaa @@ -25583,7 +26230,7 @@ p, li { white-space: pre-wrap; } Yritä uudelleen? - + Create Collection... Luo kokoelma... @@ -25598,7 +26245,7 @@ p, li { white-space: pre-wrap; } Näytä kokoelma... - + Collection Kokoelma @@ -25844,7 +26491,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Tuntematon vertainen @@ -25940,7 +26587,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Sinulle on uusia viestejä %1 kpl @@ -26324,7 +26971,7 @@ p, li { white-space: pre-wrap; } Luo ryhmä - + Subscribe to Group Tilaa ryhmä @@ -26418,8 +27065,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Näytä muokkaushistoria @@ -26430,7 +27077,7 @@ p, li { white-space: pre-wrap; } - + Preview Esikatselu @@ -26455,12 +27102,12 @@ p, li { white-space: pre-wrap; } Piilota muokkaushistoria - + Edit Page Muokkaa sivua - + Create New Wiki Page Luo uusi wikisivu @@ -26480,7 +27127,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Luo uusi wikiryhmä @@ -26522,7 +27169,7 @@ p, li { white-space: pre-wrap; } Aikaväli - + Create Account @@ -26532,12 +27179,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Päivitä @@ -26572,12 +27218,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26647,7 +27293,7 @@ p, li { white-space: pre-wrap; } Näyttää: - + Yourself Sinä itse @@ -26685,7 +27331,7 @@ p, li { white-space: pre-wrap; } Lähetä pulssi lennättimeen - + RetroShare Retroshare @@ -26697,7 +27343,7 @@ p, li { white-space: pre-wrap; } - + The Wire Lennätin @@ -26705,7 +27351,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26786,8 +27432,8 @@ p, li { white-space: pre-wrap; } Lomake - - + + Avatar Avatar @@ -26816,6 +27462,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26928,8 +27579,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Kuvat (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Kuvat (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_fr.ts b/retroshare-gui/src/lang/retroshare_fr.ts index 87874f0f0..cc9597926 100644 --- a/retroshare-gui/src/lang/retroshare_fr.ts +++ b/retroshare-gui/src/lang/retroshare_fr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Version de Retroshare @@ -79,7 +79,7 @@ Amusez-vous ;-) - + Only Hidden Node NÅ“ud caché seulement @@ -129,12 +129,12 @@ Retroshare : Recherche avancée - + Search Criteria Critère(s) de recherche - + Add a further search criterion. Ajouter un critère de recherche. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulaire - - + + TextLabel Etiquette @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barre d'outils - + Icon Only Icône seulement @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Choisissez le style des boutons outils. - + Icon Size = 8x8 Taille d'icône = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Taille d'icône = 128x128 - + Status Bar Barre de statut @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Désactive les infobulles en zone de notification - + Main page items: Articles de page principale : @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Liste d'articles - + Icon Size = 32x32 Taille icône = 32x32 @@ -828,14 +828,23 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Changer l'avatar - + + TextLabel + + + + Your Avatar Picture Votre image avatar - + + Browse... + + + Add Avatar - Ajouter avatar + Ajouter avatar @@ -843,25 +852,34 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Supprimer - + Set your Avatar picture Mettre votre image d'avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Charger l'avatar + Charger l'avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Cliquez pour modifier votre avatar @@ -869,7 +887,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à BWGraphSource - + KB/s KO/s @@ -889,44 +907,65 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à RetroShare Bandwidth Usage Utilisation de la bande passante par Retroshare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Options + TextLabel + + + + Reset Réinitialiser - Receive Rate - Vitesse de réception + Vitesse de réception - Send Rate - Vitesse d'émission + Vitesse d'émission - + Always on Top Toujours visible - Style - Style + Style - + Changes the transparency of the Bandwidth Graph Modifier la transparence du graphique de bande passande - + 100 100 @@ -936,30 +975,27 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à % opaque - Save - Sauvegarder + Sauvegarder - Cancel - Annuler + Annuler - + Since: Statistiques enregistrées depuis : - Hide Settings - Masquer les options + Masquer les options BandwidthStatsWidget - + Sum Somme @@ -981,7 +1017,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Compte - + Average Moyenne @@ -1115,7 +1151,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à - + Comments Commentaires @@ -1193,6 +1229,85 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à + + BoardsCommentsItem + + + I like this + J'aime ça + + + + 0 + 0 + + + + I dislike this + Je n'aime pas ça + + + + Toggle Message Read Status + Changer l'état de lecture du message + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Définir comme lu et supprimer l'élément + + + + Remove Item + + + + + Name + Nom + + + + Comm value + + + + + Comment + Commentaire + + + + Comments + Commentaires + + + + Hide + Cacher + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Log scale Échelle de journal + + + Default + Par défaut + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + J'aime ça + + + + 0 + 0 + + + + I dislike this + Je n'aime pas ça + + + + Toggle Message Read Status + Changer l'état de lecture du message + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Définir comme lu et supprimer l'élément + + + + Remove Item + + + + + Name + Nom + + + + Comm value + + + + + Comment + Commentaire + + + + Comments + Commentaires + + + + Hide + Cacher + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Tchats - You have %1 new messages - Vous avez %1 nouveaux messages + Vous avez %1 nouveaux messages + + + You have %1 new message + Vous avez %1 nouveau message + + + %1 new messages + %1 nouveaux messages + + + %1 new message + %1 nouveau message + + + + You have %1 mentions + - You have %1 new message - Vous avez %1 nouveau message + You have %1 mention + - %1 new messages - %1 nouveaux messages + %1 mentions + - %1 new message - %1 nouveau message + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Tout supprimer - - - mention(s) - - ChatLobbyWidget @@ -2124,13 +2339,11 @@ Double-cliquez sur un salon pour y entrer et discuter. Variante : - Group chat - Tchat public + Tchat public - - + Private chat Tchat privé @@ -2195,17 +2408,16 @@ Double-cliquez sur un salon pour y entrer et discuter. /me envoie un message avec /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Dans cet onglet, vous pouvez configurer le nombre de messages de tchat que Retroshare gardera sauvegardé sur le disque et combien de la conversation précédente, elle affiche, pour les différents systèmes de discussions. La période de stockage max permet de supprimer les anciens messages et empêche l'historique des conversations de remplir les tchats volatiles (par exemple, les salons de tchat et tchat à distance).</p></body></html> - Chatlobbies - Salons de tchat + Salons de tchat - + Enabled: Activé : @@ -2226,11 +2438,12 @@ Double-cliquez sur un salon pour y entrer et discuter. + Chat rooms Salons de tchat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Sélectionné, si l'identité et le texte ci-dessus de même origine doivent être dans le même cas pour déclencher le comptage. @@ -2291,11 +2504,17 @@ Double-cliquez sur un salon pour y entrer et discuter. + Broadcast Tchat entre amis - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Nombre de messages sauvegardés (0 = illimité) : @@ -2442,8 +2661,23 @@ Double-cliquez sur un salon pour y entrer et discuter. Tchat privé - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Double-cliquez sur un salon pour y entrer et discuter. - + is typing... écrit... @@ -2631,12 +2865,12 @@ after HTML conversion. après la conversion en HTML. - + Choose your font. Choisissez votre police de caractère. - + Do you really want to physically delete the history? Etes-vous vraiment sûr de vouloir supprimer définitivement l'historique ? @@ -2708,7 +2942,7 @@ après la conversion en HTML. Ne pas cesser de colorer après X articles trouvés (nécessite davantage de CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trouver le précédent </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ après la conversion en HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marquer ce texte comme sélectionné</b><br><i>Ctrl+M</i> - + Person id: Id d'identité: @@ -2770,7 +3004,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Non signé - + items found. articles trouvés. @@ -2790,7 +3024,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Saisissez votre message ici - + Don't stop to color after Ne pas cesser de colorer après @@ -2948,12 +3182,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. ConfCertDialog - + Details Détails - + Local Address Adresse locale : @@ -2964,12 +3198,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Adresse externe : - + Node info: Information du nÅ“ud: - + Current address: Adresse courante: @@ -2985,31 +3219,36 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Port : - + Include signatures Inclure les signatures - + RetroShare Retroshare - + - + Error : cannot get peer details. Erreur : impossible d'obtenir les détails de ce contact. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Chiffrement - + Not connected Non connecté - + Retroshare node details Détails de noeud Retroshare - + Node name : Nom de noeud : @@ -3075,13 +3319,18 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Message d'état : - + + Connectivity + + + + List of known addresses: Liste des adresses connues: - - + + Retroshare Certificate Certificat Retroshare @@ -3096,7 +3345,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. - + Hidden Address Adresse cachée @@ -3107,11 +3356,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.aucun + <p>This certificate contains: - <p>Ce certificat contient : + <p>Ce certificat contient : - + <li>a <b>node ID</b> and <b>name</b> <li>un <b>ID de noeud</b> et <b>nom</b> @@ -3124,12 +3374,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.une <b>addresse IP</b> et <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Vous pouvez utiliser ce certificat pour vous faire de nouveaux amis. Envoyez-le par courrier électronique, ou donnez-le de main à la main.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Ceci est l'ID du certificat <span style=" font-weight:600;">OpenSSL</span> du noeud, qui est signé par la clé <span style=" font-weight:600;">PGP</span> ci-dessus. </p></body></html> @@ -3139,7 +3389,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.<html><head/><body><p>Ceci est la méthode de chiffrement utilisée par <span style=" font-weight:600;">OpenSSL</span>. La connexion aux noeuds amis est </p><p>toujours lourdement chiffrée, et si la DHE est présente la connexion utilise ensuite </p><p>&quot;perfect forward secrecy&quot;.</p></body></html> - + with avec @@ -3345,12 +3595,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Détails de la demande - + Peer details Détails du contact - + Name: Nom : @@ -3368,12 +3618,12 @@ resources. Veuillez noter que Retroshare nécessitera beaucoup de bande passante, mémoire et CPU si vous ajoutez de nombreux amis. Vous pouvez ajouter autant d'amis que vous le souhaitez, mais avec avec plus de 40 cela nécessitera probablement trop de ressources. - + Location: Emplacement : - + Options Options @@ -3410,12 +3660,12 @@ resources. Collez le certificat - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Cette boîte s'attend au certificat de votre ami Retroshare. AVERTISSEMENT : cela est différent de la clé PGP de votre ami. Ne collez pas ici la clé de profil de votre ami (même pas une partie). Cela ne fonctionnera pas.</p></body></html> - + Add friend to group: Ajouter l'ami à un groupe : @@ -3425,7 +3675,7 @@ resources. Ami authentifié (clé PGP signée) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with Ajouter cet ami pour communiquer avec lui @@ -3459,7 +3709,7 @@ resources. Pour accepter la demande d'amitié, cliquez sur le bouton Terminer. - + Sorry, some error appeared Désolé, des erreurs sont survenues @@ -3479,32 +3729,32 @@ resources. À propos de votre ami : - + Key validity: Validité de la clé : - + Profile ID: - + Signers Ils lui font aussi confiance : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est un moyen d'exprimer votre confiance en cet ami, à vos autres amis. Les signatures sous cryptographie attestent que les propriétaires des clés répertoriées reconnaissent la clé PGP actuelle comme authentique.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Ce contact est déjà dans votre liste d'am. L'ajouter se limitera à enregistrer son adresse IP. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Le chargement du certificat à échoué @@ -3587,12 +3837,12 @@ resources. Le certificat semble valide - + Not a valid Retroshare certificate! Certificat Retroshare non valide! - + RetroShare Invitation Invitation Retroshare @@ -3614,12 +3864,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? C'est votre propre certificat! Vous ne voulez pas devenir ami avec vous même. N'est-ce pas? - + @@ -3667,7 +3917,37 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Vous avez une demande d'amitié de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3755,12 +4035,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Utiliser en source directe, quand disponible - + IP-Addr: Addr-IP : - + IP-Address Adresse IP @@ -3826,7 +4106,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Ajouter la clé au trousseau - + This key is already in your keyring Cette clé est déjà dans votre trousseau @@ -3887,12 +4167,12 @@ contact même si vous n'êtes pas amis. <p>Ce certificat n'a pas d'IP. Vous devrez compter sur la découverte et la DHT pour le trouver. Parce que vous exigez l'autorisation liste blanche, le pair lèvera un avertissement de sécurité dans l'onglet "Fil d'actualités". De là, vous pourrez passer son IP en liste blanche.</p> - + [Unknown] [Inconnu] - + Added with certificate from %1 Ajoutée avec certificat depuis %1 @@ -3979,7 +4259,12 @@ contact même si vous n'êtes pas amis. Résultat UDP - + + Status + Statut + + + <!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; } @@ -4409,7 +4694,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4561,7 +4846,7 @@ p, li { white-space: pre-wrap; } Aucune limitation de cercle sélectionnée - + [Unknown] [Inconnu] @@ -4576,7 +4861,7 @@ p, li { white-space: pre-wrap; } Enlever - + Search Rechercher @@ -4596,7 +4881,7 @@ p, li { white-space: pre-wrap; } Signé par des noeuds connus - + Edit Circle Modifier le cercle @@ -4616,12 +4901,12 @@ p, li { white-space: pre-wrap; } ID anon - + Circle name Nom du cercle - + Update Mettre à jour @@ -4647,7 +4932,7 @@ p, li { white-space: pre-wrap; } ID PGP liée - + Add Member Ajouter membre @@ -4791,7 +5076,7 @@ p, li { white-space: pre-wrap; } - + Attachments Fichiers joints @@ -4837,7 +5122,7 @@ p, li { white-space: pre-wrap; } Glisser/déposer les fichiers à partir des résultats de recherche - + Paste RetroShare Links Coller le lien Retroshare @@ -4847,7 +5132,7 @@ p, li { white-space: pre-wrap; } Coller le lien Retroshare - + Drop file error. Erreur lors de l'ajout du fichier. @@ -4874,17 +5159,41 @@ p, li { white-space: pre-wrap; } - + RetroShare Retroshare - - File already Added and Hashed - Fichier déjà ajouté et hashé + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Fichier déjà ajouté et hashé + + + Please add a Subject Veuillez ajouter un sujet à votre message @@ -4915,12 +5224,12 @@ p, li { white-space: pre-wrap; } Voulez-vous vraiment générer %1 messages ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Vous êtes sur le point d'ajouter les fichiers que vous ne partagez pas actuellement. Voulez-vous toujours faire cela ? - + Edit Channel Post Modifier la publication de la chaîne @@ -4940,7 +5249,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Vous êtes sur le point de publier un fichier non-possédé sur la chaîne. @@ -5032,7 +5341,7 @@ p, li { white-space: pre-wrap; } - + No Forum Aucun forum @@ -5492,7 +5801,7 @@ et utiliser le bouton d'importation pour la charger DHTGraphSource - + users utilisateurs @@ -6499,7 +6808,7 @@ et utiliser le bouton d'importation pour la charger FlatStyle_RDM - + Friends Directories Dossiers partagés de mes amis @@ -7006,7 +7315,7 @@ au moins un contact n'a pas été ajouté au groupe Rechercher des amis - + Mark all Tout marquer @@ -7020,7 +7329,7 @@ au moins un contact n'a pas été ajouté au groupe FriendsDialog - + Edit status message Modifier le message d'état @@ -7124,7 +7433,7 @@ au moins un contact n'a pas été ajouté au groupe Retroshare broadcast chat : les messages sont envoyés à tous vos amis en ligne. - + Network Réseau @@ -7189,7 +7498,7 @@ au moins un contact n'a pas été ajouté au groupe Le champ noeud est exigé avec un minimum de 3 caractères - + Failed to generate your new certificate, maybe PGP password is wrong! Échec lors de la génération de votre nouveau certificat, peut-être que votre mot de passe PGP est faux ! @@ -7232,7 +7541,7 @@ au moins un contact n'a pas été ajouté au groupe Utiliser un profil existant - + Node name Nom de l'emplacement @@ -7507,12 +7816,12 @@ et l'utiliser au moyen du bouton d'importation afin de le charger - + Profile generation failure Échec lors de la génération du profil - + Missing PGP certificate Certificat PGP manquant @@ -7931,7 +8240,7 @@ p, li { white-space: pre-wrap; } Statistiques du routeur - + GroupBox GroupBox @@ -7996,7 +8305,7 @@ p, li { white-space: pre-wrap; } Embranchement de facteur - + Details Détails @@ -8019,7 +8328,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Clés gérées @@ -8228,7 +8537,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titre @@ -8238,13 +8547,30 @@ p, li { white-space: pre-wrap; } Rechercher titre - - + + + + Description Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Rechercher description @@ -8254,42 +8580,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Trier Ordre décroissant + Trier Ordre décroissant - Sort Ascending Order - Trier Ordre croissant + Trier Ordre croissant - Sort by Name - Trier par nom + Trier par nom - Sort by Popularity - Trier par popularité + Trier par popularité - Sort by Last Post - Trier par dernier message + Trier par dernier message - Sort by Number of Posts - Trier par quantité de messages + Trier par quantité de messages - Sort by Unread - Trier par Non lus + Trier par Non lus - + You are admin (modify names and description using Edit menu) Vous êtes administrateur (modifiez les noms et la description en utilisant le menu Edition) @@ -8304,40 +8623,35 @@ p, li { white-space: pre-wrap; } Id - - + + Last Post Dernier commentaire - + + Name Nom - - Unread - - - - + Popularity Popularité - - + + Never Jamais - Display - Affichage + Affichage - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8486,7 +8800,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Chaînes @@ -8519,12 +8833,12 @@ Les chaînes peuvent être anonymes, ou attachées à une identité Retroshare a Les publications sont conservés pendant %1 jours et synchronisés au cours des derniers %2 jours, à moins que vous ne les modifiez.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Chaînes abonnées @@ -9049,7 +9363,7 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Add new post Ajouter une nouvelle publication @@ -9149,12 +9463,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Files Fichiers - + Comments Commentaires @@ -9165,18 +9479,18 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Feeds Flux - - + + Click to switch to list view - + Show unread posts only @@ -9186,12 +9500,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + No files in the channel, or no channel selected - + No text to display @@ -9251,7 +9565,7 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Download this file: @@ -9266,12 +9580,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Comments (%1) - + [No name] @@ -9347,23 +9661,36 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des + Copy Retroshare link + + + + Subscribed Abonné - - Subscribe S'abonner - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Aucune chaîne sélectionnée @@ -9385,11 +9712,6 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des Channel Post Message - - - new message(s) - - GxsCircleItem @@ -9923,7 +10245,7 @@ avant de pouvoir commenter Lancer un nouveau fil dans le forum sélectionné - + Search forums Chercher @@ -9932,12 +10254,12 @@ avant de pouvoir commenter Dernier article - + New Thread Nouveau fil - + Threaded View Affichage en arborescence @@ -9947,19 +10269,19 @@ avant de pouvoir commenter Affichage à plat - - + + Title Titre - - + + Date Date - + Author Auteur @@ -9974,7 +10296,17 @@ avant de pouvoir commenter Chargement - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10036,23 +10368,23 @@ avant de pouvoir commenter Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des forums à gauche.</p> - + No name Aucun nom - - + + Reply Répondre - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10090,12 +10422,12 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Marquer comme non lu - + Copy RetroShare Link Copier le lien Retroshare - + Hide Cacher @@ -10108,7 +10440,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for [Banni] - + [unknown] [inconnu] @@ -10138,8 +10470,8 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Vos yeux seulement - - + + Distribution Distribution @@ -10242,7 +10574,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Message d'origine - + New thread Nouveau fil @@ -10251,7 +10583,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Lire l'état - + Edit Modifier @@ -10307,7 +10639,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Afficher l'auteur dans l'onglet gens - + Author's reputation Réputation de l'auteur @@ -10327,7 +10659,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for - + <b>Loading...<b> @@ -10367,6 +10699,11 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Storage Stockage + + + Last seen at friends: + + Moderators @@ -10457,7 +10794,7 @@ prevents the message to be forwarded to your friends. Le %1, %2 a écrit : - + Forum name Nom de forum @@ -10489,11 +10826,6 @@ prevents the message to be forwarded to your friends. Forum Post Message - - - new message(s) - - GxsForumsDialog @@ -10944,7 +11276,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Aperçu avant impression - + Unsubscribe Se désabonner @@ -10959,7 +11291,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Ouvrir dans un nouvel onglet - + Remove this search @@ -10969,12 +11301,12 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de - + Request data - + Show Details Afficher détails @@ -11041,7 +11373,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de - + Search for @@ -11050,7 +11382,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Partager les permissions de publication - + Copy RetroShare Link Copier le lien Retroshare @@ -11065,7 +11397,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Tout marquer comme non lu - + AUTHD Authentification @@ -11682,7 +12014,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11691,7 +12023,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11717,6 +12049,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11728,7 +12077,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11808,27 +12157,32 @@ p, li { white-space: pre-wrap; } Formulaire - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11850,6 +12204,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11858,7 +12213,7 @@ p, li { white-space: pre-wrap; } Le texte ci-dessous est votre propre certificat Retroshare. Envoyez-le à vos amis - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11875,12 +12230,12 @@ Plate-forme de communication décentralisée privée et sécurisée. Besoin d'aide avec RetroShare? - + Open Web Help Ouvrir l'aide Web - + Copy your Cert to Clipboard Copiez votre Certificat en mémoire. @@ -11929,7 +12284,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11938,7 +12293,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12231,14 +12586,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tout - + Reputation Réputation @@ -12248,12 +12603,12 @@ p, li { white-space: pre-wrap; } Rechercher - + Anonymous Id ID anonyme - + Create new Identity Créer une nouvelle identité @@ -12398,7 +12753,7 @@ Votes négatifs ID de l'identité - + Send message Envoyer message @@ -12470,7 +12825,7 @@ Votes négatifs Générale : - + Anonymous Anonymes @@ -12485,24 +12840,24 @@ Votes négatifs Chercher ID - + This identity is owned by you Cette identité est possédée par vous-même - - + + My own identities Mes propres identités - - + + My contacts Mes contacts - + Show Items Options d'affichage @@ -12517,7 +12872,7 @@ Votes négatifs Lié à mon noeud - + Other circles Autres cercles @@ -12576,13 +12931,18 @@ Votes négatifs subscribed (Receive/forward membership requests from others and invite list). Abonné (reçoit/transfère les demandes d'adhésion de la part d'autres et listes d'invitations). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). désabonné (reçoit seulement les listes d'invitations). - + Your status: Votre statut : @@ -12642,7 +13002,7 @@ Votes négatifs Membre - + Edit Circle Modifier le cercle @@ -12690,7 +13050,7 @@ Votes négatifs Autoriser à adhérer - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12702,12 +13062,12 @@ Ces identités ne seront bientôt plus supportées. - + [Unknown node] [Noeud inconnu] - + Unverified signature from node Signature non vérifiée, de la part du noeud @@ -12719,12 +13079,12 @@ Ces identités ne seront bientôt plus supportées. Signature non contrôlée - + [unverified] [non vérifié] - + Identity owned by you, linked to your Retroshare node Identité possédée par vous, liée à votre noeud Retroshare @@ -12848,12 +13208,12 @@ Ces identités ne seront bientôt plus supportées. Voulez-vous vraiment envoyer une invitation avec votre certificat ? - + Banned Banni - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identités</h1> <p>Dans cet onglet vous pouvez créer/éditer des <b>identités pseudo-anonymes</b>, et des <b>cercles</b>. <p><b>Les identités</b> sont utilisés pour identifier vos données de manière sécurisée : signez les messages dans les salons de tchat, les messages de forum et de canal, recevez des commentaires à l'aide du système de messagerie intégré Retroshare, publiez des commentaires après les messages de canaux, discutez en utilisant des tunnels sécurisés, etc.</p> @@ -12867,7 +13227,7 @@ Ces identités ne seront bientôt plus supportées. ID inconnu : - + positive positif @@ -13052,8 +13412,8 @@ Ces identités ne seront bientôt plus supportées. - - + + People Pers. @@ -13064,7 +13424,7 @@ Ces identités ne seront bientôt plus supportées. Votre avatar - + Linked to neighbor nodes Liée(s) aux noeuds voisins @@ -13074,7 +13434,7 @@ Ces identités ne seront bientôt plus supportées. Liée(s) aux noeuds distants - + Linked to a friend Retroshare node Liée(s) à un noeud Retroshare ami @@ -13134,7 +13494,7 @@ Ces identités ne seront bientôt plus supportées. Possédé par - + Node name: Nom de noeud : @@ -13144,7 +13504,7 @@ Ces identités ne seront bientôt plus supportées. ID de noeud : - + Really delete? Vraiment supprimer ? @@ -13182,7 +13542,22 @@ Ces identités ne seront bientôt plus supportées. Pseudonyme - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nouvelle identité @@ -13199,14 +13574,14 @@ Ces identités ne seront bientôt plus supportées. - + N/A N/A - + Edit identity Modifier l'identité @@ -13217,24 +13592,27 @@ Ces identités ne seront bientôt plus supportées. Mettre à jour - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13253,17 +13631,27 @@ Ces identités ne seront bientôt plus supportées. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Erreur lors de la récupération de la clé ! - + Error KeyID invalid Erreur ID de la clé invalide - + Unknown GpgId GpgId inconnu @@ -13273,7 +13661,7 @@ Ces identités ne seront bientôt plus supportées. Vrai nom inconnu - + Create New Identity Créer une nouvelle identité @@ -13283,7 +13671,12 @@ Ces identités ne seront bientôt plus supportées. Type - + + Choose image... + + + + @@ -13323,12 +13716,11 @@ Ces identités ne seront bientôt plus supportées. Votre avatar - Set Avatar - Mettre l'avatar + Mettre l'avatar - + Linked to your profile Liée à votre profil @@ -13338,7 +13730,7 @@ Ces identités ne seront bientôt plus supportées. Vous pouvez avoir une seule ou plusieurs identités. Elles sont utilisées lorsque vous écrivez dans des salons de tchat, forums, et dans les commentaires de chaînes. Elles agissent comme destination pour le tchat distant et pour le système de courrier distant de Retroshare. - + The nickname is too short. Please input at least %1 characters. Ce pseudonyme est trop court. Veuillez saisir au moins %1 caractères. @@ -13447,8 +13839,12 @@ Ces identités ne seront bientôt plus supportées. + Quote + Citer + + Send - Envoyer + Envoyer @@ -13606,7 +14002,7 @@ Ces identités ne seront bientôt plus supportées. - + Options Options @@ -13638,12 +14034,12 @@ Ces identités ne seront bientôt plus supportées. Assistant de configuration rapide - + RetroShare %1 a secure decentralized communication platform Retroshare %1 - Logiciel de communication sécurisé et décentralisé - + Unfinished Inachevé @@ -13776,7 +14172,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Afficher - + Make sure this link has not been forged to drag you to a malicious website. Assurez-vous que ce lien n'a pas été créé pour vous emmener vers un site Web malveillant. @@ -13821,7 +14217,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Matrice des autorisations de services - + Statistics Statistiques @@ -13850,7 +14246,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. MessageComposer - + Compose Écrire @@ -13952,7 +14348,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. - + Tags Mots clés @@ -14047,12 +14443,12 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Ajouter une citation - + Send To: Envoyer à : - + &Left Aligner à Gauche @@ -14086,7 +14482,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Mes contacts - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Bonjour, <br>Je vous recommande un(e) bon(nne) ami(e), vous pouvez lui faire confiance autant qu'à moi. <br> @@ -14112,12 +14508,12 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. - + Save Message Enregistrer le message - + Message has not been Sent. Do you want to save message to draft box? Le message n'a pas été envoyé @@ -14129,7 +14525,7 @@ Désirez-vous enregistrer le message dans les brouillons? Coller le lien Retroshare - + Add to "To" Ajouter à "A" @@ -14384,7 +14780,7 @@ Voulez-vous enregistrer votre message ? Ajouter un fichier supplémentaire - + Hi,<br>I want to be friends with you on RetroShare.<br> Salut,<br>je voudrais être ami avec vous sur RetroShare. <br> @@ -14393,12 +14789,27 @@ Voulez-vous enregistrer votre message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Vous avez une invitation de la part d'un ami - + Respond now: Répondre maintenant : @@ -14414,11 +14825,12 @@ Voulez-vous enregistrer votre message ? De : + Friend Nodes - Noeuds amis + Noeuds amis - + Bullet list (disc) Liste à puces (disque) @@ -14458,13 +14870,13 @@ Voulez-vous enregistrer votre message ? Liste ordonnée (romain majuscule) - - + + Thanks, <br> Remerciements, <br> - + Distant identity: Identité distante : @@ -14603,8 +15015,23 @@ Voulez-vous enregistrer votre message ? Message - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14616,12 +15043,12 @@ Voulez-vous enregistrer votre message ? Fichiers recommandés - + Download all Recommended Files Télécharger tous les fichiers recommandés - + Subject: Sujet : @@ -14696,12 +15123,18 @@ Voulez-vous enregistrer votre message ? Envoyer invitation - + + Message Size: + + + + File Name Nom du fichier - + + Size Taille @@ -14762,10 +15195,25 @@ Voulez-vous enregistrer votre message ? Télécharger - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Envoyer invitation ? @@ -14776,12 +15224,12 @@ Voulez-vous enregistrer votre message ? - + Download all Tout télécharger - + Print Document Imprimer le document @@ -14796,7 +15244,7 @@ Voulez-vous enregistrer votre message ? Fichiers HTML (*.htm *.html);;tous les fichiers (*) - + Load images always for this message Toujours charger les images pour ce message @@ -14937,7 +15385,7 @@ Voulez-vous enregistrer votre message ? MessagesDialog - + New Message Nouveau message @@ -14993,14 +15441,14 @@ Voulez-vous enregistrer votre message ? - + Tags Mots clés - + Inbox Boîte de réception @@ -15095,7 +15543,7 @@ Voulez-vous enregistrer votre message ? Faire suivre le(s) message(s) - + Subject Sujet @@ -15207,7 +15655,7 @@ Voulez-vous enregistrer votre message ? - + Open in a new window Ouvrir dans une nouvelle fenêtre @@ -15292,7 +15740,7 @@ Voulez-vous enregistrer votre message ? - + Drafts Brouillons @@ -15421,7 +15869,7 @@ Voulez-vous enregistrer votre message ? Répondre au message - + Delete Message Supprimer le message @@ -15432,7 +15880,7 @@ Voulez-vous enregistrer votre message ? - + Expand Développer @@ -15442,7 +15890,7 @@ Voulez-vous enregistrer votre message ? Effacer le message - + from depuis @@ -15451,6 +15899,11 @@ Voulez-vous enregistrer votre message ? Reply to invite Répondre à l'invitation + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15774,7 +16227,7 @@ Erreur remontée : - + Groups Groupes @@ -15804,19 +16257,19 @@ Erreur remontée : Importer votre liste d'amis en incluant les groupes - - + + Search - + ID ID - + Search ID Chercher ID @@ -15826,7 +16279,7 @@ Erreur remontée : - + Show Items Options d'affichage @@ -16031,19 +16484,19 @@ au moins un contact n'a pas été ajouté au groupe - + Error Erreur - + File is not writeable! Fichier impossible à écrire ! - + File is not readable! Fichier illisible ! @@ -16081,9 +16534,13 @@ au moins un contact n'a pas été ajouté au groupe NewsFeed - Log entries - Entrées du journal + Entrées du journal + + + + Activity Stream + @@ -16100,7 +16557,7 @@ au moins un contact n'a pas été ajouté au groupe C'est un test. - + Newest on top Les plus récents en haut @@ -16111,21 +16568,44 @@ au moins un contact n'a pas été ajouté au groupe + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Fil d'actualités</h1> <p>Le fil d'actualités affiche les derniers événements survenus dans votre réseau, triés selon le moment où vous les avez reçus. Cela vous donne un résumé de l'activité de vos amis. Vous pouvez configurer les événements à afficher en cliquant sur <b>Options</ b>. + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Fil d'actualités</h1> <p>Le fil d'actualités affiche les derniers événements survenus dans votre réseau, triés selon le moment où vous les avez reçus. Cela vous donne un résumé de l'activité de vos amis. Vous pouvez configurer les événements à afficher en cliquant sur <b>Options</ b>. Les divers événements affichés sont : <ul> <li>Les tentatives de connexion (utile pour ajouter de nouveaux amis et savoir qui essaie de vous contacter) </li> <li> Les nouveaux articles dans les chaînes et les forums</li> <li>Les nouvelles chaînes et forums auxquels vous pouvez vous abonner</li> <li>Les messages privés de vos amis </li> </ul> </p> - Log - Journal + Journal + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16162,22 +16642,22 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de - + Test Test - + Chat Room Salon de tchat - + Systray Icon Icônes sur la barre des tâches - + Message Message @@ -16202,12 +16682,11 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Sécurité IP - Log - Journal + Journal - + Friend Connected Ami connecté @@ -16221,7 +16700,12 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Liens - + + Activity + + + + Mails Courriels @@ -16258,7 +16742,12 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Tchat public - + + Toaster position + + + + Chat rooms Salons de tchat @@ -16283,22 +16772,22 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Sensible à la casse - + Position Position - + X Margin Axe Horizontal - + Y Margin Axe Vertical - + Systray message Message sur la barre des tâches @@ -16348,7 +16837,7 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Notifications - + Disable All Toasters Désactiver toutes les notifications grille-pain @@ -16362,7 +16851,7 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Flux - + Systray Zone de notification @@ -16508,17 +16997,16 @@ Trafic faible : 10% du trafic standard et TODO : tous les transferts de fichiers PGPKeyDialog - Dialog - Dialogue + Dialogue - + Profile info Info du profil - + Name : Nom : @@ -16573,22 +17061,21 @@ Trafic faible : 10% du trafic standard et TODO : tous les transferts de fichiers Ultime - + This profile has signed your own profile key Ce profil a signé votre propre clé de profil - Key signatures : - Signatures de clé : + Signatures de clé : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Les signatures ci-dessous certifient cryptographiquement que les propriétaires des clés listées reconnaissent la clé PGP actuelle comme authentique.</span></p></body></html> - + <!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; } @@ -16606,7 +17093,7 @@ p, li { white-space: pre-wrap; } Signer cette clé - + PGP key Clé PGP @@ -16616,22 +17103,20 @@ p, li { white-space: pre-wrap; } Ces options s'appliquent à tous les emplacement du profil : - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Cela les aide à décider, en se basant sur votre propre confiance, si ils doivent permettre des connexions depuis cette clé. Signer une clé est absolument facultatif et ne peut pas être défait, alors faites-le avec sagesse.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Cela les aide à décider, en se basant sur votre propre confiance, si ils doivent permettre des connexions depuis cette clé. Signer une clé est absolument facultatif et ne peut pas être défait, alors faites-le avec sagesse.</span></p></body></html> - + Keysigning: - Sign PGP key - Signer la clé PGP + Signer la clé PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Cliuez ici si vous voulez refuser les connexions aux noeuds authentifiés par cette clé.</p></body></html> @@ -16651,7 +17136,7 @@ p, li { white-space: pre-wrap; } Accepter connexions - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Ci-dessous la clé de profil au format PGP ASCII. Elle identifie tous les emplacements du même profil. Un "certificat Retroshare" que vous pouvez échanger pour vous faire des amis, se trouve dans les "détails" de chaque emplacement. @@ -16721,28 +17206,28 @@ p, li { white-space: pre-wrap; } KO/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Erreur : impossible d'obtenir les détails de ce contact. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algorithme de la clé fournie n'est pas supporté par Retroshare (pour l'instant uniquement les clés RSA sont supportées) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16756,7 +17241,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Le niveau de confiance est une façon d'exprimer votre propre confiance en cette clé. Cela n'est pas utilisé par le logiciel, ni partagé, mais cela peut être utile pour vous afin de vous rappeler les bonnes/mauvaises clés. @@ -16801,27 +17286,47 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Actuellement, vous n'autorisez pas les connexions de nÅ“uds Retroshare signés par cette clé. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure La signature a échoué - - Maybe password is wrong - Le mot de passe est peut-être incorrect + + Check the password! + - + Maybe password is wrong + Le mot de passe est peut-être incorrect + + + You haven't set a trust level for this key. Vous n'avez pas réglé de niveau de confiance pour cette clé. - + + Retroshare profile Profil Retroshare - + This is your own PGP key, and it is signed by : Ceci est votre propre clé PGP, et elle a été signée par : @@ -17000,8 +17505,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg PeopleDialog - - + People Pers. @@ -17018,7 +17522,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Interne - + Chat with this person Tchater avec cette personne @@ -17169,7 +17673,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Photo - + TextLabel Etiquette @@ -17213,8 +17717,8 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg - <N> Comments >> - + Comments + Commentaires @@ -17249,6 +17753,11 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Write a comment... Ecrivez un commentaire... + + + Album + Album + PhotoItem @@ -17258,12 +17767,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Formulaire - + TextLabel Etiquette - + <!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; } @@ -17359,7 +17868,7 @@ p, li { white-space: pre-wrap; } Afficher la photo - + PhotoShare PhotoShare @@ -17400,7 +17909,7 @@ avant de vouloir le modifier ! - + Stop Stop @@ -17628,12 +18137,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autoriser toutes les extensions - + Plugin look-up directories Dossiers des extensions @@ -17692,7 +18201,7 @@ comportements malveillants des extensions. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Extensions</h1> <p>Les extensions sont chargées depuis les répertoires affichés dans la liste tout en bas.</p> <p>Pour des raisons de sécurité, les extensions reconnues sont chargées automatiquement, jusqu'à ce que l'exécutable principal Retroshare ou que de la bibliothèque de plug-in ne changent. Dans un tel cas, l'utilisateur doit confirmer les plugins à nouveau. Après le démarrage du programme, vous pouvez activer un plugin manuellement en cliquant sur ​​le bouton "Activer" puis ensuite redémarrer Retroshare.</p> <p>Si vous voulez développer vos propres extensions, contactez l'équipe de développeurs, ils seront heureux de vous aider !</p> - + Plugins Extensions @@ -18090,7 +18599,7 @@ comportements malveillants des extensions. Liens - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18261,13 +18770,13 @@ comportements malveillants des extensions. Site - - + + Comments Commentaires - + Copy RetroShare Link @@ -18277,7 +18786,7 @@ comportements malveillants des extensions. Afficher l'auteur dans l'onglet gens - + Comment Commentaire @@ -18298,12 +18807,12 @@ comportements malveillants des extensions. - + Hide Cacher - + Vote up Voter pour @@ -18317,7 +18826,7 @@ comportements malveillants des extensions. \/ - + Set as read and remove item Définir comme lu et supprimer l'élément @@ -18378,7 +18887,7 @@ comportements malveillants des extensions. - + Loading Chargement @@ -18468,13 +18977,7 @@ comportements malveillants des extensions. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18484,60 +18987,50 @@ comportements malveillants des extensions. Administrateur : - - - + + + unknown inconnu - + Distribution: Distribution : - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Posts @@ -18548,7 +19041,7 @@ comportements malveillants des extensions. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18617,7 +19110,12 @@ comportements malveillants des extensions. - + + Empty + Vide + + + Copy RetroShare Link @@ -18652,7 +19150,7 @@ comportements malveillants des extensions. - + [No name] @@ -18780,8 +19278,18 @@ comportements malveillants des extensions. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19061,9 +19569,8 @@ et utiliser le bouton d'importation pour la charger PulseAddDialog - Post From: - Article de : + Article de : Account 1 @@ -19078,7 +19585,7 @@ et utiliser le bouton d'importation pour la charger Compte 3 - + Add to Pulse Ajouter a Pulse @@ -19101,17 +19608,32 @@ et utiliser le bouton d'importation pour la charger URL - + GroupLabel - + IDLabel - + + From: + De : + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19136,10 +19658,20 @@ et utiliser le bouton d'importation pour la charger Négative - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19149,14 +19681,53 @@ et utiliser le bouton d'importation pour la charger - + + Post + + + + Cancel Annuler - Post Pulse to Wire - Publier Pulse sur Wire + Publier Pulse sur Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19182,10 +19753,18 @@ et utiliser le bouton d'importation pour la charger Formulaire - - - - + + + + + Click to view picture + + + + + + + Image Image @@ -19193,44 +19772,44 @@ et utiliser le bouton d'importation pour la charger PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19240,17 +19819,17 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19260,7 +19839,7 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19268,7 +19847,7 @@ et utiliser le bouton d'importation pour la charger PulseTopLevel - + retweeted @@ -19283,7 +19862,7 @@ et utiliser le bouton d'importation pour la charger - + follow Parent Group @@ -19293,7 +19872,7 @@ et utiliser le bouton d'importation pour la charger ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19318,7 +19897,7 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19354,29 +19933,29 @@ et utiliser le bouton d'importation pour la charger - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19454,7 +20033,7 @@ et utiliser le bouton d'importation pour la charger QObject - + Confirmation Confirmation @@ -19695,7 +20274,7 @@ Les caractères <b>",|,/,\,&lt;,&gt;,*,?</b> seront rem Résultat - + Unable to make path Impossible de créer le chemin @@ -19730,7 +20309,7 @@ Les caractères <b>",|,/,\,&lt;,&gt;,*,?</b> seront rem Demande de fichier annulée - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Cette version de Retroshare utilise OpenPGP SDK. En contre partie, elle n'utilise plus le système de trousseau de clés PGP, mais possède son propre trousseau de clés partagé par toutes les instances de Retroshare. <br><br> Vous ne semblez pas posséder un tel trousseau, bien que des clés PGP apparaissent pour les comptes Retroshare existants, probablement parce que vous venez d'installer cette nouvelle version du logiciel. @@ -19886,7 +20465,7 @@ L'erreur rapportée est : secs - + TR up TR émis @@ -19931,7 +20510,7 @@ L'erreur rapportée est : désactivé - + Move IP %1 to whitelist Ajouter l'IP %1 en liste blanche @@ -19947,7 +20526,7 @@ L'erreur rapportée est : - + %1 seconds ago %1 secondes avant @@ -20032,7 +20611,7 @@ Securité : pas d'IDs anomymes - + Error Erreur @@ -20423,9 +21002,8 @@ Securité : pas d'IDs anomymes - <p>This certificate contains: - <p>Ce certificat contient : + <p>Ce certificat contient : @@ -20799,7 +21377,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 Ko @@ -21021,19 +21599,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Options d'affichage d'arborescence - Show column... - Afficher la colonne... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Trier Ordre décroissant + + + + Sort Ascending Order + Trier Ordre croissant + + + + + [no title] + + + + + Show column … + + + + Show column... + Afficher la colonne... - [no title] - [pas de titre] + [pas de titre] @@ -21469,7 +22076,7 @@ p, li { white-space: pre-wrap; } Télécharger ! - + File Fichier @@ -21484,7 +22091,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Les mauvais noms de fichiers ont été nettoyé @@ -21534,7 +22141,7 @@ Les fichiers concernés sont affichés en rouge. Sauvegarder - + Collection Editor Éditeur de collection @@ -21549,7 +22156,7 @@ Les fichiers concernés sont affichés en rouge. Compte fichiers - + Real Size: Waiting child... Taille réelle : attente d'enfant... @@ -21564,12 +22171,12 @@ Les fichiers concernés sont affichés en rouge. Ceci est un dossier. Double-cliquez pour l'étendre. - + Download files Télécharger les fichiers - + Specify... Spécifier... @@ -21818,7 +22425,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich RsFriendListModel - + Name Nom @@ -21838,7 +22445,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich IP - + Profile ID @@ -21851,10 +22458,15 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich RsGxsForumModel - + Title Titre + + + UnRead + + Date @@ -21866,7 +22478,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich Auteur - + Information for this identity is currently missing. Les informations pour cette identité sont actuellement manquantes. @@ -21904,7 +22516,7 @@ prevents the message to be forwarded to your friends. [Inconnu] - + [ ... Missing Message ... ] [ ... Message manquant... ] @@ -21912,7 +22524,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Date @@ -21972,7 +22584,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22331,7 +22943,7 @@ prevents the message to be forwarded to your friends. Nom du fichier - + Download Télécharger @@ -22410,7 +23022,7 @@ prevents the message to be forwarded to your friends. Ouvrir répertoire - + Create Collection... Créer une collection ... @@ -22430,7 +23042,7 @@ prevents the message to be forwarded to your friends. Télécharger à partir d'un fichier collection... - + Collection Collection @@ -22535,12 +23147,12 @@ prevents the message to be forwarded to your friends. Détails du contact - + Deny friend Refuser cet ami - + Chat Tchat @@ -22550,7 +23162,7 @@ prevents the message to be forwarded to your friends. Dialoguer - + Expand Déplier @@ -22820,13 +23432,13 @@ derrière un pare-feu ou un VPN (virtual private network). Découverte activée (recommandé) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor a été configuré automatiquement par Retroshare. Vous ne devriez rien avoir à changer ici. - + Discovery Off Découverte désactivée @@ -23315,7 +23927,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Network Réseau @@ -23343,7 +23955,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Status Statut @@ -23440,7 +24052,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Service Address Adresse de service @@ -23475,12 +24087,12 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs Veuillez remplir par une adresse de service - + IP Range Plage d'IP - + Reported by DHT for IP masquerading Rapporté par la DHT concernant masquerading d'IP (se fait passer pour). @@ -24156,7 +24768,7 @@ p, li { white-space: pre-wrap; } Certificat PGP manquant - + Wrong password Mauvais mot de passe @@ -24210,7 +24822,7 @@ Ce choix peut être inversé dans des paramétrages. StatisticsWindow - + Add Friend Ajouter un ami @@ -24266,7 +24878,7 @@ Ce choix peut être inversé dans des paramétrages. Matrice des autorisations des services - + DHT DHT @@ -24806,7 +25418,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24820,13 +25432,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor est hors ligne actuellement - + Tor is OK Tor est OK @@ -24835,6 +25446,31 @@ p, li { white-space: pre-wrap; } No tor configuration Pas de configuration de Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25128,35 +25764,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Vous avez %1 téléchargements terminés + You have %1 completed transfers + - You have %1 completed download - Vous avez %1 téléchargement terminé + You have %1 completed transfer + - %1 completed downloads - %1 téléchargements terminés + %1 completed transfers + - %1 completed download - %1 téléchargement terminé + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Vous avez %1 téléchargements terminés + + + You have %1 completed download + Vous avez %1 téléchargement terminé + + + %1 completed downloads + %1 téléchargements terminés + + + %1 completed download + %1 téléchargement terminé TransfersDialog - + Downloads Téléchargements @@ -25167,7 +25814,7 @@ p, li { white-space: pre-wrap; } Envois - + Name i.e: file name Nom @@ -25378,7 +26025,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Partage de fichiers</h1> <p>Retroshare utilise deux modes de transfert de fichiers : les transferts directs depuis vos amis, et les transferts distants anonymes par tunnels. En plus, le transfert de fichier est multi-source et permet l'essaimage (vous pouvez être une source pendant le téléchargement) </p> <p>Vous pouvez partager des fichiers en utilisant l'icône <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> dans la barre latérale gauche. Ces fichiers seront listés dans l'onglet "Vos fichiers". Vous pouvez décider pour chaque groupe d'amis s'ils peuvent ou pas voir ces fichiers dans l'onglet Mes amis</p> <p>L'onglet "Rechercher" liste les fichiers de vos amis et des fichiers distants qui peuvent être atteints anonymement en utilisant le système à effet tunnel à sauts multiples.</p> - + Move in Queue... Mettre en file d'attente... @@ -25472,7 +26119,7 @@ p, li { white-space: pre-wrap; } S'il vous plaît entrez un nouveau--et valide--nomdefichier - + Expand all Tout déplier @@ -25604,7 +26251,7 @@ p, li { white-space: pre-wrap; } - + Columns Colonnes @@ -25615,7 +26262,7 @@ p, li { white-space: pre-wrap; } Transferts de fichiers - + Path Chemin @@ -25625,7 +26272,7 @@ p, li { white-space: pre-wrap; } Afficher la colonne des chemins - + Could not delete preview file N'a pas pu supprimer le fichier d'aperçu @@ -25635,7 +26282,7 @@ p, li { white-space: pre-wrap; } Le réessayer ? - + Create Collection... Créer une collection ... @@ -25650,7 +26297,7 @@ p, li { white-space: pre-wrap; } Vue collection ... - + Collection Collection @@ -25896,7 +26543,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Contact inconnu @@ -25992,7 +26639,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Vous avez %1 nouveaux messages @@ -26368,7 +27015,7 @@ p, li { white-space: pre-wrap; } Créer un groupe - + Subscribe to Group S'abonner au groupe @@ -26462,8 +27109,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Afficher l'historique des modifications @@ -26474,7 +27121,7 @@ p, li { white-space: pre-wrap; } - + Preview Aperçu @@ -26499,12 +27146,12 @@ p, li { white-space: pre-wrap; } Masquer l'historique des modifications - + Edit Page Modifier la page - + Create New Wiki Page Créer une nouvelle Page Wiki @@ -26524,7 +27171,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Créer un nouveau Groupe Wiki @@ -26566,7 +27213,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -26576,12 +27223,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Rafraîchir @@ -26616,12 +27262,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26691,7 +27337,7 @@ p, li { white-space: pre-wrap; } Affichage : - + Yourself Moi @@ -26729,7 +27375,7 @@ p, li { white-space: pre-wrap; } Publier Pulse sur Wire - + RetroShare @@ -26741,7 +27387,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26749,7 +27395,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26830,8 +27476,8 @@ p, li { white-space: pre-wrap; } Formulaire - - + + Avatar Avatar @@ -26860,6 +27506,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26972,8 +27623,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Images (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Images (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_hu.ts b/retroshare-gui/src/lang/retroshare_hu.ts index 80d818c8d..7ef052108 100644 --- a/retroshare-gui/src/lang/retroshare_hu.ts +++ b/retroshare-gui/src/lang/retroshare_hu.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare verzió @@ -79,7 +79,7 @@ KezdÅ‘dhet a móka! ;) - + Only Hidden Node Csak rejtett csomópont @@ -129,12 +129,12 @@ RetroShare: Összetett keresés - + Search Criteria Keresési feltétel - + Add a further search criterion. További keresési feltétel hozzáadása. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Forma - - + + TextLabel Címke @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Eszköztár - + Icon Only Csak ikonok @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Válaszd ki az Eszköztár gombjainak stílusát! - + Icon Size = 8x8 Ikon mérte: 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Ikon mérete: 128x128 - + Status Bar ÃllapotjelzÅ‘ sáv @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Értesítési Terület elemleírásának letiltása - + Main page items: FÅ‘oldal elemei: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista - + Icon Size = 32x32 Ikon mérete: 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Avatár csere - + + TextLabel + + + + Your Avatar Picture Az Avatárod - + + Browse... + + + Add Avatar - Avatár hozzáadása + Avatár hozzáadása @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Eltávolítás - + Set your Avatar picture Avatár beállítása - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatár betöltése + Avatár betöltése AvatarWidget - - Choose avatar - - - - + Click to change your avatar Kattints az avatár megváltoztatásához @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare sávszélesség használat + + + PushButton + + - + Up + Fel + + + + Down + Le + + + + Clears the graph + + + + Show Settings Beállítások megjelenítése + TextLabel + + + + Reset Visszaállítás - Receive Rate - Fogadási arány + Fogadási arány - Send Rate - Küldési arány + Küldési arány - + Always on Top Mindig felül - Style - Stílus + Stílus - + Changes the transparency of the Bandwidth Graph A sávszélesség grafikon átlátszóságának megváltoztatása - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % átlátszóság - Save - Mentés + Mentés - Cancel - Mégse + Mégse - + Since: Ãtvitel kezdete: - Hide Settings - Beállítások elrejtése + Beállítások elrejtése BandwidthStatsWidget - + Sum Összegzett @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } Számláló - + Average Ãtlag @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments Hozzászólások @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Tetszik + + + + 0 + 0 + + + + I dislike this + Nem tetszik + + + + Toggle Message Read Status + Ãœzenet olvasottságának váltása + + + + Avatar + Avatár + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Lenyitás + + + + Set as read and remove item + Megjelölés olvasottként és eltávolítás + + + + Remove Item + + + + + Name + Név + + + + Comm value + + + + + Comment + Hozzászólás + + + + Comments + Hozzászólások + + + + Hide + Elrejt + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale Napló mérték + + + Default + Alapértelmezett + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Tetszik + + + + 0 + 0 + + + + I dislike this + Nem tetszik + + + + Toggle Message Read Status + Ãœzenet olvasottságának váltása + + + + Avatar + Avatár + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Lenyitás + + + + Set as read and remove item + Megjelölés olvasottként és eltávolítás + + + + Remove Item + + + + + Name + Név + + + + Comm value + + + + + Comment + Hozzászólás + + + + Comments + Hozzászólások + + + + Hide + Elrejt + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Társalgószobák - You have %1 new messages - %1 új üzeneted van + %1 új üzeneted van + + + You have %1 new message + %1 új üzeneted van + + + %1 new messages + %1 új üzenet + + + %1 new message + %1 új üzenet + + + + You have %1 mentions + - You have %1 new message - %1 új üzeneted van + You have %1 mention + - %1 new messages - %1 új üzenet + %1 mentions + - %1 new message - %1 új üzenet + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Összes eltávolítása - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Kattints duplán egy társalgószobára a belépéshez. Változat: - Group chat - Csoportos beszélgetés + Csoportos beszélgetés - - + Private chat Privát beszélgetés @@ -2191,17 +2404,16 @@ Kattints duplán egy társalgószobára a belépéshez. Felhasználónév elküldése ezzel: /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Ezen a fülön beállíthatod, hogy a különbözÅ‘ típusú üzenetekbÅ‘l mennyit tároljon el a RetroShare a merevlemezen és hogy mennyi elÅ‘zÅ‘ beszélgetést állítson vissza az aktuális ablakba. A maximális tárolási idÅ‘ beállítása lehetÅ‘vé teszi a régi üzenetek mellÅ‘zését, illetve segít megakadályozni, hogy az elÅ‘zmények tele legyenek kevésbé fontos beszélgetésekkel (például egyes társalgószobák vagy távoli üzenetek elÅ‘zményei). </p></body></html> - Chatlobbies - Társalgószobák + Társalgószobák - + Enabled: Engedélyezve: @@ -2222,11 +2434,12 @@ Kattints duplán egy társalgószobára a belépéshez. + Chat rooms Társalgószobák - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Kattints duplán egy társalgószobára a belépéshez. + Broadcast ÃœzenÅ‘fal - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Elmentett üzenetek (0 = végtelen): @@ -2438,8 +2657,23 @@ Kattints duplán egy társalgószobára a belépéshez. Privát beszélgetés - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Kattints duplán egy társalgószobára a belépéshez. - + is typing... éppen ír... @@ -2631,12 +2865,12 @@ after HTML conversion. a HTML átalakítás után. - + Choose your font. Válassz betütípust. - + Do you really want to physically delete the history? Tényleg törölni akarod az elÅ‘zményeket? @@ -2708,7 +2942,7 @@ a HTML átalakítás után. Ne hagyd abba a színezést X elem megtalálása után (több CPU erÅ‘forrás szükséges) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>ElÅ‘zÅ‘ keresése </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ a HTML átalakítás után. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Kiválasztott szöveg megjelölése</b><br><i>Ctrl+M</i> - + Person id: Személyazonosító @@ -2770,7 +3004,7 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.Aláiratlan - + items found. találat. @@ -2790,7 +3024,7 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.Ãrj be egy üzenetet ide - + Don't stop to color after Ne állj le a színezéssel, miután @@ -2948,12 +3182,12 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz. ConfCertDialog - + Details Részletek - + Local Address Helyi cím @@ -2964,12 +3198,12 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.KülsÅ‘ cím - + Node info: Csomópont adatai: - + Current address: Jelenlegi cím: @@ -2985,31 +3219,36 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.Port - + Include signatures Aláírásokat tartalmaz - + RetroShare RetroShare - + - + Error : cannot get peer details. Hiba: a partner adatai nem elérhetÅ‘ek. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Titkosítás - + Not connected Nem csatlakozott - + Retroshare node details Retroshare csomópont részletei - + Node name : Csomópont neve : @@ -3075,13 +3319,18 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.Ãllapot üzenet: - + + Connectivity + + + + List of known addresses: Ismert címek felsorolása: - - + + Retroshare Certificate Retroshare tanúsítvány @@ -3096,7 +3345,7 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz. - + Hidden Address Rejtett cím @@ -3107,11 +3356,12 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.nincs + <p>This certificate contains: - <p>Ez a tanúsítvány tartalmaz: + <p>Ez a tanúsítvány tartalmaz: - + <li>a <b>node ID</b> and <b>name</b> <li>egy <b>csomópont azonosítót</b> és <b>nevet</b> @@ -3124,12 +3374,12 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.egy <b>IP címet</b> és <b>portot</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Használd ezt a tanúsítványt, hogy új barátokat szerezz. Küldd el emailben, vagy juttasd el a címzettnek egyéb módon.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Ez egy csomópont <span style=" font-weight:600;">OpenSSL</span> tanúsítvánnyal ellátott azonosítója, amely a fenti <span style=" font-weight:600;">PGP</span> kulccsal lett aláírva. </p></body></html> @@ -3139,7 +3389,7 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.<html><head/><body><p>Ez az <span style=" font-weight:600;">OpenSSL</span> által használt titkosítási eljárás. Az összeköttetés a barátok csomópontjaihoz</p><p>mindig erÅ‘sen titkosított és ha a DHE jelen van, akkor az összeköttetés további </p><p>&quot;tökéletes továbbítási titkosítást&quot;.</p> használ.</body></html> - + with ­ @@ -3345,12 +3595,12 @@ A nevet kettÅ‘s kattintással hozzáadhatod a szövegszerkesztÅ‘höz.A kérelem részletei - + Peer details Partner részletei - + Name: Név: @@ -3369,12 +3619,12 @@ resources. erÅ‘forrást igényel. - + Location: Hely: - + Options Beállítások @@ -3411,12 +3661,12 @@ erÅ‘forrást igényel. Tanúsítvány beillesztése - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>A mezÅ‘be a barátod Retroshare tanúsítványát illeszd be. FIGYELEM: ez különbözik a barátod profil kulcsától. Ne illeszd be ide a barátod profil kulcsát (vagy annak egy részét), mert nem fog működni!</p></body></html> - + Add friend to group: Barát hozzáadása a csoporthoz: @@ -3426,7 +3676,7 @@ erÅ‘forrást igényel. Barát azonosítása (PGP kulcs aláírása) - + Please paste below your friend's Retroshare ID @@ -3451,7 +3701,7 @@ erÅ‘forrást igényel. - + Add as friend to connect with Barát hozzáadása @@ -3460,7 +3710,7 @@ erÅ‘forrást igényel. A baráti kérelem elfogadásához kattints a Kész gombra. - + Sorry, some error appeared Sajnálom, hiba történt @@ -3480,32 +3730,32 @@ erÅ‘forrást igényel. A barátod részletei: - + Key validity: Kulcs érvényessége: - + Profile ID: - + Signers Aláírók - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Az aláírások kriptográfiailag bizonyítják, hogy az alábbi kulcsok hitelesnek ismerik el az aktuális PGP kulcsot.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. A személy már szerepel a barátlistádon. Az újbóli felvétele csak az IP címét fogja változtatni. - + To accept the Friend Request, click the Accept button. @@ -3551,7 +3801,7 @@ erÅ‘forrást igényel. - + Certificate Load Failed A tanúsítvány betöltése sikertelen @@ -3588,12 +3838,12 @@ erÅ‘forrást igényel. Úgy tűnik, érvényes a tanúsítvány - + Not a valid Retroshare certificate! Érvénytelen Retroshare tanúsítvány! - + RetroShare Invitation RetroShare meghívás @@ -3615,12 +3865,12 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Ez a saját tanusítványod! Ugye nem saját magadat akarod ismerÅ‘sként megadni?! - + @@ -3668,7 +3918,37 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Van egy barát felkérésed tÅ‘le - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3756,12 +4036,12 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Közvetlen forrásként használat, amikor lehetséges - + IP-Addr: IP-cím: - + IP-Address IP-cím: @@ -3827,7 +4107,7 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Kulcs hozzáadása a kulcstartóhoz - + This key is already in your keyring Ez a kulcs már szerepel a kulcstartódban @@ -3888,12 +4168,12 @@ távoli üzeneteket szeretnél küldeni ennek a partnernek, <p>Ez a tanúsítvány nem tartalmaz IP-t. A felfedezésre és a DHT-re vagy utalva, hogy megtaláld. Mivel fehérlistás engedélyezést kértél, ezért egy biztonsági figyelmeztetést fogsz kapni a Hírek fülön. Itt hozzáadhatod a partner IP-jét a fehérlistához.</p> - + [Unknown] [Ismeretlen] - + Added with certificate from %1 Tanúsítvánnyal hozzáadva innen: %1 @@ -3980,7 +4260,12 @@ távoli üzeneteket szeretnél küldeni ennek a partnernek, UDP kapcsolat eredménye - + + Status + Ãllapot + + + <!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; } @@ -4402,7 +4687,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4554,7 +4839,7 @@ p, li { white-space: pre-wrap; } Nincs határ kiválasztva. - + [Unknown] [Ismeretlen] @@ -4569,7 +4854,7 @@ p, li { white-space: pre-wrap; } Eltávolítás - + Search Keresés @@ -4589,7 +4874,7 @@ p, li { white-space: pre-wrap; } Ismert csomópontok által aláírva - + Edit Circle Kör szerkesztése @@ -4609,12 +4894,12 @@ p, li { white-space: pre-wrap; } Névtelen azonosító - + Circle name Kör neve - + Update Frissít @@ -4640,7 +4925,7 @@ p, li { white-space: pre-wrap; } PGP-hez linkelt azonosító - + Add Member Tag hozzáadása @@ -4784,7 +5069,7 @@ p, li { white-space: pre-wrap; } - + Attachments Mellékletek @@ -4830,7 +5115,7 @@ p, li { white-space: pre-wrap; } Fájlok megragadása és bedobása a keresési találatokból - + Paste RetroShare Links RetroShare linkek beillesztése @@ -4840,7 +5125,7 @@ p, li { white-space: pre-wrap; } RetroShare hivatkozás beillesztése - + Drop file error. Hibás hozzáadás. @@ -4867,17 +5152,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - A fájl már hozzá van adva és hashelve van. + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + A fájl már hozzá van adva és hashelve van. + + + Please add a Subject Kérlek, adj meg egy tárgyat @@ -4908,12 +5217,12 @@ p, li { white-space: pre-wrap; } Valóban generálni szeretnél %1 üzenetet ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Fájlokat fogsz hozzáadni a megosztásodhoz. Biztos ezt szeretnéd tenni? - + Edit Channel Post Csatornabejegyzés létrehozása @@ -4933,7 +5242,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Nem birtokolt fájlok beküldése a csatornára. @@ -5025,7 +5334,7 @@ p, li { white-space: pre-wrap; } - + No Forum Nincs fórum @@ -5479,7 +5788,7 @@ az importálás gombot, hogy betöltsd. DHTGraphSource - + users felhasználók @@ -6482,7 +6791,7 @@ az importálás gombot, hogy betöltsd. FlatStyle_RDM - + Friends Directories Barátok mappái @@ -6988,7 +7297,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Barát keresése - + Mark all Jelöld mind @@ -7002,7 +7311,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz FriendsDialog - + Edit status message Ãllapot szerkesztése @@ -7106,7 +7415,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Retroshare üzenÅ‘fal: az ide írt üzeneteidet az összes barátod láthatja. - + Network Hálózat @@ -7171,7 +7480,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz A csomópont mezÅ‘ legalább 3 karaktert kell tartalmazzon - + Failed to generate your new certificate, maybe PGP password is wrong! Az új tanúsítványod létrehozása meghiúsult, talán rossz PGP jelszót adtál meg. @@ -7214,7 +7523,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz MeglévÅ‘ profil használata - + Node name Csomópont neve @@ -7481,12 +7790,12 @@ Most már átmásolhatod egy másik számítógépre - + Profile generation failure A profil létrehozása meghiúsult - + Missing PGP certificate Hiányzó PGP tanusítvány @@ -7864,7 +8173,7 @@ p, li { white-space: pre-wrap; } Útválasztó statisztikái - + GroupBox @@ -7929,7 +8238,7 @@ p, li { white-space: pre-wrap; } - + Details Részletek @@ -7952,7 +8261,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Nyilvántartott kulcsok @@ -8153,7 +8462,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Cím @@ -8163,13 +8472,30 @@ p, li { white-space: pre-wrap; } Cím keresése - - + + + + Description Leírás - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Leírás keresése @@ -8179,42 +8505,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - CsökkenÅ‘ sorbarendezés + CsökkenÅ‘ sorbarendezés - Sort Ascending Order - NövekvÅ‘ sorbarendezés + NövekvÅ‘ sorbarendezés - Sort by Name - Rendezés név szerint + Rendezés név szerint - Sort by Popularity - Rendezés népszerűség szerint + Rendezés népszerűség szerint - Sort by Last Post - Rendezés utolsó üzenet szerint + Rendezés utolsó üzenet szerint - Sort by Number of Posts - Bejegyzések száma szerinti rendezés + Bejegyzések száma szerinti rendezés - Sort by Unread - Olvasatlanság szerinti rendezés + Olvasatlanság szerinti rendezés - + You are admin (modify names and description using Edit menu) @@ -8229,40 +8548,35 @@ p, li { white-space: pre-wrap; } Azonosító - - + + Last Post Utolsó bejegyzés - + + Name Név - - Unread - - - - + Popularity - - + + Never Soha - Display - Megjelenítés beállításai + Megjelenítés beállításai - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8411,7 +8725,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Csatornák @@ -8432,12 +8746,12 @@ p, li { white-space: pre-wrap; } Csatornáim - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Feliratkozások @@ -8938,7 +9252,7 @@ p, li { white-space: pre-wrap; } - + Add new post Új hozzászólás @@ -9038,12 +9352,12 @@ p, li { white-space: pre-wrap; } - + Files Fájlok - + Comments Hozzászólások @@ -9054,18 +9368,18 @@ p, li { white-space: pre-wrap; } - + Feeds Hírcsatornák - - + + Click to switch to list view - + Show unread posts only @@ -9075,12 +9389,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9140,7 +9454,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9155,12 +9469,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9236,23 +9550,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Feliratkozva - - Subscribe Feliratkozás - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nincs csatorna kiválasztva @@ -9274,11 +9601,6 @@ p, li { white-space: pre-wrap; } Channel Post Ãœzenet - - - new message(s) - - GxsCircleItem @@ -9804,7 +10126,7 @@ mielÅ‘tt hozzászólhatsz Új fonál indítása a kiválasztotta fórumban - + Search forums Fórumok keresése @@ -9813,12 +10135,12 @@ mielÅ‘tt hozzászólhatsz Utolsó beküldés - + New Thread Új szál - + Threaded View Fa nézet @@ -9828,19 +10150,19 @@ mielÅ‘tt hozzászólhatsz Egyszerű nézet - - + + Title Cím - - + + Date Dátum - + Author SzerzÅ‘ @@ -9855,7 +10177,17 @@ mielÅ‘tt hozzászólhatsz Töltés - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9912,23 +10244,23 @@ mielÅ‘tt hozzászólhatsz Tartalom keresése - + No name Nincs név - - + + Reply Válasz - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9966,12 +10298,12 @@ mielÅ‘tt hozzászólhatsz Megjelölés olvasatlanként - + Copy RetroShare Link RetroShare hivatkozás másolása - + Hide Elrejt @@ -9984,7 +10316,7 @@ mielÅ‘tt hozzászólhatsz [Letiltva] - + [unknown] [ismeretlen] @@ -10014,8 +10346,8 @@ mielÅ‘tt hozzászólhatsz - - + + Distribution @@ -10118,7 +10450,7 @@ mielÅ‘tt hozzászólhatsz Eredeti üzenet - + New thread Új szál @@ -10127,7 +10459,7 @@ mielÅ‘tt hozzászólhatsz Elolvasott / nem olvasott - + Edit Szerkesztés @@ -10183,7 +10515,7 @@ mielÅ‘tt hozzászólhatsz Mutasd a szerzÅ‘t a Személyek fülön - + Author's reputation SzerzÅ‘ megitélése @@ -10203,7 +10535,7 @@ mielÅ‘tt hozzászólhatsz - + <b>Loading...<b> @@ -10243,6 +10575,11 @@ mielÅ‘tt hozzászólhatsz Storage Tárolás + + + Last seen at friends: + + Moderators @@ -10320,7 +10657,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. %1, %2 írta: - + Forum name Fórum címe @@ -10352,11 +10689,6 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Forum Post Fórum hozzászólás - - - new message(s) - - GxsForumsDialog @@ -10797,7 +11129,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Nyomtatási kép - + Unsubscribe Leiratkozás @@ -10812,7 +11144,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Megnyitás új fülön - + Remove this search @@ -10822,12 +11154,12 @@ megjelenítve és nem lesz továbbítva a barátaid számára. - + Request data - + Show Details Mutasd a részleteket @@ -10894,7 +11226,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. - + Search for @@ -10903,7 +11235,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Nyilvános engedélyek megosztása - + Copy RetroShare Link RetroShare hivatkozás másolása @@ -10918,7 +11250,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Összes megjelölése olvasatlanként - + AUTHD HITELESÃTETT @@ -11519,7 +11851,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11528,7 +11860,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11554,7 +11886,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11632,27 +11964,32 @@ p, li { white-space: pre-wrap; } Forma - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11674,6 +12011,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11682,7 +12020,7 @@ p, li { white-space: pre-wrap; } Az alábbi szöveghalmaz a te RetroShare tanusítványod. Küld el a barátaidnak. - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11699,12 +12037,12 @@ privát és biztonságos decentralizált kommunikációt nyújtó szolgáltatás Segítségre van szükséged? - + Open Web Help Nyisd meg a segítség honlapot - + Copy your Cert to Clipboard Tanúsítványod másolása a vágólapra @@ -11752,17 +12090,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11777,7 +12110,12 @@ new short format RetroShare meghívó - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Mentés mint... @@ -12042,14 +12380,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Összes - + Reputation Népszerűség @@ -12059,12 +12397,12 @@ p, li { white-space: pre-wrap; } Keresés - + Anonymous Id Névtelen azonosító - + Create new Identity Új személyazonosság létrehozása @@ -12208,7 +12546,7 @@ p, li { white-space: pre-wrap; } Személyazonosság azonosító - + Send message Ãœzenet elküldése @@ -12280,7 +12618,7 @@ p, li { white-space: pre-wrap; } Ãltalánosan - + Anonymous Névtelen @@ -12295,24 +12633,24 @@ p, li { white-space: pre-wrap; } Azonosító keresése - + This identity is owned by you Ez a személyazonosság a tiéd - - + + My own identities Saját személyazonosságaim - - + + My contacts Kapcsolataim - + Show Items Elemek megjelenítése @@ -12327,7 +12665,7 @@ p, li { white-space: pre-wrap; } - + Other circles Más körök @@ -12386,13 +12724,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: Tagsági állapotod: @@ -12452,7 +12795,7 @@ p, li { white-space: pre-wrap; } Tag - + Edit Circle Kör szerkesztése @@ -12500,7 +12843,7 @@ p, li { white-space: pre-wrap; } Tagság megadása - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12512,12 +12855,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + [Unknown node] [Ismeretlen csomópont] - + Unverified signature from node A csomópont aláírása nem hitelesített @@ -12529,12 +12872,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.EllenÅ‘rizetlen aláírás - + [unverified] [hitelesítetlen] - + Identity owned by you, linked to your Retroshare node A te személyazonosságod, linkelve a Retroshare csomópontodhoz @@ -12654,12 +12997,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Küldesz meghívót - + Banned Letiltva - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Személyazonosságok</h1> <p>Ezen a fülön készíthetsz új vagy szerkesztheted a már meglévÅ‘ <b>ál-névtelen személyazonosságokat</b>, és <b>köröket</b>.</p> <p>A <b>személyazonosságokat</b> használjuk az adataid biztonságos azonosításához: aláírják az üzeneteid a társalgószobákban, a fórum- és csatorna hozzászólásaidat, visszajelzést kapnak a Retroshare beépített e-mail rendszerén keresztül, hozzászólhatsz csatorna bejegyzésekhez, biztonságos alagutakon keresztül beszélgethetsz, stb.</p> <p>Személyazonosságaidat<b>aláírhatod</b> a Retroshare csomópontod tanúsítványával. Az aláírt Személyazonosságok jobban ellenÅ‘rizhetÅ‘bbek ezért megbízhatóbbnak számíthatnak, ugyanakkor hozzá vannak kapcsolva a csomópontod IP címéhez.</p> <p>Az úgynevezett<b>Ãlnevek</b> segítségével névtelenséged megÅ‘rzésével léphetsz kapcsolatba a többiekkel. Nem visszakereshetÅ‘, ezáltal senki sem tudhatja, hogy pontosan kihez is tartozik egy ilyen személyazonosság.</p> <p>A <b>Körök</b> tulajdonképpen a hálózat személyazonosságainak (Ãlnév típusú, vagy aláírt) részhalmazai. Felhasználhatók arra, hogy szigorítsuk a hozzáférést egy fórumhoz, csatornához, stb. </p> <p>Egy <b>kör</b> szűkíthetÅ‘ további körökkel, ezáltal láthatatlanná téve bizonyos tartalmakat olyanok számára akik nem tagjai a szűkebb köröknek. SÅ‘t egy kör önmaga is lehet korlátozott, ez azt jelenti, hogy csak a meghívott személyek számára lesz látható a tartalom.</p> @@ -12668,7 +13011,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ismeretlen azonosító: - + positive @@ -12837,8 +13180,8 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - - + + People Személyek @@ -12849,7 +13192,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Saját avatár - + Linked to neighbor nodes @@ -12859,7 +13202,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Linked to a friend Retroshare node @@ -12919,7 +13262,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Node name: @@ -12929,7 +13272,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Csomópont azonosító : - + Really delete? Tényleg törlöd? @@ -12967,7 +13310,22 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ãlnév - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Új személyazonosság @@ -12984,14 +13342,14 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + N/A N/A - + Edit identity Személyazonosság szerkesztése @@ -13002,24 +13360,27 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Frissít - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13038,17 +13399,27 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Hiba a kulcs beolvasásakor! - + Error KeyID invalid Hiba, érvénytelen Kulcs azonosító - + Unknown GpgId Ismeretlen Gpg azonosító @@ -13058,7 +13429,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ismeretlen igazi név - + Create New Identity Új személyazonosság létrehozása @@ -13068,7 +13439,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Típus - + + Choose image... + + + + @@ -13108,12 +13484,11 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Saját avatár - Set Avatar - Avatár beállítása + Avatár beállítása - + Linked to your profile @@ -13123,7 +13498,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Rendelkezhetsz egy vagy több személyazonossággal. Ãrhatsz velük társalgószobákba, hozzászólhatsz fórumokhoz és csatorna bejegyzésekhez. Végpontként viselkednek távoli beszélgetések valamint Retroshare távoli üzenetküldés esetén. - + The nickname is too short. Please input at least %1 characters. @@ -13232,8 +13607,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. + Quote + Idézés + + Send - Küldés + Küldés @@ -13391,7 +13770,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Options Beállítások @@ -13423,12 +13802,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Gyors beállítások varázsló - + RetroShare %1 a secure decentralized communication platform RetroShare %1 egy biztonságos, központosítatlan kommunikációs platform - + Unfinished Befejezetlen @@ -13561,7 +13940,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Mutat - + Make sure this link has not been forged to drag you to a malicious website. Bizonyosodj meg róla, hogy ez a hivatkozás nem egy veszélyes weboldalra mutat. @@ -13606,7 +13985,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Szolgáltatás jogosultságok mátrix - + Statistics Statisztika @@ -13635,7 +14014,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.MessageComposer - + Compose Ãrás @@ -13737,7 +14116,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Tags Címkék @@ -13832,12 +14211,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Hosszabb idézet - + Send To: Küldés neki: - + &Left &Bal @@ -13871,7 +14250,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Kapcsolataim - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Szia,<br>Szeretném a figyelmedbe ajánlani egy barátomat. Ha bennem megbízol, benne is megbízhatsz. <br> @@ -13897,12 +14276,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Save Message Ãœzenet mentése - + Message has not been Sent. Do you want to save message to draft box? Az üzenet nem lett elküldve. @@ -13914,7 +14293,7 @@ Szeretnéd piszkozatként menteni az üzenetet? RetroShare link beillesztése - + Add to "To" Hozzáadás címzettként @@ -14169,7 +14548,7 @@ Szeretnéd menteni az üzenetet? Extra fájl hozzáadása - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -14178,12 +14557,27 @@ Szeretnéd menteni az üzenetet? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Van egy barát felkérésed - + Respond now: Válasz most: @@ -14199,11 +14593,12 @@ Szeretnéd menteni az üzenetet? Feladó: + Friend Nodes - Barát csomópontok + Barát csomópontok - + Bullet list (disc) @@ -14243,13 +14638,13 @@ Szeretnéd menteni az üzenetet? - - + + Thanks, <br> Kösz, <br> - + Distant identity: Távoli személyazonosság: @@ -14388,8 +14783,23 @@ Szeretnéd menteni az üzenetet? Ãœzenet - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14401,12 +14811,12 @@ Szeretnéd menteni az üzenetet? Ajánlott fájlok - + Download all Recommended Files Az összes ajánlott fájl letöltése - + Subject: Tárgy: @@ -14481,12 +14891,18 @@ Szeretnéd menteni az üzenetet? Meghívó küldése - + + Message Size: + + + + File Name Fájlnév - + + Size Méret @@ -14547,22 +14963,37 @@ Szeretnéd menteni az üzenetet? Letöltés - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Küldesz meghívót? - + Download all Az összes letöltése - + Print Document Dokumentum nyomtatása @@ -14577,7 +15008,7 @@ Szeretnéd menteni az üzenetet? Html-Fájlok (*.htm *.html);;Összes fájl (*) - + Load images always for this message Ezen üzenethez mindig töltse be a képeket @@ -14718,7 +15149,7 @@ Szeretnéd menteni az üzenetet? MessagesDialog - + New Message Új üzenet @@ -14774,14 +15205,14 @@ Szeretnéd menteni az üzenetet? - + Tags Címkék - + Inbox Beérkezett üzenetek @@ -14876,7 +15307,7 @@ Szeretnéd menteni az üzenetet? Ãœzenet továbbítása - + Subject Tárgy @@ -14988,7 +15419,7 @@ Szeretnéd menteni az üzenetet? - + Open in a new window Megnyitás új ablakban @@ -15073,7 +15504,7 @@ Szeretnéd menteni az üzenetet? - + Drafts Piszkozatok @@ -15194,7 +15625,7 @@ Szeretnéd menteni az üzenetet? Válasz - + Delete Message Ãœzenet törlése @@ -15205,7 +15636,7 @@ Szeretnéd menteni az üzenetet? - + Expand Lenyitás @@ -15215,7 +15646,7 @@ Szeretnéd menteni az üzenetet? Eltávolítás - + from tÅ‘le @@ -15224,6 +15655,11 @@ Szeretnéd menteni az üzenetet? Reply to invite Válaszolj a meghívásra + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15541,7 +15977,7 @@ Reported error: - + Groups Csoportok @@ -15571,19 +16007,19 @@ Reported error: barátlista visszaállítása a megtartott csoportokkal - - + + Search Keresés - + ID Azonosító - + Search ID Azonosító keresése @@ -15593,7 +16029,7 @@ Reported error: - + Show Items Elemek megjelenítése @@ -15797,19 +16233,19 @@ legalább egy partner nem lett hozzáadva a csoporthoz - + Error Hiba - + File is not writeable! A fájl nem írható! - + File is not readable! A fájl nem olvasható! @@ -15847,9 +16283,13 @@ legalább egy partner nem lett hozzáadva a csoporthoz NewsFeed - Log entries - Naplóbejegyzések + Naplóbejegyzések + + + + Activity Stream + @@ -15866,7 +16306,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Ez egy teszt. - + Newest on top A legújabb felül @@ -15877,20 +16317,39 @@ legalább egy partner nem lett hozzáadva a csoporthoz - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log - Napló + Napló + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15927,22 +16386,22 @@ legalább egy partner nem lett hozzáadva a csoporthoz - + Test Teszt - + Chat Room Társalgószoba - + Systray Icon Tálca ikon - + Message Ãœzenet @@ -15967,12 +16426,11 @@ legalább egy partner nem lett hozzáadva a csoporthoz IP biztonság - Log - Napló + Napló - + Friend Connected Kapcsolódó ismerÅ‘s @@ -15986,7 +16444,12 @@ legalább egy partner nem lett hozzáadva a csoporthoz Hivatkozások - + + Activity + + + + Mails Levelek @@ -16023,7 +16486,12 @@ legalább egy partner nem lett hozzáadva a csoporthoz Csoport beszélgetés - + + Toaster position + + + + Chat rooms Társalgószobák @@ -16036,22 +16504,22 @@ legalább egy partner nem lett hozzáadva a csoporthoz Kis- és nagybetű érzékeny - + Position Pozíció - + X Margin X margó - + Y Margin Y margó - + Systray message Tálca üzenet @@ -16101,7 +16569,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Értesítés - + Disable All Toasters @@ -16115,7 +16583,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Hírcsatorna - + Systray Rendszertálca @@ -16257,17 +16725,16 @@ legalább egy partner nem lett hozzáadva a csoporthoz PGPKeyDialog - Dialog - Párbeszéd + Párbeszéd - + Profile info Profil adatok - + Name : Név : @@ -16322,22 +16789,21 @@ legalább egy partner nem lett hozzáadva a csoporthoz Teljes - + This profile has signed your own profile key - Key signatures : - Kulcs aláírások: + Kulcs aláírások: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta: ez egyfajta segítség is a többiek számára. Az aláírások kriptográfiailag bizonyítják, hogy az alábbi kulcsok hitelesnek ismerik el az aktuális PGP kulcsot.</span></p></body></html> - + <!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; } @@ -16351,7 +16817,7 @@ p, li { white-space: pre-wrap; } Ãrd alá a kulcsot - + PGP key PGP kulcs @@ -16361,22 +16827,20 @@ p, li { white-space: pre-wrap; } Ezek a beállítások a következÅ‘ profil összes csomópontjára érvényesek: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Ez segíthet nekik eldönteni, hogy elfogadják-e a kapcsolódást az adott kulcs tulajdonosától. Egy kulcs aláírása csak egy lehetÅ‘ség, de visszavonhatatlan. Ezért fontold meg és dönts okosan.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Ez segíthet nekik eldönteni, hogy elfogadják-e a kapcsolódást az adott kulcs tulajdonosától. Egy kulcs aláírása csak egy lehetÅ‘ség, de visszavonhatatlan. Ezért fontold meg és dönts okosan.</span></p></body></html> - + Keysigning: - Sign PGP key - PGP kulcs aláírása + PGP kulcs aláírása - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16396,7 +16860,7 @@ p, li { white-space: pre-wrap; } Kapcsolatok elfogadása - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16466,28 +16930,28 @@ p, li { white-space: pre-wrap; } kB/másodpercenként - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Hiba: a partner adatai nem elérhetÅ‘ek. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) A RetroShare nem támogatja a kulcsot. (Jelenleg csak RSA kulcsok engedélyezettek) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16501,7 +16965,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16546,27 +17010,47 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Hibás aláírás - - Maybe password is wrong - Talán rossz a jelszó + + Check the password! + - + Maybe password is wrong + Talán rossz a jelszó + + + You haven't set a trust level for this key. - + + Retroshare profile RetroShare profil - + This is your own PGP key, and it is signed by : @@ -16745,8 +17229,7 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen PeopleDialog - - + People Személyek @@ -16763,7 +17246,7 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen BelsÅ‘ - + Chat with this person Beszélgetés ezzel a személlyel @@ -16910,7 +17393,7 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Fénykép - + TextLabel Címke @@ -16954,8 +17437,8 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen - <N> Comments >> - + Comments + Hozzászólások @@ -16990,6 +17473,11 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Write a comment... Hozzászólás írása... + + + Album + Album + PhotoItem @@ -16999,12 +17487,12 @@ Figyelmeztetés: az Ãtvitel beállításainál Nem engedélyezted a közvetlen Forma - + TextLabel Címke - + <!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; } @@ -17100,7 +17588,7 @@ p, li { white-space: pre-wrap; } Fénykép megnézése - + PhotoShare Fényképmegosztás @@ -17140,7 +17628,7 @@ requesting to edit it! - + Stop Megállítás @@ -17368,12 +17856,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Összes beépülÅ‘ engedélyezése - + Plugin look-up directories BeéplÅ‘k könyvtárai @@ -17423,7 +17911,7 @@ lesznek ellenÅ‘rízve. Alapállapotban a hash érték ellenÅ‘rzése megvéd a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - + Plugins BeépülÅ‘k @@ -17805,7 +18293,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. Hivatkozások - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17968,13 +18456,13 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. Oldal - - + + Comments Hozzászólások - + Copy RetroShare Link @@ -17984,7 +18472,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. Mutasd a szerzÅ‘t a Személyek fülön - + Comment Hozzászólás @@ -18005,12 +18493,12 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - + Hide Elrejt - + Vote up Szavazás mellette @@ -18024,7 +18512,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. \/ - + Set as read and remove item Megjelölés olvasottként és eltávolítás @@ -18085,7 +18573,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - + Loading Töltés @@ -18175,13 +18663,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18191,60 +18673,50 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. Adminisztrátor: - - - + + + unknown ismeretlen - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Bejegyzések @@ -18255,7 +18727,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18324,7 +18796,12 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - + + Empty + Ãœres + + + Copy RetroShare Link @@ -18359,7 +18836,7 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - + [No name] @@ -18487,8 +18964,18 @@ a kártevÅ‘ként működÅ‘ beépülÅ‘k használatától. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18758,9 +19245,8 @@ az importálás gombot, hogy betöltsd. PulseAddDialog - Post From: - Küldés ebbÅ‘l: + Küldés ebbÅ‘l: Account 1 @@ -18775,7 +19261,7 @@ az importálás gombot, hogy betöltsd. Profil 3 - + Add to Pulse Pulzushoz adás @@ -18798,17 +19284,32 @@ az importálás gombot, hogy betöltsd. URL - + GroupLabel - + IDLabel - + + From: + Feladó: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18833,10 +19334,20 @@ az importálás gombot, hogy betöltsd. rossz - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18846,14 +19357,53 @@ az importálás gombot, hogy betöltsd. - + + Post + + + + Cancel Mégse - Post Pulse to Wire - Pulzus küldése a vezetékhez + Pulzus küldése a vezetékhez + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18879,10 +19429,18 @@ az importálás gombot, hogy betöltsd. Forma - - - - + + + + + Click to view picture + + + + + + + Image Kép @@ -18890,44 +19448,44 @@ az importálás gombot, hogy betöltsd. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18937,17 +19495,17 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18957,7 +19515,7 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18965,7 +19523,7 @@ az importálás gombot, hogy betöltsd. PulseTopLevel - + retweeted @@ -18980,7 +19538,7 @@ az importálás gombot, hogy betöltsd. - + follow Parent Group @@ -18990,7 +19548,7 @@ az importálás gombot, hogy betöltsd. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19015,7 +19573,7 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19051,29 +19609,29 @@ az importálás gombot, hogy betöltsd. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19151,7 +19709,7 @@ az importálás gombot, hogy betöltsd. QObject - + Confirmation MegerÅ‘sítés @@ -19393,7 +19951,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek le lesznek cs Eredmény - + Unable to make path Hibás útvonal @@ -19428,7 +19986,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek le lesznek cs Fájl kérése megszakítva - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. A RetroShare ezen verziója OpenPGP-SDK-t használ. Ennek hála, nem használja a rendszer PGP kulcstartóját, viszont van egy saját kulcstartója, amit az összes futó RetroShare elérhet. <br><br>Úgy tűnik, hogy még nem rendelkezel ilyen kulcstartóval annak ellenére, hogy már létrehozott RetroShare fiókjaidban szerepelnek PGP kulcsok. Ez valószínűleg azért lehetséges, mert most frissítettél az alkalmazás új verziójára. @@ -19575,7 +20133,7 @@ A hibajelentés: másodpercek - + TR up @@ -19620,7 +20178,7 @@ A hibajelentés: leállítva - + Move IP %1 to whitelist @@ -19636,7 +20194,7 @@ A hibajelentés: - + %1 seconds ago %1 másodperccel ezelÅ‘tt @@ -19721,7 +20279,7 @@ Biztonság: névtelen azonosítók nem engedélyezettek - + Error Hiba @@ -20112,9 +20670,8 @@ Biztonság: névtelen azonosítók nem engedélyezettek - <p>This certificate contains: - <p>Ez a tanúsítvány tartalmaz: + <p>Ez a tanúsítvány tartalmaz: @@ -20488,7 +21045,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20710,19 +21267,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Fa nézet beállítása - Show column... - Mutatandó oszlop... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + CsökkenÅ‘ sorbarendezés + + + + Sort Ascending Order + NövekvÅ‘ sorbarendezés + + + + + [no title] + + + + + Show column … + + + + Show column... + Mutatandó oszlop... - [no title] - [nincs cím] + [nincs cím] @@ -21158,7 +21744,7 @@ p, li { white-space: pre-wrap; } Letöltés! - + File Fájl @@ -21173,7 +21759,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Rossz fájlnevek javítva @@ -21223,7 +21809,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Mentés - + Collection Editor Kollekció szerkesztÅ‘ @@ -21238,7 +21824,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Fájlok száma - + Real Size: Waiting child... Valódi méret: Várakozás a gyerekre... @@ -21253,12 +21839,12 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Ez egy könyvtár. Kattints duplán a kibontásához. - + Download files Fájlok letöltése - + Specify... Meghatározás... @@ -21505,7 +22091,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Név @@ -21525,7 +22111,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21538,10 +22124,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Cím + + + UnRead + + Date @@ -21553,7 +22144,7 @@ If you believe it is correct, remove the corresponding line from the file and re SzerzÅ‘ - + Information for this identity is currently missing. A személyazonossághoz tartozó információ jelenleg hiányzik. @@ -21592,7 +22183,7 @@ prevents the message to be forwarded to your friends. [Ismeretlen] - + [ ... Missing Message ... ] [ ... Hiányzó üzenet ... ] @@ -21600,7 +22191,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Dátum @@ -21660,7 +22251,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22019,7 +22610,7 @@ prevents the message to be forwarded to your friends. Fájlnév - + Download Letöltés @@ -22098,7 +22689,7 @@ prevents the message to be forwarded to your friends. Mappa megnyitása - + Create Collection... Gyűjtemény létrehozása @@ -22118,7 +22709,7 @@ prevents the message to be forwarded to your friends. Letöltés kollekciófájlból... - + Collection Kollekció @@ -22223,12 +22814,12 @@ prevents the message to be forwarded to your friends. Partner részletei - + Deny friend Barát elutasítása - + Chat Beszélgetés @@ -22238,7 +22829,7 @@ prevents the message to be forwarded to your friends. Beszélgetés kezdeményezése - + Expand Lenyitás @@ -22505,13 +23096,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22977,7 +23568,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Hálózat @@ -23005,7 +23596,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Ãllapot @@ -23102,7 +23693,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Kiszolgáló címe @@ -23137,12 +23728,12 @@ If you have issues connecting over Tor check the Tor logs too. Kérlek adj meg egy szolgáltatás címet - + IP Range IP tartomány - + Reported by DHT for IP masquerading @@ -23809,7 +24400,7 @@ p, li { white-space: pre-wrap; } Hiányzó PGP tanúsítvány - + Wrong password Hibás jelszó @@ -23851,7 +24442,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Barát hozzáadása @@ -23907,7 +24498,7 @@ This choice can be reverted in settings. Szolgáltatás jogosultságok mátrix - + DHT DHT @@ -24447,7 +25038,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24457,13 +25048,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK Tor rendben @@ -24472,6 +25062,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24745,35 +25360,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - %1 letöltésed elkészült + You have %1 completed transfers + - You have %1 completed download - %1 letöltésed elkészült + You have %1 completed transfer + - %1 completed downloads - %1 elkészült letöltés + %1 completed transfers + - %1 completed download - %1 elkészült letöltés + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + %1 letöltésed elkészült + + + You have %1 completed download + %1 letöltésed elkészült + + + %1 completed downloads + %1 elkészült letöltés + + + %1 completed download + %1 elkészült letöltés TransfersDialog - + Downloads Letöltések @@ -24784,7 +25410,7 @@ p, li { white-space: pre-wrap; } Feltöltések - + Name i.e: file name Név @@ -24991,7 +25617,7 @@ p, li { white-space: pre-wrap; } Meghatározás... - + Move in Queue... Mozgatás a sorban... @@ -25085,7 +25711,7 @@ p, li { white-space: pre-wrap; } Kérlek, írj be egy új --és megfelelÅ‘-- fájlnevet - + Expand all Összes lenyitása @@ -25217,7 +25843,7 @@ p, li { white-space: pre-wrap; } - + Columns Oszlopok @@ -25228,7 +25854,7 @@ p, li { white-space: pre-wrap; } Fájl átvitelek - + Path Elérési út @@ -25238,7 +25864,7 @@ p, li { white-space: pre-wrap; } Elérési útvonal mutatása - + Could not delete preview file @@ -25248,7 +25874,7 @@ p, li { white-space: pre-wrap; } Újból megpróbálod? - + Create Collection... Gyűjtemény létrehozása @@ -25263,7 +25889,7 @@ p, li { white-space: pre-wrap; } Gyűjtemény megtekintése - + Collection Kollekció @@ -25509,7 +26135,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Ismeretlen partner @@ -25605,7 +26231,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages %1 új üzeneted van @@ -25981,7 +26607,7 @@ p, li { white-space: pre-wrap; } Csoport létrehozása - + Subscribe to Group Feliratkozás a csoporthoz @@ -26075,8 +26701,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Szerkesztési elÅ‘zmények mutatása @@ -26087,7 +26713,7 @@ p, li { white-space: pre-wrap; } - + Preview ElÅ‘nézet @@ -26112,12 +26738,12 @@ p, li { white-space: pre-wrap; } Szerkesztési elÅ‘zmények elrejtése - + Edit Page Oldal szerkesztése - + Create New Wiki Page Új wiki oldal létrehozása @@ -26137,7 +26763,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Új wiki csoport létrehozása @@ -26179,7 +26805,7 @@ p, li { white-space: pre-wrap; } IdÅ‘határ - + Create Account @@ -26189,12 +26815,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Frissítés @@ -26229,12 +26854,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26304,7 +26929,7 @@ p, li { white-space: pre-wrap; } Mutatás: - + Yourself Saját magad @@ -26342,7 +26967,7 @@ p, li { white-space: pre-wrap; } Pulzus küldése a vezetékhez - + RetroShare RetroShare @@ -26354,7 +26979,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26362,7 +26987,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26443,8 +27068,8 @@ p, li { white-space: pre-wrap; } Forma - - + + Avatar Avatár @@ -26473,6 +27098,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26585,8 +27215,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Képek (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Képek (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_it.ts b/retroshare-gui/src/lang/retroshare_it.ts index 4c0818901..389d7d42d 100644 --- a/retroshare-gui/src/lang/retroshare_it.ts +++ b/retroshare-gui/src/lang/retroshare_it.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Versione Retroshare @@ -79,7 +79,7 @@ Divertiti ;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Ricerca Avanzata - + Search Criteria Criteri di Ricerca - + Add a further search criterion. Aggiungi un altro criterio di ricerca. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + TextLabel TextLabel @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barra degli strumenti - + Icon Only Solo icona @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Scegli lo stile dei bottoni degli strumenti - + Icon Size = 8x8 Dimensione icona = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Dimensione icona = 128x128 - + Status Bar Barra di stato @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Disabilita i suggerimenti sull'icona della barra delle applicazioni - + Main page items: Elementi della pagina principale: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista degli elementi - + Icon Size = 32x32 Dimensione Icona = 32x32 @@ -828,14 +828,23 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Modifica Avatar - + + TextLabel + + + + Your Avatar Picture Il Tuo Avatar - + + Browse... + + + Add Avatar - Aggiungi Avatar + Aggiungi Avatar @@ -843,25 +852,34 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Rimuovi - + Set your Avatar picture Imposta immagine Avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Carica Avatar + Carica Avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Clicca per cambiare il tuo avatar @@ -869,7 +887,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro RetroShare Bandwidth Usage Utilizzo di Banda da parte di RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostra Impostazioni + TextLabel + + + + Reset Reimposta - Receive Rate - Velocità di Ricezione + Velocità di Ricezione - Send Rate - Velocità di Invio + Velocità di Invio - + Always on Top Sempre in Primopiano - Style - Stile + Stile - + Changes the transparency of the Bandwidth Graph Cambia la trasparenza del Grafico dell'utilizzo di Banda - + 100 100 @@ -936,30 +975,27 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro % Opacità - Save - Salva + Salva - Cancel - Annulla + Annulla - + Since: Dal: - Hide Settings - Nascondi Impostazioni + Nascondi Impostazioni BandwidthStatsWidget - + Sum Totale @@ -981,7 +1017,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Conteggio - + Average Media @@ -1115,7 +1151,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro - + Comments Commenti @@ -1193,6 +1229,85 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro + + BoardsCommentsItem + + + I like this + Mi piace + + + + 0 + 0 + + + + I dislike this + Non mi piace + + + + Toggle Message Read Status + Cambia lo stato dei messaggi letti + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Allarga + + + + Set as read and remove item + Definisci letto e rimuovi elemento + + + + Remove Item + + + + + Name + Nome + + + + Comm value + + + + + Comment + Commento + + + + Comments + + + + + Hide + Nascondi + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Log scale Scala logaritmica + + + Default + Predefinito + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Mi piace + + + + 0 + 0 + + + + I dislike this + Non mi piace + + + + Toggle Message Read Status + Cambia lo stato dei messaggi letti + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Allarga + + + + Set as read and remove item + Definisci letto e rimuovi elemento + + + + Remove Item + + + + + Name + Nome + + + + Comm value + + + + + Comment + Commento + + + + Comments + + + + + Hide + Nascondi + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chat - You have %1 new messages - Hai %1 nuovi messaggi + Hai %1 nuovi messaggi + + + You have %1 new message + Hai %1 nuovo messaggio + + + %1 new messages + %1 nuovi messaggi + + + %1 new message + %1 nuovo messaggio + + + + You have %1 mentions + - You have %1 new message - Hai %1 nuovo messaggio + You have %1 mention + - %1 new messages - %1 nuovi messaggi + %1 mentions + - %1 new message - %1 nuovo messaggio + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Rimuovi tutto - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare.Variante - Group chat - Chat di gruppo + Chat di gruppo - - + Private chat Chat privata @@ -2191,17 +2404,16 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare./me sta inviando un messaggio con /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">In questa finestra puoi impostare quanti messaggi delle aree di conversazione RetroShare conserverà salvati sul disco e quanto verrà mostrato delle previe conversazioni, per i diversi sistemi di chat. Il periodo massimo di archiviazione consente di eliminare i messaggi vecchi e previene che lo storico delle conversazioni si riempa con chiacchiere volatili (p.es. aree di conversazione e conversazioni a distanza).</p></body></html> - Chatlobbies - Gruppi di chat + Gruppi di chat - + Enabled: Abilitato: @@ -2222,11 +2434,12 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. + Chat rooms Chat room - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. + Broadcast Trasmetti - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Messaggi salvati (0 = illimitato): @@ -2438,8 +2657,23 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare.Conversazione privata - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2608,7 +2842,7 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. - + is typing... sta scrivendo... @@ -2627,12 +2861,12 @@ after HTML conversion. dopo la conversione in HTML. - + Choose your font. - + Do you really want to physically delete the history? Vuoi veramente cancellare lo storico dal disco? @@ -2704,7 +2938,7 @@ dopo la conversione in HTML. Non smettere di colorare dopo X elementi trovati (richiede più potenza CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trova precedente </b><br/><i>Ctrl+Shift+G</i> @@ -2744,12 +2978,12 @@ dopo la conversione in HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Contrassegna questo testo selezionato</b><br><i>Ctr+M</i> - + Person id: @@ -2765,7 +2999,7 @@ Double click on it to add his name on text writer. Non firmato - + items found. elementi trovati. @@ -2785,7 +3019,7 @@ Double click on it to add his name on text writer. Digitare un messaggio qui - + Don't stop to color after Non smettere di colorare dopo @@ -2943,12 +3177,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Dettagli - + Local Address Indirizzo Locale @@ -2959,12 +3193,12 @@ Double click on it to add his name on text writer. Indirizzo Esterno - + Node info: - + Current address: @@ -2980,31 +3214,36 @@ Double click on it to add his name on text writer. Porta - + Include signatures Includi firme - + RetroShare RetroShare - + - + Error : cannot get peer details. Errore: impossibile ottenere dettagli contatto - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3020,22 +3259,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Cifratura - + Not connected Non connesso - + Retroshare node details Dettagli nodo RetroShare - + Node name : Nome nodo : @@ -3070,13 +3314,18 @@ Double click on it to add his name on text writer. Messaggio di stato: - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Certificato Retroshare @@ -3091,7 +3340,7 @@ Double click on it to add his name on text writer. - + Hidden Address Indirizzi Nascosti @@ -3102,11 +3351,12 @@ Double click on it to add his name on text writer. nessuno + <p>This certificate contains: - <p>Questo certificato contiene: + <p>Questo certificato contiene: - + <li>a <b>node ID</b> and <b>name</b> <li>un <b>ID nodo</b> ed un <b>nome</b> @@ -3119,12 +3369,12 @@ Double click on it to add his name on text writer. un <b>indirizz IP</b> ed una <b>porta</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Puoi usare questo certificato per farti nuovi amici. Invialo per email, o consegnalo di persona.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Questo è l'ID del certificato <span style=" font-weight:600;">OpenSSL</span> del nodo, che è firmato con questa chiave <span style=" font-weight:600;">PGP</span> indicata sopra. </p></body></html> @@ -3134,7 +3384,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Questo è un metodo di criptazione usato da <span style=" font-weight:600;">OpenSSL</span>. La connessione ai nodi amici</p><p>è sempre pesantemente criptata e in caso sia presente il DHE la connessione utilizzerà anche </p><p>&quot;la perfetta segretezza in avanti&quot;.</p></body></html> - + with con @@ -3330,12 +3580,12 @@ Double click on it to add his name on text writer. Dettagli su richiesta - + Peer details Dettagli contatto - + Name: Nome: @@ -3353,12 +3603,12 @@ resources. Tieni conto che se aggiungi troppi amici RetroShare richiederà quantità eccessive di banda, memoria e CPU. Puoi aggiungere quanti amici vuoi, ma oltre i 40 probabilmente serviranno troppo risorse. - + Location: Località: - + Options Opzioni @@ -3395,12 +3645,12 @@ resources. Incollare il certificato - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Questo riquadro richiede il certificato Retroshare del tuo amico. ATTENZIONE: Si tratta di una cosa diversa dalla chiave di profilo del tuo amico. Non incollare la chiave di profilo del tuo amico qui (nemmeno una sua parte). Non funzionerebbe.</p></body></html> - + Add friend to group: Aggiungi i tuoi amici al gruppo: @@ -3410,7 +3660,7 @@ resources. Autenticare amico (firma chiave PGP) - + Please paste below your friend's Retroshare ID @@ -3435,7 +3685,7 @@ resources. - + Add as friend to connect with Aggiungi come amico per connettersi con @@ -3444,7 +3694,7 @@ resources. Per accettare la Richiesta di Amicizia, fai clic sul bottone Fine. - + Sorry, some error appeared Siamo spiacenti, si è verificato qualche errore @@ -3464,32 +3714,32 @@ resources. Dettagli sul tuo amico: - + Key validity: Chiave validità: - + Profile ID: - + Signers Firmatari - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Le firme qui sotto attestano crittologicamente che i possessori delle chiavi elencate riconoscono l'attuale chiave PGP come autentica.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Questo contatto è già sulla tua lista amici. Aggiungendolo potrebbe aver appena impostato l'indirizzo ip. - + To accept the Friend Request, click the Accept button. @@ -3535,7 +3785,7 @@ resources. - + Certificate Load Failed Errore caricando il certificato @@ -3572,12 +3822,12 @@ resources. Il certificato sembra valido - + Not a valid Retroshare certificate! Non è un certificato Retroshare valido! - + RetroShare Invitation Inviti RetroShare @@ -3597,12 +3847,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3650,7 +3900,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Hai una richiesta di amicizia da - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3738,12 +4018,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Usa come fonte diretta, quando disponibile - + IP-Addr: Ind. IP: - + IP-Address Indirizzo IP @@ -3809,7 +4089,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Aggiungi chiave al portachiavi. - + This key is already in your keyring Questa chiave è già presente nel portachiavi @@ -3870,12 +4150,12 @@ anche se non hai amici. <p>Questo certificato non ha indirizzo IP. Dovrai utilizzare la ricerca e la DHT per trovare il tuo amico. Dato che richiedi l'uso di una lista di IP autorizzati, l'utente sarà segnalato nella lista degli elementi di sicurezza in ingresso. Da li potrai autorizzare il suo indirizzo IP.</p> - + [Unknown] - + Added with certificate from %1 Aggiunto con certificato da %1 @@ -3962,7 +4242,12 @@ anche se non hai amici. Risultato UDP - + + Status + + + + <!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; } @@ -4384,7 +4669,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4536,7 +4821,7 @@ p, li { white-space: pre-wrap; } Nessuna cerchia limitata selezionata - + [Unknown] @@ -4551,7 +4836,7 @@ p, li { white-space: pre-wrap; } Rimuovi - + Search Cerca @@ -4571,7 +4856,7 @@ p, li { white-space: pre-wrap; } Firmato da Nodi conosciuti - + Edit Circle Modifica Circolo @@ -4591,12 +4876,12 @@ p, li { white-space: pre-wrap; } Id Anonimo - + Circle name Nome della cerchia - + Update Aggiorna @@ -4622,7 +4907,7 @@ p, li { white-space: pre-wrap; } PGP Id Collegato - + Add Member Aggiungere membro @@ -4766,7 +5051,7 @@ p, li { white-space: pre-wrap; } - + Attachments Allegati @@ -4812,7 +5097,7 @@ p, li { white-space: pre-wrap; } Sposta e lascia i files dai risultati di ricerca - + Paste RetroShare Links Incolla collegamenti di RetroShare @@ -4822,7 +5107,7 @@ p, li { white-space: pre-wrap; } Incolla collegamento RetroShare - + Drop file error. Ignora errore file. @@ -4849,17 +5134,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - File già aggiunto e codificato + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + File già aggiunto e codificato + + + Please add a Subject Aggiungi un Oggetto @@ -4890,12 +5199,12 @@ p, li { white-space: pre-wrap; } Vuoi davvero generare %1 messaggi ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Stai per aggiungere dei file che non stai condividendo veramente. Vuoi comunque che questo succeda? - + Edit Channel Post @@ -4915,7 +5224,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Stai per spedire file non di tua proprietà in un canale. @@ -5007,7 +5316,7 @@ p, li { white-space: pre-wrap; } - + No Forum Nessun forum @@ -5464,7 +5773,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari DHTGraphSource - + users utenti @@ -6471,7 +6780,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari FlatStyle_RDM - + Friends Directories Cartelle amici @@ -6977,7 +7286,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Cerca Amici - + Mark all Contrassegna tutto @@ -6991,7 +7300,7 @@ uno o più peer non sono stati aggiunti ad un gruppo FriendsDialog - + Edit status message Modificare il messaggio di stato @@ -7095,7 +7404,7 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Network Rete @@ -7160,7 +7469,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Il campo nodo richiede minimo 3 caratteri - + Failed to generate your new certificate, maybe PGP password is wrong! Impossibile generare il nuovo certificato, forse la password PGP è errata! @@ -7199,7 +7508,7 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Node name Nome nodo @@ -7466,12 +7775,12 @@ il bottone IMPORT per caricarlo - + Profile generation failure Generazione profilo fallita - + Missing PGP certificate Manca certificato PGP @@ -7843,7 +8152,7 @@ p, li { white-space: pre-wrap; } Statistiche del router - + GroupBox @@ -7908,7 +8217,7 @@ p, li { white-space: pre-wrap; } - + Details Dettagli @@ -7931,7 +8240,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Chiavi gestite @@ -8136,7 +8445,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titolo @@ -8146,13 +8455,30 @@ p, li { white-space: pre-wrap; } Ricerca titolo - - + + + + Description Descrizione - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Ricerca descrizione @@ -8162,42 +8488,27 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Ordinamento decrescente + Ordinamento decrescente - Sort Ascending Order - Ordinamento crescente + Ordinamento crescente - Sort by Name - Ordina per nome + Ordina per nome - Sort by Popularity - Ordina per popolarità + Ordina per popolarità - Sort by Last Post - Ordina per post recente + Ordina per post recente - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8212,40 +8523,35 @@ p, li { white-space: pre-wrap; } Id - - + + Last Post Ultimo post - + + Name Nome - - Unread - - - - + Popularity Popolarità - - + + Never Mai - Display - Mostra + Mostra - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8394,7 +8700,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Canali @@ -8415,12 +8721,12 @@ p, li { white-space: pre-wrap; } Miei canali - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canali sottoscritti @@ -8926,7 +9232,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -9026,12 +9332,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Commenti @@ -9042,18 +9348,18 @@ p, li { white-space: pre-wrap; } - + Feeds Dispaccio - - + + Click to switch to list view - + Show unread posts only @@ -9063,12 +9369,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9128,7 +9434,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9143,12 +9449,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9224,23 +9530,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Sottoscritto - - Subscribe Entra - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nessun Canale Selezionato @@ -9262,11 +9581,6 @@ p, li { white-space: pre-wrap; } Channel Post Post del Canale - - - new message(s) - - GxsCircleItem @@ -9784,7 +10098,7 @@ prima che tu possa commentare Avvia un nuovo argomento nel forum selezionato - + Search forums Ricerca forums @@ -9793,12 +10107,12 @@ prima che tu possa commentare Ultimo post - + New Thread Nuovo Thread - + Threaded View Vista per argomento @@ -9808,19 +10122,19 @@ prima che tu possa commentare Vista semplice - - + + Title Titolo - - + + Date Data - + Author Autore @@ -9835,7 +10149,17 @@ prima che tu possa commentare Sto caricando - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9892,23 +10216,23 @@ prima che tu possa commentare Ricerca di contenuti - + No name Nessun nome - - + + Reply Rispondi - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9946,12 +10270,12 @@ prima che tu possa commentare Segna non letto - + Copy RetroShare Link Copia collegamento RetroShare - + Hide Nascondi @@ -9964,7 +10288,7 @@ prima che tu possa commentare [Bloccato] - + [unknown] [sconosciuto] @@ -9994,8 +10318,8 @@ prima che tu possa commentare - - + + Distribution Distribuzione @@ -10098,12 +10422,12 @@ prima che tu possa commentare Messaggio Originale - + New thread - + Edit Modifica @@ -10159,7 +10483,7 @@ prima che tu possa commentare Mostra l'autore nella scheda delle persone - + Author's reputation Reputazione autore @@ -10179,7 +10503,7 @@ prima che tu possa commentare - + <b>Loading...<b> @@ -10219,6 +10543,11 @@ prima che tu possa commentare Storage + + + Last seen at friends: + + Moderators @@ -10286,7 +10615,7 @@ This message is missing. You should receive it later. Il %1, %2 ha scritto: - + Forum name Nome forum @@ -10318,11 +10647,6 @@ This message is missing. You should receive it later. Forum Post Forum Post - - - new message(s) - - GxsForumsDialog @@ -10771,7 +11095,7 @@ This message is missing. You should receive it later. Anteprima stampa - + Unsubscribe Esci @@ -10786,7 +11110,7 @@ This message is missing. You should receive it later. Apri in nuova scheda - + Remove this search @@ -10796,12 +11120,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Mostra Dettagli @@ -10868,12 +11192,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Copia Collegamento RetroShare @@ -10888,7 +11212,7 @@ This message is missing. You should receive it later. Segna tutti come da leggere - + AUTHD AUTHD @@ -11453,7 +11777,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11462,7 +11786,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11488,7 +11812,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11566,49 +11890,55 @@ p, li { white-space: pre-wrap; } Modulo - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Copia nel PortaBlocco il Certificato @@ -11656,17 +11986,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11681,7 +12006,12 @@ new short format Invito RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Salva come... @@ -11946,14 +12276,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tutto - + Reputation Reputazione @@ -11963,12 +12293,12 @@ p, li { white-space: pre-wrap; } Cerca - + Anonymous Id Id Anonimo - + Create new Identity Crea nuova identità @@ -12112,7 +12442,7 @@ p, li { white-space: pre-wrap; } ID dell'identità - + Send message Invia Messaggio @@ -12184,7 +12514,7 @@ p, li { white-space: pre-wrap; } Complessivo: - + Anonymous Anonimo @@ -12199,24 +12529,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you Questa identità ti appartiene - - + + My own identities Le mie identità - - + + My contacts Contatti - + Show Items @@ -12231,7 +12561,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12290,13 +12620,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12356,7 +12691,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Modifica Circolo @@ -12404,7 +12739,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12413,12 +12748,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12430,12 +12765,12 @@ These identities will soon be not supported anymore. - + [unverified] [nonVerificato] - + Identity owned by you, linked to your Retroshare node Identità di tua proprietà, collegata al tuo nodo Retroshare @@ -12551,17 +12886,17 @@ These identities will soon be not supported anymore. - + Banned Bloccato - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive positivo @@ -12722,8 +13057,8 @@ These identities will soon be not supported anymore. - - + + People Persone @@ -12734,7 +13069,7 @@ These identities will soon be not supported anymore. Il Tuo Avatar - + Linked to neighbor nodes Collegato a nodi adiacenti @@ -12744,7 +13079,7 @@ These identities will soon be not supported anymore. Collegato a nodi distanti - + Linked to a friend Retroshare node Collegato a un nodo RetroShare tuo amico @@ -12804,7 +13139,7 @@ These identities will soon be not supported anymore. Appartenente a - + Node name: Nome nodo: @@ -12814,7 +13149,7 @@ These identities will soon be not supported anymore. ID Nodo : - + Really delete? Cancellare davvero? @@ -12852,7 +13187,22 @@ These identities will soon be not supported anymore. Pseudonimo - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nuova identità @@ -12869,14 +13219,14 @@ These identities will soon be not supported anymore. - + N/A N/D - + Edit identity Modifica Identità @@ -12887,24 +13237,27 @@ These identities will soon be not supported anymore. Aggiorna - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12923,17 +13276,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Errore ricevendo la chiave! - + Error KeyID invalid Errore KeyId non valido - + Unknown GpgId PGP Id sconosciuto @@ -12943,7 +13306,7 @@ These identities will soon be not supported anymore. Nome reale sconosciuto - + Create New Identity Crea Nuova Identità @@ -12953,7 +13316,12 @@ These identities will soon be not supported anymore. Tipo - + + Choose image... + + + + @@ -12993,12 +13361,11 @@ These identities will soon be not supported anymore. Il Tuo Avatar - Set Avatar - Imposta Avatar + Imposta Avatar - + Linked to your profile Collegato al tuo profilo @@ -13008,7 +13375,7 @@ These identities will soon be not supported anymore. Puoi avere una o più identità. Vengono impiegate quando scrivi nelle aree di discussione, sui forum e per i commenti nei canali. Fungono da destinazione per le conversazioni a distanza e per il sistema postale a distanza di RetroShare. - + The nickname is too short. Please input at least %1 characters. Nickname troppo corto. Inserisci almeno %1 caratteri. @@ -13117,8 +13484,12 @@ These identities will soon be not supported anymore. + Quote + Cita + + Send - Invia + Invia @@ -13276,7 +13647,7 @@ These identities will soon be not supported anymore. - + Options Opzioni @@ -13308,12 +13679,12 @@ These identities will soon be not supported anymore. Auto configuratore rapido - + RetroShare %1 a secure decentralized communication platform RetroShare %1 una piattaforma di comunicazione sicura decentralizzata - + Unfinished Non finito @@ -13444,7 +13815,7 @@ Libera un po' di spazio e clicca OK. Mostra - + Make sure this link has not been forged to drag you to a malicious website. Accertati che questo link non sia stato creato per condurti a siti malevoli. @@ -13489,7 +13860,7 @@ Libera un po' di spazio e clicca OK. Matrice dei permessi sui servizi - + Statistics Statistiche @@ -13518,7 +13889,7 @@ Libera un po' di spazio e clicca OK. MessageComposer - + Compose Componi @@ -13620,7 +13991,7 @@ Libera un po' di spazio e clicca OK. - + Tags Etichette @@ -13715,12 +14086,12 @@ Libera un po' di spazio e clicca OK. Aggiungi citazione - + Send To: Invia a: - + &Left &L-Sinistra @@ -13750,7 +14121,7 @@ Libera un po' di spazio e clicca OK. Contatti - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Ciao, <br>ti raccomando un mio buon amico; ci si può fidare di lui quanto di me. <br> @@ -13777,12 +14148,12 @@ Libera un po' di spazio e clicca OK. - + Save Message Salva messaggio - + Message has not been Sent. Do you want to save message to draft box? Messaggio non inviato @@ -13794,7 +14165,7 @@ Vuoi salvarlo nelle bozze? Incolla collegamento RetroShare - + Add to "To" Aggiungi in "A:" @@ -14049,7 +14420,7 @@ Vuoi salvarlo? Aggiungi File Extra - + Hi,<br>I want to be friends with you on RetroShare.<br> Ciao,<br>vorrei essere tuo amico sul network RetroShare.<br> @@ -14058,12 +14429,27 @@ Vuoi salvarlo? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Hai una richiesta di amicizia - + Respond now: Rispondi subito: @@ -14079,11 +14465,12 @@ Vuoi salvarlo? Da: + Friend Nodes - Nodi Amici + Nodi Amici - + Bullet list (disc) Elenco puntato (disco) @@ -14123,13 +14510,13 @@ Vuoi salvarlo? Elenco ordinato (romani maiuscolo) - - + + Thanks, <br> Grazie, <br> - + Distant identity: Identità distante: @@ -14268,8 +14655,23 @@ Vuoi salvarlo? Messaggio - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14281,12 +14683,12 @@ Vuoi salvarlo? Files raccomandati - + Download all Recommended Files Scarica tutti i files raccomandati - + Subject: Oggetto: @@ -14361,12 +14763,18 @@ Vuoi salvarlo? Manda invito - + + Message Size: + + + + File Name Nome File - + + Size Dimensione @@ -14427,18 +14835,33 @@ Vuoi salvarlo? Scarica - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Scarica tutto - + Print Document Stampa Documento @@ -14453,7 +14876,7 @@ Vuoi salvarlo? HTML-Files (*.htm *.html);;Tutti Files (*) - + Load images always for this message Carica sempre le immagini per questo messaggio @@ -14594,7 +15017,7 @@ Vuoi salvarlo? MessagesDialog - + New Message Nuovo messaggio @@ -14650,14 +15073,14 @@ Vuoi salvarlo? - + Tags Etichette - + Inbox Casella di posta: @@ -14752,7 +15175,7 @@ Vuoi salvarlo? Inoltra messaggio - + Subject Oggetto @@ -14865,7 +15288,7 @@ ricerca - + Open in a new window Apri in nuova finestra @@ -14950,7 +15373,7 @@ ricerca - + Drafts Bozze @@ -15075,7 +15498,7 @@ ricerca Messaggio di risposta - + Delete Message Cancella Messaggio @@ -15086,7 +15509,7 @@ ricerca - + Expand Allarga @@ -15096,7 +15519,7 @@ ricerca Rimuovi elemento - + from Da @@ -15105,6 +15528,11 @@ ricerca Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15420,7 +15848,7 @@ Errore riportato: - + Groups Gruppi @@ -15450,19 +15878,19 @@ Errore riportato: Esporta il tuo elenco amici, inclusi i gruppi - - + + Search - + ID ID - + Search ID @@ -15472,7 +15900,7 @@ Errore riportato: - + Show Items @@ -15676,19 +16104,19 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Error Errore - + File is not writeable! Non è possibile scrivere il file! - + File is not readable! Non è possibile leggere il file! @@ -15727,7 +16155,7 @@ uno o più peer non sono stati aggiunti ad un gruppo NewsFeed - Log entries + Activity Stream @@ -15745,7 +16173,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Questo è un test. - + Newest on top Più recenti in cima @@ -15756,20 +16184,35 @@ uno o più peer non sono stati aggiunti ad un gruppo - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15806,22 +16249,22 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Test Test - + Chat Room - + Systray Icon Icona riquadro sistema - + Message Messaggio @@ -15846,12 +16289,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Sicurezza IP - - Log - - - - + Friend Connected Amico connesso @@ -15902,27 +16340,37 @@ uno o più peer non sono stati aggiunti ad un gruppo Conversazione di gruppo - + + Toaster position + + + + Chat rooms Chat room - + Position Posizione - + + Activity + + + + X Margin Margine X - + Y Margin Margine Y - + Systray message Messaggio riquadro sistema @@ -15973,7 +16421,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Notifica - + Disable All Toasters Disabilita tutte le notifiche del Toaster @@ -15987,7 +16435,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Dispaccio - + Systray Riquadro sistema @@ -16133,17 +16581,16 @@ Basso Traffico: 10% di traffico standard e TODO: sospende tutti i trasferimenti PGPKeyDialog - Dialog - Dialogo + Dialogo - + Profile info - + Name : Nome: @@ -16198,22 +16645,21 @@ Basso Traffico: 10% di traffico standard e TODO: sospende tutti i trasferimenti Ultimo - + This profile has signed your own profile key - Key signatures : - Firme chiave : + Firme chiave : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Le firme qui sotto attestano crittologicamente che i possessori delle chiavi elencate riconoscono l'attuale chiave PGP come autentica.</span></p></body></html> - + <!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; } @@ -16227,7 +16673,7 @@ p, li { white-space: pre-wrap; } Firma questa chiave - + PGP key Chiave PGP @@ -16237,22 +16683,20 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Li aiuta a decidere quando accettare connessioni basate su quella chiave, fidandosi di te. Firmare una chiave è assolutamente facoltativo e la firma non si può revocare, quindi scegli saggiamente quando farlo.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Li aiuta a decidere quando accettare connessioni basate su quella chiave, fidandosi di te. Firmare una chiave è assolutamente facoltativo e la firma non si può revocare, quindi scegli saggiamente quando farlo.</span></p></body></html> - + Keysigning: - Sign PGP key - Firma Chiave PGP + Firma Chiave PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16272,7 +16716,7 @@ p, li { white-space: pre-wrap; } Accetta connessioni - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16342,27 +16786,27 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Errore: impossibile ottenere dettagli contatto - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algoritmo a chiave fornito non è supportato da RetroShare (chiavi RSA solo sono supportate al momento) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16374,7 +16818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Il livello di fiducia è un modo per esprimere la fiducia che riponi in questa chiave. Non viene utilizzato dal programma, né viene condiviso, ma può esserti utile a ricordare le chiavi buone e quelle cattive. @@ -16419,27 +16863,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.Al momento non stai autorizzando connessioni da nodi RetroShare firmati con questa chiave. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Errore Firmando - - Maybe password is wrong - Forse la password è sbagliata + + Check the password! + - + Maybe password is wrong + Forse la password è sbagliata + + + You haven't set a trust level for this key. Non hai impostato il livello di fiducia per questa chiave. - + + Retroshare profile Profilo Retroshare - + This is your own PGP key, and it is signed by : Questa è la tua chiave PGP, ed è firmata da : @@ -16618,8 +17082,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Persone @@ -16636,7 +17099,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Interno - + Chat with this person Conversa con questa persona @@ -16779,7 +17242,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel Etichetta Testo @@ -16823,8 +17286,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Commenti @@ -16859,6 +17322,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Scrivi un commento... + + + Album + Album + PhotoItem @@ -16868,12 +17336,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Modulo - + TextLabel Etichetta Testo - + <!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; } @@ -16965,7 +17433,7 @@ p, li { white-space: pre-wrap; } Visualizza foto - + PhotoShare Sondivisione Foto @@ -17005,7 +17473,7 @@ requesting to edit it! - + Stop Stop @@ -17233,12 +17701,12 @@ Altro... PluginsPage - + Authorize all plugins Autorizza tutti i moduli aggiuntivi - + Plugin look-up directories Cartella scorcio moduli aggiuntivi @@ -17296,7 +17764,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;I Plugin</h1> <p>I plugins vengono caricati dalle cartelle elencate nella lista sottostante.</p><p>Per motivi di sicurezza, i plugin accettati vengono caricati automaticamente fino a quando non vengono modificati l'eseguibile principale di RetroShare o la libreria dei plugin. In tal caso, l'utente dovrà riconfermarli. Dopo l'avvio del programma, puoi abilitare manualmente un plugin cliccando sul bottone "Abilita" e riavviando RetroShare.</p> <p>Se vuoi sviluppare un tuo plugin, contatta il team degli sviluppatori, saranno felici di aiutarti!</p> - + Plugins Moduli aggiuntivi @@ -17682,7 +18150,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Link - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17845,13 +18313,13 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Sito - - + + Comments Commenti - + Copy RetroShare Link @@ -17861,7 +18329,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Mostra l'autore nella scheda delle persone - + Comment Commento @@ -17882,12 +18350,12 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + Hide Nascondi - + Vote up Vota per @@ -17901,7 +18369,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin \/ - + Set as read and remove item Definisci letto e rimuovi elemento @@ -17962,7 +18430,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + Loading Sto caricando... @@ -18052,13 +18520,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18068,60 +18530,50 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Amministratore: - - - + + + unknown sconosciuto - + Distribution: Distribuzione: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Post @@ -18132,7 +18584,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18201,7 +18653,12 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + + Empty + Vuoto + + + Copy RetroShare Link @@ -18236,7 +18693,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + [No name] @@ -18360,8 +18817,18 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18631,9 +19098,8 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseAddDialog - Post From: - Post da: + Post da: Account 1 @@ -18648,7 +19114,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari Conto 3 - + Add to Pulse Aggiungere al segnale @@ -18671,17 +19137,32 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari URL - + GroupLabel - + IDLabel - + + From: + Da: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18706,10 +19187,20 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari Negativo - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18719,14 +19210,53 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + + Post + + + + Cancel Annulla - Post Pulse to Wire - Manda un segnale sul filo + Manda un segnale sul filo + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18752,10 +19282,18 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - - - - + + + + + Click to view picture + + + + + + + Image Immagine @@ -18763,44 +19301,44 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18810,17 +19348,17 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18830,7 +19368,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18838,7 +19376,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseTopLevel - + retweeted @@ -18853,7 +19391,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + follow Parent Group @@ -18863,7 +19401,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18888,7 +19426,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18924,29 +19462,29 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19024,7 +19562,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari QObject - + Confirmation Conferma @@ -19265,7 +19803,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Risultato - + Unable to make path Percorso Impossibile @@ -19300,7 +19838,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Richiesta file cancellata - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Questa versione di RetroShare usa OpenPGP-SDK. Come effetto collaterale, non utilizza il portachiavi PGP condiviso di sistema, ma ha il proprio portachiavi condiviso da tutte le istanze di RetroShare. <br><br>Non sembri avere un tale portachiavi, sebbene chiavi PGP siano menzionati da account RetroShare esistenti, probabilmente perché hai appena cambiato per questa nuova versione del software. @@ -19446,7 +19984,7 @@ L’errore segnalato è: secondi - + TR up @@ -19491,7 +20029,7 @@ L’errore segnalato è: disabilitato - + Move IP %1 to whitelist Sposta l’IP %1 alla lista bianca @@ -19507,7 +20045,7 @@ L’errore segnalato è: - + %1 seconds ago %1 secondi fa @@ -19591,7 +20129,7 @@ Security: no anonymous IDs - + Error Errore @@ -19982,9 +20520,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Questo certificato contiene: + <p>Questo certificato contiene: @@ -20358,7 +20895,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20580,18 +21117,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + Ordinamento decrescente + + + + Sort Ascending Order + Ordinamento crescente + + + + + [no title] + + + + + Show column … @@ -21028,7 +21586,7 @@ p, li { white-space: pre-wrap; } Scarica! - + File File @@ -21043,7 +21601,7 @@ p, li { white-space: pre-wrap; } Segmento - + Bad filenames have been cleaned Nomi Files incorretti sono stati puliti @@ -21093,7 +21651,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Salva - + Collection Editor Editor di Raccolte @@ -21108,7 +21666,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Conteggio File - + Real Size: Waiting child... @@ -21123,12 +21681,12 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Questa è una directory. Doppio click per espanderla. - + Download files - + Specify... Specifica... @@ -21377,7 +21935,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con RsFriendListModel - + Name Nome @@ -21397,7 +21955,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con IP - + Profile ID @@ -21410,10 +21968,15 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con RsGxsForumModel - + Title Titolo + + + UnRead + + Date @@ -21425,7 +21988,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con Autore - + Information for this identity is currently missing. @@ -21463,7 +22026,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Messaggio Perso ... ] @@ -21471,7 +22034,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -21531,7 +22094,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21889,7 +22452,7 @@ prevents the message to be forwarded to your friends. Nome File - + Download Scarica @@ -21968,7 +22531,7 @@ prevents the message to be forwarded to your friends. Apri cartella - + Create Collection... Crea Raccolta... @@ -21988,7 +22551,7 @@ prevents the message to be forwarded to your friends. Scarica da una raccolta di file... - + Collection Raccolta @@ -22093,12 +22656,12 @@ prevents the message to be forwarded to your friends. Dettagli contatto - + Deny friend Rifiuta amico - + Chat Conversazione @@ -22108,7 +22671,7 @@ prevents the message to be forwarded to your friends. Avvia conversazione - + Expand Allarga @@ -22375,13 +22938,13 @@ behind a firewall or a VPN. Scoperta Attivata (raccomandato) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Scoperta Disattivata @@ -22849,7 +23412,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Rete @@ -22877,7 +23440,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22974,7 +23537,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Indirizzo Servizio @@ -23009,12 +23572,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range Intervallo IP - + Reported by DHT for IP masquerading Segnalato dalla DHT per mascheramento IP @@ -23682,7 +24245,7 @@ p, li { white-space: pre-wrap; } Manca certificato PGP - + Wrong password @@ -23736,7 +24299,7 @@ Questa scelta può essere ripristinata in Impostazioni. StatisticsWindow - + Add Friend Aggiungi amico @@ -23792,7 +24355,7 @@ Questa scelta può essere ripristinata in Impostazioni. Matrice dei permessi sui servizi - + DHT DHT @@ -24332,7 +24895,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24342,13 +24905,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24357,6 +24919,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24630,35 +25217,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Hai scaricato il %1 + You have %1 completed transfers + - You have %1 completed download - Hai completato il %1 di scaricamento + You have %1 completed transfer + - %1 completed downloads - completato %1 scaricamenti + %1 completed transfers + - %1 completed download - completato %1 scaricamento + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Hai scaricato il %1 + + + You have %1 completed download + Hai completato il %1 di scaricamento + + + %1 completed downloads + completato %1 scaricamenti + + + %1 completed download + completato %1 scaricamento TransfersDialog - + Downloads Scaricamenti @@ -24669,7 +25267,7 @@ p, li { white-space: pre-wrap; } Caricamenti - + Name i.e: file name Nome @@ -24880,7 +25478,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Trasferimento File</h1> <p>RetroShare offre due modi per trasferie file: trasferimenti diretti dai tuoi amici, e trasferimenti a distanza anonimizzati con tunnel. Inoltre, il trasferimento file è multi-fonte e consente lo swarming (puoi essere una fonta mentre scarichi).</p> <p>Puoi condividere file usando l’icona <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> bekka barra laterale sinistra. Queste file verranno elencati nella finestrella "I Miei File". Per ciascun gruppo di amici, puoi stabilire se potranno vedere o meno questi file nella finestra "File degli Amici".</p> <p>La finestra di ricerca riporta i file nelle liste dei file dei tuoi amici, ed i file distanti che possono essere raggiunti anonimamente tramite il sistema di tunneling a multi-hop.</p> - + Move in Queue... Sposta in coda... @@ -24974,7 +25572,7 @@ p, li { white-space: pre-wrap; } Per favore inserisci un nuovo--e valido--nome per il file - + Expand all Espandi tutto @@ -25106,7 +25704,7 @@ p, li { white-space: pre-wrap; } - + Columns Colonne @@ -25117,7 +25715,7 @@ p, li { white-space: pre-wrap; } Trasferimento file - + Path Tracciato @@ -25127,7 +25725,7 @@ p, li { white-space: pre-wrap; } Visualizza colonna dei Percorsi - + Could not delete preview file Impossibile eliminare il file anteprima @@ -25137,7 +25735,7 @@ p, li { white-space: pre-wrap; } Riprovare? - + Create Collection... Crea Raccolta... @@ -25152,7 +25750,7 @@ p, li { white-space: pre-wrap; } Guarda Raccolta... - + Collection Raccolta @@ -25398,7 +25996,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Contatto sconosciuto @@ -25494,7 +26092,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Hai %1 nuovi messaggi @@ -25870,7 +26468,7 @@ p, li { white-space: pre-wrap; } Creare gruppo - + Subscribe to Group Sottoscrivi al Gruppo @@ -25964,8 +26562,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Visualizza storico modifiche @@ -25976,7 +26574,7 @@ p, li { white-space: pre-wrap; } - + Preview Anteprima @@ -26001,12 +26599,12 @@ p, li { white-space: pre-wrap; } Nascondi storico modifiche - + Edit Page Modifica pagina - + Create New Wiki Page Creare nuova pagina Wiki @@ -26026,7 +26624,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Crea nuovo gruppo Wiki @@ -26068,7 +26666,7 @@ p, li { white-space: pre-wrap; } Lasso di tempo - + Create Account @@ -26078,12 +26676,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Aggiornamento @@ -26118,12 +26715,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26193,7 +26790,7 @@ p, li { white-space: pre-wrap; } Mostrando: - + Yourself Te stesso @@ -26231,7 +26828,7 @@ p, li { white-space: pre-wrap; } Posta segnale sil filo - + RetroShare RetroShare @@ -26243,7 +26840,7 @@ p, li { white-space: pre-wrap; } - + The Wire Il Cavo @@ -26251,7 +26848,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26332,8 +26929,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar Avatar @@ -26362,6 +26959,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26474,8 +27076,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Immagini (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Immagini (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_ja_JP.ts b/retroshare-gui/src/lang/retroshare_ja_JP.ts index 1627fecee..ce4e63aeb 100644 --- a/retroshare-gui/src/lang/retroshare_ja_JP.ts +++ b/retroshare-gui/src/lang/retroshare_ja_JP.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshareãƒãƒ¼ã‚¸ãƒ§ãƒ³ @@ -79,7 +79,7 @@ 楽ã—ん㧠;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: 高度ãªæ¤œç´¢ - + Search Criteria 検索基準 - + Add a further search criterion. ã•ã‚‰ã«æ¤œç´¢åŸºæº–を追加 @@ -283,7 +283,7 @@ AlbumDialog - + Album アルãƒãƒ  @@ -414,7 +414,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -457,8 +457,8 @@ p, li { white-space: pre-wrap; } フォーム - - + + TextLabel ラベル @@ -525,7 +525,7 @@ p, li { white-space: pre-wrap; } ツールãƒãƒ¼ - + Icon Only アイコンã®ã¿ @@ -550,7 +550,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 アイコンサイズ = 8x8 @@ -575,7 +575,7 @@ p, li { white-space: pre-wrap; } アイコンサイズ = 128x128 - + Status Bar @@ -650,7 +650,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -665,7 +665,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 アイコンサイズ = 32x32 @@ -731,13 +731,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + ラベル + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -746,25 +751,30 @@ p, li { white-space: pre-wrap; } 削除 - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar クリックã§ã‚¢ãƒã‚¿ãƒ¼ã‚’変更 @@ -772,7 +782,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -792,44 +802,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare å¸¯åŸŸä½¿ç”¨é‡ + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 設定を表示 + TextLabel + ラベル + + + Reset リセット - Receive Rate - å—信速度 + å—信速度 - Send Rate - é€ä¿¡é€Ÿåº¦ + é€ä¿¡é€Ÿåº¦ - + Always on Top 常ã«æ‰‹å‰ã«è¡¨ç¤º - Style - スタイル + スタイル - + Changes the transparency of the Bandwidth Graph 帯域グラフã®é€æ˜Žåº¦ã‚’変更 - + 100 100 @@ -839,30 +870,27 @@ p, li { white-space: pre-wrap; } % ä¸é€æ˜Ž - Save - ä¿å­˜ + ä¿å­˜ - Cancel - キャンセル + キャンセル - + Since: 開始: - Hide Settings - 設定をéžè¡¨ç¤º + 設定をéžè¡¨ç¤º BandwidthStatsWidget - + Sum @@ -884,7 +912,7 @@ p, li { white-space: pre-wrap; } カウント - + Average @@ -1018,7 +1046,7 @@ p, li { white-space: pre-wrap; } ラベル - + Comments コメント @@ -1096,6 +1124,85 @@ p, li { white-space: pre-wrap; } ラベル + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 未読/既読ã®åˆ‡ã‚Šæ›¿ãˆ + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + RetroShareリンクをコピー + + + + + Expand + 展開 + + + + Set as read and remove item + + + + + Remove Item + アイテムを削除 + + + + Name + åå‰ + + + + Comm value + + + + + Comment + コメント + + + + Comments + + + + + Hide + éžè¡¨ç¤º + + BwCtrlWindow @@ -1231,6 +1338,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1283,6 +1400,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 未読/既読ã®åˆ‡ã‚Šæ›¿ãˆ + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + RetroShareリンクをコピー + + + + + Expand + 展開 + + + + Set as read and remove item + + + + + Remove Item + アイテムを削除 + + + + Name + åå‰ + + + + Comm value + + + + + Comment + コメント + + + + Comments + + + + + Hide + éžè¡¨ç¤º + + ChatLobbyDialog @@ -1491,22 +1687,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1520,11 +1716,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1981,13 +2172,11 @@ Double click a chat room to enter and chat. - Group chat - グループãƒãƒ£ãƒƒãƒˆ + グループãƒãƒ£ãƒƒãƒˆ - - + Private chat プライベートãƒãƒ£ãƒƒãƒˆ @@ -2052,17 +2241,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2083,11 +2267,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2148,11 +2333,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2291,8 +2482,23 @@ Double click a chat room to enter and chat. プライベートãƒãƒ£ãƒƒãƒˆ - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2461,7 +2667,7 @@ Double click a chat room to enter and chat. - + is typing... 書ãè¾¼ã¿ä¸­... @@ -2478,12 +2684,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? 本当ã«å±¥æ­´ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ @@ -2555,7 +2761,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2591,12 +2797,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2612,7 +2818,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2632,7 +2838,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2790,12 +2996,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 詳細 - + Local Address ローカル アドレス @@ -2806,12 +3012,12 @@ Double click on it to add his name on text writer. 外部アドレス - + Node info: - + Current address: @@ -2827,31 +3033,41 @@ Double click on it to add his name on text writer. ãƒãƒ¼ãƒˆ - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. エラー: ピア詳細をå–å¾—ã§ãã¾ã›ã‚“. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2867,22 +3083,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2917,13 +3133,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2938,7 +3159,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2949,17 +3170,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2969,7 +3195,7 @@ Double click on it to add his name on text writer. - + with @@ -3057,32 +3283,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: åå‰: - + Location: 場所: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -3092,7 +3318,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -3117,12 +3343,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3142,32 +3368,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3213,17 +3439,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed 証明書ã®èª­ã¿è¾¼ã¿ã«å¤±æ•— - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3243,12 +3469,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3296,7 +3522,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3344,12 +3600,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3379,7 +3635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3437,12 +3693,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3517,7 +3773,12 @@ even if you don't make friends. - + + Status + 状態 + + + <!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; } @@ -3939,7 +4200,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4087,7 +4348,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4102,7 +4363,7 @@ p, li { white-space: pre-wrap; } - + Search 検索 @@ -4118,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -4134,12 +4395,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4161,7 +4422,7 @@ p, li { white-space: pre-wrap; } ä½œæˆ - + Add Member @@ -4291,7 +4552,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4337,7 +4598,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4347,7 +4608,7 @@ p, li { white-space: pre-wrap; } RetroShareリンクを貼り付㑠- + Drop file error. @@ -4374,17 +4635,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject 件åを追加ã—ã¦ãã ã•ã„ @@ -4415,12 +4696,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4440,7 +4721,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4532,7 +4813,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4951,7 +5232,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5954,7 +6235,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6445,7 +6726,7 @@ at least one peer was not added to a group - + Mark all @@ -6459,7 +6740,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6563,7 +6844,7 @@ at least one peer was not added to a group - + Network @@ -6628,7 +6909,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6659,7 +6940,7 @@ at least one peer was not added to a group - + Node name @@ -6918,12 +7199,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7286,7 +7567,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7351,7 +7632,7 @@ p, li { white-space: pre-wrap; } - + Details 詳細 @@ -7374,7 +7655,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7575,7 +7856,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title タイトル @@ -7585,13 +7866,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description 説明 - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7601,42 +7899,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7651,40 +7914,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post 最新ã®æŠ•ç¨¿ - + + Name åå‰ - - Unread - - - - + Popularity 人気度 - - + + Never - Display - 表示 + 表示 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7833,7 +8091,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7854,12 +8112,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels 購読済ã¿ã®ãƒãƒ£ãƒ³ãƒãƒ« @@ -8280,7 +8538,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8380,12 +8638,12 @@ p, li { white-space: pre-wrap; } - + Files ファイル - + Comments コメント @@ -8396,18 +8654,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8417,12 +8675,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8482,7 +8740,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8497,12 +8755,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8578,23 +8836,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe 購読 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected ãƒãƒ£ãƒ³ãƒãƒ«ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“。 @@ -8616,11 +8887,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -9113,7 +9379,7 @@ before you can comment - + Search forums @@ -9122,12 +9388,12 @@ before you can comment 最新ã®æŠ•ç¨¿ - + New Thread - + Threaded View @@ -9137,19 +9403,19 @@ before you can comment - - + + Title タイトル - - + + Date 期日 - + Author @@ -9164,7 +9430,17 @@ before you can comment ロード中 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9209,23 +9485,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9263,12 +9539,12 @@ before you can comment - + Copy RetroShare Link RetroShareリンクをコピー - + Hide éžè¡¨ç¤º @@ -9277,7 +9553,7 @@ before you can comment 展開 - + [unknown] @@ -9307,8 +9583,8 @@ before you can comment - - + + Distribution @@ -9391,12 +9667,12 @@ before you can comment - + New thread - + Edit @@ -9452,7 +9728,7 @@ before you can comment - + Author's reputation @@ -9472,7 +9748,7 @@ before you can comment - + <b>Loading...<b> @@ -9512,6 +9788,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9579,7 +9860,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9611,11 +9892,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -10028,7 +10304,7 @@ This message is missing. You should receive it later. - + Unsubscribe 購読中止 @@ -10043,7 +10319,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -10053,12 +10329,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10125,12 +10401,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link RetroShareリンクをコピー @@ -10145,7 +10421,7 @@ This message is missing. You should receive it later. ã™ã¹ã¦ã‚’未読ã«è¨­å®š - + AUTHD @@ -10667,7 +10943,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10676,7 +10952,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10702,7 +10978,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10776,49 +11052,55 @@ p, li { white-space: pre-wrap; } フォーム - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10866,17 +11148,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10891,7 +11168,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... åå‰ã‚’付ã‘ã¦ä¿å­˜ @@ -11156,14 +11438,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -11173,12 +11455,12 @@ p, li { white-space: pre-wrap; } 検索 - + Anonymous Id - + Create new Identity @@ -11322,7 +11604,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11394,7 +11676,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11409,24 +11691,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11441,7 +11723,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11500,13 +11782,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11566,7 +11853,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11614,7 +11901,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11623,12 +11910,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11640,12 +11927,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11761,17 +12048,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11928,8 +12215,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11940,7 +12227,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11950,7 +12237,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12010,7 +12297,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12020,7 +12307,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12058,7 +12345,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12075,14 +12362,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity @@ -12093,24 +12380,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12130,12 +12420,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12145,7 +12460,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12155,7 +12470,12 @@ These identities will soon be not supported anymore. タイプ - + + Choose image... + + + + @@ -12195,12 +12515,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12210,7 +12525,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12315,8 +12630,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - é€ä¿¡ + é€ä¿¡ @@ -12474,7 +12793,7 @@ These identities will soon be not supported anymore. - + Options @@ -12506,12 +12825,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12640,7 +12959,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12685,7 +13004,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12714,7 +13033,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12816,7 +13135,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12911,12 +13230,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12946,7 +13265,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12972,12 +13296,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12988,7 +13312,7 @@ Do you want to save message to draft box? RetroShareリンクを貼り付㑠- + Add to "To" @@ -13242,7 +13566,7 @@ Do you want to save message ? ã•ã‚‰ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’追加 - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13256,6 +13580,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13268,7 +13607,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13308,13 +13647,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13453,8 +13792,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13466,12 +13820,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13546,12 +13900,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13612,18 +13972,33 @@ Do you want to save message ? ダウンロード - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13638,7 +14013,7 @@ Do you want to save message ? - + Load images always for this message @@ -13747,7 +14122,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13767,14 +14142,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13845,7 +14220,7 @@ Do you want to save message ? - + Subject 件å @@ -13925,7 +14300,7 @@ Do you want to save message ? - + Open in a new window @@ -14010,7 +14385,7 @@ Do you want to save message ? - + Drafts @@ -14099,7 +14474,7 @@ Do you want to save message ? - + Delete Message @@ -14110,7 +14485,7 @@ Do you want to save message ? - + Expand 展開 @@ -14120,7 +14495,7 @@ Do you want to save message ? アイテムを削除 - + from @@ -14129,6 +14504,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14428,7 +14808,7 @@ Reported error: - + Groups @@ -14458,19 +14838,19 @@ Reported error: - - + + Search 検索 - + ID ID - + Search ID @@ -14480,7 +14860,7 @@ Reported error: - + Show Items @@ -14679,18 +15059,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14728,7 +15108,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14742,7 +15122,7 @@ at least one peer was not added to a group - + Newest on top @@ -14753,20 +15133,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14799,22 +15194,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14835,12 +15230,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14887,27 +15277,37 @@ at least one peer was not added to a group グループãƒãƒ£ãƒƒãƒˆ - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14957,7 +15357,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14967,7 +15367,7 @@ at least one peer was not added to a group - + Systray @@ -15094,17 +15494,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : åå‰: @@ -15159,22 +15554,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15188,7 +15578,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15198,22 +15588,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15233,7 +15613,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15299,27 +15679,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. エラー: ピア詳細をå–å¾—ã§ãã¾ã›ã‚“. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15331,7 +15711,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15376,27 +15756,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure ç½²å失敗 - - Maybe password is wrong - ãŠãらãパスワードãŒé–“é•ã£ã¦ã„ã¾ã™ + + Check the password! + - + Maybe password is wrong + ãŠãらãパスワードãŒé–“é•ã£ã¦ã„ã¾ã™ + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15567,8 +15967,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15585,7 +15984,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15724,7 +16123,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel ラベル @@ -15764,8 +16163,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + コメント @@ -15796,6 +16195,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment コメントを追加 + + + Album + アルãƒãƒ  + PhotoItem @@ -15805,12 +16209,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.フォーム - + TextLabel ラベル - + <!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; } @@ -15890,7 +16294,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15930,7 +16334,7 @@ requesting to edit it! - + Stop @@ -16154,12 +16558,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories @@ -16168,7 +16572,7 @@ p, li { white-space: pre-wrap; } <無効> - + Plugins @@ -16502,7 +16906,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16637,13 +17041,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments コメント - + Copy RetroShare Link RetroShareリンクをコピー @@ -16653,7 +17057,7 @@ p, li { white-space: pre-wrap; } - + Comment コメント @@ -16674,12 +17078,12 @@ p, li { white-space: pre-wrap; } - + Hide éžè¡¨ç¤º - + Vote up @@ -16689,7 +17093,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16750,7 +17154,7 @@ p, li { white-space: pre-wrap; } ラベル - + Loading ロード中 @@ -16812,13 +17216,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16828,60 +17226,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel ラベル - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16892,7 +17280,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16961,7 +17349,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link RetroShareリンクをコピー @@ -16996,7 +17389,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17112,8 +17505,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17381,12 +17784,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17401,17 +17799,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17436,10 +17849,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17449,13 +17872,48 @@ and use the import button to load it - + + Post + + + + Cancel キャンセル - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17478,10 +17936,18 @@ and use the import button to load it フォーム - - - - + + + + + Click to view picture + + + + + + + Image @@ -17489,44 +17955,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17536,17 +18002,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17556,7 +18022,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17564,7 +18030,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17579,7 +18045,7 @@ and use the import button to load it - + follow Parent Group @@ -17589,7 +18055,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17614,7 +18080,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17650,29 +18116,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17750,7 +18216,7 @@ and use the import button to load it QObject - + Confirmation @@ -17989,7 +18455,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -18024,7 +18490,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18162,7 +18628,7 @@ Reported error is: - + TR up @@ -18207,7 +18673,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18223,7 +18689,7 @@ Reported error is: - + %1 seconds ago @@ -18307,7 +18773,7 @@ Security: no anonymous IDs - + Error @@ -18697,11 +19163,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19035,7 +19496,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19257,18 +19718,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19705,7 +20187,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19720,7 +20202,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19768,7 +20250,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace ä¿å­˜ - + Collection Editor @@ -19783,7 +20265,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19798,12 +20280,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -20050,7 +20532,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name åå‰ @@ -20070,7 +20552,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20083,10 +20565,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title タイトル + + + UnRead + + Date @@ -20098,7 +20585,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -20136,7 +20623,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -20144,7 +20631,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 期日 @@ -20204,7 +20691,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20558,7 +21045,7 @@ prevents the message to be forwarded to your friends. - + Download ダウンロード @@ -20637,7 +21124,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20657,7 +21144,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20762,12 +21249,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat ãƒãƒ£ãƒƒãƒˆ @@ -20777,7 +21264,7 @@ prevents the message to be forwarded to your friends. ãƒãƒ£ãƒƒãƒˆã‚’始ã‚ã‚‹ - + Expand 展開 @@ -21040,13 +21527,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21512,7 +21999,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21540,7 +22027,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status 状態 @@ -21637,7 +22124,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21672,12 +22159,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22342,7 +22829,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22384,7 +22871,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22440,7 +22927,7 @@ This choice can be reverted in settings. - + DHT @@ -22972,7 +23459,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22982,13 +23469,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22997,6 +23483,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23270,27 +23781,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23298,7 +23804,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23309,7 +23815,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name åå‰ @@ -23516,7 +24022,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23610,7 +24116,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23742,7 +24248,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23753,7 +24259,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23763,7 +24269,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23773,7 +24279,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23788,7 +24294,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24030,7 +24536,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24126,7 +24632,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24494,7 +25000,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24588,8 +25094,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24600,7 +25106,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24625,12 +25131,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24650,7 +25156,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24688,7 +25194,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24698,12 +25204,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24738,12 +25243,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24781,7 +25286,7 @@ p, li { white-space: pre-wrap; } æ–°è¦ - + Yourself @@ -24795,7 +25300,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24807,7 +25312,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24815,7 +25320,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24896,8 +25401,8 @@ p, li { white-space: pre-wrap; } フォーム - - + + Avatar @@ -24926,6 +25431,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25038,7 +25548,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ko.ts b/retroshare-gui/src/lang/retroshare_ko.ts index 97514b191..d3aa306a1 100644 --- a/retroshare-gui/src/lang/retroshare_ko.ts +++ b/retroshare-gui/src/lang/retroshare_ko.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ 레트로 ì‰ì–´: 고급 검색 - + Search Criteria 검색 문구 - + Add a further search criterion. 검색 문구 ë” ì¶”ê°€í•©ë‹ˆë‹¤. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album 앨범 @@ -490,7 +490,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -533,8 +533,8 @@ p, li { white-space: pre-wrap; } ì–‘ì‹ - - + + TextLabel í…스트 ë ˆì´ë¸” @@ -601,7 +601,7 @@ p, li { white-space: pre-wrap; } ë„구 ëª¨ìŒ - + Icon Only ì•„ì´ì½˜ë§Œ @@ -626,7 +626,7 @@ p, li { white-space: pre-wrap; } ë„구 단추 스타ì¼ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤. - + Icon Size = 8x8 ì•„ì´ì½˜ í¬ê¸° = 8x8 @@ -651,7 +651,7 @@ p, li { white-space: pre-wrap; } ì•„ì´ì½˜ í¬ê¸° = 128x128 - + Status Bar ìƒíƒœ 표시줄 @@ -726,7 +726,7 @@ p, li { white-space: pre-wrap; } SysTray í’ì„  ë„ì›€ë§ ë¹„í™œì„±í™” - + Main page items: @@ -741,7 +741,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 ì•„ì´ì½˜ í¬ê¸° = 32x32 @@ -807,14 +807,23 @@ p, li { white-space: pre-wrap; } 아바타 바꾸기 - + + TextLabel + í…스트 ë ˆì´ë¸” + + + Your Avatar Picture 아바타 사진 - + + Browse... + + + Add Avatar - 아바타 추가 + 아바타 추가 @@ -822,25 +831,34 @@ p, li { white-space: pre-wrap; } 제거 - + Set your Avatar picture 아바타 사진 설정 - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - 아바타 불러오기 + 아바타 불러오기 AvatarWidget - - Choose avatar - - - - + Click to change your avatar 아바타를 바꾸려면 누르십시오 @@ -848,7 +866,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -868,44 +886,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage 레트로 ì‰ì–´ ëŒ€ì—­í­ ì‚¬ìš© + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 옵션 ë³´ì´ê¸° + TextLabel + í…스트 ë ˆì´ë¸” + + + Reset 초기화 - Receive Rate - 수신율 + 수신율 - Send Rate - 송신율 + 송신율 - + Always on Top í•­ìƒ ìœ„ë¡œ - Style - ìŠ¤íƒ€ì¼ + ìŠ¤íƒ€ì¼ - + Changes the transparency of the Bandwidth Graph ëŒ€ì—­í­ ê·¸ëž˜í”„ 투명ë„를 바꿉니다 - + 100 100 @@ -915,30 +954,27 @@ p, li { white-space: pre-wrap; } % íˆ¬ëª…ë„ - Save - 저장 + 저장 - Cancel - 취소 + 취소 - + Since: 시초: - Hide Settings - 설정 숨기기 + 설정 숨기기 BandwidthStatsWidget - + Sum ì´í•© @@ -960,7 +996,7 @@ p, li { white-space: pre-wrap; } 계수 - + Average @@ -1094,7 +1130,7 @@ p, li { white-space: pre-wrap; } í…스트 ë ˆì´ë¸” - + Comments 설명 @@ -1172,6 +1208,85 @@ p, li { white-space: pre-wrap; } í…스트 ë ˆì´ë¸” + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + 레트로 ì‰ì–´ ë§í¬ 복사 + + + + + Expand + 확장 + + + + Set as read and remove item + í•­ëª©ì„ ì½ìŒìœ¼ë¡œ 설정하고 제거 + + + + Remove Item + 항목 제거 + + + + Name + ì´ë¦„ + + + + Comm value + + + + + Comment + 답글 달기 + + + + Comments + + + + + Hide + 숨김 + + BwCtrlWindow @@ -1307,6 +1422,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + 기본값 + + + + Dark + + ChannelPage @@ -1359,6 +1484,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + 레트로 ì‰ì–´ ë§í¬ 복사 + + + + + Expand + 확장 + + + + Set as read and remove item + í•­ëª©ì„ ì½ìŒìœ¼ë¡œ 설정하고 제거 + + + + Remove Item + 항목 제거 + + + + Name + ì´ë¦„ + + + + Comm value + + + + + Comment + 답글 달기 + + + + Comments + + + + + Hide + 숨김 + + ChatLobbyDialog @@ -1567,22 +1771,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1596,11 +1800,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -2049,13 +2248,11 @@ Double click a chat room to enter and chat. - Group chat - 집단 대화 + 집단 대화 - - + Private chat ê°œì¸ ëŒ€í™” @@ -2120,17 +2317,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2151,11 +2343,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2216,11 +2409,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2359,8 +2558,23 @@ Double click a chat room to enter and chat. ê°œì¸ ëŒ€í™” - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2529,7 +2743,7 @@ Double click a chat room to enter and chat. - + is typing... 입력중 ... @@ -2546,12 +2760,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? 실제 기ë¡ì„ ì •ë§ë¡œ 삭제하시겠습니까? @@ -2623,7 +2837,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2659,12 +2873,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2680,7 +2894,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2700,7 +2914,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2858,12 +3072,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 세부 ì •ë³´ - + Local Address 지역 주소 @@ -2874,12 +3088,12 @@ Double click on it to add his name on text writer. 외부 주소 - + Node info: - + Current address: @@ -2895,31 +3109,41 @@ Double click on it to add his name on text writer. í¬íŠ¸ - + Include signatures 서명 í¬í•¨ - + RetroShare 레트로 ì‰ì–´ - + - + Error : cannot get peer details. 오류 : ë™ë£Œ 세부 정보를 가져올 수 없습니다 - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2935,22 +3159,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2985,13 +3209,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3006,7 +3235,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3017,17 +3246,22 @@ Double click on it to add his name on text writer. ì—†ìŒ - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3037,7 +3271,7 @@ Double click on it to add his name on text writer. - + with @@ -3133,32 +3367,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: ì´ë¦„: - + Location: 지역: - + Options 옵션 - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -3168,7 +3402,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -3193,12 +3427,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3218,32 +3452,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3289,17 +3523,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed 서명 ë¶ˆëŸ¬ì˜¤ê¸°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤ - + Not a valid Retroshare certificate! - + RetroShare Invitation 레트로 ì‰ì–´ 초대 @@ -3319,12 +3553,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3372,7 +3606,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3424,12 +3688,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3459,7 +3723,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3517,12 +3781,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3597,7 +3861,12 @@ even if you don't make friends. - + + Status + ìƒíƒœ + + + <!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; } @@ -4019,7 +4288,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4167,7 +4436,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4182,7 +4451,7 @@ p, li { white-space: pre-wrap; } - + Search 검색 @@ -4198,7 +4467,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -4214,12 +4483,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4241,7 +4510,7 @@ p, li { white-space: pre-wrap; } 만들기 - + Add Member @@ -4371,7 +4640,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4417,7 +4686,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links 레트로 ì‰ì–´ ë§í¬ 붙여넣기 @@ -4427,7 +4696,7 @@ p, li { white-space: pre-wrap; } 레트로 ì‰ì–´ ë§í¬ 붙여넣기 - + Drop file error. @@ -4454,17 +4723,37 @@ p, li { white-space: pre-wrap; } - + RetroShare 레트로 ì‰ì–´ - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject ì œëª©ì„ ìž…ë ¥í•´ì£¼ì‹­ì‹œì˜¤ @@ -4495,12 +4784,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4520,7 +4809,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4612,7 +4901,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -5031,7 +5320,7 @@ and use the import button to load it DHTGraphSource - + users @@ -6034,7 +6323,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6525,7 +6814,7 @@ at least one peer was not added to a group - + Mark all @@ -6539,7 +6828,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6643,7 +6932,7 @@ at least one peer was not added to a group - + Network @@ -6708,7 +6997,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6739,7 +7028,7 @@ at least one peer was not added to a group - + Node name @@ -6998,12 +7287,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7366,7 +7655,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7431,7 +7720,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7454,7 +7743,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7655,7 +7944,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 제목 @@ -7665,13 +7954,30 @@ p, li { white-space: pre-wrap; } 제목 검색 - - + + + + Description 설명 - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7681,42 +7987,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7731,40 +8002,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post 최신 게시글 - + + Name ì´ë¦„ - - Unread - - - - + Popularity ì¸ê¸°ë„ - - + + Never - Display - 표시 + 표시 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7913,7 +8179,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7934,12 +8200,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels 가입한 ì±„ë„ @@ -8364,7 +8630,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8464,12 +8730,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments 설명 @@ -8480,18 +8746,18 @@ p, li { white-space: pre-wrap; } - + Feeds 피드 - - + + Click to switch to list view - + Show unread posts only @@ -8501,12 +8767,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8566,7 +8832,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8581,12 +8847,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8662,23 +8928,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe 가입 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected ì„ íƒí•œ ì±„ë„ ì—†ìŒ @@ -8700,11 +8979,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -9197,7 +9471,7 @@ before you can comment - + Search forums í¬ëŸ¼ 검색 @@ -9206,12 +9480,12 @@ before you can comment 최신 게시글 - + New Thread - + Threaded View @@ -9221,19 +9495,19 @@ before you can comment - - + + Title 제목 - - + + Date 날짜 - + Author ìž‘ì„±ìž @@ -9248,7 +9522,17 @@ before you can comment 불러오는 중 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9293,23 +9577,23 @@ before you can comment ìž‘ì„±ìž ê²€ìƒ‰ - + No name ì´ë¦„ ì—†ìŒ - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9347,12 +9631,12 @@ before you can comment ì½ì§€ ì•ŠìŒìœ¼ë¡œ 표시 - + Copy RetroShare Link 레트로 ì‰ì–´ ë§í¬ 복사 - + Hide 숨김 @@ -9361,7 +9645,7 @@ before you can comment 확장 - + [unknown] @@ -9391,8 +9675,8 @@ before you can comment - - + + Distribution @@ -9479,12 +9763,12 @@ before you can comment - + New thread - + Edit 편집 @@ -9540,7 +9824,7 @@ before you can comment - + Author's reputation @@ -9560,7 +9844,7 @@ before you can comment - + <b>Loading...<b> @@ -9600,6 +9884,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9667,7 +9956,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9699,11 +9988,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -10116,7 +10400,7 @@ This message is missing. You should receive it later. - + Unsubscribe 탈퇴 @@ -10131,7 +10415,7 @@ This message is missing. You should receive it later. 새 탭ì—ì„œ 열기 - + Remove this search @@ -10141,12 +10425,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10213,12 +10497,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link 레트로 ì‰ì–´ ë§í¬ 복사 @@ -10233,7 +10517,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10755,7 +11039,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10764,7 +11048,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10790,7 +11074,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10864,49 +11148,55 @@ p, li { white-space: pre-wrap; } ì–‘ì‹ - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10954,17 +11244,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10979,7 +11264,12 @@ new short format 레트로 ì‰ì–´ 초대 - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... 다른 ì´ë¦„으로 저장... @@ -11244,14 +11534,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All ëª¨ë‘ - + Reputation @@ -11261,12 +11551,12 @@ p, li { white-space: pre-wrap; } 검색 - + Anonymous Id - + Create new Identity @@ -11410,7 +11700,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11482,7 +11772,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11497,24 +11787,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11529,7 +11819,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11588,13 +11878,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11654,7 +11949,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11702,7 +11997,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11711,12 +12006,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11728,12 +12023,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11849,17 +12144,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12016,8 +12311,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12028,7 +12323,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12038,7 +12333,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12098,7 +12393,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12108,7 +12403,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12146,7 +12441,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12163,14 +12458,14 @@ These identities will soon be not supported anymore. - + N/A ì—†ìŒ - + Edit identity @@ -12181,24 +12476,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12218,12 +12516,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12233,7 +12556,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12243,7 +12566,12 @@ These identities will soon be not supported anymore. í˜•ì‹ - + + Choose image... + + + + @@ -12283,12 +12611,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12298,7 +12621,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12403,8 +12726,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - 보내기 + 보내기 @@ -12562,7 +12889,7 @@ These identities will soon be not supported anymore. - + Options 옵션 @@ -12594,12 +12921,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12732,7 +13059,7 @@ These identities will soon be not supported anymore. 표시 - + Make sure this link has not been forged to drag you to a malicious website. @@ -12777,7 +13104,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12806,7 +13133,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12908,7 +13235,7 @@ These identities will soon be not supported anymore. - + Tags @@ -13003,12 +13330,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -13038,7 +13365,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -13064,12 +13396,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -13080,7 +13412,7 @@ Do you want to save message to draft box? 레트로 ì‰ì–´ ë§í¬ 붙여넣기 - + Add to "To" @@ -13334,7 +13666,7 @@ Do you want to save message ? 추가 íŒŒì¼ ì¶”ê°€ - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13348,6 +13680,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13360,7 +13707,7 @@ Do you want to save message ? ì–´ë””ì—ì„œ : - + Bullet list (disc) @@ -13400,13 +13747,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13545,8 +13892,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13558,12 +13920,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: 제목: @@ -13638,12 +14000,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13704,18 +14072,33 @@ Do you want to save message ? 다운로드 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13730,7 +14113,7 @@ Do you want to save message ? - + Load images always for this message @@ -13839,7 +14222,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13859,14 +14242,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13937,7 +14320,7 @@ Do you want to save message ? - + Subject 제목 @@ -14021,7 +14404,7 @@ Do you want to save message ? - + Open in a new window @@ -14106,7 +14489,7 @@ Do you want to save message ? - + Drafts @@ -14195,7 +14578,7 @@ Do you want to save message ? - + Delete Message @@ -14206,7 +14589,7 @@ Do you want to save message ? - + Expand 확장 @@ -14216,7 +14599,7 @@ Do you want to save message ? 항목 제거 - + from @@ -14225,6 +14608,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14524,7 +14912,7 @@ Reported error: - + Groups @@ -14554,19 +14942,19 @@ Reported error: - - + + Search 검색 - + ID ID - + Search ID @@ -14576,7 +14964,7 @@ Reported error: - + Show Items @@ -14775,18 +15163,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14824,7 +15212,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14838,7 +15226,7 @@ at least one peer was not added to a group - + Newest on top @@ -14849,20 +15237,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14895,22 +15298,22 @@ at least one peer was not added to a group - + Test 시험 - + Chat Room - + Systray Icon - + Message @@ -14931,12 +15334,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14983,27 +15381,37 @@ at least one peer was not added to a group 집단 대화 - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -15053,7 +15461,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -15067,7 +15475,7 @@ at least one peer was not added to a group 피드 - + Systray @@ -15194,17 +15602,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -15259,22 +15662,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15288,7 +15686,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15298,22 +15696,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15333,7 +15721,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15399,27 +15787,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare Retroshare (ë’¤ì—몫) - - + + Error : cannot get peer details. 오류 : ë™ë£Œ 세부 정보를 가져올 수 없습니다 - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15431,7 +15819,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15476,27 +15864,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure 서명 실패 - - Maybe password is wrong - 비밀번호가 ìž˜ëª»ëœ ê²ƒ 같습니다 + + Check the password! + - + Maybe password is wrong + 비밀번호가 ìž˜ëª»ëœ ê²ƒ 같습니다 + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15667,8 +16075,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15685,7 +16092,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15824,7 +16231,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel í…스트 ë ˆì´ë¸” @@ -15868,8 +16275,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + 설명 @@ -15900,6 +16307,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment 설명 추가 + + + Album + 앨범 + PhotoItem @@ -15909,12 +16321,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.ì–‘ì‹ - + TextLabel í…스트 ë ˆì´ë¸” - + <!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; } @@ -15994,7 +16406,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -16034,7 +16446,7 @@ requesting to edit it! - + Stop @@ -16258,17 +16670,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16594,7 +17006,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16729,13 +17141,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments 설명 - + Copy RetroShare Link 레트로 ì‰ì–´ ë§í¬ 복사 @@ -16745,7 +17157,7 @@ p, li { white-space: pre-wrap; } - + Comment 답글 달기 @@ -16766,12 +17178,12 @@ p, li { white-space: pre-wrap; } - + Hide 숨김 - + Vote up @@ -16781,7 +17193,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item í•­ëª©ì„ ì½ìŒìœ¼ë¡œ 설정하고 제거 @@ -16842,7 +17254,7 @@ p, li { white-space: pre-wrap; } í…스트 ë ˆì´ë¸” - + Loading 불러오는 중 @@ -16888,13 +17300,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16904,60 +17310,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel í…스트 ë ˆì´ë¸” - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16968,7 +17364,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17037,7 +17433,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link 레트로 ì‰ì–´ ë§í¬ 복사 @@ -17072,7 +17473,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17188,8 +17589,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17457,12 +17868,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17477,17 +17883,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + ì–´ë””ì—ì„œ : + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17512,10 +17933,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17525,13 +17956,48 @@ and use the import button to load it - + + Post + + + + Cancel 취소 - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17558,10 +18024,18 @@ and use the import button to load it ì–‘ì‹ - - - - + + + + + Click to view picture + + + + + + + Image @@ -17569,44 +18043,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17616,17 +18090,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17636,7 +18110,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17644,7 +18118,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17659,7 +18133,7 @@ and use the import button to load it - + follow Parent Group @@ -17669,7 +18143,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17694,7 +18168,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17730,29 +18204,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17830,7 +18304,7 @@ and use the import button to load it QObject - + Confirmation @@ -18069,7 +18543,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -18104,7 +18578,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18244,7 +18718,7 @@ Reported error is: - + TR up @@ -18289,7 +18763,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18305,7 +18779,7 @@ Reported error is: - + %1 seconds ago @@ -18389,7 +18863,7 @@ Security: no anonymous IDs - + Error @@ -18779,11 +19253,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19117,7 +19586,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19339,18 +19808,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19787,7 +20277,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19802,7 +20292,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19850,7 +20340,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 저장 - + Collection Editor @@ -19865,7 +20355,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19880,12 +20370,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -20132,7 +20622,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name ì´ë¦„ @@ -20152,7 +20642,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20165,10 +20655,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 제목 + + + UnRead + + Date @@ -20180,7 +20675,7 @@ If you believe it is correct, remove the corresponding line from the file and re ìž‘ì„±ìž - + Information for this identity is currently missing. @@ -20218,7 +20713,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -20226,7 +20721,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 날짜 @@ -20286,7 +20781,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20640,7 +21135,7 @@ prevents the message to be forwarded to your friends. - + Download 다운로드 @@ -20719,7 +21214,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20739,7 +21234,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20844,12 +21339,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat 대화 @@ -20859,7 +21354,7 @@ prevents the message to be forwarded to your friends. 대화 시작 - + Expand 확장 @@ -21122,13 +21617,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21594,7 +22089,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21622,7 +22117,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status ìƒíƒœ @@ -21719,7 +22214,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21754,12 +22249,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22424,7 +22919,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22466,7 +22961,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22522,7 +23017,7 @@ This choice can be reverted in settings. - + DHT @@ -23054,7 +23549,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23064,13 +23559,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23079,6 +23573,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23352,27 +23871,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23380,7 +23894,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23391,7 +23905,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name ì´ë¦„ @@ -23598,7 +24112,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23692,7 +24206,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23824,7 +24338,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23835,7 +24349,7 @@ p, li { white-space: pre-wrap; } - + Path 경로 @@ -23845,7 +24359,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23855,7 +24369,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23870,7 +24384,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24112,7 +24626,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24208,7 +24722,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24576,7 +25090,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24670,8 +25184,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24682,7 +25196,7 @@ p, li { white-space: pre-wrap; } - + Preview 미리보기 @@ -24707,12 +25221,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24732,7 +25246,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24770,7 +25284,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24780,12 +25294,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24820,12 +25333,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24859,7 +25372,7 @@ p, li { white-space: pre-wrap; } 새 피드 - + Yourself @@ -24873,7 +25386,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24885,7 +25398,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24893,7 +25406,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24974,8 +25487,8 @@ p, li { white-space: pre-wrap; } ì–‘ì‹ - - + + Avatar @@ -25004,6 +25517,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25116,7 +25634,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_nl.ts b/retroshare-gui/src/lang/retroshare_nl.ts index 8b6fd9559..c59474c60 100644 --- a/retroshare-gui/src/lang/retroshare_nl.ts +++ b/retroshare-gui/src/lang/retroshare_nl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare versie @@ -79,7 +79,7 @@ Veel plezier ;-) - + Only Hidden Node @@ -128,12 +128,12 @@ RetroShare: Geavanceerd Zoeken - + Search Criteria Zoek Criteria - + Add a further search criterion. Voeg een volgend zoek criterium toe @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; }⎠AlbumDialog - + Album Album @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; }⎠AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; }⎠Formulier - - + + TextLabel Tekst label @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; }⎠Werkbalk - + Icon Only Alleen pictogram @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; }⎠Kies de stijl van de gereedschaps knoppen. - + Icon Size = 8x8 Pictogramgrootte = 8 x 8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; }⎠Pictogramgroote = 128x128 - + Status Bar Status Bar @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; }⎠- + Main page items: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; }⎠- + Icon Size = 32x32 Pictogramgrootte = 32 x 32 @@ -827,14 +827,23 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Avatar wijzigen - + + TextLabel + Tekst label + + + Your Avatar Picture Uw Avatar afbeelding - + + Browse... + + + Add Avatar - Avatar toevoegen + Avatar toevoegen @@ -842,25 +851,34 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Verwijderen - + Set your Avatar picture Uw Avatar afbeelding instellen - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Laad Avatar + Laad Avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klik om je avatar te veranderen @@ -868,7 +886,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update RetroShare Bandwidth Usage Bandbreedte gebruik door RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Instellingen weergeven + TextLabel + Tekst label + + + Reset Opnieuw instellen - Receive Rate - Ontvang ranglijst + Ontvang ranglijst - Send Rate - Verzend ranglijst + Verzend ranglijst - + Always on Top Altijd op de voorgrond - Style - Stijl + Stijl - + Changes the transparency of the Bandwidth Graph Verander de doorzichtigheid van de grafische bandbreedte - + 100 100 @@ -935,30 +974,27 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Ondoorzichtig - Save - Opslaan + Opslaan - Cancel - Annuleren + Annuleren - + Since: Sinds - Hide Settings - Verberg instellingen + Verberg instellingen BandwidthStatsWidget - + Sum Som @@ -980,7 +1016,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Aantal - + Average Gemiddelde @@ -1114,7 +1150,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Tekst label - + Comments Opmerkingen @@ -1192,6 +1228,85 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Tekst label + + BoardsCommentsItem + + + I like this + Ik vind dit leuk! + + + + 0 + 0 + + + + I dislike this + Ik vindt dit niet leuk + + + + Toggle Message Read Status + Verander boodschap gelezen status + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopieer RetroShare Link + + + + + Expand + Uitbreiden + + + + Set as read and remove item + Markeer als gelezen en verplaats item + + + + Remove Item + Item verwijderen + + + + Name + Naam + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Log scale + + + Default + Standaard + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Ik vind dit leuk! + + + + 0 + 0 + + + + I dislike this + Ik vindt dit niet leuk + + + + Toggle Message Read Status + Verander boodschap gelezen status + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopieer RetroShare Link + + + + + Expand + Uitbreiden + + + + Set as read and remove item + Markeer als gelezen en verplaats item + + + + Remove Item + Item verwijderen + + + + Name + Naam + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to - You have %1 new messages - U heeft %1 nieuwe berichten + U heeft %1 nieuwe berichten + + + You have %1 new message + U heeft %1 nieuw bericht + + + %1 new messages + %1 nieuwe berichten + + + %1 new message + %1 nieuw bericht + + + + You have %1 mentions + - You have %1 new message - U heeft %1 nieuw bericht + You have %1 mention + - %1 new messages - %1 nieuwe berichten + %1 mentions + - %1 new message - %1 nieuw bericht + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Verwijder alles - - - mention(s) - - ChatLobbyWidget @@ -2097,13 +2312,11 @@ Double click a chat room to enter and chat. - Group chat - Groeps chat + Groeps chat - - + Private chat Privé Chat @@ -2168,17 +2381,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/> <body><p align="justify"> op dit tabblad kunt u instellen hoeveel chatberichten Retroshare blijft opgeslagen op de schijf en hoeveel van de vorige conversatie wordt weergegeven, voor de verschillende chat-systemen. De maximale opslagperiode te ontdoen van oude berichten en voorkomt u dat de chatgeschiedenis uit te vullen met vluchtige chat (bijvoorbeeld chat lobby's en verre chat).</p></body></html> - Chatlobbies - Chatlobbies + Chatlobbies - + Enabled: Ingeschakeld: @@ -2199,11 +2411,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2264,11 +2477,17 @@ Double click a chat room to enter and chat. + Broadcast Uitzenden - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Opgeslagen berichten (0 = ongelimiteerd): @@ -2411,8 +2630,23 @@ Double click a chat room to enter and chat. Privé Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2581,7 +2815,7 @@ Double click a chat room to enter and chat. - + is typing... typt.... @@ -2598,12 +2832,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Wil je echt voorgoed de geschiedenis verwijderen? @@ -2675,7 +2909,7 @@ after HTML conversion. Niet stoppen met kleuren na X items gevonden (meer CPU nodig) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Zoek vorige</b> <br/><i>Ctrl + Shift + G</i> @@ -2715,12 +2949,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Markeer deze geselecteerde tekst</b><br><i>Ctrl + M</i> - + Person id: @@ -2736,7 +2970,7 @@ Double click on it to add his name on text writer. - + items found. objecten gevonden. @@ -2756,7 +2990,7 @@ Double click on it to add his name on text writer. Typ een bericht hier - + Don't stop to color after @@ -2914,12 +3148,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Gegevens - + Local Address Lokaal adres @@ -2930,12 +3164,12 @@ Double click on it to add his name on text writer. Extern adres - + Node info: - + Current address: @@ -2951,31 +3185,41 @@ Double click on it to add his name on text writer. Poort - + Include signatures Inclusief handtekeningen - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: kan geen verbindings gegevens vinden. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2991,22 +3235,22 @@ Double click on it to add his name on text writer. - + Encryption Versleuteling - + Not connected Niet verbonden - + Retroshare node details - + Node name : @@ -3041,13 +3285,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3062,7 +3311,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3073,17 +3322,22 @@ Double click on it to add his name on text writer. Geen - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3093,7 +3347,7 @@ Double click on it to add his name on text writer. - + with @@ -3285,12 +3539,12 @@ Double click on it to add his name on text writer. Gegevens van uw aanvraag - + Peer details Verbindings details - + Name: Naam: @@ -3303,12 +3557,12 @@ Double click on it to add his name on text writer. Knooppunt - + Location: Woonplaats: - + Options Opties @@ -3317,12 +3571,12 @@ Double click on it to add his name on text writer. Voeg het certificaat handmatig in - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Voeg een vriend toe aan een groep: @@ -3332,7 +3586,7 @@ Double click on it to add his name on text writer. Verifieer vriend (Teken PGP Sleutel) - + Please paste below your friend's Retroshare ID @@ -3357,7 +3611,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Voeg toe als vriend om mee verbonden te worden @@ -3366,7 +3620,7 @@ Double click on it to add his name on text writer. Om je vriend's verzoek te accepteren klik de Klaar knop - + Sorry, some error appeared Sorry, een error verscheen @@ -3386,32 +3640,32 @@ Double click on it to add his name on text writer. Gegevens van uw vriend: - + Key validity: Sleutel deugdelijkheid: - + Profile ID: - + Signers Ondertekenaars - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Deze verbinding staat al op je vriend zijn lijst. Toevoegen stelt waarschijnlijk alleen zijn ip adres in. - + To accept the Friend Request, click the Accept button. @@ -3457,7 +3711,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Certificaat fout @@ -3490,12 +3744,12 @@ Double click on it to add his name on text writer. Verbindings ID - + Not a valid Retroshare certificate! - + RetroShare Invitation RetroShare uitnodiging @@ -3515,12 +3769,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3568,7 +3822,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.U heeft een aanvraag om vriend te worden - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3656,12 +3940,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Gebruiken als directe bron indien mogelijk - + IP-Addr: IP-Adr: - + IP-Address IP Adres: @@ -3719,7 +4003,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Sleutel toevoegen aan keyring - + This key is already in your keyring Deze sleutel is al in uw keyring @@ -3777,12 +4061,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 Toegevoegd met certificaat van %1 @@ -3865,7 +4149,12 @@ even if you don't make friends. UDP Resultaat - + + Status + Status + + + <!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; } @@ -4287,7 +4576,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4435,7 +4724,7 @@ p, li { white-space: pre-wrap; } Geen Cirkel Limitaties Geselecteerd - + [Unknown] @@ -4450,7 +4739,7 @@ p, li { white-space: pre-wrap; } Verwijder - + Search Zoek @@ -4470,7 +4759,7 @@ p, li { white-space: pre-wrap; } Ondertekend door bekende knooppunten - + Edit Circle Bewerk Cirkel @@ -4490,12 +4779,12 @@ p, li { white-space: pre-wrap; } Anoniem ID - + Circle name - + Update @@ -4521,7 +4810,7 @@ p, li { white-space: pre-wrap; } PGP geaccocieerd ID - + Add Member @@ -4665,7 +4954,7 @@ p, li { white-space: pre-wrap; }⎠- + Attachments Attachments @@ -4711,7 +5000,7 @@ p, li { white-space: pre-wrap; }⎠Bestanden Slepen en Neerzetten uit het zoek resultaat - + Paste RetroShare Links PLak RetroShare Link's @@ -4721,7 +5010,7 @@ p, li { white-space: pre-wrap; }⎠PLak RetroShare Link - + Drop file error. Verwijder bestands error @@ -4748,17 +5037,41 @@ p, li { white-space: pre-wrap; }⎠- + RetroShare RetroShare - - File already Added and Hashed - Bestand is reeds toegevoegd en in de hash opgenomen + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Bestand is reeds toegevoegd en in de hash opgenomen + + + Please add a Subject Voeg een onderwerp toe @@ -4789,12 +5102,12 @@ p, li { white-space: pre-wrap; }⎠Wilt u echt %1 berichten genereren? - + You are about to add files you're not actually sharing. Do you still want this to happen? U gaat nu bestanden toevoegen die niet gedeeld zijn. Weet u zeker dat u dat wilt? - + Edit Channel Post @@ -4814,7 +5127,7 @@ p, li { white-space: pre-wrap; }⎠- + About to post un-owned files to a channel. U staat op het punt om bestanden waar u geen eigenaar van bent naar een Kanaal te posten. @@ -4906,7 +5219,7 @@ p, li { white-space: pre-wrap; } - + No Forum Geen Forum @@ -5361,7 +5674,7 @@ en daar de importeer functie gebruiken DHTGraphSource - + users gebruikers @@ -6364,7 +6677,7 @@ en daar de importeer functie gebruiken FlatStyle_RDM - + Friends Directories Vrienden directories @@ -6859,7 +7172,7 @@ at least one peer was not added to a group Zoek vrienden - + Mark all Selecteer alles @@ -6873,7 +7186,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Bewerk berichten status @@ -6977,7 +7290,7 @@ at least one peer was not added to a group Retroshare groepschat: berichten worden verstuurd naar alle verbonden vrienden. - + Network Netwerk @@ -7042,7 +7355,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7073,7 +7386,7 @@ at least one peer was not added to a group - + Node name @@ -7332,12 +7645,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7709,7 +8022,7 @@ p, li { white-space: pre-wrap; } Router Statistieken - + GroupBox @@ -7774,7 +8087,7 @@ p, li { white-space: pre-wrap; } - + Details Gegevens @@ -7797,7 +8110,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Beheerde sleutels @@ -7998,7 +8311,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8008,13 +8321,30 @@ p, li { white-space: pre-wrap; } Zoek Titel - - + + + + Description Beschrijving - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Zoek beschrijving @@ -8024,42 +8354,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sorteer op naam + Sorteer op naam - Sort by Popularity - Sorteer op populariteit + Sorteer op populariteit - Sort by Last Post - Sorteer op laatste post + Sorteer op laatste post - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8074,40 +8381,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Het laatste bericht - + + Name Naam - - Unread - - - - + Popularity Populariteit - - + + Never - Display - Toon + Toon - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8256,7 +8558,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanalen @@ -8277,12 +8579,12 @@ p, li { white-space: pre-wrap; } Mijn Kanalen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Geabonneerde kanalen @@ -8755,7 +9057,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8855,12 +9157,12 @@ p, li { white-space: pre-wrap; } - + Files Bestanden - + Comments Opmerkingen @@ -8871,18 +9173,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8892,12 +9194,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8957,7 +9259,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8972,12 +9274,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9053,23 +9355,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Geabonneerd - - Subscribe Registreren - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Geen kanaal geselecteerd @@ -9091,11 +9406,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanaal bericht - - - new message(s) - - GxsCircleItem @@ -9613,7 +9923,7 @@ voor je een opmerking kan doen Start een nieuw draadje in het geselecteerde forum - + Search forums Zoek forums @@ -9622,12 +9932,12 @@ voor je een opmerking kan doen Het laatste bericht - + New Thread Nieuw draadje - + Threaded View Threaded View @@ -9637,19 +9947,19 @@ voor je een opmerking kan doen Flat View - - + + Title Titel - - + + Date Datum - + Author Auteur @@ -9664,7 +9974,17 @@ voor je een opmerking kan doen Laden - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9721,23 +10041,23 @@ voor je een opmerking kan doen Zoek Inhoud - + No name Geen naam - - + + Reply Antwoord - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9775,12 +10095,12 @@ voor je een opmerking kan doen Merk als ongelezen - + Copy RetroShare Link Kopieer RetroShare Link - + Hide Verberg @@ -9789,7 +10109,7 @@ voor je een opmerking kan doen Uitbreiden - + [unknown] @@ -9819,8 +10139,8 @@ voor je een opmerking kan doen - - + + Distribution @@ -9919,12 +10239,12 @@ voor je een opmerking kan doen Origineel bericht - + New thread - + Edit Bewerk @@ -9980,7 +10300,7 @@ voor je een opmerking kan doen - + Author's reputation @@ -10000,7 +10320,7 @@ voor je een opmerking kan doen - + <b>Loading...<b> @@ -10040,6 +10360,11 @@ voor je een opmerking kan doen Storage + + + Last seen at friends: + + Moderators @@ -10107,7 +10432,7 @@ This message is missing. You should receive it later. Op %1, %2 schreef: - + Forum name @@ -10139,11 +10464,6 @@ This message is missing. You should receive it later. Forum Post Forum bericht - - - new message(s) - - GxsForumsDialog @@ -10592,7 +10912,7 @@ This message is missing. You should receive it later. PrintVoorbeeld - + Unsubscribe Uitschrijven @@ -10607,7 +10927,7 @@ This message is missing. You should receive it later. Open in een nieuw tab - + Remove this search @@ -10617,12 +10937,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Details weergeven @@ -10689,12 +11009,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopieer RetroShare Link @@ -10709,7 +11029,7 @@ This message is missing. You should receive it later. Merk alles als ongelezen - + AUTHD AUTHD @@ -11243,7 +11563,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11252,7 +11572,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11278,7 +11598,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11356,49 +11676,55 @@ p, li { white-space: pre-wrap; }⎠Formulier - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopieer uw certificaat naar het klembord @@ -11446,17 +11772,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11471,7 +11792,12 @@ new short format RetroShare uitnodiging - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Sla op als... @@ -11736,14 +12062,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alles - + Reputation Reputatie @@ -11753,12 +12079,12 @@ p, li { white-space: pre-wrap; } Zoek - + Anonymous Id Anoniem Id - + Create new Identity Maak een nieuwe identiteit @@ -11902,7 +12228,7 @@ p, li { white-space: pre-wrap; } - + Send message Verstuur bericht @@ -11974,7 +12300,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anoniem @@ -11989,24 +12315,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you Deze identiteit is eigendom van u - - + + My own identities - - + + My contacts - + Show Items @@ -12021,7 +12347,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12080,13 +12406,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12146,7 +12477,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Bewerk Cirkel @@ -12194,7 +12525,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12203,12 +12534,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12220,12 +12551,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node Identiteit eigendom van u, gekoppeld aan uw Retroshare knoop @@ -12341,17 +12672,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12508,8 +12839,8 @@ These identities will soon be not supported anymore. - - + + People Mensen @@ -12520,7 +12851,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12530,7 +12861,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12590,7 +12921,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12600,7 +12931,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12638,7 +12969,22 @@ These identities will soon be not supported anymore. Pseudoniem - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nieuwe identiteit @@ -12655,14 +13001,14 @@ These identities will soon be not supported anymore. - + N/A Onbekend - + Edit identity Identiteit aanpassen @@ -12673,24 +13019,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12709,17 +13058,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Fout bij ophalen sleutel! - + Error KeyID invalid SleutelID is ongeldig - + Unknown GpgId Onbekend GPG ID @@ -12729,7 +13088,7 @@ These identities will soon be not supported anymore. Onbekende echte naam - + Create New Identity Maak een nieuwe identiteit @@ -12739,7 +13098,12 @@ These identities will soon be not supported anymore. Type - + + Choose image... + + + + @@ -12779,12 +13143,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12794,7 +13153,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12899,8 +13258,12 @@ These identities will soon be not supported anymore. + Quote + Citaat + + Send - Verstuur + Verstuur @@ -13058,7 +13421,7 @@ These identities will soon be not supported anymore. - + Options Opties @@ -13090,12 +13453,12 @@ These identities will soon be not supported anymore. Snel start Wizard - + RetroShare %1 a secure decentralized communication platform RetroShare %1 is een beveiligd gedecentraliseerde communicatie platform - + Unfinished Niet afgemaakt @@ -13227,7 +13590,7 @@ Maak meer ruimte vrij en klik Ok. Toon - + Make sure this link has not been forged to drag you to a malicious website. Wees er zeker van dat deze link je niet naar een verdachte website stuurt @@ -13272,7 +13635,7 @@ Maak meer ruimte vrij en klik Ok. Service toestemming matrix - + Statistics Statistieken @@ -13301,7 +13664,7 @@ Maak meer ruimte vrij en klik Ok. MessageComposer - + Compose Opstellen @@ -13403,7 +13766,7 @@ Maak meer ruimte vrij en klik Ok. - + Tags Labels @@ -13498,12 +13861,12 @@ Maak meer ruimte vrij en klik Ok. Voeg een citaat blok toe - + Send To: Verstuur naar: - + &Left &links @@ -13533,7 +13896,12 @@ Maak meer ruimte vrij en klik Ok. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hallo,<br>ik wil een goede vriend van mij aanraden; als je mij vertrouwd kun je hem ook vertrouwen. <br> @@ -13559,12 +13927,12 @@ Maak meer ruimte vrij en klik Ok. - + Save Message Bewaar bericht - + Message has not been Sent. Do you want to save message to draft box? Bericht is niet verzonden.⎠@@ -13576,7 +13944,7 @@ Wil je het bericht bewaren in de concepten map? PLak RetroShare Link - + Add to "To" Voeg toe aan "Aan" @@ -13831,7 +14199,7 @@ Wil je het bericht bewaren? Voeg extra bestand toe - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13845,6 +14213,21 @@ Wil je het bericht bewaren? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13857,7 +14240,7 @@ Wil je het bericht bewaren? Van: - + Bullet list (disc) @@ -13897,13 +14280,13 @@ Wil je het bericht bewaren? - - + + Thanks, <br> - + Distant identity: @@ -14042,8 +14425,23 @@ Wil je het bericht bewaren? Bericht - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14055,12 +14453,12 @@ Wil je het bericht bewaren? Aanbevolen bestanden - + Download all Recommended Files Download alle Aanbevolen bestanden - + Subject: Onderwerp: @@ -14135,12 +14533,18 @@ Wil je het bericht bewaren? - + + Message Size: + + + + File Name Bestandsnaam - + + Size Grootte @@ -14201,18 +14605,33 @@ Wil je het bericht bewaren? Download - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Download alles - + Print Document Print Document @@ -14227,7 +14646,7 @@ Wil je het bericht bewaren? HTML- bestand (*.htm *.html );;Alle bestanden (*) - + Load images always for this message Afbeeldingen altijd laden voor dit bericht @@ -14368,7 +14787,7 @@ Wil je het bericht bewaren? MessagesDialog - + New Message Nieuw bericht @@ -14424,14 +14843,14 @@ Wil je het bericht bewaren? - + Tags Labels - + Inbox Inbox @@ -14526,7 +14945,7 @@ Wil je het bericht bewaren? Stuur bericht door - + Subject Onderwerp @@ -14638,7 +15057,7 @@ Wil je het bericht bewaren? - + Open in a new window Open in een nieuw scherm @@ -14723,7 +15142,7 @@ Wil je het bericht bewaren? - + Drafts Concepten @@ -14844,7 +15263,7 @@ Wil je het bericht bewaren? Beantwoord bericht - + Delete Message Verwijder bericht @@ -14855,7 +15274,7 @@ Wil je het bericht bewaren? - + Expand Uitbreiden @@ -14865,7 +15284,7 @@ Wil je het bericht bewaren? Item verwijderen - + from van @@ -14874,6 +15293,11 @@ Wil je het bericht bewaren? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15187,7 +15611,7 @@ Reported error: - + Groups Groepen @@ -15217,19 +15641,19 @@ Reported error: importeer vriendenlijst, inclusief groepen - - + + Search - + ID ID - + Search ID @@ -15239,7 +15663,7 @@ Reported error: - + Show Items @@ -15438,18 +15862,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -15487,7 +15911,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15505,7 +15929,7 @@ at least one peer was not added to a group Dit is een test. - + Newest on top @@ -15516,20 +15940,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15566,22 +16005,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon Systeem tray ikoon - + Message Bericht @@ -15606,12 +16045,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Vriend verbonden @@ -15658,27 +16092,37 @@ at least one peer was not added to a group Groeps chat - + + Toaster position + + + + Chat rooms - + Position Positie - + + Activity + + + + X Margin X marge - + Y Margin Y marge - + Systray message Systemtray bericht @@ -15728,7 +16172,7 @@ at least one peer was not added to a group Notify - + Disable All Toasters Alle Toasters uitschakelen @@ -15742,7 +16186,7 @@ at least one peer was not added to a group Feed - + Systray @@ -15884,17 +16328,16 @@ Laag verkeer: 10% standaard verkeerd en TODO: pauseerd alle bestands overdrachte PGPKeyDialog - Dialog - Dialoog + Dialoog - + Profile info - + Name : @@ -15949,22 +16392,17 @@ Laag verkeer: 10% standaard verkeerd en TODO: pauseerd alle bestands overdrachte Uiterst - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15978,7 +16416,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15988,22 +16426,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Onderteken PGP Sleutel + Onderteken PGP Sleutel - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16023,7 +16455,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16089,28 +16521,28 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: kan geen verbindings gegevens vinden. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) De ingevoerde sleutel algoritme wordt niet ondersteund door RetroShare⎠(Alleen RSA sleutels worden op dit moment ondersteund) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16122,7 +16554,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16167,27 +16599,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Handtekening fout - - Maybe password is wrong - Misschien is uw wachtwoord fout + + Check the password! + - + Maybe password is wrong + Misschien is uw wachtwoord fout + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16366,8 +16818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Mensen @@ -16384,7 +16835,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Interne - + Chat with this person @@ -16527,7 +16978,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel Tekst label @@ -16571,8 +17022,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Opmerkingen @@ -16607,6 +17058,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Schrijf een opmerking + + + Album + Album + PhotoItem @@ -16616,12 +17072,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulier - + TextLabel Tekst label - + <!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; } @@ -16717,7 +17173,7 @@ p, li { white-space: pre-wrap; }⎠Bekijk Foto - + PhotoShare PhotoShare @@ -16758,7 +17214,7 @@ voordat je het kunt bewerken! - + Stop Stop @@ -16986,12 +17442,12 @@ p, li { white-space: pre-wrap; }⎠PluginsPage - + Authorize all plugins Authoriseer alle plugins - + Plugin look-up directories Plugin look-up directories @@ -17031,7 +17487,7 @@ malicious behavior of crafted plugins. Controleer dit voor plugin ontwikkeling. Zij worden niet gecontroleerd voor de index. Echter, gewoonlijk zal het controleren van de index je beschermen tegen verdacht gebruik van de plugins - + Plugins Plugins @@ -17413,7 +17869,7 @@ malicious behavior of crafted plugins. Andere Onderwerpen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17584,13 +18040,13 @@ malicious behavior of crafted plugins. Site - - + + Comments Opmerkingen - + Copy RetroShare Link Kopieer RetroShare Link @@ -17600,7 +18056,7 @@ malicious behavior of crafted plugins. - + Comment Opmerking @@ -17621,12 +18077,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up Stemmen van @@ -17640,7 +18096,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item Markeer als gelezen en verplaats item @@ -17701,7 +18157,7 @@ malicious behavior of crafted plugins. Tekst label - + Loading Laden @@ -17787,13 +18243,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17803,60 +18253,50 @@ malicious behavior of crafted plugins. - - - + + + unknown onbekend - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Tekst label - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17867,7 +18307,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17936,7 +18376,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link Kopieer RetroShare Link @@ -17971,7 +18416,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18095,8 +18540,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18368,9 +18823,8 @@ en daar de importeer functie gebruiken PulseAddDialog - Post From: - Bericht van: + Bericht van: Account 1 @@ -18385,7 +18839,7 @@ en daar de importeer functie gebruiken Account 3 - + Add to Pulse Voeg aan Pulse toe @@ -18408,17 +18862,32 @@ en daar de importeer functie gebruiken URL - + GroupLabel - + IDLabel - + + From: + Van: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18443,10 +18912,20 @@ en daar de importeer functie gebruiken - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18456,14 +18935,53 @@ en daar de importeer functie gebruiken - + + Post + + + + Cancel Annuleren - Post Pulse to Wire - Post Pulse to Wire + Post Pulse to Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18489,10 +19007,18 @@ en daar de importeer functie gebruiken Formulier - - - - + + + + + Click to view picture + + + + + + + Image PLaatje @@ -18500,44 +19026,44 @@ en daar de importeer functie gebruiken PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18547,17 +19073,17 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18567,7 +19093,7 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18575,7 +19101,7 @@ en daar de importeer functie gebruiken PulseTopLevel - + retweeted @@ -18590,7 +19116,7 @@ en daar de importeer functie gebruiken - + follow Parent Group @@ -18600,7 +19126,7 @@ en daar de importeer functie gebruiken ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18625,7 +19151,7 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18661,29 +19187,29 @@ en daar de importeer functie gebruiken - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18761,7 +19287,7 @@ en daar de importeer functie gebruiken QObject - + Confirmation Bevestiging @@ -19003,7 +19529,7 @@ Karakters <b>",|,/,\,&lt;,&gt;,*,?</b> worden vervangen Resultaat - + Unable to make path Niet mogelijk om pad te maken @@ -19038,7 +19564,7 @@ Karakters <b>",|,/,\,&lt;,&gt;,*,?</b> worden vervangen Bestands aanvraag gestopt - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Deze versie van RetroShare maakt gebruik van OpenPGP-SDK. Als bijeffect gebruikt het niet de gedeelde PGP sleutelring maar heeft zijn eigen sleutelring die gebruikt wordt door alle RetroShare gevallen.<br><br> @@ -19181,7 +19707,7 @@ De error is: %2 secs - + TR up TR omhoog @@ -19226,7 +19752,7 @@ De error is: %2 - + Move IP %1 to whitelist @@ -19242,7 +19768,7 @@ De error is: %2 - + %1 seconds ago @@ -19326,7 +19852,7 @@ Security: no anonymous IDs - + Error Fout @@ -19716,11 +20242,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -20090,7 +20611,7 @@ p, li { white-space: pre-wrap; }⎠RSGraphWidget - + %1 KB %1 KB @@ -20312,18 +20833,39 @@ p, li { white-space: pre-wrap; }⎠RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20760,7 +21302,7 @@ p, li { white-space: pre-wrap; }⎠Download! - + File Bestand @@ -20775,7 +21317,7 @@ p, li { white-space: pre-wrap; }⎠Index - + Bad filenames have been cleaned Verkeerde bestandsnamen zijn opgeschoond @@ -20825,7 +21367,7 @@ Betrokken bestanden zijn rood gekleurd Opslaan - + Collection Editor Collection Editor @@ -20840,7 +21382,7 @@ Betrokken bestanden zijn rood gekleurd Bestandstotaal - + Real Size: Waiting child... Werkelijke grootte: Wachten ... @@ -20855,12 +21397,12 @@ Betrokken bestanden zijn rood gekleurd Dit is een directory. Dubbelklik om te openen - + Download files - + Specify... Specificeer... @@ -21109,7 +21651,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde RsFriendListModel - + Name Naam @@ -21129,7 +21671,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde IP - + Profile ID @@ -21142,10 +21684,15 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde RsGxsForumModel - + Title Titel + + + UnRead + + Date @@ -21157,7 +21704,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde Auteur - + Information for this identity is currently missing. @@ -21195,7 +21742,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Bericht ontbreekt ... ] @@ -21203,7 +21750,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21263,7 +21810,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21618,7 +22165,7 @@ prevents the message to be forwarded to your friends. Bestandsnaam - + Download Download @@ -21697,7 +22244,7 @@ prevents the message to be forwarded to your friends. Open map - + Create Collection... Collectie maken... @@ -21717,7 +22264,7 @@ prevents the message to be forwarded to your friends. Download van collectief bestand... - + Collection Collectie @@ -21822,12 +22369,12 @@ prevents the message to be forwarded to your friends. Verbindings details - + Deny friend Weiger vriend - + Chat Chat @@ -21837,7 +22384,7 @@ prevents the message to be forwarded to your friends. Start chat - + Expand Uitbreiden @@ -22107,13 +22654,13 @@ je ook als ja achter een Firewall of VPN zit. Discovery ingeschakeld (aanbevolen) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Ontdekking uit @@ -22579,7 +23126,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Netwerk @@ -22607,7 +23154,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22704,7 +23251,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22739,12 +23286,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23412,7 +23959,7 @@ p, li { white-space: pre-wrap; } Ontbrekende PGP certificaat - + Wrong password @@ -23454,7 +24001,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Vriend toevoegen @@ -23510,7 +24057,7 @@ This choice can be reverted in settings. Service toestemming matrix - + DHT DHT @@ -24050,7 +24597,7 @@ p, li { white-space: pre-wrap; }⎠TorStatus - + Tor @@ -24060,13 +24607,12 @@ p, li { white-space: pre-wrap; }⎠- - + Tor is currently offline - + Tor is OK @@ -24075,6 +24621,31 @@ p, li { white-space: pre-wrap; }⎠No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24348,35 +24919,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Je hebt %1 complete downloads + You have %1 completed transfers + - You have %1 completed download - Je hebt %1 complete download + You have %1 completed transfer + - %1 completed downloads - %1 complete downloads + %1 completed transfers + - %1 completed download - %1 complete download + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Je hebt %1 complete downloads + + + You have %1 completed download + Je hebt %1 complete download + + + %1 completed downloads + %1 complete downloads + + + %1 completed download + %1 complete download TransfersDialog - + Downloads Downloads @@ -24387,7 +24969,7 @@ p, li { white-space: pre-wrap; } Uploads - + Name i.e: file name Naam @@ -24594,7 +25176,7 @@ p, li { white-space: pre-wrap; } Specificeer... - + Move in Queue... Verplaats in Rij... @@ -24688,7 +25270,7 @@ p, li { white-space: pre-wrap; } Vul een nieuwe -en geldige- bestandsnaam in - + Expand all Alles uitklappen @@ -24820,7 +25402,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolommen @@ -24831,7 +25413,7 @@ p, li { white-space: pre-wrap; } Bestandsoverdrachten - + Path Pad @@ -24841,7 +25423,7 @@ p, li { white-space: pre-wrap; } Pad kolom weergeven - + Could not delete preview file Kan geen gegevens verwijderen voorvertoningsbestand @@ -24851,7 +25433,7 @@ p, li { white-space: pre-wrap; } Probeer het opnieuw? - + Create Collection... Collectie maken.. @@ -24866,7 +25448,7 @@ p, li { white-space: pre-wrap; } Bekijk collectie.. - + Collection Collectie @@ -25108,7 +25690,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Onbekenden verbinding @@ -25204,7 +25786,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages U heeft %1 nieuwe berichten @@ -25576,7 +26158,7 @@ p, li { white-space: pre-wrap; } Maak een groep - + Subscribe to Group Registreer bij deze Groep @@ -25670,8 +26252,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Toon Bewerkte Geschiedenis @@ -25682,7 +26264,7 @@ p, li { white-space: pre-wrap; } - + Preview Voorbeeld @@ -25707,12 +26289,12 @@ p, li { white-space: pre-wrap; } Verberg Bewerkte Geschiedenis - + Edit Page Bewerk pagina - + Create New Wiki Page Maak een nieuwe Wiki pagina @@ -25732,7 +26314,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Maak een nieuwe Wiki groep @@ -25774,7 +26356,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -25784,12 +26366,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Ververs @@ -25824,12 +26405,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25899,7 +26480,7 @@ p, li { white-space: pre-wrap; } Toon: - + Yourself Uzelf @@ -25937,7 +26518,7 @@ p, li { white-space: pre-wrap; } Post Pulse to Wire - + RetroShare RetroShare @@ -25949,7 +26530,7 @@ p, li { white-space: pre-wrap; } - + The Wire De Kabel @@ -25957,7 +26538,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26038,8 +26619,8 @@ p, li { white-space: pre-wrap; } Formulier - - + + Avatar Avatar @@ -26068,6 +26649,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26180,7 +26766,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_pl.ts b/retroshare-gui/src/lang/retroshare_pl.ts index d98bb81ec..ef7478036 100644 --- a/retroshare-gui/src/lang/retroshare_pl.ts +++ b/retroshare-gui/src/lang/retroshare_pl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Wyszukiwanie zaawansowane - + Search Criteria Kryteria wyszukiwania - + Add a further search criterion. Dodaj nastÄ™pne kryterium wyszukiwania. @@ -271,7 +271,7 @@ AlbumDialog - + Album Album @@ -410,7 +410,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -453,8 +453,8 @@ p, li { white-space: pre-wrap; } Formularz - - + + TextLabel @@ -529,7 +529,7 @@ p, li { white-space: pre-wrap; } - + Icon Only Tylko ikona @@ -554,7 +554,7 @@ p, li { white-space: pre-wrap; } Wybierz styl przycisków narzÄ™dzi - + Icon Size = 8x8 Rozmiar ikon = 8x8 @@ -579,7 +579,7 @@ p, li { white-space: pre-wrap; } Rozmiar ikon = 128x128 {128x?} - + Status Bar @@ -654,7 +654,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -669,7 +669,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Rozmiar ikon = 32x32 {32x?} @@ -735,13 +735,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -750,25 +755,30 @@ p, li { white-space: pre-wrap; } UsuÅ„ - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar Kliknij, aby zmienić swój awatar @@ -776,7 +786,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -796,44 +806,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Zużycie Å‚Ä…cza przez RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Pokaż ustawienia + TextLabel + + + + Reset Zresetuj - Receive Rate - PrÄ™dkość pobierania + PrÄ™dkość pobierania - Send Rate - PrÄ™dkość wysyÅ‚ania + PrÄ™dkość wysyÅ‚ania - + Always on Top Zawsze na wierzchu - Style - Styl + Styl - + Changes the transparency of the Bandwidth Graph Zmienia przezroczystość wykresu zużycia Å‚Ä…cza - + 100 100 @@ -843,30 +874,27 @@ p, li { white-space: pre-wrap; } % nieprzezroczysty - Save - Zapisz + Zapisz - Cancel - Anuluj + Anuluj - + Since: Od: - Hide Settings - Ukryj ustawienia + Ukryj ustawienia BandwidthStatsWidget - + Sum @@ -888,7 +916,7 @@ p, li { white-space: pre-wrap; } Liczba - + Average @@ -1022,7 +1050,7 @@ p, li { white-space: pre-wrap; } - + Comments Komentarze @@ -1100,6 +1128,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + PrzeÅ‚Ä…cz status przeczytanej wiadomoÅ›ci + + + + Avatar + Awatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + RozwiÅ„ + + + + Set as read and remove item + + + + + Remove Item + UsuÅ„ element + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Ukryj + + BwCtrlWindow @@ -1235,6 +1342,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + DomyÅ›lne + + + + Dark + + ChannelPage @@ -1287,6 +1404,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + PrzeÅ‚Ä…cz status przeczytanej wiadomoÅ›ci + + + + Avatar + Awatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + RozwiÅ„ + + + + Set as read and remove item + + + + + Remove Item + UsuÅ„ element + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Ukryj + + ChatLobbyDialog @@ -1494,24 +1690,40 @@ into the image, so as to - You have %1 new messages - Masz %1 nowych wiadomoÅ›ci + Masz %1 nowych wiadomoÅ›ci + + + You have %1 new message + Masz %1 nowÄ… wiadomość + + + %1 new messages + %1 nowych wiadomoÅ›ci + + + %1 new message + %1 nowa wiadomość + + + + You have %1 mentions + - You have %1 new message - Masz %1 nowÄ… wiadomość + You have %1 mention + - %1 new messages - %1 nowych wiadomoÅ›ci + %1 mentions + - %1 new message - %1 nowa wiadomość + %1 mention + @@ -1524,11 +1736,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1993,13 +2200,11 @@ Double click a chat room to enter and chat. - Group chat - Chat grupowy + Chat grupowy - - + Private chat Chat prywatny @@ -2064,17 +2269,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2095,11 +2295,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2160,11 +2361,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2303,8 +2510,23 @@ Double click a chat room to enter and chat. Prywatny Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2473,7 +2695,7 @@ Double click a chat room to enter and chat. - + is typing... pisze... @@ -2490,12 +2712,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Czy naprawdÄ™ chcesz fizycznie usunąć historiÄ™? @@ -2567,7 +2789,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2603,12 +2825,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2624,7 +2846,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2644,7 +2866,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2802,12 +3024,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Szczegóły - + Local Address Adres Lokalny @@ -2818,12 +3040,12 @@ Double click on it to add his name on text writer. Adres zewnÄ™trzny - + Node info: - + Current address: @@ -2839,31 +3061,41 @@ Double click on it to add his name on text writer. Port - + Include signatures ZaÅ‚Ä…cz podpisy - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2879,22 +3111,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2929,13 +3161,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2950,7 +3187,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2961,17 +3198,22 @@ Double click on it to add his name on text writer. brak - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2981,7 +3223,7 @@ Double click on it to add his name on text writer. - + with @@ -3089,12 +3331,12 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Nazwa: @@ -3103,22 +3345,22 @@ Double click on it to add his name on text writer. Email: - + Location: Miejsce: - + Options Opcje - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Dodaj przyjaciela do grupy: @@ -3128,7 +3370,7 @@ Double click on it to add his name on text writer. Uwierzytelnij znajomego (Podpisz Klucz PGP) - + Please paste below your friend's Retroshare ID @@ -3153,12 +3395,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3178,32 +3420,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3249,17 +3491,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Åadowanie certyfikatu nie powiodÅ‚o siÄ™ - + Not a valid Retroshare certificate! - + RetroShare Invitation Zaproszenie RetroShare @@ -3279,12 +3521,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3332,7 +3574,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3388,12 +3660,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3431,7 +3703,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3489,12 +3761,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3569,7 +3841,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3991,7 +4268,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4139,7 +4416,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4154,7 +4431,7 @@ p, li { white-space: pre-wrap; } - + Search Szukaj @@ -4170,7 +4447,7 @@ p, li { white-space: pre-wrap; } Podpisane - + Edit Circle @@ -4186,12 +4463,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4213,7 +4490,7 @@ p, li { white-space: pre-wrap; } Utwórz - + Add Member @@ -4347,7 +4624,7 @@ p, li { white-space: pre-wrap; } - + Attachments ZaÅ‚Ä…czniki @@ -4393,7 +4670,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4403,7 +4680,7 @@ p, li { white-space: pre-wrap; } Wklej Link RetroShare - + Drop file error. @@ -4430,17 +4707,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4471,12 +4768,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4496,7 +4793,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4588,7 +4885,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -5011,7 +5308,7 @@ and use the import button to load it DHTGraphSource - + users @@ -6014,7 +6311,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Katalogi Przyjaciół @@ -6505,7 +6802,7 @@ at least one peer was not added to a group Szukaj Przyjaciół - + Mark all Zaznacz wszystkie @@ -6519,7 +6816,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6623,7 +6920,7 @@ at least one peer was not added to a group - + Network @@ -6688,7 +6985,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6719,7 +7016,7 @@ at least one peer was not added to a group - + Node name @@ -6978,12 +7275,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7346,7 +7643,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7411,7 +7708,7 @@ p, li { white-space: pre-wrap; } - + Details Szczegóły @@ -7434,7 +7731,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7635,7 +7932,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title TytuÅ‚ @@ -7645,13 +7942,30 @@ p, li { white-space: pre-wrap; } Szukaj TytuÅ‚ - - + + + + Description Opis - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Szukaj Opisu @@ -7661,42 +7975,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sortuj wedÅ‚ug Nazwy + Sortuj wedÅ‚ug Nazwy - Sort by Popularity - Sortuj wedÅ‚ug PopularnoÅ›ci + Sortuj wedÅ‚ug PopularnoÅ›ci - Sort by Last Post - Sortuj wedÅ‚ug Ostatniego Postu + Sortuj wedÅ‚ug Ostatniego Postu - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7711,40 +8002,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Ostatni Post - + + Name - - Unread - - - - + Popularity Popularność - - + + Never - Display - WyÅ›wietl + WyÅ›wietl - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7893,7 +8179,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels KanaÅ‚y @@ -7914,12 +8200,12 @@ p, li { white-space: pre-wrap; } Moje KanaÅ‚y - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Subskrybowane kanaÅ‚y @@ -8356,7 +8642,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8456,12 +8742,12 @@ p, li { white-space: pre-wrap; } - + Files Pliki - + Comments Komentarze @@ -8472,18 +8758,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8493,12 +8779,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8558,7 +8844,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8573,12 +8859,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8654,23 +8940,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Subskrybowane - - Subscribe Zapisz siÄ™ - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nie wybrano kanaÅ‚u @@ -8692,11 +8991,6 @@ p, li { white-space: pre-wrap; } Channel Post Wiadomość - - - new message(s) - - GxsCircleItem @@ -9200,7 +9494,7 @@ before you can comment Rozpocznij nowy WÄ…tek dla Wybranego Forum - + Search forums Przeszukaj fora @@ -9209,12 +9503,12 @@ before you can comment Ostatni Post - + New Thread Nowy WÄ…tek - + Threaded View Widok WÄ…tku @@ -9224,19 +9518,19 @@ before you can comment Widok PÅ‚aski - - + + Title TytuÅ‚ - - + + Date Data - + Author Autor @@ -9251,7 +9545,17 @@ before you can comment Wczytywanie - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9308,23 +9612,23 @@ before you can comment Szukaj ZawartoÅ›ci - + No name Bez nazwy - - + + Reply Odpowiedz - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9362,12 +9666,12 @@ before you can comment Oznacz jako nieprzeczytane - + Copy RetroShare Link Skopiuj Link RetroShare - + Hide Ukryj @@ -9376,7 +9680,7 @@ before you can comment RozwiÅ„ - + [unknown] @@ -9406,8 +9710,8 @@ before you can comment - - + + Distribution @@ -9506,12 +9810,12 @@ before you can comment Oryginalna Wiadomość - + New thread - + Edit Edytuj @@ -9567,7 +9871,7 @@ before you can comment - + Author's reputation @@ -9587,7 +9891,7 @@ before you can comment - + <b>Loading...<b> @@ -9627,6 +9931,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9694,7 +10003,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9726,11 +10035,6 @@ This message is missing. You should receive it later. Forum Post Wiadomość - - - new message(s) - - GxsForumsDialog @@ -10159,7 +10463,7 @@ This message is missing. You should receive it later. PodglÄ…d wydruku - + Unsubscribe Wypisz siÄ™ @@ -10174,7 +10478,7 @@ This message is missing. You should receive it later. Otwórz w nowej karcie - + Remove this search @@ -10184,12 +10488,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10256,12 +10560,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Skopiuj Link RetroShare @@ -10276,7 +10580,7 @@ This message is missing. You should receive it later. Oznacz wszystkie jako nieprzeczytane - + AUTHD @@ -10798,7 +11102,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10807,7 +11111,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10833,7 +11137,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10911,49 +11215,55 @@ p, li { white-space: pre-wrap; } Formularz - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -11001,17 +11311,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11026,7 +11331,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Zapisz jako... @@ -11291,14 +11601,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Wszyscy - + Reputation Reputacja @@ -11308,12 +11618,12 @@ p, li { white-space: pre-wrap; } Szukaj - + Anonymous Id - + Create new Identity Stwórz nowÄ… Tożsamość @@ -11457,7 +11767,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11529,7 +11839,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonim @@ -11544,24 +11854,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11576,7 +11886,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11635,13 +11945,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11701,7 +12016,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11749,7 +12064,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11758,12 +12073,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11775,12 +12090,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11896,17 +12211,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12063,8 +12378,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12075,7 +12390,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12085,7 +12400,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12145,7 +12460,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12155,7 +12470,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12193,7 +12508,7 @@ These identities will soon be not supported anymore. Pseudonim - + New identity @@ -12210,14 +12525,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -12228,24 +12543,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12265,12 +12583,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12280,7 +12623,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12290,7 +12633,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12330,12 +12678,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12345,7 +12688,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12450,8 +12793,12 @@ These identities will soon be not supported anymore. + Quote + Cytat + + Send - WyÅ›lij + WyÅ›lij @@ -12609,7 +12956,7 @@ These identities will soon be not supported anymore. - + Options Opcje @@ -12641,12 +12988,12 @@ These identities will soon be not supported anymore. Kreator szybkiego startu - + RetroShare %1 a secure decentralized communication platform RetroShare %1 bezpieczna, zdecentralizowana platforma komunikacji - + Unfinished NiedokoÅ„czone @@ -12775,7 +13122,7 @@ These identities will soon be not supported anymore. Pokaż - + Make sure this link has not been forged to drag you to a malicious website. @@ -12820,7 +13167,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12849,7 +13196,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12951,7 +13298,7 @@ These identities will soon be not supported anymore. - + Tags Tagi @@ -13046,12 +13393,12 @@ These identities will soon be not supported anymore. - + Send To: WyÅ›lij do: - + &Left &Lewo @@ -13081,7 +13428,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -13107,12 +13459,12 @@ These identities will soon be not supported anymore. - + Save Message Zapisz wiadomość - + Message has not been Sent. Do you want to save message to draft box? Wiadomość nie zostaÅ‚a wysÅ‚ana. @@ -13124,7 +13476,7 @@ Czy chcesz zapisać wiadomość do wersji roboczych? Wklej Link RetroShare - + Add to "To" Dodaj do "Do" @@ -13379,7 +13731,7 @@ Czy chcesz zapisać wiadomość ? Dodaj dodatkowy plik - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13393,6 +13745,21 @@ Czy chcesz zapisać wiadomość ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13405,7 +13772,7 @@ Czy chcesz zapisać wiadomość ? Od klatki: - + Bullet list (disc) @@ -13445,13 +13812,13 @@ Czy chcesz zapisać wiadomość ? - - + + Thanks, <br> - + Distant identity: @@ -13590,8 +13957,23 @@ Czy chcesz zapisać wiadomość ? Wiadomość - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13603,12 +13985,12 @@ Czy chcesz zapisać wiadomość ? Rekomendowane Pliki - + Download all Recommended Files Pobierz wszystkie Polecane Pliki - + Subject: Temat: @@ -13683,12 +14065,18 @@ Czy chcesz zapisać wiadomość ? - + + Message Size: + + + + File Name Nazwa pliku - + + Size Rozmiar @@ -13749,18 +14137,33 @@ Czy chcesz zapisać wiadomość ? Pobierz - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Pobierz wszystkie - + Print Document Drukuj Dokument @@ -13775,7 +14178,7 @@ Czy chcesz zapisać wiadomość ? Pliki HTML (*.htm *.html);;Wszystkie pliki (*) - + Load images always for this message @@ -13908,7 +14311,7 @@ Czy chcesz zapisać wiadomość ? MessagesDialog - + New Message Nowa Wiadmość @@ -13956,14 +14359,14 @@ Czy chcesz zapisać wiadomość ? - + Tags Tagi - + Inbox PrzychodzÄ…ce @@ -14058,7 +14461,7 @@ Czy chcesz zapisać wiadomość ? - + Subject TytuÅ‚ @@ -14138,7 +14541,7 @@ Czy chcesz zapisać wiadomość ? - + Open in a new window @@ -14223,7 +14626,7 @@ Czy chcesz zapisać wiadomość ? - + Drafts @@ -14320,7 +14723,7 @@ Czy chcesz zapisać wiadomość ? Odpowiedz WiadomoÅ›ciÄ… - + Delete Message @@ -14331,7 +14734,7 @@ Czy chcesz zapisać wiadomość ? - + Expand RozwiÅ„ @@ -14341,7 +14744,7 @@ Czy chcesz zapisać wiadomość ? UsuÅ„ element - + from od @@ -14350,6 +14753,11 @@ Czy chcesz zapisać wiadomość ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14649,7 +15057,7 @@ Reported error: - + Groups Grupy @@ -14679,19 +15087,19 @@ Reported error: - - + + Search Szukaj - + ID ID - + Search ID @@ -14701,7 +15109,7 @@ Reported error: - + Show Items @@ -14900,18 +15308,18 @@ at least one peer was not added to a group - + Error BÅ‚Ä…d - + File is not writeable! - + File is not readable! @@ -14949,7 +15357,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14967,7 +15375,7 @@ at least one peer was not added to a group To jest test. - + Newest on top @@ -14978,20 +15386,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15028,22 +15451,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon - + Message Wiadomość @@ -15064,12 +15487,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -15116,27 +15534,37 @@ at least one peer was not added to a group Rozmowy grupowe - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -15186,7 +15614,7 @@ at least one peer was not added to a group Powiadom - + Disable All Toasters @@ -15196,7 +15624,7 @@ at least one peer was not added to a group - + Systray @@ -15323,17 +15751,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -15388,22 +15811,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15417,7 +15835,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15427,22 +15845,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Podpisz klucz PGP + Podpisz klucz PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15462,7 +15874,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15528,27 +15940,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15560,7 +15972,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15605,27 +16017,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong - Być może hasÅ‚o jest bÅ‚Ä™dne + + Check the password! + - + Maybe password is wrong + Być może hasÅ‚o jest bÅ‚Ä™dne + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15796,8 +16228,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15814,7 +16245,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15957,7 +16388,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.ZdjÄ™cie - + TextLabel @@ -16001,8 +16432,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Komentarze @@ -16037,6 +16468,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Napisz komentarz... + + + Album + Album + PhotoItem @@ -16046,12 +16482,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formularz - + TextLabel - + <!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; } @@ -16143,7 +16579,7 @@ p, li { white-space: pre-wrap; } Pokaż ZdjÄ™cie - + PhotoShare @@ -16183,7 +16619,7 @@ requesting to edit it! - + Stop Stop @@ -16411,17 +16847,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins Wtyczki @@ -16767,7 +17203,7 @@ p, li { white-space: pre-wrap; } Inne Tematy - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16906,13 +17342,13 @@ p, li { white-space: pre-wrap; } Strona - - + + Comments Komentarze - + Copy RetroShare Link @@ -16922,7 +17358,7 @@ p, li { white-space: pre-wrap; } - + Comment Skomentuj @@ -16943,12 +17379,12 @@ p, li { white-space: pre-wrap; } - + Hide Ukryj - + Vote up @@ -16962,7 +17398,7 @@ p, li { white-space: pre-wrap; } \/ - + Set as read and remove item @@ -17023,7 +17459,7 @@ p, li { white-space: pre-wrap; } - + Loading Wczytywanie @@ -17077,13 +17513,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17093,60 +17523,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown nieznane - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17157,7 +17577,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17226,7 +17646,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -17261,7 +17686,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17377,8 +17802,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17645,11 +18080,6 @@ and use the import button to load it PulseAddDialog - - - Post From: - - Account 1 Konto 1 @@ -17663,7 +18093,7 @@ and use the import button to load it Konto 3 - + Add to Pulse @@ -17682,17 +18112,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Od klatki: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17717,10 +18162,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17730,13 +18185,48 @@ and use the import button to load it - + + Post + + + + Cancel Anuluj - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17763,10 +18253,18 @@ and use the import button to load it Formularz - - - - + + + + + Click to view picture + + + + + + + Image Obraz @@ -17774,44 +18272,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17821,17 +18319,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17841,7 +18339,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17849,7 +18347,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17864,7 +18362,7 @@ and use the import button to load it - + follow Parent Group @@ -17874,7 +18372,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17899,7 +18397,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17935,29 +18433,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18035,7 +18533,7 @@ and use the import button to load it QObject - + Confirmation @@ -18275,7 +18773,7 @@ Symbole <b>",|,/,\,&lt;,&gt;,*,?</b> zostanÄ… zastÄ…pio - + Unable to make path @@ -18310,7 +18808,7 @@ Symbole <b>",|,/,\,&lt;,&gt;,*,?</b> zostanÄ… zastÄ…pio - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18448,7 +18946,7 @@ Reported error is: sekund - + TR up @@ -18493,7 +18991,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18509,7 +19007,7 @@ Reported error is: - + %1 seconds ago @@ -18593,7 +19091,7 @@ Security: no anonymous IDs - + Error BÅ‚Ä…d @@ -18983,11 +19481,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19326,7 +19819,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -19548,18 +20041,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19996,7 +20510,7 @@ p, li { white-space: pre-wrap; } - + File Plik @@ -20011,7 +20525,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned @@ -20061,7 +20575,7 @@ Pliki których to dotyczy sÄ… oznaczone na czerwono. Zapisz - + Collection Editor @@ -20076,7 +20590,7 @@ Pliki których to dotyczy sÄ… oznaczone na czerwono. - + Real Size: Waiting child... @@ -20091,12 +20605,12 @@ Pliki których to dotyczy sÄ… oznaczone na czerwono. - + Download files - + Specify... @@ -20343,7 +20857,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -20363,7 +20877,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20376,10 +20890,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title TytuÅ‚ + + + UnRead + + Date @@ -20391,7 +20910,7 @@ If you believe it is correct, remove the corresponding line from the file and re Autor - + Information for this identity is currently missing. @@ -20429,7 +20948,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... BrakujÄ…ca Wiadomość ... ] @@ -20437,7 +20956,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -20497,7 +21016,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20851,7 +21370,7 @@ prevents the message to be forwarded to your friends. Nazwa pliku - + Download Pobierz @@ -20930,7 +21449,7 @@ prevents the message to be forwarded to your friends. Otwórz folder - + Create Collection... @@ -20950,7 +21469,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -21055,12 +21574,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat Chat @@ -21070,7 +21589,7 @@ prevents the message to be forwarded to your friends. Rozpocznij rozmowÄ™ - + Expand RozwiÅ„ @@ -21333,13 +21852,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21805,7 +22324,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21833,7 +22352,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Stan @@ -21930,7 +22449,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21965,12 +22484,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22635,7 +23154,7 @@ p, li { white-space: pre-wrap; } BrakujÄ…cy Certyfikat PGP - + Wrong password @@ -22677,7 +23196,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Dodaj Przyjaciela @@ -22733,7 +23252,7 @@ This choice can be reverted in settings. - + DHT @@ -23269,7 +23788,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23279,13 +23798,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23294,6 +23812,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23567,35 +24110,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Masz %1 zakoÅ„czonych pobieraÅ„ + You have %1 completed transfers + - You have %1 completed download - Masz %1 zakoÅ„czone pobieranie + You have %1 completed transfer + - %1 completed downloads - %1 zakoÅ„czonych pobieraÅ„ + %1 completed transfers + - %1 completed download - %1 zakoÅ„czone pobieranie + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Masz %1 zakoÅ„czonych pobieraÅ„ + + + You have %1 completed download + Masz %1 zakoÅ„czone pobieranie + + + %1 completed downloads + %1 zakoÅ„czonych pobieraÅ„ + + + %1 completed download + %1 zakoÅ„czone pobieranie TransfersDialog - + Downloads Pobierania @@ -23606,7 +24160,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Nazwa @@ -23813,7 +24367,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23907,7 +24461,7 @@ p, li { white-space: pre-wrap; } - + Expand all RozwiÅ„ wszystkie @@ -24039,7 +24593,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolumny @@ -24050,7 +24604,7 @@ p, li { white-space: pre-wrap; } Transfery plików - + Path Åšcieżka @@ -24060,7 +24614,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24070,7 +24624,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -24085,7 +24639,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24327,7 +24881,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24423,7 +24977,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Masz %1 nowych wiadomoÅ›ci @@ -24795,7 +25349,7 @@ p, li { white-space: pre-wrap; } Stwórz GrupÄ™ - + Subscribe to Group @@ -24889,8 +25443,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Pokaż HistoriÄ™ Edycji @@ -24901,7 +25455,7 @@ p, li { white-space: pre-wrap; } - + Preview PodglÄ…d @@ -24926,12 +25480,12 @@ p, li { white-space: pre-wrap; } Ukryj HistoriÄ™ Edycji - + Edit Page Edytuj StronÄ™ - + Create New Wiki Page Utwórz NowÄ… StronÄ™ Wiki @@ -24951,7 +25505,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Utwórz NowÄ… GrupÄ™ Wiki @@ -24989,7 +25543,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24999,12 +25553,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh OdÅ›wież @@ -25039,12 +25592,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25098,7 +25651,7 @@ p, li { white-space: pre-wrap; } ZarzÄ…dzaj Kontami - + Yourself @@ -25124,7 +25677,7 @@ p, li { white-space: pre-wrap; } Konto 3 - + RetroShare RetroShare @@ -25136,7 +25689,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -25144,7 +25697,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25225,8 +25778,8 @@ p, li { white-space: pre-wrap; } Formularz - - + + Avatar Awatar @@ -25255,6 +25808,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25367,7 +25925,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_pt.ts b/retroshare-gui/src/lang/retroshare_pt.ts index 79a297a23..4835855cf 100644 --- a/retroshare-gui/src/lang/retroshare_pt.ts +++ b/retroshare-gui/src/lang/retroshare_pt.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Opções + TextLabel + + + + Reset Repor - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Omissão + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Nome: - + Location: - + Options Opções - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options Opções @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. Mostrar - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? De: - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13459,7 +13798,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13475,14 +13814,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13553,7 +13892,7 @@ Do you want to save message ? - + Subject @@ -13633,7 +13972,7 @@ Do you want to save message ? - + Open in a new window @@ -13718,7 +14057,7 @@ Do you want to save message ? - + Drafts @@ -13807,7 +14146,7 @@ Do you want to save message ? - + Delete Message @@ -13818,7 +14157,7 @@ Do you want to save message ? - + Expand @@ -13828,7 +14167,7 @@ Do you want to save message ? - + from @@ -13837,6 +14176,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14136,7 +14480,7 @@ Reported error: - + Groups @@ -14166,19 +14510,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14188,7 +14532,7 @@ Reported error: - + Show Items @@ -14387,18 +14731,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14436,7 +14780,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14450,7 +14794,7 @@ at least one peer was not added to a group - + Newest on top @@ -14461,20 +14805,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14507,22 +14866,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14543,12 +14902,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14595,27 +14949,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14665,7 +15029,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14675,7 +15039,7 @@ at least one peer was not added to a group - + Systray @@ -14802,17 +15166,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14867,22 +15226,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14896,7 +15250,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14906,22 +15260,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14941,7 +15285,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15007,27 +15351,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15039,7 +15383,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15084,27 +15428,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15275,8 +15635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15293,7 +15652,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15425,7 +15784,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15461,7 +15820,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15489,6 +15848,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15498,12 +15862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15583,7 +15947,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15623,7 +15987,7 @@ requesting to edit it! - + Stop @@ -15847,17 +16211,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16183,7 +16547,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16314,13 +16678,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16330,7 +16694,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16351,12 +16715,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16366,7 +16730,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16427,7 +16791,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16450,13 +16814,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16466,60 +16824,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16530,7 +16878,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16599,7 +16947,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16634,7 +16987,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16750,8 +17103,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17019,12 +17382,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17039,17 +17397,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17074,10 +17447,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17087,13 +17470,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17105,10 +17523,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17116,44 +17542,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17163,17 +17589,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17191,7 +17617,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17206,7 +17632,7 @@ and use the import button to load it - + follow Parent Group @@ -17216,7 +17642,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17241,7 +17667,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17277,29 +17703,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17377,7 +17803,7 @@ and use the import button to load it QObject - + Confirmation @@ -17616,7 +18042,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17651,7 +18077,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17789,7 +18215,7 @@ Reported error is: - + TR up @@ -17834,7 +18260,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17850,7 +18276,7 @@ Reported error is: - + %1 seconds ago @@ -17934,7 +18360,7 @@ Security: no anonymous IDs - + Error @@ -18324,11 +18750,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18662,7 +19083,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18884,18 +19305,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19332,7 +19774,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19347,7 +19789,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19395,7 +19837,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19410,7 +19852,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19425,12 +19867,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19677,7 +20119,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19697,7 +20139,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19710,10 +20152,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19725,7 +20172,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19763,7 +20210,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19771,7 +20218,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19831,7 +20278,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20185,7 +20632,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20264,7 +20711,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20284,7 +20731,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20389,12 +20836,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20404,7 +20851,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20667,13 +21114,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21139,7 +21586,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21167,7 +21614,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21264,7 +21711,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21299,12 +21746,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21969,7 +22416,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22011,7 +22458,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22067,7 +22514,7 @@ This choice can be reverted in settings. - + DHT @@ -22599,7 +23046,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22609,13 +23056,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22624,6 +23070,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22897,27 +23368,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22925,7 +23391,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22936,7 +23402,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23143,7 +23609,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23237,7 +23703,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23369,7 +23835,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23380,7 +23846,7 @@ p, li { white-space: pre-wrap; } - + Path Caminho @@ -23390,7 +23856,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23400,7 +23866,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23415,7 +23881,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23657,7 +24123,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23753,7 +24219,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24121,7 +24587,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24215,8 +24681,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24227,7 +24693,7 @@ p, li { white-space: pre-wrap; } - + Preview Antevisão @@ -24252,12 +24718,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24277,7 +24743,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24315,7 +24781,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24325,12 +24791,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24365,12 +24826,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24400,7 +24861,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24410,7 +24871,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24422,7 +24883,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24430,7 +24891,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24511,8 +24972,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24541,6 +25002,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24653,7 +25119,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ru.ts b/retroshare-gui/src/lang/retroshare_ru.ts index 4a6dff8e4..cfe0de745 100644 --- a/retroshare-gui/src/lang/retroshare_ru.ts +++ b/retroshare-gui/src/lang/retroshare_ru.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version ВерÑÐ¸Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ñ‹ @@ -79,7 +79,7 @@ РазвлекайтеÑÑŒ ;-) - + Only Hidden Node Только Ñкрытый узел Ñети @@ -129,12 +129,12 @@ RetroShare: раÑширенный поиÑк - + Search Criteria Критерии поиÑка - + Add a further search criterion. Добавить дополнительный критерий поиÑка. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Ðльбом @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Форма - - + + TextLabel ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Панель инÑтрументов - + Icon Only Только значки @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Выберите Ñтиль кнопки инÑтрументов. - + Icon Size = 8x8 Размер значка = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Размер значка = 128x128 - + Status Bar Строка ÑоÑтоÑÐ½Ð¸Ñ @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Отключить подÑказки в ÑиÑтемном трее - + Main page items: Элементы интерфейÑа главного окна @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Выпадающие ÑпиÑки - + Icon Size = 32x32 Размер значка = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Изменить аватар - + + TextLabel + ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + + + Your Avatar Picture Ваш аватар - + + Browse... + + + Add Avatar - Добавить аватар + Добавить аватар @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Удалить Ñту позицию - + Set your Avatar picture УÑтановить ваш аватар - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Загрузить аватар + Загрузить аватар AvatarWidget - - Choose avatar - - - - + Click to change your avatar Ðажать Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð° @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s кБ/Ñ @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage ЗагруженноÑÑ‚ÑŒ канала передачи данных + + + PushButton + + - + Up + Отдача + + + + Down + Скачивание + + + + Clears the graph + + + + Show Settings Показать наÑтройки + TextLabel + ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + + + Reset Ð¡Ð±Ñ€Ð¾Ñ - Receive Rate - СкороÑÑ‚ÑŒ приёма + СкороÑÑ‚ÑŒ приёма - Send Rate - СкороÑÑ‚ÑŒ отдачи + СкороÑÑ‚ÑŒ отдачи - + Always on Top Поверх вÑех окон - Style - Стиль + Стиль - + Changes the transparency of the Bandwidth Graph Изменить прозрачноÑÑ‚ÑŒ графика пропуÑкной ÑпоÑобноÑти - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % непрозрачноÑти - Save - Сохранить + Сохранить - Cancel - Отмена + Отмена - + Since: С: - Hide Settings - Скрыть наÑтройки + Скрыть наÑтройки BandwidthStatsWidget - + Sum Суммарно @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } ПодÑчёт - + Average Среднее @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° - + Comments Комментарии @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° + + BoardsCommentsItem + + + I like this + Мне нравитÑÑ + + + + 0 + 0 + + + + I dislike this + Мне не понравилоÑÑŒ + + + + Toggle Message Read Status + Изменить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ð¾Ð³Ð¾ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ + + + + Avatar + Ðватар + + + + New Comment + + + + + Copy RetroShare Link + Скопировать ÑÑылку RetroShare + + + + + Expand + + + + + Set as read and remove item + УÑтановить как чтение и удаление Ñлемента + + + + Remove Item + Удалить объект + + + + Name + Ð˜Ð¼Ñ + + + + Comm value + + + + + Comment + Комментарий + + + + Comments + Комментарии + + + + Hide + + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale ЛогарифмичеÑÐºÐ°Ñ ÑˆÐºÐ°Ð»Ð° + + + Default + По умолчанию + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Мне нравитÑÑ + + + + 0 + 0 + + + + I dislike this + Мне не понравилоÑÑŒ + + + + Toggle Message Read Status + Изменить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ð¾Ð³Ð¾ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ + + + + Avatar + Ðватар + + + + New Comment + + + + + Copy RetroShare Link + Скопировать ÑÑылку RetroShare + + + + + Expand + + + + + Set as read and remove item + УÑтановить как чтение и удаление Ñлемента + + + + Remove Item + Удалить объект + + + + Name + Ð˜Ð¼Ñ + + + + Comm value + + + + + Comment + Комментарий + + + + Comments + Комментарии + + + + Hide + + + ChatLobbyDialog @@ -1592,24 +1796,40 @@ into the image, so as to Чаты - You have %1 new messages - У Ð²Ð°Ñ %1 новых Ñообщений + У Ð²Ð°Ñ %1 новых Ñообщений + + + You have %1 new message + У Ð²Ð°Ñ %1 новых Ñообщений + + + %1 new messages + %1 новых Ñообщений + + + %1 new message + %1 новое Ñообщение + + + + You have %1 mentions + - You have %1 new message - У Ð²Ð°Ñ %1 новых Ñообщений + You have %1 mention + - %1 new messages - %1 новых Ñообщений + %1 mentions + - %1 new message - %1 новое Ñообщение + %1 mention + @@ -1622,11 +1842,6 @@ into the image, so as to Remove All Удалить вÑÑ‘ - - - mention(s) - - ChatLobbyWidget @@ -2121,13 +2336,11 @@ Double click a chat room to enter and chat. Вариант: - Group chat - Групповой чат + Групповой чат - - + Private chat Приватный чат @@ -2192,17 +2405,16 @@ Double click a chat room to enter and chat. /me отправлÑет Ñообщение Ñ /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Ð’ Ñтой вкладке вы можете задать, какое количеÑтво Ñообщений чата RetroShare будет хранить на диÑке, а также объём Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÑоÑтоÑвшихÑÑ Ð±ÐµÑед Ð´Ð»Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð½Ñ‹Ñ… ÑиÑтем чатов. МакÑимальный период Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет очищать иÑторию чатов и предотвращает её заполнение временными чатами (например, обычные чаты или удалённые чаты).</p></body></html> - Chatlobbies - Комнаты чата + Комнаты чата - + Enabled: Включено: @@ -2223,11 +2435,12 @@ Double click a chat room to enter and chat. + Chat rooms Чат-комнаты - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Отметьте, еÑли Ð´Ð»Ñ Ð¿Ð¾Ð´Ñчёта должны одновременно приÑутÑтвовать и личноÑÑ‚ÑŒ, и текÑÑ‚ выше. @@ -2288,11 +2501,17 @@ Double click a chat room to enter and chat. + Broadcast Широковещательный чат - + + Node-to-node chat + + + + Saved messages (0 = unlimited): СохранÑемые ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (0 = не ограничено): @@ -2439,8 +2658,23 @@ Double click a chat room to enter and chat. Приватный чат - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2613,7 +2847,7 @@ Double click a chat room to enter and chat. - + is typing... печатает... @@ -2632,12 +2866,12 @@ after HTML conversion. %1 Ñимволов поÑле ÐºÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² HTML. - + Choose your font. Выберите шрифт. - + Do you really want to physically delete the history? Ð’Ñ‹ дейÑтвительно хотите удалить Ñ Ð´Ð¸Ñка иÑторию Ñообщений? @@ -2709,7 +2943,7 @@ after HTML conversion. Продолжить выделÑÑ‚ÑŒ цветом поÑле X найденных вхождений (требуетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµ реÑурÑов процеÑÑора) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Ðайти предыдущее </b><br/><i>Ctrl+Shift+G</i> @@ -2749,12 +2983,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Отметить Ñтот выделенный текÑÑ‚</b><br><i>Ctrl + M</i> - + Person id: Идентификатор личноÑти: @@ -2770,7 +3004,7 @@ Double click on it to add his name on text writer. Ðе подпиÑано - + items found. удовлетворÑÑŽÑ‚ уÑловию. @@ -2790,7 +3024,7 @@ Double click on it to add his name on text writer. Печатайте ваши ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð´ÐµÑÑŒ - + Don't stop to color after Продолжить выделÑÑ‚ÑŒ цветом поÑле @@ -2948,12 +3182,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details ПодробноÑти - + Local Address Локальный Ð°Ð´Ñ€ÐµÑ @@ -2964,12 +3198,12 @@ Double click on it to add his name on text writer. Внешний Ð°Ð´Ñ€ÐµÑ - + Node info: Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± узле: - + Current address: Текущий адреÑ: @@ -2985,31 +3219,36 @@ Double click on it to add his name on text writer. Порт - + Include signatures Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи - + RetroShare RetroShare - + - + Error : cannot get peer details. Ошибка: не могу получить ÑовокупноÑÑ‚ÑŒ деталей. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Шифрование - + Not connected не Ñоединён - + Retroshare node details Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± узле Retroshare - + Node name : Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð°: @@ -3075,13 +3319,18 @@ Double click on it to add his name on text writer. Сообщение о личном ÑтатуÑе: - + + Connectivity + + + + List of known addresses: СпиÑок извеÑтных адреÑов: - - + + Retroshare Certificate Сертификат Retroshare @@ -3096,7 +3345,7 @@ Double click on it to add his name on text writer. - + Hidden Address Скрытый Ð°Ð´Ñ€ÐµÑ @@ -3107,11 +3356,12 @@ Double click on it to add his name on text writer. нет + <p>This certificate contains: - <p>Этот Ñертификат Ñодержит: + <p>Этот Ñертификат Ñодержит: - + <li>a <b>node ID</b> and <b>name</b> <li><b>идентификатор узла</b> и <b>имÑ</b> @@ -3124,12 +3374,12 @@ Double click on it to add his name on text writer. <b>IP-адреÑ</b> и <b>порт</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Ð’Ñ‹ можете иÑпользовать Ñтот Ñертификат, чтобы пополнить ÑпиÑок ваших контактов. Отправьте его потенциальному учаÑтнику по Ñлектронной почте или передайте лично в руки.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/> <body><p>Это идентификатор узла <span style="font-weight:600;"> OpenSSL</span> Ñертификат, которого подпиÑан <span style="font-weight:600;"> PGP</span> ключём выше.</p></body></html> @@ -3139,7 +3389,7 @@ Double click on it to add his name on text writer. <html><head/> <body><p>Это метод шифрованиÑ, иÑпользуемый <span style="font-weight:600;"> OpenSSL</span>. Подключение к доверенному узлу</p> <p>вÑегда шифруетÑÑ Ñтойким алгоритмом и еÑли DHE приÑутÑтвует, дальнейшее Ñоединение иÑпользует метод</p> <p>«Ñовершенной ÑекретноÑти Ñ ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸ÐµÐ¼Â».</p></body></html> - + with Ñ @@ -3345,12 +3595,12 @@ Double click on it to add his name on text writer. ПодробноÑти запроÑа - + Peer details Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± учаÑтнике - + Name: ИмÑ: @@ -3368,12 +3618,12 @@ resources. Обратите внимание на тот факт, что вы можете добавлÑÑ‚ÑŒ в ваше окружение Ñтолько контактов, Ñколько пожелаете. Ðо их количеÑтво более 40, вероÑтно, приведёт к заметной загрузке CPU, памÑти и пропуÑкной ÑпоÑобноÑти вашего интернет-канала. - + Location: РаÑположение: - + Options Параметры @@ -3410,12 +3660,12 @@ resources. Ð’Ñтавить Ñертификат - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Сюда Ñледует вводить Ñертификаты потенциальных контактов. Ð’ÐИМÐÐИЕ: Ñертификаты — Ñто не проÑто пбличные PGP-ключи, Ñто более ÑÐ»Ð¾Ð¶Ð½Ð°Ñ Ñтруктура данных. Ðе вÑтавлÑйте Ñюда PGP-ключи Ñвоих потенциальных контактов (ни полноÑтью, ни чаÑтично) – Ñто не Ñработает. Сертификат должен вводитьÑÑ Ð¿Ð¾Ð»Ð½Ð¾Ñтью!</p></body></html> - + Add friend to group: Добавить Ñтот узел в группу: @@ -3425,7 +3675,7 @@ resources. ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð³Ð¾ узла (подпиÑать его PGP-ключ) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with Добавить Ñертификат учаÑтника Ð´Ð»Ñ Ð¿Ð¾Ñледующего ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð½Ð¸Ð¼ @@ -3459,7 +3709,7 @@ resources. Чтобы принÑÑ‚ÑŒ Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° предложение обменÑÑ‚ÑŒÑÑ Ñертификатами, нажмите кнопку «Завершить». - + Sorry, some error appeared К Ñожалению, поÑвилиÑÑŒ некоторые ошибки @@ -3479,32 +3729,32 @@ resources. ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± узле: - + Key validity: Уровень Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ðº ключу: - + Profile ID: - + Signers ПодпиÑавшие - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">ПодпиÑание публичного ключа учаÑтника Ñети – Ñто ÑпоÑоб обозначить Ñвоё доверие тому или иному учаÑтнику. Сигнатуры, которые вы видите ниже, подтверждают, что ключи в ÑпиÑке заверены и признаютÑÑ ÐºÐ°Ðº подлинные.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Этот учаÑтник уже находитÑÑ Ð² вашем доверенном окружении. Добавление Ñертификата Ñнова лишь уÑтановит актуальный IP-Ð°Ð´Ñ€ÐµÑ Ñтого узла. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Ошибка загрузки Ñертификата @@ -3587,12 +3837,12 @@ resources. Сертификат в порÑдке - + Not a valid Retroshare certificate! ÐедейÑтвительный Ñертификат RetroShare! - + RetroShare Invitation Приглашение в RetroShare @@ -3612,12 +3862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Это же ваш ÑобÑтвенный Ñертификат! Ð’Ñ‹ не хотели бы ÑоединитьÑÑ Ñ Ñамим Ñобой, не так ли? - + @@ -3665,7 +3915,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.У Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° Ñоединение от - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3753,12 +4033,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.ИÑпользовать как прÑмой иÑточник, при возможноÑти - + IP-Addr: IP-адреÑ: - + IP-Address IP-адреÑ: @@ -3824,7 +4104,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Добавить ключ в ÑвÑзку ключей - + This key is already in your keyring Это ключ уже в вашей ÑвÑзке @@ -3885,12 +4165,12 @@ even if you don't make friends. Этот Ñертификат не Ñодержит в Ñебе IP-адреÑа. Ð’ данном Ñлучае Ð´Ð»Ñ ÑƒÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÑƒÐ·Ð»Ð¾Ð¼ ваш клиент задейÑтвует ÑÐµÑ€Ð²Ð¸Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð¸ раÑпределённую таблицу хешей DHT. ПоÑкольку вам требуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ белого ÑпиÑка, подключение к учаÑтнику вызовет предупреждение ÑиÑтемы безопаÑноÑти во вкладке новоÑтей. Оттуда вы можете добавить его IP-Ð°Ð´Ñ€ÐµÑ Ð² белый ÑпиÑок. - + [Unknown] - + Added with certificate from %1 Добавлено Ñ Ñертификатом от %1 @@ -3977,7 +4257,12 @@ even if you don't make friends. Результат UDP - + + Status + Ð¡Ñ‚Ð°Ñ‚ÑƒÑ + + + <!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; } @@ -4407,7 +4692,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4559,7 +4844,7 @@ p, li { white-space: pre-wrap; } Ðе выбраны Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÐºÑ€ÑƒÐ³Ð° - + [Unknown] @@ -4574,7 +4859,7 @@ p, li { white-space: pre-wrap; } Удалить - + Search ПоиÑк @@ -4594,7 +4879,7 @@ p, li { white-space: pre-wrap; } ПодпиÑано извеÑтными узлами - + Edit Circle Редактировать круг @@ -4614,12 +4899,12 @@ p, li { white-space: pre-wrap; } Ðнонимный идентификатор - + Circle name Ðазвание круга - + Update Обновить @@ -4645,7 +4930,7 @@ p, li { white-space: pre-wrap; } Идентификатор, привÑзанный к PGP-ключу - + Add Member Добавить члена @@ -4789,7 +5074,7 @@ p, li { white-space: pre-wrap; } - + Attachments Ð’Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ @@ -4835,7 +5120,7 @@ p, li { white-space: pre-wrap; } Перетащить файлы из результатов поиÑка - + Paste RetroShare Links Ð’Ñтавить RetroShare-ÑÑылки @@ -4845,7 +5130,7 @@ p, li { white-space: pre-wrap; } Ð’Ñтавить ÑÑылку RetroShare - + Drop file error. Ошибка Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°. @@ -4872,17 +5157,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Файл уже добавлен и хеширован + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Файл уже добавлен и хеширован + + + Please add a Subject Добавьте тему ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ @@ -4913,12 +5222,12 @@ p, li { white-space: pre-wrap; } Ð’Ñ‹ дейÑтвительно хотите Ñоздать %1 Ñообщений? - + You are about to add files you're not actually sharing. Do you still want this to happen? Ð’Ñ‹ хотите добавить файлы которые не ещё не общедоÑтупны. Продолжить в любом Ñлучае? - + Edit Channel Post Редактировать Ñообщение канала @@ -4938,7 +5247,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. О том, как размещать не Ñвои файлы в канале. @@ -5030,7 +5339,7 @@ p, li { white-space: pre-wrap; } - + No Forum Ðет форума @@ -5490,7 +5799,7 @@ and use the import button to load it DHTGraphSource - + users пользователи @@ -6497,7 +6806,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Папки доверенных учаÑтников @@ -7003,7 +7312,7 @@ at least one peer was not added to a group ПоиÑк контактов - + Mark all Отметить вÑе @@ -7017,7 +7326,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Изменить ваш ÑÑ‚Ð°Ñ‚ÑƒÑ @@ -7121,7 +7430,7 @@ at least one peer was not added to a group Широковещательный чат RetroShare: ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ раÑÑылатьÑÑ Ð²Ñем подключённым узлам. - + Network Сеть @@ -7186,7 +7495,7 @@ at least one peer was not added to a group Поле Ð´Ð»Ñ Ð¼ÐµÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть длиной минимум 3 Ñимвола - + Failed to generate your new certificate, maybe PGP password is wrong! Ðе удалоÑÑŒ Ñоздать ваш новый Ñертификат. Может быть, введён неправильный пароль PGP! @@ -7229,7 +7538,7 @@ at least one peer was not added to a group ИÑпользовать ÑущеÑтвующий профиль - + Node name Ðазвание узла @@ -7496,12 +7805,12 @@ and use the import button to load it - + Profile generation failure Ошибка при Ñоздании Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ - + Missing PGP certificate ОтÑутÑтвует Ñертификат PGP @@ -7920,7 +8229,7 @@ p, li { white-space: pre-wrap; } СтатиÑтика роутера - + GroupBox Группы @@ -7985,7 +8294,7 @@ p, li { white-space: pre-wrap; } КоличеÑтво ветвей - + Details ПодробноÑти @@ -8008,7 +8317,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys УправлÑемые ключи @@ -8217,7 +8526,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Ðазвание @@ -8227,13 +8536,30 @@ p, li { white-space: pre-wrap; } ПоиÑк по названию - - + + + + Description ОпиÑание - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description ПоиÑк по опиÑанию @@ -8243,42 +8569,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Сортировать по убыванию + Сортировать по убыванию - Sort Ascending Order - Сортировать по возраÑтанию + Сортировать по возраÑтанию - Sort by Name - Сортировать по имени + Сортировать по имени - Sort by Popularity - Сортировать по популÑрноÑти + Сортировать по популÑрноÑти - Sort by Last Post - Сортировать по поÑледнему Ñообщению + Сортировать по поÑледнему Ñообщению - Sort by Number of Posts - Сортировать по количеÑтву Ñообщений + Сортировать по количеÑтву Ñообщений - Sort by Unread - Сортировать по количеÑтву непрочтённых Ñообщений + Сортировать по количеÑтву непрочтённых Ñообщений - + You are admin (modify names and description using Edit menu) Ð’Ñ‹ админиÑтратор (изменÑйте название и опиÑание иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼ÐµÐ½ÑŽ "Редактировать") @@ -8293,40 +8612,35 @@ p, li { white-space: pre-wrap; } Идентификатор - - + + Last Post ПоÑледнее непрочтённое - + + Name Ð˜Ð¼Ñ - - Unread - - - - + Popularity ПопулÑрноÑÑ‚ÑŒ - - + + Never Ðикогда - Display - Показать + Показать - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8475,7 +8789,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Каналы @@ -8500,12 +8814,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Каналы</h1> <p>Каналы дают возможноÑÑ‚ÑŒ публиковать контент (например, кино или музыку), который подлежит раздаче пользователÑм Ñети.</p> <p>Ð’ ÑпиÑке каналов ÑодержатÑÑ Ñ‚Ðµ каналы, на которые подпиÑано ваше доверенное окружение, равно как и ваш узел автоматичеÑки отÑылает окружению информацию о каналах, на которые подпиÑаны вы. Такой механизм позволÑет раÑпроÑтранÑÑ‚ÑŒ по Ñети информацию о хороших каналах и блокировать неудачные.</p> <p>ОÑтавлÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² канале может только его Ñоздатель. ОÑтальные учаÑтники могут лишь читать его Ñодержимое и только в том Ñлучае, еÑли канал не ÑвлÑетÑÑ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ñ‹Ð¼. Тем не менее, вы можете ⇥ дать права на чтение или модификацию канала пользователÑм из доверенного окружениÑ.</p>⇥ <p>Канал может быть анонимным или пÑевдонимным, еÑли за ним закреплён определённый идентификатор пользователÑ. ⇥ Включите режим «Разрешить комментарии», еÑли Ð’Ñ‹ хотите дать пользователÑм возможноÑÑ‚ÑŒ комментировать ÑообщениÑ.</p> <p>Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð° удалÑÑŽÑ‚ÑÑ Ñ‡ÐµÑ€ÐµÐ· %1 меÑÑца.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels ПодпиÑка на каналы @@ -9030,7 +9344,7 @@ p, li { white-space: pre-wrap; } - + Add new post Добавить новое Ñообщение @@ -9130,12 +9444,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Комментарии @@ -9146,18 +9460,18 @@ p, li { white-space: pre-wrap; } - + Feeds Каналы - - + + Click to switch to list view - + Show unread posts only @@ -9167,12 +9481,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9232,7 +9546,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9247,12 +9561,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9328,23 +9642,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe ПодпиÑатьÑÑ - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Ðе выбраны каналы @@ -9366,11 +9693,6 @@ p, li { white-space: pre-wrap; } Channel Post Сообщение канала - - - new message(s) - - GxsCircleItem @@ -9904,7 +10226,7 @@ before you can comment Ðачать новую тему в выбранном форуме - + Search forums ПоиÑк по форумам @@ -9913,12 +10235,12 @@ before you can comment ПоÑледнее Ñообщение - + New Thread ÐÐ¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð° - + Threaded View Древовидный вид @@ -9928,19 +10250,19 @@ before you can comment ПлоÑкий вид - - + + Title Ðазвание - - + + Date Дата - + Author Ðвтор @@ -9955,7 +10277,17 @@ before you can comment Загрузка - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10016,23 +10348,23 @@ before you can comment <p>ПодпиÑка на форум означает, что ваш клиент будет Ñобирать Ñреди доверенного Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð²Ñе имеющиеÑÑ ÑообщениÑ, а также, в Ñвою очередь, делать форумный котент видимым Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтников из вашего окружениÑ.</p> <p>ВпоÑледÑтвии, при желании, вы Ñможете отпиÑатьÑÑ Ð¾Ñ‚ форума, воÑпользовавшиÑÑŒ контекÑтным меню.</p> - + No name Без Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ - - + + Reply Ответ - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10070,12 +10402,12 @@ before you can comment Отметить как непрочитанное - + Copy RetroShare Link Скопировать ÑÑылку RetroShare - + Hide Скрыть @@ -10088,7 +10420,7 @@ before you can comment [Заблокировано] - + [unknown] [неизвеÑтно] @@ -10118,8 +10450,8 @@ before you can comment Только Ð´Ð»Ñ Ð²Ð°Ñ - - + + Distribution РаÑпроÑтранение @@ -10222,7 +10554,7 @@ before you can comment Оригинал ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ - + New thread ÐÐ¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð° @@ -10231,7 +10563,7 @@ before you can comment Указывать ÑоÑтоÑние прочитано / не прочитано - + Edit Изменить @@ -10287,7 +10619,7 @@ before you can comment Показать Ñтот идентификатор на вкладке "УчаÑтники" - + Author's reputation Ð ÐµÐ¿ÑƒÑ‚Ð°Ñ†Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° @@ -10307,7 +10639,7 @@ before you can comment - + <b>Loading...<b> @@ -10347,6 +10679,11 @@ before you can comment Storage Хранение Ñообщений + + + Last seen at friends: + + Moderators @@ -10439,7 +10776,7 @@ prevents the message to be forwarded to your friends. %1 %2 напиÑал(а): - + Forum name Ðазвание форума @@ -10471,11 +10808,6 @@ prevents the message to be forwarded to your friends. Forum Post Сообщение форума - - - new message(s) - - GxsForumsDialog @@ -10924,7 +11256,7 @@ prevents the message to be forwarded to your friends. Предварительный проÑмотр - + Unsubscribe Отменить подпиÑку @@ -10939,7 +11271,7 @@ prevents the message to be forwarded to your friends. Открыть в новой вкладке - + Remove this search @@ -10949,12 +11281,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details Показать подробноÑти @@ -11021,7 +11353,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -11030,7 +11362,7 @@ prevents the message to be forwarded to your friends. ПоделитьÑÑ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ на запиÑÑŒ - + Copy RetroShare Link Скопировать ÑÑылку RetroShare @@ -11045,7 +11377,7 @@ prevents the message to be forwarded to your friends. Отметить вÑÑ‘ как непрочитанное - + AUTHD ТребуетÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11671,7 +12003,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11697,6 +12029,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11708,7 +12057,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11788,27 +12137,32 @@ p, li { white-space: pre-wrap; } Форма - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11830,6 +12184,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11838,7 +12193,7 @@ p, li { white-space: pre-wrap; } ТекÑÑ‚, который вы видите ниже, еÑÑ‚ÑŒ ваш Ñертификат. Отправьте его тому, Ñ ÐºÐµÐ¼ вы желаете ÑоединитьÑÑ - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11855,12 +12210,12 @@ private and secure decentralized communication platform. Вам нужна помощь по RetroShare? - + Open Web Help Открыть помощь в веб - + Copy your Cert to Clipboard Скопировать Ñертификат в буфер обмена @@ -11909,7 +12264,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11918,7 +12273,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12211,14 +12566,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Ð’Ñе учаÑтники - + Reputation Ð ÐµÐ¿ÑƒÑ‚Ð°Ñ†Ð¸Ñ @@ -12228,12 +12583,12 @@ p, li { white-space: pre-wrap; } ПоиÑк - + Anonymous Id Ðнонимный идентификатор - + Create new Identity Создать новую личноÑÑ‚ÑŒ @@ -12377,7 +12732,7 @@ p, li { white-space: pre-wrap; } Идентификатор личноÑти - + Send message Отправить Ñообщение @@ -12469,7 +12824,7 @@ p, li { white-space: pre-wrap; } ОбщаÑ: - + Anonymous Ðнонимные учаÑтники @@ -12484,24 +12839,24 @@ p, li { white-space: pre-wrap; } ПоиÑк идентификатора - + This identity is owned by you Эта личноÑÑ‚ÑŒ закреплена за вами - - + + My own identities ЛичноÑти, Ñозданные мною - - + + My contacts Мои контакты - + Show Items Показать... @@ -12516,7 +12871,7 @@ p, li { white-space: pre-wrap; } ЛичноÑти, привÑзанные к моему узлу - + Other circles Другие круги @@ -12575,13 +12930,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). подпиÑанный (получает/передаёт запроÑÑ‹ членÑтва от других). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). неподпиÑанный (только получает приглашениÑ). - + Your status: Ваш ÑтатуÑ: @@ -12641,7 +13001,7 @@ p, li { white-space: pre-wrap; } Член - + Edit Circle Редактировать круг @@ -12689,7 +13049,7 @@ p, li { white-space: pre-wrap; } Разрешить членÑтво - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12701,12 +13061,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [неизвеÑтный узел] - + Unverified signature from node ÐÐµÐ¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´Ñ‘Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ от узла @@ -12718,12 +13078,12 @@ These identities will soon be not supported anymore. ÐÐµÐ¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ - + [unverified] [не подтверждено] - + Identity owned by you, linked to your Retroshare node ЛичноÑÑ‚ÑŒ закреплена за вами и привÑзана к вашему узлу RetroShare @@ -12847,12 +13207,12 @@ These identities will soon be not supported anymore. Отправить приглашение Ñ Ð’Ð°ÑˆÐ¸Ð¼ Ñертификатом? - + Banned Заблокированные учаÑтники - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;ЛичноÑти</h1> <p>Ð’ Ñтой вкладке вы имеете возможноÑÑ‚ÑŒ Ñоздавать/редактировать <b>анонимные и пÑевдонимные личноÑти</b>, а также <b>круги</b>.</p> <p><b>ЛичноÑти</b> иÑпользуютÑÑ Ð´Ð»Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñной публикации Ñообщений: от имени личноÑтей вы поÑылаете ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² чаты, форумы и каналы, получаете отклики через вÑтроенный в RetroShare почтовый ÑервиÑ, публикуете комментарии в каналах, чатах. От имени личноÑтей в определённых ÑлучаÑÑ… прокладываютÑÑ Ð°Ð½Ð¾Ð½Ð¸Ð¼Ð½Ñ‹Ðµ туннели и Ñ‚. п.</p> <p>ЛичноÑти не обÑзательно должны быть <b>подпиÑаны</b> вашим личным Ñертификатом. ПодпиÑанные личноÑти иногда полезны, еÑли вы хотите подчеркнуть авторÑтво того или иного ÑообщениÑ. Однако по подпиÑанным личноÑÑ‚Ñм зачаÑтую можно отÑледить IP-Ð°Ð´Ñ€ÐµÑ Ð°Ð²Ñ‚Ð¾Ñ€Ð° ÑообщениÑ.</p> <p><b>Ðнонимные личноÑти</b> позволÑÑŽÑ‚ вам анонимно, а значит – безопаÑно, взаимодейÑтвовать Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ учаÑтниками тёмной Ñети. Ðнонимные личноÑти не могут быть подменены, но никто не может однозначно обозначить привÑзку анонимной личноÑти к конкретному Ñертификату, а значит – и пользователю.</p> <p><b>Круги</b> – Ñто ÑовокупноÑÑ‚ÑŒ личноÑтей (анонимных или подпиÑанных), Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ которых широко раÑпроÑтранÑетÑÑ Ð¿Ð¾ тёмной Ñети. Круги иÑпользуютÑÑ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð¾Ñ€ÑƒÐ¼Ð¾Ð² и каналов, Ñодержимое которых доÑтупно только учаÑтникам конкретного круга </p> <p><b>Один круг</b> может быть ограничен другим кругом, как ÑледÑтвие, определÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ÑŒ его учаÑтников определённому множеÑтву учаÑтников, принадлежащему другому кругу. ЕÑÑ‚ÑŒ возможноÑÑ‚ÑŒ Ñоздавать Ñамый приватный тип кругов, где Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ них доÑтупна только членам Ñамого круга, читайте – закрытого клуба.</p> <p><b>Локальный круг</b> еÑÑ‚ÑŒ ÑовокупноÑÑ‚ÑŒ доверенных узлов, предÑтавленных их PGP-идентификаторами, и широко иÑпользуемых Ð´Ð»Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð¾ÑтупноÑти каналов и форумов. Такого рода круги не раÑпроÑтранÑÑŽÑ‚ÑÑ Ð¿Ð¾ Ñети и ÑпиÑок его членов доÑтупен только вам.</p> @@ -12861,7 +13221,7 @@ These identities will soon be not supported anymore. ÐеизвеÑтный идентификатор: - + positive положительно @@ -13046,8 +13406,8 @@ These identities will soon be not supported anymore. - - + + People УчаÑтники @@ -13058,7 +13418,7 @@ These identities will soon be not supported anymore. Ðажмите здеÑÑŒ, чтобы изменить Ñвой аватар - + Linked to neighbor nodes ЛичноÑти, привÑзанные к ближнему окружению @@ -13068,7 +13428,7 @@ These identities will soon be not supported anymore. ЛичноÑти, привÑзанные к удалённому узлу - + Linked to a friend Retroshare node ЛичноÑти, привÑзанные к доверенному окружению @@ -13128,7 +13488,7 @@ These identities will soon be not supported anymore. Принадлежит... - + Node name: Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð°: @@ -13138,7 +13498,7 @@ These identities will soon be not supported anymore. Идентификатор узла: - + Really delete? ДейÑтвительно удалить? @@ -13176,7 +13536,22 @@ These identities will soon be not supported anymore. ПÑевдоним - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity ÐÐ¾Ð²Ð°Ñ Ð»Ð¸Ñ‡Ð½Ð¾ÑÑ‚ÑŒ @@ -13193,14 +13568,14 @@ These identities will soon be not supported anymore. - + N/A ÐедоÑтупен - + Edit identity Редактировать личноÑÑ‚ÑŒ @@ -13211,24 +13586,27 @@ These identities will soon be not supported anymore. Обновить - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13247,17 +13625,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Ошибка при получении ключа! - + Error KeyID invalid Ошибка: недейÑтвительный идентификатор ключа - + Unknown GpgId ÐеизвеÑтный идентификатор GPG @@ -13267,7 +13655,7 @@ These identities will soon be not supported anymore. ÐеизвеÑтное Ð¸Ð¼Ñ - + Create New Identity Создать новую личноÑÑ‚ÑŒ @@ -13277,7 +13665,12 @@ These identities will soon be not supported anymore. Тип - + + Choose image... + + + + @@ -13317,12 +13710,11 @@ These identities will soon be not supported anymore. Ðажмите здеÑÑŒ, чтобы изменить аватар - Set Avatar - УÑтановить аватар + УÑтановить аватар - + Linked to your profile ПривÑзан к моему профилю @@ -13332,7 +13724,7 @@ These identities will soon be not supported anymore. Ð’Ñ‹ можете иметь один или неÑколько идентификаторов. Они иÑпользуютÑÑ, когда вы пишете в чате лобби, на форумах и канале комментариев. Они выÑтупают в качеÑтве Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ чата и удалённой почтовой ÑиÑтемы Retroshare. - + The nickname is too short. Please input at least %1 characters. ПÑевдоним ÑвлÑетÑÑ Ñлишком коротким. ПожалуйÑта, введите по крайней мере %1 Ñимволов. @@ -13441,8 +13833,12 @@ These identities will soon be not supported anymore. + Quote + Цитата + + Send - Отправить + Отправить @@ -13600,7 +13996,7 @@ These identities will soon be not supported anymore. - + Options Параметры @@ -13632,12 +14028,12 @@ These identities will soon be not supported anymore. Помощник быÑтрого Ñтарта - + RetroShare %1 a secure decentralized communication platform RetroShare %1 — безопаÑÐ½Ð°Ñ Ð´ÐµÑ†ÐµÐ½Ñ‚Ñ€Ð°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° - + Unfinished Ещё не готово @@ -13770,7 +14166,7 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка Показать - + Make sure this link has not been forged to drag you to a malicious website. УбедитеÑÑŒ, что Ñта ÑÑылка не была подделана, чтобы перенаправить Ð²Ð°Ñ Ð½Ð° вредоноÑный веб-Ñайт. @@ -13815,7 +14211,7 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка Управление правами доÑтупа - + Statistics СтатиÑтика Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ @@ -13844,7 +14240,7 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка MessageComposer - + Compose СоÑтавить @@ -13946,7 +14342,7 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка - + Tags Метки @@ -14041,12 +14437,12 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка Добавить цитату - + Send To: Отправить: - + &Left По левому краю @@ -14080,7 +14476,7 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка Мои контакты - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> ЗдравÑтвуйте, <br>Ñ Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´ÑƒÑŽ вам один из моих лучших контактов. Ð’Ñ‹ можете доверÑÑ‚ÑŒ ему ровно наÑтолько, наÑколько вы доверÑете мне. Это хороший узел, поверьте.<br> @@ -14106,12 +14502,12 @@ RetroShare безопаÑно приоÑтановит доÑтуп диÑка - + Save Message Сохранить Ñообщение - + Message has not been Sent. Do you want to save message to draft box? Сообщение не отправлено. @@ -14123,7 +14519,7 @@ Do you want to save message to draft box? Ð’Ñтавить ÑÑылку RetroShare - + Add to "To" Добавить к "кому" @@ -14378,7 +14774,7 @@ Do you want to save message ? Добавить файл - + Hi,<br>I want to be friends with you on RetroShare.<br> Привет, <br>ЕÑÑ‚ÑŒ предложение обменÑÑ‚ÑŒÑÑ Ñертификатами друг Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¼. Ðе возражаете?<br> @@ -14387,12 +14783,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Ð’Ñ‹ получили предложение на Ñоединение Ñ Ð´ÐµÐ¹Ñтвующим узлом RetroShare - + Respond now: Ответить ÑейчаÑ: @@ -14408,11 +14819,12 @@ Do you want to save message ? Из: + Friend Nodes - Доверенные узлы Ñети + Доверенные узлы Ñети - + Bullet list (disc) Маркированный ÑпиÑок (диÑк) @@ -14452,13 +14864,13 @@ Do you want to save message ? ОтÑортированный ÑпиÑок (в римÑкой ÑиÑтеме по убыванию) - - + + Thanks, <br> СпаÑибо, <br> - + Distant identity: Ð£Ð´Ð°Ð»Ñ‘Ð½Ð½Ð°Ñ Ð»Ð¸Ñ‡Ð½Ð¾ÑÑ‚ÑŒ: @@ -14597,8 +15009,23 @@ Do you want to save message ? Сообщение - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14610,12 +15037,12 @@ Do you want to save message ? Рекомендованные файлы - + Download all Recommended Files Скачать вÑе рекомендованные файлы - + Subject: Тема: @@ -14690,12 +15117,18 @@ Do you want to save message ? ПоÑлать приглашение - + + Message Size: + + + + File Name Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° - + + Size Размер @@ -14756,10 +15189,25 @@ Do you want to save message ? Скачать - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? ПоÑлать приглашение @@ -14770,12 +15218,12 @@ Do you want to save message ? - + Download all Скачать вÑÑ‘ - + Print Document РаÑпечатать документ @@ -14790,7 +15238,7 @@ Do you want to save message ? HTML-файлы (*.htm *.html);;Ð’Ñе файлы (*) - + Load images always for this message Загружать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ñегда Ð´Ð»Ñ Ñтого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ @@ -14931,7 +15379,7 @@ Do you want to save message ? MessagesDialog - + New Message Ðовое Ñообщение @@ -14987,14 +15435,14 @@ Do you want to save message ? - + Tags Метки - + Inbox ВходÑщие @@ -15089,7 +15537,7 @@ Do you want to save message ? ПереÑлать Ñообщение - + Subject Тема @@ -15201,7 +15649,7 @@ Do you want to save message ? - + Open in a new window Открыть в новом окне @@ -15286,7 +15734,7 @@ Do you want to save message ? - + Drafts Черновики @@ -15415,7 +15863,7 @@ Do you want to save message ? Ответить на Ñообщение - + Delete Message Удалить Ñообщение @@ -15426,7 +15874,7 @@ Do you want to save message ? - + Expand Развернуть @@ -15436,7 +15884,7 @@ Do you want to save message ? Удалить объект - + from от @@ -15445,6 +15893,11 @@ Do you want to save message ? Reply to invite Ответить на приглашение + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15768,7 +16221,7 @@ Reported error: - + Groups Группы @@ -15798,19 +16251,19 @@ Reported error: Импорт ÑпиÑка контактов, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑŽ о группах - - + + Search - + ID - + Search ID ПоиÑк идентификатора @@ -15820,7 +16273,7 @@ Reported error: - + Show Items Показать... @@ -16024,19 +16477,19 @@ at least one peer was not added to a group - + Error Ошибка - + File is not writeable! Ðет прав на запиÑÑŒ файла! - + File is not readable! Ðет прав на чтение файла! @@ -16074,9 +16527,13 @@ at least one peer was not added to a group NewsFeed - Log entries - Журнал + Журнал + + + + Activity Stream + @@ -16093,7 +16550,7 @@ at least one peer was not added to a group Это проверка. - + Newest on top Ðовые наверху @@ -16104,20 +16561,43 @@ at least one peer was not added to a group + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;ÐовоÑÑ‚Ð½Ð°Ñ Ð»ÐµÐ½Ñ‚Ð°</h1> <p>Лента новоÑтей отображает поÑледние ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð²Ð°ÑˆÐµÐ¹ Ñети в порÑдке получениÑ. Можно наÑтроить какие виды Ñобытий отображать в журнале, нажав <b>Параметры</b>. </p> <p>Ð¡Ð¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть Ñледующими: <ul> <li>попытка ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (полезно Ð´Ð»Ñ Ð¿Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ð¼Ð¸ доверенными учаÑтниками и отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÑ… учаÑтников, которые пытаютÑÑ Ðº вам подключитьÑÑ)</li> <li>поÑвление Ñообщений в форумах и каналах</li> <li>поÑвление новых форумов или каналов</li> <li>личные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚ ваших контактов</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;ÐовоÑÑ‚Ð½Ð°Ñ Ð»ÐµÐ½Ñ‚Ð°</h1> <p>Лента новоÑтей отображает поÑледние ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð²Ð°ÑˆÐµÐ¹ Ñети в порÑдке получениÑ. Можно наÑтроить какие виды Ñобытий отображать в журнале, нажав <b>Параметры</b>. </p> <p>Ð¡Ð¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть Ñледующими: <ul> <li>попытка ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (полезно Ð´Ð»Ñ Ð¿Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ð¼Ð¸ доверенными учаÑтниками и отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÑ… учаÑтников, которые пытаютÑÑ Ðº вам подключитьÑÑ)</li> <li>поÑвление Ñообщений в форумах и каналах</li> <li>поÑвление новых форумов или каналов</li> <li>личные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚ ваших контактов</li> </ul> </p> + + + Log + Журнал - Log - Журнал + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16154,22 +16634,22 @@ at least one peer was not added to a group - + Test ТеÑÑ‚ - + Chat Room Чат-комната - + Systray Icon Значок в ÑиÑтемном трее - + Message Сообщение @@ -16194,12 +16674,11 @@ at least one peer was not added to a group IP-безопаÑноÑÑ‚ÑŒ - Log - Журнал + Журнал - + Friend Connected Узел подключён @@ -16213,7 +16692,12 @@ at least one peer was not added to a group Публикации - + + Activity + + + + Mails Почта @@ -16250,7 +16734,12 @@ at least one peer was not added to a group Групповой чат - + + Toaster position + + + + Chat rooms Чат-комнаты @@ -16275,22 +16764,22 @@ at least one peer was not added to a group Учитывать региÑÑ‚Ñ€ - + Position МеÑтоположение - + X Margin ОтÑтуп по горизонтали - + Y Margin ОтÑтуп по вертикали - + Systray message Сообщение в панели уведомлений @@ -16340,7 +16829,7 @@ at least one peer was not added to a group Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ - + Disable All Toasters Отключить вÑе вÑплывающие ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ @@ -16354,7 +16843,7 @@ at least one peer was not added to a group Канал - + Systray Панель уведомлений @@ -16501,17 +16990,16 @@ at least one peer was not added to a group PGPKeyDialog - Dialog - Диалоговое окно + Диалоговое окно - + Profile info Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ профиле - + Name : ИмÑ: @@ -16566,22 +17054,21 @@ at least one peer was not added to a group Окончательный - + This profile has signed your own profile key Этот ключ подпиÑан вашим ÑобÑтвенным PGP-ключом - Key signatures : - Ключ подпиÑи: + Ключ подпиÑи: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">ПодпиÑание публичного ключа учаÑтника Ñети – Ñто ÑпоÑоб обозначить Ñвоё доверие тому или иному учаÑтнику. ПодпиÑи, которые вы видите ниже, подтверждают, что ключи в ÑпиÑке заверены и признаютÑÑ ÐºÐ°Ðº подлинные.</span></p></body></html> - + <!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; } @@ -16599,7 +17086,7 @@ p, li { white-space: pre-wrap; } ПодпиÑать Ñтот ключ - + PGP key PGP-ключ @@ -16609,22 +17096,20 @@ p, li { white-space: pre-wrap; } Эти опции применÑÑŽÑ‚ÑÑ Ð´Ð»Ñ Ð²Ñех меÑтоположений, привÑзанных к профилю: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Механизм подпиÑÐ°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ может оказатьÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ‹Ð¼ другим учаÑтникам Ñети, которые, добавлÑÑ Ñ‡ÑƒÐ¶Ð¾Ð¹ Ñертификат в Ñвоё окружение, имеют возможноÑÑ‚ÑŒ поÑмотреть, кто подпиÑал ключ в Ñертификате. Следует отметить, что подпиÑание чужих ключей не ÑвлÑетÑÑ Ð¾Ð±Ñзательным и не может быть впоÑледÑтвии отменено. ПоÑтому подходите к вопроÑу подпиÑаниÑ, взвеÑив вÑе «за» и «против».</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Механизм подпиÑÐ°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ может оказатьÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ‹Ð¼ другим учаÑтникам Ñети, которые, добавлÑÑ Ñ‡ÑƒÐ¶Ð¾Ð¹ Ñертификат в Ñвоё окружение, имеют возможноÑÑ‚ÑŒ поÑмотреть, кто подпиÑал ключ в Ñертификате. Следует отметить, что подпиÑание чужих ключей не ÑвлÑетÑÑ Ð¾Ð±Ñзательным и не может быть впоÑледÑтвии отменено. ПоÑтому подходите к вопроÑу подпиÑаниÑ, взвеÑив вÑе «за» и «против».</span></p></body></html> - + Keysigning: - Sign PGP key - ПодпиÑать PGP-ключ + ПодпиÑать PGP-ключ - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Щёлкните здеÑÑŒ, еÑли вы хотите отказать в Ñоединении узлам, привÑзанным к Ñтому публичному ключу.</p></body></html> @@ -16644,7 +17129,7 @@ p, li { white-space: pre-wrap; } Разрешить Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Ðиже находитÑÑ ÐºÐ»ÑŽÑ‡ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ ÑƒÐ·Ð»Ð° в формате PGP ASCII. Он идентифицирует вÑе узлы данного профилÑ. Сертификат Retroshare, которым вы можете обменÑÑ‚ÑŒÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ в доверенное окружение, находитÑÑ Ð² разделе "ПодробноÑти" каждого отдельного узла. @@ -16714,28 +17199,28 @@ p, li { white-space: pre-wrap; } кБ/Ñ - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Ошибка: не могу получить ÑовокупноÑÑ‚ÑŒ деталей. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) ПредоÑтавленный алгоритм ключа не поддерживаетÑÑ RetroShare (на данный момент поддерживаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ RSA-ключи) - + Warning: In your File-Transfer option, you select allow direct download to Yes. Предупреждение: в наÑтройках файлообмена вы разрешили прÑмую загрузку. @@ -16747,7 +17232,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Предупреждение: в наÑтройках файлообмена вы запретили прÑмую загрузку. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Уровень Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ ÑвлÑетÑÑ ÑпоÑобом выразить доверие в Ñтом ключе. Он не иÑпользуетÑÑ Ñторонним программным обеÑпечением, но может быть полезным Ð´Ð»Ñ Ð²Ð°Ñ, чтобы запомнить хорошие/плохие ключи. @@ -16792,27 +17277,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹ не разрешаете ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ñ‚ узлов Retroshare, подпиÑанные Ñтим ключом. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Ошибка в подпиÑи - - Maybe password is wrong - Может быть, неправильный пароль + + Check the password! + - + Maybe password is wrong + Может быть, неправильный пароль + + + You haven't set a trust level for this key. Ð’Ñ‹ не наÑтроили уровень Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð´Ð»Ñ Ñтого ключа. - + + Retroshare profile Профиль RetroShare - + This is your own PGP key, and it is signed by : Это ваш ÑобÑтвенный ключ PGP и он подпиÑан: @@ -16991,8 +17496,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People УчаÑтники @@ -17009,7 +17513,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Внутренний - + Chat with this person Ðачать чат @@ -17160,7 +17664,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Фото - + TextLabel ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° @@ -17204,8 +17708,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Комментарии @@ -17240,6 +17744,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Ðапишите комментарий... + + + Album + Ðльбом + PhotoItem @@ -17249,12 +17758,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Форма - + TextLabel ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° - + <!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; } @@ -17350,7 +17859,7 @@ p, li { white-space: pre-wrap; } ПроÑмотр фото - + PhotoShare PhotoShare @@ -17391,7 +17900,7 @@ requesting to edit it! - + Stop Стоп @@ -17619,12 +18128,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Разрешить вÑе плагины - + Plugin look-up directories Папки поиÑка плагинов @@ -17683,7 +18192,7 @@ malicious behavior of crafted plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Plugins</h1><p>Плагины загружаютÑÑ Ð¸Ð· каталогов, перечиÑленных в нижней чаÑти ÑпиÑка.</p><p>По ÑоображениÑм безопаÑноÑти, разрешённые плагины загружаютÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки до главного иÑполнÑемого файла RetroShare или Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ¸ плагинов. Ð’ таком Ñлучае, пользователь должен подтвердить их Ñнова. ПоÑле запуÑка программы, вы можете включить плагин вручную, нажав на кнопку "Включить" и перезагрузить RetroShare.</p> <p>ЕÑли вы хотите разрабатывать Ñвои ÑобÑтвенные плагины, ÑвÑжитеÑÑŒ Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ Разработчиков, они будут рады помочь вам!</p> - + Plugins Плагины @@ -18081,7 +18590,7 @@ malicious behavior of crafted plugins. Публикации - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18252,13 +18761,13 @@ malicious behavior of crafted plugins. Сайт - - + + Comments Комментарии - + Copy RetroShare Link Скопировать ÑÑылку RetroShare @@ -18268,7 +18777,7 @@ malicious behavior of crafted plugins. - + Comment Комментарий @@ -18289,12 +18798,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up ГолоÑовать "за" @@ -18308,7 +18817,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item УÑтановить как чтение и удаление Ñлемента @@ -18369,7 +18878,7 @@ malicious behavior of crafted plugins. ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° - + Loading Загрузка @@ -18459,13 +18968,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18475,60 +18978,50 @@ malicious behavior of crafted plugins. ÐдминиÑтратор: - - - + + + unknown - + Distribution: РаÑпроÑтранение: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel ТекÑÑ‚Ð¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ @@ -18539,7 +19032,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18608,7 +19101,12 @@ malicious behavior of crafted plugins. - + + Empty + ПуÑто + + + Copy RetroShare Link Скопировать ÑÑылку RetroShare @@ -18643,7 +19141,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18771,8 +19269,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19052,9 +19560,8 @@ and use the import button to load it PulseAddDialog - Post From: - Сообщение от: + Сообщение от: Account 1 @@ -19069,7 +19576,7 @@ and use the import button to load it Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ 3 - + Add to Pulse Добавить в Pulse @@ -19092,17 +19599,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Из: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19127,10 +19649,20 @@ and use the import button to load it Отрицательное мнение - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19140,14 +19672,53 @@ and use the import button to load it - + + Post + + + + Cancel Отмена - Post Pulse to Wire - Сообщение-Ð¸Ð¼Ð¿ÑƒÐ»ÑŒÑ Ð´Ð»Ñ Ð¢ÐµÐ»ÐµÐ³Ñ€Ð°Ñ„Ð° + Сообщение-Ð¸Ð¼Ð¿ÑƒÐ»ÑŒÑ Ð´Ð»Ñ Ð¢ÐµÐ»ÐµÐ³Ñ€Ð°Ñ„Ð° + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19173,10 +19744,18 @@ and use the import button to load it Форма - - - - + + + + + Click to view picture + + + + + + + Image Изображение @@ -19184,44 +19763,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19231,17 +19810,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19251,7 +19830,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19259,7 +19838,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -19274,7 +19853,7 @@ and use the import button to load it - + follow Parent Group @@ -19284,7 +19863,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19309,7 +19888,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19345,29 +19924,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19445,7 +20024,7 @@ and use the import button to load it QObject - + Confirmation Подтверждение @@ -19687,7 +20266,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Результат - + Unable to make path Ðевозможно задать путь @@ -19722,7 +20301,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° файл отменён - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Эта верÑÐ¸Ñ RetroShare иÑпользует OpenPGP-SDK. Ð’ качеÑтве побочного Ñффекта, она не иÑпользует ÑиÑтемное публичное PGP хранилище, но имеет Ñвоё ÑобÑтвенное хранилище, которое иÑпользуетÑÑ Ð²Ñеми ÑкземплÑрами RetroShare. <br><br>Похоже, что вы не имеете такое хранилище, Ñ…Ð¾Ñ‚Ñ ÐºÐ»ÑŽÑ‡Ð¸ PGP упоминаютÑÑ ÑƒÑ‡Ñ‘Ñ‚Ð½Ñ‹Ð¼Ð¸ запиÑÑми RetroShare, вероÑтно, потому, что вы только что обновилиÑÑŒ до Ñтой новой верÑии программного обеÑпечениÑ. @@ -19876,7 +20455,7 @@ Reported error is: Ñек. - + TR up Отдача TR @@ -19921,7 +20500,7 @@ Reported error is: отключено - + Move IP %1 to whitelist ПеренеÑти IP %1 в белый ÑпиÑок @@ -19937,7 +20516,7 @@ Reported error is: - + %1 seconds ago %1 Ñекунд назад @@ -20022,7 +20601,7 @@ Security: no anonymous IDs - + Error Ошибка @@ -20413,9 +20992,8 @@ Security: no anonymous IDs Ðажмите, чтобы возобновить процеÑÑ Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ - <p>This certificate contains: - <p>Этот Ñертификат Ñодержит: + <p>Этот Ñертификат Ñодержит: @@ -20753,7 +21331,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 КБ @@ -20975,19 +21553,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options ÐаÑтройка древовидного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ - Show column... - Показать Ñтолбец... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Сортировать по убыванию + + + + Sort Ascending Order + Сортировать по возраÑтанию + + + + + [no title] + + + + + Show column … + + + + Show column... + Показать Ñтолбец... - [no title] - [без заголовка] + [без заголовка] @@ -21423,7 +22030,7 @@ p, li { white-space: pre-wrap; } Скачать! - + File Файл @@ -21438,7 +22045,7 @@ p, li { white-space: pre-wrap; } Ð¥Ñш - + Bad filenames have been cleaned Были очищены неправильные имена файлов @@ -21488,7 +22095,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Сохранить - + Collection Editor Редактор коллекции @@ -21503,7 +22110,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace КоличеÑтво Файлов - + Real Size: Waiting child... ДейÑтвительный размер: ждите... @@ -21518,12 +22125,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Это каталог. Ðажмите дважды, чтобы развернуть его. - + Download files Скачать файлы - + Specify... Выбрать... @@ -21772,7 +22379,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Ð˜Ð¼Ñ @@ -21792,7 +22399,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21805,10 +22412,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Ðазвание + + + UnRead + + Date @@ -21820,7 +22432,7 @@ If you believe it is correct, remove the corresponding line from the file and re Ðвтор - + Information for this identity is currently missing. Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± Ñтой личноÑти отÑутÑтвует @@ -21860,7 +22472,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Пропущенное Ñообщение ... ] @@ -21868,7 +22480,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Дата @@ -21928,7 +22540,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22286,7 +22898,7 @@ prevents the message to be forwarded to your friends. Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° - + Download Скачать @@ -22365,7 +22977,7 @@ prevents the message to be forwarded to your friends. Открыть папку - + Create Collection... Создание коллекции... @@ -22385,7 +22997,7 @@ prevents the message to be forwarded to your friends. Загрузить из файла коллекции... - + Collection ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ @@ -22490,12 +23102,12 @@ prevents the message to be forwarded to your friends. Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± учаÑтнике - + Deny friend Отказать в Ñоединении - + Chat Чат @@ -22505,7 +23117,7 @@ prevents the message to be forwarded to your friends. Ðачать чат - + Expand Развернуть @@ -22772,13 +23384,13 @@ behind a firewall or a VPN. Обнаружение включено (рекомендуетÑÑ) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor был автоматичеÑки наÑтроен Retroshare. ЗдеÑÑŒ не нужно ничего менÑÑ‚ÑŒ. - + Discovery Off Обнаружение выключено @@ -23270,7 +23882,7 @@ If you have issues connecting over Tor check the Tor logs too. <p>Ð’ любом Ñлучае узел Retroshare, дейÑтвующий как транÑлÑтор, не может видеть передаваемые данные, так как они зашифрованы и аутентифицированы Ð´Ð²ÑƒÐ¼Ñ Ñ€ÐµÑ‚Ñ€Ð°Ð½Ñлируемыми узлами.</p> - + Network Сеть @@ -23298,7 +23910,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Ð¡Ñ‚Ð°Ñ‚ÑƒÑ @@ -23395,7 +24007,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address ÐÐ´Ñ€ÐµÑ Ñлужбы @@ -23430,12 +24042,12 @@ If you have issues connecting over Tor check the Tor logs too. ПожалуйÑта, заполните Ð°Ð´Ñ€ÐµÑ Ñлужбы - + IP Range Диапазон IP-адреÑов - + Reported by DHT for IP masquerading Получено из DHT; попытка подмены IP-адреÑа @@ -24109,7 +24721,7 @@ p, li { white-space: pre-wrap; } ОтÑутÑтвует Ñертификат PGP - + Wrong password Ðеверный пароль @@ -24163,7 +24775,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Добавить доверенный узел @@ -24219,7 +24831,7 @@ This choice can be reverted in settings. Управление правами доÑтупа - + DHT DHT @@ -24759,7 +25371,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24773,13 +25385,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупен - + Tor is OK Tor в порÑдке @@ -24788,6 +25399,31 @@ p, li { white-space: pre-wrap; } No tor configuration Ðет конфигурации Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25073,35 +25709,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - У Ð²Ð°Ñ %1 завершённых закачек + You have %1 completed transfers + - You have %1 completed download - У Ð²Ð°Ñ ÐµÑÑ‚ÑŒ %1 Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° + You have %1 completed transfer + - %1 completed downloads - %1 завершённых закачек + %1 completed transfers + - %1 completed download - %1 завершённых загрузок + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + У Ð²Ð°Ñ %1 завершённых закачек + + + You have %1 completed download + У Ð²Ð°Ñ ÐµÑÑ‚ÑŒ %1 Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° + + + %1 completed downloads + %1 завершённых закачек + + + %1 completed download + %1 завершённых загрузок TransfersDialog - + Downloads Обмен файлами @@ -25112,7 +25759,7 @@ p, li { white-space: pre-wrap; } Передача - + Name i.e: file name Ð˜Ð¼Ñ @@ -25323,7 +25970,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;File Transfer</h1> <p>RetroShare поддерживает два метода передачи файлов: прÑмые передачи между друзьÑми и анонимные туннельные передачи. Кроме Ñтого поддерживаетÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° от неÑкольких иÑточников (вы также можете быть иÑточником, пока Ñкачиваете файл)</p> <p>ЕÑÑ‚ÑŒ возможноÑÑ‚ÑŒ раздавать Ñвои файлы, воÑпользуйтеÑÑŒ значком <img src=":/images/directoryadd_24x24_shadow.png" width=16 /> на панели. Эти файлы будут добавлены в ÑпиÑок разделÑемых вами реÑурÑов. Дополнительно вы можете указать доÑтупноÑÑ‚ÑŒ Ñтих файлов Ð´Ð»Ñ Ð±Ð»Ð¸Ð¶Ð½ÐµÐ³Ð¾ окружениÑ</p> <p>Вкладка "ПоиÑк" позволÑет иÑкать файлы Ñреди доÑтупных реÑурÑов ваших контактов, а также у удалённых пользователей, через ÑÐµÑ€Ð²Ð¸Ñ Ð°Ð½Ð¾Ð½Ð¸Ð¼Ð½Ñ‹Ñ… туннелей.</p> - + Move in Queue... ПеремеÑтить в очереди... @@ -25417,7 +26064,7 @@ p, li { white-space: pre-wrap; } ПожалуйÑта введите новое--и дейÑтвительное--Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° - + Expand all РаÑкрыть вÑÑ‘ @@ -25549,7 +26196,7 @@ p, li { white-space: pre-wrap; } - + Columns Столбцы @@ -25560,7 +26207,7 @@ p, li { white-space: pre-wrap; } Файлообмен - + Path Путь @@ -25570,7 +26217,7 @@ p, li { white-space: pre-wrap; } Показать Ñтолбец "Путь" - + Could not delete preview file Ðе удалоÑÑŒ удалить файл предварительного проÑмотра @@ -25580,7 +26227,7 @@ p, li { white-space: pre-wrap; } Попробуйте ещё раз? - + Create Collection... Создание коллекции... @@ -25595,7 +26242,7 @@ p, li { white-space: pre-wrap; } ПроÑмотр коллекции... - + Collection ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ @@ -25841,7 +26488,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer ÐеизвеÑтный учаÑтник @@ -25937,7 +26584,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages У Ð²Ð°Ñ %1 новых Ñообщений @@ -26321,7 +26968,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group ПодпиÑатьÑÑ Ð½Ð° группу @@ -26415,8 +27062,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Показать иÑторию Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ @@ -26427,7 +27074,7 @@ p, li { white-space: pre-wrap; } - + Preview ПредпроÑмотр @@ -26452,12 +27099,12 @@ p, li { white-space: pre-wrap; } Скрыть иÑторию Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ - + Edit Page Редактировать Ñтраницу - + Create New Wiki Page Создать новую Ñтраницу Wiki @@ -26477,7 +27124,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Создать новую группу Wiki @@ -26519,7 +27166,7 @@ p, li { white-space: pre-wrap; } Диапазон времени - + Create Account @@ -26529,12 +27176,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Обновить @@ -26569,12 +27215,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26644,7 +27290,7 @@ p, li { white-space: pre-wrap; } Показаны: - + Yourself Ð¡ÐµÐ±Ñ @@ -26682,7 +27328,7 @@ p, li { white-space: pre-wrap; } Сообщение-Ð¸Ð¼Ð¿ÑƒÐ»ÑŒÑ Ð´Ð»Ñ Ð¢ÐµÐ»ÐµÐ³Ñ€Ð°Ñ„Ð° - + RetroShare RetroShare @@ -26694,7 +27340,7 @@ p, li { white-space: pre-wrap; } - + The Wire Провод @@ -26702,7 +27348,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26783,8 +27429,8 @@ p, li { white-space: pre-wrap; } Форма - - + + Avatar Ðватар @@ -26813,6 +27459,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26925,8 +27576,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_sl.ts b/retroshare-gui/src/lang/retroshare_sl.ts index 7a7fe45cd..a8c42dad2 100644 --- a/retroshare-gui/src/lang/retroshare_sl.ts +++ b/retroshare-gui/src/lang/retroshare_sl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -167,7 +167,7 @@ AlbumDialog - + Album @@ -282,7 +282,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -325,8 +325,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -393,7 +393,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -418,7 +418,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -443,7 +443,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -518,7 +518,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -533,7 +533,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -599,13 +599,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -614,25 +619,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -640,7 +650,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -660,44 +670,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Pokaži nastavitve + TextLabel + + + + Reset Ponastavi - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -707,30 +726,23 @@ p, li { white-space: pre-wrap; } - Save - Shrani + Shrani - Cancel - PrekliÄi + PrekliÄi - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -752,7 +764,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -886,7 +898,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -964,6 +976,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ime + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1099,6 +1190,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Privzeto + + + + Dark + + ChannelPage @@ -1151,6 +1252,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ime + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1359,22 +1539,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1388,11 +1568,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1825,13 +2000,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1896,17 +2065,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1927,11 +2091,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1992,11 +2157,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2135,8 +2306,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2305,7 +2491,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2322,12 +2508,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2399,7 +2585,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2435,12 +2621,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2456,7 +2642,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2476,7 +2662,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2634,12 +2820,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2650,12 +2836,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2671,31 +2857,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2711,22 +2907,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2761,13 +2957,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2782,7 +2983,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2793,17 +2994,22 @@ Double click on it to add his name on text writer. brez - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2813,7 +3019,7 @@ Double click on it to add his name on text writer. - + with @@ -2897,32 +3103,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Ime: - + Location: - + Options Možnosti - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2932,7 +3138,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2957,12 +3163,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2982,32 +3188,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3053,17 +3259,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3083,12 +3289,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3136,7 +3342,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3180,12 +3416,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3215,7 +3451,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3273,12 +3509,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3353,7 +3589,12 @@ even if you don't make friends. - + + Status + Stanje + + + <!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; } @@ -3775,7 +4016,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3915,7 +4156,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3930,7 +4171,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3946,7 +4187,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3962,12 +4203,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3989,7 +4230,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4115,7 +4356,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4161,7 +4402,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4171,7 +4412,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4198,17 +4439,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4239,12 +4500,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4264,7 +4525,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4352,7 +4613,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4767,7 +5028,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5770,7 +6031,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6261,7 +6522,7 @@ at least one peer was not added to a group - + Mark all @@ -6275,7 +6536,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6379,7 +6640,7 @@ at least one peer was not added to a group - + Network @@ -6444,7 +6705,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6475,7 +6736,7 @@ at least one peer was not added to a group - + Node name @@ -6734,12 +6995,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7102,7 +7363,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7167,7 +7428,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7190,7 +7451,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7391,7 +7652,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7401,13 +7662,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7417,42 +7695,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7467,40 +7710,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Ime - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7649,7 +7883,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7670,12 +7904,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8045,7 +8279,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8145,12 +8379,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8161,18 +8395,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8182,12 +8416,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8247,7 +8481,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8262,12 +8496,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8343,23 +8577,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8381,11 +8628,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8870,17 +9112,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8890,19 +9132,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8917,7 +9159,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8962,23 +9214,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9016,17 +9268,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9056,8 +9308,8 @@ before you can comment - - + + Distribution @@ -9144,12 +9396,12 @@ before you can comment - + New thread - + Edit @@ -9205,7 +9457,7 @@ before you can comment - + Author's reputation @@ -9225,7 +9477,7 @@ before you can comment - + <b>Loading...<b> @@ -9265,6 +9517,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9332,7 +9589,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9364,11 +9621,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9774,7 +10026,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9789,7 +10041,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9799,12 +10051,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9871,12 +10123,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9891,7 +10143,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10405,7 +10657,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10414,7 +10666,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10440,7 +10692,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10514,49 +10766,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10604,17 +10862,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10629,7 +10882,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10894,14 +11152,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10911,12 +11169,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11060,7 +11318,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11132,7 +11390,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11147,24 +11405,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11179,7 +11437,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11238,13 +11496,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11304,7 +11567,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11352,7 +11615,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11361,12 +11624,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11378,12 +11641,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11499,17 +11762,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11666,8 +11929,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11678,7 +11941,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11688,7 +11951,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11748,7 +12011,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11758,7 +12021,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11796,7 +12059,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11813,14 +12076,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11831,24 +12094,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11868,12 +12134,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11883,7 +12174,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11893,7 +12184,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11933,12 +12229,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11948,7 +12239,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12053,7 +12344,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12212,7 +12503,7 @@ These identities will soon be not supported anymore. - + Options Možnosti @@ -12244,12 +12535,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12378,7 +12669,7 @@ These identities will soon be not supported anymore. Pokaži - + Make sure this link has not been forged to drag you to a malicious website. @@ -12423,7 +12714,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12452,7 +12743,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12554,7 +12845,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12649,12 +12940,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12684,7 +12975,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12710,12 +13006,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12726,7 +13022,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12980,7 +13276,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12994,6 +13290,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13006,7 +13317,7 @@ Do you want to save message ? Od: - + Bullet list (disc) @@ -13046,13 +13357,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13191,8 +13502,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13204,12 +13530,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13284,12 +13610,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13350,18 +13682,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13376,7 +13723,7 @@ Do you want to save message ? - + Load images always for this message @@ -13485,7 +13832,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13501,14 +13848,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13579,7 +13926,7 @@ Do you want to save message ? - + Subject @@ -13659,7 +14006,7 @@ Do you want to save message ? - + Open in a new window @@ -13744,7 +14091,7 @@ Do you want to save message ? - + Drafts @@ -13833,7 +14180,7 @@ Do you want to save message ? - + Delete Message @@ -13844,7 +14191,7 @@ Do you want to save message ? - + Expand @@ -13854,7 +14201,7 @@ Do you want to save message ? - + from @@ -13863,6 +14210,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14162,7 +14514,7 @@ Reported error: - + Groups @@ -14192,19 +14544,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14214,7 +14566,7 @@ Reported error: - + Show Items @@ -14413,18 +14765,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14462,7 +14814,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14476,7 +14828,7 @@ at least one peer was not added to a group - + Newest on top @@ -14487,20 +14839,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14533,22 +14900,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14569,12 +14936,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14621,27 +14983,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14691,7 +15063,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14701,7 +15073,7 @@ at least one peer was not added to a group - + Systray @@ -14828,17 +15200,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14893,22 +15260,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14922,7 +15284,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14932,22 +15294,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14967,7 +15319,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15033,27 +15385,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15065,7 +15417,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15110,27 +15462,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15301,8 +15669,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15319,7 +15686,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15451,7 +15818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15487,7 +15854,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15515,6 +15882,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... ... + + + Album + + PhotoItem @@ -15524,12 +15896,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15609,7 +15981,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15649,7 +16021,7 @@ requesting to edit it! - + Stop @@ -15873,17 +16245,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16209,7 +16581,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16340,13 +16712,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16356,7 +16728,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16377,12 +16749,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16392,7 +16764,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16453,7 +16825,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16476,13 +16848,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16492,60 +16858,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown neznano - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16556,7 +16912,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16625,7 +16981,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16660,7 +17021,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16776,8 +17137,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17045,12 +17416,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17065,17 +17431,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + Od: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17100,10 +17481,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17113,13 +17504,48 @@ and use the import button to load it - + + Post + + + + Cancel PrekliÄi - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17138,10 +17564,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17149,44 +17583,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17196,17 +17630,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17216,7 +17650,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17224,7 +17658,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17239,7 +17673,7 @@ and use the import button to load it - + follow Parent Group @@ -17249,7 +17683,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17274,7 +17708,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17310,29 +17744,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17410,7 +17844,7 @@ and use the import button to load it QObject - + Confirmation @@ -17649,7 +18083,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17684,7 +18118,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17822,7 +18256,7 @@ Reported error is: - + TR up @@ -17867,7 +18301,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17883,7 +18317,7 @@ Reported error is: - + %1 seconds ago @@ -17967,7 +18401,7 @@ Security: no anonymous IDs - + Error @@ -18357,11 +18791,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18695,7 +19124,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18917,18 +19346,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19365,7 +19815,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19380,7 +19830,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19428,7 +19878,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Shrani - + Collection Editor @@ -19443,7 +19893,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19458,12 +19908,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19710,7 +20160,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Ime @@ -19730,7 +20180,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19743,10 +20193,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19758,7 +20213,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19796,7 +20251,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19804,7 +20259,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19864,7 +20319,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20218,7 +20673,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20297,7 +20752,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20317,7 +20772,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20422,12 +20877,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20437,7 +20892,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20700,13 +21155,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21172,7 +21627,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21200,7 +21655,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Stanje @@ -21297,7 +21752,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21332,12 +21787,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22002,7 +22457,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22044,7 +22499,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22100,7 +22555,7 @@ This choice can be reverted in settings. - + DHT @@ -22632,7 +23087,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22642,13 +23097,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22657,6 +23111,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22930,27 +23409,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22958,7 +23432,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22969,7 +23443,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Ime @@ -23176,7 +23650,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23270,7 +23744,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23402,7 +23876,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23413,7 +23887,7 @@ p, li { white-space: pre-wrap; } - + Path Pot @@ -23423,7 +23897,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23433,7 +23907,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23448,7 +23922,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23690,7 +24164,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23786,7 +24260,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24154,7 +24628,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24248,8 +24722,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24260,7 +24734,7 @@ p, li { white-space: pre-wrap; } - + Preview Predogled @@ -24285,12 +24759,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24310,7 +24784,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24348,7 +24822,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24358,12 +24832,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24398,12 +24871,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24433,7 +24906,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24443,7 +24916,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24455,7 +24928,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24463,7 +24936,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24544,8 +25017,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24574,6 +25047,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24686,7 +25164,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_sr.ts b/retroshare-gui/src/lang/retroshare_sr.ts index 2f058046b..6d5a3f97d 100644 --- a/retroshare-gui/src/lang/retroshare_sr.ts +++ b/retroshare-gui/src/lang/retroshare_sr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -122,12 +122,12 @@ Ðапредна претрага - + Search Criteria Критеријум претраге - + Add a further search criterion. Додајте додатни критеријум претраге. @@ -168,7 +168,7 @@ AlbumDialog - + Album @@ -283,7 +283,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -326,8 +326,8 @@ p, li { white-space: pre-wrap; } Образац - - + + TextLabel @@ -394,7 +394,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -419,7 +419,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -444,7 +444,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -519,7 +519,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -600,13 +600,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -615,25 +620,30 @@ p, li { white-space: pre-wrap; } Уклони - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar Кликните да промените аватар @@ -641,7 +651,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -661,44 +671,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Употреба протока + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Прикажи подешавања + TextLabel + + + + Reset Поништи - Receive Rate - Брзина пријема + Брзина пријема - Send Rate - Брзина Ñлања + Брзина Ñлања - + Always on Top Увек на врху - Style - Стил + Стил - + Changes the transparency of the Bandwidth Graph Мења провидноÑÑ‚ графикона за проток - + 100 100 @@ -708,30 +739,27 @@ p, li { white-space: pre-wrap; } % непровидно - Save - Сачувај + Сачувај - Cancel - Откажи + Откажи - + Since: Од: - Hide Settings - Сакриј подешавања + Сакриј подешавања BandwidthStatsWidget - + Sum @@ -753,7 +781,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -887,7 +915,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -965,6 +993,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Промени ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ð¾Ñ€ÑƒÐºÐ° + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Прошири + + + + Set as read and remove item + + + + + Remove Item + Уклони Ñтавку + + + + Name + Ðазив + + + + Comm value + + + + + Comment + Коментар + + + + Comments + + + + + Hide + Сакриј + + BwCtrlWindow @@ -1100,6 +1207,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Подразумевано + + + + Dark + + ChannelPage @@ -1152,6 +1269,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Промени ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ð¾Ñ€ÑƒÐºÐ° + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Прошири + + + + Set as read and remove item + + + + + Remove Item + Уклони Ñтавку + + + + Name + Ðазив + + + + Comm value + + + + + Comment + Коментар + + + + Comments + + + + + Hide + Сакриј + + ChatLobbyDialog @@ -1360,22 +1556,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1389,11 +1585,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1830,13 +2021,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1901,17 +2086,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1932,11 +2112,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1997,11 +2178,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2140,8 +2327,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2310,7 +2512,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2327,12 +2529,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2404,7 +2606,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2440,12 +2642,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2461,7 +2663,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2481,7 +2683,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2639,12 +2841,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2655,12 +2857,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2676,31 +2878,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare Ретрошер - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2716,22 +2928,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2766,13 +2978,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2787,7 +3004,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2798,17 +3015,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2818,7 +3040,7 @@ Double click on it to add his name on text writer. - + with @@ -2902,32 +3124,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Ðазив: - + Location: МеÑто: - + Options Опције - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2937,7 +3159,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2962,12 +3184,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2987,32 +3209,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3058,17 +3280,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3088,12 +3310,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3141,7 +3363,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3185,12 +3437,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3220,7 +3472,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3278,12 +3530,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3358,7 +3610,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3780,7 +4037,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3924,7 +4181,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3939,7 +4196,7 @@ p, li { white-space: pre-wrap; } - + Search Претражи @@ -3955,7 +4212,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3971,12 +4228,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3998,7 +4255,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4124,7 +4381,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4170,7 +4427,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4180,7 +4437,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4207,17 +4464,37 @@ p, li { white-space: pre-wrap; } - + RetroShare Ретрошер - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4248,12 +4525,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4273,7 +4550,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4365,7 +4642,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4780,7 +5057,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5783,7 +6060,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6274,7 +6551,7 @@ at least one peer was not added to a group - + Mark all @@ -6288,7 +6565,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6392,7 +6669,7 @@ at least one peer was not added to a group - + Network @@ -6457,7 +6734,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6488,7 +6765,7 @@ at least one peer was not added to a group - + Node name @@ -6747,12 +7024,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7115,7 +7392,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7180,7 +7457,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7203,7 +7480,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7404,7 +7681,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7414,13 +7691,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7430,42 +7724,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7480,40 +7739,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post ПоÑледња порука - + + Name Ðазив - - Unread - - - - + Popularity ПопуларноÑÑ‚ - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7662,7 +7912,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7683,12 +7933,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8058,7 +8308,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8158,12 +8408,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8174,18 +8424,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8195,12 +8445,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8260,7 +8510,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8275,12 +8525,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8356,23 +8606,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe Пријави ме - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8394,11 +8657,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8883,7 +9141,7 @@ before you can comment - + Search forums @@ -8892,12 +9150,12 @@ before you can comment ПоÑледња порука - + New Thread - + Threaded View @@ -8907,19 +9165,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8934,7 +9192,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8979,23 +9247,23 @@ before you can comment - + No name - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9033,12 +9301,12 @@ before you can comment - + Copy RetroShare Link - + Hide Сакриј @@ -9047,7 +9315,7 @@ before you can comment Прошири - + [unknown] @@ -9077,8 +9345,8 @@ before you can comment - - + + Distribution @@ -9161,12 +9429,12 @@ before you can comment - + New thread - + Edit @@ -9222,7 +9490,7 @@ before you can comment - + Author's reputation @@ -9242,7 +9510,7 @@ before you can comment - + <b>Loading...<b> @@ -9282,6 +9550,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9349,7 +9622,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9381,11 +9654,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9791,7 +10059,7 @@ This message is missing. You should receive it later. - + Unsubscribe Одјави ме @@ -9806,7 +10074,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9816,12 +10084,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9888,12 +10156,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9908,7 +10176,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10422,7 +10690,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10431,7 +10699,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10457,7 +10725,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10531,49 +10799,55 @@ p, li { white-space: pre-wrap; } Образац - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... … - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10621,17 +10895,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10646,7 +10915,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10911,14 +11185,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10928,12 +11202,12 @@ p, li { white-space: pre-wrap; } Претражи - + Anonymous Id - + Create new Identity @@ -11077,7 +11351,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11149,7 +11423,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11164,24 +11438,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11196,7 +11470,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11255,13 +11529,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11321,7 +11600,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11369,7 +11648,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11378,12 +11657,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11395,12 +11674,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11516,17 +11795,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11683,8 +11962,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11695,7 +11974,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11705,7 +11984,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11765,7 +12044,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11775,7 +12054,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11813,7 +12092,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11830,14 +12109,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11848,24 +12127,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11885,12 +12167,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11900,7 +12207,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11910,7 +12217,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11950,12 +12262,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11965,7 +12272,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12070,7 +12377,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12229,7 +12536,7 @@ These identities will soon be not supported anymore. - + Options Опције @@ -12261,12 +12568,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12395,7 +12702,7 @@ These identities will soon be not supported anymore. Прикажи - + Make sure this link has not been forged to drag you to a malicious website. @@ -12440,7 +12747,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12469,7 +12776,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12571,7 +12878,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12666,12 +12973,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12701,7 +13008,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12727,12 +13039,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12743,7 +13055,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12997,7 +13309,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13011,6 +13323,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13023,7 +13350,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13063,13 +13390,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13208,8 +13535,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13221,12 +13563,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13301,12 +13643,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13367,18 +13715,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13393,7 +13756,7 @@ Do you want to save message ? - + Load images always for this message @@ -13502,7 +13865,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13518,14 +13881,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13596,7 +13959,7 @@ Do you want to save message ? - + Subject ÐаÑлов @@ -13676,7 +14039,7 @@ Do you want to save message ? - + Open in a new window @@ -13761,7 +14124,7 @@ Do you want to save message ? - + Drafts @@ -13850,7 +14213,7 @@ Do you want to save message ? - + Delete Message @@ -13861,7 +14224,7 @@ Do you want to save message ? - + Expand Прошири @@ -13871,7 +14234,7 @@ Do you want to save message ? Уклони Ñтавку - + from @@ -13880,6 +14243,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14179,7 +14547,7 @@ Reported error: - + Groups @@ -14209,19 +14577,19 @@ Reported error: - - + + Search Претражи - + ID ИД - + Search ID @@ -14231,7 +14599,7 @@ Reported error: - + Show Items @@ -14430,18 +14798,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14479,7 +14847,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14493,7 +14861,7 @@ at least one peer was not added to a group - + Newest on top @@ -14504,20 +14872,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14550,22 +14933,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14586,12 +14969,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14638,27 +15016,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14708,7 +15096,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14718,7 +15106,7 @@ at least one peer was not added to a group - + Systray @@ -14845,17 +15233,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14910,22 +15293,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14939,7 +15317,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14949,22 +15327,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14984,7 +15352,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15050,27 +15418,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare Ретрошер - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15082,7 +15450,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15127,27 +15495,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15318,8 +15702,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15336,7 +15719,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15475,7 +15858,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15515,7 +15898,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15543,6 +15926,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... … + + + Album + + PhotoItem @@ -15552,12 +15940,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Образац - + TextLabel - + <!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; } @@ -15637,7 +16025,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15677,7 +16065,7 @@ requesting to edit it! - + Stop @@ -15901,17 +16289,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16237,7 +16625,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16368,13 +16756,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments - + Copy RetroShare Link @@ -16384,7 +16772,7 @@ p, li { white-space: pre-wrap; } - + Comment Коментар @@ -16405,12 +16793,12 @@ p, li { white-space: pre-wrap; } - + Hide Сакриј - + Vote up @@ -16420,7 +16808,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16481,7 +16869,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16515,13 +16903,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16531,60 +16913,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16595,7 +16967,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16664,7 +17036,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16699,7 +17076,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16815,8 +17192,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17084,12 +17471,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17104,17 +17486,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17139,10 +17536,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17152,13 +17559,48 @@ and use the import button to load it - + + Post + + + + Cancel Поништи - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17177,10 +17619,18 @@ and use the import button to load it Образац - - - - + + + + + Click to view picture + + + + + + + Image @@ -17188,44 +17638,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17235,17 +17685,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17255,7 +17705,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17263,7 +17713,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17278,7 +17728,7 @@ and use the import button to load it - + follow Parent Group @@ -17288,7 +17738,7 @@ and use the import button to load it … - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17313,7 +17763,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17349,29 +17799,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17449,7 +17899,7 @@ and use the import button to load it QObject - + Confirmation @@ -17688,7 +18138,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17723,7 +18173,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17861,7 +18311,7 @@ Reported error is: - + TR up @@ -17906,7 +18356,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17922,7 +18372,7 @@ Reported error is: - + %1 seconds ago @@ -18006,7 +18456,7 @@ Security: no anonymous IDs - + Error @@ -18396,11 +18846,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18734,7 +19179,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18956,18 +19401,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19404,7 +19870,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19419,7 +19885,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19467,7 +19933,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Сачувај - + Collection Editor @@ -19482,7 +19948,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19497,12 +19963,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19749,7 +20215,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Ðазив @@ -19769,7 +20235,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19782,10 +20248,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19797,7 +20268,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19835,7 +20306,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19843,7 +20314,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19903,7 +20374,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20257,7 +20728,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20336,7 +20807,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20356,7 +20827,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20461,12 +20932,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20476,7 +20947,7 @@ prevents the message to be forwarded to your friends. - + Expand Прошири @@ -20739,13 +21210,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21211,7 +21682,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21239,7 +21710,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21336,7 +21807,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21371,12 +21842,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22041,7 +22512,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22083,7 +22554,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22139,7 +22610,7 @@ This choice can be reverted in settings. - + DHT @@ -22671,7 +23142,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22681,13 +23152,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22696,6 +23166,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22969,27 +23464,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22997,7 +23487,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23008,7 +23498,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Ðазив @@ -23215,7 +23705,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23309,7 +23799,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23441,7 +23931,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23452,7 +23942,7 @@ p, li { white-space: pre-wrap; } - + Path Путања @@ -23462,7 +23952,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23472,7 +23962,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23487,7 +23977,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23729,7 +24219,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23825,7 +24315,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24193,7 +24683,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24287,8 +24777,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24299,7 +24789,7 @@ p, li { white-space: pre-wrap; } - + Preview Преглед @@ -24324,12 +24814,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24349,7 +24839,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24387,7 +24877,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24397,12 +24887,11 @@ p, li { white-space: pre-wrap; } - ... - … + … - + Refresh @@ -24437,12 +24926,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24472,7 +24961,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24482,7 +24971,7 @@ p, li { white-space: pre-wrap; } - + RetroShare Ретрошер @@ -24494,7 +24983,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24502,7 +24991,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24583,8 +25072,8 @@ p, li { white-space: pre-wrap; } Образац - - + + Avatar @@ -24613,6 +25102,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24725,7 +25219,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_sv.ts b/retroshare-gui/src/lang/retroshare_sv.ts index 30831234a..3bdd3ebc7 100644 --- a/retroshare-gui/src/lang/retroshare_sv.ts +++ b/retroshare-gui/src/lang/retroshare_sv.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -128,12 +128,12 @@ RetroShare: Avancerad sökning - + Search Criteria Sökkriterium - + Add a further search criterion. Lägg till ytterligare sökkriterium. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Formulär - - + + TextLabel Bildtext @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Verktygsfält - + Icon Only Endast ikon @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 Ikonstorlek = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Ikonstorlek = 128x128 - + Status Bar Statusfält @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Ikonstorlek = 32x32 @@ -827,14 +827,23 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot Byt profilbild - + + TextLabel + + + + Your Avatar Picture Din profilbild - + + Browse... + + + Add Avatar - Lägg till profilbild + Lägg till profilbild @@ -842,25 +851,34 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot Ta bort - + Set your Avatar picture Lägg till din probild - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Läs in profilbild + Läs in profilbild AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klicka för att ändra din profilbild @@ -868,7 +886,7 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot RetroShare Bandwidth Usage RetroShare bandbreddsanvändning + + + PushButton + + - + Up + Upp + + + + Down + Ner + + + + Clears the graph + + + + Show Settings Visa inställningar + TextLabel + + + + Reset Ã…terställ - Receive Rate - Mottagningshastighet + Mottagningshastighet - Send Rate - Sändningshastighet + Sändningshastighet - + Always on Top Alltid överst - Style - Stil + Stil - + Changes the transparency of the Bandwidth Graph Ändrar transparensen pÃ¥ bandbreddsgrafen - + 100 100 @@ -935,30 +974,27 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot % Opak - Save - Spara + Spara - Cancel - Avbryt + Avbryt - + Since: Sedan: - Hide Settings - Dölj inställningar + Dölj inställningar BandwidthStatsWidget - + Sum @@ -980,7 +1016,7 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot Antal - + Average Medel @@ -1114,7 +1150,7 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot - + Comments Kommentarer @@ -1192,6 +1228,85 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot + + BoardsCommentsItem + + + I like this + Jag gillar detta + + + + 0 + 0 + + + + I dislike this + Jag gillar inte detta + + + + Toggle Message Read Status + Växla meddelandestatus + + + + Avatar + Profilbild + + + + New Comment + + + + + Copy RetroShare Link + Kopiera RetroShare-länk + + + + + Expand + + + + + Set as read and remove item + Markera som läst och ta bort objektet + + + + Remove Item + Ta bort objektet + + + + Name + Namn + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Dölj + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Kom bara ihÃ¥g... all data här, *KOMMER* att förloras när vi uppgraderar prot Log scale + + + Default + Standard + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Jag gillar detta + + + + 0 + 0 + + + + I dislike this + Jag gillar inte detta + + + + Toggle Message Read Status + Växla meddelandestatus + + + + Avatar + Profilbild + + + + New Comment + + + + + Copy RetroShare Link + Kopiera RetroShare-länk + + + + + Expand + + + + + Set as read and remove item + Markera som läst och ta bort objektet + + + + Remove Item + Ta bort objektet + + + + Name + Namn + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Dölj + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to - You have %1 new messages - Du har %1 nya meddelanden + Du har %1 nya meddelanden + + + You have %1 new message + Du har %1 nytt meddelande + + + %1 new messages + %1 nya meddelanden + + + %1 new message + %1 nytt meddelande + + + + You have %1 mentions + - You have %1 new message - Du har %1 nytt meddelande + You have %1 mention + - %1 new messages - %1 nya meddelanden + %1 mentions + - %1 new message - %1 nytt meddelande + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Ta bort alla - - - mention(s) - - ChatLobbyWidget @@ -2097,13 +2312,11 @@ Double click a chat room to enter and chat. - Group chat - Gruppchatt + Gruppchatt - - + Private chat Privatchatt @@ -2168,17 +2381,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - Chatlobbies - Chatlobbyn + Chatlobbyn - + Enabled: Aktiverad: @@ -2199,11 +2411,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2264,11 +2477,17 @@ Double click a chat room to enter and chat. + Broadcast Sändning - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Sparade meddelanden (0 = obegränsat) @@ -2411,8 +2630,23 @@ Double click a chat room to enter and chat. Privatchatt - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2581,7 +2815,7 @@ Double click a chat room to enter and chat. - + is typing... skriver... @@ -2598,12 +2832,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Vill du verkligen ta bort historiken? @@ -2675,7 +2909,7 @@ after HTML conversion. Sluta inte att färga efter X hittade (använder mer CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2715,12 +2949,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2736,7 +2970,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2756,7 +2990,7 @@ Double click on it to add his name on text writer. Skriv ett meddelande här - + Don't stop to color after @@ -2914,12 +3148,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaljer - + Local Address Lokal adress @@ -2930,12 +3164,12 @@ Double click on it to add his name on text writer. Extern adress - + Node info: - + Current address: @@ -2951,31 +3185,41 @@ Double click on it to add his name on text writer. Port - + Include signatures Inkludera signaturer - + RetroShare RetroShare - + - + Error : cannot get peer details. Fel: Kan inte hämta användaruppgifter. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2991,22 +3235,22 @@ Double click on it to add his name on text writer. - + Encryption Kryptering - + Not connected Inte ansluten - + Retroshare node details - + Node name : Nodnamn : @@ -3041,13 +3285,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Retroshare-certifikat @@ -3062,7 +3311,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3073,17 +3322,22 @@ Double click on it to add his name on text writer. ingen - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3093,7 +3347,7 @@ Double click on it to add his name on text writer. - + with med @@ -3285,12 +3539,12 @@ Double click on it to add his name on text writer. Fakta om begäran - + Peer details Användarinformation - + Name: Namn: @@ -3303,22 +3557,22 @@ Double click on it to add his name on text writer. Nod: - + Location: Plats: - + Options Alternativ - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Lägg till kontakt till grupp: @@ -3328,7 +3582,7 @@ Double click on it to add his name on text writer. Autentisera kontakt (Signera PGP-nyckel) - + Please paste below your friend's Retroshare ID @@ -3353,7 +3607,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Lägg till en kontakt att ansluta till @@ -3362,7 +3616,7 @@ Double click on it to add his name on text writer. Klicka pÃ¥ 'Slutför' för att acceptera denna kontaktförfrÃ¥gan - + Sorry, some error appeared NÃ¥got fel uppstod @@ -3382,32 +3636,32 @@ Double click on it to add his name on text writer. Fakta om din kontakt: - + Key validity: Nyckelvaliditet: - + Profile ID: - + Signers Signerad av: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Denna användare finns redan pÃ¥ din kontaktlista. Att lägga till den kanske bara anger IP-adress. - + To accept the Friend Request, click the Accept button. @@ -3453,7 +3707,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Certifikatinläsning misslyckades @@ -3486,12 +3740,12 @@ Double click on it to add his name on text writer. Användar-ID - + Not a valid Retroshare certificate! - + RetroShare Invitation RetroShare-inbjudan @@ -3511,12 +3765,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3564,7 +3818,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du har en kontaktförfrÃ¥gan frÃ¥n - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3652,12 +3936,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Använd som direkt källa, om tillgänglig - + IP-Addr: - + IP-Address IP-adress @@ -3715,7 +3999,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Lägg till nyckel till nyckelring - + This key is already in your keyring Den här nyckeln finns redan i din nyckelring @@ -3773,12 +4057,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3853,7 +4137,12 @@ even if you don't make friends. UDP Resultat - + + Status + Status + + + <!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; } @@ -4275,7 +4564,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4423,7 +4712,7 @@ p, li { white-space: pre-wrap; } Inga cirkel begränsningar valda - + [Unknown] @@ -4438,7 +4727,7 @@ p, li { white-space: pre-wrap; } Ta bort - + Search Sök @@ -4458,7 +4747,7 @@ p, li { white-space: pre-wrap; } Signerad av kända noder - + Edit Circle Editera cirkeln @@ -4478,12 +4767,12 @@ p, li { white-space: pre-wrap; } Anonymt Id - + Circle name - + Update @@ -4509,7 +4798,7 @@ p, li { white-space: pre-wrap; } PGP-länkat ID - + Add Member @@ -4653,7 +4942,7 @@ p, li { white-space: pre-wrap; } - + Attachments Bilagor @@ -4699,7 +4988,7 @@ p, li { white-space: pre-wrap; } Dra och släpp filer frÃ¥n sökresultat - + Paste RetroShare Links Klistra in RetroShare-länkar @@ -4709,7 +4998,7 @@ p, li { white-space: pre-wrap; } Klistra in RetroShare-länk - + Drop file error. Dra & släpp-fel @@ -4736,17 +5025,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Filen är redan tillagd och hash-beräknad + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Filen är redan tillagd och hash-beräknad + + + Please add a Subject Ange ett ämne @@ -4777,12 +5090,12 @@ p, li { white-space: pre-wrap; } Vill du verkligen generera %1 meddelanden? - + You are about to add files you're not actually sharing. Do you still want this to happen? Du är pÃ¥ väg att lägga till filer som du inte delar. Vill du verkligen fortsätta? - + Edit Channel Post @@ -4802,7 +5115,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Om att posta icke delade filer till en kanal @@ -4894,7 +5207,7 @@ p, li { white-space: pre-wrap; } - + No Forum Inga forum @@ -5349,7 +5662,7 @@ och där läsa in den med importfunktionen. DHTGraphSource - + users användare @@ -6352,7 +6665,7 @@ och där läsa in den med importfunktionen. FlatStyle_RDM - + Friends Directories Kontakters mappar @@ -6847,7 +7160,7 @@ at least one peer was not added to a group Sök kontakter - + Mark all Markera alla @@ -6861,7 +7174,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Redigera statusmeddelande @@ -6965,7 +7278,7 @@ at least one peer was not added to a group Retroshare utsändningschat: meddelanden skickas till alla anslutna vänner. - + Network Nätverk @@ -7030,7 +7343,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7061,7 +7374,7 @@ at least one peer was not added to a group - + Node name @@ -7324,12 +7637,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7701,7 +8014,7 @@ p, li { white-space: pre-wrap; } Router-statistik - + GroupBox @@ -7766,7 +8079,7 @@ p, li { white-space: pre-wrap; } - + Details Detaljer @@ -7789,7 +8102,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Hanterade nycklar @@ -7990,7 +8303,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8000,13 +8313,30 @@ p, li { white-space: pre-wrap; } Sök titel - - + + + + Description Beskrivning - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Sök beskrivning @@ -8016,42 +8346,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sortera efter namn + Sortera efter namn - Sort by Popularity - Sortera efter popularitet + Sortera efter popularitet - Sort by Last Post - Sortera efter senaste inlägg + Sortera efter senaste inlägg - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8066,40 +8373,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Senaste inlägget - + + Name Namn - - Unread - - - - + Popularity Popularitet - - + + Never - Display - Visa + Visa - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8248,7 +8550,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanaler @@ -8269,12 +8571,12 @@ p, li { white-space: pre-wrap; } Mina kanaler - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Kanalabonnemang @@ -8739,7 +9041,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8839,12 +9141,12 @@ p, li { white-space: pre-wrap; } - + Files Filer - + Comments Kommentarer @@ -8855,18 +9157,18 @@ p, li { white-space: pre-wrap; } - + Feeds Flöden - - + + Click to switch to list view - + Show unread posts only @@ -8876,12 +9178,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8941,7 +9243,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8956,12 +9258,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9037,23 +9339,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Prenumererat - - Subscribe Prenumerera - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Inga kanaler markerade @@ -9075,11 +9390,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanalinlägg - - - new message(s) - - GxsCircleItem @@ -9597,7 +9907,7 @@ innan du kan kommentera Starta ny trÃ¥d i aktuellt forum - + Search forums Sök i forum @@ -9606,12 +9916,12 @@ innan du kan kommentera Senaste inlägget - + New Thread Ny trÃ¥d - + Threaded View TrÃ¥dvy @@ -9621,19 +9931,19 @@ innan du kan kommentera Platt vy - - + + Title Rubrik - - + + Date Datum - + Author Författare @@ -9648,7 +9958,17 @@ innan du kan kommentera Läser in - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9705,23 +10025,23 @@ innan du kan kommentera SökinnehÃ¥ll - + No name Inget namn - - + + Reply Svara - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9759,12 +10079,12 @@ innan du kan kommentera Markera som oläst - + Copy RetroShare Link Kopiera RetroShare-länk - + Hide Dölj @@ -9773,7 +10093,7 @@ innan du kan kommentera Expandera - + [unknown] @@ -9803,8 +10123,8 @@ innan du kan kommentera - - + + Distribution @@ -9903,12 +10223,12 @@ innan du kan kommentera Originalmeddelande - + New thread - + Edit Redigera @@ -9964,7 +10284,7 @@ innan du kan kommentera - + Author's reputation @@ -9984,7 +10304,7 @@ innan du kan kommentera - + <b>Loading...<b> @@ -10024,6 +10344,11 @@ innan du kan kommentera Storage + + + Last seen at friends: + + Moderators @@ -10091,7 +10416,7 @@ This message is missing. You should receive it later. I %1, skrev %2: - + Forum name Forumnamn @@ -10123,11 +10448,6 @@ This message is missing. You should receive it later. Forum Post Foruminlägg - - - new message(s) - - GxsForumsDialog @@ -10572,7 +10892,7 @@ This message is missing. You should receive it later. Förhandsgranskning - + Unsubscribe Avsluta prenumerationen @@ -10587,7 +10907,7 @@ This message is missing. You should receive it later. Öppna i ny flik - + Remove this search @@ -10597,12 +10917,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Visa detaljer @@ -10669,12 +10989,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopiera RetroShare-länk @@ -10689,7 +11009,7 @@ This message is missing. You should receive it later. Markera alla som olästa - + AUTHD AUTHD @@ -11215,7 +11535,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11224,7 +11544,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11250,7 +11570,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11328,49 +11648,55 @@ p, li { white-space: pre-wrap; } Formulär - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopiera certifikatet till Urklipp @@ -11418,17 +11744,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11443,7 +11764,12 @@ new short format RetroShare-inbjudan - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Spara som... @@ -11708,14 +12034,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alla - + Reputation Rykte @@ -11725,12 +12051,12 @@ p, li { white-space: pre-wrap; } Sök - + Anonymous Id Anonymt Id - + Create new Identity Skapa ny identitet @@ -11874,7 +12200,7 @@ p, li { white-space: pre-wrap; } Identitets-ID - + Send message Skicka meddelande @@ -11946,7 +12272,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonym @@ -11961,24 +12287,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11993,7 +12319,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12052,13 +12378,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12118,7 +12449,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Editera cirkeln @@ -12166,7 +12497,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12175,12 +12506,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12192,12 +12523,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12313,17 +12644,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12480,8 +12811,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12492,7 +12823,7 @@ These identities will soon be not supported anymore. Din avatar - + Linked to neighbor nodes @@ -12502,7 +12833,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12562,7 +12893,7 @@ These identities will soon be not supported anymore. Ägd av - + Node name: Nodnamn: @@ -12572,7 +12903,7 @@ These identities will soon be not supported anymore. Nod-ID : - + Really delete? @@ -12610,7 +12941,22 @@ These identities will soon be not supported anymore. Pseudonym - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Ny identitet @@ -12627,14 +12973,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity Editera identitet @@ -12645,24 +12991,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12681,17 +13030,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Ett fel uppstod vid hämtning av nyckeln! - + Error KeyID invalid Fel NyckelID felaktigt - + Unknown GpgId Okänt GpgId @@ -12701,7 +13060,7 @@ These identities will soon be not supported anymore. Okänt riktigt namn - + Create New Identity Skapa ny Identitet @@ -12711,7 +13070,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12751,12 +13115,7 @@ These identities will soon be not supported anymore. Din avatar - - Set Avatar - - - - + Linked to your profile @@ -12766,7 +13125,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12875,8 +13234,12 @@ These identities will soon be not supported anymore. + Quote + Citera + + Send - Skicka + Skicka @@ -13034,7 +13397,7 @@ These identities will soon be not supported anymore. - + Options Alternativ @@ -13066,12 +13429,12 @@ These identities will soon be not supported anymore. Snabbstartsguide - + RetroShare %1 a secure decentralized communication platform RetroShare %1 en säker, decentraliserad kommunikationsplattform - + Unfinished PÃ¥gÃ¥ende @@ -13204,7 +13567,7 @@ Frigör mer diskutrymme och klicka OK. Visa - + Make sure this link has not been forged to drag you to a malicious website. Tillse att den här länken inte leder till en webbsida med skadlig kod. @@ -13249,7 +13612,7 @@ Frigör mer diskutrymme och klicka OK. TjänstÃ¥tkomstmatrix - + Statistics Statistik @@ -13278,7 +13641,7 @@ Frigör mer diskutrymme och klicka OK. MessageComposer - + Compose Skriv @@ -13380,7 +13743,7 @@ Frigör mer diskutrymme och klicka OK. - + Tags Taggar @@ -13475,12 +13838,12 @@ Frigör mer diskutrymme och klicka OK. Lägg till blockcitat - + Send To: Skicka till: - + &Left &Vänster @@ -13510,7 +13873,12 @@ Frigör mer diskutrymme och klicka OK. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hej! Jag rekommenderar mina kontakter. Du kan autentisera dem ocksÃ¥, när du autentiserar mig. @@ -13536,12 +13904,12 @@ Frigör mer diskutrymme och klicka OK. - + Save Message Spara meddelande - + Message has not been Sent. Do you want to save message to draft box? Meddelandet har inte skickats. @@ -13553,7 +13921,7 @@ Vill du spara meddelandet i Utkast? Klistra in RetroShare-länk - + Add to "To" Lägg till i "Till" @@ -13808,7 +14176,7 @@ Vill du spara meddelandet? Lägg till fil - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13822,6 +14190,21 @@ Vill du spara meddelandet? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13834,7 +14217,7 @@ Vill du spara meddelandet? FrÃ¥n: - + Bullet list (disc) @@ -13874,13 +14257,13 @@ Vill du spara meddelandet? - - + + Thanks, <br> - + Distant identity: @@ -14019,8 +14402,23 @@ Vill du spara meddelandet? Meddelande - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14032,12 +14430,12 @@ Vill du spara meddelandet? Rekommenderade filer - + Download all Recommended Files Ladda ner alla rekommenderade filer - + Subject: Ämne: @@ -14112,12 +14510,18 @@ Vill du spara meddelandet? - + + Message Size: + + + + File Name Filnamn - + + Size Storlek @@ -14178,18 +14582,33 @@ Vill du spara meddelandet? Ladda ner - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Ladda ner alla - + Print Document Skriv ut dokument @@ -14204,7 +14623,7 @@ Vill du spara meddelandet? HTML-filer (*.htm *.html);;Alla Filer (*) - + Load images always for this message Ladda alltid bilder för detta meddelande @@ -14345,7 +14764,7 @@ Vill du spara meddelandet? MessagesDialog - + New Message Nytt meddelande @@ -14401,14 +14820,14 @@ Vill du spara meddelandet? - + Tags Taggar - + Inbox Inkorg @@ -14503,7 +14922,7 @@ Vill du spara meddelandet? Vidarebefordra meddelande - + Subject Ämne @@ -14615,7 +15034,7 @@ Vill du spara meddelandet? - + Open in a new window Öppna i nytt fönster @@ -14700,7 +15119,7 @@ Vill du spara meddelandet? - + Drafts Utkast @@ -14821,7 +15240,7 @@ Vill du spara meddelandet? Svarsmeddelande - + Delete Message Ta bort meddelande @@ -14832,7 +15251,7 @@ Vill du spara meddelandet? - + Expand Expandera @@ -14842,7 +15261,7 @@ Vill du spara meddelandet? Ta bort objektet - + from FrÃ¥n @@ -14851,6 +15270,11 @@ Vill du spara meddelandet? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15164,7 +15588,7 @@ Reported error: - + Groups Grupper @@ -15194,19 +15618,19 @@ Reported error: importera din vänlista inklusive grupper - - + + Search Sök - + ID ID - + Search ID @@ -15216,7 +15640,7 @@ Reported error: - + Show Items @@ -15415,18 +15839,18 @@ at least one peer was not added to a group - + Error Fel - + File is not writeable! - + File is not readable! @@ -15464,7 +15888,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15482,7 +15906,7 @@ at least one peer was not added to a group Detta är ett test. - + Newest on top @@ -15493,20 +15917,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15543,22 +15982,22 @@ at least one peer was not added to a group - + Test Testa - + Chat Room - + Systray Icon Meddelandefältsikon - + Message Meddelande @@ -15583,12 +16022,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Kontakten anslöt @@ -15635,27 +16069,37 @@ at least one peer was not added to a group Gruppchatt - + + Toaster position + + + + Chat rooms - + Position Placering - + + Activity + + + + X Margin X-marginal - + Y Margin Y-marginal - + Systray message Systemmeddelande @@ -15705,7 +16149,7 @@ at least one peer was not added to a group Underrättelser - + Disable All Toasters @@ -15719,7 +16163,7 @@ at least one peer was not added to a group Flöde - + Systray @@ -15861,17 +16305,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : Namn : @@ -15926,22 +16365,17 @@ at least one peer was not added to a group FörbehÃ¥llslöst - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15955,7 +16389,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15965,22 +16399,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Signera GPG-nyckel + Signera GPG-nyckel - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16000,7 +16428,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16066,27 +16494,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Fel: Kan inte hämta användaruppgifter. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Angiven nyckelalgoritm stöds inte av RetroShare. (För tillfället stöds endast RSA-nycklar) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16098,7 +16526,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16143,27 +16571,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Signatur misslyckades - - Maybe password is wrong - Lösenordet kanske är fel + + Check the password! + - + Maybe password is wrong + Lösenordet kanske är fel + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16342,8 +16790,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16360,7 +16807,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16503,7 +16950,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Bild - + TextLabel Bildtext @@ -16547,8 +16994,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Kommentarer @@ -16583,6 +17030,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Skriv en kommentar... + + + Album + Album + PhotoItem @@ -16592,12 +17044,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulär - + TextLabel Bildtext - + <!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; } @@ -16693,7 +17145,7 @@ p, li { white-space: pre-wrap; } Visa bild - + PhotoShare Bilddelning @@ -16734,7 +17186,7 @@ före redigering! - + Stop Stopp @@ -16962,12 +17414,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins TillÃ¥t alla insticksprogram - + Plugin look-up directories Mappar med insticksprogram @@ -17010,7 +17462,7 @@ fall görs som skydd mot skadligt beteende frÃ¥n felaktigt utformade insticksprogram. - + Plugins Insticksprogram @@ -17380,7 +17832,7 @@ felaktigt utformade insticksprogram. Andra rubriker - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17539,13 +17991,13 @@ felaktigt utformade insticksprogram. Webbplats - - + + Comments Kommentarer - + Copy RetroShare Link Kopiera RetroShare-länk @@ -17555,7 +18007,7 @@ felaktigt utformade insticksprogram. - + Comment Kommentar @@ -17576,12 +18028,12 @@ felaktigt utformade insticksprogram. - + Hide Dölj - + Vote up @@ -17595,7 +18047,7 @@ felaktigt utformade insticksprogram. \/ - + Set as read and remove item Markera som läst och ta bort objektet @@ -17656,7 +18108,7 @@ felaktigt utformade insticksprogram. - + Loading Läser in @@ -17738,13 +18190,7 @@ felaktigt utformade insticksprogram. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17754,60 +18200,50 @@ felaktigt utformade insticksprogram. - - - + + + unknown okänd - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17818,7 +18254,7 @@ felaktigt utformade insticksprogram. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17887,7 +18323,12 @@ felaktigt utformade insticksprogram. - + + Empty + + + + Copy RetroShare Link Kopiera RetroShare-länk @@ -17922,7 +18363,7 @@ felaktigt utformade insticksprogram. - + [No name] @@ -18046,8 +18487,18 @@ felaktigt utformade insticksprogram. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18319,9 +18770,8 @@ och där läsa in den med importfunktionen. PulseAddDialog - Post From: - Inlägg frÃ¥n: + Inlägg frÃ¥n: Account 1 @@ -18336,7 +18786,7 @@ och där läsa in den med importfunktionen. Konto 3 - + Add to Pulse Lägg till i Pulse @@ -18359,17 +18809,32 @@ och där läsa in den med importfunktionen. URL - + GroupLabel - + IDLabel - + + From: + FrÃ¥n: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18394,10 +18859,20 @@ och där läsa in den med importfunktionen. Negativ - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18407,14 +18882,53 @@ och där läsa in den med importfunktionen. - + + Post + + + + Cancel Avbryt - Post Pulse to Wire - Posta Pulse till Wire + Posta Pulse till Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18440,10 +18954,18 @@ och där läsa in den med importfunktionen. Formulär - - - - + + + + + Click to view picture + + + + + + + Image Bild @@ -18451,44 +18973,44 @@ och där läsa in den med importfunktionen. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18498,17 +19020,17 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18518,7 +19040,7 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18526,7 +19048,7 @@ och där läsa in den med importfunktionen. PulseTopLevel - + retweeted @@ -18541,7 +19063,7 @@ och där läsa in den med importfunktionen. - + follow Parent Group @@ -18551,7 +19073,7 @@ och där läsa in den med importfunktionen. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18576,7 +19098,7 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18612,29 +19134,29 @@ och där läsa in den med importfunktionen. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18712,7 +19234,7 @@ och där läsa in den med importfunktionen. QObject - + Confirmation Bekräftelse @@ -18954,7 +19476,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> kommer att ersätt Resultat - + Unable to make path Kunde inte skapa sökväg @@ -18989,7 +19511,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> kommer att ersätt Filbegäran avbruten - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Denna version av RetroShare använder OpenPGP-SDK. Som sidoeffekt använder den inte systemets delade PGP-nyckelring, utan har sin egen nyckelring som delas av alla RetroShare-instanser. <br><br>Du verkar inte ha nÃ¥gon sÃ¥dan nyckelring, även om GPG-nycklar associeras med befintliga RetroShare-konton, troligen för att du just uppgraderat till denna nya version av programmet. @@ -19130,7 +19652,7 @@ Rapporterat fel är: %2 sek - + TR up @@ -19175,7 +19697,7 @@ Rapporterat fel är: %2 - + Move IP %1 to whitelist @@ -19191,7 +19713,7 @@ Rapporterat fel är: %2 - + %1 seconds ago @@ -19275,7 +19797,7 @@ Security: no anonymous IDs - + Error Fel @@ -19665,11 +20187,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -20039,7 +20556,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20261,18 +20778,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20709,7 +21247,7 @@ p, li { white-space: pre-wrap; } Ladda ner! - + File Fil @@ -20724,7 +21262,7 @@ p, li { white-space: pre-wrap; } Hash-summa - + Bad filenames have been cleaned DÃ¥liga filnamn har rensats @@ -20774,7 +21312,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos Spara - + Collection Editor @@ -20789,7 +21327,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos - + Real Size: Waiting child... @@ -20804,12 +21342,12 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos - + Download files - + Specify... Specificera @@ -21058,7 +21596,7 @@ Om du tror att den är giltig, ta bort strängen frÃ¥n filen och öppna den pÃ¥ RsFriendListModel - + Name Namn @@ -21078,7 +21616,7 @@ Om du tror att den är giltig, ta bort strängen frÃ¥n filen och öppna den pÃ¥ IP - + Profile ID @@ -21091,10 +21629,15 @@ Om du tror att den är giltig, ta bort strängen frÃ¥n filen och öppna den pÃ¥ RsGxsForumModel - + Title + + + UnRead + + Date @@ -21106,7 +21649,7 @@ Om du tror att den är giltig, ta bort strängen frÃ¥n filen och öppna den pÃ¥ - + Information for this identity is currently missing. @@ -21144,7 +21687,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Meddelande saknas ... ] @@ -21152,7 +21695,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21212,7 +21755,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21571,7 +22114,7 @@ prevents the message to be forwarded to your friends. Filnamn - + Download Ladda ner @@ -21650,7 +22193,7 @@ prevents the message to be forwarded to your friends. Öppna mapp - + Create Collection... Skapa samling... @@ -21670,7 +22213,7 @@ prevents the message to be forwarded to your friends. Ladda ner frÃ¥n samlingsfil... - + Collection Samling @@ -21775,12 +22318,12 @@ prevents the message to be forwarded to your friends. Användarinformation - + Deny friend Avvisa kontakt - + Chat Chatt @@ -21790,7 +22333,7 @@ prevents the message to be forwarded to your friends. Starta chatt - + Expand Expandera @@ -22060,13 +22603,13 @@ bra om du sitter bakom en brandvägg eller en VPN-tunnel. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22532,7 +23075,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Nätverk @@ -22560,7 +23103,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22657,7 +23200,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22692,12 +23235,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23365,7 +23908,7 @@ p, li { white-space: pre-wrap; } PGP-certifikat saknas - + Wrong password @@ -23407,7 +23950,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Lägg till kontakt @@ -23463,7 +24006,7 @@ This choice can be reverted in settings. TjänstÃ¥tkomstmatrix - + DHT DHT @@ -24003,7 +24546,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24013,13 +24556,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24028,6 +24570,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24301,35 +24868,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Du har %1 slutförda nedladdningar + You have %1 completed transfers + - You have %1 completed download - Du har %1 slutförd nedladdning + You have %1 completed transfer + - %1 completed downloads - %1 slutförda nedladdningar + %1 completed transfers + - %1 completed download - %1 slutförd nedladdning + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Du har %1 slutförda nedladdningar + + + You have %1 completed download + Du har %1 slutförd nedladdning + + + %1 completed downloads + %1 slutförda nedladdningar + + + %1 completed download + %1 slutförd nedladdning TransfersDialog - + Downloads Nerladdningar @@ -24340,7 +24918,7 @@ p, li { white-space: pre-wrap; } Uppladdningar - + Name i.e: file name Namn @@ -24547,7 +25125,7 @@ p, li { white-space: pre-wrap; } Specificera - + Move in Queue... Flytta i kön... @@ -24641,7 +25219,7 @@ p, li { white-space: pre-wrap; } Ange nytt giltigt filnamn - + Expand all Expandera alla @@ -24773,7 +25351,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolumner @@ -24784,7 +25362,7 @@ p, li { white-space: pre-wrap; } Filöverföringar - + Path Sökväg @@ -24794,7 +25372,7 @@ p, li { white-space: pre-wrap; } Visa Väg-kolumn - + Could not delete preview file @@ -24804,7 +25382,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... Skapa samling... @@ -24819,7 +25397,7 @@ p, li { white-space: pre-wrap; } Visa samling... - + Collection Samling @@ -25061,7 +25639,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Okänd användare @@ -25157,7 +25735,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Du har %1 nya meddelanden @@ -25529,7 +26107,7 @@ p, li { white-space: pre-wrap; } Skapa grupp - + Subscribe to Group Prenumerera pÃ¥ grupp @@ -25623,8 +26201,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Visa redigeringshistorik @@ -25635,7 +26213,7 @@ p, li { white-space: pre-wrap; } - + Preview Förhandsgranskning @@ -25660,12 +26238,12 @@ p, li { white-space: pre-wrap; } Dölj redigeringshistorik - + Edit Page Redigera sida - + Create New Wiki Page Skapa nya Wiki-sida @@ -25685,7 +26263,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Skapa nya Wiki-grupp @@ -25727,7 +26305,7 @@ p, li { white-space: pre-wrap; } Tidsintervall - + Create Account @@ -25737,12 +26315,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Uppdatera @@ -25777,12 +26354,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25852,7 +26429,7 @@ p, li { white-space: pre-wrap; } Visar: - + Yourself Du själv @@ -25890,7 +26467,7 @@ p, li { white-space: pre-wrap; } Posta Pulse till Wire - + RetroShare RetroShare @@ -25902,7 +26479,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -25910,7 +26487,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25991,8 +26568,8 @@ p, li { white-space: pre-wrap; } Formulär - - + + Avatar Profilbild @@ -26021,6 +26598,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26133,7 +26715,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_tr.ts b/retroshare-gui/src/lang/retroshare_tr.ts index 78be8b683..b0d731573 100644 --- a/retroshare-gui/src/lang/retroshare_tr.ts +++ b/retroshare-gui/src/lang/retroshare_tr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare sürümü @@ -79,7 +79,7 @@ Keyfinize bakın ;-) - + Only Hidden Node Yalnızca Gizli Düğüm @@ -129,12 +129,12 @@ RetroShare: GeliÅŸmiÅŸ Arama - + Search Criteria Arama Ölçütü - + Add a further search criterion. BaÅŸka bir arama ölçütü ekler. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Albüm @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Form - - + + TextLabel Metin Etiketi @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Araç ÇubuÄŸu - + Icon Only Yalnız Simge @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Araç düğmelerinin biçemini seçin. - + Icon Size = 8x8 Simge Boyutu = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Simge Boyutu = 128x128 - + Status Bar Durum ÇubuÄŸu @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Sistem Tepsisi Ä°pucu Kullanılmasın - + Main page items: Ana sayfa ögeleri: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Öge listesi - + Icon Size = 32x32 Simge Boyutu = 32x32 @@ -828,14 +828,23 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Avatarı DeÄŸiÅŸtir - + + TextLabel + Metin Etiketi + + + Your Avatar Picture Avatar Görseliniz - + + Browse... + + + Add Avatar - Avatar Ekle + Avatar Ekle @@ -843,25 +852,34 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Sil - + Set your Avatar picture Avatar görselinizi ayarlayın - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatar Yükle + Avatar Yükle AvatarWidget - - Choose avatar - - - - + Click to change your avatar Avatarınızı deÄŸiÅŸtirmek için tıklayın @@ -869,7 +887,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim RetroShare Bandwidth Usage RetroShare Bant GeniÅŸliÄŸi Kullanımı + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Ayarlara Bakın + TextLabel + Metin Etiketi + + + Reset Sıfırlayın - Receive Rate - Alma Hızı + Alma Hızı - Send Rate - Gönderme Hızı + Gönderme Hızı - + Always on Top Her zaman üstte - Style - Biçem + Biçem - + Changes the transparency of the Bandwidth Graph Bant geniÅŸliÄŸi grafiÄŸinin saydamlığını ayarlar - + 100 100 @@ -936,30 +975,27 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim % Mat - Save - Kaydedin + Kaydedin - Cancel - Ä°ptal + Ä°ptal - + Since: BaÅŸlangıç: - Hide Settings - Ayarlar Gizlensin + Ayarlar Gizlensin BandwidthStatsWidget - + Sum Toplam @@ -981,7 +1017,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Sayı - + Average Ortalama @@ -1115,7 +1151,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Metin Etiketi - + Comments Yorumlar @@ -1193,6 +1229,85 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Metin Etiketi + + BoardsCommentsItem + + + I like this + BeÄŸendim + + + + 0 + 0 + + + + I dislike this + BeÄŸenmedim + + + + Toggle Message Read Status + Ä°leti Okundu Durumunu DeÄŸiÅŸtir + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + GeniÅŸlet + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ad + + + + Comm value + + + + + Comment + + + + + Comments + Yorumlar + + + + Hide + Gizle + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Unutmayın: Buradaki herhangi bir bilgi, iletiÅŸim kurallarını güncellediÄŸim Log scale Günlük ÖlçeÄŸi + + + Default + + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + BeÄŸendim + + + + 0 + 0 + + + + I dislike this + BeÄŸenmedim + + + + Toggle Message Read Status + Ä°leti Okundu Durumunu DeÄŸiÅŸtir + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + GeniÅŸlet + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ad + + + + Comm value + + + + + Comment + + + + + Comments + Yorumlar + + + + Hide + Gizle + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Sohbetler - You have %1 new messages - %1 yeni iletiniz var + %1 yeni iletiniz var + + + You have %1 new message + %1 yeni iletiniz var + + + %1 new messages + %1 yeni ileti + + + %1 new message + %1 yeni ileti + + + + You have %1 mentions + - You have %1 new message - %1 yeni iletiniz var + You have %1 mention + - %1 new messages - %1 yeni ileti + %1 mentions + - %1 new message - %1 yeni ileti + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Tümünü Kaldır - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Odaya katılıp sohbet etmek için çift tıklayın. ÇeÅŸit: - Group chat - Grup Sohbeti + Grup Sohbeti - - + Private chat Özel sohbet @@ -2191,17 +2404,16 @@ Odaya katılıp sohbet etmek için çift tıklayın. /me ÅŸununla bir ileti gönderiyorum /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Farklı sohbet sistemleri için RetroShare tarafından diskinizde saklanacak sohbet iletisi sayısı ve görüşme geçmiÅŸinin ne kadarını görüntüleneceÄŸi buradan ayarlanabilir. En fazla saklama süresi, eski iletilerin silinmesini ve sohbet geçmiÅŸinin geçici sohbetlerle dolmasını engeller (sohbet odaları ve uzak sohbet gibi).</p></body></html> - Chatlobbies - Sohbet Odaları + Sohbet Odaları - + Enabled: Etkin: @@ -2222,11 +2434,12 @@ Odaya katılıp sohbet etmek için çift tıklayın. + Chat rooms Sohbet odaları - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Denetlendi, sayının arttırılması için kimlik ve yukarıdaki metin aynı olmalıdır. @@ -2287,11 +2500,17 @@ Odaya katılıp sohbet etmek için çift tıklayın. + Broadcast Yayınla - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Kayıtlı iletiler (0 = sınırsız): @@ -2438,8 +2657,23 @@ Odaya katılıp sohbet etmek için çift tıklayın. Özel Sohbet - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Odaya katılıp sohbet etmek için çift tıklayın. - + is typing... yazıyor... @@ -2631,12 +2865,12 @@ after HTML conversion. karakter fazla olacak. - + Choose your font. Yazı türünüzü seçin. - + Do you really want to physically delete the history? GeçmiÅŸi tamamen silmek istediÄŸinize emin misiniz? @@ -2708,7 +2942,7 @@ karakter fazla olacak. X nesne bulunduktan sonra renklendirmeye devam edilsin (daha fazla iÅŸlemci gücü gerekir) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Önceki </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ karakter fazla olacak. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Seçili metni iÅŸaretleyin</b><br><i>Ctrl+M</i> - + Person id: KiÅŸi kodu: @@ -2770,7 +3004,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Ä°mzalanmamış - + items found. öge bulundu. @@ -2790,7 +3024,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Buraya iletinizi yazın - + Don't stop to color after Åžuradan sonra renklendirme durdurulmasın @@ -2948,12 +3182,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. ConfCertDialog - + Details Ayrıntılar - + Local Address Yerel Adres @@ -2964,12 +3198,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Dış Adres - + Node info: Düğüm bilgisi: - + Current address: Geçerli adres: @@ -2985,31 +3219,36 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Kapı - + Include signatures Imzalar katılsın - + RetroShare RetroShare - + - + Error : cannot get peer details. Hata: eÅŸ ayrıntıları alınamıyor. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Åžifreleme - + Not connected BaÄŸlı deÄŸil - + Retroshare node details RetroShare düğüm bilgileri - + Node name : Düğüm adı : @@ -3075,13 +3319,18 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Durum iletisi: - + + Connectivity + + + + List of known addresses: Bilinen adreslerin listesi: - - + + Retroshare Certificate RetroShare Sertifikası @@ -3096,7 +3345,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. - + Hidden Address Gizli Adres @@ -3107,11 +3356,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. yok + <p>This certificate contains: - <p>Bu sertifikanın içeriÄŸi: + <p>Bu sertifikanın içeriÄŸi: - + <li>a <b>node ID</b> and <b>name</b> <li>bir <b>düğüm kodu</b> ve <b>ad</b> @@ -3124,12 +3374,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. bir <b>IP adresi</b> ve <b>kapı</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Yeni arkadaÅŸlar eklemek için bu sertifikayı kullanabilirsiniz. Sertifikayı e-posta ile gönderebilir ya da elden ele verebilirsiniz.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Düğümün <span style=" font-weight:600;">OpenSSL</span> sertifikası kodu. Yukarıdaki <span style=" font-weight:600;">PGP</span> anahtarı tarafından imzalanmıştır. </p></body></html> @@ -3139,7 +3389,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. <html><head/><body><p><span style=" font-weight:600;">OpenSSL</span> tarafından kullanılan ÅŸifreleme yöntemi. ArkadaÅŸ düğümlerle kurulan baÄŸlantı</p><p> her zaman yoÄŸun bir ÅŸekilde ÅŸifrelenir ve DHE varsa baÄŸlantı </p><p>&quot;mükemmel bir yönlendirme gizliliÄŸine&quot;.</p> sahiptir</body></html> - + with ile @@ -3345,12 +3595,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Ä°stek hakkında ayrıntılar - + Peer details EÅŸ bilgileri - + Name: Ad: @@ -3368,12 +3618,12 @@ resources. Lütfen unutmayın, çok fazla arkadaÅŸ eklerseniz, RetroShare aşırı miktarda bant geniÅŸliÄŸine, belleÄŸe ve iÅŸlemci gücüne gerek duyar. Ä°stediÄŸiniz kadar ekleyebilirsiniz, ama 40 arkadaÅŸtan fazlası çok fazla kaynaÄŸa gerek duyabilir. - + Location: Konum: - + Options Ayarlar @@ -3410,12 +3660,12 @@ resources. Sertifikayı yapıştırın - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Arkadaşınızın RetroShare sertifikasını bu kutuya yapıştırın. UYARI: bu sertifika arkadaşınızın profil anahtarından farklıdır. Arkadaşınızın profil anahtarını (bir bölümünü bile) buraya yapıştırmayın, çalışmaz.</p></body></html> - + Add friend to group: Gruba arkadaÅŸ ekleyin: @@ -3425,7 +3675,7 @@ resources. Arkadaşı doÄŸrulayın (PGP anahtarını imzalayın) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with BaÄŸlantı kurulacak arkadaÅŸ olarak ekleyin @@ -3459,7 +3709,7 @@ resources. ArkadaÅŸlık isteÄŸini kabul etmek için Tamam üzerine tıklayın. - + Sorry, some error appeared Maalesef, bir sorun çıktı @@ -3479,32 +3729,32 @@ resources. Arkadaşınızın bilgileri: - + Key validity: Anahtar geçerliliÄŸi: - + Profile ID: - + Signers Ä°mzalayanlar - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diÄŸer arkadaÅŸlarınıza bu arkadaşınıza güvendiÄŸinizi gösterirsiniz. AÅŸağıdaki imzalar, listelenmiÅŸ anahtar sahiplerinin geçerli PGP anahtarını özgün olarak tanındığını ÅŸifreli olarak ispatlar.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Bu eÅŸ zaten arkadaÅŸ listenizde. Eklerseniz yalnız IP adresi deÄŸiÅŸebilir. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Sertifika Yüklenemedi @@ -3587,12 +3837,12 @@ resources. Sertifika geçerli görünüyor - + Not a valid Retroshare certificate! Geçerli bir Retroshare sertifikası deÄŸil! - + RetroShare Invitation RetroShare ÇaÄŸrısı @@ -3614,12 +3864,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Bu sizin kendi sertifikanız! Kendi kendinizle arakadaÅŸ olmak istemezsiniz. DeÄŸil mi? - + @@ -3667,7 +3917,37 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. Åžu kiÅŸi arkadaÅŸlık isteÄŸinde bulundu - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3755,12 +4035,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. OlabildiÄŸinde doÄŸrudan kaynak olarak kullanılsın - + IP-Addr: IP Adresi: - + IP-Address IP Adresi @@ -3826,7 +4106,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. Anahtarı, anahtarlığa ekle - + This key is already in your keyring Bu anahtar zaten anahtarlığınızda bulunuyor @@ -3887,12 +4167,12 @@ kullanılabilir. <p>Bu sertifikada bir IP adresi yok. IP adresini bulmak için keÅŸif ve DHT özelliÄŸine güvenmelisiniz. Beyaz listeye eklenme zorunlu olsun seçeneÄŸini etkinleÅŸtirdiÄŸiniz için Haber Akışı sekmesinde eÅŸle ilgili bir güvenlik uyarısı görüntülenecek. Oraya bakarak eÅŸin IP adresini beyaz listeye alabilirsiniz.</p> - + [Unknown] [Bilinmiyor] - + Added with certificate from %1 Sertifikasıyla birlikte %1 üzerinden eklendi @@ -3979,7 +4259,12 @@ kullanılabilir. UDP Sonucu - + + Status + Durum + + + <!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; } @@ -4409,7 +4694,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4561,7 +4846,7 @@ p, li { white-space: pre-wrap; } Herhangi Bir Çevre Sınırlaması SeçilmemiÅŸ - + [Unknown] [Bilinmiyor] @@ -4576,7 +4861,7 @@ p, li { white-space: pre-wrap; } Sil - + Search Arama @@ -4596,7 +4881,7 @@ p, li { white-space: pre-wrap; } Bilinen düğümler tarafından imzalanmış - + Edit Circle Çevreyi Düzenle @@ -4616,12 +4901,12 @@ p, li { white-space: pre-wrap; } Ä°simsiz Kod - + Circle name Çevre adı - + Update Güncelle @@ -4647,7 +4932,7 @@ p, li { white-space: pre-wrap; } PGP BaÄŸlantılı Kod - + Add Member Ãœye Ekle @@ -4791,7 +5076,7 @@ p, li { white-space: pre-wrap; } - + Attachments Ek dosyalar @@ -4837,7 +5122,7 @@ p, li { white-space: pre-wrap; } Arama Sonuçlarından Dosyaları Sürükleyip Bırakın - + Paste RetroShare Links RetroShare BaÄŸlantılarını Yapıştır @@ -4847,7 +5132,7 @@ p, li { white-space: pre-wrap; } RetroShare BaÄŸlantısını Yapıştır - + Drop file error. Dosya bırakma hatası. @@ -4874,17 +5159,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Dosya Zaten EklenmiÅŸ ve Karılmış + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Dosya Zaten EklenmiÅŸ ve Karılmış + + + Please add a Subject Lütfen bir konu ekleyin @@ -4915,12 +5224,12 @@ p, li { white-space: pre-wrap; } Gerçekten %1 ileti oluÅŸturmak istiyor musunuz? - + You are about to add files you're not actually sharing. Do you still want this to happen? Gerçekte paylaÅŸmadığınız dosyaları eklemek istediÄŸinize emin misiniz? - + Edit Channel Post Kanal Ä°letisini Düzenle @@ -4940,7 +5249,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Sahibi olmadığınız dosyaları bir kanala göndermek üzeresiniz. @@ -5032,7 +5341,7 @@ p, li { white-space: pre-wrap; } - + No Forum Forum Yok @@ -5492,7 +5801,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz DHTGraphSource - + users kullanıcılar @@ -6499,7 +6808,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz FlatStyle_RDM - + Friends Directories ArkadaÅŸ Klasörleri @@ -7005,7 +7314,7 @@ en az bir eÅŸ bir gruba eklenemedi ArkadaÅŸ Arama - + Mark all Tümünü iÅŸaretle @@ -7019,7 +7328,7 @@ en az bir eÅŸ bir gruba eklenemedi FriendsDialog - + Edit status message Durum iletisini düzenle @@ -7123,7 +7432,7 @@ en az bir eÅŸ bir gruba eklenemedi RetroShare sohbeti yayını: iletiler baÄŸlı olan tüm arkadaÅŸlara gönderilir. - + Network AÄŸ @@ -7188,7 +7497,7 @@ en az bir eÅŸ bir gruba eklenemedi Düğüm alanına en az 3 karakter yazmalısınız - + Failed to generate your new certificate, maybe PGP password is wrong! Yeni sertifikanız üretilemedi. PGP parolası yanlış olabilir! @@ -7231,7 +7540,7 @@ en az bir eÅŸ bir gruba eklenemedi Varolan profili kullan - + Node name Düğüm adı @@ -7498,12 +7807,12 @@ ve İçe Aktar düğmesini kullanarak yükleyebilirsiniz - + Profile generation failure Profil üretilemedi - + Missing PGP certificate PGP sertifikası eksik @@ -7910,7 +8219,7 @@ p, li { white-space: pre-wrap; } Yöneltici Ä°statistikleri - + GroupBox Grup Kutusu @@ -7975,7 +8284,7 @@ p, li { white-space: pre-wrap; } Dallanma Çarpanı - + Details Ayrıntılar @@ -7998,7 +8307,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Yönetilen Anahtarlar @@ -8207,7 +8516,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title BaÅŸlık @@ -8217,13 +8526,30 @@ p, li { white-space: pre-wrap; } BaÅŸlık Arama - - + + + + Description Açıklama - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Açıklama Arama @@ -8233,42 +8559,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Azalan Düzende Sırala + Azalan Düzende Sırala - Sort Ascending Order - Artan Düzende Sırala + Artan Düzende Sırala - Sort by Name - Ada Göre Sırala + Ada Göre Sırala - Sort by Popularity - BeÄŸeniye Göre Sırala + BeÄŸeniye Göre Sırala - Sort by Last Post - Son Ä°letiye Göre Sırala + Son Ä°letiye Göre Sırala - Sort by Number of Posts - Ä°leti Sayısına Göre Sırala + Ä°leti Sayısına Göre Sırala - Sort by Unread - Okunmamışlara Göre Sırala + Okunmamışlara Göre Sırala - + You are admin (modify names and description using Edit menu) Yöneticisiniz (Düzenle menüsünden ad ve açıklamaları deÄŸiÅŸtirebilirsiniz) @@ -8283,40 +8602,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Son Ä°leti - + + Name Ad - - Unread - - - - + Popularity - - + + Never Hiç - Display - Görünüm + Görünüm - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8465,7 +8779,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanallar @@ -8490,12 +8804,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kanallar</h1> <p>Kanallar aÄŸa yaymak istediÄŸiniz verileri (film, müzik gibi) göndermenizi saÄŸlar.</p> <p>ArkadaÅŸlarınızın abone olduÄŸu kanalları görebilirsiniz. Abone olduÄŸunuz kanallar da otomatik olarak arkadaÅŸlarınıza iletilir. Böylece aÄŸdaki iyi kanallar öne çıkar.</p> <p>Bir kanala yalnız kanalı oluÅŸturan kiÅŸi veri gönderebilir. Kanal özel bir kanal deÄŸilse aÄŸdaki diÄŸer eÅŸler bu verileri yalnızca okuyabilir. Bununla birlikte veri gönderme ya da okuma izinlerini arkadaşınız oluan RetroShare düğümleri ile paylaÅŸabilirsiniz.</p> <p>Kanallar isimsiz olabileceÄŸi gibi bir RetroShare kimliÄŸiyle iliÅŸkilendirilebilir. Böylece okuyucular gerek duyduÄŸunda sizinle iletiÅŸim kurabilir. GönderdiÄŸiniz verilere kullanıcıların yorum yapmasını istiyorsanız "Yorumlar Kullanılsın" seçeneÄŸini etkinleÅŸtirin.</p> <p>Bu deÄŸeri deÄŸiÅŸtirmediyseniz, kanala gönderilen veriler %1 gün tutulur ve son %2 gündeki veriler eÅŸitlenir.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Abone Olunan Kanallar @@ -9020,7 +9334,7 @@ p, li { white-space: pre-wrap; } - + Add new post Yeni ileti oluÅŸtur @@ -9120,12 +9434,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Yorumlar @@ -9136,18 +9450,18 @@ p, li { white-space: pre-wrap; } - + Feeds Akış - - + + Click to switch to list view - + Show unread posts only @@ -9157,12 +9471,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9222,7 +9536,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9237,12 +9551,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9318,23 +9632,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe Abone Ol - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Bir Kanal SeçilmemiÅŸ @@ -9356,11 +9683,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanal Ä°letisi - - - new message(s) - - GxsCircleItem @@ -9894,7 +10216,7 @@ bir kimlik oluÅŸturmalısınız SeçilmiÅŸ Foruma Yeni Konu Ekle - + Search forums Forum Arama @@ -9903,12 +10225,12 @@ bir kimlik oluÅŸturmalısınız Son Ä°leti - + New Thread Yeni Konu - + Threaded View İç İçe Görünüm @@ -9918,19 +10240,19 @@ bir kimlik oluÅŸturmalısınız Düz Görünüm - - + + Title BaÅŸlık - - + + Date Tarih - + Author Yazar @@ -9945,7 +10267,17 @@ bir kimlik oluÅŸturmalısınız Yükleniyor - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10006,23 +10338,23 @@ bir kimlik oluÅŸturmalısınız <p>Foruma abone olduÄŸunuzda diÄŸer abone olan arkadaÅŸlarınızın gönderilerini alabilir ve forumu tüm diÄŸer arkadaÅŸlarınıza görünür kılabilirsiniz..</p><p>Ä°stediÄŸinizde soldaki forum listesine saÄŸ tıklayarak abonelikten ayrılabilirsiniz.</p> - + No name Adsız - - + + Reply Yanıtla - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10060,12 +10392,12 @@ bir kimlik oluÅŸturmalısınız Okunmamış Olarak Ä°ÅŸaretle - + Copy RetroShare Link RetroShare BaÄŸlantısını Kopyala - + Hide Gizle @@ -10078,7 +10410,7 @@ bir kimlik oluÅŸturmalısınız [EngellenmiÅŸ] - + [unknown] [bilinmiyor] @@ -10108,8 +10440,8 @@ bir kimlik oluÅŸturmalısınız Yalnız sizin gözlerinize - - + + Distribution Dağıtım @@ -10212,7 +10544,7 @@ bir kimlik oluÅŸturmalısınız Özgün Ä°leti - + New thread Yeni konu @@ -10221,7 +10553,7 @@ bir kimlik oluÅŸturmalısınız Okunma durumu - + Edit Düzenle @@ -10277,7 +10609,7 @@ bir kimlik oluÅŸturmalısınız KiÅŸiler sekmesinde yazar görüntülensin - + Author's reputation Yazarın deÄŸerlendirmesi @@ -10297,7 +10629,7 @@ bir kimlik oluÅŸturmalısınız - + <b>Loading...<b> @@ -10337,6 +10669,11 @@ bir kimlik oluÅŸturmalısınız Storage Depolama + + + Last seen at friends: + + Moderators @@ -10430,7 +10767,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: %1 zamanında, %2 kullanıcısının iletisi: - + Forum name Forum adı @@ -10462,11 +10799,6 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Forum Post Forum Ä°letisi - - - new message(s) - - GxsForumsDialog @@ -10915,7 +11247,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Baskı Önizleme - + Unsubscribe Abonelikten Ayrıl @@ -10930,7 +11262,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Yeni sekmede açılsın - + Remove this search @@ -10940,12 +11272,12 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: - + Request data - + Show Details Ayrıntılara Bakın @@ -11012,7 +11344,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: - + Search for @@ -11021,7 +11353,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Yayınlama izinlerini paylaÅŸ - + Copy RetroShare Link RetroShare BaÄŸlantısını Kopyala @@ -11036,7 +11368,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Tümünü okunmamış olarak iÅŸaretle - + AUTHD DoÄŸrulanmış @@ -11653,7 +11985,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11688,6 +12020,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11699,7 +12048,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <span style=" font-size:8pt; font-weight:600;"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <span style=" font-size:8pt; font-weight:600;"><!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:9pt; font-weight:400; font-style:normal;"> @@ -11779,27 +12128,32 @@ p, li { white-space: pre-wrap; } Form - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11821,6 +12175,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11829,7 +12184,7 @@ p, li { white-space: pre-wrap; } AÅŸağıdaki metin sizin RetroShare sertifikanızdır. Bu metni arkadaÅŸlarınıza gönderin - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11845,12 +12200,12 @@ merkezi olmayan kiÅŸisel ve güvenli bir iletiÅŸim platformu. RetroShare hakkında yardıma ihtiyacınız var mı? - + Open Web Help Web Yardımını Aç - + Copy your Cert to Clipboard Sertifikanızı Panoya Kopyalayın @@ -11899,7 +12254,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11908,7 +12263,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12201,14 +12556,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tümü - + Reputation DeÄŸerlendirme @@ -12218,12 +12573,12 @@ p, li { white-space: pre-wrap; } Arama - + Anonymous Id Ä°simsiz Kod - + Create new Identity Yeni kimlik ekle @@ -12367,7 +12722,7 @@ p, li { white-space: pre-wrap; } Kimlik Kodu - + Send message Ä°leti Gönder @@ -12458,7 +12813,7 @@ p, li { white-space: pre-wrap; } Genel DeÄŸerlendirme: - + Anonymous Ä°simsiz @@ -12473,24 +12828,24 @@ p, li { white-space: pre-wrap; } Kod Arama - + This identity is owned by you Bu kimlik size ait - - + + My own identities Kendi kimliklerim - - + + My contacts KiÅŸilerim - + Show Items Ögeleri Görüntüle @@ -12505,7 +12860,7 @@ p, li { white-space: pre-wrap; } Düğümümle baÄŸlantılı - + Other circles DiÄŸer çevreler @@ -12564,13 +12919,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). abone (diÄŸer kiÅŸiler ve çaÄŸrı listesinden üyelik isteklerini alıp iletebilir). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). abone deÄŸil (yalnız çaÄŸrı listesini alabilir). - + Your status: Durumunuz: @@ -12630,7 +12990,7 @@ p, li { white-space: pre-wrap; } Ãœye - + Edit Circle Çevreyi Düzenle @@ -12678,7 +13038,7 @@ p, li { white-space: pre-wrap; } ÃœyeliÄŸi onayla - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12690,12 +13050,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + [Unknown node] [Düğüm bilinmiyor] - + Unverified signature from node Düğümden doÄŸrulanmamış imza alındı @@ -12707,12 +13067,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. DenetlenmemiÅŸ imza - + [unverified] [doÄŸrulanmamış] - + Identity owned by you, linked to your Retroshare node RetroShare düğümünüze baÄŸlı size ait kimlik @@ -12836,12 +13196,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Sertifikanız ile bir çaÄŸrı göndermek istediÄŸinize emin misiniz? - + Banned EngellenmiÅŸ - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kimlikler</h1> <p>Bu sekmeden <b>sahte isimsiz kimlikler</b> ve <b>çevreler</b> oluÅŸturup düzenleyebilirsiniz. </p> <p><b>Kimlikler</b> verilerinizin güvenli olarak tanınmasını saÄŸlamak için forum ve kanal iletilerini imzalamakta ve RetroShare iç e-posta sistemini kullanarak geri bildirimleri almak, kanal iletilerinden sonra yorum yapmak gibi iÅŸlemler için kullanılır</p> <p> Kimlikler isteÄŸe baÄŸlı olarak RetroShare düğümünüzün sertifikası ile <b>imzalanabilir</b>. Ä°mzalanmış kimliklere güvenilmesi daha kolaydır ancak bunlar düğümünüzün IP adresinin kolayca belirlenmesini saÄŸlar.</p> <p><b>Ä°simsiz kimlikler</b> diÄŸer kullanıcılar ile kimliÄŸinizi gizli tutarak etkileÅŸimde bulunmanızı saÄŸlar. Kandırılamazlar ancak hiç kimse verilen bir kimliÄŸin gerçek sahibini ispatlayamaz.</p> <p><b>Çevreler</b> aÄŸ üzerinde bir alanı paylaÅŸan bir kimlik grubudur (isimsiz ya da imzalanmış). Çevreler forum ve kanal gibi ögelerin görüntülenmesini kısıtlamak için kullanılır. </p> <p>Bir <b>çevre</b> baÅŸka bir çevre tarafından ya da yalnız kendi üyeleri tarafından görülebilecek ÅŸekilde kendi içinde kısıtlanabilir.</p> @@ -12850,7 +13210,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Kod Bilinmiyor : - + positive olumlu @@ -13035,8 +13395,8 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - - + + People KiÅŸiler @@ -13047,7 +13407,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Avatarınız - + Linked to neighbor nodes KomÅŸu düğümlerle baÄŸlantılı @@ -13057,7 +13417,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Uzak düğümlerle baÄŸlantılı - + Linked to a friend Retroshare node Bir arkadaşın RetroShare düğümüyle baÄŸlantılı @@ -13117,7 +13477,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Sahibi - + Node name: Düğüm adı: @@ -13127,7 +13487,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Düğüm Kodu: - + Really delete? Gerçekten silinsin mi? @@ -13165,7 +13525,22 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Takma Ad - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Yeni kimlik @@ -13182,14 +13557,14 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + N/A Kullanılamıyor - + Edit identity KimliÄŸi düzenle @@ -13200,24 +13575,27 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Güncelle - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13236,17 +13614,27 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Anahtar alınamadı! - + Error KeyID invalid Anahtar kodu geçersiz - + Unknown GpgId GpgKodu bilinmiyor @@ -13256,7 +13644,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Gerçek ad bilinmiyor - + Create New Identity Yeni Kimlik OluÅŸtur @@ -13266,7 +13654,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Tür - + + Choose image... + + + + @@ -13306,12 +13699,11 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Avatarınız - Set Avatar - Avatarı Ayarla + Avatarı Ayarla - + Linked to your profile Profilinizle baÄŸlantılı @@ -13321,7 +13713,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Bir ya da bir kaç kimliÄŸiniz olabilir. Kimlikler sohbet odalarında, forumlarda ve kanal yorumlarında yazışırken kullanılır. Uzak sohbet ve RetroShare uzak posta sistemi için hedef olarak kullanılırlar. - + The nickname is too short. Please input at least %1 characters. Takma ad çok kısa. Lütfen en az %1 karakter yazın. @@ -13430,8 +13822,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. + Quote + + + Send - Gönder + Gönder @@ -13589,7 +13985,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + Options Ayarlar @@ -13621,12 +14017,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Hızlı BaÅŸlangıç Yardımcısı - + RetroShare %1 a secure decentralized communication platform RetroShare %1 merkezi olmayan güvenli bir iletiÅŸim platformudur - + Unfinished Tamamlanmamış @@ -13759,7 +14155,7 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın.Görüntüle - + Make sure this link has not been forged to drag you to a malicious website. Bu baÄŸlantının sizi zararlı yazılım bulunduran bir web sitesine yönlendirmediÄŸinden emin olun. @@ -13804,7 +14200,7 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın.Hizmet izinleri matrisi - + Statistics Ä°statistikler @@ -13833,7 +14229,7 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın.MessageComposer - + Compose Yeni Ä°leti @@ -13935,7 +14331,7 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın. - + Tags Etiketler @@ -14030,12 +14426,12 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın.Blok Alıntısı Ekle - + Send To: Kime: - + &Left So&la @@ -14069,7 +14465,7 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın.KiÅŸilerim - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Merhaba, <br>Ä°yi bir arkadaşımı öneriyorum; bana güveniyorsan ona da güvenebilirsin. <br> @@ -14095,12 +14491,12 @@ Lütfen biraz boÅŸ disk alanı açıp Tamam düğmesine tıklayın. - + Save Message Ä°letiyi Kaydet - + Message has not been Sent. Do you want to save message to draft box? Ä°leti gönderilemedi @@ -14112,7 +14508,7 @@ Do you want to save message to draft box? RetroShare BaÄŸlantısını Yapıştır - + Add to "To" "Kime" alanına ekle @@ -14367,7 +14763,7 @@ Do you want to save message ? BaÅŸka Dosya Ekleyin - + Hi,<br>I want to be friends with you on RetroShare.<br> Merhaba,<br>RetroShare üzerinde sizinle arkadaÅŸ olmak istiyorum.<br> @@ -14376,12 +14772,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Bir arkadaÅŸlık isteÄŸiniz var - + Respond now: Åžimdi yanıtlayın: @@ -14397,11 +14808,12 @@ Do you want to save message ? Kimden: + Friend Nodes - ArkadaÅŸ Düğümleri + ArkadaÅŸ Düğümleri - + Bullet list (disc) Ä°mli liste (disk) @@ -14441,13 +14853,13 @@ Do you want to save message ? Sıralı liste (büyük romen) - - + + Thanks, <br> TeÅŸekkürler, <br> - + Distant identity: Uzak kimlik: @@ -14586,8 +14998,23 @@ Do you want to save message ? Ä°leti - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14599,12 +15026,12 @@ Do you want to save message ? Önerilen Dosyalar - + Download all Recommended Files Önerilen Tüm Dosyaları Ä°ndir - + Subject: Konu: @@ -14679,12 +15106,18 @@ Do you want to save message ? ÇaÄŸrı Gönder - + + Message Size: + + + + File Name Dosya Adı - + + Size Boyut @@ -14745,10 +15178,25 @@ Do you want to save message ? Indir - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? ÇaÄŸrı Gönder @@ -14759,12 +15207,12 @@ Do you want to save message ? - + Download all Tümünü indir - + Print Document Belgeyi Yazdır @@ -14779,7 +15227,7 @@ Do you want to save message ? HTML Dosyaları (*.htm *.html);;Tüm Dosyalar (*) - + Load images always for this message Bu iletideki görseller her zaman yüklensin @@ -14920,7 +15368,7 @@ Do you want to save message ? MessagesDialog - + New Message Yeni Ä°leti @@ -14976,14 +15424,14 @@ Do you want to save message ? - + Tags Etiketler - + Inbox Gelen @@ -15078,7 +15526,7 @@ Do you want to save message ? Ä°letiyi Ä°let - + Subject Konu @@ -15190,7 +15638,7 @@ Do you want to save message ? - + Open in a new window Yeni pencerede açılsın @@ -15275,7 +15723,7 @@ Do you want to save message ? - + Drafts Taslaklar @@ -15404,7 +15852,7 @@ Do you want to save message ? Ä°letiyi Yanıtla - + Delete Message Ä°letiyi Sil @@ -15415,7 +15863,7 @@ Do you want to save message ? - + Expand GeniÅŸlet @@ -15425,7 +15873,7 @@ Do you want to save message ? Ögeyi Sil - + from kimden @@ -15434,6 +15882,11 @@ Do you want to save message ? Reply to invite ÇaÄŸrıyı Yanıtla + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15758,7 +16211,7 @@ Bildirilen hata: - + Groups Gruplar @@ -15788,19 +16241,19 @@ Bildirilen hata: arkadaÅŸ listenizi gruplarla birlikte içe aktarın - - + + Search Arama - + ID Kod - + Search ID @@ -15810,7 +16263,7 @@ Bildirilen hata: - + Show Items Ögeleri Görüntüle @@ -16014,19 +16467,19 @@ en az bir eÅŸ bir gruba eklenemedi - + Error Hata - + File is not writeable! Dosya yazılabilir deÄŸil! - + File is not readable! Dosya okunabilir deÄŸil! @@ -16064,9 +16517,13 @@ en az bir eÅŸ bir gruba eklenemedi NewsFeed - Log entries - Günlük kayıtları + Günlük kayıtları + + + + Activity Stream + @@ -16083,7 +16540,7 @@ en az bir eÅŸ bir gruba eklenemedi Bu bir denemedir. - + Newest on top Yeniden eskiye @@ -16094,20 +16551,43 @@ en az bir eÅŸ bir gruba eklenemedi + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Haber Akışı</h1> <p>Haber Akışı ağınızdaki son geliÅŸmeleri aldığınız tarihe göre sıralayarak görüntüler. Bu özellik arkadaÅŸlarınızın yaptığı iÅŸlemlerin bir özetini verir. Hangi iÅŸlemlerin görüntüleneceÄŸini seçmek için <b>Ayarlar</b> üzerine tıklayabilirsiniz. </p> <p>Seçenekler ÅŸunlardır: <ul> <li>BaÄŸlanma giriÅŸimleri (yeni kiÅŸiler ile arkadaÅŸ olmak ve size ulaÅŸmaya çalışanları görmek için)</li> <li>Kanal ve Forum iletileri</li> <li>Abone olabileceÄŸiniz yeni kanal ve forumlar</li> <li>ArkadaÅŸlarınızdan gelen özel iletiler</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Haber Akışı</h1> <p>Haber Akışı ağınızdaki son geliÅŸmeleri aldığınız tarihe göre sıralayarak görüntüler. Bu özellik arkadaÅŸlarınızın yaptığı iÅŸlemlerin bir özetini verir. Hangi iÅŸlemlerin görüntüleneceÄŸini seçmek için <b>Ayarlar</b> üzerine tıklayabilirsiniz. </p> <p>Seçenekler ÅŸunlardır: <ul> <li>BaÄŸlanma giriÅŸimleri (yeni kiÅŸiler ile arkadaÅŸ olmak ve size ulaÅŸmaya çalışanları görmek için)</li> <li>Kanal ve Forum iletileri</li> <li>Abone olabileceÄŸiniz yeni kanal ve forumlar</li> <li>ArkadaÅŸlarınızdan gelen özel iletiler</li> </ul> </p> + + + Log + Haber - Log - Haber + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16144,22 +16624,22 @@ en az bir eÅŸ bir gruba eklenemedi - + Test Deneme - + Chat Room Sohbet Odası - + Systray Icon Sistem Tepsisi Simgesi - + Message Ä°leti @@ -16184,12 +16664,11 @@ en az bir eÅŸ bir gruba eklenemedi IP güvenliÄŸi - Log - Haber + Haber - + Friend Connected ArkadaÅŸ BaÄŸlandı @@ -16203,7 +16682,12 @@ en az bir eÅŸ bir gruba eklenemedi BaÄŸlantılar - + + Activity + + + + Mails Postalar @@ -16240,7 +16724,12 @@ en az bir eÅŸ bir gruba eklenemedi Grup Sohbeti - + + Toaster position + + + + Chat rooms Sohbet odaları @@ -16265,22 +16754,22 @@ en az bir eÅŸ bir gruba eklenemedi Büyük küçük harfe duyarlı - + Position Konum - + X Margin X Kenar BoÅŸluÄŸu - + Y Margin Y Kenar BoÅŸluÄŸu - + Systray message Sistem Tepsisi Ä°letisi @@ -16330,7 +16819,7 @@ en az bir eÅŸ bir gruba eklenemedi Bildir - + Disable All Toasters Tüm Bildirimleri Devre Dışı Bırak @@ -16344,7 +16833,7 @@ en az bir eÅŸ bir gruba eklenemedi Akış - + Systray Sistem Tepsisi @@ -16490,17 +16979,16 @@ Düşük Trafik: %10 standart trafik ve YAPILACAK: tüm dosya aktarımları dura PGPKeyDialog - Dialog - Pencere + Pencere - + Profile info Profil bilgileri - + Name : Ad : @@ -16555,22 +17043,21 @@ Düşük Trafik: %10 standart trafik ve YAPILACAK: tüm dosya aktarımları dura Çok Fazla - + This profile has signed your own profile key Bu profil kendi profil anahtarınız ile imzalanmış - Key signatures : - Anahtar imzaları : + Anahtar imzaları : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diÄŸer arkadaÅŸlarınıza bu arkadaşınıza güvendiÄŸinizi gösterirsiniz. AÅŸağıdaki imzalar, listelenmiÅŸ anahtar sahiplerinin geçerli PGP anahtarını özgün olarak tanındığını ÅŸifreli olarak ispatlar.</span></p></body></html> - + <!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; } @@ -16588,7 +17075,7 @@ p, li { white-space: pre-wrap; } Bu anahtarı imzala - + PGP key PGP anahtarı @@ -16598,22 +17085,20 @@ p, li { white-space: pre-wrap; } Bu seçenekler profildeki tüm düğümlere uygulanır: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diÄŸer arkadaÅŸlarınıza bu arkadaşınıza güvendiÄŸinizi gösterirsiniz. Böylece arkadaÅŸlarınız bu anahtara güvenme durumunuza göre baÄŸlantıları onaylamaya karar verebilir. Anahtar imzalama iÅŸlemi isteÄŸe baÄŸlıdır ancak geri alınamaz. Bu nedenle ne yaptığınızdan emin olun.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diÄŸer arkadaÅŸlarınıza bu arkadaşınıza güvendiÄŸinizi gösterirsiniz. Böylece arkadaÅŸlarınız bu anahtara güvenme durumunuza göre baÄŸlantıları onaylamaya karar verebilir. Anahtar imzalama iÅŸlemi isteÄŸe baÄŸlıdır ancak geri alınamaz. Bu nedenle ne yaptığınızdan emin olun.</span></p></body></html> - + Keysigning: - Sign PGP key - PGP anahtarını imzala + PGP anahtarını imzala - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Bu anahtar ile kimliÄŸi doÄŸrulanmış baÄŸlantıları reddetmek için buraya tıklayın.</p></body></html> @@ -16633,7 +17118,7 @@ p, li { white-space: pre-wrap; } BaÄŸlantıları onayla - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. AÅŸağıda düğümün ASCII biçimindeki PGP anahtarını görebilirsiniz. Bu bilgi aynı profildeki tüm düğümleri belirler. ArkadaÅŸ olmak için deÄŸiÅŸ tokuÅŸ edeceÄŸiniz bir "RetroShare Sertifikası" her düğüm için "Ayrıntılar" bölümünde bulunabilir. @@ -16703,28 +17188,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Hata: eÅŸ ayrıntıları alınamadı. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Verilen anahtar algoritmasi RetroShare tarafından desteklenmiyor (Åžu anda yalnız RSA anahtarları destekleniyor) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16738,7 +17223,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Güvenilirlik düzeyi bu anahtara güveninizi göstermenin bir yoludur. Yazılım tarafından kullanılmaz ya da paylaşılmaz ancak iyi ve kötü anahtarları anımsamanıza yardımcı olur. @@ -16783,27 +17268,47 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. Bu anahtar ile imzalanmış RetroShare düğümlerinden gelen baÄŸlantıları reddetmeyi seçtiniz. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Ä°mza Sorunu - - Maybe password is wrong - Parola yanlış olabilir + + Check the password! + - + Maybe password is wrong + Parola yanlış olabilir + + + You haven't set a trust level for this key. Bu anahtar için bir güvenilirlik düzeyi ayarlamamışsınız. - + + Retroshare profile RetroShare profili - + This is your own PGP key, and it is signed by : Bu sizin kendi PGP anahtarınız ve imzalayan : @@ -16982,8 +17487,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. PeopleDialog - - + People KiÅŸiler @@ -17000,7 +17504,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. İç - + Chat with this person Bu kiÅŸiyle sohbet et @@ -17151,7 +17655,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. FotoÄŸraf - + TextLabel Metin Etiketi @@ -17195,8 +17699,8 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. - <N> Comments >> - + Comments + Yorumlar @@ -17231,6 +17735,11 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. Write a comment... Yorum yaz... + + + Album + Albüm + PhotoItem @@ -17240,12 +17749,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doÄŸrudan indirmeye Ä°zin verilmemiÅŸ. Form - + TextLabel Metin Etiketi - + <!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; } @@ -17341,7 +17850,7 @@ p, li { white-space: pre-wrap; } FotoÄŸrafı Görüntüle - + PhotoShare PhotoShare @@ -17382,7 +17891,7 @@ lütfen bir albüm seçin! - + Stop Durdur @@ -17610,12 +18119,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Tüm uygulama eklerini doÄŸrula - + Plugin look-up directories Uygulama eklerinin aranacağı klasörler @@ -17674,7 +18183,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Uygulama&nbsp;Ekleri</h1> <p>Uygulama ekleri aÅŸağıdaki listedeki klasörlerden yüklenir.</p> <p>Güvenlik nedeniyle onaylanmış uygulama ekleri temel RetroShare çalıştırılabilir dosyası ya da uygulama eki kitaplıkları deÄŸiÅŸene kadar otomatik olarak yüklenir. Bu durumda kullanıcı uygulama eklerini yeniden onaylamalıdır. Bir uygulama ekini el ile etkinleÅŸtirmek için "EtkinleÅŸtir" düğmesine tıklayıp RetroShare yazılımını yeniden baÅŸlatın.</p><p>Kendi uygulama eklerinizi geliÅŸtirmek isterseniz, geliÅŸtirici ekibiyle görüşebilirsiniz. Size seve seve yardımcı olurlar!</p> - + Plugins Uygulama Ekleri @@ -18072,7 +18581,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. BaÄŸlantılar - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18243,13 +18752,13 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Site - - + + Comments Yorumlar - + Copy RetroShare Link @@ -18259,7 +18768,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. KiÅŸiler sekmesinde yazar görüntülensin - + Comment Yorum yapın @@ -18280,12 +18789,12 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + Hide Gizle - + Vote up BeÄŸendim @@ -18299,7 +18808,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. \/ - + Set as read and remove item OkunmuÅŸ olarak iÅŸaretle ve ögeyi sil @@ -18360,7 +18869,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Metin Etiketi - + Loading Yükleniyor @@ -18450,13 +18959,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18466,60 +18969,50 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Yönetici: - - - + + + unknown - + Distribution: Dağıtım: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Metin Etiketi - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Ä°letiler @@ -18530,7 +19023,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18599,7 +19092,12 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + + Empty + + + + Copy RetroShare Link @@ -18634,7 +19132,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + [No name] @@ -18762,8 +19260,18 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19035,9 +19543,8 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseAddDialog - Post From: - Åžu Hesapla Gönderilsin: + Åžu Hesapla Gönderilsin: Account 1 @@ -19052,7 +19559,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz 3. Hesap - + Add to Pulse Pulse üzerine ekle @@ -19075,17 +19582,32 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Adres - + GroupLabel - + IDLabel - + + From: + Kimden: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19110,10 +19632,20 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Olumsuz - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19123,14 +19655,53 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + + Post + + + + Cancel Ä°ptal - Post Pulse to Wire - Pulse Wire Ãœzerine Gönder + Pulse Wire Ãœzerine Gönder + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19156,10 +19727,18 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Form - - - - + + + + + Click to view picture + + + + + + + Image Görsel @@ -19167,44 +19746,44 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19214,17 +19793,17 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19234,7 +19813,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19242,7 +19821,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseTopLevel - + retweeted @@ -19257,7 +19836,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + follow Parent Group @@ -19267,7 +19846,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19292,7 +19871,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19328,29 +19907,29 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19428,7 +20007,7 @@ KimliÄŸi İçe Aktar düğmesine tıklayarak yükleyebilirsiniz QObject - + Confirmation Onaylama @@ -19670,7 +20249,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Sonuç - + Unable to make path Yol oluÅŸturulamadı @@ -19705,7 +20284,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Dosya isteÄŸi iptal edildi - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Bu RetroShare sürümü OpenPGP-SDK kullanır. Bu nedenle sistem paylaşımlı PGP anahtarlığını kullanamaz, ama çalışan tüm RetroShare kopyaları ile paylaşılan kendi anahtarlığı bulunur.<br><br>Büyük olasılıkla uygulamanın yeni sürümüne henüz geçtiÄŸiniz için, var olan RetroShare hesaplarında PGP anahtarlarının olduÄŸu anılmasına raÄŸmen, böyle bir anahtarlığınız yok gibi görünüyor. @@ -19849,7 +20428,7 @@ Bildirilen hata: saniye - + TR up AK yük @@ -19894,7 +20473,7 @@ Bildirilen hata: devre dışı - + Move IP %1 to whitelist %1 IP adresini beyaz listeye taşı @@ -19910,7 +20489,7 @@ Bildirilen hata: - + %1 seconds ago %1 saniye önce @@ -19995,7 +20574,7 @@ Güvenlik: Ä°simsiz kodlar kullanılamaz - + Error Hata @@ -20386,9 +20965,8 @@ Güvenlik: Ä°simsiz kodlar kullanılamaz - <p>This certificate contains: - <p>Bu sertifikanın içeriÄŸi: + <p>Bu sertifikanın içeriÄŸi: @@ -20762,7 +21340,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20984,19 +21562,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options AÄŸaç Görünümü Ayarları - Show column... - Görüntülenecek sütun... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Azalan Düzende Sırala + + + + Sort Ascending Order + Artan Düzende Sırala + + + + + [no title] + + + + + Show column … + + + + Show column... + Görüntülenecek sütun... - [no title] - [baÅŸlık yok] + [baÅŸlık yok] @@ -21432,7 +22039,7 @@ p, li { white-space: pre-wrap; } Ä°ndir! - + File Dosya @@ -21447,7 +22054,7 @@ p, li { white-space: pre-wrap; } Karma - + Bad filenames have been cleaned Kötü dosya adları temizlendi @@ -21497,7 +22104,7 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Kaydet - + Collection Editor Derleme Düzenleyici @@ -21512,7 +22119,7 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Dosya Sayısı - + Real Size: Waiting child... Gerçek Boyut: Alt öge bekleniyor... @@ -21527,12 +22134,12 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Bu bir klasör. GeniÅŸletmek için çift tıklayın. - + Download files - + Specify... Belirtin... @@ -21781,7 +22388,7 @@ Dosyanın doÄŸru olduÄŸunu düşünüyorsanız bu satırı silerek dosyayı Retr RsFriendListModel - + Name Ad @@ -21801,7 +22408,7 @@ Dosyanın doÄŸru olduÄŸunu düşünüyorsanız bu satırı silerek dosyayı Retr IP Adresi - + Profile ID @@ -21814,10 +22421,15 @@ Dosyanın doÄŸru olduÄŸunu düşünüyorsanız bu satırı silerek dosyayı Retr RsGxsForumModel - + Title BaÅŸlık + + + UnRead + + Date @@ -21829,7 +22441,7 @@ Dosyanın doÄŸru olduÄŸunu düşünüyorsanız bu satırı silerek dosyayı Retr Yazar - + Information for this identity is currently missing. Bu kimlikle ilgili bilgiler ÅŸu anda eksik. @@ -21870,7 +22482,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: [Bilinmiyor] - + [ ... Missing Message ... ] [... Ä°leti Eksik ... ] @@ -21878,7 +22490,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: RsMessageModel - + Date Tarih @@ -21938,7 +22550,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: - + [Notification] @@ -22297,7 +22909,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Dosya Adı - + Download Indir @@ -22376,7 +22988,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Klasör Aç - + Create Collection... Derleme OluÅŸtur... @@ -22396,7 +23008,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Derleme dosyasından indir... - + Collection Derleme @@ -22501,12 +23113,12 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: EÅŸ ayrıntıları - + Deny friend ArkadaÅŸlık isteÄŸini reddet - + Chat Sohbet @@ -22516,7 +23128,7 @@ arkadaÅŸlarınız da olumlu olarak deÄŸerlendirmemiÅŸ: Sohbet BaÅŸlat - + Expand GeniÅŸlet @@ -22787,13 +23399,13 @@ yardımcı olur. KeÅŸif Açık (Önerilir) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off KeÅŸif Kapalı @@ -23261,7 +23873,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network AÄŸ @@ -23289,7 +23901,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Durum @@ -23386,7 +23998,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Hizmet Adresi @@ -23421,12 +24033,12 @@ If you have issues connecting over Tor check the Tor logs too. Lütfen bir hizmet adresi yazın - + IP Range IP Aralığı - + Reported by DHT for IP masquerading DHT tarafından IP maskelemesi için bildirildi @@ -24094,7 +24706,7 @@ p, li { white-space: pre-wrap; } PGP Sertifikası Eksik - + Wrong password @@ -24148,7 +24760,7 @@ Bu seçim ayarlardan deÄŸiÅŸtirilebilir. StatisticsWindow - + Add Friend ArkadaÅŸ Ekle @@ -24204,7 +24816,7 @@ Bu seçim ayarlardan deÄŸiÅŸtirilebilir. Hizmet izinleri matrisi - + DHT DHT @@ -24744,7 +25356,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24754,13 +25366,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24769,6 +25380,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25062,35 +25698,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - %1 dosya indirildi + You have %1 completed transfers + - You have %1 completed download - %1 dosya indirildi + You have %1 completed transfer + - %1 completed downloads - %1 dosya indirildi + %1 completed transfers + - %1 completed download - %1 dosya indirildi + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + %1 dosya indirildi + + + You have %1 completed download + %1 dosya indirildi + + + %1 completed downloads + %1 dosya indirildi + + + %1 completed download + %1 dosya indirildi TransfersDialog - + Downloads Ä°ndirmeler @@ -25101,7 +25748,7 @@ p, li { white-space: pre-wrap; } Yüklemeler - + Name i.e: file name Ad @@ -25312,7 +25959,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Dosya Aktarımı</h1> <p>RetroShare iki ÅŸekilde dosya aktarımı sunar: ArkadaÅŸlarınızdan doÄŸrudan aktarım ve uzak isimsiz tünel aktarımı. Ek olarak, dosya aktarımı birden çok kaynak kullanabilir ve karşılıklıdır (indirme yapılırken yükleme de yapılır)</p> <p>Sol yan çubuktaki <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> simgesini kullanarak dosyaları paylaÅŸabilirsiniz. Paylaşılan dosyalar Dosyalarım sekmesi altında görüntülenir. Her bir arkadaÅŸ grubunuzun bu dosyaları kendi ArkadaÅŸların Dosyaları sekmelerinde görüp görümeyeceÄŸini seçebilirsiniz.</p> <p>Arama sekmesi arkadaÅŸlarınızın dosya listelerinde arama yapar ve birden çok sıçramalı tünel sistemi üzerinden uzak dosyalara isimsiz olarak eriÅŸebilir.</p> - + Move in Queue... Kuyrukta Taşı... @@ -25406,7 +26053,7 @@ p, li { white-space: pre-wrap; } Lütfen yeni -ve geçerli- bir dosya adı yazın - + Expand all Tümünü geniÅŸlet @@ -25538,7 +26185,7 @@ p, li { white-space: pre-wrap; } - + Columns Sütunlar @@ -25549,7 +26196,7 @@ p, li { white-space: pre-wrap; } Dosya Aktarımları - + Path Yol @@ -25559,7 +26206,7 @@ p, li { white-space: pre-wrap; } Yol Sütunu Görüntülensin - + Could not delete preview file Önizleme dosyası silinemedi @@ -25569,7 +26216,7 @@ p, li { white-space: pre-wrap; } Yeniden denensin mi? - + Create Collection... Derleme Ekle... @@ -25584,7 +26231,7 @@ p, li { white-space: pre-wrap; } Derlemeyi Görüntüle... - + Collection Derleme @@ -25830,7 +26477,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Bilinmeyen EÅŸ @@ -25926,7 +26573,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages %1 yeni iletiniz var @@ -26298,7 +26945,7 @@ p, li { white-space: pre-wrap; } Grup Ekle - + Subscribe to Group Gruba Abone Ol @@ -26392,8 +27039,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Düzenleme GeçmiÅŸi Görüntülensin @@ -26404,7 +27051,7 @@ p, li { white-space: pre-wrap; } - + Preview Önizleme @@ -26429,12 +27076,12 @@ p, li { white-space: pre-wrap; } Düzenleme GeçmiÅŸi Gizlensin - + Edit Page Sayfayı Düzenle - + Create New Wiki Page Yeni Wiki Sayfası Ekle @@ -26454,7 +27101,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Yeni Wiki Grubu Ekle @@ -26496,7 +27143,7 @@ p, li { white-space: pre-wrap; } ZamanAralığı - + Create Account @@ -26506,12 +27153,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Yenile @@ -26546,12 +27192,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26621,7 +27267,7 @@ p, li { white-space: pre-wrap; } Görüntülenen: - + Yourself Benimkiler @@ -26659,7 +27305,7 @@ p, li { white-space: pre-wrap; } Wire Ãœzerine Pulse Gönderin - + RetroShare @@ -26671,7 +27317,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26679,7 +27325,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26760,8 +27406,8 @@ p, li { white-space: pre-wrap; } Form - - + + Avatar Avatar @@ -26790,6 +27436,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26902,8 +27553,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Görseller (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Görseller (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_zh_CN.ts b/retroshare-gui/src/lang/retroshare_zh_CN.ts index f5769dd23..a07132cf4 100644 --- a/retroshare-gui/src/lang/retroshare_zh_CN.ts +++ b/retroshare-gui/src/lang/retroshare_zh_CN.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare 版本 @@ -79,7 +79,7 @@ ç¥æ‚¨ä½¿ç”¨æ„‰å¿« ;-) - + Only Hidden Node ä»…éšè—节点 @@ -129,12 +129,12 @@ RetroShare: 高级æœç´¢ - + Search Criteria æœç´¢æ¡ä»¶ - + Add a further search criterion. 追加æœç´¢æ¡ä»¶ã€‚ @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album 相册 @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } 表格 - - + + TextLabel 文字标签 @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } å·¥å…·æ  - + Icon Only åªå…许图标 @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } 选择工具æ æŒ‰é’®é£Žæ ¼ - + Icon Size = 8x8 å›¾æ ‡å¤§å° = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } å›¾æ ‡å¤§å° = 128x128 - + Status Bar 状æ€çƒ‚ @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } 系统托盘图标ä¸æç¤ºä¿¡æ¯ - + Main page items: 主页项目: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } 项目列表 - + Icon Size = 32x32 å›¾æ ‡å¤§å° = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } æ›´æ¢å¤´åƒ - + + TextLabel + + + + Your Avatar Picture 您的头åƒæ–‡ä»¶ - + + Browse... + + + Add Avatar - æ·»åŠ å¤´åƒ + æ·»åŠ å¤´åƒ @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } 删除 - + Set your Avatar picture è®¾ç½®å¤´åƒ - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - è½½å…¥å¤´åƒ + è½½å…¥å¤´åƒ AvatarWidget - - Choose avatar - - - - + Click to change your avatar ç‚¹å‡»æ›´æ”¹æ‚¨çš„å¤´åƒ @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare 带宽使用 + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 显示设置 + TextLabel + + + + Reset é‡ç½® - Receive Rate - 接收速度 + 接收速度 - Send Rate - å‘é€é€Ÿåº¦ + å‘é€é€Ÿåº¦ - + Always on Top 置顶 - Style - æ ·å¼ + æ ·å¼ - + Changes the transparency of the Bandwidth Graph 调整带宽图表的é€æ˜Žåº¦ - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % ä¸é€æ˜Ž - Save - ä¿å­˜ + ä¿å­˜ - Cancel - å–消 + å–消 - + Since: 自从: - Hide Settings - éšè—设置 + éšè—设置 BandwidthStatsWidget - + Sum 总和 @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } æ•°é‡ - + Average å¹³å‡ @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + 赞 + + + + 0 + 0 + + + + I dislike this + 踩 + + + + Toggle Message Read Status + 切æ¢æ¶ˆæ¯é˜…è¯»çŠ¶æ€ + + + + Avatar + å¤´åƒ + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展开 + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + éšè— + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale 日志 + + + Default + 默认 + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + 赞 + + + + 0 + 0 + + + + I dislike this + 踩 + + + + Toggle Message Read Status + 切æ¢æ¶ˆæ¯é˜…è¯»çŠ¶æ€ + + + + Avatar + å¤´åƒ + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展开 + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + éšè— + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to èŠå¤©å®¤ - You have %1 new messages - 您有 %1 ä¸ªæ–°æ¶ˆæ¯ + 您有 %1 ä¸ªæ–°æ¶ˆæ¯ + + + You have %1 new message + 您有 %1 ä¸ªæ–°æ¶ˆæ¯ + + + %1 new messages + %1 ä¸ªæ–°æ¶ˆæ¯ + + + %1 new message + %1 ä¸ªæ–°æ¶ˆæ¯ + + + + You have %1 mentions + - You have %1 new message - 您有 %1 ä¸ªæ–°æ¶ˆæ¯ + You have %1 mention + - %1 new messages - %1 ä¸ªæ–°æ¶ˆæ¯ + %1 mentions + - %1 new message - %1 ä¸ªæ–°æ¶ˆæ¯ + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All 删除全部 - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Double click a chat room to enter and chat. å˜é‡: - Group chat - ç¾¤èŠ + ç¾¤èŠ - - + Private chat ç§èŠ @@ -2191,17 +2404,16 @@ Double click a chat room to enter and chat. /meå‘é€æ¶ˆæ¯ç»™ /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">对于ä¸åŒçš„èŠå¤©ç³»ç»Ÿï¼Œè¿™ä¸ªé€‰é¡¹å¡æ˜¯ç”¨æ¥è®¾ç½®å…许RetroShareå¯ä»¥ä¿å­˜å¤šå°‘èŠå¤©æ¶ˆæ¯ï¼Œä»¥åŠæ˜¾ç¤ºå¤šå°‘æ¡è¿‡åŽ»çš„对è¯ã€‚最大存储周期å…许丢弃旧消æ¯ä»¥é˜²æ»žç•™è¿‡å¤šä¸é‡è¦çš„消æ¯(比如,èŠå¤©å®¤å’Œå¹´ä»£ä¹…远的èŠå¤©è®°å½•).</p></body></html> - Chatlobbies - èŠå¤©å®¤ + èŠå¤©å®¤ - + Enabled: å·²å¯ç”¨: @@ -2222,11 +2434,12 @@ Double click a chat room to enter and chat. + Chat rooms èŠå¤©å®¤ - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Double click a chat room to enter and chat. + Broadcast 广播 - + + Node-to-node chat + + + + Saved messages (0 = unlimited): å·²ä¿å­˜æ¶ˆæ¯(0=æ— é™åˆ¶) @@ -2438,8 +2657,23 @@ Double click a chat room to enter and chat. ç§èŠ - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Double click a chat room to enter and chat. - + is typing... 正在输入... @@ -2629,12 +2863,12 @@ after HTML conversion. 警告:è¿™æ¡ä¿¡æ¯åœ¨HTML转æ¢åŽè¿˜å¤šä½™%1个字符 - + Choose your font. 选择字体 - + Do you really want to physically delete the history? 您确认è¦åˆ é™¤èŠå¤©è®°å½•? @@ -2706,7 +2940,7 @@ after HTML conversion. X物å“å‘现åŽï¼Œè¯·å‹¿åœæ­¢ç€è‰²(需è¦æ›´å¤šCPUå ç”¨) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>查找以å‰çš„</b><br/><i>Ctrl+Shift+G</i> @@ -2746,12 +2980,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>标记选择文本</b><br><i>Ctrl+M</i> - + Person id: 个人ID @@ -2767,7 +3001,7 @@ Double click on it to add his name on text writer. 未签å - + items found. 已找到 @@ -2787,7 +3021,7 @@ Double click on it to add his name on text writer. åœ¨æ­¤è¾“å…¥æ¶ˆæ¯ - + Don't stop to color after 请勿åœæ­¢ç€è‰² @@ -2945,12 +3179,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 详情 - + Local Address æœ¬åœ°åœ°å€ @@ -2961,12 +3195,12 @@ Double click on it to add his name on text writer. å…¬ç½‘åœ°å€ - + Node info: 节点信æ¯: - + Current address: 当å‰åœ°å€: @@ -2982,31 +3216,36 @@ Double click on it to add his name on text writer. ç«¯å£ - + Include signatures 包å«ç­¾å - + RetroShare RetroShare - + - + Error : cannot get peer details. 错误:无法获å–节点详情。 - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3022,22 +3261,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption 加密 - + Not connected 未连接 - + Retroshare node details RetroShare节点详情 - + Node name : 节点å @@ -3072,13 +3316,18 @@ Double click on it to add his name on text writer. 状æ€æ¶ˆæ¯ï¼š - + + Connectivity + + + + List of known addresses: 已知地å€åˆ—表: - - + + Retroshare Certificate RetroShare è¯ä¹¦ @@ -3093,7 +3342,7 @@ Double click on it to add his name on text writer. - + Hidden Address éšè—åœ°å€ @@ -3104,11 +3353,12 @@ Double click on it to add his name on text writer. æ—  + <p>This certificate contains: - <p>æ­¤è¯ä¹¦åŒ…å«ï¼š + <p>æ­¤è¯ä¹¦åŒ…å«ï¼š - + <li>a <b>node ID</b> and <b>name</b> <li>a <b>节点 ID</b> å’Œ <b>åå­—</b> @@ -3121,12 +3371,12 @@ Double click on it to add his name on text writer. an <b>IP地å€</b> å’Œ<b>端å£</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>您å¯ä»¥ä½¿ç”¨æ­¤è¯ä¹¦ç»“交新朋å‹ã€‚通过电å­é‚®ä»¶å‘é€ï¼Œæˆ–手动å‘é€ã€‚</ p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>这是节点的ID <span style=" font-weight:600;">OpenSSL</span> è¯ä¹¦, 被下é¢ç”¨æˆ·ç­¾å过的:<span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3136,7 +3386,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>这个加密方å¼æ˜¯ <span style=" font-weight:600;">OpenSSL</span>. 到好å‹çš„连接</p><p>是强加密的,如果有DHE</p><p>&quot;安全效果会更加完美&quot;.</p></body></html> - + with å’Œ @@ -3342,12 +3592,12 @@ Double click on it to add his name on text writer. 请求详情 - + Peer details 节点详情 - + Name: å称: @@ -3365,12 +3615,12 @@ resources. 请注æ„,如果你添加太多的好å‹ï¼ŒRetroShare 将会需è¦å¤§é‡å¸¦å®½ï¼Œå†…存和CPUå ç”¨ï¼Œä½ å¯ä»¥å°½å¯èƒ½å¤šçš„加好å‹ï¼Œä½†æ˜¯è¶…过40个好å‹å¯èƒ½å°±ä¼šå ç”¨å¤§é‡èµ„æº - + Location: ä½ç½®: - + Options 选项 @@ -3407,12 +3657,12 @@ resources. 粘贴è¯ä¹¦ - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>这里åªèƒ½è¾“入你的好å‹çš„RetroShareè¯ä¹¦ã€‚ 注æ„,这跟你好å‹è´¦æˆ·çš„密钥是ä¸ä¸€æ ·çš„。ä¸è¦å†è¿™é‡Œç²˜è´´å¥½å‹çš„密钥,没用的 (就算是密钥的一部分也ä¸è¡Œ)。</p></body></html> - + Add friend to group: 添加至好å‹åˆ†ç»„: @@ -3422,7 +3672,7 @@ resources. 为好å‹çš„ PGP 密钥签å - + Please paste below your friend's Retroshare ID @@ -3447,7 +3697,7 @@ resources. - + Add as friend to connect with 添加为å¯ä»¥å»ºç«‹è¿žæŽ¥çš„å¥½å‹ @@ -3456,7 +3706,7 @@ resources. 点击完æˆå¯æŽ¥å—好å‹è¯·æ±‚。 - + Sorry, some error appeared 抱歉,出现错误 @@ -3476,32 +3726,32 @@ resources. 您的好å‹è¯¦æƒ…: - + Key validity: 密钥有效性: - + Profile ID: - + Signers ç­¾å者 - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">签署好å‹çš„钥匙是表达你对这个好å‹ï¼Œç»™ä½ çš„其他好å‹çš„信任的一ç§æ–¹å¼ã€‚ 下é¢çš„ç­¾å加密地è¯æ˜Žæ‰€åˆ—出的密钥的所有者将当å‰çš„PGP密钥识别为真实的</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. 此节点已ç»å­˜åœ¨äºŽæ‚¨çš„好å‹åˆ—表中。é‡å¤æ·»åŠ ä»…设置其IP地å€ã€‚ - + To accept the Friend Request, click the Accept button. @@ -3547,7 +3797,7 @@ resources. - + Certificate Load Failed è¯ä¹¦è½½å…¥å¤±è´¥ @@ -3584,12 +3834,12 @@ resources. è¯ä¹¦ä¼¼ä¹Žæœ‰æ•ˆ - + Not a valid Retroshare certificate! ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ RetroShare è¯ä¹¦ï¼ - + RetroShare Invitation RetroShare 邀请 @@ -3611,12 +3861,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? 这是你自己的è¯ä¹¦ï¼ä½ è¯¥ä¸ä¼šæ˜¯æƒ³å’Œè‡ªå·±äº¤æœ‹å‹å§ï¼Ÿ - + @@ -3664,7 +3914,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.您有一个好å‹è¯·æ±‚æ¥è‡ª - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3752,12 +4032,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.å¯ç”¨æ—¶ï¼Œä½œä¸ºç›´è¿žæ•°æ®æºã€‚ - + IP-Addr: IP 地å€: - + IP-Address IP 地å€: @@ -3823,7 +4103,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.将密钥添加到钥匙环中 - + This key is already in your keyring 密钥已存在于您的钥匙环中 @@ -3884,12 +4164,12 @@ even if you don't make friends. <p>æ­¤è¯ä¹¦æ²¡æœ‰IP。 你会ä¾é èŠ‚点å‘现和DHT找到它。 由于您需è¦æ¸…除白åå•ï¼ŒèŠ‚点将在NewsFeed选项å¡ä¸­å¼•å‘安全警告。 从那里,你å¯ä»¥å°†ä»–çš„IP列入白åå•ã€‚</ p> - + [Unknown] [未知] - + Added with certificate from %1 添加æ¥è‡ª1%çš„è¯ä¹¦ @@ -3976,7 +4256,12 @@ even if you don't make friends. UDP 结果 - + + Status + çŠ¶æ€ + + + <!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; } @@ -4398,7 +4683,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4550,7 +4835,7 @@ p, li { white-space: pre-wrap; } 未选择圈å­é™åˆ¶ - + [Unknown] [未知] @@ -4565,7 +4850,7 @@ p, li { white-space: pre-wrap; } 删除 - + Search æœç´¢ @@ -4585,7 +4870,7 @@ p, li { white-space: pre-wrap; } ç­¾å者:已知节点 - + Edit Circle ç¼–è¾‘åœˆå­ @@ -4605,12 +4890,12 @@ p, li { white-space: pre-wrap; } 匿å ID - + Circle name 圈å­å称 - + Update æ›´æ–° @@ -4636,7 +4921,7 @@ p, li { white-space: pre-wrap; } PGP å…³è” ID - + Add Member 添加æˆå‘˜ @@ -4780,7 +5065,7 @@ p, li { white-space: pre-wrap; } - + Attachments 附件 @@ -4826,7 +5111,7 @@ p, li { white-space: pre-wrap; } 从æœç´¢ç»“果中拖拽文件 - + Paste RetroShare Links 粘贴 RetroShare 链接 @@ -4836,7 +5121,7 @@ p, li { white-space: pre-wrap; } 粘贴 RetroShare 链接 - + Drop file error. 文件拖拽出错。 @@ -4863,17 +5148,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - 文件已添加并生æˆæ•£åˆ—校验值 + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + 文件已添加并生æˆæ•£åˆ—校验值 + + + Please add a Subject 请添加主题 @@ -4904,12 +5213,12 @@ p, li { white-space: pre-wrap; } ä½ çœŸçš„æƒ³ç”Ÿæˆ ï¼…1 消æ¯å—? - + You are about to add files you're not actually sharing. Do you still want this to happen? 你正在添加未分享的文件,ä»æƒ³ç»§ç»­? - + Edit Channel Post @@ -4929,7 +5238,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. å°†è¦åˆ†äº«ä¸€ä¸ªéžæ‰€æœ‰è€…的文件到一个频é“。 @@ -5021,7 +5330,7 @@ p, li { white-space: pre-wrap; } - + No Forum æ— è®ºå› @@ -5480,7 +5789,7 @@ and use the import button to load it DHTGraphSource - + users 用户 @@ -6487,7 +6796,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories 好å‹ç›®å½• @@ -6991,7 +7300,7 @@ at least one peer was not added to a group æœç´¢å¥½å‹ - + Mark all 标记全部 @@ -7005,7 +7314,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message 编辑状æ€æ¶ˆæ¯ @@ -7109,7 +7418,7 @@ at least one peer was not added to a group RetroShare 广而告之:此处的消æ¯ä¼šå‘给当å‰è¿žæŽ¥çš„所有好å‹ã€‚ - + Network 网络 @@ -7174,7 +7483,7 @@ at least one peer was not added to a group 节点字段需è¦æœ€å°‘3个字符 - + Failed to generate your new certificate, maybe PGP password is wrong! æ–°è¯ä¹¦ç”Ÿæˆå¤±è´¥ï¼Œå¯èƒ½æ‚¨çš„ PGP 密ç æœ‰è¯¯! @@ -7209,7 +7518,7 @@ at least one peer was not added to a group <html><head/><body><p>您的节点å称指定将在此计算机上è¿è¡Œçš„RetroShare实例。</p></body></html> - + Node name 节点å称 @@ -7476,12 +7785,12 @@ and use the import button to load it - + Profile generation failure 用户档案创建失败 - + Missing PGP certificate 丢失的 PGP è¯ä¹¦ @@ -7895,7 +8204,7 @@ p, li { white-space: pre-wrap; } 路由状æ€ç»Ÿè®¡ - + GroupBox 群组 @@ -7960,7 +8269,7 @@ p, li { white-space: pre-wrap; } åˆ†æ”¯å› å­ - + Details 详情 @@ -7983,7 +8292,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys 管ç†å¯†é’¥ @@ -8192,7 +8501,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 标题 @@ -8202,13 +8511,30 @@ p, li { white-space: pre-wrap; } æœç´¢æ ‡é¢˜ - - + + + + Description æè¿° - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description æœç´¢æè¿° @@ -8218,42 +8544,31 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - 按é™åºæŽ’列 + 按é™åºæŽ’列 - Sort Ascending Order - 按å‡åºæŽ’列 + 按å‡åºæŽ’列 - Sort by Name - 按åç§°æŽ’åº + 按åç§°æŽ’åº - Sort by Popularity - æŒ‰æ´»è·ƒåº¦æŽ’åº + æŒ‰æ´»è·ƒåº¦æŽ’åº - Sort by Last Post - æŒ‰æ–°è´´æ–‡æŽ’åº + æŒ‰æ–°è´´æ–‡æŽ’åº - - Sort by Number of Posts - - - - Sort by Unread - 按未读信æ¯åˆ†ç±» + 按未读信æ¯åˆ†ç±» - + You are admin (modify names and description using Edit menu) 你是管ç†å‘˜(修改åå­—å’Œæ述请用编辑èœå•) @@ -8268,40 +8583,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post 最新贴文 - + + Name - - Unread - - - - + Popularity 活跃度 - - + + Never ä»Žä¸ - Display - 显示 + 显示 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8450,7 +8760,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels é¢‘é“ @@ -8475,12 +8785,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;频é“</h1> <p> 频é“里你å¯ä»¥æŽ¨é€ (比如电影, 音ä¹) ,这些会传输到网络的å„处</p> <p>您å¯ä»¥çœ‹åˆ°æ‚¨çš„好å‹è®¢é˜…的频é“,并自动将订阅频é“转å‘给您的好å‹ã€‚这促进了网络中的良好沟通。</p> <p>åªæœ‰é¢‘é“的创建者å¯ä»¥åœ¨è¯¥é¢‘é“上å‘布。 网络中的其他对等体åªèƒ½ä»Žå…¶ä¸­è¯»å–,除éžè¯¥ä¿¡é“是ç§æœ‰çš„。然而,您å¯ä»¥ 与好å‹çš„RetroShare节点共享å‘布æƒé™æˆ–阅读æƒé™ã€‚</p> <p> 频é“也能设置为匿å的,或附加到RetroShare身份, 以便读者å¯ä»¥åœ¨éœ€è¦æ—¶è”系您。</p> <p> 频é“推é€èƒ½ä¿å­˜ %1 days, 能åŒæ­¥%2天以内的消æ¯ï¼Œé™¤éžä½ ä¿®æ”¹äº†è¿™ä¸ªã€‚</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels è®¢é˜…çš„é¢‘é“ @@ -9001,7 +9311,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -9101,12 +9411,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -9117,18 +9427,18 @@ p, li { white-space: pre-wrap; } - + Feeds 订阅 - - + + Click to switch to list view - + Show unread posts only @@ -9138,12 +9448,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9203,7 +9513,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9218,12 +9528,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9299,23 +9609,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed 已订阅 - - Subscribe 订阅 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected 未选择频é“! @@ -9337,11 +9660,6 @@ p, li { white-space: pre-wrap; } Channel Post 频é“文章 - - - new message(s) - - GxsCircleItem @@ -9858,7 +10176,7 @@ before you can comment 新建主题帖 - + Search forums æœç´¢è®ºå› @@ -9867,12 +10185,12 @@ before you can comment 最新贴文 - + New Thread æ–°å¸–å­ - + Threaded View è¯é¢˜è§†å›¾ @@ -9882,19 +10200,19 @@ before you can comment 普通视图 - - + + Title 标题 - - + + Date 日期 - + Author 作者 @@ -9909,7 +10227,17 @@ before you can comment 正在载入 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9970,23 +10298,23 @@ before you can comment <p>订阅论å›å°†æ”¶é›† 您订阅的好å‹çš„ å¯ç”¨å¸–å­ã€‚</p><p>之åŽï¼Œæ‚¨å¯ä»¥ä»Žå·¦ä¾§çš„论å›åˆ—表的上下文èœå•ä¸­å–消订阅。</p> - + No name 未命å - - + + Reply å›žå¤ - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -10024,12 +10352,12 @@ before you can comment 标为未读 - + Copy RetroShare Link å¤åˆ¶ RetroShare 链接 - + Hide éšè— @@ -10042,7 +10370,7 @@ before you can comment [被å±è”½çš„] - + [unknown] [未知] @@ -10072,8 +10400,8 @@ before you can comment åªæœ‰ä½ èƒ½çœ‹è§ - - + + Distribution 传播范围 @@ -10176,7 +10504,7 @@ before you can comment 原始贴文 - + New thread @@ -10185,7 +10513,7 @@ before you can comment 读å–çŠ¶æ€ - + Edit 编辑 @@ -10241,7 +10569,7 @@ before you can comment 在身份页显示作者 - + Author's reputation 作者的信誉 @@ -10261,7 +10589,7 @@ before you can comment - + <b>Loading...<b> @@ -10301,6 +10629,11 @@ before you can comment Storage 存储 + + + Last seen at friends: + + Moderators @@ -10393,7 +10726,7 @@ prevents the message to be forwarded to your friends. %1, %2 写é“: - + Forum name 论å›å称 @@ -10425,11 +10758,6 @@ prevents the message to be forwarded to your friends. Forum Post 邮件 - - - new message(s) - - GxsForumsDialog @@ -10878,7 +11206,7 @@ prevents the message to be forwarded to your friends. 打å°é¢„览 - + Unsubscribe 退订 @@ -10893,7 +11221,7 @@ prevents the message to be forwarded to your friends. 在新标签中打开 - + Remove this search @@ -10903,12 +11231,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details 显示细节 @@ -10975,7 +11303,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -10984,7 +11312,7 @@ prevents the message to be forwarded to your friends. 共享å‘布æƒé™ - + Copy RetroShare Link å¤åˆ¶ RetroShare 链接 @@ -10999,7 +11327,7 @@ prevents the message to be forwarded to your friends. 全部标为未读 - + AUTHD ä»…ç­¾å文章 @@ -11608,7 +11936,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -11617,7 +11945,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11643,6 +11971,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size: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; font-weight:600;">RetroShare Translations:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<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; font-weight:600;">RetroShare Website Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></p> +<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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> +<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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> +<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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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: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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11654,7 +11999,7 @@ p, li { white-space: pre-wrap; } <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; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</span></p> <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; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</span></p> <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-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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:9pt; font-weight:400; font-style:normal;"> @@ -11734,27 +12079,32 @@ p, li { white-space: pre-wrap; } è¡¨å• - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11776,6 +12126,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11784,7 +12135,7 @@ p, li { white-space: pre-wrap; } 下é¢çš„文本是你的 RetroShare è¯ä¹¦ã€‚把它å‘é€ç»™ä½ çš„å¥½å‹ - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11797,12 +12148,12 @@ private and secure decentralized communication platform. åˆæ¬¡ä½¿ç”¨å‘导 - + Open Web Help 打开网络帮助 - + Copy your Cert to Clipboard å¤åˆ¶æ‚¨çš„è¯ä¹¦åˆ°å‰ªè´´æ¿ @@ -11851,7 +12202,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11860,7 +12211,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12149,14 +12500,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All 全部 - + Reputation 信誉 @@ -12166,12 +12517,12 @@ p, li { white-space: pre-wrap; } æœç´¢ - + Anonymous Id 匿å ID - + Create new Identity 新建身份 @@ -12315,7 +12666,7 @@ p, li { white-space: pre-wrap; } 身份ID - + Send message å‘é€æ¶ˆæ¯ @@ -12387,7 +12738,7 @@ p, li { white-space: pre-wrap; } 总体: - + Anonymous 匿å @@ -12402,24 +12753,24 @@ p, li { white-space: pre-wrap; } æœç´¢ ID - + This identity is owned by you 这个身份被你是拥有者 - - + + My own identities 我所拥有的身份 - - + + My contacts 我的通讯录 - + Show Items 显示项目 @@ -12434,7 +12785,7 @@ p, li { white-space: pre-wrap; } 链接到我的节点 - + Other circles å…¶ä»–åœˆå­ @@ -12493,13 +12844,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). 订阅(接收/转å‘其他人的æˆå‘˜è¯·æ±‚和邀请列表)。 + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). 未订阅(仅能收到邀请列表) - + Your status: 你的状æ€ï¼š @@ -12559,7 +12915,7 @@ p, li { white-space: pre-wrap; } æˆå‘˜ - + Edit Circle ç¼–è¾‘åœˆå­ @@ -12607,7 +12963,7 @@ p, li { white-space: pre-wrap; } 授予会员资格 - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12619,12 +12975,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [未知节点] - + Unverified signature from node æ¥è‡ªèŠ‚点的未验è¯ç­¾å @@ -12636,12 +12992,12 @@ These identities will soon be not supported anymore. 未检查的签å - + [unverified] [未验è¯] - + Identity owned by you, linked to your Retroshare node 你所拥有的身份,链接到你的RetroShare节点 @@ -12765,17 +13121,17 @@ These identities will soon be not supported anymore. 你真的è¦ä»¥ä½ çš„è¯ä¹¦å‘é€é‚€è¯·å— - + Banned å·²å±è”½ - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;身份</h1> <p>身份在此选项å¡ä¸­ï¼Œä½ å¯ä»¥åˆ›å»º/编辑伪匿å身份<b>, å’Œ<b>圈å­</b>。</b> <p>身份<b> 身份用于安全地识别你的数æ®ï¼šä¸ºèŠå¤©å®¤ï¼Œè®ºå›å’Œé¢‘é“文章中的消æ¯ç­¾å, 使用 RetroShare 内置电å­é‚®ä»¶ç³»ç»ŸæŽ¥æ”¶å馈,在频é“å‘å¸ƒæ–‡ç« åŽ å‘表评论,使用安全隧é“èŠå¤©ç­‰ã€‚</p> <p>身份å¯ä»»æ„ç”±<b>ä½  RetroShare 节点的è¯ä¹¦</b>ç­¾å。 ç­¾å的身份更容易信任,但很容易链接到你节点的 IP 地å€ã€‚</b> <p><b>匿å身份</b>å…许您与其他用户匿å交互。 他们ä¸èƒ½ 被欺骗,但是没有人å¯ä»¥è¯æ˜Žè°çœŸæ­£æ‹¥æœ‰ä¸€ä¸ªç‰¹å®šçš„身份。</p> <p><b>圈å­</b>是通过网络远程共享的身份(匿å或签å)ç»„ï¼Œå®ƒä»¬å¯ ç”¨äºŽé™åˆ¶è®ºå›ï¼Œé¢‘é“等的å¯è§æ€§ç­‰<p>。</p> 一个<b>圈å­</b>å¯ä»¥å—é™äºŽå¦ä¸€ä¸ªåœˆå­ï¼Œä»Žè€Œé™åˆ¶å®ƒå¯¹è¯¥åœˆå­æˆå‘˜çš„å¯è§æ€§ï¼Œç”šè‡³é™åˆ¶åœˆå­æœ¬èº«çš„å¯è§æ€§ï¼Œè¿™æ„味ç€åªæœ‰è¢«é‚€è¯·çš„æˆå‘˜å¯ä»¥çœ‹åˆ°ã€‚ - + positive æ­£é¢çš„ @@ -12960,8 +13316,8 @@ These identities will soon be not supported anymore. - - + + People 人物 @@ -12972,7 +13328,7 @@ These identities will soon be not supported anymore. ä½ çš„å¤´åƒ - + Linked to neighbor nodes 链接到相邻节点 @@ -12982,7 +13338,7 @@ These identities will soon be not supported anymore. 链接到远程节点 - + Linked to a friend Retroshare node 链接到好å‹çš„RetroShare节点 @@ -13042,7 +13398,7 @@ These identities will soon be not supported anymore. 拥有者 - + Node name: 节点å称: @@ -13052,7 +13408,7 @@ These identities will soon be not supported anymore. 节点Id: - + Really delete? 真的è¦åˆ é™¤ï¼Ÿ @@ -13090,7 +13446,22 @@ These identities will soon be not supported anymore. 笔å - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity 新建身份 @@ -13107,14 +13478,14 @@ These identities will soon be not supported anymore. - + N/A ä¸é€‚用 - + Edit identity 编辑身份 @@ -13125,24 +13496,27 @@ These identities will soon be not supported anymore. æ›´æ–° - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13161,17 +13535,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! 错误:密钥获å–出错! - + Error KeyID invalid 错误:密钥ID无效 - + Unknown GpgId 未知 GPG ID @@ -13181,7 +13565,7 @@ These identities will soon be not supported anymore. 未知真实姓å*** - + Create New Identity 创建新身份 @@ -13191,7 +13575,12 @@ These identities will soon be not supported anymore. 类型 - + + Choose image... + + + + @@ -13231,12 +13620,11 @@ These identities will soon be not supported anymore. ä½ çš„å¤´åƒ - Set Avatar - è®¾ç½®å¤´åƒ + è®¾ç½®å¤´åƒ - + Linked to your profile 链接到你的用户档案 @@ -13246,7 +13634,7 @@ These identities will soon be not supported anymore. 您å¯ä»¥æ‹¥æœ‰ä¸€ä¸ªæˆ–多个身份。 当您在èŠå¤©å¤§åŽ…,论å›å’Œé¢‘é“中撰写评论时,会使用它们。 它们作为远程èŠå¤©å’ŒRetroShare远程邮件系统的接收地å€ã€‚ - + The nickname is too short. Please input at least %1 characters. 63/5000 昵称太短。 请输入至少%1个字符。 @@ -13356,8 +13744,12 @@ These identities will soon be not supported anymore. + Quote + 引用 + + Send - å‘é€ + å‘é€ @@ -13515,7 +13907,7 @@ These identities will soon be not supported anymore. - + Options 选项 @@ -13547,12 +13939,12 @@ These identities will soon be not supported anymore. 快速入门å‘导 - + RetroShare %1 a secure decentralized communication platform RetroShare %1 ― 一个分布å¼å®‰å…¨é€šä¿¡å¹³å° - + Unfinished æœªå®Œæˆ @@ -13685,7 +14077,7 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 显示 - + Make sure this link has not been forged to drag you to a malicious website. 请确认此连接ä¸æ˜¯ä¼ªé€ ï¼Œä¸æ˜¯æŒ‡å‘æ¶æ„网站。 @@ -13730,7 +14122,7 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 æœåŠ¡æƒé™åˆ—表 - + Statistics 统计 @@ -13759,7 +14151,7 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 MessageComposer - + Compose 写信 @@ -13861,7 +14253,7 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 - + Tags 标签 @@ -13956,12 +14348,12 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 添加大段引用 - + Send To: å‘é€è‡³: - + &Left &å·¦å¯¹é½ @@ -13995,7 +14387,7 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 我的通讯录 - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> 你好,<br>我å‘你推è我的一个好å‹ï¼›å¦‚果你信任我,也å¯ä»¥ä¿¡ä»»ä»–们。<br> @@ -14021,12 +14413,12 @@ RetroShare 将暂åœå¯¹æ­¤ç›®å½•çš„访问。 - + Save Message ä¿å­˜é‚®ä»¶ - + Message has not been Sent. Do you want to save message to draft box? 邮件未å‘é€ã€‚ @@ -14038,7 +14430,7 @@ Do you want to save message to draft box? 粘贴 RetroShare 链接 - + Add to "To" 添加至"收件人" @@ -14293,7 +14685,7 @@ Do you want to save message ? 添加é¢å¤–文件 - + Hi,<br>I want to be friends with you on RetroShare.<br> 你好,<br>我想与你æˆä¸º RetroShare 上的好å‹ã€‚<br> @@ -14302,12 +14694,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite 您有一æ¡å¥½å‹æŽ¨è - + Respond now: 现在回应: @@ -14323,11 +14730,12 @@ Do you want to save message ? å‘件人: + Friend Nodes - 好å‹èŠ‚点 + 好å‹èŠ‚点 - + Bullet list (disc) 列表(圆盘形) @@ -14367,13 +14775,13 @@ Do you want to save message ? 排åº(拉ä¸å­—æ¯å€’åº) - - + + Thanks, <br> æ„Ÿè°¢, <br> - + Distant identity: 远程身份 @@ -14512,8 +14920,23 @@ Do you want to save message ? 邮件 - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14525,12 +14948,12 @@ Do you want to save message ? 推è的文件 - + Download all Recommended Files 下载所有推è文件 - + Subject: 主题: @@ -14605,12 +15028,18 @@ Do you want to save message ? å‘é€é‚€è¯· - + + Message Size: + + + + File Name 文件å称 - + + Size å¤§å° @@ -14671,10 +15100,25 @@ Do you want to save message ? 下载 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? å‘é€é‚€è¯·ï¼Ÿ @@ -14685,12 +15129,12 @@ Do you want to save message ? - + Download all 下载全部 - + Print Document 打å°æ–‡æ¡£ @@ -14705,7 +15149,7 @@ Do you want to save message ? HTML 文件 (*.htm *.html);;所有文件 (*) - + Load images always for this message 此消æ¯æ€»æ˜¯è½½å…¥å›¾åƒ @@ -14846,7 +15290,7 @@ Do you want to save message ? MessagesDialog - + New Message æ–°ä¿¡æ¯ @@ -14902,14 +15346,14 @@ Do you want to save message ? - + Tags 标签 - + Inbox 收件箱 @@ -15004,7 +15448,7 @@ Do you want to save message ? 转å‘信件 - + Subject 主题 @@ -15116,7 +15560,7 @@ Do you want to save message ? - + Open in a new window 在新窗å£ä¸­æ‰“å¼€ @@ -15201,7 +15645,7 @@ Do you want to save message ? - + Drafts è‰ç¨¿ç®± @@ -15330,7 +15774,7 @@ Do you want to save message ? 回å¤æ¶ˆæ¯ - + Delete Message åˆ é™¤æ¶ˆæ¯ @@ -15341,7 +15785,7 @@ Do you want to save message ? - + Expand 展开 @@ -15351,7 +15795,7 @@ Do you want to save message ? 删除项目 - + from æ¥è‡ª @@ -15360,6 +15804,11 @@ Do you want to save message ? Reply to invite 回å¤é‚€è¯· + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15682,7 +16131,7 @@ Reported error: - + Groups 分组 @@ -15712,19 +16161,19 @@ Reported error: 导出你的好å‹åˆ—表包括分组 - - + + Search - + ID ID - + Search ID æœç´¢ ID @@ -15734,7 +16183,7 @@ Reported error: - + Show Items 显示项目 @@ -15938,18 +16387,18 @@ at least one peer was not added to a group - + Error 错误 - + File is not writeable! æ— æ³•å†™å…¥æ–‡ä»¶ï¼ - + File is not readable! 无法读å–æ–‡ä»¶ï¼ @@ -15986,9 +16435,13 @@ at least one peer was not added to a group NewsFeed - Log entries - 日志æ¡ç›® + 日志æ¡ç›® + + + + Activity Stream + @@ -16005,7 +16458,7 @@ at least one peer was not added to a group 这是一个测试。 - + Newest on top æ–°çš„åœ¨ä¸Šé¢ @@ -16016,8 +16469,12 @@ at least one peer was not added to a group + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;事件中心</h1> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;事件中心</h1> <p>事件中心显示网络上最近的事件,按您收到的时间排åºã€‚ 它为您æ供了一份好å‹æ´»åŠ¨æ‘˜è¦ã€‚您å¯ä»¥ç‚¹å‡»<b>选项</b>设置è¦æ˜¾ç¤ºçš„事件。</p> <p>å¯æ˜¾ç¤ºçš„å„ç§äº‹ä»¶åŒ…括: @@ -16027,16 +16484,35 @@ at least one peer was not added to a group <li>好å‹å‘é€çš„ç§äººæ¶ˆæ¯</li></ul> </p> - Log - 日志 + 日志 + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16073,22 +16549,22 @@ at least one peer was not added to a group - + Test 测试 - + Chat Room èŠå¤©å®¤ - + Systray Icon 系统托盘图标 - + Message 邮件 @@ -16113,12 +16589,11 @@ at least one peer was not added to a group IP安全 - Log - 日志 + 日志 - + Friend Connected 好å‹å·²è¿žæŽ¥ @@ -16132,7 +16607,12 @@ at least one peer was not added to a group 链接 - + + Activity + + + + Mails 邮件 @@ -16169,7 +16649,12 @@ at least one peer was not added to a group ç¾¤èŠ - + + Toaster position + + + + Chat rooms èŠå¤©å®¤ @@ -16182,22 +16667,22 @@ at least one peer was not added to a group 区分大å°å†™ - + Position ä½ç½® - + X Margin X è¾¹è· - + Y Margin Y è¾¹è· - + Systray message ç³»ç»Ÿæ‰˜ç›˜æ¶ˆæ¯ @@ -16247,7 +16732,7 @@ at least one peer was not added to a group æ示 - + Disable All Toasters ç¦ç”¨æ‰€æœ‰å¼¹å‡ºæ¶ˆæ¯ @@ -16261,7 +16746,7 @@ at least one peer was not added to a group 日志订阅 - + Systray 系统托盘 @@ -16407,17 +16892,16 @@ at least one peer was not added to a group PGPKeyDialog - Dialog - å¯¹è¯ + å¯¹è¯ - + Profile info ç”¨æˆ·ä¿¡æ¯ - + Name : åå­—: @@ -16472,22 +16956,21 @@ at least one peer was not added to a group ç»å¯¹ - + This profile has signed your own profile key 节点是å¦å¯¹æˆ‘çš„PGP密钥签å - Key signatures : - 密钥签å。 + 密钥签å。 - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">签署好å‹çš„钥匙是表达你对这个好å‹ï¼Œç»™ä½ çš„其他好å‹çš„信任的一ç§æ–¹å¼ã€‚ 下é¢çš„ç­¾å加密地è¯æ˜Žæ‰€åˆ—出的密钥的所有者将当å‰çš„PGP密钥识别为真实的</span></p></body></html> - + <!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; } @@ -16505,7 +16988,7 @@ p, li { white-space: pre-wrap; } 为此密钥签å - + PGP key PGP 密钥 @@ -16515,22 +16998,20 @@ p, li { white-space: pre-wrap; } 这些选项将应用到这个用户的所有节点 - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">签署好å‹çš„钥匙是表达你对这个好å‹ï¼Œç»™ä½ çš„其他好å‹çš„信任的一ç§æ–¹å¼ã€‚ 它å¯ä»¥å¸®åŠ©ä»–们决定是å¦å…许基于您自己的信任的密钥进行连接。 签署密钥是ç»å¯¹å¯é€‰çš„,ä¸èƒ½æ’¤é”€ï¼Œæ‰€ä»¥è¯·åšå‡ºæ˜Žæ™ºçš„选择.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">签署好å‹çš„钥匙是表达你对这个好å‹ï¼Œç»™ä½ çš„其他好å‹çš„信任的一ç§æ–¹å¼ã€‚ 它å¯ä»¥å¸®åŠ©ä»–们决定是å¦å…许基于您自己的信任的密钥进行连接。 签署密钥是ç»å¯¹å¯é€‰çš„,ä¸èƒ½æ’¤é”€ï¼Œæ‰€ä»¥è¯·åšå‡ºæ˜Žæ™ºçš„选择.</span></p></body></html> - + Keysigning: - Sign PGP key - 签署PGP密钥 + 签署PGP密钥 - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>如果è¦æ‹’ç»ä¸Žæ­¤å¯†é’¥éªŒè¯çš„节点的连接,请å•å‡»æ­¤å¤„。</p></body></html> @@ -16550,7 +17031,7 @@ p, li { white-space: pre-wrap; } 接å—连接 - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16620,28 +17101,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. 错误:无法获å–节点详情。 - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) RetroShare ä¸æ”¯æŒæ­¤å¯†é’¥ç®—法 (ç›®å‰ä»…æ”¯æŒ RSA 密钥) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16655,7 +17136,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. 信任级别是表达您对此密钥的信任的一ç§æ–¹å¼ã€‚ 它ä¸è¢«è½¯ä»¶ä½¿ç”¨ï¼Œä¹Ÿä¸æ˜¯å…±äº«çš„,仅用于方便记ä½å¥½/å的密钥。 @@ -16700,27 +17181,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.您目å‰ä¸å…许通过此密钥签åçš„RetroShare节点进行连接。 - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure ç­¾å失败 - - Maybe password is wrong - 密ç å¯èƒ½ä¸å¯¹ + + Check the password! + - + Maybe password is wrong + 密ç å¯èƒ½ä¸å¯¹ + + + You haven't set a trust level for this key. 你还没有对这个密钥设置信任等级 - + + Retroshare profile RetroShare用户档案 - + This is your own PGP key, and it is signed by : 这是你的密钥,签å人是: @@ -16899,8 +17400,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People 人物 @@ -16917,7 +17417,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.内部 - + Chat with this person 与此人èŠå¤© @@ -17068,7 +17568,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.照片 - + TextLabel 文字标签 @@ -17112,7 +17612,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -17148,6 +17648,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... 写评论... + + + Album + 相册 + PhotoItem @@ -17157,12 +17662,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.表格 - + TextLabel 文字标签 - + <!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; } @@ -17258,7 +17763,7 @@ p, li { white-space: pre-wrap; } 查看照片 - + PhotoShare 分享照片 @@ -17298,7 +17803,7 @@ requesting to edit it! - + Stop åœæ­¢ @@ -17526,12 +18031,12 @@ p, li { white-space:pre-wrapï¼›} PluginsPage - + Authorize all plugins å…许所有æ’件 - + Plugin look-up directories æ’件查找目录 @@ -17590,7 +18095,7 @@ malicious behavior of crafted plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;æ’件</h1> <p>æ’件从下列列表中目录中加载。</p> <p> 由于安全原因,接å—çš„æ’件自动加载 直到主RetroShareå¯æ‰§è¡Œæ–‡ä»¶æˆ–æ’件库更改。 在 è¿™ç§æƒ…况下,用户需è¦å†æ¬¡ç¡®è®¤ã€‚ 程åºå¯åŠ¨åŽï¼Œæ‚¨å¯ä»¥é€šè¿‡å•å‡»â€œå¯ç”¨â€æŒ‰é’®æ‰‹åŠ¨å¯ç”¨æ’件, 然åŽé‡æ–°å¯åŠ¨RetroShare。</p> <p>如果è¦å¼€å‘自己的æ’件,请è”系开å‘人员团队, 他们将ä¹æ„帮助您!</p> - + Plugins æ’件 @@ -17980,7 +18485,7 @@ malicious behavior of crafted plugins. 链接: - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18151,13 +18656,13 @@ malicious behavior of crafted plugins. 站点 - - + + Comments 注释 - + Copy RetroShare Link @@ -18167,7 +18672,7 @@ malicious behavior of crafted plugins. 在身份页显示作者 - + Comment 评论 @@ -18188,12 +18693,12 @@ malicious behavior of crafted plugins. - + Hide éšè— - + Vote up 赞 @@ -18207,7 +18712,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item 设置为已读并删除æ¡ç›® @@ -18268,7 +18773,7 @@ malicious behavior of crafted plugins. - + Loading 正在载入 @@ -18358,13 +18863,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18374,60 +18873,50 @@ malicious behavior of crafted plugins. 管ç†å‘˜ï¼š - - - + + + unknown 未知 - + Distribution: 传播范围 - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts è´´æ–‡ @@ -18438,7 +18927,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18507,7 +18996,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link @@ -18542,7 +19036,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18666,8 +19160,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18939,9 +19443,8 @@ and use the import button to load it PulseAddDialog - Post From: - è´´æ–‡æ¥è‡ªï¼š + è´´æ–‡æ¥è‡ªï¼š Account 1 @@ -18956,7 +19459,7 @@ and use the import button to load it 账户3 - + Add to Pulse 添加至 Pulse @@ -18979,17 +19482,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + å‘件人: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19014,10 +19532,20 @@ and use the import button to load it è´Ÿé¢çš„ - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19027,14 +19555,53 @@ and use the import button to load it - + + Post + + + + Cancel å–消 - Post Pulse to Wire - å‘wireå‘刺探包 + å‘wireå‘刺探包 + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19060,10 +19627,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image å›¾åƒ @@ -19071,44 +19646,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19118,17 +19693,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19138,7 +19713,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19146,7 +19721,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -19161,7 +19736,7 @@ and use the import button to load it - + follow Parent Group @@ -19171,7 +19746,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19196,7 +19771,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19232,29 +19807,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19332,7 +19907,7 @@ and use the import button to load it QObject - + Confirmation 确认 @@ -19572,7 +20147,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 结果 - + Unable to make path 无法创建路径 @@ -19607,7 +20182,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 文件请求已å–消 - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. 此版本的 RetroShare 正在使用 OpenPGP-SDK。因此没有使用系统中的共享PGP钥匙环,而是自有钥匙环,在所有RetroShare实例间共享。<br><br> 您似乎没有这ç§é’¥åŒ™çŽ¯ï¼Œå°½ç®¡çŽ°æœ‰ RetroShare 账户中引用了PGP密钥,也许您刚刚æ‰å‡çº§è‡³æ­¤æ–°ç‰ˆæœ¬ã€‚ @@ -19756,7 +20331,7 @@ Reported error is: s - + TR up 上行æµé‡ @@ -19801,7 +20376,7 @@ Reported error is: ç¦ç”¨ - + Move IP %1 to whitelist 添加%1至白åå• @@ -19817,7 +20392,7 @@ Reported error is: - + %1 seconds ago %1 ç§’å‰ @@ -19903,7 +20478,7 @@ Security: no anonymous IDs - + Error 错误 @@ -20294,9 +20869,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>æ­¤è¯ä¹¦åŒ…å«ï¼š + <p>æ­¤è¯ä¹¦åŒ…å«ï¼š @@ -20670,7 +21244,7 @@ p, li { white-space:pre-wrapï¼›} RSGraphWidget - + %1 KB %1 KB @@ -20892,19 +21466,48 @@ p, li { white-space:pre-wrapï¼›} RSTreeWidget - + Tree View Options 树状视图选项 - Show column... - 显示列 + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + 按é™åºæŽ’列 + + + + Sort Ascending Order + 按å‡åºæŽ’列 + + + + + [no title] + + + + + Show column … + + + + Show column... + 显示列 - [no title] - [无标题] + [无标题] @@ -21340,7 +21943,7 @@ p, li { white-space:pre-wrapï¼›} 下载! - + File 文件 @@ -21355,7 +21958,7 @@ p, li { white-space:pre-wrapï¼›} 散列值 - + Bad filenames have been cleaned 无效文件å已修改。 @@ -21405,7 +22008,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace ä¿å­˜ - + Collection Editor åˆé›†ç¼–辑者 @@ -21420,7 +22023,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace æ–‡ä»¶æ•°é‡ - + Real Size: Waiting child... 真实大å°:等待å­é›†... @@ -21435,12 +22038,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 这是一个目录,åŒå‡»å±•å¼€ - + Download files - + Specify... 指定... @@ -21689,7 +22292,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -21709,7 +22312,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21722,10 +22325,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 标题 + + + UnRead + + Date @@ -21737,7 +22345,7 @@ If you believe it is correct, remove the corresponding line from the file and re 作者 - + Information for this identity is currently missing. 这个身份的信æ¯çŽ°åœ¨ä¸¢å¤±äº† @@ -21777,7 +22385,7 @@ prevents the message to be forwarded to your friends. [未知] - + [ ... Missing Message ... ] [ ... ä¸¢å¤±æ¶ˆæ¯ ... ] @@ -21785,7 +22393,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 日期 @@ -21845,7 +22453,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22204,7 +22812,7 @@ prevents the message to be forwarded to your friends. 文件å称 - + Download 下载 @@ -22283,7 +22891,7 @@ prevents the message to be forwarded to your friends. 打开文件夹 - + Create Collection... 创建资æºé›†åˆ @@ -22303,7 +22911,7 @@ prevents the message to be forwarded to your friends. 从集åˆæ–‡ä»¶ä¸­ä¸‹è½½... - + Collection 资æºé›†åˆ @@ -22408,12 +23016,12 @@ prevents the message to be forwarded to your friends. 节点详情 - + Deny friend æ‹’ç»å¥½å‹ - + Chat èŠå¤© @@ -22423,7 +23031,7 @@ prevents the message to be forwarded to your friends. 开始èŠå¤© - + Expand 展开 @@ -22693,13 +23301,13 @@ behind a firewall or a VPN. 节点探索开å¯(推è) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off 节点探索关闭 @@ -23167,7 +23775,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network 网络 @@ -23195,7 +23803,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status çŠ¶æ€ @@ -23292,7 +23900,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address æœåŠ¡åœ°å€ @@ -23327,12 +23935,12 @@ If you have issues connecting over Tor check the Tor logs too. 请填写æœåŠ¡åœ°å€ - + IP Range IP 范围 - + Reported by DHT for IP masquerading DHT报告IP伪装 @@ -23999,7 +24607,7 @@ p, li { white-space: pre-wrap; } 缺失 PGP è¯ä¹¦ - + Wrong password 密ç é”™è¯¯ @@ -24055,7 +24663,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend æ·»åŠ å¥½å‹ @@ -24111,7 +24719,7 @@ This choice can be reverted in settings. æœåŠ¡æƒé™åˆ—表 - + DHT DHT @@ -24653,7 +25261,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24663,13 +25271,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor现在离线 - + Tor is OK Tor已就绪 @@ -24678,6 +25285,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24970,35 +25602,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - 您有 %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + You have %1 completed transfers + - You have %1 completed download - 您有 %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + You have %1 completed transfer + - %1 completed downloads - %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + %1 completed transfers + - %1 completed download - %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + 您有 %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + + + You have %1 completed download + 您有 %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + + + %1 completed downloads + %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ + + + %1 completed download + %1 ä¸ªä¸‹è½½ä»»åŠ¡å·²å®Œæˆ TransfersDialog - + Downloads 下载 @@ -25009,7 +25652,7 @@ p, li { white-space: pre-wrap; } 上传 - + Name i.e: file name å称 @@ -25225,7 +25868,7 @@ p, li { white-space: pre-wrap; } <p>æœç´¢æ ‡ç­¾åˆ—出æ¥è‡ªå¥½å‹æ–‡ä»¶åˆ—表中的文件,åŠé€šè¿‡å¤šè·³éš§é“系统匿åå¯è§çš„远程文件。</p> - + Move in Queue... 队列ä½ç½®... @@ -25319,7 +25962,7 @@ p, li { white-space: pre-wrap; } 输入新的有效文件å - + Expand all 全部展开 @@ -25451,7 +26094,7 @@ p, li { white-space: pre-wrap; } - + Columns 列 @@ -25462,7 +26105,7 @@ p, li { white-space: pre-wrap; } 文件传输 - + Path 路径 @@ -25472,7 +26115,7 @@ p, li { white-space: pre-wrap; } æ˜¾ç¤ºè·¯å¾„æ  - + Could not delete preview file ä¸èƒ½åˆ é™¤ä¹‹å‰æ–‡ä»¶ @@ -25482,7 +26125,7 @@ p, li { white-space: pre-wrap; } å†è¯•ä¸€æ¬¡ï¼Ÿ - + Create Collection... 创建资æºé›†åˆ @@ -25497,7 +26140,7 @@ p, li { white-space: pre-wrap; } 打开资æºé›†åˆ - + Collection 资æºé›†åˆ @@ -25743,7 +26386,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer 未知节点 @@ -25839,7 +26482,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages 您有 %1 ä¸ªæ–°æ¶ˆæ¯ @@ -26219,7 +26862,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group 订阅å°ç»„ @@ -26313,8 +26956,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History æ˜¾ç¤ºç¼–è¾‘åŽ†å² @@ -26325,7 +26968,7 @@ p, li { white-space: pre-wrap; } - + Preview 预览 @@ -26350,12 +26993,12 @@ p, li { white-space: pre-wrap; } éšè—ç¼–è¾‘åŽ†å² - + Edit Page ç¼–è¾‘é¡µé¢ - + Create New Wiki Page 创建新Wikié¡µé¢ @@ -26375,7 +27018,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group 创建新Wiki组 @@ -26417,7 +27060,7 @@ p, li { white-space: pre-wrap; } 时间范围 - + Create Account @@ -26427,12 +27070,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh 刷新 @@ -26467,12 +27109,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26542,7 +27184,7 @@ p, li { white-space: pre-wrap; } 当å‰æ˜¾ç¤º: - + Yourself 我自己 @@ -26580,7 +27222,7 @@ p, li { white-space: pre-wrap; } å‘wireå‘刺探包 - + RetroShare @@ -26592,7 +27234,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26600,7 +27242,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26681,8 +27323,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar å¤´åƒ @@ -26711,6 +27353,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26823,8 +27470,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - 图片 (*.png *.xpm *.jpg *.tiff *.gif *.jpeg) + 图片 (*.png *.xpm *.jpg *.tiff *.gif *.jpeg) diff --git a/retroshare-gui/src/lang/retroshare_zh_TW.ts b/retroshare-gui/src/lang/retroshare_zh_TW.ts index d6d5a0959..92a16dae4 100644 --- a/retroshare-gui/src/lang/retroshare_zh_TW.ts +++ b/retroshare-gui/src/lang/retroshare_zh_TW.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -167,7 +167,7 @@ AlbumDialog - + Album @@ -286,7 +286,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -329,8 +329,8 @@ p, li { white-space: pre-wrap; } 表單 - - + + TextLabel @@ -397,7 +397,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -422,7 +422,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -447,7 +447,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -522,7 +522,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -537,7 +537,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -603,13 +603,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -618,25 +623,30 @@ p, li { white-space: pre-wrap; } 刪除 - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -644,7 +654,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -664,44 +674,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings é¸é … + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -711,30 +730,19 @@ p, li { white-space: pre-wrap; } - - Save - - - - Cancel - å–消 + å–消 - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -756,7 +764,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -890,7 +898,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -968,6 +976,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展開 + + + + Set as read and remove item + 設置為已讀并刪除項目 + + + + Remove Item + 刪除項目 + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + éš±è— + + BwCtrlWindow @@ -1103,6 +1190,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1155,6 +1252,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展開 + + + + Set as read and remove item + 設置為已讀并刪除項目 + + + + Remove Item + 刪除項目 + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + éš±è— + + ChatLobbyDialog @@ -1363,22 +1539,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1392,11 +1568,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1821,13 +1992,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1892,17 +2057,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1923,11 +2083,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1988,11 +2149,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2131,8 +2298,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2301,7 +2483,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2318,12 +2500,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2395,7 +2577,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2431,12 +2613,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2452,7 +2634,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2472,7 +2654,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2630,12 +2812,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2646,12 +2828,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2667,31 +2849,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2707,22 +2899,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2757,13 +2949,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2778,7 +2975,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2789,17 +2986,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2809,7 +3011,7 @@ Double click on it to add his name on text writer. - + with @@ -2893,32 +3095,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: å稱: - + Location: - + Options é¸é … - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2928,7 +3130,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2953,12 +3155,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2978,32 +3180,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3049,17 +3251,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3079,12 +3281,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3132,7 +3334,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3176,12 +3408,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3211,7 +3443,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3269,12 +3501,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3349,7 +3581,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3771,7 +4008,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3915,7 +4152,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3930,7 +4167,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3946,7 +4183,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3962,12 +4199,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3989,7 +4226,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4115,7 +4352,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4161,7 +4398,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4171,7 +4408,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4198,17 +4435,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4239,12 +4496,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4264,7 +4521,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4352,7 +4609,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4767,7 +5024,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5770,7 +6027,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6261,7 +6518,7 @@ at least one peer was not added to a group - + Mark all @@ -6275,7 +6532,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6379,7 +6636,7 @@ at least one peer was not added to a group - + Network @@ -6444,7 +6701,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6475,7 +6732,7 @@ at least one peer was not added to a group - + Node name @@ -6734,12 +6991,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7102,7 +7359,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7167,7 +7424,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7190,7 +7447,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7391,7 +7648,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 標題 @@ -7401,13 +7658,30 @@ p, li { white-space: pre-wrap; } æœç´¢æ¨™é¡Œ - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7417,42 +7691,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7467,40 +7706,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7649,7 +7879,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7670,12 +7900,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8068,7 +8298,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8168,12 +8398,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8184,18 +8414,18 @@ p, li { white-space: pre-wrap; } - + Feeds 訂閱 - - + + Click to switch to list view - + Show unread posts only @@ -8205,12 +8435,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8270,7 +8500,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8285,12 +8515,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8366,23 +8596,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8404,11 +8647,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8893,17 +9131,17 @@ before you can comment - + Search forums æœç´¢è«–壇 - + New Thread - + Threaded View @@ -8913,19 +9151,19 @@ before you can comment - - + + Title 標題 - - + + Date 日期 - + Author 作者 @@ -8940,7 +9178,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8985,23 +9233,23 @@ before you can comment æœç´¢ä½œè€… - + No name 未命å - - + + Reply - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Loading... @@ -9039,12 +9287,12 @@ before you can comment 標為未讀 - + Copy RetroShare Link - + Hide éš±è— @@ -9053,7 +9301,7 @@ before you can comment 展開 - + [unknown] @@ -9083,8 +9331,8 @@ before you can comment - - + + Distribution @@ -9167,12 +9415,12 @@ before you can comment - + New thread - + Edit 編輯 @@ -9228,7 +9476,7 @@ before you can comment - + Author's reputation @@ -9248,7 +9496,7 @@ before you can comment - + <b>Loading...<b> @@ -9288,6 +9536,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9355,7 +9608,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9387,11 +9640,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9797,7 +10045,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9812,7 +10060,7 @@ This message is missing. You should receive it later. 在新標簽中打開 - + Remove this search @@ -9822,12 +10070,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9894,12 +10142,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9914,7 +10162,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10428,7 +10676,7 @@ This message is missing. You should receive it later. <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -10437,7 +10685,7 @@ p, li { white-space: pre-wrap; } <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <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; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10463,7 +10711,7 @@ p, li { white-space: pre-wrap; } <!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:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10537,49 +10785,55 @@ p, li { white-space: pre-wrap; } 表單 - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10627,17 +10881,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10652,7 +10901,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10917,14 +11171,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10934,12 +11188,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11083,7 +11337,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11155,7 +11409,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11170,24 +11424,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11202,7 +11456,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11261,13 +11515,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11327,7 +11586,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11375,7 +11634,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11384,12 +11643,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11401,12 +11660,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11522,17 +11781,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11689,8 +11948,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11701,7 +11960,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11711,7 +11970,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11771,7 +12030,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11781,7 +12040,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11819,7 +12078,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11836,14 +12095,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11854,24 +12113,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11891,12 +12153,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11906,7 +12193,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11916,7 +12203,12 @@ These identities will soon be not supported anymore. é¡žåž‹ - + + Choose image... + + + + @@ -11956,12 +12248,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11971,7 +12258,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12076,7 +12363,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12235,7 +12522,7 @@ These identities will soon be not supported anymore. - + Options é¸é … @@ -12267,12 +12554,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12401,7 +12688,7 @@ These identities will soon be not supported anymore. 顯示 - + Make sure this link has not been forged to drag you to a malicious website. @@ -12446,7 +12733,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12475,7 +12762,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12577,7 +12864,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12672,12 +12959,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12707,7 +12994,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12733,12 +13025,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12749,7 +13041,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -13003,7 +13295,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13017,6 +13309,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13029,7 +13336,7 @@ Do you want to save message ? 從: - + Bullet list (disc) @@ -13069,13 +13376,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13214,8 +13521,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13227,12 +13549,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13307,12 +13629,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13373,18 +13701,33 @@ Do you want to save message ? 下載 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13399,7 +13742,7 @@ Do you want to save message ? - + Load images always for this message @@ -13508,7 +13851,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13524,14 +13867,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13602,7 +13945,7 @@ Do you want to save message ? - + Subject @@ -13682,7 +14025,7 @@ Do you want to save message ? - + Open in a new window @@ -13767,7 +14110,7 @@ Do you want to save message ? - + Drafts @@ -13856,7 +14199,7 @@ Do you want to save message ? - + Delete Message @@ -13867,7 +14210,7 @@ Do you want to save message ? - + Expand 展開 @@ -13877,7 +14220,7 @@ Do you want to save message ? 刪除項目 - + from @@ -13886,6 +14229,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14185,7 +14533,7 @@ Reported error: - + Groups @@ -14215,19 +14563,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14237,7 +14585,7 @@ Reported error: - + Show Items @@ -14436,18 +14784,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14485,7 +14833,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14499,7 +14847,7 @@ at least one peer was not added to a group - + Newest on top @@ -14510,20 +14858,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14556,22 +14919,22 @@ at least one peer was not added to a group - + Test 測試 - + Chat Room - + Systray Icon - + Message @@ -14592,12 +14955,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14644,27 +15002,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14714,7 +15082,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14728,7 +15096,7 @@ at least one peer was not added to a group 訂閱 - + Systray @@ -14855,17 +15223,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14920,22 +15283,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14949,7 +15307,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14959,22 +15317,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14994,7 +15342,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15060,27 +15408,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15092,7 +15440,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15137,27 +15485,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15328,8 +15692,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15346,7 +15709,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15485,7 +15848,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15521,7 +15884,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15549,6 +15912,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... ... + + + Album + + PhotoItem @@ -15558,12 +15926,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.表單 - + TextLabel - + <!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; } @@ -15643,7 +16011,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15683,7 +16051,7 @@ requesting to edit it! - + Stop @@ -15907,17 +16275,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16243,7 +16611,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16374,13 +16742,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16390,7 +16758,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16411,12 +16779,12 @@ p, li { white-space: pre-wrap; } - + Hide éš±è— - + Vote up @@ -16426,7 +16794,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item 設置為已讀并刪除項目 @@ -16487,7 +16855,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16529,13 +16897,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16545,60 +16907,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16609,7 +16961,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16678,7 +17030,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16713,7 +17070,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16829,8 +17186,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17098,12 +17465,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17118,17 +17480,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + 從: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17153,10 +17530,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17166,13 +17553,48 @@ and use the import button to load it - + + Post + + + + Cancel å–消 - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17199,10 +17621,18 @@ and use the import button to load it 表單 - - - - + + + + + Click to view picture + + + + + + + Image @@ -17210,44 +17640,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17257,17 +17687,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17277,7 +17707,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17285,7 +17715,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17300,7 +17730,7 @@ and use the import button to load it - + follow Parent Group @@ -17310,7 +17740,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17335,7 +17765,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17371,29 +17801,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17471,7 +17901,7 @@ and use the import button to load it QObject - + Confirmation @@ -17710,7 +18140,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17745,7 +18175,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17883,7 +18313,7 @@ Reported error is: s - + TR up @@ -17928,7 +18358,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17944,7 +18374,7 @@ Reported error is: - + %1 seconds ago @@ -18028,7 +18458,7 @@ Security: no anonymous IDs - + Error @@ -18418,11 +18848,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18756,7 +19181,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18978,18 +19403,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19426,7 +19872,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19441,7 +19887,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19489,7 +19935,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19504,7 +19950,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19519,12 +19965,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19771,7 +20217,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19791,7 +20237,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19804,10 +20250,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 標題 + + + UnRead + + Date @@ -19819,7 +20270,7 @@ If you believe it is correct, remove the corresponding line from the file and re 作者 - + Information for this identity is currently missing. @@ -19857,7 +20308,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19865,7 +20316,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 日期 @@ -19925,7 +20376,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20279,7 +20730,7 @@ prevents the message to be forwarded to your friends. - + Download 下載 @@ -20358,7 +20809,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20378,7 +20829,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20483,12 +20934,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20498,7 +20949,7 @@ prevents the message to be forwarded to your friends. - + Expand 展開 @@ -20761,13 +21212,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21233,7 +21684,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21261,7 +21712,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21358,7 +21809,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21393,12 +21844,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22063,7 +22514,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22105,7 +22556,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22161,7 +22612,7 @@ This choice can be reverted in settings. - + DHT @@ -22693,7 +23144,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22703,13 +23154,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22718,6 +23168,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22991,27 +23466,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23019,7 +23489,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23030,7 +23500,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23237,7 +23707,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23331,7 +23801,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23463,7 +23933,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23474,7 +23944,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23484,7 +23954,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23494,7 +23964,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23509,7 +23979,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23751,7 +24221,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23847,7 +24317,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24215,7 +24685,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24309,8 +24779,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24321,7 +24791,7 @@ p, li { white-space: pre-wrap; } - + Preview é è¦½ @@ -24346,12 +24816,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24371,7 +24841,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24409,7 +24879,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24419,12 +24889,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24459,12 +24928,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24498,7 +24967,7 @@ p, li { white-space: pre-wrap; } 新建 - + Yourself @@ -24508,7 +24977,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24520,7 +24989,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24528,7 +24997,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24609,8 +25078,8 @@ p, li { white-space: pre-wrap; } 表單 - - + + Avatar @@ -24639,6 +25108,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24751,7 +25225,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) From ab12f531d0b93929fe5f0627509d82c2115629b7 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 26 Feb 2021 10:39:38 +0100 Subject: [PATCH 013/697] fixed removal of board share publish permission entry in drop menu --- retroshare-gui/src/gui/Posted/PostedDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 1364cf2d7..15ce3139b 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -192,7 +192,8 @@ GxsGroupDialog *PostedDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxs int PostedDialog::shareKeyType() { - return POSTED_KEY_SHARE; + //return POSTED_KEY_SHARE; + return 0; // Boards are public. By the time we offer the possibility to make them restricted, we need to not show the 'share publish permission' entry in the drop menu. } GxsMessageFrameWidget *PostedDialog::createMessageFrameWidget(const RsGxsGroupId &groupId) From 8e61b0ce4f0893392b296efaeff973d84b83750b Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 26 Feb 2021 11:16:01 +0100 Subject: [PATCH 014/697] moved key share consts into an enum in GroupKeyShare class --- retroshare-gui/src/gui/Posted/PostedDialog.cpp | 2 +- retroshare-gui/src/gui/gxs/GxsGroupShareKey.h | 10 +++++++--- .../src/gui/gxschannels/GxsChannelDialog.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 15ce3139b..f1837da3b 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -193,7 +193,7 @@ GxsGroupDialog *PostedDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxs int PostedDialog::shareKeyType() { //return POSTED_KEY_SHARE; - return 0; // Boards are public. By the time we offer the possibility to make them restricted, we need to not show the 'share publish permission' entry in the drop menu. + return GroupShareKey::NO_KEY_SHARE; // Boards are public. By the time we offer the possibility to make them restricted, we need to not show the 'share publish permission' entry in the drop menu. } GxsMessageFrameWidget *PostedDialog::createMessageFrameWidget(const RsGxsGroupId &groupId) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h index ed8df360a..441d5e41d 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h @@ -25,9 +25,6 @@ #include "ui_GxsGroupShareKey.h" -#define CHANNEL_KEY_SHARE 0x00000001 -#define FORUM_KEY_SHARE 0x00000002 -#define POSTED_KEY_SHARE 0x00000003 class GroupShareKey : public QDialog { @@ -40,6 +37,13 @@ public: GroupShareKey(QWidget *parent = 0, const RsGxsGroupId& grpId = RsGxsGroupId(), int grpType = 0); ~GroupShareKey(); + enum KeyShareType: uint8_t { + NO_KEY_SHARE = 0x00000000, + CHANNEL_KEY_SHARE = 0x00000001, + FORUM_KEY_SHARE = 0x00000002, + POSTED_KEY_SHARE = 0x00000003, + }; + protected: void changeEvent(QEvent *e); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 5d08ea707..e18a161a3 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -207,7 +207,7 @@ GxsGroupDialog *GxsChannelDialog::createGroupDialog(GxsGroupDialog::Mode mode, R int GxsChannelDialog::shareKeyType() { - return CHANNEL_KEY_SHARE; + return GroupShareKey::CHANNEL_KEY_SHARE; } GxsMessageFrameWidget *GxsChannelDialog::createMessageFrameWidget(const RsGxsGroupId &groupId) From 339948a15cbfe32c239b371e0ca8a9a26b51365a Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 26 Feb 2021 23:01:41 +0100 Subject: [PATCH 015/697] added missing event for FriendList when friends added now that notifyQt is not used anymore --- libretroshare/src/rsserver/p3peers.cc | 25 ++++++++++++------- libretroshare/src/rsserver/p3peers.h | 2 +- .../src/gui/common/NewFriendList.cpp | 1 + 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 7223eec90..4bcb09694 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -121,15 +121,21 @@ p3Peers::p3Peers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm) :mLinkMgr(lm), mPeerMgr(pm), mNetMgr(nm) {} /* Updates ... */ -bool p3Peers::FriendsChanged(bool add) +bool p3Peers::FriendsChanged(const RsPeerId& pid,bool add) { #ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::FriendsChanged()" << std::endl; + std::cerr << "p3Peers::FriendsChanged()" << std::endl; #endif - RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, add? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mSslId = pid; + rsEvents->postEvent(ev); + } + RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, add? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); // this is meant to disappear - /* TODO */ - return false; + /* TODO */ + return false; } bool p3Peers::OthersChanged() @@ -769,7 +775,7 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe return true; } - FriendsChanged(true); + FriendsChanged(ssl_id,true); /* otherwise - we install as ssl_id..... * If we are adding an SSL certificate. we flag lastcontact as now. @@ -783,7 +789,7 @@ bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,con { if( mPeerMgr->addSslOnlyFriend(sslId, pgp_id,details)) { - FriendsChanged(true); + FriendsChanged(sslId,true); return true; } else @@ -802,8 +808,9 @@ bool p3Peers::removeFriendLocation(const RsPeerId &sslId) #endif //will remove if it's a ssl id mPeerMgr->removeFriend(sslId, false); - return true; + FriendsChanged(sslId,false); + return true; } bool p3Peers::removeFriend(const RsPgpId& gpgId) @@ -1641,7 +1648,7 @@ bool p3Peers::loadCertificateFromString( if(res) { mPeerMgr->notifyPgpKeyReceived(gpgid); - FriendsChanged(true); + FriendsChanged(ssl_id,true); } return res; diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index 9b0a7666f..56f1f73e6 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -48,7 +48,7 @@ public: virtual ~p3Peers() {} /* Updates ... */ - virtual bool FriendsChanged(bool add); + virtual bool FriendsChanged(const RsPeerId &pid, bool add); virtual bool OthersChanged(); /* Peer Details (Net & Auth) */ diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 16f356957..7f139b794 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -179,6 +179,7 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par mEventHandlerId_peer=0; // forces initialization mEventHandlerId_gssp=0; // forces initialization + rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_STATE_CHANGED ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_gssp, RsEventType::GOSSIP_DISCOVERY ); From b16c30bc3fe20b5520dc43d62b4ab687c4d6ed80 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 26 Feb 2021 23:20:48 +0100 Subject: [PATCH 016/697] fixed registration of event handler --- libretroshare/src/rsserver/p3peers.cc | 3 +-- retroshare-gui/src/gui/common/NewFriendList.cpp | 4 +++- retroshare-gui/src/gui/common/NewFriendList.h | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 4bcb09694..c44877fc5 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -128,8 +128,7 @@ bool p3Peers::FriendsChanged(const RsPeerId& pid,bool add) #endif if(rsEvents) { - auto ev = std::make_shared(); - ev->mSslId = pid; + auto ev = std::make_shared(pid); rsEvents->postEvent(ev); } RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, add? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); // this is meant to disappear diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 7f139b794..1cfa05ef4 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -178,8 +178,9 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par mEventHandlerId_peer=0; // forces initialization mEventHandlerId_gssp=0; // forces initialization + mEventHandlerId_pssc=0; // forces initialization - rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_STATE_CHANGED ); + rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_pssc, RsEventType::PEER_STATE_CHANGED ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_gssp, RsEventType::GOSSIP_DISCOVERY ); @@ -267,6 +268,7 @@ NewFriendList::~NewFriendList() { rsEvents->unregisterEventsHandler(mEventHandlerId_peer); rsEvents->unregisterEventsHandler(mEventHandlerId_gssp); + rsEvents->unregisterEventsHandler(mEventHandlerId_pssc); delete mModel; delete mProxyModel; diff --git a/retroshare-gui/src/gui/common/NewFriendList.h b/retroshare-gui/src/gui/common/NewFriendList.h index 79b2d0a5a..224cc0a11 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.h +++ b/retroshare-gui/src/gui/common/NewFriendList.h @@ -123,6 +123,7 @@ private: bool mShowState; RsEventsHandlerId_t mEventHandlerId_peer; RsEventsHandlerId_t mEventHandlerId_gssp; + RsEventsHandlerId_t mEventHandlerId_pssc; std::set openGroups; std::set openPeers; From ae8071c6d92fe27ebc3d71241c9ecf8d58c6ace6 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 27 Feb 2021 12:30:57 +0100 Subject: [PATCH 017/697] Fixing fonts stylesheets for boards --- retroshare-gui/src/gui/qss/stylesheet/Standard.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index e79ec6d1c..a9c191749 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -1041,7 +1041,7 @@ BoardPostDisplayWidget_card > QFrame#mainFrame[new=true] { BoardPostDisplayWidget_compact QLabel#titleLabel, BoardPostDisplayWidget_card QLabel#titleLabel{ - font-size: 14pt; + font-size: 12pt; font: bold; } From 1e1032ec9420a29c85bdaa40c09c7e37d5d4989e Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 27 Feb 2021 20:43:41 +0100 Subject: [PATCH 018/697] attempt to fix some issues on comments feeds --- retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp | 4 +++- retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui | 8 +++++++- retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp | 4 ++-- retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui | 11 ++++++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp index 757d10ec5..670567f03 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp @@ -422,7 +422,9 @@ void BoardsCommentsItem::makeUpVote() void BoardsCommentsItem::setComment(const RsGxsComment& cmt) { - ui->commLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(cmt.mComment.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS)); + uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + + ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));; ui->nameLabel->setId(cmt.mMeta.mAuthorId); ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs)); diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui index 5b244fe90..b3e529091 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui @@ -44,6 +44,9 @@ 9 + + 3 + @@ -279,7 +282,7 @@ 20 - 10 + 6 @@ -377,6 +380,9 @@ 0 + + 3 + diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp index bfa33cde9..88b724598 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp @@ -305,7 +305,7 @@ void ChannelsCommentsItem::loadMessage() RsQThreadUtils::postToObject( [cmt,this]() { - uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -434,7 +434,7 @@ void ChannelsCommentsItem::fill() /* subject */ //ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str())); - uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); // fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy //ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui index c686adb3c..45c55b841 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui @@ -44,6 +44,12 @@ 9 + + 6 + + + 3 + @@ -262,6 +268,9 @@ 0 + + 3 + @@ -391,7 +400,7 @@ 58 - 10 + 6 From 3e4841426dc7e2da9aa955f1c6f6c431caf06230 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Feb 2021 15:49:58 +0100 Subject: [PATCH 019/697] added debug tags around GxsIdDetails --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 7ec21aa96..51dbcf2bc 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -61,6 +61,8 @@ #define MAX_ATTEMPTS 10 #define MAX_PROCESS_COUNT_PER_TIMER 50 +// #define DEBUG_GXSIDDETAILS 1 + //const int kRecognTagClass_DEVELOPMENT = 1; // //const int kRecognTagType_Dev_Ambassador = 1; @@ -468,7 +470,9 @@ void GxsIdDetails::checkCleanImagesCache() if(mLastIconCacheCleaning + DELAY_BETWEEN_ICON_CACHE_CLEANING < now) { +#ifdef DEBUG_GXSIDDETAILS std::cerr << "(II) Cleaning the icons cache." << std::endl; +#endif int nb_deleted = 0; uint32_t size_deleted = 0; uint32_t total_size = 0; @@ -478,7 +482,9 @@ void GxsIdDetails::checkCleanImagesCache() for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();) { bool all_empty = true ; +#ifdef DEBUG_GXSIDDETAILS std::cerr << " Examining pixmaps sizes for " << it->first << "." << std::endl; +#endif for(int i=0;i<4;++i) if(it->second[i].first>0) @@ -487,7 +493,9 @@ void GxsIdDetails::checkCleanImagesCache() { int s = it->second[i].second.width()*it->second[i].second.height()*4; +#ifdef DEBUG_GXSIDDETAILS std::cerr << " Deleting pixmap " << it->first << " size " << i << " " << s << " bytes." << std::endl; +#endif it->second[i].second = QPixmap(); it->second[i].first = 0; @@ -498,13 +506,17 @@ void GxsIdDetails::checkCleanImagesCache() { all_empty = false; total_size += it->second[i].second.width()*it->second[i].second.height()*4; +#ifdef DEBUG_GXSIDDETAILS std::cerr << " Keeking " << it->first << " size " << i << std::endl; +#endif } } if(all_empty) { +#ifdef DEBUG_GXSIDDETAILS std::cerr << " Deleting entry " << it->first << " because no pixmaps are stored here. " << std::endl; +#endif it = mDefaultIconCache.erase(it); } else @@ -534,7 +546,9 @@ bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len, // the same image to be allocated many times. We do this using a cache. The cache is also cleaned-up // on a regular time basis so as to get rid of unused images. +#ifdef DEBUG_GXSIDDETAILS debug_dumpImagesCache(); +#endif checkCleanImagesCache(); // now look for the icon From 761a4ee3efa7f21227f962a212aba39ad5afa3ff Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Feb 2021 15:50:18 +0100 Subject: [PATCH 020/697] fixed auto-scrolling in NewFriendList --- .../src/gui/common/NewFriendList.cpp | 129 +++++++++++++----- retroshare-gui/src/gui/common/NewFriendList.h | 8 +- 2 files changed, 96 insertions(+), 41 deletions(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 1cfa05ef4..a792d936c 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -99,8 +99,11 @@ /****** * #define FRIENDS_DEBUG 1 + * #define DEBUG_NEW_FRIEND_LIST 1 *****/ +#define DEBUG_NEW_FRIEND_LIST 1 + Q_DECLARE_METATYPE(ElidedLabel*) class FriendListSortFilterProxyModel: public QSortFilterProxyModel @@ -284,21 +287,6 @@ void NewFriendList::itemCollapsed(const QModelIndex& index) mModel->collapseItem(mProxyModel->mapToSource(index)); } -void NewFriendList::sortColumn(int col,Qt::SortOrder so) -{ - std::set expanded_indexes; - std::set selected_indexes; - - saveExpandedPathsAndSelection(expanded_indexes, selected_indexes); - mProxyModel->setSortingEnabled(true); - mProxyModel->sort(col,so); - mProxyModel->setSortingEnabled(false); - restoreExpandedPathsAndSelection(expanded_indexes, selected_indexes); - - mLastSortColumn = col; - mLastSortOrder = so; -} - void NewFriendList::headerContextMenuRequested(QPoint /*p*/) { QMenu displayMenu(tr("Show Items"), this); @@ -381,75 +369,109 @@ void NewFriendList::addToolButton(QToolButton *toolButton) ui->titleBarFrame->layout()->addWidget(toolButton); } -void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_indexes, std::set& selected_indexes) +void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel) { + QModelIndexList selectedIndexes = ui->peerTreeWidget->selectionModel()->selectedIndexes(); + QModelIndex current_index = selectedIndexes.empty()?QModelIndex():(*selectedIndexes.begin()); + #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << "Saving expended paths and selection..." << std::endl; #endif for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursSaveExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,selected_indexes); + recursSaveExpandedItems(mProxyModel->index(row,0),current_index,QString(),expanded_indexes,sel); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << " selected index: \"" << sel.toStdString() << "\"" << std::endl; +#endif } -void NewFriendList::restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const std::set& selected_indexes) +void NewFriendList::restoreExpandedPathsAndSelection(const std::set& expanded_indexes,const QString& index_to_select,QModelIndex& selected_index) { #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << "Restoring expended paths and selection..." << std::endl; + std::cerr << " index to select: \"" << index_to_select.toStdString() << "\"" << std::endl; #endif ui->peerTreeWidget->blockSignals(true) ; for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,selected_indexes); + recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,index_to_select,selected_index); ui->peerTreeWidget->blockSignals(false) ; } -void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QString& parent_path,std::set& exp, std::set& sel) +void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QModelIndex& current_index,const QString& parent_path,std::set& exp, QString& sel) { QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; - if(ui->peerTreeWidget->selectionModel()->selection().contains(index)) - sel.insert(local_path) ; - +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << " At index " << index.row() << ". data[1]=" << local_path.toStdString() ; +#endif if(ui->peerTreeWidget->isExpanded(index)) { #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "Index " << local_path.toStdString() << " is expanded." << std::endl; + std::cerr << " Index is expanded." ; #endif if(index.isValid()) exp.insert(local_path) ; for(int row=0;rowrowCount(index);++row) - recursSaveExpandedItems(index.child(row,0),local_path,exp,sel) ; + recursSaveExpandedItems(index.child(row,0),current_index,local_path,exp,sel) ; } #ifdef DEBUG_NEW_FRIEND_LIST else - std::cerr << "Index " << local_path.toStdString() << " is not expanded." << std::endl; + std::cerr << " not expanded." ; #endif + + if(index == current_index) + { +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << " adding to selection!" << std::endl; +#endif + sel = local_path ; + } +#ifdef DEBUG_NEW_FRIEND_LIST + else + std::cerr << std::endl; +#endif + + } -void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const std::set &sel) +void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString& sel,QModelIndex& selected_index) { QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "at index " << index.row() << ". data[1]=" << local_path.toStdString() << std::endl; + std::cerr << " At index " << index.row() << ". data[1]=" << local_path.toStdString() ; #endif - if(sel.find(local_path) != sel.end()) - ui->peerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - if(exp.find(local_path) != exp.end()) { #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "re expanding index " << local_path.toStdString() << std::endl; + std::cerr << " re expanding " << std::endl; #endif ui->peerTreeWidget->setExpanded(index,true) ; for(int row=0;rowrowCount(index);++row) - recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel) ; + recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel,selected_index) ; } + + if(sel == local_path) + { +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << " selecting index \"" << local_path.toStdString() << "\"" << std::endl; +#endif + ui->peerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + selected_index = index; + } +#ifdef DEBUG_NEW_FRIEND_LIST + else + std::cerr << std::endl; +#endif + + } @@ -1101,9 +1123,14 @@ void NewFriendList::removeGroup() void NewFriendList::applyWhileKeepingTree(std::function predicate) { std::set expanded_indexes; - std::set selected_indexes; + QString selected; - saveExpandedPathsAndSelection(expanded_indexes, selected_indexes); + saveExpandedPathsAndSelection(expanded_indexes, selected); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "After collecting selection, selected paths is: \"" << selected.toStdString() << "\"" << std::endl; +#endif + whileBlocking(ui->peerTreeWidget)->clearSelection(); // This is a hack to avoid crashes on windows while calling endInsertRows(). I'm not sure wether these crashes are // due to a Qt bug, or a misuse of the proxy model on my side. Anyway, this solves them for good. @@ -1124,8 +1151,9 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) predicate(); + QModelIndex selected_index; mProxyModel->setSourceModel(mModel); - restoreExpandedPathsAndSelection(expanded_indexes, selected_indexes); + restoreExpandedPathsAndSelection(expanded_indexes,selected,selected_index); // restore hidden columns for(uint32_t i=0;i predicate) } // restore sorting - sortColumn(mLastSortColumn,mLastSortOrder); + // sortColumn(mLastSortColumn,mLastSortOrder); + mProxyModel->sort(mLastSortColumn,mLastSortOrder); + + if(selected_index.isValid()) + ui->peerTreeWidget->scrollTo(selected_index); } +void NewFriendList::sortColumn(int col,Qt::SortOrder so) +{ + std::set expanded_indexes; + QString selected; + QModelIndex selected_index; + + saveExpandedPathsAndSelection(expanded_indexes, selected); + whileBlocking(ui->peerTreeWidget)->clearSelection(); + + mProxyModel->setSortingEnabled(true); + mProxyModel->sort(col,so); + mProxyModel->setSortingEnabled(false); + + restoreExpandedPathsAndSelection(expanded_indexes,selected,selected_index); + + if(selected_index.isValid()) + ui->peerTreeWidget->scrollTo(selected_index); + + mLastSortColumn = col; + mLastSortOrder = so; +} + + void NewFriendList::checkInternalData(bool force) { applyWhileKeepingTree([force,this]() { mModel->checkInternalData(force) ; }); diff --git a/retroshare-gui/src/gui/common/NewFriendList.h b/retroshare-gui/src/gui/common/NewFriendList.h index 224cc0a11..67ae9e651 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.h +++ b/retroshare-gui/src/gui/common/NewFriendList.h @@ -106,10 +106,10 @@ private: void applyWhileKeepingTree(std::function predicate); void expandGroup(const RsNodeGroupId& gid); - void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const std::set &sel); - void recursSaveExpandedItems(const QModelIndex& index,const QString& parent_path,std::set& exp, std::set& sel); - void saveExpandedPathsAndSelection(std::set& expanded_indexes, std::set& selected_indexes); - void restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const std::set& selected_indexes); + void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString &sel, QModelIndex &selected_index); + void recursSaveExpandedItems(const QModelIndex& index, const QModelIndex& current_index, const QString& parent_path, std::set& exp, QString &sel); + void saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel); + void restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const QString &index_to_select, QModelIndex &selected_index); void checkInternalData(bool force); From 1f8b49ea295e84c78710132753f58d94ace304e6 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Feb 2021 15:56:27 +0100 Subject: [PATCH 021/697] removed debug info from NewFriendList --- retroshare-gui/src/gui/common/NewFriendList.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index a792d936c..83218c10d 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -102,8 +102,6 @@ * #define DEBUG_NEW_FRIEND_LIST 1 *****/ -#define DEBUG_NEW_FRIEND_LIST 1 - Q_DECLARE_METATYPE(ElidedLabel*) class FriendListSortFilterProxyModel: public QSortFilterProxyModel From f5233b119050f492b59efa4910d3918eb16ec1e9 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Feb 2021 20:02:57 +0100 Subject: [PATCH 022/697] moved from 0.6.6-RC2 to 0.6.6 --- libretroshare/src/retroshare/rsversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/retroshare/rsversion.h b/libretroshare/src/retroshare/rsversion.h index 3d853bc1f..c16f6b9e7 100644 --- a/libretroshare/src/retroshare/rsversion.h +++ b/libretroshare/src/retroshare/rsversion.h @@ -56,7 +56,7 @@ * Customize it trough qmake command line @see retroshare.pri */ #ifndef RS_EXTRA_VERSION -# define RS_EXTRA_VERSION "-RC2" +# define RS_EXTRA_VERSION "" #endif From 2075e8c23b7fa9db531ef655134e6c53afab2291 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 20 Feb 2021 03:16:29 +0100 Subject: [PATCH 023/697] Fix Bubble Chat Style --- build_scripts/Windows-msys2/build/pack.bat | 1 - build_scripts/Windows/build/pack.bat | 1 - .../src/gui/common/RSTextBrowser.cpp | 34 +- retroshare-gui/src/gui/common/RSTextBrowser.h | 2 + .../gui/qss/chat/Bubble/history/hincoming.htm | 11 +- .../gui/qss/chat/Bubble/history/houtgoing.htm | 10 +- .../src/gui/qss/chat/Bubble/history/images.sh | 13 - .../history/img/bubble-blue/bubble_BC.png | Bin 228 -> 207 bytes .../history/img/bubble-blue/bubble_BL.png | Bin 531 -> 481 bytes .../history/img/bubble-blue/bubble_BR.png | Bin 542 -> 494 bytes .../history/img/bubble-blue/bubble_CC.png | Bin 158 -> 142 bytes .../history/img/bubble-blue/bubble_CL.png | Bin 232 -> 208 bytes .../history/img/bubble-blue/bubble_CR.png | Bin 247 -> 221 bytes .../history/img/bubble-blue/bubble_TC.png | Bin 216 -> 196 bytes .../history/img/bubble-blue/bubble_TL.png | Bin 460 -> 436 bytes .../history/img/bubble-blue/bubble_TR.png | Bin 516 -> 492 bytes .../img/bubble-blue/bubble_tick-left.png | Bin 460 -> 434 bytes .../img/bubble-blue/bubble_tick-right.png | Bin 456 -> 439 bytes .../history/img/bubble-blue/bubble_tick.png | Bin 481 -> 439 bytes .../history/img/bubble-green/bubble_BC.png | Bin 221 -> 202 bytes .../history/img/bubble-green/bubble_BL.png | Bin 525 -> 476 bytes .../history/img/bubble-green/bubble_BR.png | Bin 535 -> 487 bytes .../history/img/bubble-green/bubble_CC.png | Bin 158 -> 142 bytes .../history/img/bubble-green/bubble_CL.png | Bin 219 -> 205 bytes .../history/img/bubble-green/bubble_CR.png | Bin 237 -> 224 bytes .../history/img/bubble-green/bubble_TC.png | Bin 219 -> 194 bytes .../history/img/bubble-green/bubble_TL.png | Bin 463 -> 425 bytes .../history/img/bubble-green/bubble_TR.png | Bin 515 -> 482 bytes .../img/bubble-green/bubble_tick-left.png | Bin 448 -> 420 bytes .../img/bubble-green/bubble_tick-right.png | Bin 441 -> 429 bytes .../history/img/bubble-green/bubble_tick.png | Bin 451 -> 429 bytes .../history/img/bubble-grey/bubble_BC.png | Bin 314 -> 196 bytes .../history/img/bubble-grey/bubble_BL.png | Bin 485 -> 427 bytes .../history/img/bubble-grey/bubble_BR.png | Bin 474 -> 416 bytes .../history/img/bubble-grey/bubble_CC.png | Bin 270 -> 142 bytes .../history/img/bubble-grey/bubble_CL.png | Bin 300 -> 184 bytes .../history/img/bubble-grey/bubble_CR.png | Bin 313 -> 191 bytes .../history/img/bubble-grey/bubble_TC.png | Bin 298 -> 181 bytes .../history/img/bubble-grey/bubble_TL.png | Bin 450 -> 381 bytes .../history/img/bubble-grey/bubble_TR.png | Bin 457 -> 426 bytes .../img/bubble-grey/bubble_tick-left.png | Bin 376 -> 398 bytes .../img/bubble-grey/bubble_tick-right.png | Bin 386 -> 391 bytes .../history/img/bubble-grey/bubble_tick.png | Bin 393 -> 385 bytes .../history/img/bubble-orange/bubble_BC.png | Bin 216 -> 198 bytes .../history/img/bubble-orange/bubble_BL.png | Bin 495 -> 464 bytes .../history/img/bubble-orange/bubble_BR.png | Bin 485 -> 454 bytes .../history/img/bubble-orange/bubble_CC.png | Bin 158 -> 142 bytes .../history/img/bubble-orange/bubble_CL.png | Bin 219 -> 198 bytes .../history/img/bubble-orange/bubble_CR.png | Bin 229 -> 212 bytes .../history/img/bubble-orange/bubble_TC.png | Bin 204 -> 185 bytes .../history/img/bubble-orange/bubble_TL.png | Bin 439 -> 412 bytes .../history/img/bubble-orange/bubble_TR.png | Bin 479 -> 455 bytes .../img/bubble-orange/bubble_tick-left.png | Bin 399 -> 408 bytes .../img/bubble-orange/bubble_tick-right.png | Bin 419 -> 398 bytes .../history/img/bubble-orange/bubble_tick.png | Bin 417 -> 393 bytes .../history/img/bubble-red/bubble_BC.png | Bin 339 -> 200 bytes .../history/img/bubble-red/bubble_BL.png | Bin 622 -> 468 bytes .../history/img/bubble-red/bubble_BR.png | Bin 610 -> 458 bytes .../history/img/bubble-red/bubble_CC.png | Bin 279 -> 142 bytes .../history/img/bubble-red/bubble_CL.png | Bin 338 -> 200 bytes .../history/img/bubble-red/bubble_CR.png | Bin 352 -> 209 bytes .../history/img/bubble-red/bubble_TC.png | Bin 330 -> 193 bytes .../history/img/bubble-red/bubble_TL.png | Bin 575 -> 418 bytes .../history/img/bubble-red/bubble_TR.png | Bin 613 -> 459 bytes .../img/bubble-red/bubble_tick-left.png | Bin 483 -> 421 bytes .../img/bubble-red/bubble_tick-right.png | Bin 495 -> 417 bytes .../history/img/bubble-red/bubble_tick.png | Bin 505 -> 413 bytes .../gui/qss/chat/Bubble/history/incoming.htm | 10 +- .../src/gui/qss/chat/Bubble/history/main.css | 52 +- .../gui/qss/chat/Bubble/history/ooutgoing.htm | 8 +- .../gui/qss/chat/Bubble/history/outgoing.htm | 8 +- .../gui/qss/chat/Bubble/history/system.htm | 15 +- .../gui/qss/chat/Bubble/private/hincoming.htm | 9 +- .../gui/qss/chat/Bubble/private/houtgoing.htm | 8 +- .../src/gui/qss/chat/Bubble/private/images.sh | 13 - .../private/img/bubble-blue/bubble_BC.png | Bin 228 -> 207 bytes .../private/img/bubble-blue/bubble_BL.png | Bin 531 -> 481 bytes .../private/img/bubble-blue/bubble_BR.png | Bin 542 -> 494 bytes .../private/img/bubble-blue/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-blue/bubble_CL.png | Bin 232 -> 208 bytes .../private/img/bubble-blue/bubble_CR.png | Bin 247 -> 221 bytes .../private/img/bubble-blue/bubble_TC.png | Bin 216 -> 196 bytes .../private/img/bubble-blue/bubble_TL.png | Bin 460 -> 436 bytes .../private/img/bubble-blue/bubble_TR.png | Bin 516 -> 492 bytes .../img/bubble-blue/bubble_tick-left.png | Bin 460 -> 434 bytes .../img/bubble-blue/bubble_tick-right.png | Bin 456 -> 439 bytes .../private/img/bubble-blue/bubble_tick.png | Bin 481 -> 439 bytes .../private/img/bubble-green/bubble_BC.png | Bin 221 -> 202 bytes .../private/img/bubble-green/bubble_BL.png | Bin 525 -> 476 bytes .../private/img/bubble-green/bubble_BR.png | Bin 535 -> 487 bytes .../private/img/bubble-green/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-green/bubble_CL.png | Bin 219 -> 205 bytes .../private/img/bubble-green/bubble_CR.png | Bin 237 -> 224 bytes .../private/img/bubble-green/bubble_TC.png | Bin 219 -> 194 bytes .../private/img/bubble-green/bubble_TL.png | Bin 463 -> 425 bytes .../private/img/bubble-green/bubble_TR.png | Bin 515 -> 482 bytes .../img/bubble-green/bubble_tick-left.png | Bin 448 -> 420 bytes .../img/bubble-green/bubble_tick-right.png | Bin 441 -> 429 bytes .../private/img/bubble-green/bubble_tick.png | Bin 451 -> 429 bytes .../private/img/bubble-grey/bubble_BC.png | Bin 314 -> 196 bytes .../private/img/bubble-grey/bubble_BL.png | Bin 485 -> 427 bytes .../private/img/bubble-grey/bubble_BR.png | Bin 474 -> 416 bytes .../private/img/bubble-grey/bubble_CC.png | Bin 270 -> 142 bytes .../private/img/bubble-grey/bubble_CL.png | Bin 300 -> 184 bytes .../private/img/bubble-grey/bubble_CR.png | Bin 313 -> 191 bytes .../private/img/bubble-grey/bubble_TC.png | Bin 298 -> 181 bytes .../private/img/bubble-grey/bubble_TL.png | Bin 450 -> 381 bytes .../private/img/bubble-grey/bubble_TR.png | Bin 457 -> 426 bytes .../img/bubble-grey/bubble_tick-left.png | Bin 376 -> 398 bytes .../img/bubble-grey/bubble_tick-right.png | Bin 386 -> 391 bytes .../private/img/bubble-grey/bubble_tick.png | Bin 393 -> 385 bytes .../private/img/bubble-orange/bubble_BC.png | Bin 216 -> 198 bytes .../private/img/bubble-orange/bubble_BL.png | Bin 495 -> 464 bytes .../private/img/bubble-orange/bubble_BR.png | Bin 485 -> 454 bytes .../private/img/bubble-orange/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-orange/bubble_CL.png | Bin 219 -> 198 bytes .../private/img/bubble-orange/bubble_CR.png | Bin 229 -> 212 bytes .../private/img/bubble-orange/bubble_TC.png | Bin 204 -> 185 bytes .../private/img/bubble-orange/bubble_TL.png | Bin 439 -> 412 bytes .../private/img/bubble-orange/bubble_TR.png | Bin 479 -> 455 bytes .../img/bubble-orange/bubble_tick-left.png | Bin 399 -> 408 bytes .../img/bubble-orange/bubble_tick-right.png | Bin 419 -> 398 bytes .../private/img/bubble-orange/bubble_tick.png | Bin 417 -> 393 bytes .../private/img/bubble-red/bubble_BC.png | Bin 339 -> 200 bytes .../private/img/bubble-red/bubble_BL.png | Bin 622 -> 468 bytes .../private/img/bubble-red/bubble_BR.png | Bin 610 -> 458 bytes .../private/img/bubble-red/bubble_CC.png | Bin 279 -> 142 bytes .../private/img/bubble-red/bubble_CL.png | Bin 338 -> 200 bytes .../private/img/bubble-red/bubble_CR.png | Bin 352 -> 209 bytes .../private/img/bubble-red/bubble_TC.png | Bin 330 -> 193 bytes .../private/img/bubble-red/bubble_TL.png | Bin 575 -> 418 bytes .../private/img/bubble-red/bubble_TR.png | Bin 613 -> 459 bytes .../img/bubble-red/bubble_tick-left.png | Bin 483 -> 421 bytes .../img/bubble-red/bubble_tick-right.png | Bin 495 -> 417 bytes .../private/img/bubble-red/bubble_tick.png | Bin 505 -> 413 bytes .../gui/qss/chat/Bubble/private/incoming.htm | 8 +- .../src/gui/qss/chat/Bubble/private/main.css | 52 +- .../gui/qss/chat/Bubble/private/ooutgoing.htm | 8 +- .../gui/qss/chat/Bubble/private/outgoing.htm | 8 +- .../gui/qss/chat/Bubble/private/system.htm | 8 +- .../gui/qss/chat/Bubble/public/hincoming.htm | 11 +- .../gui/qss/chat/Bubble/public/houtgoing.htm | 10 +- .../src/gui/qss/chat/Bubble/public/images.sh | 13 - .../public/img/bubble-blue/bubble_BC.png | Bin 228 -> 207 bytes .../public/img/bubble-blue/bubble_BL.png | Bin 531 -> 481 bytes .../public/img/bubble-blue/bubble_BR.png | Bin 542 -> 494 bytes .../public/img/bubble-blue/bubble_CC.png | Bin 158 -> 142 bytes .../public/img/bubble-blue/bubble_CL.png | Bin 232 -> 208 bytes .../public/img/bubble-blue/bubble_CR.png | Bin 247 -> 221 bytes .../public/img/bubble-blue/bubble_TC.png | Bin 216 -> 196 bytes .../public/img/bubble-blue/bubble_TL.png | Bin 460 -> 436 bytes .../public/img/bubble-blue/bubble_TR.png | Bin 516 -> 492 bytes .../img/bubble-blue/bubble_tick-left.png | Bin 460 -> 434 bytes .../img/bubble-blue/bubble_tick-right.png | Bin 456 -> 439 bytes .../public/img/bubble-blue/bubble_tick.png | Bin 481 -> 439 bytes .../public/img/bubble-green/bubble_BC.png | Bin 221 -> 202 bytes .../public/img/bubble-green/bubble_BL.png | Bin 525 -> 476 bytes .../public/img/bubble-green/bubble_BR.png | Bin 535 -> 487 bytes .../public/img/bubble-green/bubble_CC.png | Bin 158 -> 142 bytes .../public/img/bubble-green/bubble_CL.png | Bin 219 -> 205 bytes .../public/img/bubble-green/bubble_CR.png | Bin 237 -> 224 bytes .../public/img/bubble-green/bubble_TC.png | Bin 219 -> 194 bytes .../public/img/bubble-green/bubble_TL.png | Bin 463 -> 425 bytes .../public/img/bubble-green/bubble_TR.png | Bin 515 -> 482 bytes .../img/bubble-green/bubble_tick-left.png | Bin 448 -> 420 bytes .../img/bubble-green/bubble_tick-right.png | Bin 441 -> 429 bytes .../public/img/bubble-green/bubble_tick.png | Bin 451 -> 429 bytes .../public/img/bubble-grey/bubble_BC.png | Bin 314 -> 196 bytes .../public/img/bubble-grey/bubble_BL.png | Bin 485 -> 427 bytes .../public/img/bubble-grey/bubble_BR.png | Bin 474 -> 416 bytes .../public/img/bubble-grey/bubble_CC.png | Bin 270 -> 142 bytes .../public/img/bubble-grey/bubble_CL.png | Bin 300 -> 184 bytes .../public/img/bubble-grey/bubble_CR.png | Bin 313 -> 191 bytes .../public/img/bubble-grey/bubble_TC.png | Bin 298 -> 181 bytes .../public/img/bubble-grey/bubble_TL.png | Bin 450 -> 381 bytes .../public/img/bubble-grey/bubble_TR.png | Bin 457 -> 426 bytes .../img/bubble-grey/bubble_tick-left.png | Bin 376 -> 398 bytes .../img/bubble-grey/bubble_tick-right.png | Bin 386 -> 391 bytes .../public/img/bubble-grey/bubble_tick.png | Bin 393 -> 385 bytes .../public/img/bubble-orange/bubble_BC.png | Bin 216 -> 198 bytes .../public/img/bubble-orange/bubble_BL.png | Bin 495 -> 464 bytes .../public/img/bubble-orange/bubble_BR.png | Bin 485 -> 454 bytes .../public/img/bubble-orange/bubble_CC.png | Bin 158 -> 142 bytes .../public/img/bubble-orange/bubble_CL.png | Bin 219 -> 198 bytes .../public/img/bubble-orange/bubble_CR.png | Bin 229 -> 212 bytes .../public/img/bubble-orange/bubble_TC.png | Bin 204 -> 185 bytes .../public/img/bubble-orange/bubble_TL.png | Bin 439 -> 412 bytes .../public/img/bubble-orange/bubble_TR.png | Bin 479 -> 455 bytes .../img/bubble-orange/bubble_tick-left.png | Bin 399 -> 408 bytes .../img/bubble-orange/bubble_tick-right.png | Bin 419 -> 398 bytes .../public/img/bubble-orange/bubble_tick.png | Bin 417 -> 393 bytes .../public/img/bubble-red/bubble_BC.png | Bin 339 -> 200 bytes .../public/img/bubble-red/bubble_BL.png | Bin 622 -> 468 bytes .../public/img/bubble-red/bubble_BR.png | Bin 610 -> 458 bytes .../public/img/bubble-red/bubble_CC.png | Bin 279 -> 142 bytes .../public/img/bubble-red/bubble_CL.png | Bin 338 -> 200 bytes .../public/img/bubble-red/bubble_CR.png | Bin 352 -> 209 bytes .../public/img/bubble-red/bubble_TC.png | Bin 330 -> 193 bytes .../public/img/bubble-red/bubble_TL.png | Bin 575 -> 418 bytes .../public/img/bubble-red/bubble_TR.png | Bin 613 -> 459 bytes .../img/bubble-red/bubble_tick-left.png | Bin 483 -> 421 bytes .../img/bubble-red/bubble_tick-right.png | Bin 495 -> 417 bytes .../public/img/bubble-red/bubble_tick.png | Bin 505 -> 413 bytes .../gui/qss/chat/Bubble/public/incoming.htm | 10 +- .../src/gui/qss/chat/Bubble/public/main.css | 54 +- .../gui/qss/chat/Bubble/public/ooutgoing.htm | 8 +- .../gui/qss/chat/Bubble/public/outgoing.htm | 10 +- .../src/gui/qss/chat/Bubble/public/system.htm | 10 +- .../src/gui/qss/chat/Bubble/src/images.sh | 15 - .../src/gui/qss/chat/Bubble/src/img.svg | 1109 +---------------- .../Bubble/src/img/bubble-blue/bubble_BC.png | Bin 228 -> 207 bytes .../Bubble/src/img/bubble-blue/bubble_BL.png | Bin 531 -> 481 bytes .../Bubble/src/img/bubble-blue/bubble_BR.png | Bin 542 -> 494 bytes .../Bubble/src/img/bubble-blue/bubble_CC.png | Bin 158 -> 142 bytes .../Bubble/src/img/bubble-blue/bubble_CL.png | Bin 232 -> 208 bytes .../Bubble/src/img/bubble-blue/bubble_CR.png | Bin 247 -> 221 bytes .../Bubble/src/img/bubble-blue/bubble_TC.png | Bin 216 -> 196 bytes .../Bubble/src/img/bubble-blue/bubble_TL.png | Bin 460 -> 436 bytes .../Bubble/src/img/bubble-blue/bubble_TR.png | Bin 516 -> 492 bytes .../src/img/bubble-blue/bubble_tick-left.png | Bin 460 -> 434 bytes .../src/img/bubble-blue/bubble_tick-right.png | Bin 456 -> 439 bytes .../src/img/bubble-blue/bubble_tick.png | Bin 481 -> 439 bytes .../Bubble/src/img/bubble-green/bubble_BC.png | Bin 221 -> 202 bytes .../Bubble/src/img/bubble-green/bubble_BL.png | Bin 525 -> 476 bytes .../Bubble/src/img/bubble-green/bubble_BR.png | Bin 535 -> 487 bytes .../Bubble/src/img/bubble-green/bubble_CC.png | Bin 158 -> 142 bytes .../Bubble/src/img/bubble-green/bubble_CL.png | Bin 219 -> 205 bytes .../Bubble/src/img/bubble-green/bubble_CR.png | Bin 237 -> 224 bytes .../Bubble/src/img/bubble-green/bubble_TC.png | Bin 219 -> 194 bytes .../Bubble/src/img/bubble-green/bubble_TL.png | Bin 463 -> 425 bytes .../Bubble/src/img/bubble-green/bubble_TR.png | Bin 515 -> 482 bytes .../src/img/bubble-green/bubble_tick-left.png | Bin 448 -> 420 bytes .../img/bubble-green/bubble_tick-right.png | Bin 441 -> 429 bytes .../src/img/bubble-green/bubble_tick.png | Bin 451 -> 429 bytes .../Bubble/src/img/bubble-grey/bubble_BC.png | Bin 314 -> 196 bytes .../Bubble/src/img/bubble-grey/bubble_BL.png | Bin 485 -> 427 bytes .../Bubble/src/img/bubble-grey/bubble_BR.png | Bin 474 -> 416 bytes .../Bubble/src/img/bubble-grey/bubble_CC.png | Bin 270 -> 142 bytes .../Bubble/src/img/bubble-grey/bubble_CL.png | Bin 300 -> 184 bytes .../Bubble/src/img/bubble-grey/bubble_CR.png | Bin 313 -> 191 bytes .../Bubble/src/img/bubble-grey/bubble_TC.png | Bin 298 -> 181 bytes .../Bubble/src/img/bubble-grey/bubble_TL.png | Bin 450 -> 381 bytes .../Bubble/src/img/bubble-grey/bubble_TR.png | Bin 457 -> 426 bytes .../src/img/bubble-grey/bubble_tick-left.png | Bin 376 -> 398 bytes .../src/img/bubble-grey/bubble_tick-right.png | Bin 386 -> 391 bytes .../src/img/bubble-grey/bubble_tick.png | Bin 393 -> 385 bytes .../src/img/bubble-orange/bubble_BC.png | Bin 216 -> 198 bytes .../src/img/bubble-orange/bubble_BL.png | Bin 495 -> 464 bytes .../src/img/bubble-orange/bubble_BR.png | Bin 485 -> 454 bytes .../src/img/bubble-orange/bubble_CC.png | Bin 158 -> 142 bytes .../src/img/bubble-orange/bubble_CL.png | Bin 219 -> 198 bytes .../src/img/bubble-orange/bubble_CR.png | Bin 229 -> 212 bytes .../src/img/bubble-orange/bubble_TC.png | Bin 204 -> 185 bytes .../src/img/bubble-orange/bubble_TL.png | Bin 439 -> 412 bytes .../src/img/bubble-orange/bubble_TR.png | Bin 479 -> 455 bytes .../img/bubble-orange/bubble_tick-left.png | Bin 399 -> 408 bytes .../img/bubble-orange/bubble_tick-right.png | Bin 419 -> 398 bytes .../src/img/bubble-orange/bubble_tick.png | Bin 417 -> 393 bytes .../Bubble/src/img/bubble-red/bubble_BC.png | Bin 339 -> 200 bytes .../Bubble/src/img/bubble-red/bubble_BL.png | Bin 622 -> 468 bytes .../Bubble/src/img/bubble-red/bubble_BR.png | Bin 610 -> 458 bytes .../Bubble/src/img/bubble-red/bubble_CC.png | Bin 279 -> 142 bytes .../Bubble/src/img/bubble-red/bubble_CL.png | Bin 338 -> 200 bytes .../Bubble/src/img/bubble-red/bubble_CR.png | Bin 352 -> 209 bytes .../Bubble/src/img/bubble-red/bubble_TC.png | Bin 330 -> 193 bytes .../Bubble/src/img/bubble-red/bubble_TL.png | Bin 575 -> 418 bytes .../Bubble/src/img/bubble-red/bubble_TR.png | Bin 613 -> 459 bytes .../src/img/bubble-red/bubble_tick-left.png | Bin 483 -> 421 bytes .../src/img/bubble-red/bubble_tick-right.png | Bin 495 -> 417 bytes .../Bubble/src/img/bubble-red/bubble_tick.png | Bin 505 -> 413 bytes .../gui/qss/chat/Bubble/src/make_images.sh | 82 ++ .../private/Kopie von incoming.htm | 30 - .../chat/Bubble_Compact/private/hincoming.htm | 11 +- .../chat/Bubble_Compact/private/houtgoing.htm | 11 +- .../qss/chat/Bubble_Compact/private/images.sh | 13 - .../private/img/bubble-blue/bubble_BC.png | Bin 228 -> 207 bytes .../private/img/bubble-blue/bubble_BL.png | Bin 531 -> 481 bytes .../private/img/bubble-blue/bubble_BR.png | Bin 542 -> 494 bytes .../private/img/bubble-blue/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-blue/bubble_CL.png | Bin 232 -> 208 bytes .../private/img/bubble-blue/bubble_CR.png | Bin 247 -> 221 bytes .../private/img/bubble-blue/bubble_TC.png | Bin 216 -> 196 bytes .../private/img/bubble-blue/bubble_TL.png | Bin 460 -> 436 bytes .../private/img/bubble-blue/bubble_TR.png | Bin 516 -> 492 bytes .../img/bubble-blue/bubble_tick-left.png | Bin 460 -> 434 bytes .../img/bubble-blue/bubble_tick-right.png | Bin 456 -> 439 bytes .../private/img/bubble-blue/bubble_tick.png | Bin 481 -> 439 bytes .../private/img/bubble-green/bubble_BC.png | Bin 221 -> 202 bytes .../private/img/bubble-green/bubble_BL.png | Bin 525 -> 476 bytes .../private/img/bubble-green/bubble_BR.png | Bin 535 -> 487 bytes .../private/img/bubble-green/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-green/bubble_CL.png | Bin 219 -> 205 bytes .../private/img/bubble-green/bubble_CR.png | Bin 237 -> 224 bytes .../private/img/bubble-green/bubble_TC.png | Bin 219 -> 194 bytes .../private/img/bubble-green/bubble_TL.png | Bin 463 -> 425 bytes .../private/img/bubble-green/bubble_TR.png | Bin 515 -> 482 bytes .../img/bubble-green/bubble_tick-left.png | Bin 448 -> 420 bytes .../img/bubble-green/bubble_tick-right.png | Bin 441 -> 429 bytes .../private/img/bubble-green/bubble_tick.png | Bin 451 -> 429 bytes .../private/img/bubble-grey/bubble_BC.png | Bin 314 -> 196 bytes .../private/img/bubble-grey/bubble_BL.png | Bin 485 -> 427 bytes .../private/img/bubble-grey/bubble_BR.png | Bin 474 -> 416 bytes .../private/img/bubble-grey/bubble_CC.png | Bin 270 -> 142 bytes .../private/img/bubble-grey/bubble_CL.png | Bin 300 -> 184 bytes .../private/img/bubble-grey/bubble_CR.png | Bin 313 -> 191 bytes .../private/img/bubble-grey/bubble_TC.png | Bin 298 -> 181 bytes .../private/img/bubble-grey/bubble_TL.png | Bin 450 -> 381 bytes .../private/img/bubble-grey/bubble_TR.png | Bin 457 -> 426 bytes .../img/bubble-grey/bubble_tick-left.png | Bin 376 -> 398 bytes .../img/bubble-grey/bubble_tick-right.png | Bin 386 -> 391 bytes .../private/img/bubble-grey/bubble_tick.png | Bin 393 -> 385 bytes .../private/img/bubble-orange/bubble_BC.png | Bin 216 -> 198 bytes .../private/img/bubble-orange/bubble_BL.png | Bin 495 -> 464 bytes .../private/img/bubble-orange/bubble_BR.png | Bin 485 -> 454 bytes .../private/img/bubble-orange/bubble_CC.png | Bin 158 -> 142 bytes .../private/img/bubble-orange/bubble_CL.png | Bin 219 -> 198 bytes .../private/img/bubble-orange/bubble_CR.png | Bin 229 -> 212 bytes .../private/img/bubble-orange/bubble_TC.png | Bin 204 -> 185 bytes .../private/img/bubble-orange/bubble_TL.png | Bin 439 -> 412 bytes .../private/img/bubble-orange/bubble_TR.png | Bin 479 -> 455 bytes .../img/bubble-orange/bubble_tick-left.png | Bin 399 -> 408 bytes .../img/bubble-orange/bubble_tick-right.png | Bin 419 -> 398 bytes .../private/img/bubble-orange/bubble_tick.png | Bin 417 -> 393 bytes .../private/img/bubble-red/bubble_BC.png | Bin 339 -> 200 bytes .../private/img/bubble-red/bubble_BL.png | Bin 622 -> 468 bytes .../private/img/bubble-red/bubble_BR.png | Bin 610 -> 458 bytes .../private/img/bubble-red/bubble_CC.png | Bin 279 -> 142 bytes .../private/img/bubble-red/bubble_CL.png | Bin 338 -> 200 bytes .../private/img/bubble-red/bubble_CR.png | Bin 352 -> 209 bytes .../private/img/bubble-red/bubble_TC.png | Bin 330 -> 193 bytes .../private/img/bubble-red/bubble_TL.png | Bin 575 -> 418 bytes .../private/img/bubble-red/bubble_TR.png | Bin 613 -> 459 bytes .../img/bubble-red/bubble_tick-left.png | Bin 483 -> 421 bytes .../img/bubble-red/bubble_tick-right.png | Bin 495 -> 417 bytes .../private/img/bubble-red/bubble_tick.png | Bin 505 -> 413 bytes .../chat/Bubble_Compact/private/incoming.htm | 11 +- .../qss/chat/Bubble_Compact/private/main.css | 52 +- .../chat/Bubble_Compact/private/ooutgoing.htm | 11 +- .../chat/Bubble_Compact/private/outgoing.htm | 12 +- .../chat/Bubble_Compact/private/system.htm | 12 +- .../__MACOSX__Bubble/history/._hincoming.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/history/._houtgoing.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/history/._images.sh | Bin 237 -> 0 bytes .../qss/chat/__MACOSX__Bubble/history/._img | Bin 237 -> 0 bytes .../__MACOSX__Bubble/history/._incoming.htm | Bin 304 -> 0 bytes .../chat/__MACOSX__Bubble/history/._info.xml | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/history/._main.css | Bin 304 -> 0 bytes .../__MACOSX__Bubble/history/._ooutgoing.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/history/._outgoing.htm | Bin 303 -> 0 bytes .../__MACOSX__Bubble/history/._system.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/history/._variants | Bin 237 -> 0 bytes .../history/img/._bubble-grey | Bin 237 -> 0 bytes .../history/img/._bubble-orange | Bin 237 -> 0 bytes .../__MACOSX__Bubble/history/img/._bubble-red | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_BC.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_BL.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_BR.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_CC.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_CL.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_CR.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_TC.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_TL.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-right.png | Bin 237 -> 0 bytes .../history/img/bubble-grey/._bubble_tick.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_BC.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_BL.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_BR.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_CC.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_CL.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_CR.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_TC.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_TL.png | Bin 237 -> 0 bytes .../history/img/bubble-orange/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-right.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_BC.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_BL.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_BR.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_CC.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_CL.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_CR.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_TC.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_TL.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-right.png | Bin 237 -> 0 bytes .../history/img/bubble-red/._bubble_tick.png | Bin 237 -> 0 bytes .../history/variants/._color.css | Bin 237 -> 0 bytes .../history/variants/._standard.css | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/private/._.DS_Store | Bin 82 -> 0 bytes .../__MACOSX__Bubble/private/._hincoming.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/private/._houtgoing.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/private/._images.sh | Bin 237 -> 0 bytes .../qss/chat/__MACOSX__Bubble/private/._img | Bin 237 -> 0 bytes .../__MACOSX__Bubble/private/._incoming.htm | Bin 304 -> 0 bytes .../chat/__MACOSX__Bubble/private/._info.xml | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/private/._main.css | Bin 304 -> 0 bytes .../__MACOSX__Bubble/private/._ooutgoing.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/private/._outgoing.htm | Bin 303 -> 0 bytes .../__MACOSX__Bubble/private/._system.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/private/._variants | Bin 237 -> 0 bytes .../private/img/._bubble-grey | Bin 237 -> 0 bytes .../private/img/._bubble-orange | Bin 237 -> 0 bytes .../__MACOSX__Bubble/private/img/._bubble-red | Bin 237 -> 0 bytes .../private/img/bubble-blue/._.DS_Store | Bin 82 -> 0 bytes .../private/img/bubble-green/._.DS_Store | Bin 82 -> 0 bytes .../private/img/bubble-grey/._bubble_BC.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_BL.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_BR.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_CC.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_CL.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_CR.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_TC.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_TL.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-right.png | Bin 237 -> 0 bytes .../private/img/bubble-grey/._bubble_tick.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_BC.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_BL.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_BR.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_CC.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_CL.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_CR.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_TC.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_TL.png | Bin 237 -> 0 bytes .../private/img/bubble-orange/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-right.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_BC.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_BL.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_BR.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_CC.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_CL.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_CR.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_TC.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_TL.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-right.png | Bin 237 -> 0 bytes .../private/img/bubble-red/._bubble_tick.png | Bin 237 -> 0 bytes .../private/variants/._color.css | Bin 237 -> 0 bytes .../private/variants/._standard.css | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/._hincoming.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/._houtgoing.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/public/._images.sh | Bin 237 -> 0 bytes .../qss/chat/__MACOSX__Bubble/public/._img | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/._incoming.htm | Bin 304 -> 0 bytes .../chat/__MACOSX__Bubble/public/._info.xml | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/public/._main.css | Bin 304 -> 0 bytes .../__MACOSX__Bubble/public/._ooutgoing.htm | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/._outgoing.htm | Bin 303 -> 0 bytes .../chat/__MACOSX__Bubble/public/._system.htm | Bin 237 -> 0 bytes .../chat/__MACOSX__Bubble/public/._variants | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/img/._bubble-grey | Bin 237 -> 0 bytes .../public/img/._bubble-orange | Bin 237 -> 0 bytes .../__MACOSX__Bubble/public/img/._bubble-red | Bin 237 -> 0 bytes .../public/img/bubble-blue/._.DS_Store | Bin 82 -> 0 bytes .../public/img/bubble-green/._.DS_Store | Bin 82 -> 0 bytes .../public/img/bubble-grey/._bubble_BC.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_BL.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_BR.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_CC.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_CL.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_CR.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_TC.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_TL.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-right.png | Bin 237 -> 0 bytes .../public/img/bubble-grey/._bubble_tick.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_BC.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_BL.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_BR.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_CC.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_CL.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_CR.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_TC.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_TL.png | Bin 237 -> 0 bytes .../public/img/bubble-orange/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-right.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_BC.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_BL.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_BR.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_CC.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_CL.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_CR.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_TC.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_TL.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-right.png | Bin 237 -> 0 bytes .../public/img/bubble-red/._bubble_tick.png | Bin 237 -> 0 bytes .../public/variants/._color.css | Bin 237 -> 0 bytes .../public/variants/._standard.css | Bin 237 -> 0 bytes .../qss/chat/__MACOSX__Bubble/src/._images.sh | Bin 186 -> 0 bytes .../gui/qss/chat/__MACOSX__Bubble/src/._img | Bin 237 -> 0 bytes .../__MACOSX__Bubble/src/img/._bubble-grey | Bin 237 -> 0 bytes .../__MACOSX__Bubble/src/img/._bubble-orange | Bin 237 -> 0 bytes .../__MACOSX__Bubble/src/img/._bubble-red | Bin 237 -> 0 bytes .../src/img/bubble-blue/._.DS_Store | Bin 82 -> 0 bytes .../src/img/bubble-green/._.DS_Store | Bin 82 -> 0 bytes .../src/img/bubble-grey/._bubble_BC.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_BL.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_BR.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_CC.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_CL.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_CR.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_TC.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_TL.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-grey/._bubble_tick-right.png | Bin 237 -> 0 bytes .../src/img/bubble-grey/._bubble_tick.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_BC.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_BL.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_BR.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_CC.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_CL.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_CR.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_TC.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_TL.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_TR.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-orange/._bubble_tick-right.png | Bin 237 -> 0 bytes .../src/img/bubble-orange/._bubble_tick.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_BC.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_BL.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_BR.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_CC.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_CL.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_CR.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_TC.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_TL.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_TR.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_tick-left.png | Bin 237 -> 0 bytes .../img/bubble-red/._bubble_tick-right.png | Bin 237 -> 0 bytes .../src/img/bubble-red/._bubble_tick.png | Bin 237 -> 0 bytes 544 files changed, 439 insertions(+), 1335 deletions(-) delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh mode change 100644 => 100755 retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg create mode 100755 retroshare-gui/src/gui/qss/chat/Bubble/src/make_images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/Kopie von incoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._houtgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._img delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._incoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._main.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._outgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._variants delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-grey delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-orange delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-red delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._color.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._houtgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._img delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._incoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._main.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._outgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._variants delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-grey delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-orange delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-red delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-blue/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._color.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._hincoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._houtgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._img delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._incoming.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._main.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._outgoing.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._variants delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-grey delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-orange delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-red delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-blue/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._color.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._images.sh delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-grey delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-orange delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-red delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-blue/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TL.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TR.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-left.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png delete mode 100644 retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick.png diff --git a/build_scripts/Windows-msys2/build/pack.bat b/build_scripts/Windows-msys2/build/pack.bat index 20fb72c4d..75a66af3c 100644 --- a/build_scripts/Windows-msys2/build/pack.bat +++ b/build_scripts/Windows-msys2/build/pack.bat @@ -148,7 +148,6 @@ echo copy stylesheets xcopy /S "%SourcePath%\retroshare-gui\src\gui\qss\chat" "%RsDeployPath%\stylesheets" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\compact" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\standard" %Quite% -rmdir /S /Q "%RsDeployPath%\stylesheets\__MACOSX__Bubble" %Quite% echo copy sounds xcopy /S "%SourcePath%\retroshare-gui\src\sounds" "%RsDeployPath%\sounds" %Quite% diff --git a/build_scripts/Windows/build/pack.bat b/build_scripts/Windows/build/pack.bat index 204158ae3..8a82f35e3 100644 --- a/build_scripts/Windows/build/pack.bat +++ b/build_scripts/Windows/build/pack.bat @@ -139,7 +139,6 @@ echo copy stylesheets xcopy /S "%SourcePath%\retroshare-gui\src\gui\qss\chat" "%RsDeployPath%\stylesheets" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\compact" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\standard" %Quite% -rmdir /S /Q "%RsDeployPath%\stylesheets\__MACOSX__Bubble" %Quite% echo copy sounds xcopy /S "%SourcePath%\retroshare-gui\src\sounds" "%RsDeployPath%\sounds" %Quite% diff --git a/retroshare-gui/src/gui/common/RSTextBrowser.cpp b/retroshare-gui/src/gui/common/RSTextBrowser.cpp index 43bad4e7b..96180b874 100644 --- a/retroshare-gui/src/gui/common/RSTextBrowser.cpp +++ b/retroshare-gui/src/gui/common/RSTextBrowser.cpp @@ -51,6 +51,14 @@ RSTextBrowser::RSTextBrowser(QWidget *parent) : connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl))); } +void RSTextBrowser::append(const QString &text) +{ + //In Win RSTextBrowser don't recognize file:/// + QString fileText = text; + QTextBrowser::append(fileText.replace("file:///","file://")); + +} + void RSTextBrowser::linkClicked(const QUrl &url) { if (!mLinkClickActive) { @@ -128,14 +136,22 @@ QVariant RSTextBrowser::loadResource(int type, const QUrl &name) // case 2: always trust the image if it comes from local Config or Data directories. - if(type == QTextDocument::ImageResource) { + if(type == QTextDocument::ImageResource) + { QFileInfo fi = QFileInfo(name.path()); - if(fi.exists() && fi.isFile()) { + if(fi.exists() && fi.isFile()) + { QString cpath = fi.canonicalFilePath(); - if (cpath.startsWith(QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())).canonicalPath(),Qt::CaseInsensitive) - || cpath.startsWith(QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())).canonicalPath(),Qt::CaseInsensitive)) - return QTextBrowser::loadResource(type, name); - }} + QStringList autPath = { QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())).canonicalPath() + , QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())).canonicalPath() + , QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())+"/stylesheets/").canonicalPath() //May be link + , QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())+"/stylesheets/").canonicalPath() //May be link + }; + for(auto& it : autPath) + if (!it.isEmpty() && cpath.startsWith(it, Qt::CaseInsensitive)) + return QPixmap(fi.absoluteFilePath()); + } + } // case 3: only display if the user allows it. Data resources can be bad (svg bombs) but we filter them out globally at the network layer. // It would be good to add here a home-made resource loader that only loads images and not svg crap, just in case. @@ -285,10 +301,10 @@ QString RSTextBrowser::anchorForPosition(const QPoint &pos) const rx.setMinimal(true); QString sel = cursor.selection().toHtml(); QStringList anchors; - int pos=0; - while ((pos = rx.indexIn(sel,pos)) != -1) { + int posX=0; + while ((posX = rx.indexIn(sel,posX)) != -1) { anchors << rx.cap(1); - pos += rx.matchedLength(); + posX += rx.matchedLength(); } if (!anchors.isEmpty()){ anchor = anchors.at(0); diff --git a/retroshare-gui/src/gui/common/RSTextBrowser.h b/retroshare-gui/src/gui/common/RSTextBrowser.h index 05a0e0d2e..57f351d2b 100644 --- a/retroshare-gui/src/gui/common/RSTextBrowser.h +++ b/retroshare-gui/src/gui/common/RSTextBrowser.h @@ -39,6 +39,8 @@ class RSTextBrowser : public QTextBrowser public: explicit RSTextBrowser(QWidget *parent = 0); + void append(const QString &text); + void setPlaceholderText(const QString &text); void setImageBlockWidget(RSImageBlockWidget *widget); void resetImagesStatus(bool load); diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm index 1b8c4fe38..0b4df8458 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm @@ -2,25 +2,26 @@ %css-style% + - + - + - + - + - +
- + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm index fcb291fe1..9342d3071 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png index d9c28aaa7b247bae8cee3a07eb28369417012ddf..fa45de4abe17dfbd593342446d1065423b4479fa 100644 GIT binary patch delta 142 zcmV;90CE510nY)DBoYa5NLh0L01m?d01m?e$8V@)kwz$STuDShR5*?0)4>ryP!NOR zKP)cK(Wpdy&Z^K5rD(vgPZPOG0pCn!H(HOYVoX#k2a#Tncv4>QPH*RU)p)@&n8B&^ wW^in+pyutgUPZv}1{c8g-vTnGsRThiIEY))g8x_|)XwXr!6a8Q`d0XKffA={&!OTIu>?xg(nzrs* zTAX#2^?BgBJ$)~myo-g8mEC*wl%;@CO6maL9yN;uwKsQb?aGhVH^`p~;NzOYmk6|$ Ofx*+&&t;ucLK6T((mikh diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png index 8a3e85ec3cf4ec962b741ef200cdd2e943363064..68de5c2964e82362df65d4966de59df42fa3a3a1 100644 GIT binary patch delta 419 zcmV;U0bKr*1mOdaBoYa5NLh0L01m?d01m?e$8V@)kwz$gZb?KzR5*>*(7|gHQ4q)R z@66k`yV>n-!IA{4qQQWIBE8syJ$Up|=zry(<-v=d?4^P?dr+&;79ve+Hv8Uq*yPlt z>d_wzGcfRB7~y&n;Mw5yyZ0}jkA0pv5{1k`rd@e8oPq$l0st_(`gu8<1rRVZf`QTX zU=R^(4PZcj6VASzoKB{gfgzYd8-y%!icdIV2Px_<^mc6_kjUW{SB~;0v@OqRRI29faNu^V*a1=8j(oJhqK@`UE|2gw^=ib~D+ggpZVu@t0*jB;48x^VF#FehyyA}KxS`c@| zonR3JSJ{XfsTw0znxwSNxM-A;ai+YMt4pogR1q)& zUK3u0V8BX31q4uzCINf<-#@+I8SYYlctdoGvx+r>NCJU`Km`CW-0N+&xB5e(gXkc$ zf-_)5I9QORdV>Cb@5AfOuLHb7bcSFRZw=NOj1g1>6+H^1gG(81KYRGJ*LnNpWxGq^ zgxo2)Gh|K(PVwVfRTXwegRRbwCl4OIYJVPm{MM%oLiA7sL+%aHE4i-*MnHFe=gs=s zU}J6l@rw@cy4#dNsRgCX4E1QKWd@mi#$OQ;1!holrMz+HZoYDRWvO*iSC`LF1T(Hn zH84gja2iS7fv=(fmIql{a z>wg3$>J&f&SOn&QIbil!z{E5t`Jo+;4NO4t`}nWGWUBtb{{wykY;bU8Q|4Rw00000 LNkvXXu0mjfhTzzz diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png index f18a209e2aceca343be94459c34d56301601f01b..db142436459a07044864026b63ed4c8f471e7ca4 100644 GIT binary patch delta 432 zcmV;h0Z;y(1nvWnBoYa5NLh0L01m?d01m?e$8V@)kwz$gdr3q=R5*?0lEG>dQ51&1 zlP0*(tv-iK@!13^_zt=gK@p1JvVx1+N(!xQ6&KY|H9~7_QpcppOeT{%_xvt0O2lbj zz<+fv-1GhC{2aTxmq zSt#*hl2zY-{!z0OxPvf)pcJSA2qPKg_>bcrFsI`F4Ty##f*`t>yAfqbLLTXzO$gnC z10b&j6uxjQ1*IDEg^gTHdqu>8nRifs+e=Gq`@W1t!1<(b+vpXn!~(d%NBl zKU=*IyaPsc%>d0-)9DXqeC(y{e;F|z^k(VC!<~G4Z4KDE%pJgP+-pbAeirexdtP+5 zyVJerZRW+B%K7A?^#1^W2UWrY;4ARCYCONpc^PmM2*9)gO{#b8<<$Y2{64&emh1mP azX0|kb delta 480 zcmV<60U!SE1D*tsBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zn@L1LR5*>Tk=;%cQ51#0ea@i9$StqoGx!d^4_@dS@C?L+aAOQ!7zqAFg*4TeU;`Gg z2rbi&r5&cznVy;L#TgBh24ip~JJ}a!t#7X!S*-n31xf{{LRLUtDtRds3WFr$^@p$H z?xP0}fj2;`s!F8*KoJl{Py%aEBUlxG6d{Zz6unjiq<~{efqE|>SOGC$5fo5hI2z-^ zgElY#+(kM-V8r;%;N9ZQB7!SQI#G)2G@C#I6jv^o3k>qdD;TjTiV;|E^oUyD2I>2i zS3q1HbvfYfEq{SAf-wSs6=Cl*p}rTE@#>T3IvMX&6|M%{yJImTh~NikoWwkT`*_Ug z-P14me(fdD1k&mL0Kxoii+C_eRrOx`Z8=Y{^9LRnH#zPN5C)F W&)urfDj5&}0000S|Iv5xjI14-?iy0VruY)k7lg8|diDm{GITpX)*)xkW k3Y+pun-*L-a4<=MA%KI~@5kp)9zabDp00i_>zopr0KDWFZU6uP diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png index 346d6e3d65762794cfe71cc1e44b422e753833ed..60ab43b8983ea6b88929d821253f174d3cfceb79 100644 GIT binary patch delta 143 zcmV;A0C4~40nh=EBoYa5NLh0L01m?d01m?e$8V@)kwz$TT}ebiR49?{%rOo?P!NRS zf7T0e0<{w;oxtJT&AXCOJdKbDg~}u|*=+HNa}qFgb6%#gCx8^D3DH)j4w1qHAVFLJ xkMaYb0uqSQH-Noj!1&_=0hQiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WLQaxQ9Lo_D7 zowSj&!9jo}{k{AjAs^l~2ibDYJ?eRT%=E*=eiwnBn20{>8;Q-6bE7=H4&2axZRXF+ z_{2b!HTKOEktYU>3g>>h*+0l`ST%87be+`JvwRZHpRKm@<}_!$V7eNsaF}stx0KuU TDcMCpXE1oW`njxgN@xNAb{#*O diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png index e876448fc04de5e260f29a18c47b803dfb1211c1..77934e9d98c4619d8a4c58a35c92e1e8ba31c6a6 100644 GIT binary patch delta 156 zcmV;N0Av660o?(RBoYa5NLh0L01m?d01m?e$8V@)kwz$gYDq*vR49?{k-G_iKoCUV z+LB;vh8AW8f`J_v8yJhf9Rod()4PE0000< KMNUMnLSTX&=sVB= delta 183 zcmV;o07(Dc0rvrrBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zbV)=(R49?{k|7R*P!L4l{%|8s($iG-U>GcdGgQ|!!O;X}5KCyq7vTHUX0rRtPCUl9 zF$h=`%&YjQFt1`!AfOwbyzcD{=z+<$*(sbyweX6d%3ts+h#-KtC}@t!#^kT^&F54l l_FZGL9(ib-`L{DwHV+Ig2#D8^M*si{002ovPDHLkV1kc^O$z`3 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png index f21120bbd914a125538c0b785f736a9ec8f805b8..bac53adab7dcd74fd2bb22096603baed5a9eb789 100644 GIT binary patch delta 131 zcmV-}0DS-00mK22BoYa5NLh0L01m?d01m?e$8V@)kwz$HQAtEWR5*=eU>NLxk%57M zg{lUMcb@%EO#@k6%@wI>9s}d9CqJm`!ta0oQPVsImS2CV>OcmTKmVv~Ak|&?>mQZF l@bQ;F)HRTik*ek~006@27-;*V3-0bP0l+XkK DVg))t diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png index 5212f419dfa4ce8c1bc022832176b74aa12032ee..e9261c34c1fd113d578cec4c373d00629efd3a5d 100644 GIT binary patch delta 373 zcmV-*0gC?21GEE>BoYa5NLh0L01m?d01m?e$8V@)kwz$gK}keGR49?flD$p>Q4oc{ znR|EHWtZij4GVOJHIYO*TU!e)EVNK!Wn%12wDbuqY%F{QD__dO9%6uN0fhx1v2mK2 zV&=;^CjAk=?T8Yv!1WTPEn%1Hx?3vhDn#->Xw81#~0Bcs9oXMi%ia ztON+)2S+!TQIe#cR!l)*<{XnL7ZyZJi#i1*X6+epc!X)qwI1rJAZx&qvWuf33743YW(XB6FM z#qEkyIatU6NtN8bcJ+GxQgQwLwC+LObQ9P-Jhf&~yAOsd4-vz$LfKe7kIE^vu rl_}LQ5-)0nz5~Dl6T78t{_5Zd+cGkR2svLJ00000NkvXXu0mjf_t&hu diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png index f1c15529ac3dd93853e7e205110c781abb76a8d1..25ed23587760b59978b9f58f5a302b768b4c815d 100644 GIT binary patch delta 430 zcmV;f0a5;h1ndKlBoYa5NLh0L01m?d01m?e$8V@)kwz$gc}YY;R49?f&`(QLVHC&l z?|JSx+{u}An4H0MS1?;Q?t1}lf>uEUt-_7;0>Z5eUxFY(fkc~H*`~IIo1m3KC8U(z z95H6*KKIXaj++88M{3m%&g#JD{5bHx69E-K&dfhWIxAa4)AGP_|IvK^mA>70-h2P7 z59nV3cU~udHt;z|Cqusd7?AmN-+JGdlhxZ#fgG?)fz7X}r2!7TvU6PU?(;F9_Irer zgZ1Raqb0Vt`098gj*cHJj)X0O81tkr}wb(I#QIEMf+hS~{`?z*vzC9Ai)yUQG zYIs$AX_yHPW42T0O5xNzN#0T+$Y7^R@6F|n{96ehM7wnPhhD@$W%NT}@n z1B8P33k=#&Y(jtrqcIyGuL9lC6U)I-LZ0+D^R4$!zrB6_ z0kD6gk+sjM4hm&ZDBC^DyUrfny?#;b@4h~Iv+&Z#y+6{(%BNJ(9}76hJu6#1Hg@)j zcRNdm%THba@mVB6UV1X;Nu4KgN@(Ez&2eUKUtwhG?qXwp@c}R*B66yMRmJ*$Dk~!x zuM3mSQLeX}wQ%;)l4(x0IpgF(ITTx0W#*LBDWMVW+-T8gP26hCJ$npH$O$~%W;VZoH8U4G6$+42vOrACYqQA#(?f`1R~XN wM!<*=NL5$8l(9>7OtXDW>K7szp!Tc5cVW577|V9!b^rhX07*qoM6N<$g6uNP5&!@I diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png index 3a6ccf16ab5092e49d7590a424ae7f93f668e693..c162ec17ac366fdb7e03d2af862bf9bcd80d7b2d 100644 GIT binary patch delta 371 zcmV-(0gV341F{2+kUdL6VHk$5 z=e+0W@nC)uRO-PnEOAPSz$hZ9rur2vEiLs!g2tBS3R(&qg4TAYhW4o8RD>NBeH)H_ zM|lqq4>#P`a0y={vGQs%w7zwu5+h5?v*QS0iN;b8Q4m&wB^pCOG?<^q(UqNHyS8>> zI72nJk_pOx{t-X~KnK4L`Zs{YH}>*&zIvt{r&OrrNo3-1<9*P@K8fe78fUo#BF{=YtZn%?8gAaOyzb_A=j;De;@x51&H?UFHE;Q|8UpIgq<)> zG6I0@`3PVLm?BsPD3L&5--!a~++Meujni{`a$)LL(PN_9?h+e~4GsW$`2KUVQLjge zbLnQwuJ}(rV?*}9fB@2N`^~H4%h33AysgqRg>3R)fbq>q4|wtRHxCAt_zJ7bPk#Ub Rr6~Xa002ovPDHLkV1ne5tO5W4 delta 397 zcmV;80doGb1Iz=EBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zNl8ROR49>+kg-Z!VGxDCGylKddv{m#?yjy0F0R34QBX`Hf~8nkN}eE5NEy;t`2+z8 zfnXJ^Ed;@8eGT8hQba2)B(P(#SKUI<1H&)_=P>ih-FcKGRX4tmmRG+VTeZHizS1U` z2y#*rNr2QK1}8|!Ar71KoxhEd_VTHJm9o`tyN)Dq1|0xL5@N7-6#V2P3mJA&$l^}Vfer-ptw8&Oz!m-tdjS#ES>(`ouZPJcu8IqLvNcTS$TXP3)9`1 z+N^lFuu{aTv#6 z&wMA}!^|X0w1`&9MWocq$@~Gk@Gm%#gOlbmD@R8+DaW}yTz`@NV#+dJpBq#C~o%R z^kIyTE0T{`7f?`FnRIn<_ z&S8?u-R1tn`t;CiBAQlJiw_JHKtT|HM6d&PMgb98gFYO-Kv&(!?1r;@xJ5)9B6i#O zG$Dc@7=S(d7Bx535^8J2^msem1LNE7{;?2Xiims*RMD@spEP(~bcO;r>+6HA-qB6Z zV7Lb`jX(Oo;&z&}2K|WX^w+fa%>W+9e+21Ff%y3?!kv}MeaTv!x z&%N)P`-6ew62s|AHe^#`5;Kd9*PD-Q$;d<;87vehW#H-thpuy-7e(iFSHH(_ z=t^GS_4)Ma>HC$XGgm=C6u;Oif~cbY9JWyf6+{$2)~*^MAc`9CH+~pEK?KCdX&VFy zd?SBb?WT}_g{V^V`52=S$H!9#wuS>(*8ix)lIJ=$5My$v^Vf0nIM4n?5dh1HC8lmQ z*4`X;h_{D-pyO+ot&=?7`Sy*wGQDegnWJ>DZ#V}W(>D|l5 z!U}5kEQ~3=m$Eydp5c+pe5I?iCCF+jNBJ&Od|97cPipo35V*1cgIn;7`>;p%;KW(3 z9Q8`~kI!p!%jWIr0LTI5`rn<%=uCgxVk+&#`(}Y&AjH=S^}Pt-01?0fUV#eKR`>+@ W9en=YMo)AA0000!k}*hIVHAbG`~KHF6Jsbv6R{}N3Qiq@Q(YXyN$BEII_uD-TNgoa?O15R zLEF(uu!vORq9BT5P^8qjScwK&jZrX0q4G`#g9vTXyPof!d(Y+Cc=k+~kf>We03n$D z2NVJW!w|J?ee(Tqf~HZ?d5s;TSjm*&p&GvVGzgh z@67Y;pWApYM3O^HFh^1dfna43UqBkcH{si~u!_}LiC6{{1wmqv+q=DeW>VZj(z|L@Q544U|5|(Pz0aAGjARmHf(8i*^8g|mpTI^$8!I2fLSMpG@D1z( zRzk3`vat=K;stdw;DyPFX67u5i4w+)#>Nj;v6~<3vc=sw91#h?+NsBZ>K=Iz(JpYA{D?KIEpnxvVenL;uJnM|S}PX!ua=i63)y;*M# zwjR8D#r9yAESXXgg(ONcEiy8B#-9-p1?CA{n!Po5yLG*~xN&kxZ!CAI%#ed+O$81R z1D1db>3qIAduQ%iXT3UcuD!@g+2(9H^H)Fs13ExgvTPJrs>{}mE4CIpaW%I82uzGq z0n5NDa0XZe7LEl>bkjOi<*|Vx2}piD{}q_bw14pbfFIDLd=<9Kwj=-m002ovPDHLk FV1hBs%Lo7f diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png index 65a70a294c68ab74dc4a0c2c312cf1731749aab1..655a2db643b7df080a7e28e1975d369655293f7d 100644 GIT binary patch delta 425 zcmV;a0apH(1m^>gBoYa5NLh0L01m?d01m?e$8V@)kwz$gbV)=(R5*?0lEG>eK@>$# z^~@@gtt&smrT77UmtT-=+=vK@kd3&CAZ`K?B`Bg0%tA)OV3-LRdZwp)x~Hq|bun$6 zMJGSt-Bi7z-np+X754PVSXf3%IJU&NMoBm&su+1X%G>F~@dMx+5ZO`|EbI(fSVA_o zzyi!7B~++?1VoRrBqOz;gr&{u47|B;UMDn8zkxN^r~fo`*JueTVi^>%O|tk=Hng9c zFTko7px9!&o4{BJ902is*^p1#vU*V*0!7~wh9PxO4H(!!hJ%@`6Cd-M@@4TZEz%jV z?44jI?0`kc0=5aj`Ksd0bWZWMJguG=uYmE58SD;!?f?)BjarUom%P84P#%_Ni^o^{ zz*iveYX%rb4Y_D4PKy~Q`6c;9T`!+4KCKRx2f)#7?f~KL@x7#3YSJjqn-BGVC;VJM7_}MkiZ*$%T+y`2q>Oe(T_x`*-z_4@q>$JW9AM^+69Sbid Tk}NI^00000NkvXXu0mjfs8Pff delta 473 zcmV;~0Ve+E1D6DlBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zlu1NER5*>TkwIz{K@^6+SJRM?1Gw=Jp23wD@JPBA#1puXs9O<16vc%>i6~;!;24t_ zC(L9rnVIgXnXc;kU33evGekrm6x8DV-}hdX-Ov?Df|N+9BE^7WMHM5Y#ITIq{(Lka zTt2u8ya1+kpsoxFlMsfJ;piYBGeb^)3`3yWi$lNzkyd3UkPJ%+lVNh0890zcznla3Se<8p0y3=H1}U7{mJ?p;4gZYmiwpl{{Z|1Upe%z9%Qry P00000NkvXXu0mjfa^cWJ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png index d498c3b85f7247b6ad649037fa1efb814859c843..61cf46ac0dff4acfbe3ce37b9e205812c1a3b8df 100644 GIT binary patch delta 68 zcmbQo*vB|QMToP&BeIx*f$uN~Gak=hkuuTEQ2qDwZ}S_w8aijS^-5V}JxDMVU|@A; VdaCkPwTb}S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|KI_QR!`%S%8&s3ho%d(31`R`4?;~0Rz)78&qol`;+0DGb~8~^|S delta 154 zcmX@hc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 z?J?wQFyLW6ulbij*xTLic>K)DK1r{I(oQ@&5k-q!zMVANtD>4P@7gBaR2M~&&cqWM z&vz*=6i{fI{);i5q2veSf_`b{Wxdi4yua3*x_-CLy6>;>y~iJ>?*-b-;OXk;vd$@? F2>>KFI9vb# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png index 1d79a09045df21acb1298b87afe0e0560536c937..38c07275fe6e45d4fddde8eefdc9d7787d3aaf59 100644 GIT binary patch delta 160 zcmV;R0AK&@0pJ0UBoYa5NLh0L01m?d01m?e$8V@)kwz$gZAnByR49?{(jgARKnz6D z@AOEOdW0M=Ck&H^%?4wEm6S}BZ%P(WVu^J>IiC9q z*no>B6XOx!`|uZ_n?KM2qUmwKwG5a5g805zAE=9uYI%bCR+vBo%m>oeED|&+%KiWV O002ovPDHK)LSTaR4MA!E delta 172 zcmV;d08{_q0qp^hBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zYDq*vR49?{k}(d0Knw)uP=1t0Q1ddX{3m~*qCuiQ@T9opl;R2yEmL@HOS^L6G};Sd zh_SP68FMZgJBGZbh50!Rz#CXq`ORM0SG)@{an^LB{Ts5+oLpr delta 154 zcmX@ac$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo9le z|NQ@N&uq#l9O|2#kdTl9#0yt73Z;CsHwM*6{-suYMQ3+Vz3`a5{+hsr#dL zDes??UwU`3{ad!J(Oz<8&I99RtFM>}Op08=&d|mnGVOrWw&_5d89ZJ6T-G@yGywql Ciao9X diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png index 0a1c804de7d869b6974d6c0d778047a421d85d67..7e43bfc0d10d6a3b427907ed327087b2c1932059 100644 GIT binary patch delta 362 zcmV-w0hRvG1E~X$BoYa5NLh0L01m?d01m?e$8V@)kwz$gHc3Q5R49?fkUdI6VGu>n zo$t&0NnV~Yi3xe&4~U6k1koZOZoooIEi_mOZo$$W2sRdO!P4zm+6jUnK|^AZASsNB zjZ;l=@8QhAe~XqlC zrzZC8xfhLh&Xho{rpN1h=|=swl-S*W>^HPc(AL#z1=VUJ<%{pH99FaH@Yb-&kER2z z=N;y0o4ylPDyVh)ZhkbpnvV`D9rsuvKPkHIJ#R z_|5_p@pOP{zTd3nd(E5OwO+nfGHu%AgdcqMgitWhe*gf7FUQX&XbCfw38SVm{st_IQeqT$FEYB6&M;%$7L5hERxpSbEqn{<#;qWN%Qh}sMejp|h!n!58$k%7Rn#U3NnHssqd9m{ z<~MilzxkaOwh(KiRz7f6=kVd-z-=c0LO`y}e?`W>OeR+H(^CJga$MiH?8Lw7EVMU(9IzXKPsv-$t;e}5+*erArh%WV|xMY*b}`WUBJA_O#X<3Zz$nRJvs1@RWe? zs4+@(Cu~-i8jHhPXdyjvO~}-d;Yf%%vlb#kAj))olwcy92O56^!nW+;QM?rx1H6?C zEW124n5+g!q*K5c5dYD@L=o|*D58prAfg}&2zSE(scA%=F+i^azW|vtomt`-F~k4> O002n`MNUMnLSTXgFv8ma delta 453 zcmV;$0XqKT1A_#RBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zfJsC_R49?9(miWbK@`UE|1CdHEYQlwE3KY$I-NChuJ7F09sL`|X{_Yb723hFwWcY}u{fw=( zdga^IueX6>KZ)}y@XGPzc(zHDa$)v7m*!KFlgaYTa_1tDNYdT`u3!>UX&f?t?dDlZ zQ_gf+ar^T0N^~?{WS^D0kt^|&Rzazz7Ni8iIW%godCUFtIQd5p|{x#qSu%5JzdmkJ_00000NkvXXu0mjf#qigV diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png index 09424c08eb81a05e344d47e090dbecc5160655a2..b3f423af08638310b472bbe32814bafdda7f4cc6 100644 GIT binary patch delta 357 zcmV-r0h<261Ed3xBoYa5NLh0L01m?d01m?e$8V@)kwz$gF-b&0R49>+kiAL+Q4odC z%-sD;HoIok7?2Gq6bx1>S{OtS#6o-!5v+U=!56Sr!A4n&fX`u<+JJ&AF(%nui`|5% z1ot#E%*^>14&kTBJMzlrxqB;BIXDaF02T-{SQ%ikvML~A5G7F4X7|Efv`pQI-QH4^kh@9)Q4ogzf99Nx8Jg;;1M2qL5w5fKCndn>Jcl7Nk!+6z`z ziSJy|vV>`m$Mn&HG^7i2I0vCoam4^YsZm~)K1FZv)BoYa5NLh0L01m?d01m?e$8V@)kwz$gI!Q!9R49>^lCduXVHk&> z?|PM9tGEUoBoZ?li!fL^*_iwV5)&~COEs}bBo==J8^R=EDhURWh%{kBwRO4luI|3? zGaOA5iJWKn4ey)Zv%Ig^Rt2qf0<9HFN>msiWeXLCC?!EjcAp!lS9$L3IrHv;TLl!~ z7#ab{XeJbY2oMMa8iQy%V`nh)=CrlkcW5o;h5(~206;_`0D%VdcQsK`@Xnu0~-Xweso@$FPCBQJ_6g5!(@F+Vz!KHsuUt6uM^j6E+y0ThOxb9>urwO2J|lHdM$ew9TdT>)zXAXwyi9)RUZ#oSgTO9i358P*v1(@m!}>F6wzSRM~qh(#W}I zZyUw=dZzZQsva#2L1-g_3bb$1+$LgwVax$@JeEuxh8LnkB4Ub&02s|jkmhLjCJMk< zG{|fsLRZ{38d;i__Nl<|cyG*uJqjp}svsd#;t?DIB@ZOOi zo&VsW;!r&!k345)6v8zB&N{R1Il=AWG|C3`V=v0;Qu6 zg3Jxg1Hl7-yg*gMBIGX^nB0iyHV_oU2Q?dAb;3Y7g_O)D(kvvi|Ax8hC42W30CY2B z&R3jzB5HP%4o82W)7lNWYMI7vz4Ekpx34!&-twUtd$^=(nGw66cvqNm{h6(+3!3N6 z>zB31O*{?&OeT9`iKC%2x9G}xZBE>xD+Alkt=6kitpH;{#COuHX)6^!9x6G7l*D$D z51ON`0;53q?@>&9sc#~FIG8ubL(4!Guzct@sQ?qO0UdY+-ueEt@OdI5+9{>OV M07*qoM6N<$g80IrlmGw# delta 388 zcmV-~0ek+f1H%K5Bq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zKuJVFR49>!(!EPUQ5b;n=iCpyY8I0DfeDF3ElmwUOJhW1L(tyP(Adz{pU@Oe?a?F= zIkeai6i5z5(oz{Ar8gS7T_NyoxGF_lJJW&p$8$LFs$E$W;s0ZZ015<;D?f;c@9-DY zMB!nD3@Vx(1!(=JeTzW}bW4KQ^?@OOf+*5a4FBxEBY5G6}pi-5rEG2TR zrlNk%-eVQ#+HJjUwhDY#NeQST z-b$$OMmUu?%hXbpti+4ymKN7`fH`0o&=8Rx)}mXZQ;E~eg*jub1G7COA}IN>WJ)O= ihyWJg0IrC10KNe&8%k^!YCiW&zS3)pq!>TO_ uX;}v?my4J@2yNz9$Ufd6ec{^Q^|CDzaye)G_?H0fWbkzLb6Mw<&;$TxgEQj* literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!2%@r2u_~>q?nSt-CY>|xA&jf59DzcctjQh zRbK~TMkkHg6(GT~0>^Y94c5zWJpBDtAjiqm#W6(V{Mw5fIT;iLoG-eZn>gpXp0AtZ?Fd5wajShAXpFhReKFdvBFfMk&|q3sb^GXI*+3pZtT-Rhsvbf34aN zplPZlt`Q|Ei6yC4$wjF^iowXh&`8(7OxM6L#L&pf$k58jQrp1D%D^Dt3WFAkhTQy= z%(P0}8WcNsOap3=1lbUrpH@mmtT}V`<;yxP!WTttDnm{ Hr-UW|GHzU{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png index 6d5e6e15eda36dac15385b5669acce580ba3e064..eebfe3b91f39640ebc240a2644d8a942a55dfbe2 100644 GIT binary patch delta 377 zcmV-<0fzqN1FHj&865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGv;il70XRuS zK~y-6)seAE13?gmznRNkAsiN>7C9paDFnehhE*OlkB}mrq`2zdz@QdJ@CflpvO5-W z1Hm)V(jNw9i}~jNXNB+T0C&^r^dZl4r>ckus*0+TBncvdhyb810067&db!zbwhuGR z41f^At{0J3fB~!7Z1%ibtuV8H-L^PrW;@VNfRC~)%cg1e9GDs2`yIf0PtpPqK&z_q z!{P8g%d*rt*Phd?6#(GZ>vfW*>D6E`xJlC#5!rJRUHk+vz?WsYD2n1X&+~KDZCdX= zA%uewqSin&nM~fg-EP0v>z&1e#^Gat04zfY@8j|KrLOC&D2hwxTqinEICO)k4X^-S ztEze&jYd!N`CQD*0g0+6as&X|UrB*eAP4%uHE;oBzX3!k;DGF_P5}28Ky)K5{eRXc XJuI;eMf{uR00000NkvXXu0mjfEZM9x literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>8 zUk71ECym(^Ai=T%$8;bK*2@rcZ0%tn=dGuUV~EE2rRNO2nH>e%9+s;uU(UWUph@GP zgNqJ}ptk4au!HyNlhdcppK$Elp?hjeI}-FGI=Gf?-00cUUTvQJ@YrsbwSU@LW1l6a z9sMlYd1K$M7;hyO*FYA=DTOxc{!ePnE2-+TO8 zz$o0p|%ElrP z|Eq<=kT+^K`|;neLtQU;3Y;*C{&+93x;Qm?<4yxshZe5TS0<55k6q$tP&mcI$;nx~ zzsbOp;iquV;y>awOp)8dvhMBvcLnHi)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU( zWMyP%Wn`&sU}R-r5O9S-3q?b2eoAIqC2kFhojaxhHAsSN2+mI{DNig)WhgH%*UQYy dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(69BkXt|I^d diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png index 68871ceddf27294f43f97e6c2cbab13d5faafe97..2763880e9bdf2967b314aecd09661e44b80f3a15 100644 GIT binary patch delta 366 zcmV-!0g?XN1E2$t865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGsR1W{0WC>H zK~y-6<&wcl!$1^8Pb44Yu6|zsLU%2tU~$o9vT!G4AyN?+LKhODK^mcuPSco|OfoLa zloY4^0WS>94BT_yT*gyM831DpZQC9#d$(Gx>cL=e1-t^9o-XXh7~@=8Ym`!Zpv55{ zIHdJqp63A|A|y%j2~>dj18ACm=3us?TL?f|mMj*FXW-ij=o{=L)?5??X`1dQlSv5d zoKMhNJ3Hv!&U8AxS4u5`+&Mv2RYw2-tu=X`6Ncg2cs#xZl9L@+fR%_KA_PIO91e%q zzzdMM%m98}*N5_&reVEam!r|>aW+RbJoaU5@>D2nGr^LZp9PhE1t ziT15L;D+CZzkmV!Z M07*qoM6N<$f?<7~?EnA( delta 424 zcmZ3$e2aO4WIYQ51H;x|=C6PhQRD=%g{b0wh>g z;Fu1i1;9Aw*xJKD#v@M`#}JM4OZzu^F*^#h?YDkkTEq15Da&b*mAP+JZg?q0EWMbZ zsKgSavV4Ye0gLIAlF7UG&fa)p<8Hw<^`H2o-~74%#$I}@h={8I%hG3e=gj%E$duv8 zf*;JLk$t)P4tq9>WJ*u_DILwPa;h%!5~uVWA;u-94`*LLf7-f^X+hz#puiJ9r_M}j z>NvGFB6&w$&5Oy2SDCl5dYN6Seivh~EPzu@4=65GEIi@@@i}l~H);&AX zGRddj@8x{U-MbO1M!E~+DpGB zOS}d8SGB}7q9i4;B-JXpC>2OC7#SEE=^B{n8W@Hc8d(_`S{Yet8yHy`7zA8l&_dCW io1c=IR*9rR7)^&_=ZSLTBDa*#dz_2B>?irBcEbxddW?)EuJ)Uu?^vL38xY(DD1V0ni5W&6cEH=t$)Pgg&ebxsLQ0M<1g5dZ)H literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W=!2%@ZVz%W1DW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`0$SBdfgIbxnJjv*44lmGmf->7lGWzMF+)+<3A44O7f zEG|`_?13s&OI#yLQW8s2t&)pUffR$0fuWJEftjv>VThrTm64&9k)^hQk(Gf#z!e59 z6b-rgDVb@NxHTwt?wAJDAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ048rn@Bjb+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png index ebe042e97296a7b05ee2f71031e3f9214b27c374..70a084c58cc8dc1beaf3543f6e812aac1b8c3bee 100644 GIT binary patch delta 130 zcmZ3(w1aViq%0c)1H;~Z_vQd8&H|6fVg?4j!ywFfJby*X#NQfGuAVNAAsQ2tQx34` z@bK{b64#5dP*zktcmM=WoH%jd$dMxl&YU>|rca#c5ICO1;F)lxK{5Tn|Ns9r%Ncb9 b4>B-hNwd9_;mD8xTEpP!>gTe~DWM4fx1lrb literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhRgkmPy6ft{7V@vq&OHDo_*T@)UR6N8c~vxSdwa$T$Bo=7=U_= zbPddO4GcpJjjW6et&A+S4UDV|3<9n&XrXAx%}>cptHiBAv2({Xpaw~h4Z-BuF?hQAxvX}(6P49wzX=K5#@mpqa`CQ5(vLGLN@5ADW_)Mv pxHp{t0z%d<2gY`1Jc^xhR%Z$p3p%f;`S9G?GGFR*j@ z7IinW6#kqQsGXKRhtq3Hkj0wWw&ELJXjG=_*Zi0{VWz>eR-5-GbES8`6Xwy|x$G~{ zFx3**h?11Vl2ohYqEsNoU}Ruuq-$WNYhV~+Xk=w%Xk}!nZD3?&U=VPHK?_AgZhlH; zS|x4`ik&;A0X0a1YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;uc GLK6UyPg|1! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png index 8cb90399455c87336899e6097e512ba72af5be7e..1ea1710389d0af614fec4be5b6d0d914709439ca 100644 GIT binary patch delta 127 zcmZ3*w3Ts!q%0c)1H;Myzc?VpS>O>_%)r2R7=#&*=dVba_){a?$2>8 zTnAxBCym(^Ai=T%$8;bK*2`dF-Fy}d(oDbBkTH+c}l9E`GYL#4+3Zxi} z3=EBQ4a{^63_}c!tc(n;j4ZVcjI0a{0PsvQH#H~TGbH_BG21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0sy*RQtJQ! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png index c3200aff4e60ae100e14e960fe4a4afba18239ed..1fd1527eeb09dfcf3a3f341cd66237406168b239 100644 GIT binary patch delta 331 zcmV-R0krVIGkpU-v0SZY( zK~yM_#ZfVCgfI}CwQQd)ID;Ebm>wFwlC(i0=&CgQAZ5Nlnsj`Dj@N-xAkZO&%PCE^ zvaFfenOWe!hyH-4+xMda1c2(g4y&qqiK6KFbUKwnh|41a1V9eM&^YHllu}M91t}$@ zl)pxxqA0?y>pqhtxf){-1OcRfl;E6$F?Lsg0O)ZXzp^ZA;yB*Obd#Llv)%XoTbibg zwH8`y2q6Ff-unea1a>4)mSvLX`MWU&LI`lq;l1C;>-;1@0A$;?uTd0TwAMSzJK%u> z0&sTDJt?KO&uN-=+ldI?`@;^-*4lh6%zKY%ng9UvJcBW|T;RX~3xXgb)LI+P`L=D1 du@Zr$%x^VcHJ1-av|#`M002ovPDHLkV1f)qld1p! delta 404 zcmey%bclI^WIYQ50|VD4we>)XDaqU2h2ejD|C#+j9%q3^WHAE+?{yGnbkdkz0TL`L za7+i%0zk~muz1zM`#{DiPZ!4!iOa1McKb0U3bgM3X}tU9{8H02PYuO`eufi|9J>*C z`J+Oc_=1fecr`fQJ1l&kn3$aI>a0<+ePeyZF{hJpN>-Cso|`$RTcW=IH@iDOqY_6^ zgF@b$`NuA9-QT76Wx9VXkN)(Jl^u%`wz^vV`}ptY=d0JYZ7n}N%i!Xxhez+_B+E~W z%-eZYwWRF!T(t@(hBb1*G4`@&A1k>0oR;@Z;EwO5&B`nb*PIW%^ZW5^21c&3>hP&@ zEl)}W80rHU+L)IpJ&aO+JMUk?>EBFA$827Qu5}Rs`b)LMHKHUXu_V9nO2EggJS27X+RBVIGm;on$0XIoR zK~yM_#gIK}0znvtpV?ibu33$Zg$-HiUHbig5QgC`a8YGq0Vwr( zRzfVxqE@TXZnqf@hxen=s831z?!Vzb7`u(ZQ)jE< z!VfGFmo67EB&8qa^vT)Nc-=tpqY#TB8<%yGvZ&!ZsS6u^N9vqx`e8hI<+HQ1C57wT zKl{rcc5V35eQI}oq;J^cryGnVbf*4IsJJ%Ebp9TH`ReD&mu!OdKR13``JLxsg}4# zl%yn~>+1H%wQBP%0ADoc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngBaz BqjvxR diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png index 49fe22b335f593f65c80a3334818cc9a5fd00f23..c76994a6728fa41ec14ab479e1ca5c6ddd702f51 100644 GIT binary patch delta 348 zcmV-i0i*u-0*(Wa865@y006zd-kbmc010qNS#tmY4#NNd4#NS*Z>VIGM*$~)0UJp~ zK~yM_m6E+`!!Q(u&(*bv5@J=R6yz9!*ANV*(4{y_mvr;1WXOYbEM&>6z=x-KrU+wDL^`+F0AK#Rp9jH0OMcDo~E3_6|8nYnFj2T-2pqaX-YN~xje zc}F#`App=|FnEzt4qey%ml*&U0Bts#_wjf6vZk@l3T6yeO=d3N?mQhIIyiVs;bPg>?4lj u8*A-Dzu*7U3a3Z_@p`@fJpD+QR`>>(Xf#)GZ`Oza00000z%d<2gY`1Jc^xhR#m6dZcucy6z~pyBH! zuds9HiQFgm4eAc)>`eMAe17W2&lf8HFgxY0FTbqMVIGQ2{4^0Tf9@ zK~yM_mC~_F!%!5)@qbI8b;#1i**6H?e1qVm_!1ogq3&WgArFu~LYG2T$sBM91zp6U zAP7PT9g^EixS`y8U0M-buHX2<`N83wfe^x4YXPvyf?z`PRllZ#MNr00000NkvXXu0mjfc9EFf literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhR@+9A#k=CP0;g!}elcC}&N0BhY2UWJPG6Z_ z_J8Ryk$p1nk$BDb*IRnG&Y5HT|6sil^UUsc9bUP0eO9YXcI>>(8MaF^KqJ?8jqlc= z1zQZan_LpOq@EVmHvj+qcLl0q88cYSfv!?5ag8WRNi0dVN-jzTQVd20hDN#uX1WH3 zA%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsW()}YwAV;WF{B*=!~{Irtt#G+J&^73-M g%)IR4VIGSOF)00S-w- zK~yM_m65+n!%!55zk72-QJ(Ey`T}1UReOsG|hKw ztvd^LVC(+`opZEvc6M~m_0IQyKXALE2>8 zUk71ECym(^Ai=T%$8;bK*30m(yT=a5nds@_7$R{w_w+_Tra%GK3&yXHWN_3qa&FwX zdExZ>?TZYwAZ${y2E4M)FK7R}Hhhk?}+)wpk`X$ElXMMwFx^mZVxG7o`Fz1|tJQ zBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4}a`RI%(<*UmQ0&|>4X8m9WJ7R%T1k0g mQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT& z^Tze_%-hYyw&CUjri}ZX32gcYRuo;H9rBj{12a>#*(aUNSK^TVN zr@E&nnq(4!haf0|WTB{8xpAutuftn%=|#Bl3Pc1^5Erfl1r?GQGRA>%oI`j0E;@q? zXFM$Z;Detk>gBDfHEHYU;9L2ey|DZAZzEGmjb>&dFz$KJ#tMH?P^16f@#exm}TVxKtl2I zqvrmt*}e6Rs;js8lO0KlkRr%wApn|5tz7B2boavXRcl)mr)W;p>)hHbF_>SYdHT-q z+IC#Oar)?-VvVSn1e2!iIFOvZvgWYsL(sVFSDA00000NkvXXu0mjf_Vvc% delta 433 zcmV;i0Z#tV1MdTnBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zY)M2xR5*>j(#>j9K@(bQ^D zk4Rz~35~ei#}N^+!x50a{b*mmTb2QT1wug)er2czzPJCy?s89=%#eX>%mYoJ;on@F&^h~ zEp})9zO_fUqN|O$ld<^~;-nlSM*J6c z)rZ&IzH-LWrDY2j7R?JBSCW_XZ{+Px>5AA{8wN)s(#}C b1HJ>s#-zD{^QyuC0000W diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png index 639fc3878ea5d5dca14cf5762f9042e6314cd98c..3cec3cc27249238e8865fd4cec95e7d74074b083 100644 GIT binary patch delta 391 zcmV;20eJr91I7c8BoYa5NLh0L01m?d01m?e$8V@)kwz$gQ%OWYR5*?0l3hvzF%*Tr z$UM0kAKiybZ~?AE5quH!#W#Pz4HPUEDX5e}5h;b@FLkJ;woGd~otl~4_>dHfPP+lm z(@k>oo!mo|^fxRhFcvZc+M=`pEnoz+Cb=o4t6QuC_dv#+0#INrhy@Xp_!v}sOoo*8EUQz%?xg)4JbzI{|nPm_Up!LXJiDDGf1jhLTlFd#6F%*SAkQeYld;}lEXK>+CAH$6s6XVhtb}rS(%AXj*iugCiAR&YR zBRGr-%`e5a>vPP`>S03)CbLdkh1UrR3^*%13($$ZER2U0?=)_gTZWSO1xbM*b##w*@%28VE#r#AHVp zc%VlRhY))>9ThC^a(G(f05}I+?AbD_(C=KT8<*i#n?bcnd#A$jSW!-#U0{-R^t5uo z2Ji^zopr0K%{ov;Y7A delta 84 zcmeBUoX0ppMTw=@$uool2x>S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|Lxw`GmA0` joAOGV7F;=SFiC+Sx1Bj$B)dBlsE5JR)z4*}Q$iB}lsXpa diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png index f19354d8b9debeb3b9da8fdecedb487288a22a0c..ecb8de13e29d00f00686754ea4cc7cef4cccccf6 100644 GIT binary patch delta 133 zcmcc3c#Ls^iV$akM`SSr1K(i~W;~w1B4whRMni=K5rMN4Ai}-VH`)1sudy9NKz7U;?A!g?)8X<$s72%&ua( l(f%xQ2jhzQ+oi6>-(vWy#1rtRTaEz)JYD@<);T3K0RY(zHTM7j delta 154 zcmX@cc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 zopg}1!GVV*{cxuBzuW_SYfsI}t99A2$3>vVQeaby!B3ZMD?PFfJeu2F+AOf8!7^dq zrtK$oDpZ`*{}GbV8}o>{k)dBGpze9xg}JA{R+aD4^P9C(#HU(S#TaNagQu&X%Q~lo FCIFe#i(`n!#J3lA^BxM|X}ef#9HN%U zrIx~!rIy%W^Cx(L$3s;;+xXO-7Sry$s_Iy9DCo>mU+v(CFs|p5%S;|M-CXBb-)f^@ z&v@?}yB(wc{&%cVx7jW&=iyfu-lVwGIer(T{bG4O=O!su1|aZs^>bP0l+XkKSi3jZ delta 164 zcmcb@_>^&iiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WrlRRAV4rkTAcs^Oq(c0+IIB&9&_wpA{4lSz{Vu}fnndE$`RBU}+ z?1q_wH&jxYnBNyVl>bz{@Pz+J1FLrRzc*}4j2C_QwNPMzobMf{UAx%WBONrE4H>>> Q0Nudg>FVdQ&MBb@0CBiIBme*a diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png index ce4a2357abda53c72c52e065065e6f53e012d5e0..64fa0e7c12a8affd27262c681fe56af55d660044 100644 GIT binary patch delta 120 zcmX@ZxRY^$iV$akM`SSr1K(i~W;~w1B4whRMzou!i(`mI@7ePkc@HQE9B{Dz^>D@n z+fAIh))yw}RZS}pLN1Q_J2vIUk~pBvu_~ Y-5MptmwlC$kpT!iUHx3vIVCg!0QoO3TL1t6 delta 139 zcmdnVc!qI;iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{W@JUv|;Lo9mN zo_7>%Fc4rlxbsS7w{y({m3W&EyniBm&TzfBwNhn<^eQ%y3tBUnx9;4ujOX5RF0-4< q+?#p(uCu*u|9av<`N@Qpa`q)tL<9}Y-u(hv#o+1c=d#Wzp$P!yku+cc diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png index 70e3cad6488456ac13e35246e92806d8e1d1f619..ef3d963d6c89263f9550239c6f19ce1238cbf948 100644 GIT binary patch delta 349 zcmV-j0iyo51DpepBoYa5NLh0L01m?d01m?e$8V@)kwz$gDM>^@R49?flDkdVSEFl2_(P8610Go z*f`Y`XTF(pGVtFef6&X%eo=q`a&bg(xzA}7aFVm>I2M&f00KDAH}o43w^`4v60bnM z2wDGE3v#f3P4GD2zFyD)jdiGXAZ&wM2Rljy2#|Xj^3Ys%`s{R}ya!+8;FOoY)~6OG*Qm85XK%`tV9f*iDi)3D=+_bB5rL}sRP6&k&cujDE zXc80 zJUET*6vYZ;+rZosBLPQ1mODt@A9GqRnI5e^I2n*nh~}VTAqtux5NFR84F?oUs-TXw z{P7OzgQFm>ovS7~5Fn@o><|QTWg=L-#Ux7v8zrgAn)ArlH)vrB_M>1+FZvTf?feV1 WBq$^yWb~K-0000T_4>~FWmlec?|sxuZK=2GlSAxGW-LTbuuE$r9Yy{mKWtPA5>M4==WWCO`2 z^*UQULQR&@+2_cdb7*Y`m{50{0Y{0^kYQr0CWa=PowK*~_Bh)3zRie<5E{oQ#n>E+ m&BN&#?J2V}liEMSKlB5Wv4fmLIG}I<0000ixy{zW&8!PsCN(08Dw7(_b>#QQ>%DK=8QL`9_GlN*e41LA4=607AKejLLwrK0j31<1U!Iu2ktc(0TX~o7ws*K0Ac)p^C3apJb3Dt z>w)V+&Gn}WU|Ga0hJaR}_}M_H?^Z7{^&{Xn;RxMrB&=qvMh34HwvH!dZMTvD0000< KMNUMnLSTX?HnCm+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png index f407cbbf7174d0c69426e7331dd1db7290bc18d1..8efd044b0c38f6e929c25a6fbd82f792815ad99e 100644 GIT binary patch delta 345 zcmV-f0jB+kULAmU=)U* z^Ch$-R_(>2Acm3_+9)^_9V~GX1R;}y|G?27;jV)?If{#egOjv^;NYxI{sIS~n;7i{ zZ5)!`P&DuI@g2_d9L^EOBRgwk4m~ccEF09eKnZ9-LMKRQkPy%nC_n^#6h7D{zw2_D zHl&7Kj>-XlVK*QFi0Zck3Y+fQGnPPj*>bSh05>nAJG7LdE;iqVtwkPIZx7niOJzu0h9twK#N`_;abss zd3>gGeow<&3Mw<5W{Iy)Nax}UfS%vRKYO6=Es~o&mDeh*cgW4f76A0RUD_vi+`2`k rZPQ<6q4cjnF`gdK+C1ho?h(HM!|^(95NZhF00000NkvXXu0mjf-BOoJ delta 336 zcmV-W0k8g;1CIlcBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z3`s;mR49>^kG)C*Q4oc{xw%)#^#>QSq97<%iiIGE7FIzlwy?4lAHdc(@dYf!T4HNw zV-wP7FbEn&jV!pLi8f=g%O;>ma*Ba(;G8)ls;XpCRX&oK_UR5`at`ZTP%vN(3>g@< z;4&^45U{=G&f7C`woRB^!u%o_0TGaY{6@CxqRq|mEmDaXX*XbL1tvr? z<0ZbzCp3K->NU8#87#m#$JF!;#psyk^l08eqa2UjY zPY6Pbg&=}LU5Y|M#X*N62s${cs7sw4I{6KXOCjLcsl^YFPhcrdiqcJdD^gLHiWN#) zUxo^?$=@M`6s!<$xrgKK;DHmby{%9RJfQ1=qY%dhrwcCNDX5frdE-2H#8#n#jqe6P z^GSLnAc{bL>)n$x#7AVw+@zFSCm!Vb4j(FDkw6}wfa!URn7**L%;{m8SwIIw8<-b< z!x)9R6fq-`*hz70?Xn2y+5qd{hz>&{Npy&@l_?H@$o~rLSGd2W+MvFg#{@JzboluR z>W`c}P}?Z5|MA5Y&^lCeqyK@f(&UA^L>xe!7MZ8S~Hab7?zRIm^&1hMulENuiq-^VURz)HKb z619l22^KjpLZU|HjGJAHBwPfG^M`@?XP9po7-2g51_SgpC=K5lz7+I^zONxT=h@lB z-a8|e&LX8`q&O3R6vWwgXz1>7>{TD!h8IeX|2EExiC@qoxykVlU z#YKYs-KNtBP)dyfk|;F|g#~Q&gbWUeqUfK1RtWW5 zY99seW{%NXGnsh!@d26*u3lZj;wdY|MQqzn2)Mt7c8iO*b$ZJutoc5!(l1CuQ547V z@4fF1^@(Loa3Y8xVlZeE?87Li(Q30AEg~j^CX2;jGYFPdG0Y$iMO1_#d+3v~F%;Ro z?_R^(!+&^p>iO_H=fDxRzTgmm!&?df>qjZHu4`HfwFM!-`L#kjAOVCQiZ_#*Eb$+& zsDFTPfb^z+DjM25@(VU~*Zn$)XP^c_4gc+$DwqfWd2~Sq6G8Iw6D2X2h=X$;#VUuv zafR~oG$Z-m<|twSWDnRD=sQZcR2TQzv5wQgTH>o3C-alcg{m=x4559`<&%9b?y~i+ zDFN5nAh|R{;dPrEw}*S!ATH!t115m*_qDn8B2%?3P0F)ltN`OcUxvO*0px&wAOKoG co6gI80xgqW8LPEb_W%F@07*qoM6N<$f>a8X3jhEB delta 354 zcmV-o0iFJd1EB+uBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z9!W$&R49>+(7j3nK@h<4|Hk!5#6!h2HrYckCqUQ==82={$g50-gIm?N^{*10Z!%U-OM?{6($- z{Ti30h?C+msl~$!YO}jw%aC+DN;+W66zhif+&TGt9%ZeS__K{%9WWn1!So8)SDu?$ z?iUJdZtY-#=9}ix4N|sf~W&i*H07*qoM6N<$f)eMG ArT_o{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png index 7bd1d84f96210f506b40923f10ef8c1a2a308d8f..c27064260bcdc497b9d02283fb391d34243b906d 100644 GIT binary patch delta 136 zcmcc2bb@h$iV$akM`SSr1K(i~W;~w1B4x4?qefP!r;B5VMeox~2RR!81eh;IMtFZx zC`(t~mXO`VA@^^c?-@q}RvRYID;rIdCh=WX*4(Oaa>K#&9SL`yHqBY(UQ{d76Bkzc ojG;_=4rA^s2DJmV-}irFa(yWhwdq9ACk7z!boFyt=akR{0KphGMgRZ+ delta 275 zcmX@Xc$sN}NQ}kxTlL_h{frxmkk9Q90XVnTE3dl;#{+UQPjnwv7_bxDtjLu?FEbHuBg>L zqN>Gyvf$_ve#soOA0?7|az1Q3XrB7PCZyh=;VhfD!*4$Z;|fN%sk84b$*OOVXQ`Gb zO89({8EA)UiEBhjN@7W>RdP`(kYX@0Ff`INFw-?K3^6paGBUI>veY&(vNA9TxWb@? gq9HdwB{QuOw+6+|9n&V7X>c-ly85}Sb4q9e028@cK>z>% diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png index 5018dc60a24d9feaa5276bdf6c53d3e3d97802b4..4d22f79c1686731247507ba865954266790dae11 100644 GIT binary patch delta 407 zcmV;I0cig21k?kNBoYa5NLh0L01m?d01m?e$8V@)lRW|_e*s}hL_t(Ijn&c5N*hrW z$MNsElbMOZ7&K@%icnm%w7M17E?oKyeXTx(8=pYB5d|MX3YI1*{z>8(Cv*QC7dPUf zV``Tk_`&6J&*vPt!r#>ZcFNto)BJERrIkSH_%Z@9$8B5q*qivU0OTKxur2dNPnkVOPWvBm-zjiLl%Y~yYNQ>pm=?^d1 zjFtIx`C3F=bTYV{msD*N(b(`qf~n&9(j+nS|8=Vw*E({C97$Qpukm*JJpTfDU)2VV zAB>@j^BEbstdBmD3)c(LdiHVk$?Fe7L$8%G`g4a*e_i?gT2%;t5! zTb=gRKaxL}W^`I6Hv3#rz@>l-0UvthY$`t4GaczU%B&am{{6LSo378!k#%^+_U?4S z>%(i)i`MzP*!<7cMSH1S!`+>i&n(gxn)&$;V~}U}ygZKfvl5J-R}w>^V?knlzmw#*G2z?e`iag8WR zNi0dVN-jzTQVd20hDN#uX1WH3A%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsUz$l}zY W*tuicL^E|R1_n=8KbLh*2~7aT%HZe# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png index 994743d0c35fbcbb3dfa3ae441e0e8ae19b52d5e..00d2a62557ee75825ea580d6dfdff0e7c2b62ec3 100644 GIT binary patch delta 397 zcmV;80doH01j+-DBoYa5NLh0L01m?d01m?e$8V@)lQ9A(e*srXL_t(IjpdTRN&`U< zhrg9nK8=mw`}ihyieMvXW2u6b*rc!%L`4XqA_)FT;7ra$a>mQ$a(8<(7Q4hKm%M-j z!_F={-*5KE8aZB51Q3N>p%BbiATOa*NHWrs%VP2BVgIpTIh~t*(6s_0kCvewdtJ67+%JLByR!A1)9LKZyd~1o(3!d r1u*iU*zYTUUKOCm&%fhO{U72RLk{KW$N|#T00000NkvXXu0mjf{}{7r delta 550 zcmX@b{D@_ONyvhP!xZ9? zb1jlP<2R!*(=mtJ&z)9EJ3I_%4WC^)XGV#fW5X=>2mF7RmSxLx+-(SG-Z=9h$BRFH zR(ADw%HKHc-6ttg%kJ`yL!r_0!Ykn4ejHW-*vuKWW8=OY4nx zGZ?o%pE%#jkFhS&e(9(Acm6Y0FgKt5_wA5m!%tx7tCqM%l%yn~>+1H%wQBP%0ADVO0|RG)M`SSr1MhVZW^~e+T>%m-D{xE)(jq|2 z#ZX=)$_Hdfd%8G=Xq->}vw!1LduCBaVN+gd(}F7p4kjruSlwiH7d*FeB2bxXiEBhj zN@7W>RdP`(kYX@0Ff`INFw-?K3~@FzvNAHXGP2Y*FtRc*2)M$ag`y)jKP5A*5?KeT X2F1=D(BU06on222ryrmo|}Fu z_k!#Ww(ZY+>a{aOIUE*rc!b2+q#xUP{q)_pUZTYjUh}(Blek1Ly<+_k`0v2^M!sL( o3%*M!zGv!{>$mkg_(Haa*UU!Hiqo|~lK}`kUHx3vIVCg!001d8<^TWy delta 275 zcmX@Xc!_C(NPO zi{Z`da0wtI%+tj&MC1J19#5_Y0|A!R?Jj?M!yWHGTwNP{%UMK;gR4oMyDc+K^X4+w zASSl{%cqQ-87voYzX*P7slc-8b@-pA{Cd`1J>Qu)-$WfR{^;!Zv2M-hHHplkX+pMh z*mV1VR;ZS^MwFx^mZVxG7o`Fz1|tJQBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4} fa`RI%(<*UmQ0&|>jbWm>IwymttDnm{r-UW|P!w1g diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png index d538eea05ef1f8dd4163652da56db18c4c52aa20..08b3a53ae51f2f915e3468a1e739007eba744cbc 100644 GIT binary patch delta 145 zcmaFBbdhm_iV$akM`SSr1K(i~W;~w1B4x5ZqegL@r;B5V#>BVhtoa-gL|h&g>z-oD zbx#&_$+m2%cXNC=wc?7O<;lNA&Y_7i3eHA6oiA9M6O23puDRTP;=taMbE;wPO zi{Z`da0wtI#nZ(xMC1J1iQZhT4m>Q{a;Jo=q{{C(9$b37(&EzFB(XlF^XG3h30#`c zG@;2OC7#SEE=^B{n8W@Hc8d(_` wS{Yet8yHy`7zA8l&_dCWo1c=IR*9j37p_CGbH}uaW*VFfp00i_>zopr0FU5duK)l5 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png index 27c7d02b412440b51d42af05c3322c4805a27cb5..9900f8bee2b9771716b89215a9069d9e051e16de 100644 GIT binary patch delta 129 zcmX@bbdYg^iV$akM`SSr1K(i~W;~w1B4x59qeilyr;B5VMeo^5yLlTNcvvoOe6mbn zi{okW;3H34YDyAj&1lelklEC_U%w&b;H+mx2UB8w`d6$y+4?=PO6C01rmyq#JWjUq h>@Ik3B=IWy2LpSKNL2mC6hQ_c@O1TaS?83{1OQF>Hc9{h delta 275 zcmX@ec#3I)N+%J4>=0 z7*;l!>Sq;iTANoSyZg_Fy;s^j_osfSPN^@raq_UA-E5w=S09-dZWE1Lv8U)R&}h{X z*NBpo#FA92@ylT2KH0 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png index c5e3fc3b18d9f4f955f2dd4e7755d0a9b5046b7f..12ce5c81e7e4c29ed9126294767ae19b6423f819 100644 GIT binary patch delta 357 zcmV-r0h<251fm0wBoYa5NLh0L01m?d01m?e$8V@)lMVtWe*rH^L_t(2k;RZbP6AOB zg}?h|<~fgHfK2!`!pvxb2@uq%6>HGeMq*`YtSxm5HtxWMxC%QLU@WvDAU=zk!UB-k zc&l5S^WAeU{P)No^zw6G7a)LKMN#p(lbl7KJ~bi(?MP!CfB^b=|8U&d(6_$Po5W3M zRv2TcE(c>qJ?Qly*#%eS3c+0! z`)M$|i~}=f)Q9d4Y$Y(Cg3Zhb%K^v6)b~u`hG7cT64Y8Sn}8Bvd^Wa-@a# zSC}Z!0@?vbfmqZ6vkIUXII4v4^JnFq9Ra04PO zmtpa$gZCL27@a*`978nDFP(JOi>XlLX#Mwp>2B$NR()jFy>!9IFgNIe>ld!Ki^4PH zUAoO|UDsAM+*5m@+Qp%?;>4NEhc3ETxb*MTpKUFEXZbvi^YDa9ujfw8*XkLSln#Xd zpX=cA#UQ?5{TzWUBv^nL`q>7r!Pjz%E9xPAO77$!%;rD0R z&eB;$$;a0`k*Sitkm0zGBTi^$S!+h|8@m^Co*KOr{#E*d?E=q%!bL1;=?Sr+*}He{ zsCL=U_qLvGjd`L;%XY<%h7&1Ff)@{b-Ne4H-f?Zl<|oc8d78xoB)1Drc**tVb5ZL2 zlA>Ne(ImqJmgaDSo`VaU{1iI&?2bHrYvGe-!w(<%`pX|wCU9GbMR2*PYY8ZXZdhwp zXH+#)KrZj$&4$GZuOnJd9SOfS#c-zU?Z~74|7S3*y8o}Ve$GMlTN`xk9`AbN4-8t> z64!{5l*E!$tK_0oAjM#0U}&UkV5Vze7-DE-Wn^e&WT|anWMyCwaD_n&MMG|WN@iLm oZVif^JEj3ONP=t#&QB{TPb^AhD4*yd%EiFo>FVdQ&MBb@0IOs=ij&^_Du?E!`dNd0qq1zXHt8 zhT++VhdPw1e+0g)-21`y_|?S$5CZ0B;QYkUlPO zmtpa$gZCL27&ARx978nDFP&tq?~*9cHvjz`+osgRySzJgn5yWpa@spTWY5UhDmAsm zOZ{K7U+*ohO@%iDa+H)d<=wn}v-sPax^$8HbkT_IGs@ELRX&>=sC20Q(2sEQ1q{L! zhXsBr2YD<@fA{h0&L6)_*8g36^jqKEx5wGtUH-%io;Wq>!=&aC#&`1$mg+yMtWNy% z>5s$(dqK^eR)TM2o)}HAX#Oj4$F6eQ>)f80BiHk6&j0mu@qA?9!S#Uqj#}b-hNSB@ zsheKse!N^Cy5Psuj>hLs7aNlpZP;(^N+{x4)|R<;ZS=jD@^jWo#NKr|)taztTEhYH zjJ(Eo8ayRY#k;ncPUSkUwRGNU$?OHP8rA`N4lA7!L-=ei@=t7Acy`{s$^$`OE6+2f zvU{0Tm{~-gSgtsiDY!AyDSS$ru?h2)@D%$s6TH}NL@jvIT>rdzb#oA_i}Z^vYXTK` zQtX5^4g?%@ac)f9Q~x2OMQ!ym{iHUj)q;DN&hK45fBuuDvcL#XEpd$~Nl7e8wMs5Z z1yT$~28Kqu24=bjh9QPVRz`+aMwZ$JMpgy}0aqBbP&DM`r(~v8A~cAg>rm|6F>Rum QIu`?jr>mdKI;Vst04inVRsaA1 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png index d1b1f6b6459ac7d90d94dc2499f20cf3dc13909b..7e332b401e639e9ae497367421476df018d91456 100644 GIT binary patch delta 360 zcmV-u0hj*c1Em9yBoYa5NLh0L01m?d01m?e$8V@)ld=IPe*rQ{L_t(2k&TeeN&-|B{&& zM^hom7Y+wLzV|ujeFgIpXG*0m^M!lI3LkUofdotgB9g$8U>RTlQi23?)_mc*+4FSv z!8VOUDmf5pD+d&^74A7kNAiGw1nr=}(t8wAJzf(bzXK-4Rh zk{gQFEERF^%8-olr$m6xG?fX6TsV4V3E{BgE;cWa0f@$+_p+BzN2<}MFb>?LNN`T)PjXJl@My;C8tgN>CyL|Ov zGqW@Rz#l^Yy7}?yB~&su^!F({{{rSK1s~|0yw`7*E%65PO zi{Z`da0wvexu=U`h{pN37dLt_2MV-4e4n@Jky6Bx%_6IBbWHNo$vxt9klmmuqI2&z z#;q?5Zofz)8wmQw$UJKrpWaqX0`e@hc5>X@SORX-o|No?8WwP{5y81XU}v} z@SWjtqHD?CT@wT}_-2-WuUNC$!dvLm1#@Li=C}3@e(i6y&Z=prrg`nucXM)jA^BKA zg?)?tigzEbrj<6n)I8kPoY_CIA*%P9w0E)cnZ;9?{rYC=7k~Cy{FUE)V+8tLJdAn(2Aouk`x$imIo(?8FjY^uD~f@Vid%u06kQv;F;b=Z?hhmV8zr(|~O+ zT!Vq0RxNRjC`m~yNwrEYN(E93Mh1pPx&~&t28JPqMpj0KRz{ZE21Zr}1_4(Xv`{qU h=BH$)RibDRMA4zxxntTyGj%Qo22WQ%mvv4FO#p^>q~ zyea?^GzdTnf6$B~q}N-XB{3FUHIg&=Ts)rea^Hdh8juB#ED(-_QoB>J>+?)z1qjIBr~e=_0gGuuQckajqesB_{{+@M z+*dJsJ!`XU8h{M=3TmKafoXBm?Nqj_<%5pvJ^(#`MuNLCG+N}_?c!GDdEbRcpb7N- z30_;A+HY6cdd&bzKpXFCv_Aomt=Eo$C!ovFBYgqw)nez-uhruK0000PO zi{Z`da0wvev!{z=h{pN36a2lI5(V1le_uMgok>~6s)M7O{pPh@Ef<#hD|U9&`)U4C zRNB=Qzu0@eVv|h;$8L?3rUji!)!bJ~t?GBMmj_;|GcedM`Ajlxip_m)CJXNw`iXiU zHaE2xs5ZH73uNCj1Ue3q)JI*?+-~O;=e~Cnc3(KD!X@AM_shRH>D}FXC^wpM13|m`}8=0~8I|EOy)HO@@sYZo|KWr)c*LW(; zpyn{c{-2xN>a!-kT?q^T)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU(WMyP%Wn`&s sU}R-r5O9S-3q?b2eoAIqC4($Z9g3YhrcE?c=VD;+boFyt=akR{0Ew@oP5=M^ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png index 313e2db043272ac86789785d3cfd80ee2a7b1a25..8ef8a7a23dedc5b1edcbd0a0af5a940082ba5eb4 100644 GIT binary patch delta 352 zcmV-m0iXW)1DykqBoYa5NLh0L01m?d01m?e$8V@)lgI%le*r2!cPMr)N)4QBw%#n|F&F&>H`2;%Ct77WyirVz_NQ# zqXOj;NA+qkeRXlBojf*j+au0+{LPyrHVDxH@S0G%CHwMpzgch(C7f##YWcQzx;`|# zYI)CNm@z22TzbvQTERVdl`;!l`$mzicsyC3U%XLELK$_Jo~tFJ(On<~Sp0beV=s}I yDbFtCR&09*m;y{6`b`SJ0Ahd!w15w~ukr;9vtdv%-X7Ti0000RR9VIi(kBHyu5CkS9riDKkSLaLR>S$Lkfdw2~&X^S!I6yHh=9>F4A?1+!L(8#Np{ zmzH`KSa_B1G>}}XQU2vMLl0{ZU(fLcKfagEUVhMJ!ohOpVJbP>o|J5y@YBcw*Y|Qne zllJ{vT3^XBkDc55!wbP_UNP_9Zwy@j*n;ncwWm_9`I4=rdvo(%uDKc{;%Z;YrpjAw z`|?4++_LCGnf~xoZqJ_xU-s&av+?$P2@DF=64!{5l*E!$tK_0oAjM#0U}&UkV5Vze z7-DE-Wn^e&WT|anWMyCwaD_n&p+Oy}BR4-KGp!Q04#mzL(
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css index 443b58d74..c56eaeb54 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px; } +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px; } +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px; } +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px; } .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm index 66ef6876c..fbc2a25b9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm index acf919dca..b60708aa9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm index 103d2bca1..d5cc3d402 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm @@ -3,21 +3,24 @@ +
+ - + - + - + - + - + - +
%name% %time% - %message%
+
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm index 1b8c4fe38..da27694e7 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm @@ -2,13 +2,14 @@ %css-style% + - + - + @@ -19,9 +19,9 @@ - + - +
- + - + @@ -18,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm index fcb291fe1..10415c60a 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png index d9c28aaa7b247bae8cee3a07eb28369417012ddf..fa45de4abe17dfbd593342446d1065423b4479fa 100644 GIT binary patch delta 142 zcmV;90CE510nY)DBoYa5NLh0L01m?d01m?e$8V@)kwz$STuDShR5*?0)4>ryP!NOR zKP)cK(Wpdy&Z^K5rD(vgPZPOG0pCn!H(HOYVoX#k2a#Tncv4>QPH*RU)p)@&n8B&^ wW^in+pyutgUPZv}1{c8g-vTnGsRThiIEY))g8x_|)XwXr!6a8Q`d0XKffA={&!OTIu>?xg(nzrs* zTAX#2^?BgBJ$)~myo-g8mEC*wl%;@CO6maL9yN;uwKsQb?aGhVH^`p~;NzOYmk6|$ Ofx*+&&t;ucLK6T((mikh diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png index 8a3e85ec3cf4ec962b741ef200cdd2e943363064..68de5c2964e82362df65d4966de59df42fa3a3a1 100644 GIT binary patch delta 419 zcmV;U0bKr*1mOdaBoYa5NLh0L01m?d01m?e$8V@)kwz$gZb?KzR5*>*(7|gHQ4q)R z@66k`yV>n-!IA{4qQQWIBE8syJ$Up|=zry(<-v=d?4^P?dr+&;79ve+Hv8Uq*yPlt z>d_wzGcfRB7~y&n;Mw5yyZ0}jkA0pv5{1k`rd@e8oPq$l0st_(`gu8<1rRVZf`QTX zU=R^(4PZcj6VASzoKB{gfgzYd8-y%!icdIV2Px_<^mc6_kjUW{SB~;0v@OqRRI29faNu^V*a1=8j(oJhqK@`UE|2gw^=ib~D+ggpZVu@t0*jB;48x^VF#FehyyA}KxS`c@| zonR3JSJ{XfsTw0znxwSNxM-A;ai+YMt4pogR1q)& zUK3u0V8BX31q4uzCINf<-#@+I8SYYlctdoGvx+r>NCJU`Km`CW-0N+&xB5e(gXkc$ zf-_)5I9QORdV>Cb@5AfOuLHb7bcSFRZw=NOj1g1>6+H^1gG(81KYRGJ*LnNpWxGq^ zgxo2)Gh|K(PVwVfRTXwegRRbwCl4OIYJVPm{MM%oLiA7sL+%aHE4i-*MnHFe=gs=s zU}J6l@rw@cy4#dNsRgCX4E1QKWd@mi#$OQ;1!holrMz+HZoYDRWvO*iSC`LF1T(Hn zH84gja2iS7fv=(fmIql{a z>wg3$>J&f&SOn&QIbil!z{E5t`Jo+;4NO4t`}nWGWUBtb{{wykY;bU8Q|4Rw00000 LNkvXXu0mjfhTzzz diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png index f18a209e2aceca343be94459c34d56301601f01b..db142436459a07044864026b63ed4c8f471e7ca4 100644 GIT binary patch delta 432 zcmV;h0Z;y(1nvWnBoYa5NLh0L01m?d01m?e$8V@)kwz$gdr3q=R5*?0lEG>dQ51&1 zlP0*(tv-iK@!13^_zt=gK@p1JvVx1+N(!xQ6&KY|H9~7_QpcppOeT{%_xvt0O2lbj zz<+fv-1GhC{2aTxmq zSt#*hl2zY-{!z0OxPvf)pcJSA2qPKg_>bcrFsI`F4Ty##f*`t>yAfqbLLTXzO$gnC z10b&j6uxjQ1*IDEg^gTHdqu>8nRifs+e=Gq`@W1t!1<(b+vpXn!~(d%NBl zKU=*IyaPsc%>d0-)9DXqeC(y{e;F|z^k(VC!<~G4Z4KDE%pJgP+-pbAeirexdtP+5 zyVJerZRW+B%K7A?^#1^W2UWrY;4ARCYCONpc^PmM2*9)gO{#b8<<$Y2{64&emh1mP azX0|kb delta 480 zcmV<60U!SE1D*tsBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zn@L1LR5*>Tk=;%cQ51#0ea@i9$StqoGx!d^4_@dS@C?L+aAOQ!7zqAFg*4TeU;`Gg z2rbi&r5&cznVy;L#TgBh24ip~JJ}a!t#7X!S*-n31xf{{LRLUtDtRds3WFr$^@p$H z?xP0}fj2;`s!F8*KoJl{Py%aEBUlxG6d{Zz6unjiq<~{efqE|>SOGC$5fo5hI2z-^ zgElY#+(kM-V8r;%;N9ZQB7!SQI#G)2G@C#I6jv^o3k>qdD;TjTiV;|E^oUyD2I>2i zS3q1HbvfYfEq{SAf-wSs6=Cl*p}rTE@#>T3IvMX&6|M%{yJImTh~NikoWwkT`*_Ug z-P14me(fdD1k&mL0Kxoii+C_eRrOx`Z8=Y{^9LRnH#zPN5C)F W&)urfDj5&}0000S|Iv5xjI14-?iy0VruY)k7lg8|diDm{GITpX)*)xkW k3Y+pun-*L-a4<=MA%KI~@5kp)9zabDp00i_>zopr0KDWFZU6uP diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png index 346d6e3d65762794cfe71cc1e44b422e753833ed..60ab43b8983ea6b88929d821253f174d3cfceb79 100644 GIT binary patch delta 143 zcmV;A0C4~40nh=EBoYa5NLh0L01m?d01m?e$8V@)kwz$TT}ebiR49?{%rOo?P!NRS zf7T0e0<{w;oxtJT&AXCOJdKbDg~}u|*=+HNa}qFgb6%#gCx8^D3DH)j4w1qHAVFLJ xkMaYb0uqSQH-Noj!1&_=0hQiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WLQaxQ9Lo_D7 zowSj&!9jo}{k{AjAs^l~2ibDYJ?eRT%=E*=eiwnBn20{>8;Q-6bE7=H4&2axZRXF+ z_{2b!HTKOEktYU>3g>>h*+0l`ST%87be+`JvwRZHpRKm@<}_!$V7eNsaF}stx0KuU TDcMCpXE1oW`njxgN@xNAb{#*O diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png index e876448fc04de5e260f29a18c47b803dfb1211c1..77934e9d98c4619d8a4c58a35c92e1e8ba31c6a6 100644 GIT binary patch delta 156 zcmV;N0Av660o?(RBoYa5NLh0L01m?d01m?e$8V@)kwz$gYDq*vR49?{k-G_iKoCUV z+LB;vh8AW8f`J_v8yJhf9Rod()4PE0000< KMNUMnLSTX&=sVB= delta 183 zcmV;o07(Dc0rvrrBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zbV)=(R49?{k|7R*P!L4l{%|8s($iG-U>GcdGgQ|!!O;X}5KCyq7vTHUX0rRtPCUl9 zF$h=`%&YjQFt1`!AfOwbyzcD{=z+<$*(sbyweX6d%3ts+h#-KtC}@t!#^kT^&F54l l_FZGL9(ib-`L{DwHV+Ig2#D8^M*si{002ovPDHLkV1kc^O$z`3 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png index f21120bbd914a125538c0b785f736a9ec8f805b8..bac53adab7dcd74fd2bb22096603baed5a9eb789 100644 GIT binary patch delta 131 zcmV-}0DS-00mK22BoYa5NLh0L01m?d01m?e$8V@)kwz$HQAtEWR5*=eU>NLxk%57M zg{lUMcb@%EO#@k6%@wI>9s}d9CqJm`!ta0oQPVsImS2CV>OcmTKmVv~Ak|&?>mQZF l@bQ;F)HRTik*ek~006@27-;*V3-0bP0l+XkK DVg))t diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png index 5212f419dfa4ce8c1bc022832176b74aa12032ee..e9261c34c1fd113d578cec4c373d00629efd3a5d 100644 GIT binary patch delta 373 zcmV-*0gC?21GEE>BoYa5NLh0L01m?d01m?e$8V@)kwz$gK}keGR49?flD$p>Q4oc{ znR|EHWtZij4GVOJHIYO*TU!e)EVNK!Wn%12wDbuqY%F{QD__dO9%6uN0fhx1v2mK2 zV&=;^CjAk=?T8Yv!1WTPEn%1Hx?3vhDn#->Xw81#~0Bcs9oXMi%ia ztON+)2S+!TQIe#cR!l)*<{XnL7ZyZJi#i1*X6+epc!X)qwI1rJAZx&qvWuf33743YW(XB6FM z#qEkyIatU6NtN8bcJ+GxQgQwLwC+LObQ9P-Jhf&~yAOsd4-vz$LfKe7kIE^vu rl_}LQ5-)0nz5~Dl6T78t{_5Zd+cGkR2svLJ00000NkvXXu0mjf_t&hu diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png index f1c15529ac3dd93853e7e205110c781abb76a8d1..25ed23587760b59978b9f58f5a302b768b4c815d 100644 GIT binary patch delta 430 zcmV;f0a5;h1ndKlBoYa5NLh0L01m?d01m?e$8V@)kwz$gc}YY;R49?f&`(QLVHC&l z?|JSx+{u}An4H0MS1?;Q?t1}lf>uEUt-_7;0>Z5eUxFY(fkc~H*`~IIo1m3KC8U(z z95H6*KKIXaj++88M{3m%&g#JD{5bHx69E-K&dfhWIxAa4)AGP_|IvK^mA>70-h2P7 z59nV3cU~udHt;z|Cqusd7?AmN-+JGdlhxZ#fgG?)fz7X}r2!7TvU6PU?(;F9_Irer zgZ1Raqb0Vt`098gj*cHJj)X0O81tkr}wb(I#QIEMf+hS~{`?z*vzC9Ai)yUQG zYIs$AX_yHPW42T0O5xNzN#0T+$Y7^R@6F|n{96ehM7wnPhhD@$W%NT}@n z1B8P33k=#&Y(jtrqcIyGuL9lC6U)I-LZ0+D^R4$!zrB6_ z0kD6gk+sjM4hm&ZDBC^DyUrfny?#;b@4h~Iv+&Z#y+6{(%BNJ(9}76hJu6#1Hg@)j zcRNdm%THba@mVB6UV1X;Nu4KgN@(Ez&2eUKUtwhG?qXwp@c}R*B66yMRmJ*$Dk~!x zuM3mSQLeX}wQ%;)l4(x0IpgF(ITTx0W#*LBDWMVW+-T8gP26hCJ$npH$O$~%W;VZoH8U4G6$+42vOrACYqQA#(?f`1R~XN wM!<*=NL5$8l(9>7OtXDW>K7szp!Tc5cVW577|V9!b^rhX07*qoM6N<$g6uNP5&!@I diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png index 3a6ccf16ab5092e49d7590a424ae7f93f668e693..c162ec17ac366fdb7e03d2af862bf9bcd80d7b2d 100644 GIT binary patch delta 371 zcmV-(0gV341F{2+kUdL6VHk$5 z=e+0W@nC)uRO-PnEOAPSz$hZ9rur2vEiLs!g2tBS3R(&qg4TAYhW4o8RD>NBeH)H_ zM|lqq4>#P`a0y={vGQs%w7zwu5+h5?v*QS0iN;b8Q4m&wB^pCOG?<^q(UqNHyS8>> zI72nJk_pOx{t-X~KnK4L`Zs{YH}>*&zIvt{r&OrrNo3-1<9*P@K8fe78fUo#BF{=YtZn%?8gAaOyzb_A=j;De;@x51&H?UFHE;Q|8UpIgq<)> zG6I0@`3PVLm?BsPD3L&5--!a~++Meujni{`a$)LL(PN_9?h+e~4GsW$`2KUVQLjge zbLnQwuJ}(rV?*}9fB@2N`^~H4%h33AysgqRg>3R)fbq>q4|wtRHxCAt_zJ7bPk#Ub Rr6~Xa002ovPDHLkV1ne5tO5W4 delta 397 zcmV;80doGb1Iz=EBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zNl8ROR49>+kg-Z!VGxDCGylKddv{m#?yjy0F0R34QBX`Hf~8nkN}eE5NEy;t`2+z8 zfnXJ^Ed;@8eGT8hQba2)B(P(#SKUI<1H&)_=P>ih-FcKGRX4tmmRG+VTeZHizS1U` z2y#*rNr2QK1}8|!Ar71KoxhEd_VTHJm9o`tyN)Dq1|0xL5@N7-6#V2P3mJA&$l^}Vfer-ptw8&Oz!m-tdjS#ES>(`ouZPJcu8IqLvNcTS$TXP3)9`1 z+N^lFuu{aTv#6 z&wMA}!^|X0w1`&9MWocq$@~Gk@Gm%#gOlbmD@R8+DaW}yTz`@NV#+dJpBq#C~o%R z^kIyTE0T{`7f?`FnRIn<_ z&S8?u-R1tn`t;CiBAQlJiw_JHKtT|HM6d&PMgb98gFYO-Kv&(!?1r;@xJ5)9B6i#O zG$Dc@7=S(d7Bx535^8J2^msem1LNE7{;?2Xiims*RMD@spEP(~bcO;r>+6HA-qB6Z zV7Lb`jX(Oo;&z&}2K|WX^w+fa%>W+9e+21Ff%y3?!kv}MeaTv!x z&%N)P`-6ew62s|AHe^#`5;Kd9*PD-Q$;d<;87vehW#H-thpuy-7e(iFSHH(_ z=t^GS_4)Ma>HC$XGgm=C6u;Oif~cbY9JWyf6+{$2)~*^MAc`9CH+~pEK?KCdX&VFy zd?SBb?WT}_g{V^V`52=S$H!9#wuS>(*8ix)lIJ=$5My$v^Vf0nIM4n?5dh1HC8lmQ z*4`X;h_{D-pyO+ot&=?7`Sy*wGQDegnWJ>DZ#V}W(>D|l5 z!U}5kEQ~3=m$Eydp5c+pe5I?iCCF+jNBJ&Od|97cPipo35V*1cgIn;7`>;p%;KW(3 z9Q8`~kI!p!%jWIr0LTI5`rn<%=uCgxVk+&#`(}Y&AjH=S^}Pt-01?0fUV#eKR`>+@ W9en=YMo)AA0000!k}*hIVHAbG`~KHF6Jsbv6R{}N3Qiq@Q(YXyN$BEII_uD-TNgoa?O15R zLEF(uu!vORq9BT5P^8qjScwK&jZrX0q4G`#g9vTXyPof!d(Y+Cc=k+~kf>We03n$D z2NVJW!w|J?ee(Tqf~HZ?d5s;TSjm*&p&GvVGzgh z@67Y;pWApYM3O^HFh^1dfna43UqBkcH{si~u!_}LiC6{{1wmqv+q=DeW>VZj(z|L@Q544U|5|(Pz0aAGjARmHf(8i*^8g|mpTI^$8!I2fLSMpG@D1z( zRzk3`vat=K;stdw;DyPFX67u5i4w+)#>Nj;v6~<3vc=sw91#h?+NsBZ>K=Iz(JpYA{D?KIEpnxvVenL;uJnM|S}PX!ua=i63)y;*M# zwjR8D#r9yAESXXgg(ONcEiy8B#-9-p1?CA{n!Po5yLG*~xN&kxZ!CAI%#ed+O$81R z1D1db>3qIAduQ%iXT3UcuD!@g+2(9H^H)Fs13ExgvTPJrs>{}mE4CIpaW%I82uzGq z0n5NDa0XZe7LEl>bkjOi<*|Vx2}piD{}q_bw14pbfFIDLd=<9Kwj=-m002ovPDHLk FV1hBs%Lo7f diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png index 65a70a294c68ab74dc4a0c2c312cf1731749aab1..655a2db643b7df080a7e28e1975d369655293f7d 100644 GIT binary patch delta 425 zcmV;a0apH(1m^>gBoYa5NLh0L01m?d01m?e$8V@)kwz$gbV)=(R5*?0lEG>eK@>$# z^~@@gtt&smrT77UmtT-=+=vK@kd3&CAZ`K?B`Bg0%tA)OV3-LRdZwp)x~Hq|bun$6 zMJGSt-Bi7z-np+X754PVSXf3%IJU&NMoBm&su+1X%G>F~@dMx+5ZO`|EbI(fSVA_o zzyi!7B~++?1VoRrBqOz;gr&{u47|B;UMDn8zkxN^r~fo`*JueTVi^>%O|tk=Hng9c zFTko7px9!&o4{BJ902is*^p1#vU*V*0!7~wh9PxO4H(!!hJ%@`6Cd-M@@4TZEz%jV z?44jI?0`kc0=5aj`Ksd0bWZWMJguG=uYmE58SD;!?f?)BjarUom%P84P#%_Ni^o^{ zz*iveYX%rb4Y_D4PKy~Q`6c;9T`!+4KCKRx2f)#7?f~KL@x7#3YSJjqn-BGVC;VJM7_}MkiZ*$%T+y`2q>Oe(T_x`*-z_4@q>$JW9AM^+69Sbid Tk}NI^00000NkvXXu0mjfs8Pff delta 473 zcmV;~0Ve+E1D6DlBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zlu1NER5*>TkwIz{K@^6+SJRM?1Gw=Jp23wD@JPBA#1puXs9O<16vc%>i6~;!;24t_ zC(L9rnVIgXnXc;kU33evGekrm6x8DV-}hdX-Ov?Df|N+9BE^7WMHM5Y#ITIq{(Lka zTt2u8ya1+kpsoxFlMsfJ;piYBGeb^)3`3yWi$lNzkyd3UkPJ%+lVNh0890zcznla3Se<8p0y3=H1}U7{mJ?p;4gZYmiwpl{{Z|1Upe%z9%Qry P00000NkvXXu0mjfa^cWJ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png index d498c3b85f7247b6ad649037fa1efb814859c843..61cf46ac0dff4acfbe3ce37b9e205812c1a3b8df 100644 GIT binary patch delta 68 zcmbQo*vB|QMToP&BeIx*f$uN~Gak=hkuuTEQ2qDwZ}S_w8aijS^-5V}JxDMVU|@A; VdaCkPwTb}S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|KI_QR!`%S%8&s3ho%d(31`R`4?;~0Rz)78&qol`;+0DGb~8~^|S delta 154 zcmX@hc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 z?J?wQFyLW6ulbij*xTLic>K)DK1r{I(oQ@&5k-q!zMVANtD>4P@7gBaR2M~&&cqWM z&vz*=6i{fI{);i5q2veSf_`b{Wxdi4yua3*x_-CLy6>;>y~iJ>?*-b-;OXk;vd$@? F2>>KFI9vb# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png index 1d79a09045df21acb1298b87afe0e0560536c937..38c07275fe6e45d4fddde8eefdc9d7787d3aaf59 100644 GIT binary patch delta 160 zcmV;R0AK&@0pJ0UBoYa5NLh0L01m?d01m?e$8V@)kwz$gZAnByR49?{(jgARKnz6D z@AOEOdW0M=Ck&H^%?4wEm6S}BZ%P(WVu^J>IiC9q z*no>B6XOx!`|uZ_n?KM2qUmwKwG5a5g805zAE=9uYI%bCR+vBo%m>oeED|&+%KiWV O002ovPDHK)LSTaR4MA!E delta 172 zcmV;d08{_q0qp^hBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zYDq*vR49?{k}(d0Knw)uP=1t0Q1ddX{3m~*qCuiQ@T9opl;R2yEmL@HOS^L6G};Sd zh_SP68FMZgJBGZbh50!Rz#CXq`ORM0SG)@{an^LB{Ts5+oLpr delta 154 zcmX@ac$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo9le z|NQ@N&uq#l9O|2#kdTl9#0yt73Z;CsHwM*6{-suYMQ3+Vz3`a5{+hsr#dL zDes??UwU`3{ad!J(Oz<8&I99RtFM>}Op08=&d|mnGVOrWw&_5d89ZJ6T-G@yGywql Ciao9X diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png index 0a1c804de7d869b6974d6c0d778047a421d85d67..7e43bfc0d10d6a3b427907ed327087b2c1932059 100644 GIT binary patch delta 362 zcmV-w0hRvG1E~X$BoYa5NLh0L01m?d01m?e$8V@)kwz$gHc3Q5R49?fkUdI6VGu>n zo$t&0NnV~Yi3xe&4~U6k1koZOZoooIEi_mOZo$$W2sRdO!P4zm+6jUnK|^AZASsNB zjZ;l=@8QhAe~XqlC zrzZC8xfhLh&Xho{rpN1h=|=swl-S*W>^HPc(AL#z1=VUJ<%{pH99FaH@Yb-&kER2z z=N;y0o4ylPDyVh)ZhkbpnvV`D9rsuvKPkHIJ#R z_|5_p@pOP{zTd3nd(E5OwO+nfGHu%AgdcqMgitWhe*gf7FUQX&XbCfw38SVm{st_IQeqT$FEYB6&M;%$7L5hERxpSbEqn{<#;qWN%Qh}sMejp|h!n!58$k%7Rn#U3NnHssqd9m{ z<~MilzxkaOwh(KiRz7f6=kVd-z-=c0LO`y}e?`W>OeR+H(^CJga$MiH?8Lw7EVMU(9IzXKPsv-$t;e}5+*erArh%WV|xMY*b}`WUBJA_O#X<3Zz$nRJvs1@RWe? zs4+@(Cu~-i8jHhPXdyjvO~}-d;Yf%%vlb#kAj))olwcy92O56^!nW+;QM?rx1H6?C zEW124n5+g!q*K5c5dYD@L=o|*D58prAfg}&2zSE(scA%=F+i^azW|vtomt`-F~k4> O002n`MNUMnLSTXgFv8ma delta 453 zcmV;$0XqKT1A_#RBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zfJsC_R49?9(miWbK@`UE|1CdHEYQlwE3KY$I-NChuJ7F09sL`|X{_Yb723hFwWcY}u{fw=( zdga^IueX6>KZ)}y@XGPzc(zHDa$)v7m*!KFlgaYTa_1tDNYdT`u3!>UX&f?t?dDlZ zQ_gf+ar^T0N^~?{WS^D0kt^|&Rzazz7Ni8iIW%godCUFtIQd5p|{x#qSu%5JzdmkJ_00000NkvXXu0mjf#qigV diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png index 09424c08eb81a05e344d47e090dbecc5160655a2..b3f423af08638310b472bbe32814bafdda7f4cc6 100644 GIT binary patch delta 357 zcmV-r0h<261Ed3xBoYa5NLh0L01m?d01m?e$8V@)kwz$gF-b&0R49>+kiAL+Q4odC z%-sD;HoIok7?2Gq6bx1>S{OtS#6o-!5v+U=!56Sr!A4n&fX`u<+JJ&AF(%nui`|5% z1ot#E%*^>14&kTBJMzlrxqB;BIXDaF02T-{SQ%ikvML~A5G7F4X7|Efv`pQI-QH4^kh@9)Q4ogzf99Nx8Jg;;1M2qL5w5fKCndn>Jcl7Nk!+6z`z ziSJy|vV>`m$Mn&HG^7i2I0vCoam4^YsZm~)K1FZv)BoYa5NLh0L01m?d01m?e$8V@)kwz$gI!Q!9R49>^lCduXVHk&> z?|PM9tGEUoBoZ?li!fL^*_iwV5)&~COEs}bBo==J8^R=EDhURWh%{kBwRO4luI|3? zGaOA5iJWKn4ey)Zv%Ig^Rt2qf0<9HFN>msiWeXLCC?!EjcAp!lS9$L3IrHv;TLl!~ z7#ab{XeJbY2oMMa8iQy%V`nh)=CrlkcW5o;h5(~206;_`0D%VdcQsK`@Xnu0~-Xweso@$FPCBQJ_6g5!(@F+Vz!KHsuUt6uM^j6E+y0ThOxb9>urwO2J|lHdM$ew9TdT>)zXAXwyi9)RUZ#oSgTO9i358P*v1(@m!}>F6wzSRM~qh(#W}I zZyUw=dZzZQsva#2L1-g_3bb$1+$LgwVax$@JeEuxh8LnkB4Ub&02s|jkmhLjCJMk< zG{|fsLRZ{38d;i__Nl<|cyG*uJqjp}svsd#;t?DIB@ZOOi zo&VsW;!r&!k345)6v8zB&N{R1Il=AWG|C3`V=v0;Qu6 zg3Jxg1Hl7-yg*gMBIGX^nB0iyHV_oU2Q?dAb;3Y7g_O)D(kvvi|Ax8hC42W30CY2B z&R3jzB5HP%4o82W)7lNWYMI7vz4Ekpx34!&-twUtd$^=(nGw66cvqNm{h6(+3!3N6 z>zB31O*{?&OeT9`iKC%2x9G}xZBE>xD+Alkt=6kitpH;{#COuHX)6^!9x6G7l*D$D z51ON`0;53q?@>&9sc#~FIG8ubL(4!Guzct@sQ?qO0UdY+-ueEt@OdI5+9{>OV M07*qoM6N<$g80IrlmGw# delta 388 zcmV-~0ek+f1H%K5Bq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zKuJVFR49>!(!EPUQ5b;n=iCpyY8I0DfeDF3ElmwUOJhW1L(tyP(Adz{pU@Oe?a?F= zIkeai6i5z5(oz{Ar8gS7T_NyoxGF_lJJW&p$8$LFs$E$W;s0ZZ015<;D?f;c@9-DY zMB!nD3@Vx(1!(=JeTzW}bW4KQ^?@OOf+*5a4FBxEBY5G6}pi-5rEG2TR zrlNk%-eVQ#+HJjUwhDY#NeQST z-b$$OMmUu?%hXbpti+4ymKN7`fH`0o&=8Rx)}mXZQ;E~eg*jub1G7COA}IN>WJ)O= ihyWJg0IrC10KNe&8%k^!YCiW&zS3)pq!>TO_ uX;}v?my4J@2yNz9$Ufd6ec{^Q^|CDzaye)G_?H0fWbkzLb6Mw<&;$TxgEQj* literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!2%@r2u_~>q?nSt-CY>|xA&jf59DzcctjQh zRbK~TMkkHg6(GT~0>^Y94c5zWJpBDtAjiqm#W6(V{Mw5fIT;iLoG-eZn>gpXp0AtZ?Fd5wajShAXpFhReKFdvBFfMk&|q3sb^GXI*+3pZtT-Rhsvbf34aN zplPZlt`Q|Ei6yC4$wjF^iowXh&`8(7OxM6L#L&pf$k58jQrp1D%D^Dt3WFAkhTQy= z%(P0}8WcNsOap3=1lbUrpH@mmtT}V`<;yxP!WTttDnm{ Hr-UW|GHzU{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png index 6d5e6e15eda36dac15385b5669acce580ba3e064..eebfe3b91f39640ebc240a2644d8a942a55dfbe2 100644 GIT binary patch delta 377 zcmV-<0fzqN1FHj&865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGv;il70XRuS zK~y-6)seAE13?gmznRNkAsiN>7C9paDFnehhE*OlkB}mrq`2zdz@QdJ@CflpvO5-W z1Hm)V(jNw9i}~jNXNB+T0C&^r^dZl4r>ckus*0+TBncvdhyb810067&db!zbwhuGR z41f^At{0J3fB~!7Z1%ibtuV8H-L^PrW;@VNfRC~)%cg1e9GDs2`yIf0PtpPqK&z_q z!{P8g%d*rt*Phd?6#(GZ>vfW*>D6E`xJlC#5!rJRUHk+vz?WsYD2n1X&+~KDZCdX= zA%uewqSin&nM~fg-EP0v>z&1e#^Gat04zfY@8j|KrLOC&D2hwxTqinEICO)k4X^-S ztEze&jYd!N`CQD*0g0+6as&X|UrB*eAP4%uHE;oBzX3!k;DGF_P5}28Ky)K5{eRXc XJuI;eMf{uR00000NkvXXu0mjfEZM9x literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>8 zUk71ECym(^Ai=T%$8;bK*2@rcZ0%tn=dGuUV~EE2rRNO2nH>e%9+s;uU(UWUph@GP zgNqJ}ptk4au!HyNlhdcppK$Elp?hjeI}-FGI=Gf?-00cUUTvQJ@YrsbwSU@LW1l6a z9sMlYd1K$M7;hyO*FYA=DTOxc{!ePnE2-+TO8 zz$o0p|%ElrP z|Eq<=kT+^K`|;neLtQU;3Y;*C{&+93x;Qm?<4yxshZe5TS0<55k6q$tP&mcI$;nx~ zzsbOp;iquV;y>awOp)8dvhMBvcLnHi)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU( zWMyP%Wn`&sU}R-r5O9S-3q?b2eoAIqC2kFhojaxhHAsSN2+mI{DNig)WhgH%*UQYy dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(69BkXt|I^d diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png index 68871ceddf27294f43f97e6c2cbab13d5faafe97..2763880e9bdf2967b314aecd09661e44b80f3a15 100644 GIT binary patch delta 366 zcmV-!0g?XN1E2$t865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGsR1W{0WC>H zK~y-6<&wcl!$1^8Pb44Yu6|zsLU%2tU~$o9vT!G4AyN?+LKhODK^mcuPSco|OfoLa zloY4^0WS>94BT_yT*gyM831DpZQC9#d$(Gx>cL=e1-t^9o-XXh7~@=8Ym`!Zpv55{ zIHdJqp63A|A|y%j2~>dj18ACm=3us?TL?f|mMj*FXW-ij=o{=L)?5??X`1dQlSv5d zoKMhNJ3Hv!&U8AxS4u5`+&Mv2RYw2-tu=X`6Ncg2cs#xZl9L@+fR%_KA_PIO91e%q zzzdMM%m98}*N5_&reVEam!r|>aW+RbJoaU5@>D2nGr^LZp9PhE1t ziT15L;D+CZzkmV!Z M07*qoM6N<$f?<7~?EnA( delta 424 zcmZ3$e2aO4WIYQ51H;x|=C6PhQRD=%g{b0wh>g z;Fu1i1;9Aw*xJKD#v@M`#}JM4OZzu^F*^#h?YDkkTEq15Da&b*mAP+JZg?q0EWMbZ zsKgSavV4Ye0gLIAlF7UG&fa)p<8Hw<^`H2o-~74%#$I}@h={8I%hG3e=gj%E$duv8 zf*;JLk$t)P4tq9>WJ*u_DILwPa;h%!5~uVWA;u-94`*LLf7-f^X+hz#puiJ9r_M}j z>NvGFB6&w$&5Oy2SDCl5dYN6Seivh~EPzu@4=65GEIi@@@i}l~H);&AX zGRddj@8x{U-MbO1M!E~+DpGB zOS}d8SGB}7q9i4;B-JXpC>2OC7#SEE=^B{n8W@Hc8d(_`S{Yet8yHy`7zA8l&_dCW io1c=IR*9rR7)^&_=ZSLTBDa*#dz_2B>?irBcEbxddW?)EuJ)Uu?^vL38xY(DD1V0ni5W&6cEH=t$)Pgg&ebxsLQ0M<1g5dZ)H literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W=!2%@ZVz%W1DW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`0$SBdfgIbxnJjv*44lmGmf->7lGWzMF+)+<3A44O7f zEG|`_?13s&OI#yLQW8s2t&)pUffR$0fuWJEftjv>VThrTm64&9k)^hQk(Gf#z!e59 z6b-rgDVb@NxHTwt?wAJDAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ048rn@Bjb+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png index ebe042e97296a7b05ee2f71031e3f9214b27c374..70a084c58cc8dc1beaf3543f6e812aac1b8c3bee 100644 GIT binary patch delta 130 zcmZ3(w1aViq%0c)1H;~Z_vQd8&H|6fVg?4j!ywFfJby*X#NQfGuAVNAAsQ2tQx34` z@bK{b64#5dP*zktcmM=WoH%jd$dMxl&YU>|rca#c5ICO1;F)lxK{5Tn|Ns9r%Ncb9 b4>B-hNwd9_;mD8xTEpP!>gTe~DWM4fx1lrb literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhRgkmPy6ft{7V@vq&OHDo_*T@)UR6N8c~vxSdwa$T$Bo=7=U_= zbPddO4GcpJjjW6et&A+S4UDV|3<9n&XrXAx%}>cptHiBAv2({Xpaw~h4Z-BuF?hQAxvX}(6P49wzX=K5#@mpqa`CQ5(vLGLN@5ADW_)Mv pxHp{t0z%d<2gY`1Jc^xhR%Z$p3p%f;`S9G?GGFR*j@ z7IinW6#kqQsGXKRhtq3Hkj0wWw&ELJXjG=_*Zi0{VWz>eR-5-GbES8`6Xwy|x$G~{ zFx3**h?11Vl2ohYqEsNoU}Ruuq-$WNYhV~+Xk=w%Xk}!nZD3?&U=VPHK?_AgZhlH; zS|x4`ik&;A0X0a1YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;uc GLK6UyPg|1! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png index 8cb90399455c87336899e6097e512ba72af5be7e..1ea1710389d0af614fec4be5b6d0d914709439ca 100644 GIT binary patch delta 127 zcmZ3*w3Ts!q%0c)1H;Myzc?VpS>O>_%)r2R7=#&*=dVba_){a?$2>8 zTnAxBCym(^Ai=T%$8;bK*2`dF-Fy}d(oDbBkTH+c}l9E`GYL#4+3Zxi} z3=EBQ4a{^63_}c!tc(n;j4ZVcjI0a{0PsvQH#H~TGbH_BG21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0sy*RQtJQ! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png index c3200aff4e60ae100e14e960fe4a4afba18239ed..1fd1527eeb09dfcf3a3f341cd66237406168b239 100644 GIT binary patch delta 331 zcmV-R0krVIGkpU-v0SZY( zK~yM_#ZfVCgfI}CwQQd)ID;Ebm>wFwlC(i0=&CgQAZ5Nlnsj`Dj@N-xAkZO&%PCE^ zvaFfenOWe!hyH-4+xMda1c2(g4y&qqiK6KFbUKwnh|41a1V9eM&^YHllu}M91t}$@ zl)pxxqA0?y>pqhtxf){-1OcRfl;E6$F?Lsg0O)ZXzp^ZA;yB*Obd#Llv)%XoTbibg zwH8`y2q6Ff-unea1a>4)mSvLX`MWU&LI`lq;l1C;>-;1@0A$;?uTd0TwAMSzJK%u> z0&sTDJt?KO&uN-=+ldI?`@;^-*4lh6%zKY%ng9UvJcBW|T;RX~3xXgb)LI+P`L=D1 du@Zr$%x^VcHJ1-av|#`M002ovPDHLkV1f)qld1p! delta 404 zcmey%bclI^WIYQ50|VD4we>)XDaqU2h2ejD|C#+j9%q3^WHAE+?{yGnbkdkz0TL`L za7+i%0zk~muz1zM`#{DiPZ!4!iOa1McKb0U3bgM3X}tU9{8H02PYuO`eufi|9J>*C z`J+Oc_=1fecr`fQJ1l&kn3$aI>a0<+ePeyZF{hJpN>-Cso|`$RTcW=IH@iDOqY_6^ zgF@b$`NuA9-QT76Wx9VXkN)(Jl^u%`wz^vV`}ptY=d0JYZ7n}N%i!Xxhez+_B+E~W z%-eZYwWRF!T(t@(hBb1*G4`@&A1k>0oR;@Z;EwO5&B`nb*PIW%^ZW5^21c&3>hP&@ zEl)}W80rHU+L)IpJ&aO+JMUk?>EBFA$827Qu5}Rs`b)LMHKHUXu_V9nO2EggJS27X+RBVIGm;on$0XIoR zK~yM_#gIK}0znvtpV?ibu33$Zg$-HiUHbig5QgC`a8YGq0Vwr( zRzfVxqE@TXZnqf@hxen=s831z?!Vzb7`u(ZQ)jE< z!VfGFmo67EB&8qa^vT)Nc-=tpqY#TB8<%yGvZ&!ZsS6u^N9vqx`e8hI<+HQ1C57wT zKl{rcc5V35eQI}oq;J^cryGnVbf*4IsJJ%Ebp9TH`ReD&mu!OdKR13``JLxsg}4# zl%yn~>+1H%wQBP%0ADoc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngBaz BqjvxR diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png index 49fe22b335f593f65c80a3334818cc9a5fd00f23..c76994a6728fa41ec14ab479e1ca5c6ddd702f51 100644 GIT binary patch delta 348 zcmV-i0i*u-0*(Wa865@y006zd-kbmc010qNS#tmY4#NNd4#NS*Z>VIGM*$~)0UJp~ zK~yM_m6E+`!!Q(u&(*bv5@J=R6yz9!*ANV*(4{y_mvr;1WXOYbEM&>6z=x-KrU+wDL^`+F0AK#Rp9jH0OMcDo~E3_6|8nYnFj2T-2pqaX-YN~xje zc}F#`App=|FnEzt4qey%ml*&U0Bts#_wjf6vZk@l3T6yeO=d3N?mQhIIyiVs;bPg>?4lj u8*A-Dzu*7U3a3Z_@p`@fJpD+QR`>>(Xf#)GZ`Oza00000z%d<2gY`1Jc^xhR#m6dZcucy6z~pyBH! zuds9HiQFgm4eAc)>`eMAe17W2&lf8HFgxY0FTbqMVIGQ2{4^0Tf9@ zK~yM_mC~_F!%!5)@qbI8b;#1i**6H?e1qVm_!1ogq3&WgArFu~LYG2T$sBM91zp6U zAP7PT9g^EixS`y8U0M-buHX2<`N83wfe^x4YXPvyf?z`PRllZ#MNr00000NkvXXu0mjfc9EFf literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhR@+9A#k=CP0;g!}elcC}&N0BhY2UWJPG6Z_ z_J8Ryk$p1nk$BDb*IRnG&Y5HT|6sil^UUsc9bUP0eO9YXcI>>(8MaF^KqJ?8jqlc= z1zQZan_LpOq@EVmHvj+qcLl0q88cYSfv!?5ag8WRNi0dVN-jzTQVd20hDN#uX1WH3 zA%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsW()}YwAV;WF{B*=!~{Irtt#G+J&^73-M g%)IR4VIGSOF)00S-w- zK~yM_m65+n!%!55zk72-QJ(Ey`T}1UReOsG|hKw ztvd^LVC(+`opZEvc6M~m_0IQyKXALE2>8 zUk71ECym(^Ai=T%$8;bK*30m(yT=a5nds@_7$R{w_w+_Tra%GK3&yXHWN_3qa&FwX zdExZ>?TZYwAZ${y2E4M)FK7R}Hhhk?}+)wpk`X$ElXMMwFx^mZVxG7o`Fz1|tJQ zBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4}a`RI%(<*UmQ0&|>4X8m9WJ7R%T1k0g mQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT& z^Tze_%-hYyw&CUjri}ZX32gcYRuo;H9rBj{12a>#*(aUNSK^TVN zr@E&nnq(4!haf0|WTB{8xpAutuftn%=|#Bl3Pc1^5Erfl1r?GQGRA>%oI`j0E;@q? zXFM$Z;Detk>gBDfHEHYU;9L2ey|DZAZzEGmjb>&dFz$KJ#tMH?P^16f@#exm}TVxKtl2I zqvrmt*}e6Rs;js8lO0KlkRr%wApn|5tz7B2boavXRcl)mr)W;p>)hHbF_>SYdHT-q z+IC#Oar)?-VvVSn1e2!iIFOvZvgWYsL(sVFSDA00000NkvXXu0mjf_Vvc% delta 433 zcmV;i0Z#tV1MdTnBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zY)M2xR5*>j(#>j9K@(bQ^D zk4Rz~35~ei#}N^+!x50a{b*mmTb2QT1wug)er2czzPJCy?s89=%#eX>%mYoJ;on@F&^h~ zEp})9zO_fUqN|O$ld<^~;-nlSM*J6c z)rZ&IzH-LWrDY2j7R?JBSCW_XZ{+Px>5AA{8wN)s(#}C b1HJ>s#-zD{^QyuC0000W diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png index 639fc3878ea5d5dca14cf5762f9042e6314cd98c..3cec3cc27249238e8865fd4cec95e7d74074b083 100644 GIT binary patch delta 391 zcmV;20eJr91I7c8BoYa5NLh0L01m?d01m?e$8V@)kwz$gQ%OWYR5*?0l3hvzF%*Tr z$UM0kAKiybZ~?AE5quH!#W#Pz4HPUEDX5e}5h;b@FLkJ;woGd~otl~4_>dHfPP+lm z(@k>oo!mo|^fxRhFcvZc+M=`pEnoz+Cb=o4t6QuC_dv#+0#INrhy@Xp_!v}sOoo*8EUQz%?xg)4JbzI{|nPm_Up!LXJiDDGf1jhLTlFd#6F%*SAkQeYld;}lEXK>+CAH$6s6XVhtb}rS(%AXj*iugCiAR&YR zBRGr-%`e5a>vPP`>S03)CbLdkh1UrR3^*%13($$ZER2U0?=)_gTZWSO1xbM*b##w*@%28VE#r#AHVp zc%VlRhY))>9ThC^a(G(f05}I+?AbD_(C=KT8<*i#n?bcnd#A$jSW!-#U0{-R^t5uo z2Ji^zopr0K%{ov;Y7A delta 84 zcmeBUoX0ppMTw=@$uool2x>S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|Lxw`GmA0` joAOGV7F;=SFiC+Sx1Bj$B)dBlsE5JR)z4*}Q$iB}lsXpa diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png index f19354d8b9debeb3b9da8fdecedb487288a22a0c..ecb8de13e29d00f00686754ea4cc7cef4cccccf6 100644 GIT binary patch delta 133 zcmcc3c#Ls^iV$akM`SSr1K(i~W;~w1B4whRMni=K5rMN4Ai}-VH`)1sudy9NKz7U;?A!g?)8X<$s72%&ua( l(f%xQ2jhzQ+oi6>-(vWy#1rtRTaEz)JYD@<);T3K0RY(zHTM7j delta 154 zcmX@cc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 zopg}1!GVV*{cxuBzuW_SYfsI}t99A2$3>vVQeaby!B3ZMD?PFfJeu2F+AOf8!7^dq zrtK$oDpZ`*{}GbV8}o>{k)dBGpze9xg}JA{R+aD4^P9C(#HU(S#TaNagQu&X%Q~lo FCIFe#i(`n!#J3lA^BxM|X}ef#9HN%U zrIx~!rIy%W^Cx(L$3s;;+xXO-7Sry$s_Iy9DCo>mU+v(CFs|p5%S;|M-CXBb-)f^@ z&v@?}yB(wc{&%cVx7jW&=iyfu-lVwGIer(T{bG4O=O!su1|aZs^>bP0l+XkKSi3jZ delta 164 zcmcb@_>^&iiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WrlRRAV4rkTAcs^Oq(c0+IIB&9&_wpA{4lSz{Vu}fnndE$`RBU}+ z?1q_wH&jxYnBNyVl>bz{@Pz+J1FLrRzc*}4j2C_QwNPMzobMf{UAx%WBONrE4H>>> Q0Nudg>FVdQ&MBb@0CBiIBme*a diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png index ce4a2357abda53c72c52e065065e6f53e012d5e0..64fa0e7c12a8affd27262c681fe56af55d660044 100644 GIT binary patch delta 120 zcmX@ZxRY^$iV$akM`SSr1K(i~W;~w1B4whRMzou!i(`mI@7ePkc@HQE9B{Dz^>D@n z+fAIh))yw}RZS}pLN1Q_J2vIUk~pBvu_~ Y-5MptmwlC$kpT!iUHx3vIVCg!0QoO3TL1t6 delta 139 zcmdnVc!qI;iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{W@JUv|;Lo9mN zo_7>%Fc4rlxbsS7w{y({m3W&EyniBm&TzfBwNhn<^eQ%y3tBUnx9;4ujOX5RF0-4< q+?#p(uCu*u|9av<`N@Qpa`q)tL<9}Y-u(hv#o+1c=d#Wzp$P!yku+cc diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png index 70e3cad6488456ac13e35246e92806d8e1d1f619..ef3d963d6c89263f9550239c6f19ce1238cbf948 100644 GIT binary patch delta 349 zcmV-j0iyo51DpepBoYa5NLh0L01m?d01m?e$8V@)kwz$gDM>^@R49?flDkdVSEFl2_(P8610Go z*f`Y`XTF(pGVtFef6&X%eo=q`a&bg(xzA}7aFVm>I2M&f00KDAH}o43w^`4v60bnM z2wDGE3v#f3P4GD2zFyD)jdiGXAZ&wM2Rljy2#|Xj^3Ys%`s{R}ya!+8;FOoY)~6OG*Qm85XK%`tV9f*iDi)3D=+_bB5rL}sRP6&k&cujDE zXc80 zJUET*6vYZ;+rZosBLPQ1mODt@A9GqRnI5e^I2n*nh~}VTAqtux5NFR84F?oUs-TXw z{P7OzgQFm>ovS7~5Fn@o><|QTWg=L-#Ux7v8zrgAn)ArlH)vrB_M>1+FZvTf?feV1 WBq$^yWb~K-0000T_4>~FWmlec?|sxuZK=2GlSAxGW-LTbuuE$r9Yy{mKWtPA5>M4==WWCO`2 z^*UQULQR&@+2_cdb7*Y`m{50{0Y{0^kYQr0CWa=PowK*~_Bh)3zRie<5E{oQ#n>E+ m&BN&#?J2V}liEMSKlB5Wv4fmLIG}I<0000ixy{zW&8!PsCN(08Dw7(_b>#QQ>%DK=8QL`9_GlN*e41LA4=607AKejLLwrK0j31<1U!Iu2ktc(0TX~o7ws*K0Ac)p^C3apJb3Dt z>w)V+&Gn}WU|Ga0hJaR}_}M_H?^Z7{^&{Xn;RxMrB&=qvMh34HwvH!dZMTvD0000< KMNUMnLSTX?HnCm+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png index f407cbbf7174d0c69426e7331dd1db7290bc18d1..8efd044b0c38f6e929c25a6fbd82f792815ad99e 100644 GIT binary patch delta 345 zcmV-f0jB+kULAmU=)U* z^Ch$-R_(>2Acm3_+9)^_9V~GX1R;}y|G?27;jV)?If{#egOjv^;NYxI{sIS~n;7i{ zZ5)!`P&DuI@g2_d9L^EOBRgwk4m~ccEF09eKnZ9-LMKRQkPy%nC_n^#6h7D{zw2_D zHl&7Kj>-XlVK*QFi0Zck3Y+fQGnPPj*>bSh05>nAJG7LdE;iqVtwkPIZx7niOJzu0h9twK#N`_;abss zd3>gGeow<&3Mw<5W{Iy)Nax}UfS%vRKYO6=Es~o&mDeh*cgW4f76A0RUD_vi+`2`k rZPQ<6q4cjnF`gdK+C1ho?h(HM!|^(95NZhF00000NkvXXu0mjf-BOoJ delta 336 zcmV-W0k8g;1CIlcBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z3`s;mR49>^kG)C*Q4oc{xw%)#^#>QSq97<%iiIGE7FIzlwy?4lAHdc(@dYf!T4HNw zV-wP7FbEn&jV!pLi8f=g%O;>ma*Ba(;G8)ls;XpCRX&oK_UR5`at`ZTP%vN(3>g@< z;4&^45U{=G&f7C`woRB^!u%o_0TGaY{6@CxqRq|mEmDaXX*XbL1tvr? z<0ZbzCp3K->NU8#87#m#$JF!;#psyk^l08eqa2UjY zPY6Pbg&=}LU5Y|M#X*N62s${cs7sw4I{6KXOCjLcsl^YFPhcrdiqcJdD^gLHiWN#) zUxo^?$=@M`6s!<$xrgKK;DHmby{%9RJfQ1=qY%dhrwcCNDX5frdE-2H#8#n#jqe6P z^GSLnAc{bL>)n$x#7AVw+@zFSCm!Vb4j(FDkw6}wfa!URn7**L%;{m8SwIIw8<-b< z!x)9R6fq-`*hz70?Xn2y+5qd{hz>&{Npy&@l_?H@$o~rLSGd2W+MvFg#{@JzboluR z>W`c}P}?Z5|MA5Y&^lCeqyK@f(&UA^L>xe!7MZ8S~Hab7?zRIm^&1hMulENuiq-^VURz)HKb z619l22^KjpLZU|HjGJAHBwPfG^M`@?XP9po7-2g51_SgpC=K5lz7+I^zONxT=h@lB z-a8|e&LX8`q&O3R6vWwgXz1>7>{TD!h8IeX|2EExiC@qoxykVlU z#YKYs-KNtBP)dyfk|;F|g#~Q&gbWUeqUfK1RtWW5 zY99seW{%NXGnsh!@d26*u3lZj;wdY|MQqzn2)Mt7c8iO*b$ZJutoc5!(l1CuQ547V z@4fF1^@(Loa3Y8xVlZeE?87Li(Q30AEg~j^CX2;jGYFPdG0Y$iMO1_#d+3v~F%;Ro z?_R^(!+&^p>iO_H=fDxRzTgmm!&?df>qjZHu4`HfwFM!-`L#kjAOVCQiZ_#*Eb$+& zsDFTPfb^z+DjM25@(VU~*Zn$)XP^c_4gc+$DwqfWd2~Sq6G8Iw6D2X2h=X$;#VUuv zafR~oG$Z-m<|twSWDnRD=sQZcR2TQzv5wQgTH>o3C-alcg{m=x4559`<&%9b?y~i+ zDFN5nAh|R{;dPrEw}*S!ATH!t115m*_qDn8B2%?3P0F)ltN`OcUxvO*0px&wAOKoG co6gI80xgqW8LPEb_W%F@07*qoM6N<$f>a8X3jhEB delta 354 zcmV-o0iFJd1EB+uBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z9!W$&R49>+(7j3nK@h<4|Hk!5#6!h2HrYckCqUQ==82={$g50-gIm?N^{*10Z!%U-OM?{6($- z{Ti30h?C+msl~$!YO}jw%aC+DN;+W66zhif+&TGt9%ZeS__K{%9WWn1!So8)SDu?$ z?iUJdZtY-#=9}ix4N|sf~W&i*H07*qoM6N<$f)eMG ArT_o{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png index 7bd1d84f96210f506b40923f10ef8c1a2a308d8f..c27064260bcdc497b9d02283fb391d34243b906d 100644 GIT binary patch delta 136 zcmcc2bb@h$iV$akM`SSr1K(i~W;~w1B4x4?qefP!r;B5VMeox~2RR!81eh;IMtFZx zC`(t~mXO`VA@^^c?-@q}RvRYID;rIdCh=WX*4(Oaa>K#&9SL`yHqBY(UQ{d76Bkzc ojG;_=4rA^s2DJmV-}irFa(yWhwdq9ACk7z!boFyt=akR{0KphGMgRZ+ delta 275 zcmX@Xc$sN}NQ}kxTlL_h{frxmkk9Q90XVnTE3dl;#{+UQPjnwv7_bxDtjLu?FEbHuBg>L zqN>Gyvf$_ve#soOA0?7|az1Q3XrB7PCZyh=;VhfD!*4$Z;|fN%sk84b$*OOVXQ`Gb zO89({8EA)UiEBhjN@7W>RdP`(kYX@0Ff`INFw-?K3^6paGBUI>veY&(vNA9TxWb@? gq9HdwB{QuOw+6+|9n&V7X>c-ly85}Sb4q9e028@cK>z>% diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png index 5018dc60a24d9feaa5276bdf6c53d3e3d97802b4..4d22f79c1686731247507ba865954266790dae11 100644 GIT binary patch delta 407 zcmV;I0cig21k?kNBoYa5NLh0L01m?d01m?e$8V@)lRW|_e*s}hL_t(Ijn&c5N*hrW z$MNsElbMOZ7&K@%icnm%w7M17E?oKyeXTx(8=pYB5d|MX3YI1*{z>8(Cv*QC7dPUf zV``Tk_`&6J&*vPt!r#>ZcFNto)BJERrIkSH_%Z@9$8B5q*qivU0OTKxur2dNPnkVOPWvBm-zjiLl%Y~yYNQ>pm=?^d1 zjFtIx`C3F=bTYV{msD*N(b(`qf~n&9(j+nS|8=Vw*E({C97$Qpukm*JJpTfDU)2VV zAB>@j^BEbstdBmD3)c(LdiHVk$?Fe7L$8%G`g4a*e_i?gT2%;t5! zTb=gRKaxL}W^`I6Hv3#rz@>l-0UvthY$`t4GaczU%B&am{{6LSo378!k#%^+_U?4S z>%(i)i`MzP*!<7cMSH1S!`+>i&n(gxn)&$;V~}U}ygZKfvl5J-R}w>^V?knlzmw#*G2z?e`iag8WR zNi0dVN-jzTQVd20hDN#uX1WH3A%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsUz$l}zY W*tuicL^E|R1_n=8KbLh*2~7aT%HZe# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png index 994743d0c35fbcbb3dfa3ae441e0e8ae19b52d5e..00d2a62557ee75825ea580d6dfdff0e7c2b62ec3 100644 GIT binary patch delta 397 zcmV;80doH01j+-DBoYa5NLh0L01m?d01m?e$8V@)lQ9A(e*srXL_t(IjpdTRN&`U< zhrg9nK8=mw`}ihyieMvXW2u6b*rc!%L`4XqA_)FT;7ra$a>mQ$a(8<(7Q4hKm%M-j z!_F={-*5KE8aZB51Q3N>p%BbiATOa*NHWrs%VP2BVgIpTIh~t*(6s_0kCvewdtJ67+%JLByR!A1)9LKZyd~1o(3!d r1u*iU*zYTUUKOCm&%fhO{U72RLk{KW$N|#T00000NkvXXu0mjf{}{7r delta 550 zcmX@b{D@_ONyvhP!xZ9? zb1jlP<2R!*(=mtJ&z)9EJ3I_%4WC^)XGV#fW5X=>2mF7RmSxLx+-(SG-Z=9h$BRFH zR(ADw%HKHc-6ttg%kJ`yL!r_0!Ykn4ejHW-*vuKWW8=OY4nx zGZ?o%pE%#jkFhS&e(9(Acm6Y0FgKt5_wA5m!%tx7tCqM%l%yn~>+1H%wQBP%0ADVO0|RG)M`SSr1MhVZW^~e+T>%m-D{xE)(jq|2 z#ZX=)$_Hdfd%8G=Xq->}vw!1LduCBaVN+gd(}F7p4kjruSlwiH7d*FeB2bxXiEBhj zN@7W>RdP`(kYX@0Ff`INFw-?K3~@FzvNAHXGP2Y*FtRc*2)M$ag`y)jKP5A*5?KeT X2F1=D(BU06on222ryrmo|}Fu z_k!#Ww(ZY+>a{aOIUE*rc!b2+q#xUP{q)_pUZTYjUh}(Blek1Ly<+_k`0v2^M!sL( o3%*M!zGv!{>$mkg_(Haa*UU!Hiqo|~lK}`kUHx3vIVCg!001d8<^TWy delta 275 zcmX@Xc!_C(NPO zi{Z`da0wtI%+tj&MC1J19#5_Y0|A!R?Jj?M!yWHGTwNP{%UMK;gR4oMyDc+K^X4+w zASSl{%cqQ-87voYzX*P7slc-8b@-pA{Cd`1J>Qu)-$WfR{^;!Zv2M-hHHplkX+pMh z*mV1VR;ZS^MwFx^mZVxG7o`Fz1|tJQBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4} fa`RI%(<*UmQ0&|>jbWm>IwymttDnm{r-UW|P!w1g diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png index d538eea05ef1f8dd4163652da56db18c4c52aa20..08b3a53ae51f2f915e3468a1e739007eba744cbc 100644 GIT binary patch delta 145 zcmaFBbdhm_iV$akM`SSr1K(i~W;~w1B4x5ZqegL@r;B5V#>BVhtoa-gL|h&g>z-oD zbx#&_$+m2%cXNC=wc?7O<;lNA&Y_7i3eHA6oiA9M6O23puDRTP;=taMbE;wPO zi{Z`da0wtI#nZ(xMC1J1iQZhT4m>Q{a;Jo=q{{C(9$b37(&EzFB(XlF^XG3h30#`c zG@;2OC7#SEE=^B{n8W@Hc8d(_` wS{Yet8yHy`7zA8l&_dCWo1c=IR*9j37p_CGbH}uaW*VFfp00i_>zopr0FU5duK)l5 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png index 27c7d02b412440b51d42af05c3322c4805a27cb5..9900f8bee2b9771716b89215a9069d9e051e16de 100644 GIT binary patch delta 129 zcmX@bbdYg^iV$akM`SSr1K(i~W;~w1B4x59qeilyr;B5VMeo^5yLlTNcvvoOe6mbn zi{okW;3H34YDyAj&1lelklEC_U%w&b;H+mx2UB8w`d6$y+4?=PO6C01rmyq#JWjUq h>@Ik3B=IWy2LpSKNL2mC6hQ_c@O1TaS?83{1OQF>Hc9{h delta 275 zcmX@ec#3I)N+%J4>=0 z7*;l!>Sq;iTANoSyZg_Fy;s^j_osfSPN^@raq_UA-E5w=S09-dZWE1Lv8U)R&}h{X z*NBpo#FA92@ylT2KH0 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png index c5e3fc3b18d9f4f955f2dd4e7755d0a9b5046b7f..12ce5c81e7e4c29ed9126294767ae19b6423f819 100644 GIT binary patch delta 357 zcmV-r0h<251fm0wBoYa5NLh0L01m?d01m?e$8V@)lMVtWe*rH^L_t(2k;RZbP6AOB zg}?h|<~fgHfK2!`!pvxb2@uq%6>HGeMq*`YtSxm5HtxWMxC%QLU@WvDAU=zk!UB-k zc&l5S^WAeU{P)No^zw6G7a)LKMN#p(lbl7KJ~bi(?MP!CfB^b=|8U&d(6_$Po5W3M zRv2TcE(c>qJ?Qly*#%eS3c+0! z`)M$|i~}=f)Q9d4Y$Y(Cg3Zhb%K^v6)b~u`hG7cT64Y8Sn}8Bvd^Wa-@a# zSC}Z!0@?vbfmqZ6vkIUXII4v4^JnFq9Ra04PO zmtpa$gZCL27@a*`978nDFP(JOi>XlLX#Mwp>2B$NR()jFy>!9IFgNIe>ld!Ki^4PH zUAoO|UDsAM+*5m@+Qp%?;>4NEhc3ETxb*MTpKUFEXZbvi^YDa9ujfw8*XkLSln#Xd zpX=cA#UQ?5{TzWUBv^nL`q>7r!Pjz%E9xPAO77$!%;rD0R z&eB;$$;a0`k*Sitkm0zGBTi^$S!+h|8@m^Co*KOr{#E*d?E=q%!bL1;=?Sr+*}He{ zsCL=U_qLvGjd`L;%XY<%h7&1Ff)@{b-Ne4H-f?Zl<|oc8d78xoB)1Drc**tVb5ZL2 zlA>Ne(ImqJmgaDSo`VaU{1iI&?2bHrYvGe-!w(<%`pX|wCU9GbMR2*PYY8ZXZdhwp zXH+#)KrZj$&4$GZuOnJd9SOfS#c-zU?Z~74|7S3*y8o}Ve$GMlTN`xk9`AbN4-8t> z64!{5l*E!$tK_0oAjM#0U}&UkV5Vze7-DE-Wn^e&WT|anWMyCwaD_n&MMG|WN@iLm oZVif^JEj3ONP=t#&QB{TPb^AhD4*yd%EiFo>FVdQ&MBb@0IOs=ij&^_Du?E!`dNd0qq1zXHt8 zhT++VhdPw1e+0g)-21`y_|?S$5CZ0B;QYkUlPO zmtpa$gZCL27&ARx978nDFP&tq?~*9cHvjz`+osgRySzJgn5yWpa@spTWY5UhDmAsm zOZ{K7U+*ohO@%iDa+H)d<=wn}v-sPax^$8HbkT_IGs@ELRX&>=sC20Q(2sEQ1q{L! zhXsBr2YD<@fA{h0&L6)_*8g36^jqKEx5wGtUH-%io;Wq>!=&aC#&`1$mg+yMtWNy% z>5s$(dqK^eR)TM2o)}HAX#Oj4$F6eQ>)f80BiHk6&j0mu@qA?9!S#Uqj#}b-hNSB@ zsheKse!N^Cy5Psuj>hLs7aNlpZP;(^N+{x4)|R<;ZS=jD@^jWo#NKr|)taztTEhYH zjJ(Eo8ayRY#k;ncPUSkUwRGNU$?OHP8rA`N4lA7!L-=ei@=t7Acy`{s$^$`OE6+2f zvU{0Tm{~-gSgtsiDY!AyDSS$ru?h2)@D%$s6TH}NL@jvIT>rdzb#oA_i}Z^vYXTK` zQtX5^4g?%@ac)f9Q~x2OMQ!ym{iHUj)q;DN&hK45fBuuDvcL#XEpd$~Nl7e8wMs5Z z1yT$~28Kqu24=bjh9QPVRz`+aMwZ$JMpgy}0aqBbP&DM`r(~v8A~cAg>rm|6F>Rum QIu`?jr>mdKI;Vst04inVRsaA1 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png index d1b1f6b6459ac7d90d94dc2499f20cf3dc13909b..7e332b401e639e9ae497367421476df018d91456 100644 GIT binary patch delta 360 zcmV-u0hj*c1Em9yBoYa5NLh0L01m?d01m?e$8V@)ld=IPe*rQ{L_t(2k&TeeN&-|B{&& zM^hom7Y+wLzV|ujeFgIpXG*0m^M!lI3LkUofdotgB9g$8U>RTlQi23?)_mc*+4FSv z!8VOUDmf5pD+d&^74A7kNAiGw1nr=}(t8wAJzf(bzXK-4Rh zk{gQFEERF^%8-olr$m6xG?fX6TsV4V3E{BgE;cWa0f@$+_p+BzN2<}MFb>?LNN`T)PjXJl@My;C8tgN>CyL|Ov zGqW@Rz#l^Yy7}?yB~&su^!F({{{rSK1s~|0yw`7*E%65PO zi{Z`da0wvexu=U`h{pN37dLt_2MV-4e4n@Jky6Bx%_6IBbWHNo$vxt9klmmuqI2&z z#;q?5Zofz)8wmQw$UJKrpWaqX0`e@hc5>X@SORX-o|No?8WwP{5y81XU}v} z@SWjtqHD?CT@wT}_-2-WuUNC$!dvLm1#@Li=C}3@e(i6y&Z=prrg`nucXM)jA^BKA zg?)?tigzEbrj<6n)I8kPoY_CIA*%P9w0E)cnZ;9?{rYC=7k~Cy{FUE)V+8tLJdAn(2Aouk`x$imIo(?8FjY^uD~f@Vid%u06kQv;F;b=Z?hhmV8zr(|~O+ zT!Vq0RxNRjC`m~yNwrEYN(E93Mh1pPx&~&t28JPqMpj0KRz{ZE21Zr}1_4(Xv`{qU h=BH$)RibDRMA4zxxntTyGj%Qo22WQ%mvv4FO#p^>q~ zyea?^GzdTnf6$B~q}N-XB{3FUHIg&=Ts)rea^Hdh8juB#ED(-_QoB>J>+?)z1qjIBr~e=_0gGuuQckajqesB_{{+@M z+*dJsJ!`XU8h{M=3TmKafoXBm?Nqj_<%5pvJ^(#`MuNLCG+N}_?c!GDdEbRcpb7N- z30_;A+HY6cdd&bzKpXFCv_Aomt=Eo$C!ovFBYgqw)nez-uhruK0000PO zi{Z`da0wvev!{z=h{pN36a2lI5(V1le_uMgok>~6s)M7O{pPh@Ef<#hD|U9&`)U4C zRNB=Qzu0@eVv|h;$8L?3rUji!)!bJ~t?GBMmj_;|GcedM`Ajlxip_m)CJXNw`iXiU zHaE2xs5ZH73uNCj1Ue3q)JI*?+-~O;=e~Cnc3(KD!X@AM_shRH>D}FXC^wpM13|m`}8=0~8I|EOy)HO@@sYZo|KWr)c*LW(; zpyn{c{-2xN>a!-kT?q^T)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU(WMyP%Wn`&s sU}R-r5O9S-3q?b2eoAIqC4($Z9g3YhrcE?c=VD;+boFyt=akR{0Ew@oP5=M^ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png index 313e2db043272ac86789785d3cfd80ee2a7b1a25..8ef8a7a23dedc5b1edcbd0a0af5a940082ba5eb4 100644 GIT binary patch delta 352 zcmV-m0iXW)1DykqBoYa5NLh0L01m?d01m?e$8V@)lgI%le*r2!cPMr)N)4QBw%#n|F&F&>H`2;%Ct77WyirVz_NQ# zqXOj;NA+qkeRXlBojf*j+au0+{LPyrHVDxH@S0G%CHwMpzgch(C7f##YWcQzx;`|# zYI)CNm@z22TzbvQTERVdl`;!l`$mzicsyC3U%XLELK$_Jo~tFJ(On<~Sp0beV=s}I yDbFtCR&09*m;y{6`b`SJ0Ahd!w15w~ukr;9vtdv%-X7Ti0000RR9VIi(kBHyu5CkS9riDKkSLaLR>S$Lkfdw2~&X^S!I6yHh=9>F4A?1+!L(8#Np{ zmzH`KSa_B1G>}}XQU2vMLl0{ZU(fLcKfagEUVhMJ!ohOpVJbP>o|J5y@YBcw*Y|Qne zllJ{vT3^XBkDc55!wbP_UNP_9Zwy@j*n;ncwWm_9`I4=rdvo(%uDKc{;%Z;YrpjAw z`|?4++_LCGnf~xoZqJ_xU-s&av+?$P2@DF=64!{5l*E!$tK_0oAjM#0U}&UkV5Vze z7-DE-Wn^e&WT|anWMyCwaD_n&p+Oy}BR4-KGp!Q04#mzL(
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css index 443b58d74..c56eaeb54 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px; } +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px; } +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px; } +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px; } .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm index 66ef6876c..fbc2a25b9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm index acf919dca..b60708aa9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm index ec98b3b43..3be7fc603 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm index 3d9703654..5e5925b16 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm @@ -2,25 +2,26 @@ %css-style% + - + - + - + - + - +
- + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm index 4cbc1a875..aad55004a 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png index d9c28aaa7b247bae8cee3a07eb28369417012ddf..fa45de4abe17dfbd593342446d1065423b4479fa 100644 GIT binary patch delta 142 zcmV;90CE510nY)DBoYa5NLh0L01m?d01m?e$8V@)kwz$STuDShR5*?0)4>ryP!NOR zKP)cK(Wpdy&Z^K5rD(vgPZPOG0pCn!H(HOYVoX#k2a#Tncv4>QPH*RU)p)@&n8B&^ wW^in+pyutgUPZv}1{c8g-vTnGsRThiIEY))g8x_|)XwXr!6a8Q`d0XKffA={&!OTIu>?xg(nzrs* zTAX#2^?BgBJ$)~myo-g8mEC*wl%;@CO6maL9yN;uwKsQb?aGhVH^`p~;NzOYmk6|$ Ofx*+&&t;ucLK6T((mikh diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png index 8a3e85ec3cf4ec962b741ef200cdd2e943363064..68de5c2964e82362df65d4966de59df42fa3a3a1 100644 GIT binary patch delta 419 zcmV;U0bKr*1mOdaBoYa5NLh0L01m?d01m?e$8V@)kwz$gZb?KzR5*>*(7|gHQ4q)R z@66k`yV>n-!IA{4qQQWIBE8syJ$Up|=zry(<-v=d?4^P?dr+&;79ve+Hv8Uq*yPlt z>d_wzGcfRB7~y&n;Mw5yyZ0}jkA0pv5{1k`rd@e8oPq$l0st_(`gu8<1rRVZf`QTX zU=R^(4PZcj6VASzoKB{gfgzYd8-y%!icdIV2Px_<^mc6_kjUW{SB~;0v@OqRRI29faNu^V*a1=8j(oJhqK@`UE|2gw^=ib~D+ggpZVu@t0*jB;48x^VF#FehyyA}KxS`c@| zonR3JSJ{XfsTw0znxwSNxM-A;ai+YMt4pogR1q)& zUK3u0V8BX31q4uzCINf<-#@+I8SYYlctdoGvx+r>NCJU`Km`CW-0N+&xB5e(gXkc$ zf-_)5I9QORdV>Cb@5AfOuLHb7bcSFRZw=NOj1g1>6+H^1gG(81KYRGJ*LnNpWxGq^ zgxo2)Gh|K(PVwVfRTXwegRRbwCl4OIYJVPm{MM%oLiA7sL+%aHE4i-*MnHFe=gs=s zU}J6l@rw@cy4#dNsRgCX4E1QKWd@mi#$OQ;1!holrMz+HZoYDRWvO*iSC`LF1T(Hn zH84gja2iS7fv=(fmIql{a z>wg3$>J&f&SOn&QIbil!z{E5t`Jo+;4NO4t`}nWGWUBtb{{wykY;bU8Q|4Rw00000 LNkvXXu0mjfhTzzz diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png index f18a209e2aceca343be94459c34d56301601f01b..db142436459a07044864026b63ed4c8f471e7ca4 100644 GIT binary patch delta 432 zcmV;h0Z;y(1nvWnBoYa5NLh0L01m?d01m?e$8V@)kwz$gdr3q=R5*?0lEG>dQ51&1 zlP0*(tv-iK@!13^_zt=gK@p1JvVx1+N(!xQ6&KY|H9~7_QpcppOeT{%_xvt0O2lbj zz<+fv-1GhC{2aTxmq zSt#*hl2zY-{!z0OxPvf)pcJSA2qPKg_>bcrFsI`F4Ty##f*`t>yAfqbLLTXzO$gnC z10b&j6uxjQ1*IDEg^gTHdqu>8nRifs+e=Gq`@W1t!1<(b+vpXn!~(d%NBl zKU=*IyaPsc%>d0-)9DXqeC(y{e;F|z^k(VC!<~G4Z4KDE%pJgP+-pbAeirexdtP+5 zyVJerZRW+B%K7A?^#1^W2UWrY;4ARCYCONpc^PmM2*9)gO{#b8<<$Y2{64&emh1mP azX0|kb delta 480 zcmV<60U!SE1D*tsBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zn@L1LR5*>Tk=;%cQ51#0ea@i9$StqoGx!d^4_@dS@C?L+aAOQ!7zqAFg*4TeU;`Gg z2rbi&r5&cznVy;L#TgBh24ip~JJ}a!t#7X!S*-n31xf{{LRLUtDtRds3WFr$^@p$H z?xP0}fj2;`s!F8*KoJl{Py%aEBUlxG6d{Zz6unjiq<~{efqE|>SOGC$5fo5hI2z-^ zgElY#+(kM-V8r;%;N9ZQB7!SQI#G)2G@C#I6jv^o3k>qdD;TjTiV;|E^oUyD2I>2i zS3q1HbvfYfEq{SAf-wSs6=Cl*p}rTE@#>T3IvMX&6|M%{yJImTh~NikoWwkT`*_Ug z-P14me(fdD1k&mL0Kxoii+C_eRrOx`Z8=Y{^9LRnH#zPN5C)F W&)urfDj5&}0000S|Iv5xjI14-?iy0VruY)k7lg8|diDm{GITpX)*)xkW k3Y+pun-*L-a4<=MA%KI~@5kp)9zabDp00i_>zopr0KDWFZU6uP diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png index 346d6e3d65762794cfe71cc1e44b422e753833ed..60ab43b8983ea6b88929d821253f174d3cfceb79 100644 GIT binary patch delta 143 zcmV;A0C4~40nh=EBoYa5NLh0L01m?d01m?e$8V@)kwz$TT}ebiR49?{%rOo?P!NRS zf7T0e0<{w;oxtJT&AXCOJdKbDg~}u|*=+HNa}qFgb6%#gCx8^D3DH)j4w1qHAVFLJ xkMaYb0uqSQH-Noj!1&_=0hQiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WLQaxQ9Lo_D7 zowSj&!9jo}{k{AjAs^l~2ibDYJ?eRT%=E*=eiwnBn20{>8;Q-6bE7=H4&2axZRXF+ z_{2b!HTKOEktYU>3g>>h*+0l`ST%87be+`JvwRZHpRKm@<}_!$V7eNsaF}stx0KuU TDcMCpXE1oW`njxgN@xNAb{#*O diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png index e876448fc04de5e260f29a18c47b803dfb1211c1..77934e9d98c4619d8a4c58a35c92e1e8ba31c6a6 100644 GIT binary patch delta 156 zcmV;N0Av660o?(RBoYa5NLh0L01m?d01m?e$8V@)kwz$gYDq*vR49?{k-G_iKoCUV z+LB;vh8AW8f`J_v8yJhf9Rod()4PE0000< KMNUMnLSTX&=sVB= delta 183 zcmV;o07(Dc0rvrrBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zbV)=(R49?{k|7R*P!L4l{%|8s($iG-U>GcdGgQ|!!O;X}5KCyq7vTHUX0rRtPCUl9 zF$h=`%&YjQFt1`!AfOwbyzcD{=z+<$*(sbyweX6d%3ts+h#-KtC}@t!#^kT^&F54l l_FZGL9(ib-`L{DwHV+Ig2#D8^M*si{002ovPDHLkV1kc^O$z`3 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png index f21120bbd914a125538c0b785f736a9ec8f805b8..bac53adab7dcd74fd2bb22096603baed5a9eb789 100644 GIT binary patch delta 131 zcmV-}0DS-00mK22BoYa5NLh0L01m?d01m?e$8V@)kwz$HQAtEWR5*=eU>NLxk%57M zg{lUMcb@%EO#@k6%@wI>9s}d9CqJm`!ta0oQPVsImS2CV>OcmTKmVv~Ak|&?>mQZF l@bQ;F)HRTik*ek~006@27-;*V3-0bP0l+XkK DVg))t diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png index 5212f419dfa4ce8c1bc022832176b74aa12032ee..e9261c34c1fd113d578cec4c373d00629efd3a5d 100644 GIT binary patch delta 373 zcmV-*0gC?21GEE>BoYa5NLh0L01m?d01m?e$8V@)kwz$gK}keGR49?flD$p>Q4oc{ znR|EHWtZij4GVOJHIYO*TU!e)EVNK!Wn%12wDbuqY%F{QD__dO9%6uN0fhx1v2mK2 zV&=;^CjAk=?T8Yv!1WTPEn%1Hx?3vhDn#->Xw81#~0Bcs9oXMi%ia ztON+)2S+!TQIe#cR!l)*<{XnL7ZyZJi#i1*X6+epc!X)qwI1rJAZx&qvWuf33743YW(XB6FM z#qEkyIatU6NtN8bcJ+GxQgQwLwC+LObQ9P-Jhf&~yAOsd4-vz$LfKe7kIE^vu rl_}LQ5-)0nz5~Dl6T78t{_5Zd+cGkR2svLJ00000NkvXXu0mjf_t&hu diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png index f1c15529ac3dd93853e7e205110c781abb76a8d1..25ed23587760b59978b9f58f5a302b768b4c815d 100644 GIT binary patch delta 430 zcmV;f0a5;h1ndKlBoYa5NLh0L01m?d01m?e$8V@)kwz$gc}YY;R49?f&`(QLVHC&l z?|JSx+{u}An4H0MS1?;Q?t1}lf>uEUt-_7;0>Z5eUxFY(fkc~H*`~IIo1m3KC8U(z z95H6*KKIXaj++88M{3m%&g#JD{5bHx69E-K&dfhWIxAa4)AGP_|IvK^mA>70-h2P7 z59nV3cU~udHt;z|Cqusd7?AmN-+JGdlhxZ#fgG?)fz7X}r2!7TvU6PU?(;F9_Irer zgZ1Raqb0Vt`098gj*cHJj)X0O81tkr}wb(I#QIEMf+hS~{`?z*vzC9Ai)yUQG zYIs$AX_yHPW42T0O5xNzN#0T+$Y7^R@6F|n{96ehM7wnPhhD@$W%NT}@n z1B8P33k=#&Y(jtrqcIyGuL9lC6U)I-LZ0+D^R4$!zrB6_ z0kD6gk+sjM4hm&ZDBC^DyUrfny?#;b@4h~Iv+&Z#y+6{(%BNJ(9}76hJu6#1Hg@)j zcRNdm%THba@mVB6UV1X;Nu4KgN@(Ez&2eUKUtwhG?qXwp@c}R*B66yMRmJ*$Dk~!x zuM3mSQLeX}wQ%;)l4(x0IpgF(ITTx0W#*LBDWMVW+-T8gP26hCJ$npH$O$~%W;VZoH8U4G6$+42vOrACYqQA#(?f`1R~XN wM!<*=NL5$8l(9>7OtXDW>K7szp!Tc5cVW577|V9!b^rhX07*qoM6N<$g6uNP5&!@I diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png index 3a6ccf16ab5092e49d7590a424ae7f93f668e693..c162ec17ac366fdb7e03d2af862bf9bcd80d7b2d 100644 GIT binary patch delta 371 zcmV-(0gV341F{2+kUdL6VHk$5 z=e+0W@nC)uRO-PnEOAPSz$hZ9rur2vEiLs!g2tBS3R(&qg4TAYhW4o8RD>NBeH)H_ zM|lqq4>#P`a0y={vGQs%w7zwu5+h5?v*QS0iN;b8Q4m&wB^pCOG?<^q(UqNHyS8>> zI72nJk_pOx{t-X~KnK4L`Zs{YH}>*&zIvt{r&OrrNo3-1<9*P@K8fe78fUo#BF{=YtZn%?8gAaOyzb_A=j;De;@x51&H?UFHE;Q|8UpIgq<)> zG6I0@`3PVLm?BsPD3L&5--!a~++Meujni{`a$)LL(PN_9?h+e~4GsW$`2KUVQLjge zbLnQwuJ}(rV?*}9fB@2N`^~H4%h33AysgqRg>3R)fbq>q4|wtRHxCAt_zJ7bPk#Ub Rr6~Xa002ovPDHLkV1ne5tO5W4 delta 397 zcmV;80doGb1Iz=EBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zNl8ROR49>+kg-Z!VGxDCGylKddv{m#?yjy0F0R34QBX`Hf~8nkN}eE5NEy;t`2+z8 zfnXJ^Ed;@8eGT8hQba2)B(P(#SKUI<1H&)_=P>ih-FcKGRX4tmmRG+VTeZHizS1U` z2y#*rNr2QK1}8|!Ar71KoxhEd_VTHJm9o`tyN)Dq1|0xL5@N7-6#V2P3mJA&$l^}Vfer-ptw8&Oz!m-tdjS#ES>(`ouZPJcu8IqLvNcTS$TXP3)9`1 z+N^lFuu{aTv#6 z&wMA}!^|X0w1`&9MWocq$@~Gk@Gm%#gOlbmD@R8+DaW}yTz`@NV#+dJpBq#C~o%R z^kIyTE0T{`7f?`FnRIn<_ z&S8?u-R1tn`t;CiBAQlJiw_JHKtT|HM6d&PMgb98gFYO-Kv&(!?1r;@xJ5)9B6i#O zG$Dc@7=S(d7Bx535^8J2^msem1LNE7{;?2Xiims*RMD@spEP(~bcO;r>+6HA-qB6Z zV7Lb`jX(Oo;&z&}2K|WX^w+fa%>W+9e+21Ff%y3?!kv}MeaTv!x z&%N)P`-6ew62s|AHe^#`5;Kd9*PD-Q$;d<;87vehW#H-thpuy-7e(iFSHH(_ z=t^GS_4)Ma>HC$XGgm=C6u;Oif~cbY9JWyf6+{$2)~*^MAc`9CH+~pEK?KCdX&VFy zd?SBb?WT}_g{V^V`52=S$H!9#wuS>(*8ix)lIJ=$5My$v^Vf0nIM4n?5dh1HC8lmQ z*4`X;h_{D-pyO+ot&=?7`Sy*wGQDegnWJ>DZ#V}W(>D|l5 z!U}5kEQ~3=m$Eydp5c+pe5I?iCCF+jNBJ&Od|97cPipo35V*1cgIn;7`>;p%;KW(3 z9Q8`~kI!p!%jWIr0LTI5`rn<%=uCgxVk+&#`(}Y&AjH=S^}Pt-01?0fUV#eKR`>+@ W9en=YMo)AA0000!k}*hIVHAbG`~KHF6Jsbv6R{}N3Qiq@Q(YXyN$BEII_uD-TNgoa?O15R zLEF(uu!vORq9BT5P^8qjScwK&jZrX0q4G`#g9vTXyPof!d(Y+Cc=k+~kf>We03n$D z2NVJW!w|J?ee(Tqf~HZ?d5s;TSjm*&p&GvVGzgh z@67Y;pWApYM3O^HFh^1dfna43UqBkcH{si~u!_}LiC6{{1wmqv+q=DeW>VZj(z|L@Q544U|5|(Pz0aAGjARmHf(8i*^8g|mpTI^$8!I2fLSMpG@D1z( zRzk3`vat=K;stdw;DyPFX67u5i4w+)#>Nj;v6~<3vc=sw91#h?+NsBZ>K=Iz(JpYA{D?KIEpnxvVenL;uJnM|S}PX!ua=i63)y;*M# zwjR8D#r9yAESXXgg(ONcEiy8B#-9-p1?CA{n!Po5yLG*~xN&kxZ!CAI%#ed+O$81R z1D1db>3qIAduQ%iXT3UcuD!@g+2(9H^H)Fs13ExgvTPJrs>{}mE4CIpaW%I82uzGq z0n5NDa0XZe7LEl>bkjOi<*|Vx2}piD{}q_bw14pbfFIDLd=<9Kwj=-m002ovPDHLk FV1hBs%Lo7f diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png index 65a70a294c68ab74dc4a0c2c312cf1731749aab1..655a2db643b7df080a7e28e1975d369655293f7d 100644 GIT binary patch delta 425 zcmV;a0apH(1m^>gBoYa5NLh0L01m?d01m?e$8V@)kwz$gbV)=(R5*?0lEG>eK@>$# z^~@@gtt&smrT77UmtT-=+=vK@kd3&CAZ`K?B`Bg0%tA)OV3-LRdZwp)x~Hq|bun$6 zMJGSt-Bi7z-np+X754PVSXf3%IJU&NMoBm&su+1X%G>F~@dMx+5ZO`|EbI(fSVA_o zzyi!7B~++?1VoRrBqOz;gr&{u47|B;UMDn8zkxN^r~fo`*JueTVi^>%O|tk=Hng9c zFTko7px9!&o4{BJ902is*^p1#vU*V*0!7~wh9PxO4H(!!hJ%@`6Cd-M@@4TZEz%jV z?44jI?0`kc0=5aj`Ksd0bWZWMJguG=uYmE58SD;!?f?)BjarUom%P84P#%_Ni^o^{ zz*iveYX%rb4Y_D4PKy~Q`6c;9T`!+4KCKRx2f)#7?f~KL@x7#3YSJjqn-BGVC;VJM7_}MkiZ*$%T+y`2q>Oe(T_x`*-z_4@q>$JW9AM^+69Sbid Tk}NI^00000NkvXXu0mjfs8Pff delta 473 zcmV;~0Ve+E1D6DlBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zlu1NER5*>TkwIz{K@^6+SJRM?1Gw=Jp23wD@JPBA#1puXs9O<16vc%>i6~;!;24t_ zC(L9rnVIgXnXc;kU33evGekrm6x8DV-}hdX-Ov?Df|N+9BE^7WMHM5Y#ITIq{(Lka zTt2u8ya1+kpsoxFlMsfJ;piYBGeb^)3`3yWi$lNzkyd3UkPJ%+lVNh0890zcznla3Se<8p0y3=H1}U7{mJ?p;4gZYmiwpl{{Z|1Upe%z9%Qry P00000NkvXXu0mjfa^cWJ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png index d498c3b85f7247b6ad649037fa1efb814859c843..61cf46ac0dff4acfbe3ce37b9e205812c1a3b8df 100644 GIT binary patch delta 68 zcmbQo*vB|QMToP&BeIx*f$uN~Gak=hkuuTEQ2qDwZ}S_w8aijS^-5V}JxDMVU|@A; VdaCkPwTb}S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|KI_QR!`%S%8&s3ho%d(31`R`4?;~0Rz)78&qol`;+0DGb~8~^|S delta 154 zcmX@hc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 z?J?wQFyLW6ulbij*xTLic>K)DK1r{I(oQ@&5k-q!zMVANtD>4P@7gBaR2M~&&cqWM z&vz*=6i{fI{);i5q2veSf_`b{Wxdi4yua3*x_-CLy6>;>y~iJ>?*-b-;OXk;vd$@? F2>>KFI9vb# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png index 1d79a09045df21acb1298b87afe0e0560536c937..38c07275fe6e45d4fddde8eefdc9d7787d3aaf59 100644 GIT binary patch delta 160 zcmV;R0AK&@0pJ0UBoYa5NLh0L01m?d01m?e$8V@)kwz$gZAnByR49?{(jgARKnz6D z@AOEOdW0M=Ck&H^%?4wEm6S}BZ%P(WVu^J>IiC9q z*no>B6XOx!`|uZ_n?KM2qUmwKwG5a5g805zAE=9uYI%bCR+vBo%m>oeED|&+%KiWV O002ovPDHK)LSTaR4MA!E delta 172 zcmV;d08{_q0qp^hBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zYDq*vR49?{k}(d0Knw)uP=1t0Q1ddX{3m~*qCuiQ@T9opl;R2yEmL@HOS^L6G};Sd zh_SP68FMZgJBGZbh50!Rz#CXq`ORM0SG)@{an^LB{Ts5+oLpr delta 154 zcmX@ac$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo9le z|NQ@N&uq#l9O|2#kdTl9#0yt73Z;CsHwM*6{-suYMQ3+Vz3`a5{+hsr#dL zDes??UwU`3{ad!J(Oz<8&I99RtFM>}Op08=&d|mnGVOrWw&_5d89ZJ6T-G@yGywql Ciao9X diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png index 0a1c804de7d869b6974d6c0d778047a421d85d67..7e43bfc0d10d6a3b427907ed327087b2c1932059 100644 GIT binary patch delta 362 zcmV-w0hRvG1E~X$BoYa5NLh0L01m?d01m?e$8V@)kwz$gHc3Q5R49?fkUdI6VGu>n zo$t&0NnV~Yi3xe&4~U6k1koZOZoooIEi_mOZo$$W2sRdO!P4zm+6jUnK|^AZASsNB zjZ;l=@8QhAe~XqlC zrzZC8xfhLh&Xho{rpN1h=|=swl-S*W>^HPc(AL#z1=VUJ<%{pH99FaH@Yb-&kER2z z=N;y0o4ylPDyVh)ZhkbpnvV`D9rsuvKPkHIJ#R z_|5_p@pOP{zTd3nd(E5OwO+nfGHu%AgdcqMgitWhe*gf7FUQX&XbCfw38SVm{st_IQeqT$FEYB6&M;%$7L5hERxpSbEqn{<#;qWN%Qh}sMejp|h!n!58$k%7Rn#U3NnHssqd9m{ z<~MilzxkaOwh(KiRz7f6=kVd-z-=c0LO`y}e?`W>OeR+H(^CJga$MiH?8Lw7EVMU(9IzXKPsv-$t;e}5+*erArh%WV|xMY*b}`WUBJA_O#X<3Zz$nRJvs1@RWe? zs4+@(Cu~-i8jHhPXdyjvO~}-d;Yf%%vlb#kAj))olwcy92O56^!nW+;QM?rx1H6?C zEW124n5+g!q*K5c5dYD@L=o|*D58prAfg}&2zSE(scA%=F+i^azW|vtomt`-F~k4> O002n`MNUMnLSTXgFv8ma delta 453 zcmV;$0XqKT1A_#RBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zfJsC_R49?9(miWbK@`UE|1CdHEYQlwE3KY$I-NChuJ7F09sL`|X{_Yb723hFwWcY}u{fw=( zdga^IueX6>KZ)}y@XGPzc(zHDa$)v7m*!KFlgaYTa_1tDNYdT`u3!>UX&f?t?dDlZ zQ_gf+ar^T0N^~?{WS^D0kt^|&Rzazz7Ni8iIW%godCUFtIQd5p|{x#qSu%5JzdmkJ_00000NkvXXu0mjf#qigV diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png index 09424c08eb81a05e344d47e090dbecc5160655a2..b3f423af08638310b472bbe32814bafdda7f4cc6 100644 GIT binary patch delta 357 zcmV-r0h<261Ed3xBoYa5NLh0L01m?d01m?e$8V@)kwz$gF-b&0R49>+kiAL+Q4odC z%-sD;HoIok7?2Gq6bx1>S{OtS#6o-!5v+U=!56Sr!A4n&fX`u<+JJ&AF(%nui`|5% z1ot#E%*^>14&kTBJMzlrxqB;BIXDaF02T-{SQ%ikvML~A5G7F4X7|Efv`pQI-QH4^kh@9)Q4ogzf99Nx8Jg;;1M2qL5w5fKCndn>Jcl7Nk!+6z`z ziSJy|vV>`m$Mn&HG^7i2I0vCoam4^YsZm~)K1FZv)BoYa5NLh0L01m?d01m?e$8V@)kwz$gI!Q!9R49>^lCduXVHk&> z?|PM9tGEUoBoZ?li!fL^*_iwV5)&~COEs}bBo==J8^R=EDhURWh%{kBwRO4luI|3? zGaOA5iJWKn4ey)Zv%Ig^Rt2qf0<9HFN>msiWeXLCC?!EjcAp!lS9$L3IrHv;TLl!~ z7#ab{XeJbY2oMMa8iQy%V`nh)=CrlkcW5o;h5(~206;_`0D%VdcQsK`@Xnu0~-Xweso@$FPCBQJ_6g5!(@F+Vz!KHsuUt6uM^j6E+y0ThOxb9>urwO2J|lHdM$ew9TdT>)zXAXwyi9)RUZ#oSgTO9i358P*v1(@m!}>F6wzSRM~qh(#W}I zZyUw=dZzZQsva#2L1-g_3bb$1+$LgwVax$@JeEuxh8LnkB4Ub&02s|jkmhLjCJMk< zG{|fsLRZ{38d;i__Nl<|cyG*uJqjp}svsd#;t?DIB@ZOOi zo&VsW;!r&!k345)6v8zB&N{R1Il=AWG|C3`V=v0;Qu6 zg3Jxg1Hl7-yg*gMBIGX^nB0iyHV_oU2Q?dAb;3Y7g_O)D(kvvi|Ax8hC42W30CY2B z&R3jzB5HP%4o82W)7lNWYMI7vz4Ekpx34!&-twUtd$^=(nGw66cvqNm{h6(+3!3N6 z>zB31O*{?&OeT9`iKC%2x9G}xZBE>xD+Alkt=6kitpH;{#COuHX)6^!9x6G7l*D$D z51ON`0;53q?@>&9sc#~FIG8ubL(4!Guzct@sQ?qO0UdY+-ueEt@OdI5+9{>OV M07*qoM6N<$g80IrlmGw# delta 388 zcmV-~0ek+f1H%K5Bq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zKuJVFR49>!(!EPUQ5b;n=iCpyY8I0DfeDF3ElmwUOJhW1L(tyP(Adz{pU@Oe?a?F= zIkeai6i5z5(oz{Ar8gS7T_NyoxGF_lJJW&p$8$LFs$E$W;s0ZZ015<;D?f;c@9-DY zMB!nD3@Vx(1!(=JeTzW}bW4KQ^?@OOf+*5a4FBxEBY5G6}pi-5rEG2TR zrlNk%-eVQ#+HJjUwhDY#NeQST z-b$$OMmUu?%hXbpti+4ymKN7`fH`0o&=8Rx)}mXZQ;E~eg*jub1G7COA}IN>WJ)O= ihyWJg0IrC10KNe&8%k^!YCiW&zS3)pq!>TO_ uX;}v?my4J@2yNz9$Ufd6ec{^Q^|CDzaye)G_?H0fWbkzLb6Mw<&;$TxgEQj* literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!2%@r2u_~>q?nSt-CY>|xA&jf59DzcctjQh zRbK~TMkkHg6(GT~0>^Y94c5zWJpBDtAjiqm#W6(V{Mw5fIT;iLoG-eZn>gpXp0AtZ?Fd5wajShAXpFhReKFdvBFfMk&|q3sb^GXI*+3pZtT-Rhsvbf34aN zplPZlt`Q|Ei6yC4$wjF^iowXh&`8(7OxM6L#L&pf$k58jQrp1D%D^Dt3WFAkhTQy= z%(P0}8WcNsOap3=1lbUrpH@mmtT}V`<;yxP!WTttDnm{ Hr-UW|GHzU{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png index 6d5e6e15eda36dac15385b5669acce580ba3e064..eebfe3b91f39640ebc240a2644d8a942a55dfbe2 100644 GIT binary patch delta 377 zcmV-<0fzqN1FHj&865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGv;il70XRuS zK~y-6)seAE13?gmznRNkAsiN>7C9paDFnehhE*OlkB}mrq`2zdz@QdJ@CflpvO5-W z1Hm)V(jNw9i}~jNXNB+T0C&^r^dZl4r>ckus*0+TBncvdhyb810067&db!zbwhuGR z41f^At{0J3fB~!7Z1%ibtuV8H-L^PrW;@VNfRC~)%cg1e9GDs2`yIf0PtpPqK&z_q z!{P8g%d*rt*Phd?6#(GZ>vfW*>D6E`xJlC#5!rJRUHk+vz?WsYD2n1X&+~KDZCdX= zA%uewqSin&nM~fg-EP0v>z&1e#^Gat04zfY@8j|KrLOC&D2hwxTqinEICO)k4X^-S ztEze&jYd!N`CQD*0g0+6as&X|UrB*eAP4%uHE;oBzX3!k;DGF_P5}28Ky)K5{eRXc XJuI;eMf{uR00000NkvXXu0mjfEZM9x literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>8 zUk71ECym(^Ai=T%$8;bK*2@rcZ0%tn=dGuUV~EE2rRNO2nH>e%9+s;uU(UWUph@GP zgNqJ}ptk4au!HyNlhdcppK$Elp?hjeI}-FGI=Gf?-00cUUTvQJ@YrsbwSU@LW1l6a z9sMlYd1K$M7;hyO*FYA=DTOxc{!ePnE2-+TO8 zz$o0p|%ElrP z|Eq<=kT+^K`|;neLtQU;3Y;*C{&+93x;Qm?<4yxshZe5TS0<55k6q$tP&mcI$;nx~ zzsbOp;iquV;y>awOp)8dvhMBvcLnHi)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU( zWMyP%Wn`&sU}R-r5O9S-3q?b2eoAIqC2kFhojaxhHAsSN2+mI{DNig)WhgH%*UQYy dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(69BkXt|I^d diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png index 68871ceddf27294f43f97e6c2cbab13d5faafe97..2763880e9bdf2967b314aecd09661e44b80f3a15 100644 GIT binary patch delta 366 zcmV-!0g?XN1E2$t865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGsR1W{0WC>H zK~y-6<&wcl!$1^8Pb44Yu6|zsLU%2tU~$o9vT!G4AyN?+LKhODK^mcuPSco|OfoLa zloY4^0WS>94BT_yT*gyM831DpZQC9#d$(Gx>cL=e1-t^9o-XXh7~@=8Ym`!Zpv55{ zIHdJqp63A|A|y%j2~>dj18ACm=3us?TL?f|mMj*FXW-ij=o{=L)?5??X`1dQlSv5d zoKMhNJ3Hv!&U8AxS4u5`+&Mv2RYw2-tu=X`6Ncg2cs#xZl9L@+fR%_KA_PIO91e%q zzzdMM%m98}*N5_&reVEam!r|>aW+RbJoaU5@>D2nGr^LZp9PhE1t ziT15L;D+CZzkmV!Z M07*qoM6N<$f?<7~?EnA( delta 424 zcmZ3$e2aO4WIYQ51H;x|=C6PhQRD=%g{b0wh>g z;Fu1i1;9Aw*xJKD#v@M`#}JM4OZzu^F*^#h?YDkkTEq15Da&b*mAP+JZg?q0EWMbZ zsKgSavV4Ye0gLIAlF7UG&fa)p<8Hw<^`H2o-~74%#$I}@h={8I%hG3e=gj%E$duv8 zf*;JLk$t)P4tq9>WJ*u_DILwPa;h%!5~uVWA;u-94`*LLf7-f^X+hz#puiJ9r_M}j z>NvGFB6&w$&5Oy2SDCl5dYN6Seivh~EPzu@4=65GEIi@@@i}l~H);&AX zGRddj@8x{U-MbO1M!E~+DpGB zOS}d8SGB}7q9i4;B-JXpC>2OC7#SEE=^B{n8W@Hc8d(_`S{Yet8yHy`7zA8l&_dCW io1c=IR*9rR7)^&_=ZSLTBDa*#dz_2B>?irBcEbxddW?)EuJ)Uu?^vL38xY(DD1V0ni5W&6cEH=t$)Pgg&ebxsLQ0M<1g5dZ)H literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W=!2%@ZVz%W1DW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`0$SBdfgIbxnJjv*44lmGmf->7lGWzMF+)+<3A44O7f zEG|`_?13s&OI#yLQW8s2t&)pUffR$0fuWJEftjv>VThrTm64&9k)^hQk(Gf#z!e59 z6b-rgDVb@NxHTwt?wAJDAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ048rn@Bjb+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png index ebe042e97296a7b05ee2f71031e3f9214b27c374..70a084c58cc8dc1beaf3543f6e812aac1b8c3bee 100644 GIT binary patch delta 130 zcmZ3(w1aViq%0c)1H;~Z_vQd8&H|6fVg?4j!ywFfJby*X#NQfGuAVNAAsQ2tQx34` z@bK{b64#5dP*zktcmM=WoH%jd$dMxl&YU>|rca#c5ICO1;F)lxK{5Tn|Ns9r%Ncb9 b4>B-hNwd9_;mD8xTEpP!>gTe~DWM4fx1lrb literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhRgkmPy6ft{7V@vq&OHDo_*T@)UR6N8c~vxSdwa$T$Bo=7=U_= zbPddO4GcpJjjW6et&A+S4UDV|3<9n&XrXAx%}>cptHiBAv2({Xpaw~h4Z-BuF?hQAxvX}(6P49wzX=K5#@mpqa`CQ5(vLGLN@5ADW_)Mv pxHp{t0z%d<2gY`1Jc^xhR%Z$p3p%f;`S9G?GGFR*j@ z7IinW6#kqQsGXKRhtq3Hkj0wWw&ELJXjG=_*Zi0{VWz>eR-5-GbES8`6Xwy|x$G~{ zFx3**h?11Vl2ohYqEsNoU}Ruuq-$WNYhV~+Xk=w%Xk}!nZD3?&U=VPHK?_AgZhlH; zS|x4`ik&;A0X0a1YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;uc GLK6UyPg|1! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png index 8cb90399455c87336899e6097e512ba72af5be7e..1ea1710389d0af614fec4be5b6d0d914709439ca 100644 GIT binary patch delta 127 zcmZ3*w3Ts!q%0c)1H;Myzc?VpS>O>_%)r2R7=#&*=dVba_){a?$2>8 zTnAxBCym(^Ai=T%$8;bK*2`dF-Fy}d(oDbBkTH+c}l9E`GYL#4+3Zxi} z3=EBQ4a{^63_}c!tc(n;j4ZVcjI0a{0PsvQH#H~TGbH_BG21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0sy*RQtJQ! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png index c3200aff4e60ae100e14e960fe4a4afba18239ed..1fd1527eeb09dfcf3a3f341cd66237406168b239 100644 GIT binary patch delta 331 zcmV-R0krVIGkpU-v0SZY( zK~yM_#ZfVCgfI}CwQQd)ID;Ebm>wFwlC(i0=&CgQAZ5Nlnsj`Dj@N-xAkZO&%PCE^ zvaFfenOWe!hyH-4+xMda1c2(g4y&qqiK6KFbUKwnh|41a1V9eM&^YHllu}M91t}$@ zl)pxxqA0?y>pqhtxf){-1OcRfl;E6$F?Lsg0O)ZXzp^ZA;yB*Obd#Llv)%XoTbibg zwH8`y2q6Ff-unea1a>4)mSvLX`MWU&LI`lq;l1C;>-;1@0A$;?uTd0TwAMSzJK%u> z0&sTDJt?KO&uN-=+ldI?`@;^-*4lh6%zKY%ng9UvJcBW|T;RX~3xXgb)LI+P`L=D1 du@Zr$%x^VcHJ1-av|#`M002ovPDHLkV1f)qld1p! delta 404 zcmey%bclI^WIYQ50|VD4we>)XDaqU2h2ejD|C#+j9%q3^WHAE+?{yGnbkdkz0TL`L za7+i%0zk~muz1zM`#{DiPZ!4!iOa1McKb0U3bgM3X}tU9{8H02PYuO`eufi|9J>*C z`J+Oc_=1fecr`fQJ1l&kn3$aI>a0<+ePeyZF{hJpN>-Cso|`$RTcW=IH@iDOqY_6^ zgF@b$`NuA9-QT76Wx9VXkN)(Jl^u%`wz^vV`}ptY=d0JYZ7n}N%i!Xxhez+_B+E~W z%-eZYwWRF!T(t@(hBb1*G4`@&A1k>0oR;@Z;EwO5&B`nb*PIW%^ZW5^21c&3>hP&@ zEl)}W80rHU+L)IpJ&aO+JMUk?>EBFA$827Qu5}Rs`b)LMHKHUXu_V9nO2EggJS27X+RBVIGm;on$0XIoR zK~yM_#gIK}0znvtpV?ibu33$Zg$-HiUHbig5QgC`a8YGq0Vwr( zRzfVxqE@TXZnqf@hxen=s831z?!Vzb7`u(ZQ)jE< z!VfGFmo67EB&8qa^vT)Nc-=tpqY#TB8<%yGvZ&!ZsS6u^N9vqx`e8hI<+HQ1C57wT zKl{rcc5V35eQI}oq;J^cryGnVbf*4IsJJ%Ebp9TH`ReD&mu!OdKR13``JLxsg}4# zl%yn~>+1H%wQBP%0ADoc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngBaz BqjvxR diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png index 49fe22b335f593f65c80a3334818cc9a5fd00f23..c76994a6728fa41ec14ab479e1ca5c6ddd702f51 100644 GIT binary patch delta 348 zcmV-i0i*u-0*(Wa865@y006zd-kbmc010qNS#tmY4#NNd4#NS*Z>VIGM*$~)0UJp~ zK~yM_m6E+`!!Q(u&(*bv5@J=R6yz9!*ANV*(4{y_mvr;1WXOYbEM&>6z=x-KrU+wDL^`+F0AK#Rp9jH0OMcDo~E3_6|8nYnFj2T-2pqaX-YN~xje zc}F#`App=|FnEzt4qey%ml*&U0Bts#_wjf6vZk@l3T6yeO=d3N?mQhIIyiVs;bPg>?4lj u8*A-Dzu*7U3a3Z_@p`@fJpD+QR`>>(Xf#)GZ`Oza00000z%d<2gY`1Jc^xhR#m6dZcucy6z~pyBH! zuds9HiQFgm4eAc)>`eMAe17W2&lf8HFgxY0FTbqMVIGQ2{4^0Tf9@ zK~yM_mC~_F!%!5)@qbI8b;#1i**6H?e1qVm_!1ogq3&WgArFu~LYG2T$sBM91zp6U zAP7PT9g^EixS`y8U0M-buHX2<`N83wfe^x4YXPvyf?z`PRllZ#MNr00000NkvXXu0mjfc9EFf literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhR@+9A#k=CP0;g!}elcC}&N0BhY2UWJPG6Z_ z_J8Ryk$p1nk$BDb*IRnG&Y5HT|6sil^UUsc9bUP0eO9YXcI>>(8MaF^KqJ?8jqlc= z1zQZan_LpOq@EVmHvj+qcLl0q88cYSfv!?5ag8WRNi0dVN-jzTQVd20hDN#uX1WH3 zA%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsW()}YwAV;WF{B*=!~{Irtt#G+J&^73-M g%)IR4VIGSOF)00S-w- zK~yM_m65+n!%!55zk72-QJ(Ey`T}1UReOsG|hKw ztvd^LVC(+`opZEvc6M~m_0IQyKXALE2>8 zUk71ECym(^Ai=T%$8;bK*30m(yT=a5nds@_7$R{w_w+_Tra%GK3&yXHWN_3qa&FwX zdExZ>?TZYwAZ${y2E4M)FK7R}Hhhk?}+)wpk`X$ElXMMwFx^mZVxG7o`Fz1|tJQ zBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4}a`RI%(<*UmQ0&|>4X8m9WJ7R%T1k0g mQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT& z^Tze_%-hYyw&CUjri}ZX32gcYRuo;H9rBj{12a>#*(aUNSK^TVN zr@E&nnq(4!haf0|WTB{8xpAutuftn%=|#Bl3Pc1^5Erfl1r?GQGRA>%oI`j0E;@q? zXFM$Z;Detk>gBDfHEHYU;9L2ey|DZAZzEGmjb>&dFz$KJ#tMH?P^16f@#exm}TVxKtl2I zqvrmt*}e6Rs;js8lO0KlkRr%wApn|5tz7B2boavXRcl)mr)W;p>)hHbF_>SYdHT-q z+IC#Oar)?-VvVSn1e2!iIFOvZvgWYsL(sVFSDA00000NkvXXu0mjf_Vvc% delta 433 zcmV;i0Z#tV1MdTnBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zY)M2xR5*>j(#>j9K@(bQ^D zk4Rz~35~ei#}N^+!x50a{b*mmTb2QT1wug)er2czzPJCy?s89=%#eX>%mYoJ;on@F&^h~ zEp})9zO_fUqN|O$ld<^~;-nlSM*J6c z)rZ&IzH-LWrDY2j7R?JBSCW_XZ{+Px>5AA{8wN)s(#}C b1HJ>s#-zD{^QyuC0000W diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png index 639fc3878ea5d5dca14cf5762f9042e6314cd98c..3cec3cc27249238e8865fd4cec95e7d74074b083 100644 GIT binary patch delta 391 zcmV;20eJr91I7c8BoYa5NLh0L01m?d01m?e$8V@)kwz$gQ%OWYR5*?0l3hvzF%*Tr z$UM0kAKiybZ~?AE5quH!#W#Pz4HPUEDX5e}5h;b@FLkJ;woGd~otl~4_>dHfPP+lm z(@k>oo!mo|^fxRhFcvZc+M=`pEnoz+Cb=o4t6QuC_dv#+0#INrhy@Xp_!v}sOoo*8EUQz%?xg)4JbzI{|nPm_Up!LXJiDDGf1jhLTlFd#6F%*SAkQeYld;}lEXK>+CAH$6s6XVhtb}rS(%AXj*iugCiAR&YR zBRGr-%`e5a>vPP`>S03)CbLdkh1UrR3^*%13($$ZER2U0?=)_gTZWSO1xbM*b##w*@%28VE#r#AHVp zc%VlRhY))>9ThC^a(G(f05}I+?AbD_(C=KT8<*i#n?bcnd#A$jSW!-#U0{-R^t5uo z2Ji^zopr0K%{ov;Y7A delta 84 zcmeBUoX0ppMTw=@$uool2x>S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|Lxw`GmA0` joAOGV7F;=SFiC+Sx1Bj$B)dBlsE5JR)z4*}Q$iB}lsXpa diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png index f19354d8b9debeb3b9da8fdecedb487288a22a0c..ecb8de13e29d00f00686754ea4cc7cef4cccccf6 100644 GIT binary patch delta 133 zcmcc3c#Ls^iV$akM`SSr1K(i~W;~w1B4whRMni=K5rMN4Ai}-VH`)1sudy9NKz7U;?A!g?)8X<$s72%&ua( l(f%xQ2jhzQ+oi6>-(vWy#1rtRTaEz)JYD@<);T3K0RY(zHTM7j delta 154 zcmX@cc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 zopg}1!GVV*{cxuBzuW_SYfsI}t99A2$3>vVQeaby!B3ZMD?PFfJeu2F+AOf8!7^dq zrtK$oDpZ`*{}GbV8}o>{k)dBGpze9xg}JA{R+aD4^P9C(#HU(S#TaNagQu&X%Q~lo FCIFe#i(`n!#J3lA^BxM|X}ef#9HN%U zrIx~!rIy%W^Cx(L$3s;;+xXO-7Sry$s_Iy9DCo>mU+v(CFs|p5%S;|M-CXBb-)f^@ z&v@?}yB(wc{&%cVx7jW&=iyfu-lVwGIer(T{bG4O=O!su1|aZs^>bP0l+XkKSi3jZ delta 164 zcmcb@_>^&iiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WrlRRAV4rkTAcs^Oq(c0+IIB&9&_wpA{4lSz{Vu}fnndE$`RBU}+ z?1q_wH&jxYnBNyVl>bz{@Pz+J1FLrRzc*}4j2C_QwNPMzobMf{UAx%WBONrE4H>>> Q0Nudg>FVdQ&MBb@0CBiIBme*a diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png index ce4a2357abda53c72c52e065065e6f53e012d5e0..64fa0e7c12a8affd27262c681fe56af55d660044 100644 GIT binary patch delta 120 zcmX@ZxRY^$iV$akM`SSr1K(i~W;~w1B4whRMzou!i(`mI@7ePkc@HQE9B{Dz^>D@n z+fAIh))yw}RZS}pLN1Q_J2vIUk~pBvu_~ Y-5MptmwlC$kpT!iUHx3vIVCg!0QoO3TL1t6 delta 139 zcmdnVc!qI;iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{W@JUv|;Lo9mN zo_7>%Fc4rlxbsS7w{y({m3W&EyniBm&TzfBwNhn<^eQ%y3tBUnx9;4ujOX5RF0-4< q+?#p(uCu*u|9av<`N@Qpa`q)tL<9}Y-u(hv#o+1c=d#Wzp$P!yku+cc diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png index 70e3cad6488456ac13e35246e92806d8e1d1f619..ef3d963d6c89263f9550239c6f19ce1238cbf948 100644 GIT binary patch delta 349 zcmV-j0iyo51DpepBoYa5NLh0L01m?d01m?e$8V@)kwz$gDM>^@R49?flDkdVSEFl2_(P8610Go z*f`Y`XTF(pGVtFef6&X%eo=q`a&bg(xzA}7aFVm>I2M&f00KDAH}o43w^`4v60bnM z2wDGE3v#f3P4GD2zFyD)jdiGXAZ&wM2Rljy2#|Xj^3Ys%`s{R}ya!+8;FOoY)~6OG*Qm85XK%`tV9f*iDi)3D=+_bB5rL}sRP6&k&cujDE zXc80 zJUET*6vYZ;+rZosBLPQ1mODt@A9GqRnI5e^I2n*nh~}VTAqtux5NFR84F?oUs-TXw z{P7OzgQFm>ovS7~5Fn@o><|QTWg=L-#Ux7v8zrgAn)ArlH)vrB_M>1+FZvTf?feV1 WBq$^yWb~K-0000T_4>~FWmlec?|sxuZK=2GlSAxGW-LTbuuE$r9Yy{mKWtPA5>M4==WWCO`2 z^*UQULQR&@+2_cdb7*Y`m{50{0Y{0^kYQr0CWa=PowK*~_Bh)3zRie<5E{oQ#n>E+ m&BN&#?J2V}liEMSKlB5Wv4fmLIG}I<0000ixy{zW&8!PsCN(08Dw7(_b>#QQ>%DK=8QL`9_GlN*e41LA4=607AKejLLwrK0j31<1U!Iu2ktc(0TX~o7ws*K0Ac)p^C3apJb3Dt z>w)V+&Gn}WU|Ga0hJaR}_}M_H?^Z7{^&{Xn;RxMrB&=qvMh34HwvH!dZMTvD0000< KMNUMnLSTX?HnCm+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png index f407cbbf7174d0c69426e7331dd1db7290bc18d1..8efd044b0c38f6e929c25a6fbd82f792815ad99e 100644 GIT binary patch delta 345 zcmV-f0jB+kULAmU=)U* z^Ch$-R_(>2Acm3_+9)^_9V~GX1R;}y|G?27;jV)?If{#egOjv^;NYxI{sIS~n;7i{ zZ5)!`P&DuI@g2_d9L^EOBRgwk4m~ccEF09eKnZ9-LMKRQkPy%nC_n^#6h7D{zw2_D zHl&7Kj>-XlVK*QFi0Zck3Y+fQGnPPj*>bSh05>nAJG7LdE;iqVtwkPIZx7niOJzu0h9twK#N`_;abss zd3>gGeow<&3Mw<5W{Iy)Nax}UfS%vRKYO6=Es~o&mDeh*cgW4f76A0RUD_vi+`2`k rZPQ<6q4cjnF`gdK+C1ho?h(HM!|^(95NZhF00000NkvXXu0mjf-BOoJ delta 336 zcmV-W0k8g;1CIlcBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z3`s;mR49>^kG)C*Q4oc{xw%)#^#>QSq97<%iiIGE7FIzlwy?4lAHdc(@dYf!T4HNw zV-wP7FbEn&jV!pLi8f=g%O;>ma*Ba(;G8)ls;XpCRX&oK_UR5`at`ZTP%vN(3>g@< z;4&^45U{=G&f7C`woRB^!u%o_0TGaY{6@CxqRq|mEmDaXX*XbL1tvr? z<0ZbzCp3K->NU8#87#m#$JF!;#psyk^l08eqa2UjY zPY6Pbg&=}LU5Y|M#X*N62s${cs7sw4I{6KXOCjLcsl^YFPhcrdiqcJdD^gLHiWN#) zUxo^?$=@M`6s!<$xrgKK;DHmby{%9RJfQ1=qY%dhrwcCNDX5frdE-2H#8#n#jqe6P z^GSLnAc{bL>)n$x#7AVw+@zFSCm!Vb4j(FDkw6}wfa!URn7**L%;{m8SwIIw8<-b< z!x)9R6fq-`*hz70?Xn2y+5qd{hz>&{Npy&@l_?H@$o~rLSGd2W+MvFg#{@JzboluR z>W`c}P}?Z5|MA5Y&^lCeqyK@f(&UA^L>xe!7MZ8S~Hab7?zRIm^&1hMulENuiq-^VURz)HKb z619l22^KjpLZU|HjGJAHBwPfG^M`@?XP9po7-2g51_SgpC=K5lz7+I^zONxT=h@lB z-a8|e&LX8`q&O3R6vWwgXz1>7>{TD!h8IeX|2EExiC@qoxykVlU z#YKYs-KNtBP)dyfk|;F|g#~Q&gbWUeqUfK1RtWW5 zY99seW{%NXGnsh!@d26*u3lZj;wdY|MQqzn2)Mt7c8iO*b$ZJutoc5!(l1CuQ547V z@4fF1^@(Loa3Y8xVlZeE?87Li(Q30AEg~j^CX2;jGYFPdG0Y$iMO1_#d+3v~F%;Ro z?_R^(!+&^p>iO_H=fDxRzTgmm!&?df>qjZHu4`HfwFM!-`L#kjAOVCQiZ_#*Eb$+& zsDFTPfb^z+DjM25@(VU~*Zn$)XP^c_4gc+$DwqfWd2~Sq6G8Iw6D2X2h=X$;#VUuv zafR~oG$Z-m<|twSWDnRD=sQZcR2TQzv5wQgTH>o3C-alcg{m=x4559`<&%9b?y~i+ zDFN5nAh|R{;dPrEw}*S!ATH!t115m*_qDn8B2%?3P0F)ltN`OcUxvO*0px&wAOKoG co6gI80xgqW8LPEb_W%F@07*qoM6N<$f>a8X3jhEB delta 354 zcmV-o0iFJd1EB+uBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z9!W$&R49>+(7j3nK@h<4|Hk!5#6!h2HrYckCqUQ==82={$g50-gIm?N^{*10Z!%U-OM?{6($- z{Ti30h?C+msl~$!YO}jw%aC+DN;+W66zhif+&TGt9%ZeS__K{%9WWn1!So8)SDu?$ z?iUJdZtY-#=9}ix4N|sf~W&i*H07*qoM6N<$f)eMG ArT_o{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png index 7bd1d84f96210f506b40923f10ef8c1a2a308d8f..c27064260bcdc497b9d02283fb391d34243b906d 100644 GIT binary patch delta 136 zcmcc2bb@h$iV$akM`SSr1K(i~W;~w1B4x4?qefP!r;B5VMeox~2RR!81eh;IMtFZx zC`(t~mXO`VA@^^c?-@q}RvRYID;rIdCh=WX*4(Oaa>K#&9SL`yHqBY(UQ{d76Bkzc ojG;_=4rA^s2DJmV-}irFa(yWhwdq9ACk7z!boFyt=akR{0KphGMgRZ+ delta 275 zcmX@Xc$sN}NQ}kxTlL_h{frxmkk9Q90XVnTE3dl;#{+UQPjnwv7_bxDtjLu?FEbHuBg>L zqN>Gyvf$_ve#soOA0?7|az1Q3XrB7PCZyh=;VhfD!*4$Z;|fN%sk84b$*OOVXQ`Gb zO89({8EA)UiEBhjN@7W>RdP`(kYX@0Ff`INFw-?K3^6paGBUI>veY&(vNA9TxWb@? gq9HdwB{QuOw+6+|9n&V7X>c-ly85}Sb4q9e028@cK>z>% diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png index 5018dc60a24d9feaa5276bdf6c53d3e3d97802b4..4d22f79c1686731247507ba865954266790dae11 100644 GIT binary patch delta 407 zcmV;I0cig21k?kNBoYa5NLh0L01m?d01m?e$8V@)lRW|_e*s}hL_t(Ijn&c5N*hrW z$MNsElbMOZ7&K@%icnm%w7M17E?oKyeXTx(8=pYB5d|MX3YI1*{z>8(Cv*QC7dPUf zV``Tk_`&6J&*vPt!r#>ZcFNto)BJERrIkSH_%Z@9$8B5q*qivU0OTKxur2dNPnkVOPWvBm-zjiLl%Y~yYNQ>pm=?^d1 zjFtIx`C3F=bTYV{msD*N(b(`qf~n&9(j+nS|8=Vw*E({C97$Qpukm*JJpTfDU)2VV zAB>@j^BEbstdBmD3)c(LdiHVk$?Fe7L$8%G`g4a*e_i?gT2%;t5! zTb=gRKaxL}W^`I6Hv3#rz@>l-0UvthY$`t4GaczU%B&am{{6LSo378!k#%^+_U?4S z>%(i)i`MzP*!<7cMSH1S!`+>i&n(gxn)&$;V~}U}ygZKfvl5J-R}w>^V?knlzmw#*G2z?e`iag8WR zNi0dVN-jzTQVd20hDN#uX1WH3A%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsUz$l}zY W*tuicL^E|R1_n=8KbLh*2~7aT%HZe# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png index 994743d0c35fbcbb3dfa3ae441e0e8ae19b52d5e..00d2a62557ee75825ea580d6dfdff0e7c2b62ec3 100644 GIT binary patch delta 397 zcmV;80doH01j+-DBoYa5NLh0L01m?d01m?e$8V@)lQ9A(e*srXL_t(IjpdTRN&`U< zhrg9nK8=mw`}ihyieMvXW2u6b*rc!%L`4XqA_)FT;7ra$a>mQ$a(8<(7Q4hKm%M-j z!_F={-*5KE8aZB51Q3N>p%BbiATOa*NHWrs%VP2BVgIpTIh~t*(6s_0kCvewdtJ67+%JLByR!A1)9LKZyd~1o(3!d r1u*iU*zYTUUKOCm&%fhO{U72RLk{KW$N|#T00000NkvXXu0mjf{}{7r delta 550 zcmX@b{D@_ONyvhP!xZ9? zb1jlP<2R!*(=mtJ&z)9EJ3I_%4WC^)XGV#fW5X=>2mF7RmSxLx+-(SG-Z=9h$BRFH zR(ADw%HKHc-6ttg%kJ`yL!r_0!Ykn4ejHW-*vuKWW8=OY4nx zGZ?o%pE%#jkFhS&e(9(Acm6Y0FgKt5_wA5m!%tx7tCqM%l%yn~>+1H%wQBP%0ADVO0|RG)M`SSr1MhVZW^~e+T>%m-D{xE)(jq|2 z#ZX=)$_Hdfd%8G=Xq->}vw!1LduCBaVN+gd(}F7p4kjruSlwiH7d*FeB2bxXiEBhj zN@7W>RdP`(kYX@0Ff`INFw-?K3~@FzvNAHXGP2Y*FtRc*2)M$ag`y)jKP5A*5?KeT X2F1=D(BU06on222ryrmo|}Fu z_k!#Ww(ZY+>a{aOIUE*rc!b2+q#xUP{q)_pUZTYjUh}(Blek1Ly<+_k`0v2^M!sL( o3%*M!zGv!{>$mkg_(Haa*UU!Hiqo|~lK}`kUHx3vIVCg!001d8<^TWy delta 275 zcmX@Xc!_C(NPO zi{Z`da0wtI%+tj&MC1J19#5_Y0|A!R?Jj?M!yWHGTwNP{%UMK;gR4oMyDc+K^X4+w zASSl{%cqQ-87voYzX*P7slc-8b@-pA{Cd`1J>Qu)-$WfR{^;!Zv2M-hHHplkX+pMh z*mV1VR;ZS^MwFx^mZVxG7o`Fz1|tJQBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4} fa`RI%(<*UmQ0&|>jbWm>IwymttDnm{r-UW|P!w1g diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png index d538eea05ef1f8dd4163652da56db18c4c52aa20..08b3a53ae51f2f915e3468a1e739007eba744cbc 100644 GIT binary patch delta 145 zcmaFBbdhm_iV$akM`SSr1K(i~W;~w1B4x5ZqegL@r;B5V#>BVhtoa-gL|h&g>z-oD zbx#&_$+m2%cXNC=wc?7O<;lNA&Y_7i3eHA6oiA9M6O23puDRTP;=taMbE;wPO zi{Z`da0wtI#nZ(xMC1J1iQZhT4m>Q{a;Jo=q{{C(9$b37(&EzFB(XlF^XG3h30#`c zG@;2OC7#SEE=^B{n8W@Hc8d(_` wS{Yet8yHy`7zA8l&_dCWo1c=IR*9j37p_CGbH}uaW*VFfp00i_>zopr0FU5duK)l5 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png index 27c7d02b412440b51d42af05c3322c4805a27cb5..9900f8bee2b9771716b89215a9069d9e051e16de 100644 GIT binary patch delta 129 zcmX@bbdYg^iV$akM`SSr1K(i~W;~w1B4x59qeilyr;B5VMeo^5yLlTNcvvoOe6mbn zi{okW;3H34YDyAj&1lelklEC_U%w&b;H+mx2UB8w`d6$y+4?=PO6C01rmyq#JWjUq h>@Ik3B=IWy2LpSKNL2mC6hQ_c@O1TaS?83{1OQF>Hc9{h delta 275 zcmX@ec#3I)N+%J4>=0 z7*;l!>Sq;iTANoSyZg_Fy;s^j_osfSPN^@raq_UA-E5w=S09-dZWE1Lv8U)R&}h{X z*NBpo#FA92@ylT2KH0 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png index c5e3fc3b18d9f4f955f2dd4e7755d0a9b5046b7f..12ce5c81e7e4c29ed9126294767ae19b6423f819 100644 GIT binary patch delta 357 zcmV-r0h<251fm0wBoYa5NLh0L01m?d01m?e$8V@)lMVtWe*rH^L_t(2k;RZbP6AOB zg}?h|<~fgHfK2!`!pvxb2@uq%6>HGeMq*`YtSxm5HtxWMxC%QLU@WvDAU=zk!UB-k zc&l5S^WAeU{P)No^zw6G7a)LKMN#p(lbl7KJ~bi(?MP!CfB^b=|8U&d(6_$Po5W3M zRv2TcE(c>qJ?Qly*#%eS3c+0! z`)M$|i~}=f)Q9d4Y$Y(Cg3Zhb%K^v6)b~u`hG7cT64Y8Sn}8Bvd^Wa-@a# zSC}Z!0@?vbfmqZ6vkIUXII4v4^JnFq9Ra04PO zmtpa$gZCL27@a*`978nDFP(JOi>XlLX#Mwp>2B$NR()jFy>!9IFgNIe>ld!Ki^4PH zUAoO|UDsAM+*5m@+Qp%?;>4NEhc3ETxb*MTpKUFEXZbvi^YDa9ujfw8*XkLSln#Xd zpX=cA#UQ?5{TzWUBv^nL`q>7r!Pjz%E9xPAO77$!%;rD0R z&eB;$$;a0`k*Sitkm0zGBTi^$S!+h|8@m^Co*KOr{#E*d?E=q%!bL1;=?Sr+*}He{ zsCL=U_qLvGjd`L;%XY<%h7&1Ff)@{b-Ne4H-f?Zl<|oc8d78xoB)1Drc**tVb5ZL2 zlA>Ne(ImqJmgaDSo`VaU{1iI&?2bHrYvGe-!w(<%`pX|wCU9GbMR2*PYY8ZXZdhwp zXH+#)KrZj$&4$GZuOnJd9SOfS#c-zU?Z~74|7S3*y8o}Ve$GMlTN`xk9`AbN4-8t> z64!{5l*E!$tK_0oAjM#0U}&UkV5Vze7-DE-Wn^e&WT|anWMyCwaD_n&MMG|WN@iLm oZVif^JEj3ONP=t#&QB{TPb^AhD4*yd%EiFo>FVdQ&MBb@0IOs=ij&^_Du?E!`dNd0qq1zXHt8 zhT++VhdPw1e+0g)-21`y_|?S$5CZ0B;QYkUlPO zmtpa$gZCL27&ARx978nDFP&tq?~*9cHvjz`+osgRySzJgn5yWpa@spTWY5UhDmAsm zOZ{K7U+*ohO@%iDa+H)d<=wn}v-sPax^$8HbkT_IGs@ELRX&>=sC20Q(2sEQ1q{L! zhXsBr2YD<@fA{h0&L6)_*8g36^jqKEx5wGtUH-%io;Wq>!=&aC#&`1$mg+yMtWNy% z>5s$(dqK^eR)TM2o)}HAX#Oj4$F6eQ>)f80BiHk6&j0mu@qA?9!S#Uqj#}b-hNSB@ zsheKse!N^Cy5Psuj>hLs7aNlpZP;(^N+{x4)|R<;ZS=jD@^jWo#NKr|)taztTEhYH zjJ(Eo8ayRY#k;ncPUSkUwRGNU$?OHP8rA`N4lA7!L-=ei@=t7Acy`{s$^$`OE6+2f zvU{0Tm{~-gSgtsiDY!AyDSS$ru?h2)@D%$s6TH}NL@jvIT>rdzb#oA_i}Z^vYXTK` zQtX5^4g?%@ac)f9Q~x2OMQ!ym{iHUj)q;DN&hK45fBuuDvcL#XEpd$~Nl7e8wMs5Z z1yT$~28Kqu24=bjh9QPVRz`+aMwZ$JMpgy}0aqBbP&DM`r(~v8A~cAg>rm|6F>Rum QIu`?jr>mdKI;Vst04inVRsaA1 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png index d1b1f6b6459ac7d90d94dc2499f20cf3dc13909b..7e332b401e639e9ae497367421476df018d91456 100644 GIT binary patch delta 360 zcmV-u0hj*c1Em9yBoYa5NLh0L01m?d01m?e$8V@)ld=IPe*rQ{L_t(2k&TeeN&-|B{&& zM^hom7Y+wLzV|ujeFgIpXG*0m^M!lI3LkUofdotgB9g$8U>RTlQi23?)_mc*+4FSv z!8VOUDmf5pD+d&^74A7kNAiGw1nr=}(t8wAJzf(bzXK-4Rh zk{gQFEERF^%8-olr$m6xG?fX6TsV4V3E{BgE;cWa0f@$+_p+BzN2<}MFb>?LNN`T)PjXJl@My;C8tgN>CyL|Ov zGqW@Rz#l^Yy7}?yB~&su^!F({{{rSK1s~|0yw`7*E%65PO zi{Z`da0wvexu=U`h{pN37dLt_2MV-4e4n@Jky6Bx%_6IBbWHNo$vxt9klmmuqI2&z z#;q?5Zofz)8wmQw$UJKrpWaqX0`e@hc5>X@SORX-o|No?8WwP{5y81XU}v} z@SWjtqHD?CT@wT}_-2-WuUNC$!dvLm1#@Li=C}3@e(i6y&Z=prrg`nucXM)jA^BKA zg?)?tigzEbrj<6n)I8kPoY_CIA*%P9w0E)cnZ;9?{rYC=7k~Cy{FUE)V+8tLJdAn(2Aouk`x$imIo(?8FjY^uD~f@Vid%u06kQv;F;b=Z?hhmV8zr(|~O+ zT!Vq0RxNRjC`m~yNwrEYN(E93Mh1pPx&~&t28JPqMpj0KRz{ZE21Zr}1_4(Xv`{qU h=BH$)RibDRMA4zxxntTyGj%Qo22WQ%mvv4FO#p^>q~ zyea?^GzdTnf6$B~q}N-XB{3FUHIg&=Ts)rea^Hdh8juB#ED(-_QoB>J>+?)z1qjIBr~e=_0gGuuQckajqesB_{{+@M z+*dJsJ!`XU8h{M=3TmKafoXBm?Nqj_<%5pvJ^(#`MuNLCG+N}_?c!GDdEbRcpb7N- z30_;A+HY6cdd&bzKpXFCv_Aomt=Eo$C!ovFBYgqw)nez-uhruK0000PO zi{Z`da0wvev!{z=h{pN36a2lI5(V1le_uMgok>~6s)M7O{pPh@Ef<#hD|U9&`)U4C zRNB=Qzu0@eVv|h;$8L?3rUji!)!bJ~t?GBMmj_;|GcedM`Ajlxip_m)CJXNw`iXiU zHaE2xs5ZH73uNCj1Ue3q)JI*?+-~O;=e~Cnc3(KD!X@AM_shRH>D}FXC^wpM13|m`}8=0~8I|EOy)HO@@sYZo|KWr)c*LW(; zpyn{c{-2xN>a!-kT?q^T)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU(WMyP%Wn`&s sU}R-r5O9S-3q?b2eoAIqC4($Z9g3YhrcE?c=VD;+boFyt=akR{0Ew@oP5=M^ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png index 313e2db043272ac86789785d3cfd80ee2a7b1a25..8ef8a7a23dedc5b1edcbd0a0af5a940082ba5eb4 100644 GIT binary patch delta 352 zcmV-m0iXW)1DykqBoYa5NLh0L01m?d01m?e$8V@)lgI%le*r2!cPMr)N)4QBw%#n|F&F&>H`2;%Ct77WyirVz_NQ# zqXOj;NA+qkeRXlBojf*j+au0+{LPyrHVDxH@S0G%CHwMpzgch(C7f##YWcQzx;`|# zYI)CNm@z22TzbvQTERVdl`;!l`$mzicsyC3U%XLELK$_Jo~tFJ(On<~Sp0beV=s}I yDbFtCR&09*m;y{6`b`SJ0Ahd!w15w~ukr;9vtdv%-X7Ti0000RR9VIi(kBHyu5CkS9riDKkSLaLR>S$Lkfdw2~&X^S!I6yHh=9>F4A?1+!L(8#Np{ zmzH`KSa_B1G>}}XQU2vMLl0{ZU(fLcKfagEUVhMJ!ohOpVJbP>o|J5y@YBcw*Y|Qne zllJ{vT3^XBkDc55!wbP_UNP_9Zwy@j*n;ncwWm_9`I4=rdvo(%uDKc{;%Z;YrpjAw z`|?4++_LCGnf~xoZqJ_xU-s&av+?$P2@DF=64!{5l*E!$tK_0oAjM#0U}&UkV5Vze z7-DE-Wn^e&WT|anWMyCwaD_n&p+Oy}BR4-KGp!Q04#mzL(
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css index 443b58d74..63b7067d9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css @@ -1,6 +1,6 @@ .name{ font-weight: bold; -color: #FF0000; + color: #FF0000; } .time { @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px;} +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px;} +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px;} +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px;} .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm index 836fe4510..6e3ff2027 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm index 14221ffa6..32e875781 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm index ec98b3b43..603996b4f 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
%message%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh deleted file mode 100644 index b1c977ac1..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - #convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - #convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,10 ../bubble-blue/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,130 ../bubble-green/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg b/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg old mode 100644 new mode 100755 index f153fc374..6d76ccb92 --- a/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg +++ b/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg @@ -1,1066 +1,81 @@ - - - - - - - - - - - + + + + + - - - + + - - - + + - - - - + + - - + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + - + image/svg+xml - - + + - diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png index d9c28aaa7b247bae8cee3a07eb28369417012ddf..fa45de4abe17dfbd593342446d1065423b4479fa 100644 GIT binary patch delta 142 zcmV;90CE510nY)DBoYa5NLh0L01m?d01m?e$8V@)kwz$STuDShR5*?0)4>ryP!NOR zKP)cK(Wpdy&Z^K5rD(vgPZPOG0pCn!H(HOYVoX#k2a#Tncv4>QPH*RU)p)@&n8B&^ wW^in+pyutgUPZv}1{c8g-vTnGsRThiIEY))g8x_|)XwXr!6a8Q`d0XKffA={&!OTIu>?xg(nzrs* zTAX#2^?BgBJ$)~myo-g8mEC*wl%;@CO6maL9yN;uwKsQb?aGhVH^`p~;NzOYmk6|$ Ofx*+&&t;ucLK6T((mikh diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png index 8a3e85ec3cf4ec962b741ef200cdd2e943363064..68de5c2964e82362df65d4966de59df42fa3a3a1 100644 GIT binary patch delta 419 zcmV;U0bKr*1mOdaBoYa5NLh0L01m?d01m?e$8V@)kwz$gZb?KzR5*>*(7|gHQ4q)R z@66k`yV>n-!IA{4qQQWIBE8syJ$Up|=zry(<-v=d?4^P?dr+&;79ve+Hv8Uq*yPlt z>d_wzGcfRB7~y&n;Mw5yyZ0}jkA0pv5{1k`rd@e8oPq$l0st_(`gu8<1rRVZf`QTX zU=R^(4PZcj6VASzoKB{gfgzYd8-y%!icdIV2Px_<^mc6_kjUW{SB~;0v@OqRRI29faNu^V*a1=8j(oJhqK@`UE|2gw^=ib~D+ggpZVu@t0*jB;48x^VF#FehyyA}KxS`c@| zonR3JSJ{XfsTw0znxwSNxM-A;ai+YMt4pogR1q)& zUK3u0V8BX31q4uzCINf<-#@+I8SYYlctdoGvx+r>NCJU`Km`CW-0N+&xB5e(gXkc$ zf-_)5I9QORdV>Cb@5AfOuLHb7bcSFRZw=NOj1g1>6+H^1gG(81KYRGJ*LnNpWxGq^ zgxo2)Gh|K(PVwVfRTXwegRRbwCl4OIYJVPm{MM%oLiA7sL+%aHE4i-*MnHFe=gs=s zU}J6l@rw@cy4#dNsRgCX4E1QKWd@mi#$OQ;1!holrMz+HZoYDRWvO*iSC`LF1T(Hn zH84gja2iS7fv=(fmIql{a z>wg3$>J&f&SOn&QIbil!z{E5t`Jo+;4NO4t`}nWGWUBtb{{wykY;bU8Q|4Rw00000 LNkvXXu0mjfhTzzz diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png index f18a209e2aceca343be94459c34d56301601f01b..db142436459a07044864026b63ed4c8f471e7ca4 100644 GIT binary patch delta 432 zcmV;h0Z;y(1nvWnBoYa5NLh0L01m?d01m?e$8V@)kwz$gdr3q=R5*?0lEG>dQ51&1 zlP0*(tv-iK@!13^_zt=gK@p1JvVx1+N(!xQ6&KY|H9~7_QpcppOeT{%_xvt0O2lbj zz<+fv-1GhC{2aTxmq zSt#*hl2zY-{!z0OxPvf)pcJSA2qPKg_>bcrFsI`F4Ty##f*`t>yAfqbLLTXzO$gnC z10b&j6uxjQ1*IDEg^gTHdqu>8nRifs+e=Gq`@W1t!1<(b+vpXn!~(d%NBl zKU=*IyaPsc%>d0-)9DXqeC(y{e;F|z^k(VC!<~G4Z4KDE%pJgP+-pbAeirexdtP+5 zyVJerZRW+B%K7A?^#1^W2UWrY;4ARCYCONpc^PmM2*9)gO{#b8<<$Y2{64&emh1mP azX0|kb delta 480 zcmV<60U!SE1D*tsBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zn@L1LR5*>Tk=;%cQ51#0ea@i9$StqoGx!d^4_@dS@C?L+aAOQ!7zqAFg*4TeU;`Gg z2rbi&r5&cznVy;L#TgBh24ip~JJ}a!t#7X!S*-n31xf{{LRLUtDtRds3WFr$^@p$H z?xP0}fj2;`s!F8*KoJl{Py%aEBUlxG6d{Zz6unjiq<~{efqE|>SOGC$5fo5hI2z-^ zgElY#+(kM-V8r;%;N9ZQB7!SQI#G)2G@C#I6jv^o3k>qdD;TjTiV;|E^oUyD2I>2i zS3q1HbvfYfEq{SAf-wSs6=Cl*p}rTE@#>T3IvMX&6|M%{yJImTh~NikoWwkT`*_Ug z-P14me(fdD1k&mL0Kxoii+C_eRrOx`Z8=Y{^9LRnH#zPN5C)F W&)urfDj5&}0000S|Iv5xjI14-?iy0VruY)k7lg8|diDm{GITpX)*)xkW k3Y+pun-*L-a4<=MA%KI~@5kp)9zabDp00i_>zopr0KDWFZU6uP diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png index 346d6e3d65762794cfe71cc1e44b422e753833ed..60ab43b8983ea6b88929d821253f174d3cfceb79 100644 GIT binary patch delta 143 zcmV;A0C4~40nh=EBoYa5NLh0L01m?d01m?e$8V@)kwz$TT}ebiR49?{%rOo?P!NRS zf7T0e0<{w;oxtJT&AXCOJdKbDg~}u|*=+HNa}qFgb6%#gCx8^D3DH)j4w1qHAVFLJ xkMaYb0uqSQH-Noj!1&_=0hQiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WLQaxQ9Lo_D7 zowSj&!9jo}{k{AjAs^l~2ibDYJ?eRT%=E*=eiwnBn20{>8;Q-6bE7=H4&2axZRXF+ z_{2b!HTKOEktYU>3g>>h*+0l`ST%87be+`JvwRZHpRKm@<}_!$V7eNsaF}stx0KuU TDcMCpXE1oW`njxgN@xNAb{#*O diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png index e876448fc04de5e260f29a18c47b803dfb1211c1..77934e9d98c4619d8a4c58a35c92e1e8ba31c6a6 100644 GIT binary patch delta 156 zcmV;N0Av660o?(RBoYa5NLh0L01m?d01m?e$8V@)kwz$gYDq*vR49?{k-G_iKoCUV z+LB;vh8AW8f`J_v8yJhf9Rod()4PE0000< KMNUMnLSTX&=sVB= delta 183 zcmV;o07(Dc0rvrrBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zbV)=(R49?{k|7R*P!L4l{%|8s($iG-U>GcdGgQ|!!O;X}5KCyq7vTHUX0rRtPCUl9 zF$h=`%&YjQFt1`!AfOwbyzcD{=z+<$*(sbyweX6d%3ts+h#-KtC}@t!#^kT^&F54l l_FZGL9(ib-`L{DwHV+Ig2#D8^M*si{002ovPDHLkV1kc^O$z`3 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png index f21120bbd914a125538c0b785f736a9ec8f805b8..bac53adab7dcd74fd2bb22096603baed5a9eb789 100644 GIT binary patch delta 131 zcmV-}0DS-00mK22BoYa5NLh0L01m?d01m?e$8V@)kwz$HQAtEWR5*=eU>NLxk%57M zg{lUMcb@%EO#@k6%@wI>9s}d9CqJm`!ta0oQPVsImS2CV>OcmTKmVv~Ak|&?>mQZF l@bQ;F)HRTik*ek~006@27-;*V3-0bP0l+XkK DVg))t diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png index 5212f419dfa4ce8c1bc022832176b74aa12032ee..e9261c34c1fd113d578cec4c373d00629efd3a5d 100644 GIT binary patch delta 373 zcmV-*0gC?21GEE>BoYa5NLh0L01m?d01m?e$8V@)kwz$gK}keGR49?flD$p>Q4oc{ znR|EHWtZij4GVOJHIYO*TU!e)EVNK!Wn%12wDbuqY%F{QD__dO9%6uN0fhx1v2mK2 zV&=;^CjAk=?T8Yv!1WTPEn%1Hx?3vhDn#->Xw81#~0Bcs9oXMi%ia ztON+)2S+!TQIe#cR!l)*<{XnL7ZyZJi#i1*X6+epc!X)qwI1rJAZx&qvWuf33743YW(XB6FM z#qEkyIatU6NtN8bcJ+GxQgQwLwC+LObQ9P-Jhf&~yAOsd4-vz$LfKe7kIE^vu rl_}LQ5-)0nz5~Dl6T78t{_5Zd+cGkR2svLJ00000NkvXXu0mjf_t&hu diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png index f1c15529ac3dd93853e7e205110c781abb76a8d1..25ed23587760b59978b9f58f5a302b768b4c815d 100644 GIT binary patch delta 430 zcmV;f0a5;h1ndKlBoYa5NLh0L01m?d01m?e$8V@)kwz$gc}YY;R49?f&`(QLVHC&l z?|JSx+{u}An4H0MS1?;Q?t1}lf>uEUt-_7;0>Z5eUxFY(fkc~H*`~IIo1m3KC8U(z z95H6*KKIXaj++88M{3m%&g#JD{5bHx69E-K&dfhWIxAa4)AGP_|IvK^mA>70-h2P7 z59nV3cU~udHt;z|Cqusd7?AmN-+JGdlhxZ#fgG?)fz7X}r2!7TvU6PU?(;F9_Irer zgZ1Raqb0Vt`098gj*cHJj)X0O81tkr}wb(I#QIEMf+hS~{`?z*vzC9Ai)yUQG zYIs$AX_yHPW42T0O5xNzN#0T+$Y7^R@6F|n{96ehM7wnPhhD@$W%NT}@n z1B8P33k=#&Y(jtrqcIyGuL9lC6U)I-LZ0+D^R4$!zrB6_ z0kD6gk+sjM4hm&ZDBC^DyUrfny?#;b@4h~Iv+&Z#y+6{(%BNJ(9}76hJu6#1Hg@)j zcRNdm%THba@mVB6UV1X;Nu4KgN@(Ez&2eUKUtwhG?qXwp@c}R*B66yMRmJ*$Dk~!x zuM3mSQLeX}wQ%;)l4(x0IpgF(ITTx0W#*LBDWMVW+-T8gP26hCJ$npH$O$~%W;VZoH8U4G6$+42vOrACYqQA#(?f`1R~XN wM!<*=NL5$8l(9>7OtXDW>K7szp!Tc5cVW577|V9!b^rhX07*qoM6N<$g6uNP5&!@I diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png index 3a6ccf16ab5092e49d7590a424ae7f93f668e693..c162ec17ac366fdb7e03d2af862bf9bcd80d7b2d 100644 GIT binary patch delta 371 zcmV-(0gV341F{2+kUdL6VHk$5 z=e+0W@nC)uRO-PnEOAPSz$hZ9rur2vEiLs!g2tBS3R(&qg4TAYhW4o8RD>NBeH)H_ zM|lqq4>#P`a0y={vGQs%w7zwu5+h5?v*QS0iN;b8Q4m&wB^pCOG?<^q(UqNHyS8>> zI72nJk_pOx{t-X~KnK4L`Zs{YH}>*&zIvt{r&OrrNo3-1<9*P@K8fe78fUo#BF{=YtZn%?8gAaOyzb_A=j;De;@x51&H?UFHE;Q|8UpIgq<)> zG6I0@`3PVLm?BsPD3L&5--!a~++Meujni{`a$)LL(PN_9?h+e~4GsW$`2KUVQLjge zbLnQwuJ}(rV?*}9fB@2N`^~H4%h33AysgqRg>3R)fbq>q4|wtRHxCAt_zJ7bPk#Ub Rr6~Xa002ovPDHLkV1ne5tO5W4 delta 397 zcmV;80doGb1Iz=EBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zNl8ROR49>+kg-Z!VGxDCGylKddv{m#?yjy0F0R34QBX`Hf~8nkN}eE5NEy;t`2+z8 zfnXJ^Ed;@8eGT8hQba2)B(P(#SKUI<1H&)_=P>ih-FcKGRX4tmmRG+VTeZHizS1U` z2y#*rNr2QK1}8|!Ar71KoxhEd_VTHJm9o`tyN)Dq1|0xL5@N7-6#V2P3mJA&$l^}Vfer-ptw8&Oz!m-tdjS#ES>(`ouZPJcu8IqLvNcTS$TXP3)9`1 z+N^lFuu{aTv#6 z&wMA}!^|X0w1`&9MWocq$@~Gk@Gm%#gOlbmD@R8+DaW}yTz`@NV#+dJpBq#C~o%R z^kIyTE0T{`7f?`FnRIn<_ z&S8?u-R1tn`t;CiBAQlJiw_JHKtT|HM6d&PMgb98gFYO-Kv&(!?1r;@xJ5)9B6i#O zG$Dc@7=S(d7Bx535^8J2^msem1LNE7{;?2Xiims*RMD@spEP(~bcO;r>+6HA-qB6Z zV7Lb`jX(Oo;&z&}2K|WX^w+fa%>W+9e+21Ff%y3?!kv}MeaTv!x z&%N)P`-6ew62s|AHe^#`5;Kd9*PD-Q$;d<;87vehW#H-thpuy-7e(iFSHH(_ z=t^GS_4)Ma>HC$XGgm=C6u;Oif~cbY9JWyf6+{$2)~*^MAc`9CH+~pEK?KCdX&VFy zd?SBb?WT}_g{V^V`52=S$H!9#wuS>(*8ix)lIJ=$5My$v^Vf0nIM4n?5dh1HC8lmQ z*4`X;h_{D-pyO+ot&=?7`Sy*wGQDegnWJ>DZ#V}W(>D|l5 z!U}5kEQ~3=m$Eydp5c+pe5I?iCCF+jNBJ&Od|97cPipo35V*1cgIn;7`>;p%;KW(3 z9Q8`~kI!p!%jWIr0LTI5`rn<%=uCgxVk+&#`(}Y&AjH=S^}Pt-01?0fUV#eKR`>+@ W9en=YMo)AA0000!k}*hIVHAbG`~KHF6Jsbv6R{}N3Qiq@Q(YXyN$BEII_uD-TNgoa?O15R zLEF(uu!vORq9BT5P^8qjScwK&jZrX0q4G`#g9vTXyPof!d(Y+Cc=k+~kf>We03n$D z2NVJW!w|J?ee(Tqf~HZ?d5s;TSjm*&p&GvVGzgh z@67Y;pWApYM3O^HFh^1dfna43UqBkcH{si~u!_}LiC6{{1wmqv+q=DeW>VZj(z|L@Q544U|5|(Pz0aAGjARmHf(8i*^8g|mpTI^$8!I2fLSMpG@D1z( zRzk3`vat=K;stdw;DyPFX67u5i4w+)#>Nj;v6~<3vc=sw91#h?+NsBZ>K=Iz(JpYA{D?KIEpnxvVenL;uJnM|S}PX!ua=i63)y;*M# zwjR8D#r9yAESXXgg(ONcEiy8B#-9-p1?CA{n!Po5yLG*~xN&kxZ!CAI%#ed+O$81R z1D1db>3qIAduQ%iXT3UcuD!@g+2(9H^H)Fs13ExgvTPJrs>{}mE4CIpaW%I82uzGq z0n5NDa0XZe7LEl>bkjOi<*|Vx2}piD{}q_bw14pbfFIDLd=<9Kwj=-m002ovPDHLk FV1hBs%Lo7f diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png index 65a70a294c68ab74dc4a0c2c312cf1731749aab1..655a2db643b7df080a7e28e1975d369655293f7d 100644 GIT binary patch delta 425 zcmV;a0apH(1m^>gBoYa5NLh0L01m?d01m?e$8V@)kwz$gbV)=(R5*?0lEG>eK@>$# z^~@@gtt&smrT77UmtT-=+=vK@kd3&CAZ`K?B`Bg0%tA)OV3-LRdZwp)x~Hq|bun$6 zMJGSt-Bi7z-np+X754PVSXf3%IJU&NMoBm&su+1X%G>F~@dMx+5ZO`|EbI(fSVA_o zzyi!7B~++?1VoRrBqOz;gr&{u47|B;UMDn8zkxN^r~fo`*JueTVi^>%O|tk=Hng9c zFTko7px9!&o4{BJ902is*^p1#vU*V*0!7~wh9PxO4H(!!hJ%@`6Cd-M@@4TZEz%jV z?44jI?0`kc0=5aj`Ksd0bWZWMJguG=uYmE58SD;!?f?)BjarUom%P84P#%_Ni^o^{ zz*iveYX%rb4Y_D4PKy~Q`6c;9T`!+4KCKRx2f)#7?f~KL@x7#3YSJjqn-BGVC;VJM7_}MkiZ*$%T+y`2q>Oe(T_x`*-z_4@q>$JW9AM^+69Sbid Tk}NI^00000NkvXXu0mjfs8Pff delta 473 zcmV;~0Ve+E1D6DlBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zlu1NER5*>TkwIz{K@^6+SJRM?1Gw=Jp23wD@JPBA#1puXs9O<16vc%>i6~;!;24t_ zC(L9rnVIgXnXc;kU33evGekrm6x8DV-}hdX-Ov?Df|N+9BE^7WMHM5Y#ITIq{(Lka zTt2u8ya1+kpsoxFlMsfJ;piYBGeb^)3`3yWi$lNzkyd3UkPJ%+lVNh0890zcznla3Se<8p0y3=H1}U7{mJ?p;4gZYmiwpl{{Z|1Upe%z9%Qry P00000NkvXXu0mjfa^cWJ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png index d498c3b85f7247b6ad649037fa1efb814859c843..61cf46ac0dff4acfbe3ce37b9e205812c1a3b8df 100644 GIT binary patch delta 68 zcmbQo*vB|QMToP&BeIx*f$uN~Gak=hkuuTEQ2qDwZ}S_w8aijS^-5V}JxDMVU|@A; VdaCkPwTb}S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|KI_QR!`%S%8&s3ho%d(31`R`4?;~0Rz)78&qol`;+0DGb~8~^|S delta 154 zcmX@hc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 z?J?wQFyLW6ulbij*xTLic>K)DK1r{I(oQ@&5k-q!zMVANtD>4P@7gBaR2M~&&cqWM z&vz*=6i{fI{);i5q2veSf_`b{Wxdi4yua3*x_-CLy6>;>y~iJ>?*-b-;OXk;vd$@? F2>>KFI9vb# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png index 1d79a09045df21acb1298b87afe0e0560536c937..38c07275fe6e45d4fddde8eefdc9d7787d3aaf59 100644 GIT binary patch delta 160 zcmV;R0AK&@0pJ0UBoYa5NLh0L01m?d01m?e$8V@)kwz$gZAnByR49?{(jgARKnz6D z@AOEOdW0M=Ck&H^%?4wEm6S}BZ%P(WVu^J>IiC9q z*no>B6XOx!`|uZ_n?KM2qUmwKwG5a5g805zAE=9uYI%bCR+vBo%m>oeED|&+%KiWV O002ovPDHK)LSTaR4MA!E delta 172 zcmV;d08{_q0qp^hBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zYDq*vR49?{k}(d0Knw)uP=1t0Q1ddX{3m~*qCuiQ@T9opl;R2yEmL@HOS^L6G};Sd zh_SP68FMZgJBGZbh50!Rz#CXq`ORM0SG)@{an^LB{Ts5+oLpr delta 154 zcmX@ac$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo9le z|NQ@N&uq#l9O|2#kdTl9#0yt73Z;CsHwM*6{-suYMQ3+Vz3`a5{+hsr#dL zDes??UwU`3{ad!J(Oz<8&I99RtFM>}Op08=&d|mnGVOrWw&_5d89ZJ6T-G@yGywql Ciao9X diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png index 0a1c804de7d869b6974d6c0d778047a421d85d67..7e43bfc0d10d6a3b427907ed327087b2c1932059 100644 GIT binary patch delta 362 zcmV-w0hRvG1E~X$BoYa5NLh0L01m?d01m?e$8V@)kwz$gHc3Q5R49?fkUdI6VGu>n zo$t&0NnV~Yi3xe&4~U6k1koZOZoooIEi_mOZo$$W2sRdO!P4zm+6jUnK|^AZASsNB zjZ;l=@8QhAe~XqlC zrzZC8xfhLh&Xho{rpN1h=|=swl-S*W>^HPc(AL#z1=VUJ<%{pH99FaH@Yb-&kER2z z=N;y0o4ylPDyVh)ZhkbpnvV`D9rsuvKPkHIJ#R z_|5_p@pOP{zTd3nd(E5OwO+nfGHu%AgdcqMgitWhe*gf7FUQX&XbCfw38SVm{st_IQeqT$FEYB6&M;%$7L5hERxpSbEqn{<#;qWN%Qh}sMejp|h!n!58$k%7Rn#U3NnHssqd9m{ z<~MilzxkaOwh(KiRz7f6=kVd-z-=c0LO`y}e?`W>OeR+H(^CJga$MiH?8Lw7EVMU(9IzXKPsv-$t;e}5+*erArh%WV|xMY*b}`WUBJA_O#X<3Zz$nRJvs1@RWe? zs4+@(Cu~-i8jHhPXdyjvO~}-d;Yf%%vlb#kAj))olwcy92O56^!nW+;QM?rx1H6?C zEW124n5+g!q*K5c5dYD@L=o|*D58prAfg}&2zSE(scA%=F+i^azW|vtomt`-F~k4> O002n`MNUMnLSTXgFv8ma delta 453 zcmV;$0XqKT1A_#RBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zfJsC_R49?9(miWbK@`UE|1CdHEYQlwE3KY$I-NChuJ7F09sL`|X{_Yb723hFwWcY}u{fw=( zdga^IueX6>KZ)}y@XGPzc(zHDa$)v7m*!KFlgaYTa_1tDNYdT`u3!>UX&f?t?dDlZ zQ_gf+ar^T0N^~?{WS^D0kt^|&Rzazz7Ni8iIW%godCUFtIQd5p|{x#qSu%5JzdmkJ_00000NkvXXu0mjf#qigV diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png index 09424c08eb81a05e344d47e090dbecc5160655a2..b3f423af08638310b472bbe32814bafdda7f4cc6 100644 GIT binary patch delta 357 zcmV-r0h<261Ed3xBoYa5NLh0L01m?d01m?e$8V@)kwz$gF-b&0R49>+kiAL+Q4odC z%-sD;HoIok7?2Gq6bx1>S{OtS#6o-!5v+U=!56Sr!A4n&fX`u<+JJ&AF(%nui`|5% z1ot#E%*^>14&kTBJMzlrxqB;BIXDaF02T-{SQ%ikvML~A5G7F4X7|Efv`pQI-QH4^kh@9)Q4ogzf99Nx8Jg;;1M2qL5w5fKCndn>Jcl7Nk!+6z`z ziSJy|vV>`m$Mn&HG^7i2I0vCoam4^YsZm~)K1FZv)BoYa5NLh0L01m?d01m?e$8V@)kwz$gI!Q!9R49>^lCduXVHk&> z?|PM9tGEUoBoZ?li!fL^*_iwV5)&~COEs}bBo==J8^R=EDhURWh%{kBwRO4luI|3? zGaOA5iJWKn4ey)Zv%Ig^Rt2qf0<9HFN>msiWeXLCC?!EjcAp!lS9$L3IrHv;TLl!~ z7#ab{XeJbY2oMMa8iQy%V`nh)=CrlkcW5o;h5(~206;_`0D%VdcQsK`@Xnu0~-Xweso@$FPCBQJ_6g5!(@F+Vz!KHsuUt6uM^j6E+y0ThOxb9>urwO2J|lHdM$ew9TdT>)zXAXwyi9)RUZ#oSgTO9i358P*v1(@m!}>F6wzSRM~qh(#W}I zZyUw=dZzZQsva#2L1-g_3bb$1+$LgwVax$@JeEuxh8LnkB4Ub&02s|jkmhLjCJMk< zG{|fsLRZ{38d;i__Nl<|cyG*uJqjp}svsd#;t?DIB@ZOOi zo&VsW;!r&!k345)6v8zB&N{R1Il=AWG|C3`V=v0;Qu6 zg3Jxg1Hl7-yg*gMBIGX^nB0iyHV_oU2Q?dAb;3Y7g_O)D(kvvi|Ax8hC42W30CY2B z&R3jzB5HP%4o82W)7lNWYMI7vz4Ekpx34!&-twUtd$^=(nGw66cvqNm{h6(+3!3N6 z>zB31O*{?&OeT9`iKC%2x9G}xZBE>xD+Alkt=6kitpH;{#COuHX)6^!9x6G7l*D$D z51ON`0;53q?@>&9sc#~FIG8ubL(4!Guzct@sQ?qO0UdY+-ueEt@OdI5+9{>OV M07*qoM6N<$g80IrlmGw# delta 388 zcmV-~0ek+f1H%K5Bq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zKuJVFR49>!(!EPUQ5b;n=iCpyY8I0DfeDF3ElmwUOJhW1L(tyP(Adz{pU@Oe?a?F= zIkeai6i5z5(oz{Ar8gS7T_NyoxGF_lJJW&p$8$LFs$E$W;s0ZZ015<;D?f;c@9-DY zMB!nD3@Vx(1!(=JeTzW}bW4KQ^?@OOf+*5a4FBxEBY5G6}pi-5rEG2TR zrlNk%-eVQ#+HJjUwhDY#NeQST z-b$$OMmUu?%hXbpti+4ymKN7`fH`0o&=8Rx)}mXZQ;E~eg*jub1G7COA}IN>WJ)O= ihyWJg0IrC10KNe&8%k^!YCiW&zS3)pq!>TO_ uX;}v?my4J@2yNz9$Ufd6ec{^Q^|CDzaye)G_?H0fWbkzLb6Mw<&;$TxgEQj* literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!2%@r2u_~>q?nSt-CY>|xA&jf59DzcctjQh zRbK~TMkkHg6(GT~0>^Y94c5zWJpBDtAjiqm#W6(V{Mw5fIT;iLoG-eZn>gpXp0AtZ?Fd5wajShAXpFhReKFdvBFfMk&|q3sb^GXI*+3pZtT-Rhsvbf34aN zplPZlt`Q|Ei6yC4$wjF^iowXh&`8(7OxM6L#L&pf$k58jQrp1D%D^Dt3WFAkhTQy= z%(P0}8WcNsOap3=1lbUrpH@mmtT}V`<;yxP!WTttDnm{ Hr-UW|GHzU{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png index 6d5e6e15eda36dac15385b5669acce580ba3e064..eebfe3b91f39640ebc240a2644d8a942a55dfbe2 100644 GIT binary patch delta 377 zcmV-<0fzqN1FHj&865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGv;il70XRuS zK~y-6)seAE13?gmznRNkAsiN>7C9paDFnehhE*OlkB}mrq`2zdz@QdJ@CflpvO5-W z1Hm)V(jNw9i}~jNXNB+T0C&^r^dZl4r>ckus*0+TBncvdhyb810067&db!zbwhuGR z41f^At{0J3fB~!7Z1%ibtuV8H-L^PrW;@VNfRC~)%cg1e9GDs2`yIf0PtpPqK&z_q z!{P8g%d*rt*Phd?6#(GZ>vfW*>D6E`xJlC#5!rJRUHk+vz?WsYD2n1X&+~KDZCdX= zA%uewqSin&nM~fg-EP0v>z&1e#^Gat04zfY@8j|KrLOC&D2hwxTqinEICO)k4X^-S ztEze&jYd!N`CQD*0g0+6as&X|UrB*eAP4%uHE;oBzX3!k;DGF_P5}28Ky)K5{eRXc XJuI;eMf{uR00000NkvXXu0mjfEZM9x literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>8 zUk71ECym(^Ai=T%$8;bK*2@rcZ0%tn=dGuUV~EE2rRNO2nH>e%9+s;uU(UWUph@GP zgNqJ}ptk4au!HyNlhdcppK$Elp?hjeI}-FGI=Gf?-00cUUTvQJ@YrsbwSU@LW1l6a z9sMlYd1K$M7;hyO*FYA=DTOxc{!ePnE2-+TO8 zz$o0p|%ElrP z|Eq<=kT+^K`|;neLtQU;3Y;*C{&+93x;Qm?<4yxshZe5TS0<55k6q$tP&mcI$;nx~ zzsbOp;iquV;y>awOp)8dvhMBvcLnHi)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU( zWMyP%Wn`&sU}R-r5O9S-3q?b2eoAIqC2kFhojaxhHAsSN2+mI{DNig)WhgH%*UQYy dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(69BkXt|I^d diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png index 68871ceddf27294f43f97e6c2cbab13d5faafe97..2763880e9bdf2967b314aecd09661e44b80f3a15 100644 GIT binary patch delta 366 zcmV-!0g?XN1E2$t865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGsR1W{0WC>H zK~y-6<&wcl!$1^8Pb44Yu6|zsLU%2tU~$o9vT!G4AyN?+LKhODK^mcuPSco|OfoLa zloY4^0WS>94BT_yT*gyM831DpZQC9#d$(Gx>cL=e1-t^9o-XXh7~@=8Ym`!Zpv55{ zIHdJqp63A|A|y%j2~>dj18ACm=3us?TL?f|mMj*FXW-ij=o{=L)?5??X`1dQlSv5d zoKMhNJ3Hv!&U8AxS4u5`+&Mv2RYw2-tu=X`6Ncg2cs#xZl9L@+fR%_KA_PIO91e%q zzzdMM%m98}*N5_&reVEam!r|>aW+RbJoaU5@>D2nGr^LZp9PhE1t ziT15L;D+CZzkmV!Z M07*qoM6N<$f?<7~?EnA( delta 424 zcmZ3$e2aO4WIYQ51H;x|=C6PhQRD=%g{b0wh>g z;Fu1i1;9Aw*xJKD#v@M`#}JM4OZzu^F*^#h?YDkkTEq15Da&b*mAP+JZg?q0EWMbZ zsKgSavV4Ye0gLIAlF7UG&fa)p<8Hw<^`H2o-~74%#$I}@h={8I%hG3e=gj%E$duv8 zf*;JLk$t)P4tq9>WJ*u_DILwPa;h%!5~uVWA;u-94`*LLf7-f^X+hz#puiJ9r_M}j z>NvGFB6&w$&5Oy2SDCl5dYN6Seivh~EPzu@4=65GEIi@@@i}l~H);&AX zGRddj@8x{U-MbO1M!E~+DpGB zOS}d8SGB}7q9i4;B-JXpC>2OC7#SEE=^B{n8W@Hc8d(_`S{Yet8yHy`7zA8l&_dCW io1c=IR*9rR7)^&_=ZSLTBDa*#dz_2B>?irBcEbxddW?)EuJ)Uu?^vL38xY(DD1V0ni5W&6cEH=t$)Pgg&ebxsLQ0M<1g5dZ)H literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W=!2%@ZVz%W1DW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`0$SBdfgIbxnJjv*44lmGmf->7lGWzMF+)+<3A44O7f zEG|`_?13s&OI#yLQW8s2t&)pUffR$0fuWJEftjv>VThrTm64&9k)^hQk(Gf#z!e59 z6b-rgDVb@NxHTwt?wAJDAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ048rn@Bjb+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png index ebe042e97296a7b05ee2f71031e3f9214b27c374..70a084c58cc8dc1beaf3543f6e812aac1b8c3bee 100644 GIT binary patch delta 130 zcmZ3(w1aViq%0c)1H;~Z_vQd8&H|6fVg?4j!ywFfJby*X#NQfGuAVNAAsQ2tQx34` z@bK{b64#5dP*zktcmM=WoH%jd$dMxl&YU>|rca#c5ICO1;F)lxK{5Tn|Ns9r%Ncb9 b4>B-hNwd9_;mD8xTEpP!>gTe~DWM4fx1lrb literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhRgkmPy6ft{7V@vq&OHDo_*T@)UR6N8c~vxSdwa$T$Bo=7=U_= zbPddO4GcpJjjW6et&A+S4UDV|3<9n&XrXAx%}>cptHiBAv2({Xpaw~h4Z-BuF?hQAxvX}(6P49wzX=K5#@mpqa`CQ5(vLGLN@5ADW_)Mv pxHp{t0z%d<2gY`1Jc^xhR%Z$p3p%f;`S9G?GGFR*j@ z7IinW6#kqQsGXKRhtq3Hkj0wWw&ELJXjG=_*Zi0{VWz>eR-5-GbES8`6Xwy|x$G~{ zFx3**h?11Vl2ohYqEsNoU}Ruuq-$WNYhV~+Xk=w%Xk}!nZD3?&U=VPHK?_AgZhlH; zS|x4`ik&;A0X0a1YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;uc GLK6UyPg|1! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png index 8cb90399455c87336899e6097e512ba72af5be7e..1ea1710389d0af614fec4be5b6d0d914709439ca 100644 GIT binary patch delta 127 zcmZ3*w3Ts!q%0c)1H;Myzc?VpS>O>_%)r2R7=#&*=dVba_){a?$2>8 zTnAxBCym(^Ai=T%$8;bK*2`dF-Fy}d(oDbBkTH+c}l9E`GYL#4+3Zxi} z3=EBQ4a{^63_}c!tc(n;j4ZVcjI0a{0PsvQH#H~TGbH_BG21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0sy*RQtJQ! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png index c3200aff4e60ae100e14e960fe4a4afba18239ed..1fd1527eeb09dfcf3a3f341cd66237406168b239 100644 GIT binary patch delta 331 zcmV-R0krVIGkpU-v0SZY( zK~yM_#ZfVCgfI}CwQQd)ID;Ebm>wFwlC(i0=&CgQAZ5Nlnsj`Dj@N-xAkZO&%PCE^ zvaFfenOWe!hyH-4+xMda1c2(g4y&qqiK6KFbUKwnh|41a1V9eM&^YHllu}M91t}$@ zl)pxxqA0?y>pqhtxf){-1OcRfl;E6$F?Lsg0O)ZXzp^ZA;yB*Obd#Llv)%XoTbibg zwH8`y2q6Ff-unea1a>4)mSvLX`MWU&LI`lq;l1C;>-;1@0A$;?uTd0TwAMSzJK%u> z0&sTDJt?KO&uN-=+ldI?`@;^-*4lh6%zKY%ng9UvJcBW|T;RX~3xXgb)LI+P`L=D1 du@Zr$%x^VcHJ1-av|#`M002ovPDHLkV1f)qld1p! delta 404 zcmey%bclI^WIYQ50|VD4we>)XDaqU2h2ejD|C#+j9%q3^WHAE+?{yGnbkdkz0TL`L za7+i%0zk~muz1zM`#{DiPZ!4!iOa1McKb0U3bgM3X}tU9{8H02PYuO`eufi|9J>*C z`J+Oc_=1fecr`fQJ1l&kn3$aI>a0<+ePeyZF{hJpN>-Cso|`$RTcW=IH@iDOqY_6^ zgF@b$`NuA9-QT76Wx9VXkN)(Jl^u%`wz^vV`}ptY=d0JYZ7n}N%i!Xxhez+_B+E~W z%-eZYwWRF!T(t@(hBb1*G4`@&A1k>0oR;@Z;EwO5&B`nb*PIW%^ZW5^21c&3>hP&@ zEl)}W80rHU+L)IpJ&aO+JMUk?>EBFA$827Qu5}Rs`b)LMHKHUXu_V9nO2EggJS27X+RBVIGm;on$0XIoR zK~yM_#gIK}0znvtpV?ibu33$Zg$-HiUHbig5QgC`a8YGq0Vwr( zRzfVxqE@TXZnqf@hxen=s831z?!Vzb7`u(ZQ)jE< z!VfGFmo67EB&8qa^vT)Nc-=tpqY#TB8<%yGvZ&!ZsS6u^N9vqx`e8hI<+HQ1C57wT zKl{rcc5V35eQI}oq;J^cryGnVbf*4IsJJ%Ebp9TH`ReD&mu!OdKR13``JLxsg}4# zl%yn~>+1H%wQBP%0ADoc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngBaz BqjvxR diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png index 49fe22b335f593f65c80a3334818cc9a5fd00f23..c76994a6728fa41ec14ab479e1ca5c6ddd702f51 100644 GIT binary patch delta 348 zcmV-i0i*u-0*(Wa865@y006zd-kbmc010qNS#tmY4#NNd4#NS*Z>VIGM*$~)0UJp~ zK~yM_m6E+`!!Q(u&(*bv5@J=R6yz9!*ANV*(4{y_mvr;1WXOYbEM&>6z=x-KrU+wDL^`+F0AK#Rp9jH0OMcDo~E3_6|8nYnFj2T-2pqaX-YN~xje zc}F#`App=|FnEzt4qey%ml*&U0Bts#_wjf6vZk@l3T6yeO=d3N?mQhIIyiVs;bPg>?4lj u8*A-Dzu*7U3a3Z_@p`@fJpD+QR`>>(Xf#)GZ`Oza00000z%d<2gY`1Jc^xhR#m6dZcucy6z~pyBH! zuds9HiQFgm4eAc)>`eMAe17W2&lf8HFgxY0FTbqMVIGQ2{4^0Tf9@ zK~yM_mC~_F!%!5)@qbI8b;#1i**6H?e1qVm_!1ogq3&WgArFu~LYG2T$sBM91zp6U zAP7PT9g^EixS`y8U0M-buHX2<`N83wfe^x4YXPvyf?z`PRllZ#MNr00000NkvXXu0mjfc9EFf literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhR@+9A#k=CP0;g!}elcC}&N0BhY2UWJPG6Z_ z_J8Ryk$p1nk$BDb*IRnG&Y5HT|6sil^UUsc9bUP0eO9YXcI>>(8MaF^KqJ?8jqlc= z1zQZan_LpOq@EVmHvj+qcLl0q88cYSfv!?5ag8WRNi0dVN-jzTQVd20hDN#uX1WH3 zA%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsW()}YwAV;WF{B*=!~{Irtt#G+J&^73-M g%)IR4VIGSOF)00S-w- zK~yM_m65+n!%!55zk72-QJ(Ey`T}1UReOsG|hKw ztvd^LVC(+`opZEvc6M~m_0IQyKXALE2>8 zUk71ECym(^Ai=T%$8;bK*30m(yT=a5nds@_7$R{w_w+_Tra%GK3&yXHWN_3qa&FwX zdExZ>?TZYwAZ${y2E4M)FK7R}Hhhk?}+)wpk`X$ElXMMwFx^mZVxG7o`Fz1|tJQ zBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4}a`RI%(<*UmQ0&|>4X8m9WJ7R%T1k0g mQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT& z^Tze_%-hYyw&CUjri}ZX32gcYRuo;H9rBj{12a>#*(aUNSK^TVN zr@E&nnq(4!haf0|WTB{8xpAutuftn%=|#Bl3Pc1^5Erfl1r?GQGRA>%oI`j0E;@q? zXFM$Z;Detk>gBDfHEHYU;9L2ey|DZAZzEGmjb>&dFz$KJ#tMH?P^16f@#exm}TVxKtl2I zqvrmt*}e6Rs;js8lO0KlkRr%wApn|5tz7B2boavXRcl)mr)W;p>)hHbF_>SYdHT-q z+IC#Oar)?-VvVSn1e2!iIFOvZvgWYsL(sVFSDA00000NkvXXu0mjf_Vvc% delta 433 zcmV;i0Z#tV1MdTnBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zY)M2xR5*>j(#>j9K@(bQ^D zk4Rz~35~ei#}N^+!x50a{b*mmTb2QT1wug)er2czzPJCy?s89=%#eX>%mYoJ;on@F&^h~ zEp})9zO_fUqN|O$ld<^~;-nlSM*J6c z)rZ&IzH-LWrDY2j7R?JBSCW_XZ{+Px>5AA{8wN)s(#}C b1HJ>s#-zD{^QyuC0000W diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png index 639fc3878ea5d5dca14cf5762f9042e6314cd98c..3cec3cc27249238e8865fd4cec95e7d74074b083 100644 GIT binary patch delta 391 zcmV;20eJr91I7c8BoYa5NLh0L01m?d01m?e$8V@)kwz$gQ%OWYR5*?0l3hvzF%*Tr z$UM0kAKiybZ~?AE5quH!#W#Pz4HPUEDX5e}5h;b@FLkJ;woGd~otl~4_>dHfPP+lm z(@k>oo!mo|^fxRhFcvZc+M=`pEnoz+Cb=o4t6QuC_dv#+0#INrhy@Xp_!v}sOoo*8EUQz%?xg)4JbzI{|nPm_Up!LXJiDDGf1jhLTlFd#6F%*SAkQeYld;}lEXK>+CAH$6s6XVhtb}rS(%AXj*iugCiAR&YR zBRGr-%`e5a>vPP`>S03)CbLdkh1UrR3^*%13($$ZER2U0?=)_gTZWSO1xbM*b##w*@%28VE#r#AHVp zc%VlRhY))>9ThC^a(G(f05}I+?AbD_(C=KT8<*i#n?bcnd#A$jSW!-#U0{-R^t5uo z2Ji^zopr0K%{ov;Y7A delta 84 zcmeBUoX0ppMTw=@$uool2x>S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|Lxw`GmA0` joAOGV7F;=SFiC+Sx1Bj$B)dBlsE5JR)z4*}Q$iB}lsXpa diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png index f19354d8b9debeb3b9da8fdecedb487288a22a0c..ecb8de13e29d00f00686754ea4cc7cef4cccccf6 100644 GIT binary patch delta 133 zcmcc3c#Ls^iV$akM`SSr1K(i~W;~w1B4whRMni=K5rMN4Ai}-VH`)1sudy9NKz7U;?A!g?)8X<$s72%&ua( l(f%xQ2jhzQ+oi6>-(vWy#1rtRTaEz)JYD@<);T3K0RY(zHTM7j delta 154 zcmX@cc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 zopg}1!GVV*{cxuBzuW_SYfsI}t99A2$3>vVQeaby!B3ZMD?PFfJeu2F+AOf8!7^dq zrtK$oDpZ`*{}GbV8}o>{k)dBGpze9xg}JA{R+aD4^P9C(#HU(S#TaNagQu&X%Q~lo FCIFe#i(`n!#J3lA^BxM|X}ef#9HN%U zrIx~!rIy%W^Cx(L$3s;;+xXO-7Sry$s_Iy9DCo>mU+v(CFs|p5%S;|M-CXBb-)f^@ z&v@?}yB(wc{&%cVx7jW&=iyfu-lVwGIer(T{bG4O=O!su1|aZs^>bP0l+XkKSi3jZ delta 164 zcmcb@_>^&iiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WrlRRAV4rkTAcs^Oq(c0+IIB&9&_wpA{4lSz{Vu}fnndE$`RBU}+ z?1q_wH&jxYnBNyVl>bz{@Pz+J1FLrRzc*}4j2C_QwNPMzobMf{UAx%WBONrE4H>>> Q0Nudg>FVdQ&MBb@0CBiIBme*a diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png index ce4a2357abda53c72c52e065065e6f53e012d5e0..64fa0e7c12a8affd27262c681fe56af55d660044 100644 GIT binary patch delta 120 zcmX@ZxRY^$iV$akM`SSr1K(i~W;~w1B4whRMzou!i(`mI@7ePkc@HQE9B{Dz^>D@n z+fAIh))yw}RZS}pLN1Q_J2vIUk~pBvu_~ Y-5MptmwlC$kpT!iUHx3vIVCg!0QoO3TL1t6 delta 139 zcmdnVc!qI;iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{W@JUv|;Lo9mN zo_7>%Fc4rlxbsS7w{y({m3W&EyniBm&TzfBwNhn<^eQ%y3tBUnx9;4ujOX5RF0-4< q+?#p(uCu*u|9av<`N@Qpa`q)tL<9}Y-u(hv#o+1c=d#Wzp$P!yku+cc diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png index 70e3cad6488456ac13e35246e92806d8e1d1f619..ef3d963d6c89263f9550239c6f19ce1238cbf948 100644 GIT binary patch delta 349 zcmV-j0iyo51DpepBoYa5NLh0L01m?d01m?e$8V@)kwz$gDM>^@R49?flDkdVSEFl2_(P8610Go z*f`Y`XTF(pGVtFef6&X%eo=q`a&bg(xzA}7aFVm>I2M&f00KDAH}o43w^`4v60bnM z2wDGE3v#f3P4GD2zFyD)jdiGXAZ&wM2Rljy2#|Xj^3Ys%`s{R}ya!+8;FOoY)~6OG*Qm85XK%`tV9f*iDi)3D=+_bB5rL}sRP6&k&cujDE zXc80 zJUET*6vYZ;+rZosBLPQ1mODt@A9GqRnI5e^I2n*nh~}VTAqtux5NFR84F?oUs-TXw z{P7OzgQFm>ovS7~5Fn@o><|QTWg=L-#Ux7v8zrgAn)ArlH)vrB_M>1+FZvTf?feV1 WBq$^yWb~K-0000T_4>~FWmlec?|sxuZK=2GlSAxGW-LTbuuE$r9Yy{mKWtPA5>M4==WWCO`2 z^*UQULQR&@+2_cdb7*Y`m{50{0Y{0^kYQr0CWa=PowK*~_Bh)3zRie<5E{oQ#n>E+ m&BN&#?J2V}liEMSKlB5Wv4fmLIG}I<0000ixy{zW&8!PsCN(08Dw7(_b>#QQ>%DK=8QL`9_GlN*e41LA4=607AKejLLwrK0j31<1U!Iu2ktc(0TX~o7ws*K0Ac)p^C3apJb3Dt z>w)V+&Gn}WU|Ga0hJaR}_}M_H?^Z7{^&{Xn;RxMrB&=qvMh34HwvH!dZMTvD0000< KMNUMnLSTX?HnCm+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png index f407cbbf7174d0c69426e7331dd1db7290bc18d1..8efd044b0c38f6e929c25a6fbd82f792815ad99e 100644 GIT binary patch delta 345 zcmV-f0jB+kULAmU=)U* z^Ch$-R_(>2Acm3_+9)^_9V~GX1R;}y|G?27;jV)?If{#egOjv^;NYxI{sIS~n;7i{ zZ5)!`P&DuI@g2_d9L^EOBRgwk4m~ccEF09eKnZ9-LMKRQkPy%nC_n^#6h7D{zw2_D zHl&7Kj>-XlVK*QFi0Zck3Y+fQGnPPj*>bSh05>nAJG7LdE;iqVtwkPIZx7niOJzu0h9twK#N`_;abss zd3>gGeow<&3Mw<5W{Iy)Nax}UfS%vRKYO6=Es~o&mDeh*cgW4f76A0RUD_vi+`2`k rZPQ<6q4cjnF`gdK+C1ho?h(HM!|^(95NZhF00000NkvXXu0mjf-BOoJ delta 336 zcmV-W0k8g;1CIlcBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z3`s;mR49>^kG)C*Q4oc{xw%)#^#>QSq97<%iiIGE7FIzlwy?4lAHdc(@dYf!T4HNw zV-wP7FbEn&jV!pLi8f=g%O;>ma*Ba(;G8)ls;XpCRX&oK_UR5`at`ZTP%vN(3>g@< z;4&^45U{=G&f7C`woRB^!u%o_0TGaY{6@CxqRq|mEmDaXX*XbL1tvr? z<0ZbzCp3K->NU8#87#m#$JF!;#psyk^l08eqa2UjY zPY6Pbg&=}LU5Y|M#X*N62s${cs7sw4I{6KXOCjLcsl^YFPhcrdiqcJdD^gLHiWN#) zUxo^?$=@M`6s!<$xrgKK;DHmby{%9RJfQ1=qY%dhrwcCNDX5frdE-2H#8#n#jqe6P z^GSLnAc{bL>)n$x#7AVw+@zFSCm!Vb4j(FDkw6}wfa!URn7**L%;{m8SwIIw8<-b< z!x)9R6fq-`*hz70?Xn2y+5qd{hz>&{Npy&@l_?H@$o~rLSGd2W+MvFg#{@JzboluR z>W`c}P}?Z5|MA5Y&^lCeqyK@f(&UA^L>xe!7MZ8S~Hab7?zRIm^&1hMulENuiq-^VURz)HKb z619l22^KjpLZU|HjGJAHBwPfG^M`@?XP9po7-2g51_SgpC=K5lz7+I^zONxT=h@lB z-a8|e&LX8`q&O3R6vWwgXz1>7>{TD!h8IeX|2EExiC@qoxykVlU z#YKYs-KNtBP)dyfk|;F|g#~Q&gbWUeqUfK1RtWW5 zY99seW{%NXGnsh!@d26*u3lZj;wdY|MQqzn2)Mt7c8iO*b$ZJutoc5!(l1CuQ547V z@4fF1^@(Loa3Y8xVlZeE?87Li(Q30AEg~j^CX2;jGYFPdG0Y$iMO1_#d+3v~F%;Ro z?_R^(!+&^p>iO_H=fDxRzTgmm!&?df>qjZHu4`HfwFM!-`L#kjAOVCQiZ_#*Eb$+& zsDFTPfb^z+DjM25@(VU~*Zn$)XP^c_4gc+$DwqfWd2~Sq6G8Iw6D2X2h=X$;#VUuv zafR~oG$Z-m<|twSWDnRD=sQZcR2TQzv5wQgTH>o3C-alcg{m=x4559`<&%9b?y~i+ zDFN5nAh|R{;dPrEw}*S!ATH!t115m*_qDn8B2%?3P0F)ltN`OcUxvO*0px&wAOKoG co6gI80xgqW8LPEb_W%F@07*qoM6N<$f>a8X3jhEB delta 354 zcmV-o0iFJd1EB+uBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z9!W$&R49>+(7j3nK@h<4|Hk!5#6!h2HrYckCqUQ==82={$g50-gIm?N^{*10Z!%U-OM?{6($- z{Ti30h?C+msl~$!YO}jw%aC+DN;+W66zhif+&TGt9%ZeS__K{%9WWn1!So8)SDu?$ z?iUJdZtY-#=9}ix4N|sf~W&i*H07*qoM6N<$f)eMG ArT_o{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png index 7bd1d84f96210f506b40923f10ef8c1a2a308d8f..c27064260bcdc497b9d02283fb391d34243b906d 100644 GIT binary patch delta 136 zcmcc2bb@h$iV$akM`SSr1K(i~W;~w1B4x4?qefP!r;B5VMeox~2RR!81eh;IMtFZx zC`(t~mXO`VA@^^c?-@q}RvRYID;rIdCh=WX*4(Oaa>K#&9SL`yHqBY(UQ{d76Bkzc ojG;_=4rA^s2DJmV-}irFa(yWhwdq9ACk7z!boFyt=akR{0KphGMgRZ+ delta 275 zcmX@Xc$sN}NQ}kxTlL_h{frxmkk9Q90XVnTE3dl;#{+UQPjnwv7_bxDtjLu?FEbHuBg>L zqN>Gyvf$_ve#soOA0?7|az1Q3XrB7PCZyh=;VhfD!*4$Z;|fN%sk84b$*OOVXQ`Gb zO89({8EA)UiEBhjN@7W>RdP`(kYX@0Ff`INFw-?K3^6paGBUI>veY&(vNA9TxWb@? gq9HdwB{QuOw+6+|9n&V7X>c-ly85}Sb4q9e028@cK>z>% diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png index 5018dc60a24d9feaa5276bdf6c53d3e3d97802b4..4d22f79c1686731247507ba865954266790dae11 100644 GIT binary patch delta 407 zcmV;I0cig21k?kNBoYa5NLh0L01m?d01m?e$8V@)lRW|_e*s}hL_t(Ijn&c5N*hrW z$MNsElbMOZ7&K@%icnm%w7M17E?oKyeXTx(8=pYB5d|MX3YI1*{z>8(Cv*QC7dPUf zV``Tk_`&6J&*vPt!r#>ZcFNto)BJERrIkSH_%Z@9$8B5q*qivU0OTKxur2dNPnkVOPWvBm-zjiLl%Y~yYNQ>pm=?^d1 zjFtIx`C3F=bTYV{msD*N(b(`qf~n&9(j+nS|8=Vw*E({C97$Qpukm*JJpTfDU)2VV zAB>@j^BEbstdBmD3)c(LdiHVk$?Fe7L$8%G`g4a*e_i?gT2%;t5! zTb=gRKaxL}W^`I6Hv3#rz@>l-0UvthY$`t4GaczU%B&am{{6LSo378!k#%^+_U?4S z>%(i)i`MzP*!<7cMSH1S!`+>i&n(gxn)&$;V~}U}ygZKfvl5J-R}w>^V?knlzmw#*G2z?e`iag8WR zNi0dVN-jzTQVd20hDN#uX1WH3A%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsUz$l}zY W*tuicL^E|R1_n=8KbLh*2~7aT%HZe# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png index 994743d0c35fbcbb3dfa3ae441e0e8ae19b52d5e..00d2a62557ee75825ea580d6dfdff0e7c2b62ec3 100644 GIT binary patch delta 397 zcmV;80doH01j+-DBoYa5NLh0L01m?d01m?e$8V@)lQ9A(e*srXL_t(IjpdTRN&`U< zhrg9nK8=mw`}ihyieMvXW2u6b*rc!%L`4XqA_)FT;7ra$a>mQ$a(8<(7Q4hKm%M-j z!_F={-*5KE8aZB51Q3N>p%BbiATOa*NHWrs%VP2BVgIpTIh~t*(6s_0kCvewdtJ67+%JLByR!A1)9LKZyd~1o(3!d r1u*iU*zYTUUKOCm&%fhO{U72RLk{KW$N|#T00000NkvXXu0mjf{}{7r delta 550 zcmX@b{D@_ONyvhP!xZ9? zb1jlP<2R!*(=mtJ&z)9EJ3I_%4WC^)XGV#fW5X=>2mF7RmSxLx+-(SG-Z=9h$BRFH zR(ADw%HKHc-6ttg%kJ`yL!r_0!Ykn4ejHW-*vuKWW8=OY4nx zGZ?o%pE%#jkFhS&e(9(Acm6Y0FgKt5_wA5m!%tx7tCqM%l%yn~>+1H%wQBP%0ADVO0|RG)M`SSr1MhVZW^~e+T>%m-D{xE)(jq|2 z#ZX=)$_Hdfd%8G=Xq->}vw!1LduCBaVN+gd(}F7p4kjruSlwiH7d*FeB2bxXiEBhj zN@7W>RdP`(kYX@0Ff`INFw-?K3~@FzvNAHXGP2Y*FtRc*2)M$ag`y)jKP5A*5?KeT X2F1=D(BU06on222ryrmo|}Fu z_k!#Ww(ZY+>a{aOIUE*rc!b2+q#xUP{q)_pUZTYjUh}(Blek1Ly<+_k`0v2^M!sL( o3%*M!zGv!{>$mkg_(Haa*UU!Hiqo|~lK}`kUHx3vIVCg!001d8<^TWy delta 275 zcmX@Xc!_C(NPO zi{Z`da0wtI%+tj&MC1J19#5_Y0|A!R?Jj?M!yWHGTwNP{%UMK;gR4oMyDc+K^X4+w zASSl{%cqQ-87voYzX*P7slc-8b@-pA{Cd`1J>Qu)-$WfR{^;!Zv2M-hHHplkX+pMh z*mV1VR;ZS^MwFx^mZVxG7o`Fz1|tJQBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4} fa`RI%(<*UmQ0&|>jbWm>IwymttDnm{r-UW|P!w1g diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png index d538eea05ef1f8dd4163652da56db18c4c52aa20..08b3a53ae51f2f915e3468a1e739007eba744cbc 100644 GIT binary patch delta 145 zcmaFBbdhm_iV$akM`SSr1K(i~W;~w1B4x5ZqegL@r;B5V#>BVhtoa-gL|h&g>z-oD zbx#&_$+m2%cXNC=wc?7O<;lNA&Y_7i3eHA6oiA9M6O23puDRTP;=taMbE;wPO zi{Z`da0wtI#nZ(xMC1J1iQZhT4m>Q{a;Jo=q{{C(9$b37(&EzFB(XlF^XG3h30#`c zG@;2OC7#SEE=^B{n8W@Hc8d(_` wS{Yet8yHy`7zA8l&_dCWo1c=IR*9j37p_CGbH}uaW*VFfp00i_>zopr0FU5duK)l5 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png index 27c7d02b412440b51d42af05c3322c4805a27cb5..9900f8bee2b9771716b89215a9069d9e051e16de 100644 GIT binary patch delta 129 zcmX@bbdYg^iV$akM`SSr1K(i~W;~w1B4x59qeilyr;B5VMeo^5yLlTNcvvoOe6mbn zi{okW;3H34YDyAj&1lelklEC_U%w&b;H+mx2UB8w`d6$y+4?=PO6C01rmyq#JWjUq h>@Ik3B=IWy2LpSKNL2mC6hQ_c@O1TaS?83{1OQF>Hc9{h delta 275 zcmX@ec#3I)N+%J4>=0 z7*;l!>Sq;iTANoSyZg_Fy;s^j_osfSPN^@raq_UA-E5w=S09-dZWE1Lv8U)R&}h{X z*NBpo#FA92@ylT2KH0 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png index c5e3fc3b18d9f4f955f2dd4e7755d0a9b5046b7f..12ce5c81e7e4c29ed9126294767ae19b6423f819 100644 GIT binary patch delta 357 zcmV-r0h<251fm0wBoYa5NLh0L01m?d01m?e$8V@)lMVtWe*rH^L_t(2k;RZbP6AOB zg}?h|<~fgHfK2!`!pvxb2@uq%6>HGeMq*`YtSxm5HtxWMxC%QLU@WvDAU=zk!UB-k zc&l5S^WAeU{P)No^zw6G7a)LKMN#p(lbl7KJ~bi(?MP!CfB^b=|8U&d(6_$Po5W3M zRv2TcE(c>qJ?Qly*#%eS3c+0! z`)M$|i~}=f)Q9d4Y$Y(Cg3Zhb%K^v6)b~u`hG7cT64Y8Sn}8Bvd^Wa-@a# zSC}Z!0@?vbfmqZ6vkIUXII4v4^JnFq9Ra04PO zmtpa$gZCL27@a*`978nDFP(JOi>XlLX#Mwp>2B$NR()jFy>!9IFgNIe>ld!Ki^4PH zUAoO|UDsAM+*5m@+Qp%?;>4NEhc3ETxb*MTpKUFEXZbvi^YDa9ujfw8*XkLSln#Xd zpX=cA#UQ?5{TzWUBv^nL`q>7r!Pjz%E9xPAO77$!%;rD0R z&eB;$$;a0`k*Sitkm0zGBTi^$S!+h|8@m^Co*KOr{#E*d?E=q%!bL1;=?Sr+*}He{ zsCL=U_qLvGjd`L;%XY<%h7&1Ff)@{b-Ne4H-f?Zl<|oc8d78xoB)1Drc**tVb5ZL2 zlA>Ne(ImqJmgaDSo`VaU{1iI&?2bHrYvGe-!w(<%`pX|wCU9GbMR2*PYY8ZXZdhwp zXH+#)KrZj$&4$GZuOnJd9SOfS#c-zU?Z~74|7S3*y8o}Ve$GMlTN`xk9`AbN4-8t> z64!{5l*E!$tK_0oAjM#0U}&UkV5Vze7-DE-Wn^e&WT|anWMyCwaD_n&MMG|WN@iLm oZVif^JEj3ONP=t#&QB{TPb^AhD4*yd%EiFo>FVdQ&MBb@0IOs=ij&^_Du?E!`dNd0qq1zXHt8 zhT++VhdPw1e+0g)-21`y_|?S$5CZ0B;QYkUlPO zmtpa$gZCL27&ARx978nDFP&tq?~*9cHvjz`+osgRySzJgn5yWpa@spTWY5UhDmAsm zOZ{K7U+*ohO@%iDa+H)d<=wn}v-sPax^$8HbkT_IGs@ELRX&>=sC20Q(2sEQ1q{L! zhXsBr2YD<@fA{h0&L6)_*8g36^jqKEx5wGtUH-%io;Wq>!=&aC#&`1$mg+yMtWNy% z>5s$(dqK^eR)TM2o)}HAX#Oj4$F6eQ>)f80BiHk6&j0mu@qA?9!S#Uqj#}b-hNSB@ zsheKse!N^Cy5Psuj>hLs7aNlpZP;(^N+{x4)|R<;ZS=jD@^jWo#NKr|)taztTEhYH zjJ(Eo8ayRY#k;ncPUSkUwRGNU$?OHP8rA`N4lA7!L-=ei@=t7Acy`{s$^$`OE6+2f zvU{0Tm{~-gSgtsiDY!AyDSS$ru?h2)@D%$s6TH}NL@jvIT>rdzb#oA_i}Z^vYXTK` zQtX5^4g?%@ac)f9Q~x2OMQ!ym{iHUj)q;DN&hK45fBuuDvcL#XEpd$~Nl7e8wMs5Z z1yT$~28Kqu24=bjh9QPVRz`+aMwZ$JMpgy}0aqBbP&DM`r(~v8A~cAg>rm|6F>Rum QIu`?jr>mdKI;Vst04inVRsaA1 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png index d1b1f6b6459ac7d90d94dc2499f20cf3dc13909b..7e332b401e639e9ae497367421476df018d91456 100644 GIT binary patch delta 360 zcmV-u0hj*c1Em9yBoYa5NLh0L01m?d01m?e$8V@)ld=IPe*rQ{L_t(2k&TeeN&-|B{&& zM^hom7Y+wLzV|ujeFgIpXG*0m^M!lI3LkUofdotgB9g$8U>RTlQi23?)_mc*+4FSv z!8VOUDmf5pD+d&^74A7kNAiGw1nr=}(t8wAJzf(bzXK-4Rh zk{gQFEERF^%8-olr$m6xG?fX6TsV4V3E{BgE;cWa0f@$+_p+BzN2<}MFb>?LNN`T)PjXJl@My;C8tgN>CyL|Ov zGqW@Rz#l^Yy7}?yB~&su^!F({{{rSK1s~|0yw`7*E%65PO zi{Z`da0wvexu=U`h{pN37dLt_2MV-4e4n@Jky6Bx%_6IBbWHNo$vxt9klmmuqI2&z z#;q?5Zofz)8wmQw$UJKrpWaqX0`e@hc5>X@SORX-o|No?8WwP{5y81XU}v} z@SWjtqHD?CT@wT}_-2-WuUNC$!dvLm1#@Li=C}3@e(i6y&Z=prrg`nucXM)jA^BKA zg?)?tigzEbrj<6n)I8kPoY_CIA*%P9w0E)cnZ;9?{rYC=7k~Cy{FUE)V+8tLJdAn(2Aouk`x$imIo(?8FjY^uD~f@Vid%u06kQv;F;b=Z?hhmV8zr(|~O+ zT!Vq0RxNRjC`m~yNwrEYN(E93Mh1pPx&~&t28JPqMpj0KRz{ZE21Zr}1_4(Xv`{qU h=BH$)RibDRMA4zxxntTyGj%Qo22WQ%mvv4FO#p^>q~ zyea?^GzdTnf6$B~q}N-XB{3FUHIg&=Ts)rea^Hdh8juB#ED(-_QoB>J>+?)z1qjIBr~e=_0gGuuQckajqesB_{{+@M z+*dJsJ!`XU8h{M=3TmKafoXBm?Nqj_<%5pvJ^(#`MuNLCG+N}_?c!GDdEbRcpb7N- z30_;A+HY6cdd&bzKpXFCv_Aomt=Eo$C!ovFBYgqw)nez-uhruK0000PO zi{Z`da0wvev!{z=h{pN36a2lI5(V1le_uMgok>~6s)M7O{pPh@Ef<#hD|U9&`)U4C zRNB=Qzu0@eVv|h;$8L?3rUji!)!bJ~t?GBMmj_;|GcedM`Ajlxip_m)CJXNw`iXiU zHaE2xs5ZH73uNCj1Ue3q)JI*?+-~O;=e~Cnc3(KD!X@AM_shRH>D}FXC^wpM13|m`}8=0~8I|EOy)HO@@sYZo|KWr)c*LW(; zpyn{c{-2xN>a!-kT?q^T)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU(WMyP%Wn`&s sU}R-r5O9S-3q?b2eoAIqC4($Z9g3YhrcE?c=VD;+boFyt=akR{0Ew@oP5=M^ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png index 313e2db043272ac86789785d3cfd80ee2a7b1a25..8ef8a7a23dedc5b1edcbd0a0af5a940082ba5eb4 100644 GIT binary patch delta 352 zcmV-m0iXW)1DykqBoYa5NLh0L01m?d01m?e$8V@)lgI%le*r2!cPMr)N)4QBw%#n|F&F&>H`2;%Ct77WyirVz_NQ# zqXOj;NA+qkeRXlBojf*j+au0+{LPyrHVDxH@S0G%CHwMpzgch(C7f##YWcQzx;`|# zYI)CNm@z22TzbvQTERVdl`;!l`$mzicsyC3U%XLELK$_Jo~tFJ(On<~Sp0beV=s}I yDbFtCR&09*m;y{6`b`SJ0Ahd!w15w~ukr;9vtdv%-X7Ti0000RR9VIi(kBHyu5CkS9riDKkSLaLR>S$Lkfdw2~&X^S!I6yHh=9>F4A?1+!L(8#Np{ zmzH`KSa_B1G>}}XQU2vMLl0{ZU(fLcKfagEUVhMJ!ohOpVJbP>o|J5y@YBcw*Y|Qne zllJ{vT3^XBkDc55!wbP_UNP_9Zwy@j*n;ncwWm_9`I4=rdvo(%uDKc{;%Z;YrpjAw z`|?4++_LCGnf~xoZqJ_xU-s&av+?$P2@DF=64!{5l*E!$tK_0oAjM#0U}&UkV5Vze z7-DE-Wn^e&WT|anWMyCwaD_n&p+Oy}BR4-KGp!Q04#mzL( -%css-style% - - - - -
- - - - - - - - - - - - - - - - - - - - -
 %time%
%message% %name%
- -
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm index e90846d72..55a549564 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm @@ -2,13 +2,14 @@ %css-style% +
- + - + @@ -18,10 +19,10 @@ - + - - + +
 %time%
 %name%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm index 66a16951a..d34e49b25 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm @@ -2,14 +2,15 @@ %css-style% +
- + - + @@ -18,10 +19,10 @@ - - + + - +
 %time%
 %name%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png index d9c28aaa7b247bae8cee3a07eb28369417012ddf..fa45de4abe17dfbd593342446d1065423b4479fa 100644 GIT binary patch delta 142 zcmV;90CE510nY)DBoYa5NLh0L01m?d01m?e$8V@)kwz$STuDShR5*?0)4>ryP!NOR zKP)cK(Wpdy&Z^K5rD(vgPZPOG0pCn!H(HOYVoX#k2a#Tncv4>QPH*RU)p)@&n8B&^ wW^in+pyutgUPZv}1{c8g-vTnGsRThiIEY))g8x_|)XwXr!6a8Q`d0XKffA={&!OTIu>?xg(nzrs* zTAX#2^?BgBJ$)~myo-g8mEC*wl%;@CO6maL9yN;uwKsQb?aGhVH^`p~;NzOYmk6|$ Ofx*+&&t;ucLK6T((mikh diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png index 8a3e85ec3cf4ec962b741ef200cdd2e943363064..68de5c2964e82362df65d4966de59df42fa3a3a1 100644 GIT binary patch delta 419 zcmV;U0bKr*1mOdaBoYa5NLh0L01m?d01m?e$8V@)kwz$gZb?KzR5*>*(7|gHQ4q)R z@66k`yV>n-!IA{4qQQWIBE8syJ$Up|=zry(<-v=d?4^P?dr+&;79ve+Hv8Uq*yPlt z>d_wzGcfRB7~y&n;Mw5yyZ0}jkA0pv5{1k`rd@e8oPq$l0st_(`gu8<1rRVZf`QTX zU=R^(4PZcj6VASzoKB{gfgzYd8-y%!icdIV2Px_<^mc6_kjUW{SB~;0v@OqRRI29faNu^V*a1=8j(oJhqK@`UE|2gw^=ib~D+ggpZVu@t0*jB;48x^VF#FehyyA}KxS`c@| zonR3JSJ{XfsTw0znxwSNxM-A;ai+YMt4pogR1q)& zUK3u0V8BX31q4uzCINf<-#@+I8SYYlctdoGvx+r>NCJU`Km`CW-0N+&xB5e(gXkc$ zf-_)5I9QORdV>Cb@5AfOuLHb7bcSFRZw=NOj1g1>6+H^1gG(81KYRGJ*LnNpWxGq^ zgxo2)Gh|K(PVwVfRTXwegRRbwCl4OIYJVPm{MM%oLiA7sL+%aHE4i-*MnHFe=gs=s zU}J6l@rw@cy4#dNsRgCX4E1QKWd@mi#$OQ;1!holrMz+HZoYDRWvO*iSC`LF1T(Hn zH84gja2iS7fv=(fmIql{a z>wg3$>J&f&SOn&QIbil!z{E5t`Jo+;4NO4t`}nWGWUBtb{{wykY;bU8Q|4Rw00000 LNkvXXu0mjfhTzzz diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png index f18a209e2aceca343be94459c34d56301601f01b..db142436459a07044864026b63ed4c8f471e7ca4 100644 GIT binary patch delta 432 zcmV;h0Z;y(1nvWnBoYa5NLh0L01m?d01m?e$8V@)kwz$gdr3q=R5*?0lEG>dQ51&1 zlP0*(tv-iK@!13^_zt=gK@p1JvVx1+N(!xQ6&KY|H9~7_QpcppOeT{%_xvt0O2lbj zz<+fv-1GhC{2aTxmq zSt#*hl2zY-{!z0OxPvf)pcJSA2qPKg_>bcrFsI`F4Ty##f*`t>yAfqbLLTXzO$gnC z10b&j6uxjQ1*IDEg^gTHdqu>8nRifs+e=Gq`@W1t!1<(b+vpXn!~(d%NBl zKU=*IyaPsc%>d0-)9DXqeC(y{e;F|z^k(VC!<~G4Z4KDE%pJgP+-pbAeirexdtP+5 zyVJerZRW+B%K7A?^#1^W2UWrY;4ARCYCONpc^PmM2*9)gO{#b8<<$Y2{64&emh1mP azX0|kb delta 480 zcmV<60U!SE1D*tsBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zn@L1LR5*>Tk=;%cQ51#0ea@i9$StqoGx!d^4_@dS@C?L+aAOQ!7zqAFg*4TeU;`Gg z2rbi&r5&cznVy;L#TgBh24ip~JJ}a!t#7X!S*-n31xf{{LRLUtDtRds3WFr$^@p$H z?xP0}fj2;`s!F8*KoJl{Py%aEBUlxG6d{Zz6unjiq<~{efqE|>SOGC$5fo5hI2z-^ zgElY#+(kM-V8r;%;N9ZQB7!SQI#G)2G@C#I6jv^o3k>qdD;TjTiV;|E^oUyD2I>2i zS3q1HbvfYfEq{SAf-wSs6=Cl*p}rTE@#>T3IvMX&6|M%{yJImTh~NikoWwkT`*_Ug z-P14me(fdD1k&mL0Kxoii+C_eRrOx`Z8=Y{^9LRnH#zPN5C)F W&)urfDj5&}0000S|Iv5xjI14-?iy0VruY)k7lg8|diDm{GITpX)*)xkW k3Y+pun-*L-a4<=MA%KI~@5kp)9zabDp00i_>zopr0KDWFZU6uP diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png index 346d6e3d65762794cfe71cc1e44b422e753833ed..60ab43b8983ea6b88929d821253f174d3cfceb79 100644 GIT binary patch delta 143 zcmV;A0C4~40nh=EBoYa5NLh0L01m?d01m?e$8V@)kwz$TT}ebiR49?{%rOo?P!NRS zf7T0e0<{w;oxtJT&AXCOJdKbDg~}u|*=+HNa}qFgb6%#gCx8^D3DH)j4w1qHAVFLJ xkMaYb0uqSQH-Noj!1&_=0hQiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WLQaxQ9Lo_D7 zowSj&!9jo}{k{AjAs^l~2ibDYJ?eRT%=E*=eiwnBn20{>8;Q-6bE7=H4&2axZRXF+ z_{2b!HTKOEktYU>3g>>h*+0l`ST%87be+`JvwRZHpRKm@<}_!$V7eNsaF}stx0KuU TDcMCpXE1oW`njxgN@xNAb{#*O diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png index e876448fc04de5e260f29a18c47b803dfb1211c1..77934e9d98c4619d8a4c58a35c92e1e8ba31c6a6 100644 GIT binary patch delta 156 zcmV;N0Av660o?(RBoYa5NLh0L01m?d01m?e$8V@)kwz$gYDq*vR49?{k-G_iKoCUV z+LB;vh8AW8f`J_v8yJhf9Rod()4PE0000< KMNUMnLSTX&=sVB= delta 183 zcmV;o07(Dc0rvrrBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zbV)=(R49?{k|7R*P!L4l{%|8s($iG-U>GcdGgQ|!!O;X}5KCyq7vTHUX0rRtPCUl9 zF$h=`%&YjQFt1`!AfOwbyzcD{=z+<$*(sbyweX6d%3ts+h#-KtC}@t!#^kT^&F54l l_FZGL9(ib-`L{DwHV+Ig2#D8^M*si{002ovPDHLkV1kc^O$z`3 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png index f21120bbd914a125538c0b785f736a9ec8f805b8..bac53adab7dcd74fd2bb22096603baed5a9eb789 100644 GIT binary patch delta 131 zcmV-}0DS-00mK22BoYa5NLh0L01m?d01m?e$8V@)kwz$HQAtEWR5*=eU>NLxk%57M zg{lUMcb@%EO#@k6%@wI>9s}d9CqJm`!ta0oQPVsImS2CV>OcmTKmVv~Ak|&?>mQZF l@bQ;F)HRTik*ek~006@27-;*V3-0bP0l+XkK DVg))t diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png index 5212f419dfa4ce8c1bc022832176b74aa12032ee..e9261c34c1fd113d578cec4c373d00629efd3a5d 100644 GIT binary patch delta 373 zcmV-*0gC?21GEE>BoYa5NLh0L01m?d01m?e$8V@)kwz$gK}keGR49?flD$p>Q4oc{ znR|EHWtZij4GVOJHIYO*TU!e)EVNK!Wn%12wDbuqY%F{QD__dO9%6uN0fhx1v2mK2 zV&=;^CjAk=?T8Yv!1WTPEn%1Hx?3vhDn#->Xw81#~0Bcs9oXMi%ia ztON+)2S+!TQIe#cR!l)*<{XnL7ZyZJi#i1*X6+epc!X)qwI1rJAZx&qvWuf33743YW(XB6FM z#qEkyIatU6NtN8bcJ+GxQgQwLwC+LObQ9P-Jhf&~yAOsd4-vz$LfKe7kIE^vu rl_}LQ5-)0nz5~Dl6T78t{_5Zd+cGkR2svLJ00000NkvXXu0mjf_t&hu diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png index f1c15529ac3dd93853e7e205110c781abb76a8d1..25ed23587760b59978b9f58f5a302b768b4c815d 100644 GIT binary patch delta 430 zcmV;f0a5;h1ndKlBoYa5NLh0L01m?d01m?e$8V@)kwz$gc}YY;R49?f&`(QLVHC&l z?|JSx+{u}An4H0MS1?;Q?t1}lf>uEUt-_7;0>Z5eUxFY(fkc~H*`~IIo1m3KC8U(z z95H6*KKIXaj++88M{3m%&g#JD{5bHx69E-K&dfhWIxAa4)AGP_|IvK^mA>70-h2P7 z59nV3cU~udHt;z|Cqusd7?AmN-+JGdlhxZ#fgG?)fz7X}r2!7TvU6PU?(;F9_Irer zgZ1Raqb0Vt`098gj*cHJj)X0O81tkr}wb(I#QIEMf+hS~{`?z*vzC9Ai)yUQG zYIs$AX_yHPW42T0O5xNzN#0T+$Y7^R@6F|n{96ehM7wnPhhD@$W%NT}@n z1B8P33k=#&Y(jtrqcIyGuL9lC6U)I-LZ0+D^R4$!zrB6_ z0kD6gk+sjM4hm&ZDBC^DyUrfny?#;b@4h~Iv+&Z#y+6{(%BNJ(9}76hJu6#1Hg@)j zcRNdm%THba@mVB6UV1X;Nu4KgN@(Ez&2eUKUtwhG?qXwp@c}R*B66yMRmJ*$Dk~!x zuM3mSQLeX}wQ%;)l4(x0IpgF(ITTx0W#*LBDWMVW+-T8gP26hCJ$npH$O$~%W;VZoH8U4G6$+42vOrACYqQA#(?f`1R~XN wM!<*=NL5$8l(9>7OtXDW>K7szp!Tc5cVW577|V9!b^rhX07*qoM6N<$g6uNP5&!@I diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png index 3a6ccf16ab5092e49d7590a424ae7f93f668e693..c162ec17ac366fdb7e03d2af862bf9bcd80d7b2d 100644 GIT binary patch delta 371 zcmV-(0gV341F{2+kUdL6VHk$5 z=e+0W@nC)uRO-PnEOAPSz$hZ9rur2vEiLs!g2tBS3R(&qg4TAYhW4o8RD>NBeH)H_ zM|lqq4>#P`a0y={vGQs%w7zwu5+h5?v*QS0iN;b8Q4m&wB^pCOG?<^q(UqNHyS8>> zI72nJk_pOx{t-X~KnK4L`Zs{YH}>*&zIvt{r&OrrNo3-1<9*P@K8fe78fUo#BF{=YtZn%?8gAaOyzb_A=j;De;@x51&H?UFHE;Q|8UpIgq<)> zG6I0@`3PVLm?BsPD3L&5--!a~++Meujni{`a$)LL(PN_9?h+e~4GsW$`2KUVQLjge zbLnQwuJ}(rV?*}9fB@2N`^~H4%h33AysgqRg>3R)fbq>q4|wtRHxCAt_zJ7bPk#Ub Rr6~Xa002ovPDHLkV1ne5tO5W4 delta 397 zcmV;80doGb1Iz=EBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zNl8ROR49>+kg-Z!VGxDCGylKddv{m#?yjy0F0R34QBX`Hf~8nkN}eE5NEy;t`2+z8 zfnXJ^Ed;@8eGT8hQba2)B(P(#SKUI<1H&)_=P>ih-FcKGRX4tmmRG+VTeZHizS1U` z2y#*rNr2QK1}8|!Ar71KoxhEd_VTHJm9o`tyN)Dq1|0xL5@N7-6#V2P3mJA&$l^}Vfer-ptw8&Oz!m-tdjS#ES>(`ouZPJcu8IqLvNcTS$TXP3)9`1 z+N^lFuu{aTv#6 z&wMA}!^|X0w1`&9MWocq$@~Gk@Gm%#gOlbmD@R8+DaW}yTz`@NV#+dJpBq#C~o%R z^kIyTE0T{`7f?`FnRIn<_ z&S8?u-R1tn`t;CiBAQlJiw_JHKtT|HM6d&PMgb98gFYO-Kv&(!?1r;@xJ5)9B6i#O zG$Dc@7=S(d7Bx535^8J2^msem1LNE7{;?2Xiims*RMD@spEP(~bcO;r>+6HA-qB6Z zV7Lb`jX(Oo;&z&}2K|WX^w+fa%>W+9e+21Ff%y3?!kv}MeaTv!x z&%N)P`-6ew62s|AHe^#`5;Kd9*PD-Q$;d<;87vehW#H-thpuy-7e(iFSHH(_ z=t^GS_4)Ma>HC$XGgm=C6u;Oif~cbY9JWyf6+{$2)~*^MAc`9CH+~pEK?KCdX&VFy zd?SBb?WT}_g{V^V`52=S$H!9#wuS>(*8ix)lIJ=$5My$v^Vf0nIM4n?5dh1HC8lmQ z*4`X;h_{D-pyO+ot&=?7`Sy*wGQDegnWJ>DZ#V}W(>D|l5 z!U}5kEQ~3=m$Eydp5c+pe5I?iCCF+jNBJ&Od|97cPipo35V*1cgIn;7`>;p%;KW(3 z9Q8`~kI!p!%jWIr0LTI5`rn<%=uCgxVk+&#`(}Y&AjH=S^}Pt-01?0fUV#eKR`>+@ W9en=YMo)AA0000!k}*hIVHAbG`~KHF6Jsbv6R{}N3Qiq@Q(YXyN$BEII_uD-TNgoa?O15R zLEF(uu!vORq9BT5P^8qjScwK&jZrX0q4G`#g9vTXyPof!d(Y+Cc=k+~kf>We03n$D z2NVJW!w|J?ee(Tqf~HZ?d5s;TSjm*&p&GvVGzgh z@67Y;pWApYM3O^HFh^1dfna43UqBkcH{si~u!_}LiC6{{1wmqv+q=DeW>VZj(z|L@Q544U|5|(Pz0aAGjARmHf(8i*^8g|mpTI^$8!I2fLSMpG@D1z( zRzk3`vat=K;stdw;DyPFX67u5i4w+)#>Nj;v6~<3vc=sw91#h?+NsBZ>K=Iz(JpYA{D?KIEpnxvVenL;uJnM|S}PX!ua=i63)y;*M# zwjR8D#r9yAESXXgg(ONcEiy8B#-9-p1?CA{n!Po5yLG*~xN&kxZ!CAI%#ed+O$81R z1D1db>3qIAduQ%iXT3UcuD!@g+2(9H^H)Fs13ExgvTPJrs>{}mE4CIpaW%I82uzGq z0n5NDa0XZe7LEl>bkjOi<*|Vx2}piD{}q_bw14pbfFIDLd=<9Kwj=-m002ovPDHLk FV1hBs%Lo7f diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png index 65a70a294c68ab74dc4a0c2c312cf1731749aab1..655a2db643b7df080a7e28e1975d369655293f7d 100644 GIT binary patch delta 425 zcmV;a0apH(1m^>gBoYa5NLh0L01m?d01m?e$8V@)kwz$gbV)=(R5*?0lEG>eK@>$# z^~@@gtt&smrT77UmtT-=+=vK@kd3&CAZ`K?B`Bg0%tA)OV3-LRdZwp)x~Hq|bun$6 zMJGSt-Bi7z-np+X754PVSXf3%IJU&NMoBm&su+1X%G>F~@dMx+5ZO`|EbI(fSVA_o zzyi!7B~++?1VoRrBqOz;gr&{u47|B;UMDn8zkxN^r~fo`*JueTVi^>%O|tk=Hng9c zFTko7px9!&o4{BJ902is*^p1#vU*V*0!7~wh9PxO4H(!!hJ%@`6Cd-M@@4TZEz%jV z?44jI?0`kc0=5aj`Ksd0bWZWMJguG=uYmE58SD;!?f?)BjarUom%P84P#%_Ni^o^{ zz*iveYX%rb4Y_D4PKy~Q`6c;9T`!+4KCKRx2f)#7?f~KL@x7#3YSJjqn-BGVC;VJM7_}MkiZ*$%T+y`2q>Oe(T_x`*-z_4@q>$JW9AM^+69Sbid Tk}NI^00000NkvXXu0mjfs8Pff delta 473 zcmV;~0Ve+E1D6DlBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zlu1NER5*>TkwIz{K@^6+SJRM?1Gw=Jp23wD@JPBA#1puXs9O<16vc%>i6~;!;24t_ zC(L9rnVIgXnXc;kU33evGekrm6x8DV-}hdX-Ov?Df|N+9BE^7WMHM5Y#ITIq{(Lka zTt2u8ya1+kpsoxFlMsfJ;piYBGeb^)3`3yWi$lNzkyd3UkPJ%+lVNh0890zcznla3Se<8p0y3=H1}U7{mJ?p;4gZYmiwpl{{Z|1Upe%z9%Qry P00000NkvXXu0mjfa^cWJ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png index d498c3b85f7247b6ad649037fa1efb814859c843..61cf46ac0dff4acfbe3ce37b9e205812c1a3b8df 100644 GIT binary patch delta 68 zcmbQo*vB|QMToP&BeIx*f$uN~Gak=hkuuTEQ2qDwZ}S_w8aijS^-5V}JxDMVU|@A; VdaCkPwTb}S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|KI_QR!`%S%8&s3ho%d(31`R`4?;~0Rz)78&qol`;+0DGb~8~^|S delta 154 zcmX@hc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 z?J?wQFyLW6ulbij*xTLic>K)DK1r{I(oQ@&5k-q!zMVANtD>4P@7gBaR2M~&&cqWM z&vz*=6i{fI{);i5q2veSf_`b{Wxdi4yua3*x_-CLy6>;>y~iJ>?*-b-;OXk;vd$@? F2>>KFI9vb# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png index 1d79a09045df21acb1298b87afe0e0560536c937..38c07275fe6e45d4fddde8eefdc9d7787d3aaf59 100644 GIT binary patch delta 160 zcmV;R0AK&@0pJ0UBoYa5NLh0L01m?d01m?e$8V@)kwz$gZAnByR49?{(jgARKnz6D z@AOEOdW0M=Ck&H^%?4wEm6S}BZ%P(WVu^J>IiC9q z*no>B6XOx!`|uZ_n?KM2qUmwKwG5a5g805zAE=9uYI%bCR+vBo%m>oeED|&+%KiWV O002ovPDHK)LSTaR4MA!E delta 172 zcmV;d08{_q0qp^hBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zYDq*vR49?{k}(d0Knw)uP=1t0Q1ddX{3m~*qCuiQ@T9opl;R2yEmL@HOS^L6G};Sd zh_SP68FMZgJBGZbh50!Rz#CXq`ORM0SG)@{an^LB{Ts5+oLpr delta 154 zcmX@ac$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo9le z|NQ@N&uq#l9O|2#kdTl9#0yt73Z;CsHwM*6{-suYMQ3+Vz3`a5{+hsr#dL zDes??UwU`3{ad!J(Oz<8&I99RtFM>}Op08=&d|mnGVOrWw&_5d89ZJ6T-G@yGywql Ciao9X diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png index 0a1c804de7d869b6974d6c0d778047a421d85d67..7e43bfc0d10d6a3b427907ed327087b2c1932059 100644 GIT binary patch delta 362 zcmV-w0hRvG1E~X$BoYa5NLh0L01m?d01m?e$8V@)kwz$gHc3Q5R49?fkUdI6VGu>n zo$t&0NnV~Yi3xe&4~U6k1koZOZoooIEi_mOZo$$W2sRdO!P4zm+6jUnK|^AZASsNB zjZ;l=@8QhAe~XqlC zrzZC8xfhLh&Xho{rpN1h=|=swl-S*W>^HPc(AL#z1=VUJ<%{pH99FaH@Yb-&kER2z z=N;y0o4ylPDyVh)ZhkbpnvV`D9rsuvKPkHIJ#R z_|5_p@pOP{zTd3nd(E5OwO+nfGHu%AgdcqMgitWhe*gf7FUQX&XbCfw38SVm{st_IQeqT$FEYB6&M;%$7L5hERxpSbEqn{<#;qWN%Qh}sMejp|h!n!58$k%7Rn#U3NnHssqd9m{ z<~MilzxkaOwh(KiRz7f6=kVd-z-=c0LO`y}e?`W>OeR+H(^CJga$MiH?8Lw7EVMU(9IzXKPsv-$t;e}5+*erArh%WV|xMY*b}`WUBJA_O#X<3Zz$nRJvs1@RWe? zs4+@(Cu~-i8jHhPXdyjvO~}-d;Yf%%vlb#kAj))olwcy92O56^!nW+;QM?rx1H6?C zEW124n5+g!q*K5c5dYD@L=o|*D58prAfg}&2zSE(scA%=F+i^azW|vtomt`-F~k4> O002n`MNUMnLSTXgFv8ma delta 453 zcmV;$0XqKT1A_#RBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zfJsC_R49?9(miWbK@`UE|1CdHEYQlwE3KY$I-NChuJ7F09sL`|X{_Yb723hFwWcY}u{fw=( zdga^IueX6>KZ)}y@XGPzc(zHDa$)v7m*!KFlgaYTa_1tDNYdT`u3!>UX&f?t?dDlZ zQ_gf+ar^T0N^~?{WS^D0kt^|&Rzazz7Ni8iIW%godCUFtIQd5p|{x#qSu%5JzdmkJ_00000NkvXXu0mjf#qigV diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png index 09424c08eb81a05e344d47e090dbecc5160655a2..b3f423af08638310b472bbe32814bafdda7f4cc6 100644 GIT binary patch delta 357 zcmV-r0h<261Ed3xBoYa5NLh0L01m?d01m?e$8V@)kwz$gF-b&0R49>+kiAL+Q4odC z%-sD;HoIok7?2Gq6bx1>S{OtS#6o-!5v+U=!56Sr!A4n&fX`u<+JJ&AF(%nui`|5% z1ot#E%*^>14&kTBJMzlrxqB;BIXDaF02T-{SQ%ikvML~A5G7F4X7|Efv`pQI-QH4^kh@9)Q4ogzf99Nx8Jg;;1M2qL5w5fKCndn>Jcl7Nk!+6z`z ziSJy|vV>`m$Mn&HG^7i2I0vCoam4^YsZm~)K1FZv)BoYa5NLh0L01m?d01m?e$8V@)kwz$gI!Q!9R49>^lCduXVHk&> z?|PM9tGEUoBoZ?li!fL^*_iwV5)&~COEs}bBo==J8^R=EDhURWh%{kBwRO4luI|3? zGaOA5iJWKn4ey)Zv%Ig^Rt2qf0<9HFN>msiWeXLCC?!EjcAp!lS9$L3IrHv;TLl!~ z7#ab{XeJbY2oMMa8iQy%V`nh)=CrlkcW5o;h5(~206;_`0D%VdcQsK`@Xnu0~-Xweso@$FPCBQJ_6g5!(@F+Vz!KHsuUt6uM^j6E+y0ThOxb9>urwO2J|lHdM$ew9TdT>)zXAXwyi9)RUZ#oSgTO9i358P*v1(@m!}>F6wzSRM~qh(#W}I zZyUw=dZzZQsva#2L1-g_3bb$1+$LgwVax$@JeEuxh8LnkB4Ub&02s|jkmhLjCJMk< zG{|fsLRZ{38d;i__Nl<|cyG*uJqjp}svsd#;t?DIB@ZOOi zo&VsW;!r&!k345)6v8zB&N{R1Il=AWG|C3`V=v0;Qu6 zg3Jxg1Hl7-yg*gMBIGX^nB0iyHV_oU2Q?dAb;3Y7g_O)D(kvvi|Ax8hC42W30CY2B z&R3jzB5HP%4o82W)7lNWYMI7vz4Ekpx34!&-twUtd$^=(nGw66cvqNm{h6(+3!3N6 z>zB31O*{?&OeT9`iKC%2x9G}xZBE>xD+Alkt=6kitpH;{#COuHX)6^!9x6G7l*D$D z51ON`0;53q?@>&9sc#~FIG8ubL(4!Guzct@sQ?qO0UdY+-ueEt@OdI5+9{>OV M07*qoM6N<$g80IrlmGw# delta 388 zcmV-~0ek+f1H%K5Bq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zKuJVFR49>!(!EPUQ5b;n=iCpyY8I0DfeDF3ElmwUOJhW1L(tyP(Adz{pU@Oe?a?F= zIkeai6i5z5(oz{Ar8gS7T_NyoxGF_lJJW&p$8$LFs$E$W;s0ZZ015<;D?f;c@9-DY zMB!nD3@Vx(1!(=JeTzW}bW4KQ^?@OOf+*5a4FBxEBY5G6}pi-5rEG2TR zrlNk%-eVQ#+HJjUwhDY#NeQST z-b$$OMmUu?%hXbpti+4ymKN7`fH`0o&=8Rx)}mXZQ;E~eg*jub1G7COA}IN>WJ)O= ihyWJg0IrC10KNe&8%k^!YCiW&zS3)pq!>TO_ uX;}v?my4J@2yNz9$Ufd6ec{^Q^|CDzaye)G_?H0fWbkzLb6Mw<&;$TxgEQj* literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!2%@r2u_~>q?nSt-CY>|xA&jf59DzcctjQh zRbK~TMkkHg6(GT~0>^Y94c5zWJpBDtAjiqm#W6(V{Mw5fIT;iLoG-eZn>gpXp0AtZ?Fd5wajShAXpFhReKFdvBFfMk&|q3sb^GXI*+3pZtT-Rhsvbf34aN zplPZlt`Q|Ei6yC4$wjF^iowXh&`8(7OxM6L#L&pf$k58jQrp1D%D^Dt3WFAkhTQy= z%(P0}8WcNsOap3=1lbUrpH@mmtT}V`<;yxP!WTttDnm{ Hr-UW|GHzU{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png index 6d5e6e15eda36dac15385b5669acce580ba3e064..eebfe3b91f39640ebc240a2644d8a942a55dfbe2 100644 GIT binary patch delta 377 zcmV-<0fzqN1FHj&865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGv;il70XRuS zK~y-6)seAE13?gmznRNkAsiN>7C9paDFnehhE*OlkB}mrq`2zdz@QdJ@CflpvO5-W z1Hm)V(jNw9i}~jNXNB+T0C&^r^dZl4r>ckus*0+TBncvdhyb810067&db!zbwhuGR z41f^At{0J3fB~!7Z1%ibtuV8H-L^PrW;@VNfRC~)%cg1e9GDs2`yIf0PtpPqK&z_q z!{P8g%d*rt*Phd?6#(GZ>vfW*>D6E`xJlC#5!rJRUHk+vz?WsYD2n1X&+~KDZCdX= zA%uewqSin&nM~fg-EP0v>z&1e#^Gat04zfY@8j|KrLOC&D2hwxTqinEICO)k4X^-S ztEze&jYd!N`CQD*0g0+6as&X|UrB*eAP4%uHE;oBzX3!k;DGF_P5}28Ky)K5{eRXc XJuI;eMf{uR00000NkvXXu0mjfEZM9x literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>8 zUk71ECym(^Ai=T%$8;bK*2@rcZ0%tn=dGuUV~EE2rRNO2nH>e%9+s;uU(UWUph@GP zgNqJ}ptk4au!HyNlhdcppK$Elp?hjeI}-FGI=Gf?-00cUUTvQJ@YrsbwSU@LW1l6a z9sMlYd1K$M7;hyO*FYA=DTOxc{!ePnE2-+TO8 zz$o0p|%ElrP z|Eq<=kT+^K`|;neLtQU;3Y;*C{&+93x;Qm?<4yxshZe5TS0<55k6q$tP&mcI$;nx~ zzsbOp;iquV;y>awOp)8dvhMBvcLnHi)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU( zWMyP%Wn`&sU}R-r5O9S-3q?b2eoAIqC2kFhojaxhHAsSN2+mI{DNig)WhgH%*UQYy dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(69BkXt|I^d diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png index 68871ceddf27294f43f97e6c2cbab13d5faafe97..2763880e9bdf2967b314aecd09661e44b80f3a15 100644 GIT binary patch delta 366 zcmV-!0g?XN1E2$t865@y001BJ|6u?C010qNS#tmY4#NNd4#NS*Z>VIGsR1W{0WC>H zK~y-6<&wcl!$1^8Pb44Yu6|zsLU%2tU~$o9vT!G4AyN?+LKhODK^mcuPSco|OfoLa zloY4^0WS>94BT_yT*gyM831DpZQC9#d$(Gx>cL=e1-t^9o-XXh7~@=8Ym`!Zpv55{ zIHdJqp63A|A|y%j2~>dj18ACm=3us?TL?f|mMj*FXW-ij=o{=L)?5??X`1dQlSv5d zoKMhNJ3Hv!&U8AxS4u5`+&Mv2RYw2-tu=X`6Ncg2cs#xZl9L@+fR%_KA_PIO91e%q zzzdMM%m98}*N5_&reVEam!r|>aW+RbJoaU5@>D2nGr^LZp9PhE1t ziT15L;D+CZzkmV!Z M07*qoM6N<$f?<7~?EnA( delta 424 zcmZ3$e2aO4WIYQ51H;x|=C6PhQRD=%g{b0wh>g z;Fu1i1;9Aw*xJKD#v@M`#}JM4OZzu^F*^#h?YDkkTEq15Da&b*mAP+JZg?q0EWMbZ zsKgSavV4Ye0gLIAlF7UG&fa)p<8Hw<^`H2o-~74%#$I}@h={8I%hG3e=gj%E$duv8 zf*;JLk$t)P4tq9>WJ*u_DILwPa;h%!5~uVWA;u-94`*LLf7-f^X+hz#puiJ9r_M}j z>NvGFB6&w$&5Oy2SDCl5dYN6Seivh~EPzu@4=65GEIi@@@i}l~H);&AX zGRddj@8x{U-MbO1M!E~+DpGB zOS}d8SGB}7q9i4;B-JXpC>2OC7#SEE=^B{n8W@Hc8d(_`S{Yet8yHy`7zA8l&_dCW io1c=IR*9rR7)^&_=ZSLTBDa*#dz_2B>?irBcEbxddW?)EuJ)Uu?^vL38xY(DD1V0ni5W&6cEH=t$)Pgg&ebxsLQ0M<1g5dZ)H literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W=!2%@ZVz%W1DW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`0$SBdfgIbxnJjv*44lmGmf->7lGWzMF+)+<3A44O7f zEG|`_?13s&OI#yLQW8s2t&)pUffR$0fuWJEftjv>VThrTm64&9k)^hQk(Gf#z!e59 z6b-rgDVb@NxHTwt?wAJDAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<- MPgg&ebxsLQ048rn@Bjb+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png index ebe042e97296a7b05ee2f71031e3f9214b27c374..70a084c58cc8dc1beaf3543f6e812aac1b8c3bee 100644 GIT binary patch delta 130 zcmZ3(w1aViq%0c)1H;~Z_vQd8&H|6fVg?4j!ywFfJby*X#NQfGuAVNAAsQ2tQx34` z@bK{b64#5dP*zktcmM=WoH%jd$dMxl&YU>|rca#c5ICO1;F)lxK{5Tn|Ns9r%Ncb9 b4>B-hNwd9_;mD8xTEpP!>gTe~DWM4fx1lrb literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhRgkmPy6ft{7V@vq&OHDo_*T@)UR6N8c~vxSdwa$T$Bo=7=U_= zbPddO4GcpJjjW6et&A+S4UDV|3<9n&XrXAx%}>cptHiBAv2({Xpaw~h4Z-BuF?hQAxvX}(6P49wzX=K5#@mpqa`CQ5(vLGLN@5ADW_)Mv pxHp{t0z%d<2gY`1Jc^xhR%Z$p3p%f;`S9G?GGFR*j@ z7IinW6#kqQsGXKRhtq3Hkj0wWw&ELJXjG=_*Zi0{VWz>eR-5-GbES8`6Xwy|x$G~{ zFx3**h?11Vl2ohYqEsNoU}Ruuq-$WNYhV~+Xk=w%Xk}!nZD3?&U=VPHK?_AgZhlH; zS|x4`ik&;A0X0a1YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEETh{4m<&t;uc GLK6UyPg|1! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png index 8cb90399455c87336899e6097e512ba72af5be7e..1ea1710389d0af614fec4be5b6d0d914709439ca 100644 GIT binary patch delta 127 zcmZ3*w3Ts!q%0c)1H;Myzc?VpS>O>_%)r2R7=#&*=dVba_){a?$2>8 zTnAxBCym(^Ai=T%$8;bK*2`dF-Fy}d(oDbBkTH+c}l9E`GYL#4+3Zxi} z3=EBQ4a{^63_}c!tc(n;j4ZVcjI0a{0PsvQH#H~TGbH_BG21$?&!TD(= p<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e0sy*RQtJQ! diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png index c3200aff4e60ae100e14e960fe4a4afba18239ed..1fd1527eeb09dfcf3a3f341cd66237406168b239 100644 GIT binary patch delta 331 zcmV-R0krVIGkpU-v0SZY( zK~yM_#ZfVCgfI}CwQQd)ID;Ebm>wFwlC(i0=&CgQAZ5Nlnsj`Dj@N-xAkZO&%PCE^ zvaFfenOWe!hyH-4+xMda1c2(g4y&qqiK6KFbUKwnh|41a1V9eM&^YHllu}M91t}$@ zl)pxxqA0?y>pqhtxf){-1OcRfl;E6$F?Lsg0O)ZXzp^ZA;yB*Obd#Llv)%XoTbibg zwH8`y2q6Ff-unea1a>4)mSvLX`MWU&LI`lq;l1C;>-;1@0A$;?uTd0TwAMSzJK%u> z0&sTDJt?KO&uN-=+ldI?`@;^-*4lh6%zKY%ng9UvJcBW|T;RX~3xXgb)LI+P`L=D1 du@Zr$%x^VcHJ1-av|#`M002ovPDHLkV1f)qld1p! delta 404 zcmey%bclI^WIYQ50|VD4we>)XDaqU2h2ejD|C#+j9%q3^WHAE+?{yGnbkdkz0TL`L za7+i%0zk~muz1zM`#{DiPZ!4!iOa1McKb0U3bgM3X}tU9{8H02PYuO`eufi|9J>*C z`J+Oc_=1fecr`fQJ1l&kn3$aI>a0<+ePeyZF{hJpN>-Cso|`$RTcW=IH@iDOqY_6^ zgF@b$`NuA9-QT76Wx9VXkN)(Jl^u%`wz^vV`}ptY=d0JYZ7n}N%i!Xxhez+_B+E~W z%-eZYwWRF!T(t@(hBb1*G4`@&A1k>0oR;@Z;EwO5&B`nb*PIW%^ZW5^21c&3>hP&@ zEl)}W80rHU+L)IpJ&aO+JMUk?>EBFA$827Qu5}Rs`b)LMHKHUXu_V9nO2EggJS27X+RBVIGm;on$0XIoR zK~yM_#gIK}0znvtpV?ibu33$Zg$-HiUHbig5QgC`a8YGq0Vwr( zRzfVxqE@TXZnqf@hxen=s831z?!Vzb7`u(ZQ)jE< z!VfGFmo67EB&8qa^vT)Nc-=tpqY#TB8<%yGvZ&!ZsS6u^N9vqx`e8hI<+HQ1C57wT zKl{rcc5V35eQI}oq;J^cryGnVbf*4IsJJ%Ebp9TH`ReD&mu!OdKR13``JLxsg}4# zl%yn~>+1H%wQBP%0ADoc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngBaz BqjvxR diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png index 49fe22b335f593f65c80a3334818cc9a5fd00f23..c76994a6728fa41ec14ab479e1ca5c6ddd702f51 100644 GIT binary patch delta 348 zcmV-i0i*u-0*(Wa865@y006zd-kbmc010qNS#tmY4#NNd4#NS*Z>VIGM*$~)0UJp~ zK~yM_m6E+`!!Q(u&(*bv5@J=R6yz9!*ANV*(4{y_mvr;1WXOYbEM&>6z=x-KrU+wDL^`+F0AK#Rp9jH0OMcDo~E3_6|8nYnFj2T-2pqaX-YN~xje zc}F#`App=|FnEzt4qey%ml*&U0Bts#_wjf6vZk@l3T6yeO=d3N?mQhIIyiVs;bPg>?4lj u8*A-Dzu*7U3a3Z_@p`@fJpD+QR`>>(Xf#)GZ`Oza00000z%d<2gY`1Jc^xhR#m6dZcucy6z~pyBH! zuds9HiQFgm4eAc)>`eMAe17W2&lf8HFgxY0FTbqMVIGQ2{4^0Tf9@ zK~yM_mC~_F!%!5)@qbI8b;#1i**6H?e1qVm_!1ogq3&WgArFu~LYG2T$sBM91zp6U zAP7PT9g^EixS`y8U0M-buHX2<`N83wfe^x4YXPvyf?z`PRllZ#MNr00000NkvXXu0mjfc9EFf literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!2%@3w~L7bDW)WEcNd2L?fqx=19_YU9+AaB z)z?9o(Me-=1xT>0z%d<2gY`1Jc^xhR@+9A#k=CP0;g!}elcC}&N0BhY2UWJPG6Z_ z_J8Ryk$p1nk$BDb*IRnG&Y5HT|6sil^UUsc9bUP0eO9YXcI>>(8MaF^KqJ?8jqlc= z1zQZan_LpOq@EVmHvj+qcLl0q88cYSfv!?5ag8WRNi0dVN-jzTQVd20hDN#uX1WH3 zA%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsW()}YwAV;WF{B*=!~{Irtt#G+J&^73-M g%)IR4VIGSOF)00S-w- zK~yM_m65+n!%!55zk72-QJ(Ey`T}1UReOsG|hKw ztvd^LVC(+`opZEvc6M~m_0IQyKXALE2>8 zUk71ECym(^Ai=T%$8;bK*30m(yT=a5nds@_7$R{w_w+_Tra%GK3&yXHWN_3qa&FwX zdExZ>?TZYwAZ${y2E4M)FK7R}Hhhk?}+)wpk`X$ElXMMwFx^mZVxG7o`Fz1|tJQ zBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4}a`RI%(<*UmQ0&|>4X8m9WJ7R%T1k0g mQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT& z^Tze_%-hYyw&CUjri}ZX32gcYRuo;H9rBj{12a>#*(aUNSK^TVN zr@E&nnq(4!haf0|WTB{8xpAutuftn%=|#Bl3Pc1^5Erfl1r?GQGRA>%oI`j0E;@q? zXFM$Z;Detk>gBDfHEHYU;9L2ey|DZAZzEGmjb>&dFz$KJ#tMH?P^16f@#exm}TVxKtl2I zqvrmt*}e6Rs;js8lO0KlkRr%wApn|5tz7B2boavXRcl)mr)W;p>)hHbF_>SYdHT-q z+IC#Oar)?-VvVSn1e2!iIFOvZvgWYsL(sVFSDA00000NkvXXu0mjf_Vvc% delta 433 zcmV;i0Z#tV1MdTnBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ zY)M2xR5*>j(#>j9K@(bQ^D zk4Rz~35~ei#}N^+!x50a{b*mmTb2QT1wug)er2czzPJCy?s89=%#eX>%mYoJ;on@F&^h~ zEp})9zO_fUqN|O$ld<^~;-nlSM*J6c z)rZ&IzH-LWrDY2j7R?JBSCW_XZ{+Px>5AA{8wN)s(#}C b1HJ>s#-zD{^QyuC0000W diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png index 639fc3878ea5d5dca14cf5762f9042e6314cd98c..3cec3cc27249238e8865fd4cec95e7d74074b083 100644 GIT binary patch delta 391 zcmV;20eJr91I7c8BoYa5NLh0L01m?d01m?e$8V@)kwz$gQ%OWYR5*?0l3hvzF%*Tr z$UM0kAKiybZ~?AE5quH!#W#Pz4HPUEDX5e}5h;b@FLkJ;woGd~otl~4_>dHfPP+lm z(@k>oo!mo|^fxRhFcvZc+M=`pEnoz+Cb=o4t6QuC_dv#+0#INrhy@Xp_!v}sOoo*8EUQz%?xg)4JbzI{|nPm_Up!LXJiDDGf1jhLTlFd#6F%*SAkQeYld;}lEXK>+CAH$6s6XVhtb}rS(%AXj*iugCiAR&YR zBRGr-%`e5a>vPP`>S03)CbLdkh1UrR3^*%13($$ZER2U0?=)_gTZWSO1xbM*b##w*@%28VE#r#AHVp zc%VlRhY))>9ThC^a(G(f05}I+?AbD_(C=KT8<*i#n?bcnd#A$jSW!-#U0{-R^t5uo z2Ji^zopr0K%{ov;Y7A delta 84 zcmeBUoX0ppMTw=@$uool2x>S|Iv5xjI14-?iy0VruY)k7lg8|diDriC|Lxw`GmA0` joAOGV7F;=SFiC+Sx1Bj$B)dBlsE5JR)z4*}Q$iB}lsXpa diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png index f19354d8b9debeb3b9da8fdecedb487288a22a0c..ecb8de13e29d00f00686754ea4cc7cef4cccccf6 100644 GIT binary patch delta 133 zcmcc3c#Ls^iV$akM`SSr1K(i~W;~w1B4whRMni=K5rMN4Ai}-VH`)1sudy9NKz7U;?A!g?)8X<$s72%&ua( l(f%xQ2jhzQ+oi6>-(vWy#1rtRTaEz)JYD@<);T3K0RY(zHTM7j delta 154 zcmX@cc$;y8iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{VoBRpLkLo_D7 zopg}1!GVV*{cxuBzuW_SYfsI}t99A2$3>vVQeaby!B3ZMD?PFfJeu2F+AOf8!7^dq zrtK$oDpZ`*{}GbV8}o>{k)dBGpze9xg}JA{R+aD4^P9C(#HU(S#TaNagQu&X%Q~lo FCIFe#i(`n!#J3lA^BxM|X}ef#9HN%U zrIx~!rIy%W^Cx(L$3s;;+xXO-7Sry$s_Iy9DCo>mU+v(CFs|p5%S;|M-CXBb-)f^@ z&v@?}yB(wc{&%cVx7jW&=iyfu-lVwGIer(T{bG4O=O!su1|aZs^>bP0l+XkKSi3jZ delta 164 zcmcb@_>^&iiV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{WrlRRAV4rkTAcs^Oq(c0+IIB&9&_wpA{4lSz{Vu}fnndE$`RBU}+ z?1q_wH&jxYnBNyVl>bz{@Pz+J1FLrRzc*}4j2C_QwNPMzobMf{UAx%WBONrE4H>>> Q0Nudg>FVdQ&MBb@0CBiIBme*a diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png index ce4a2357abda53c72c52e065065e6f53e012d5e0..64fa0e7c12a8affd27262c681fe56af55d660044 100644 GIT binary patch delta 120 zcmX@ZxRY^$iV$akM`SSr1K(i~W;~w1B4whRMzou!i(`mI@7ePkc@HQE9B{Dz^>D@n z+fAIh))yw}RZS}pLN1Q_J2vIUk~pBvu_~ Y-5MptmwlC$kpT!iUHx3vIVCg!0QoO3TL1t6 delta 139 zcmdnVc!qI;iV{n)lV=DA5Y%v_bTBY5a29w(7BevLUI$@DCym(^6U{W@JUv|;Lo9mN zo_7>%Fc4rlxbsS7w{y({m3W&EyniBm&TzfBwNhn<^eQ%y3tBUnx9;4ujOX5RF0-4< q+?#p(uCu*u|9av<`N@Qpa`q)tL<9}Y-u(hv#o+1c=d#Wzp$P!yku+cc diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png index 70e3cad6488456ac13e35246e92806d8e1d1f619..ef3d963d6c89263f9550239c6f19ce1238cbf948 100644 GIT binary patch delta 349 zcmV-j0iyo51DpepBoYa5NLh0L01m?d01m?e$8V@)kwz$gDM>^@R49?flDkdVSEFl2_(P8610Go z*f`Y`XTF(pGVtFef6&X%eo=q`a&bg(xzA}7aFVm>I2M&f00KDAH}o43w^`4v60bnM z2wDGE3v#f3P4GD2zFyD)jdiGXAZ&wM2Rljy2#|Xj^3Ys%`s{R}ya!+8;FOoY)~6OG*Qm85XK%`tV9f*iDi)3D=+_bB5rL}sRP6&k&cujDE zXc80 zJUET*6vYZ;+rZosBLPQ1mODt@A9GqRnI5e^I2n*nh~}VTAqtux5NFR84F?oUs-TXw z{P7OzgQFm>ovS7~5Fn@o><|QTWg=L-#Ux7v8zrgAn)ArlH)vrB_M>1+FZvTf?feV1 WBq$^yWb~K-0000T_4>~FWmlec?|sxuZK=2GlSAxGW-LTbuuE$r9Yy{mKWtPA5>M4==WWCO`2 z^*UQULQR&@+2_cdb7*Y`m{50{0Y{0^kYQr0CWa=PowK*~_Bh)3zRie<5E{oQ#n>E+ m&BN&#?J2V}liEMSKlB5Wv4fmLIG}I<0000ixy{zW&8!PsCN(08Dw7(_b>#QQ>%DK=8QL`9_GlN*e41LA4=607AKejLLwrK0j31<1U!Iu2ktc(0TX~o7ws*K0Ac)p^C3apJb3Dt z>w)V+&Gn}WU|Ga0hJaR}_}M_H?^Z7{^&{Xn;RxMrB&=qvMh34HwvH!dZMTvD0000< KMNUMnLSTX?HnCm+ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png index f407cbbf7174d0c69426e7331dd1db7290bc18d1..8efd044b0c38f6e929c25a6fbd82f792815ad99e 100644 GIT binary patch delta 345 zcmV-f0jB+kULAmU=)U* z^Ch$-R_(>2Acm3_+9)^_9V~GX1R;}y|G?27;jV)?If{#egOjv^;NYxI{sIS~n;7i{ zZ5)!`P&DuI@g2_d9L^EOBRgwk4m~ccEF09eKnZ9-LMKRQkPy%nC_n^#6h7D{zw2_D zHl&7Kj>-XlVK*QFi0Zck3Y+fQGnPPj*>bSh05>nAJG7LdE;iqVtwkPIZx7niOJzu0h9twK#N`_;abss zd3>gGeow<&3Mw<5W{Iy)Nax}UfS%vRKYO6=Es~o&mDeh*cgW4f76A0RUD_vi+`2`k rZPQ<6q4cjnF`gdK+C1ho?h(HM!|^(95NZhF00000NkvXXu0mjf-BOoJ delta 336 zcmV-W0k8g;1CIlcBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z3`s;mR49>^kG)C*Q4oc{xw%)#^#>QSq97<%iiIGE7FIzlwy?4lAHdc(@dYf!T4HNw zV-wP7FbEn&jV!pLi8f=g%O;>ma*Ba(;G8)ls;XpCRX&oK_UR5`at`ZTP%vN(3>g@< z;4&^45U{=G&f7C`woRB^!u%o_0TGaY{6@CxqRq|mEmDaXX*XbL1tvr? z<0ZbzCp3K->NU8#87#m#$JF!;#psyk^l08eqa2UjY zPY6Pbg&=}LU5Y|M#X*N62s${cs7sw4I{6KXOCjLcsl^YFPhcrdiqcJdD^gLHiWN#) zUxo^?$=@M`6s!<$xrgKK;DHmby{%9RJfQ1=qY%dhrwcCNDX5frdE-2H#8#n#jqe6P z^GSLnAc{bL>)n$x#7AVw+@zFSCm!Vb4j(FDkw6}wfa!URn7**L%;{m8SwIIw8<-b< z!x)9R6fq-`*hz70?Xn2y+5qd{hz>&{Npy&@l_?H@$o~rLSGd2W+MvFg#{@JzboluR z>W`c}P}?Z5|MA5Y&^lCeqyK@f(&UA^L>xe!7MZ8S~Hab7?zRIm^&1hMulENuiq-^VURz)HKb z619l22^KjpLZU|HjGJAHBwPfG^M`@?XP9po7-2g51_SgpC=K5lz7+I^zONxT=h@lB z-a8|e&LX8`q&O3R6vWwgXz1>7>{TD!h8IeX|2EExiC@qoxykVlU z#YKYs-KNtBP)dyfk|;F|g#~Q&gbWUeqUfK1RtWW5 zY99seW{%NXGnsh!@d26*u3lZj;wdY|MQqzn2)Mt7c8iO*b$ZJutoc5!(l1CuQ547V z@4fF1^@(Loa3Y8xVlZeE?87Li(Q30AEg~j^CX2;jGYFPdG0Y$iMO1_#d+3v~F%;Ro z?_R^(!+&^p>iO_H=fDxRzTgmm!&?df>qjZHu4`HfwFM!-`L#kjAOVCQiZ_#*Eb$+& zsDFTPfb^z+DjM25@(VU~*Zn$)XP^c_4gc+$DwqfWd2~Sq6G8Iw6D2X2h=X$;#VUuv zafR~oG$Z-m<|twSWDnRD=sQZcR2TQzv5wQgTH>o3C-alcg{m=x4559`<&%9b?y~i+ zDFN5nAh|R{;dPrEw}*S!ATH!t115m*_qDn8B2%?3P0F)ltN`OcUxvO*0px&wAOKoG co6gI80xgqW8LPEb_W%F@07*qoM6N<$f>a8X3jhEB delta 354 zcmV-o0iFJd1EB+uBq9WJLP=Bz2nYy#2xN!=000SaNLh0L01ejw01ejxLMWSfkv1rQ z9!W$&R49>+(7j3nK@h<4|Hk!5#6!h2HrYckCqUQ==82={$g50-gIm?N^{*10Z!%U-OM?{6($- z{Ti30h?C+msl~$!YO}jw%aC+DN;+W66zhif+&TGt9%ZeS__K{%9WWn1!So8)SDu?$ z?iUJdZtY-#=9}ix4N|sf~W&i*H07*qoM6N<$f)eMG ArT_o{ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png index 7bd1d84f96210f506b40923f10ef8c1a2a308d8f..c27064260bcdc497b9d02283fb391d34243b906d 100644 GIT binary patch delta 136 zcmcc2bb@h$iV$akM`SSr1K(i~W;~w1B4x4?qefP!r;B5VMeox~2RR!81eh;IMtFZx zC`(t~mXO`VA@^^c?-@q}RvRYID;rIdCh=WX*4(Oaa>K#&9SL`yHqBY(UQ{d76Bkzc ojG;_=4rA^s2DJmV-}irFa(yWhwdq9ACk7z!boFyt=akR{0KphGMgRZ+ delta 275 zcmX@Xc$sN}NQ}kxTlL_h{frxmkk9Q90XVnTE3dl;#{+UQPjnwv7_bxDtjLu?FEbHuBg>L zqN>Gyvf$_ve#soOA0?7|az1Q3XrB7PCZyh=;VhfD!*4$Z;|fN%sk84b$*OOVXQ`Gb zO89({8EA)UiEBhjN@7W>RdP`(kYX@0Ff`INFw-?K3^6paGBUI>veY&(vNA9TxWb@? gq9HdwB{QuOw+6+|9n&V7X>c-ly85}Sb4q9e028@cK>z>% diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png index 5018dc60a24d9feaa5276bdf6c53d3e3d97802b4..4d22f79c1686731247507ba865954266790dae11 100644 GIT binary patch delta 407 zcmV;I0cig21k?kNBoYa5NLh0L01m?d01m?e$8V@)lRW|_e*s}hL_t(Ijn&c5N*hrW z$MNsElbMOZ7&K@%icnm%w7M17E?oKyeXTx(8=pYB5d|MX3YI1*{z>8(Cv*QC7dPUf zV``Tk_`&6J&*vPt!r#>ZcFNto)BJERrIkSH_%Z@9$8B5q*qivU0OTKxur2dNPnkVOPWvBm-zjiLl%Y~yYNQ>pm=?^d1 zjFtIx`C3F=bTYV{msD*N(b(`qf~n&9(j+nS|8=Vw*E({C97$Qpukm*JJpTfDU)2VV zAB>@j^BEbstdBmD3)c(LdiHVk$?Fe7L$8%G`g4a*e_i?gT2%;t5! zTb=gRKaxL}W^`I6Hv3#rz@>l-0UvthY$`t4GaczU%B&am{{6LSo378!k#%^+_U?4S z>%(i)i`MzP*!<7cMSH1S!`+>i&n(gxn)&$;V~}U}ygZKfvl5J-R}w>^V?knlzmw#*G2z?e`iag8WR zNi0dVN-jzTQVd20hDN#uX1WH3A%;d)Mut{Kmf8kJRt5$ER~WQVH00)|WTsUz$l}zY W*tuicL^E|R1_n=8KbLh*2~7aT%HZe# diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png index 994743d0c35fbcbb3dfa3ae441e0e8ae19b52d5e..00d2a62557ee75825ea580d6dfdff0e7c2b62ec3 100644 GIT binary patch delta 397 zcmV;80doH01j+-DBoYa5NLh0L01m?d01m?e$8V@)lQ9A(e*srXL_t(IjpdTRN&`U< zhrg9nK8=mw`}ihyieMvXW2u6b*rc!%L`4XqA_)FT;7ra$a>mQ$a(8<(7Q4hKm%M-j z!_F={-*5KE8aZB51Q3N>p%BbiATOa*NHWrs%VP2BVgIpTIh~t*(6s_0kCvewdtJ67+%JLByR!A1)9LKZyd~1o(3!d r1u*iU*zYTUUKOCm&%fhO{U72RLk{KW$N|#T00000NkvXXu0mjf{}{7r delta 550 zcmX@b{D@_ONyvhP!xZ9? zb1jlP<2R!*(=mtJ&z)9EJ3I_%4WC^)XGV#fW5X=>2mF7RmSxLx+-(SG-Z=9h$BRFH zR(ADw%HKHc-6ttg%kJ`yL!r_0!Ykn4ejHW-*vuKWW8=OY4nx zGZ?o%pE%#jkFhS&e(9(Acm6Y0FgKt5_wA5m!%tx7tCqM%l%yn~>+1H%wQBP%0ADVO0|RG)M`SSr1MhVZW^~e+T>%m-D{xE)(jq|2 z#ZX=)$_Hdfd%8G=Xq->}vw!1LduCBaVN+gd(}F7p4kjruSlwiH7d*FeB2bxXiEBhj zN@7W>RdP`(kYX@0Ff`INFw-?K3~@FzvNAHXGP2Y*FtRc*2)M$ag`y)jKP5A*5?KeT X2F1=D(BU06on222ryrmo|}Fu z_k!#Ww(ZY+>a{aOIUE*rc!b2+q#xUP{q)_pUZTYjUh}(Blek1Ly<+_k`0v2^M!sL( o3%*M!zGv!{>$mkg_(Haa*UU!Hiqo|~lK}`kUHx3vIVCg!001d8<^TWy delta 275 zcmX@Xc!_C(NPO zi{Z`da0wtI%+tj&MC1J19#5_Y0|A!R?Jj?M!yWHGTwNP{%UMK;gR4oMyDc+K^X4+w zASSl{%cqQ-87voYzX*P7slc-8b@-pA{Cd`1J>Qu)-$WfR{^;!Zv2M-hHHplkX+pMh z*mV1VR;ZS^MwFx^mZVxG7o`Fz1|tJQBV7YCT?4}qLnA9ALn|XoZ381K1A~Ao3|c4} fa`RI%(<*UmQ0&|>jbWm>IwymttDnm{r-UW|P!w1g diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png index d538eea05ef1f8dd4163652da56db18c4c52aa20..08b3a53ae51f2f915e3468a1e739007eba744cbc 100644 GIT binary patch delta 145 zcmaFBbdhm_iV$akM`SSr1K(i~W;~w1B4x5ZqegL@r;B5V#>BVhtoa-gL|h&g>z-oD zbx#&_$+m2%cXNC=wc?7O<;lNA&Y_7i3eHA6oiA9M6O23puDRTP;=taMbE;wPO zi{Z`da0wtI#nZ(xMC1J1iQZhT4m>Q{a;Jo=q{{C(9$b37(&EzFB(XlF^XG3h30#`c zG@;2OC7#SEE=^B{n8W@Hc8d(_` wS{Yet8yHy`7zA8l&_dCWo1c=IR*9j37p_CGbH}uaW*VFfp00i_>zopr0FU5duK)l5 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png index 27c7d02b412440b51d42af05c3322c4805a27cb5..9900f8bee2b9771716b89215a9069d9e051e16de 100644 GIT binary patch delta 129 zcmX@bbdYg^iV$akM`SSr1K(i~W;~w1B4x59qeilyr;B5VMeo^5yLlTNcvvoOe6mbn zi{okW;3H34YDyAj&1lelklEC_U%w&b;H+mx2UB8w`d6$y+4?=PO6C01rmyq#JWjUq h>@Ik3B=IWy2LpSKNL2mC6hQ_c@O1TaS?83{1OQF>Hc9{h delta 275 zcmX@ec#3I)N+%J4>=0 z7*;l!>Sq;iTANoSyZg_Fy;s^j_osfSPN^@raq_UA-E5w=S09-dZWE1Lv8U)R&}h{X z*NBpo#FA92@ylT2KH0 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png index c5e3fc3b18d9f4f955f2dd4e7755d0a9b5046b7f..12ce5c81e7e4c29ed9126294767ae19b6423f819 100644 GIT binary patch delta 357 zcmV-r0h<251fm0wBoYa5NLh0L01m?d01m?e$8V@)lMVtWe*rH^L_t(2k;RZbP6AOB zg}?h|<~fgHfK2!`!pvxb2@uq%6>HGeMq*`YtSxm5HtxWMxC%QLU@WvDAU=zk!UB-k zc&l5S^WAeU{P)No^zw6G7a)LKMN#p(lbl7KJ~bi(?MP!CfB^b=|8U&d(6_$Po5W3M zRv2TcE(c>qJ?Qly*#%eS3c+0! z`)M$|i~}=f)Q9d4Y$Y(Cg3Zhb%K^v6)b~u`hG7cT64Y8Sn}8Bvd^Wa-@a# zSC}Z!0@?vbfmqZ6vkIUXII4v4^JnFq9Ra04PO zmtpa$gZCL27@a*`978nDFP(JOi>XlLX#Mwp>2B$NR()jFy>!9IFgNIe>ld!Ki^4PH zUAoO|UDsAM+*5m@+Qp%?;>4NEhc3ETxb*MTpKUFEXZbvi^YDa9ujfw8*XkLSln#Xd zpX=cA#UQ?5{TzWUBv^nL`q>7r!Pjz%E9xPAO77$!%;rD0R z&eB;$$;a0`k*Sitkm0zGBTi^$S!+h|8@m^Co*KOr{#E*d?E=q%!bL1;=?Sr+*}He{ zsCL=U_qLvGjd`L;%XY<%h7&1Ff)@{b-Ne4H-f?Zl<|oc8d78xoB)1Drc**tVb5ZL2 zlA>Ne(ImqJmgaDSo`VaU{1iI&?2bHrYvGe-!w(<%`pX|wCU9GbMR2*PYY8ZXZdhwp zXH+#)KrZj$&4$GZuOnJd9SOfS#c-zU?Z~74|7S3*y8o}Ve$GMlTN`xk9`AbN4-8t> z64!{5l*E!$tK_0oAjM#0U}&UkV5Vze7-DE-Wn^e&WT|anWMyCwaD_n&MMG|WN@iLm oZVif^JEj3ONP=t#&QB{TPb^AhD4*yd%EiFo>FVdQ&MBb@0IOs=ij&^_Du?E!`dNd0qq1zXHt8 zhT++VhdPw1e+0g)-21`y_|?S$5CZ0B;QYkUlPO zmtpa$gZCL27&ARx978nDFP&tq?~*9cHvjz`+osgRySzJgn5yWpa@spTWY5UhDmAsm zOZ{K7U+*ohO@%iDa+H)d<=wn}v-sPax^$8HbkT_IGs@ELRX&>=sC20Q(2sEQ1q{L! zhXsBr2YD<@fA{h0&L6)_*8g36^jqKEx5wGtUH-%io;Wq>!=&aC#&`1$mg+yMtWNy% z>5s$(dqK^eR)TM2o)}HAX#Oj4$F6eQ>)f80BiHk6&j0mu@qA?9!S#Uqj#}b-hNSB@ zsheKse!N^Cy5Psuj>hLs7aNlpZP;(^N+{x4)|R<;ZS=jD@^jWo#NKr|)taztTEhYH zjJ(Eo8ayRY#k;ncPUSkUwRGNU$?OHP8rA`N4lA7!L-=ei@=t7Acy`{s$^$`OE6+2f zvU{0Tm{~-gSgtsiDY!AyDSS$ru?h2)@D%$s6TH}NL@jvIT>rdzb#oA_i}Z^vYXTK` zQtX5^4g?%@ac)f9Q~x2OMQ!ym{iHUj)q;DN&hK45fBuuDvcL#XEpd$~Nl7e8wMs5Z z1yT$~28Kqu24=bjh9QPVRz`+aMwZ$JMpgy}0aqBbP&DM`r(~v8A~cAg>rm|6F>Rum QIu`?jr>mdKI;Vst04inVRsaA1 diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png index d1b1f6b6459ac7d90d94dc2499f20cf3dc13909b..7e332b401e639e9ae497367421476df018d91456 100644 GIT binary patch delta 360 zcmV-u0hj*c1Em9yBoYa5NLh0L01m?d01m?e$8V@)ld=IPe*rQ{L_t(2k&TeeN&-|B{&& zM^hom7Y+wLzV|ujeFgIpXG*0m^M!lI3LkUofdotgB9g$8U>RTlQi23?)_mc*+4FSv z!8VOUDmf5pD+d&^74A7kNAiGw1nr=}(t8wAJzf(bzXK-4Rh zk{gQFEERF^%8-olr$m6xG?fX6TsV4V3E{BgE;cWa0f@$+_p+BzN2<}MFb>?LNN`T)PjXJl@My;C8tgN>CyL|Ov zGqW@Rz#l^Yy7}?yB~&su^!F({{{rSK1s~|0yw`7*E%65PO zi{Z`da0wvexu=U`h{pN37dLt_2MV-4e4n@Jky6Bx%_6IBbWHNo$vxt9klmmuqI2&z z#;q?5Zofz)8wmQw$UJKrpWaqX0`e@hc5>X@SORX-o|No?8WwP{5y81XU}v} z@SWjtqHD?CT@wT}_-2-WuUNC$!dvLm1#@Li=C}3@e(i6y&Z=prrg`nucXM)jA^BKA zg?)?tigzEbrj<6n)I8kPoY_CIA*%P9w0E)cnZ;9?{rYC=7k~Cy{FUE)V+8tLJdAn(2Aouk`x$imIo(?8FjY^uD~f@Vid%u06kQv;F;b=Z?hhmV8zr(|~O+ zT!Vq0RxNRjC`m~yNwrEYN(E93Mh1pPx&~&t28JPqMpj0KRz{ZE21Zr}1_4(Xv`{qU h=BH$)RibDRMA4zxxntTyGj%Qo22WQ%mvv4FO#p^>q~ zyea?^GzdTnf6$B~q}N-XB{3FUHIg&=Ts)rea^Hdh8juB#ED(-_QoB>J>+?)z1qjIBr~e=_0gGuuQckajqesB_{{+@M z+*dJsJ!`XU8h{M=3TmKafoXBm?Nqj_<%5pvJ^(#`MuNLCG+N}_?c!GDdEbRcpb7N- z30_;A+HY6cdd&bzKpXFCv_Aomt=Eo$C!ovFBYgqw)nez-uhruK0000PO zi{Z`da0wvev!{z=h{pN36a2lI5(V1le_uMgok>~6s)M7O{pPh@Ef<#hD|U9&`)U4C zRNB=Qzu0@eVv|h;$8L?3rUji!)!bJ~t?GBMmj_;|GcedM`Ajlxip_m)CJXNw`iXiU zHaE2xs5ZH73uNCj1Ue3q)JI*?+-~O;=e~Cnc3(KD!X@AM_shRH>D}FXC^wpM13|m`}8=0~8I|EOy)HO@@sYZo|KWr)c*LW(; zpyn{c{-2xN>a!-kT?q^T)e_f;l9a@fRIB8oR3OD*WMF8dYhb2pU>IU(WMyP%Wn`&s sU}R-r5O9S-3q?b2eoAIqC4($Z9g3YhrcE?c=VD;+boFyt=akR{0Ew@oP5=M^ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png index 313e2db043272ac86789785d3cfd80ee2a7b1a25..8ef8a7a23dedc5b1edcbd0a0af5a940082ba5eb4 100644 GIT binary patch delta 352 zcmV-m0iXW)1DykqBoYa5NLh0L01m?d01m?e$8V@)lgI%le*r2!cPMr)N)4QBw%#n|F&F&>H`2;%Ct77WyirVz_NQ# zqXOj;NA+qkeRXlBojf*j+au0+{LPyrHVDxH@S0G%CHwMpzgch(C7f##YWcQzx;`|# zYI)CNm@z22TzbvQTERVdl`;!l`$mzicsyC3U%XLELK$_Jo~tFJ(On<~Sp0beV=s}I yDbFtCR&09*m;y{6`b`SJ0Ahd!w15w~ukr;9vtdv%-X7Ti0000RR9VIi(kBHyu5CkS9riDKkSLaLR>S$Lkfdw2~&X^S!I6yHh=9>F4A?1+!L(8#Np{ zmzH`KSa_B1G>}}XQU2vMLl0{ZU(fLcKfagEUVhMJ!ohOpVJbP>o|J5y@YBcw*Y|Qne zllJ{vT3^XBkDc55!wbP_UNP_9Zwy@j*n;ncwWm_9`I4=rdvo(%uDKc{;%Z;YrpjAw z`|?4++_LCGnf~xoZqJ_xU-s&av+?$P2@DF=64!{5l*E!$tK_0oAjM#0U}&UkV5Vze z7-DE-Wn^e&WT|anWMyCwaD_n&p+Oy}BR4-KGp!Q04#mzL( -
- + - + @@ -20,10 +19,10 @@ - + - - + +
 %time%
 %name%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css index 8f09e4dd8..dd249dca7 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css @@ -3,7 +3,7 @@ color: #FF0000; } -.time { +.time { font-size: 9px; } .incomingHeader { @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } .bubble-green { } -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px;} +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px;} +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px;} +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px;} .bubble-blue { } -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .time { color: #AAA; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm index c9028a9df..820d0daaf 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm @@ -2,14 +2,15 @@ %css-style% +
- + - + @@ -18,10 +19,10 @@ - - + + - +
 %time%
 %name%
diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm index 84a6c69d7..0733677e8 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm @@ -2,14 +2,15 @@ %css-style% +
- + - + @@ -18,12 +19,11 @@ - - + + - +
 %time%
 %name%
- diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm index ad8287db2..b8340a65b 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm @@ -2,14 +2,15 @@ %css-style% +
- + - + @@ -18,12 +19,11 @@ - - + + - +
 %time%
 %name%
- diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm deleted file mode 100644 index e9696af8a046ce09c5d540f25ecd7f883f4afa05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59) z8(A2bxf$!a7+M(UnmC$R=vo*!y6GAjIGPzdTe_M$8@biw7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI=foBSX$~@xEeU?nz$L709h_By5{E2PA+D~ZpP*&W;OXm>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI$O9JxLE2MIGQ`^ni#uT=sKDhIqAANn;Tggo4S}gnz+{F7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cO znOK-QyPE5|8CW>$nm9We>RMX5IO)2YJDNK>8yguKnwZt(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDG9WBkATuhA3bj_U14RlQmU7U5DOij&o zT};iLEX<57ES=n(Yx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWIwFV31038J6 K8W~%2)dB!Y964D4 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml deleted file mode 100644 index 908cf35de8392a00dfb1b06ffab5845bd2710b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zIGY+6yBO-48M(RXnz)%7>ROsOndzFiI9r;#7#UfZTe#Ka7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDGjV+7}4b3f_b)B4yO?6F-T-7jw&+{GxQd-2AG{oSa0xG>B$~YA%rPlk;;*bMq8z6^tyb!2&rz2LZWe IX4YJ_06RZ9E&u=k diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d97ac6d9bfc1f3f2b1cebf7622592716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zxw@FTSeoh@o4Q%(nz)!5>smOPSm-*tIU5@r8kv|mnpoE47p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@n0YY@)`AkG!eitBqRu;46I`ZkX??Z z4P-hwGjhSqMGMX71|6(EDGEzQjh3|*X^b&ZT&Ep<(tOe}RR9nB4N zja>{JjonPm9Sw|KYx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWMvIYy}038J6 Jnp<<#0ssV0IRpRz diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm deleted file mode 100644 index 8f6e1cd656357cb34c9c21a21c9979481dc82810..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8k(Azo4e{d8ksrknix2_=~@_Dy6HN(m>F0aI2xHc8#&hG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zTUa_77?|iRMP@nCZHjx>*>QyP7$gn7h{G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~ct zm|K_{I2!4in7di%npm1x>ROmtnCTk2m>4@5nVA_FyExb67p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG zx)?Z`xwz`OI6FG&nwYz~=~@~&JL?)cyBRx~nK+pl8<^DO7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zS{S;yx|->lxHwwsnwT3K=~@^Vx#>Dvnm8IcIUAXqnmE_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b^ zxVf1+nmXw^8yY(6nix1c>snemTk5)*yBIlJIGGq4I9t}_7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw zSejXw7&_^?IT@PinpnD7=vum(nChCEn;1J=n7WxdS{l{l7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zSsIxexti;`8oRmbnz)%5>N+~Qxak@iSy);a7+IRQnpo827p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* z8<-dxn;YwzxHy{VnwUGA=vtUL8R|Nly11A)xtO`S7?{@N7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zSXi1H7@Fw1xtdw%npn8H>RMP@80tEiI=MI+nmQR77#r8*7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zm^m95m|NRP(ExapdkI=Pq{n>d;q8avhG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8JW8{x;g6_TLK9aLq{WBOEV_}T^DB)R~I*Db3+S5$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zxEMN{m>KIj8XGw4nmAdQ=sKC1TI#x(nYg$ZI6FGKx|!GH7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O znwl9|I=kvRyBfRcni!i|>N*-YJL$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zIJ-JJ8(ZpHy1AO_nz&fH>N>iZy6CzZn7J7mxtcp0JG<267p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt znLApVnHlMtSvr~MnwXjx=~|c?8|WGsnmJoIxtJTfnL5_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!j z7+6|5xtZu%7+V_anmAjS>4NyW&Q2zl7H)2?PL3{aHTgy9db#;knK?O$dT9{N3;=bg BDa`-? diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95dcdb65dd850ecb6a86678b3bab72c9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~_ zSXek3J3H#S7+5;%niv?m={g!(8ta;w89JM}xVRV_nmE$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zn7BEao15yITDY3)nm9VS>ROnaJL;NQxVoB{83Xm0y4K_urR(M9S7qkpBG&2AI DZ%QeA diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794b61f88b1a885164e827fe06a4984967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~da zn3)(^8anHm8@rn6ni!h6={mU?xagX>Sh$#4y1JT~n!45G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BO zn>radx*F3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cu zx;PuVx>)MEI-8m4nz$NS>RLFtI_Vmj8M+#~m>C$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b_ z8M+x5nH%f68oCkdH?_b diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b9d36a5f683250b2ce1105697bae18b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& z7`Yg`xti%(7#kYtnz$J`>N=Ubndn-YI-0o|yP6ppy1Lfn7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt zyP2CCn7HbiI649eXJ=DgCldoVU2`KBGgkvsBPU}^!$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cN zn;E&9x*6&kI2l;znz*{U>N>d?xak^Nn7FtYni*O;o0`_-7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zS{PXxIGgG^TbLT^nz*?*>N=X6ndut1x;i--0_B{IoNDrm()Dult1@$P67|v`ni&9Z CDk+Nq diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a77a22d87d71807853bd14d17a7753ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& zx;h&=IUDIZ8#_Adnpm1y>RLEE8tS?kIhnay8n_r4nVZz)7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG z8M;|oIveW(8K$}>=9VV97EVT%x<;-Brk19rmaYaa<~8|6>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1za zxSF||y1M8(o0>T3nz*?6m{`{27p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw z7&@Dp8ae5j7`nOYnwYyf>N;8&nd=%ES-2S+J36}>I9t@@7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o* zm^nJRS{m!RnOT_YniyCZ>pGe{x#?OMn3|YaxLP$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zI+-{-T3F~>IyxHbniv_l=sG$Xy6PG_J6o6-y0}@oxtZ4F7p3dv=2vCrb%7 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163ca22e3cdd53f2cb638febdcd17e7470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!F zIh(sWnpx^P8d{p_nmC!c>N=TOy6PIaI6Imfn_9TKxtP`D7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59& zJ6jk!yO`@bTDZFDni#qn>N+|Z80s1uSsFOHn3G&2AI DZHOsf diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376ff3cfeb8f2762196a72317aaa4ab836f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5AF z85>wQx|-`67&;l~npj#G>spwYy6PI6m^&Jp8yLG7Il9#37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~` zIhq?AnHuYwTNs+@nm9YU=vo+=80lIX8Jn7zn3)?`n3&h(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zx|+M0IvVSmSsIw?nz*`|=~}wDnd@2@n41_|7@1l)xw_Tl7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Aj z7?~NkxVq{ZyEvQZnwT0n>pEE&80#828JHWGy1AMeJG#{57p3dv=2vCrn+a diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f57872049d5ed87a8cc66a4e29af31db7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BP zIyFZnmC$T>N>iZ80xy38ygvz892H)8ambF7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~^ zSvt8IyBg^_TbfwtnwUDf>RMPDx#?OMJDNB;nj5$pIJws37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6aobu zot#~rEp*L{OpSF-TwTm`9nFC(3lkGdM*|~Q7grbOn*5@4z1;k&%$%G=y)=ks1^{p$ BDU<*J diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css deleted file mode 100644 index 98da5fc9ac4f4cb60f2b354cbb8c16120b3acfe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zx|$mpxw+|@nK-)YnwT27>N=SkSm;_<8XH@W1dnmX6y7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm deleted file mode 100644 index e9696af8a046ce09c5d540f25ecd7f883f4afa05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59) z8(A2bxf$!a7+M(UnmC$R=vo*!y6GAjIGPzdTe_M$8@biw7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI=foBSX$~@xEeU?nz$L709h_By5{E2PA+D~ZpP*&W;OXm>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI$O9JxLE2MIGQ`^ni#uT=sKDhIqAANn;Tggo4S}gnz+{F7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cO znOK-QyPE5|8CW>$nm9We>RMX5IO)2YJDNK>8yguKnwZt(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDG9WBkATuhA3bj_U14RlQmU7U5DOij&o zT};iLEX<57ES=n(Yx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWIwFV31038J6 K8W~%2)dB!Y964D4 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml deleted file mode 100644 index 908cf35de8392a00dfb1b06ffab5845bd2710b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zIGY+6yBO-48M(RXnz)%7>ROsOndzFiI9r;#7#UfZTe#Ka7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDGjV+7}4b3f_b)B4yO?6F-T-7jw&+{GxQd-2AG{oSa0xG>B$~YA%rPlk;;*bMq8z6^tyb!2&rz2LZWe IX4YJ_06RZ9E&u=k diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d97ac6d9bfc1f3f2b1cebf7622592716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zxw@FTSeoh@o4Q%(nz)!5>smOPSm-*tIU5@r8kv|mnpoE47p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@n0YY@)`AkG!eitBqRu;46I`ZkX??Z z4P-hwGjhSqMGMX71|6(EDGEzQjh3|*X^b&ZT&Ep<(tOe}RR9nB4N zja>{JjonPm9Sw|KYx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWMvIYy}038J6 Jnp<<#0ssV0IRpRz diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm deleted file mode 100644 index 8f6e1cd656357cb34c9c21a21c9979481dc82810..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8k(Azo4e{d8ksrknix2_=~@_Dy6HN(m>F0aI2xHc8#&hG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zTUa_77?|iRMP@nCZHjx>*>QyP7$gn7h{G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~ct zm|K_{I2!4in7di%npm1x>ROmtnCTk2m>4@5nVA_FyExb67p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG zx)?Z`xwz`OI6FG&nwYz~=~@~&JL?)cyBRx~nK+pl8<^DO7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zS{S;yx|->lxHwwsnwT3K=~@^Vx#>Dvnm8IcIUAXqnmE_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56958ca49a4cec87e452fe5f048ea9c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 ucmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c3f52ed2f57cfe2708623517d51937df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b^ zxVf1+nmXw^8yY(6nix1c>snemTk5)*yBIlJIGGq4I9t}_7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw zSejXw7&_^?IT@PinpnD7=vum(nChCEn;1J=n7WxdS{l{l7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zSsIxexti;`8oRmbnz)%5>N+~Qxak@iSy);a7+IRQnpo827p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* z8<-dxn;YwzxHy{VnwUGA=vtUL8R|Nly11A)xtO`S7?{@N7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zSXi1H7@Fw1xtdw%npn8H>RMP@80tEiI=MI+nmQR77#r8*7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zm^m95m|NRP(ExapdkI=Pq{n>d;q8avhG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8JW8{x;g6_TLK9aLq{WBOEV_}T^DB)R~I*Db3+S5$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zxEMN{m>KIj8XGw4nmAdQ=sKC1TI#x(nYg$ZI6FGKx|!GH7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O znwl9|I=kvRyBfRcni!i|>N*-YJL$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zIJ-JJ8(ZpHy1AO_nz&fH>N>iZy6CzZn7J7mxtcp0JG<267p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt znLApVnHlMtSvr~MnwXjx=~|c?8|WGsnmJoIxtJTfnL5_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!j z7+6|5xtZu%7+V_anmAjS>4NyW&Q2zl7H)2?PL3{aHTgy9db#;knK?O$dT9{N3;=bg BDa`-? diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95dcdb65dd850ecb6a86678b3bab72c9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~_ zSXek3J3H#S7+5;%niv?m={g!(8ta;w89JM}xVRV_nmE$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zn7BEao15yITDY3)nm9VS>ROnaJL;NQxVoB{83Xm0y4K_urR(M9S7qkpBG&2AI DZ%QeA diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794b61f88b1a885164e827fe06a4984967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~da zn3)(^8anHm8@rn6ni!h6={mU?xagX>Sh$#4y1JT~n!45G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BO zn>radx*F3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cu zx;PuVx>)MEI-8m4nz$NS>RLFtI_Vmj8M+#~m>C$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b_ z8M+x5nH%f68oCkdH?_b diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b9d36a5f683250b2ce1105697bae18b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& z7`Yg`xti%(7#kYtnz$J`>N=Ubndn-YI-0o|yP6ppy1Lfn7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt zyP2CCn7HbiI649eXJ=DgCldoVU2`KBGgkvsBPU}^!$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cN zn;E&9x*6&kI2l;znz*{U>N>d?xak^Nn7FtYni*O;o0`_-7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zS{PXxIGgG^TbLT^nz*?*>N=X6ndut1x;i--0_B{IoNDrm()Dult1@$P67|v`ni&9Z CDk+Nq diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a77a22d87d71807853bd14d17a7753ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& zx;h&=IUDIZ8#_Adnpm1y>RLEE8tS?kIhnay8n_r4nVZz)7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG z8M;|oIveW(8K$}>=9VV97EVT%x<;-Brk19rmaYaa<~8|6>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1za zxSF||y1M8(o0>T3nz*?6m{`{27p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw z7&@Dp8ae5j7`nOYnwYyf>N;8&nd=%ES-2S+J36}>I9t@@7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o* zm^nJRS{m!RnOT_YniyCZ>pGe{x#?OMn3|YaxLP$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zI+-{-T3F~>IyxHbniv_l=sG$Xy6PG_J6o6-y0}@oxtZ4F7p3dv=2vCrb%7 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163ca22e3cdd53f2cb638febdcd17e7470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!F zIh(sWnpx^P8d{p_nmC!c>N=TOy6PIaI6Imfn_9TKxtP`D7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59& zJ6jk!yO`@bTDZFDni#qn>N+|Z80s1uSsFOHn3G&2AI DZHOsf diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376ff3cfeb8f2762196a72317aaa4ab836f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5AF z85>wQx|-`67&;l~npj#G>spwYy6PI6m^&Jp8yLG7Il9#37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~` zIhq?AnHuYwTNs+@nm9YU=vo+=80lIX8Jn7zn3)?`n3&h(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zx|+M0IvVSmSsIw?nz*`|=~}wDnd@2@n41_|7@1l)xw_Tl7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Aj z7?~NkxVq{ZyEvQZnwT0n>pEE&80#828JHWGy1AMeJG#{57p3dv=2vCrn+a diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f57872049d5ed87a8cc66a4e29af31db7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BP zIyFZnmC$T>N>iZ80xy38ygvz892H)8ambF7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~^ zSvt8IyBg^_TbfwtnwUDf>RMPDx#?OMJDNB;nj5$pIJws37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6aobu zot#~rEp*L{OpSF-TwTm`9nFC(3lkGdM*|~Q7grbOn*5@4z1;k&%$%G=y)=ks1^{p$ BDU<*J diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css deleted file mode 100644 index 98da5fc9ac4f4cb60f2b354cbb8c16120b3acfe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zx|$mpxw+|@nK-)YnwT27>N=SkSm;_<8XH@W1dnmX6y7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59) z8(A2bxf$!a7+M(UnmC$R=vo*!y6GAjIGPzdTe_M$8@biw7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI=foBSX$~@xEeU?nz$L709h_By5{E2PA+D~ZpP*&W;OXm>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o4 zI$O9JxLE2MIGQ`^ni#uT=sKDhIqAANn;Tggo4S}gnz+{F7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cO znOK-QyPE5|8CW>$nm9We>RMX5IO)2YJDNK>8yguKnwZt(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDG9WBkATuhA3bj_U14RlQmU7U5DOij&o zT};iLEX<57ES=n(Yx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWIwFV31038J6 K8W~%2)dB!Y964D4 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml deleted file mode 100644 index 908cf35de8392a00dfb1b06ffab5845bd2710b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zIGY+6yBO-48M(RXnz)%7>ROsOndzFiI9r;#7#UfZTe#Ka7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@joC2@)-?)G!eitBqRu;46I`ZkX?bM z4P-hwGjhSqMGMX71|6(EDGjV+7}4b3f_b)B4yO?6F-T-7jw&+{GxQd-2AG{oSa0xG>B$~YA%rPlk;;*bMq8z6^tyb!2&rz2LZWe IX4YJ_06RZ9E&u=k diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d97ac6d9bfc1f3f2b1cebf7622592716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zxw@FTSeoh@o4Q%(nz)!5>smOPSm-*tIU5@r8kv|mnpoE47p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@n0YY@)`AkG!eitBqRu;46I`ZkX??Z z4P-hwGjhSqMGMX71|6(EDGEzQjh3|*X^b&ZT&Ep<(tOe}RR9nB4N zja>{JjonPm9Sw|KYx0ZI^>Xv8GIMeg_0k}k8LGKJzE952Db3AOuvIWMvIYy}038J6 Jnp<<#0ssV0IRpRz diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm deleted file mode 100644 index 8f6e1cd656357cb34c9c21a21c9979481dc82810..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8k(Azo4e{d8ksrknix2_=~@_Dy6HN(m>F0aI2xHc8#&hG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zTUa_77?|iRMP@nCZHjx>*>QyP7$gn7h{G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~ct zm|K_{I2!4in7di%npm1x>ROmtnCTk2m>4@5nVA_FyExb67p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG zx)?Z`xwz`OI6FG&nwYz~=~@~&JL?)cyBRx~nK+pl8<^DO7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zS{S;yx|->lxHwwsnwT3K=~@^Vx#>Dvnm8IcIUAXqnmE_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56958ca49a4cec87e452fe5f048ea9c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 ucmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c3f52ed2f57cfe2708623517d51937df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b^ zxVf1+nmXw^8yY(6nix1c>snemTk5)*yBIlJIGGq4I9t}_7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw zSejXw7&_^?IT@PinpnD7=vum(nChCEn;1J=n7WxdS{l{l7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zSsIxexti;`8oRmbnz)%5>N+~Qxak@iSy);a7+IRQnpo827p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* z8<-dxn;YwzxHy{VnwUGA=vtUL8R|Nly11A)xtO`S7?{@N7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zSXi1H7@Fw1xtdw%npn8H>RMP@80tEiI=MI+nmQR77#r8*7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zm^m95m|NRP(ExapdkI=Pq{n>d;q8avhG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8JW8{x;g6_TLK9aLq{WBOEV_}T^DB)R~I*Db3+S5$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zxEMN{m>KIj8XGw4nmAdQ=sKC1TI#x(nYg$ZI6FGKx|!GH7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O znwl9|I=kvRyBfRcni!i|>N*-YJL$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zIJ-JJ8(ZpHy1AO_nz&fH>N>iZy6CzZn7J7mxtcp0JG<267p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt znLApVnHlMtSvr~MnwXjx=~|c?8|WGsnmJoIxtJTfnL5_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!j z7+6|5xtZu%7+V_anmAjS>4NyW&Q2zl7H)2?PL3{aHTgy9db#;knK?O$dT9{N3;=bg BDa`-? diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95dcdb65dd850ecb6a86678b3bab72c9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~_ zSXek3J3H#S7+5;%niv?m={g!(8ta;w89JM}xVRV_nmE$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zn7BEao15yITDY3)nm9VS>ROnaJL;NQxVoB{83Xm0y4K_urR(M9S7qkpBG&2AI DZ%QeA diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794b61f88b1a885164e827fe06a4984967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~da zn3)(^8anHm8@rn6ni!h6={mU?xagX>Sh$#4y1JT~n!45G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BO zn>radx*F3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cu zx;PuVx>)MEI-8m4nz$NS>RLFtI_Vmj8M+#~m>C$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b_ z8M+x5nH%f68oCkdH?_b diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b9d36a5f683250b2ce1105697bae18b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& z7`Yg`xti%(7#kYtnz$J`>N=Ubndn-YI-0o|yP6ppy1Lfn7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt zyP2CCn7HbiI649eXJ=DgCldoVU2`KBGgkvsBPU}^!$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cN zn;E&9x*6&kI2l;znz*{U>N>d?xak^Nn7FtYni*O;o0`_-7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zS{PXxIGgG^TbLT^nz*?*>N=X6ndut1x;i--0_B{IoNDrm()Dult1@$P67|v`ni&9Z CDk+Nq diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a77a22d87d71807853bd14d17a7753ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& zx;h&=IUDIZ8#_Adnpm1y>RLEE8tS?kIhnay8n_r4nVZz)7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG z8M;|oIveW(8K$}>=9VV97EVT%x<;-Brk19rmaYaa<~8|6>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1za zxSF||y1M8(o0>T3nz*?6m{`{27p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw z7&@Dp8ae5j7`nOYnwYyf>N;8&nd=%ES-2S+J36}>I9t@@7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o* zm^nJRS{m!RnOT_YniyCZ>pGe{x#?OMn3|YaxLP$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zI+-{-T3F~>IyxHbniv_l=sG$Xy6PG_J6o6-y0}@oxtZ4F7p3dv=2vCrb%7 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163ca22e3cdd53f2cb638febdcd17e7470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!F zIh(sWnpx^P8d{p_nmC!c>N=TOy6PIaI6Imfn_9TKxtP`D7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59& zJ6jk!yO`@bTDZFDni#qn>N+|Z80s1uSsFOHn3G&2AI DZHOsf diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376ff3cfeb8f2762196a72317aaa4ab836f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5AF z85>wQx|-`67&;l~npj#G>spwYy6PI6m^&Jp8yLG7Il9#37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~` zIhq?AnHuYwTNs+@nm9YU=vo+=80lIX8Jn7zn3)?`n3&h(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zx|+M0IvVSmSsIw?nz*`|=~}wDnd@2@n41_|7@1l)xw_Tl7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Aj z7?~NkxVq{ZyEvQZnwT0n>pEE&80#828JHWGy1AMeJG#{57p3dv=2vCrn+a diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f57872049d5ed87a8cc66a4e29af31db7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BP zIyFZnmC$T>N>iZ80xy38ygvz892H)8ambF7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~^ zSvt8IyBg^_TbfwtnwUDf>RMPDx#?OMJDNB;nj5$pIJws37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6aobu zot#~rEp*L{OpSF-TwTm`9nFC(3lkGdM*|~Q7grbOn*5@4z1;k&%$%G=y)=ks1^{p$ BDU<*J diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css deleted file mode 100644 index 98da5fc9ac4f4cb60f2b354cbb8c16120b3acfe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zx|$mpxw+|@nK-)YnwT27>N=SkSm;_<8XH@W1dnmX6y7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}aR(5C_`86Z2;dkJ5(HHS(lG;wmC&>? zBE&_L^K#~ E08?%lp#T5? diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img deleted file mode 100644 index 0be496cbea713fda0a58bc00d32e5cb997302a7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cO znOK-QyPE5|8CW>$nm9We>RMX5IO)2YJDNK>8yguKnwZt(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~ct zm|K_{I2!4in7di%npm1x>ROmtnCTk2m>4@5nVA_FyExb67p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG zx)?Z`xwz`OI6FG&nwYz~=~@~&JL?)cyBRx~nK+pl8<^DO7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zS{S;yx|->lxHwwsnwT3K=~@^Vx#>Dvnm8IcIUAXqnmE_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56958ca49a4cec87e452fe5f048ea9c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 ucmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}u>uf-_(4F-09OIxU;zLoY6T$x diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c3f52ed2f57cfe2708623517d51937df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b^ zxVf1+nmXw^8yY(6nix1c>snemTk5)*yBIlJIGGq4I9t}_7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw zSejXw7&_^?IT@PinpnD7=vum(nChCEn;1J=n7WxdS{l{l7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* zSsIxexti;`8oRmbnz)%5>N+~Qxak@iSy);a7+IRQnpo827p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}* z8<-dxn;YwzxHy{VnwUGA=vtUL8R|Nly11A)xtO`S7?{@N7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zSXi1H7@Fw1xtdw%npn8H>RMP@80tEiI=MI+nmQR77#r8*7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zm^m95m|NRP(ExapdkI=Pq{n>d;q8avhG7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d) z8JW8{x;g6_TLK9aLq{WBOEV_}T^DB)R~I*Db3+S5$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Ak zxEMN{m>KIj8XGw4nmAdQ=sKC1TI#x(nYg$ZI6FGKx|!GH7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O znwl9|I=kvRyBfRcni!i|>N*-YJL$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bv zIJ-JJ8(ZpHy1AO_nz&fH>N>iZy6CzZn7J7mxtcp0JG<267p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt znLApVnHlMtSvr~MnwXjx=~|c?8|WGsnmJoIxtJTfnL5_w7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!j z7+6|5xtZu%7+V_anmAjS>4NyW&Q2zl7H)2?PL3{aHTgy9db#;knK?O$dT9{N3;=bg BDa`-? diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95dcdb65dd850ecb6a86678b3bab72c9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~_ zSXek3J3H#S7+5;%niv?m={g!(8ta;w89JM}xVRV_nmE$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k40O zn7BEao15yITDY3)nm9VS>ROnaJL;NQxVoB{83Xm0y4K_urR(M9S7qkpBG&2AI DZ%QeA diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794b61f88b1a885164e827fe06a4984967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~da zn3)(^8anHm8@rn6ni!h6={mU?xagX>Sh$#4y1JT~n!45G7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BO zn>radx*F3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cu zx;PuVx>)MEI-8m4nz$NS>RLFtI_Vmj8M+#~m>C$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~b_ z8M+x5nH%f68oCkdH?_b diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b9d36a5f683250b2ce1105697bae18b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& z7`Yg`xti%(7#kYtnz$J`>N=Ubndn-YI-0o|yP6ppy1Lfn7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1yt zyP2CCn7HbiI649eXJ=DgCldoVU2`KBGgkvsBPU}^!$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~cN zn;E&9x*6&kI2l;znz*{U>N>d?xak^Nn7FtYni*O;o0`_-7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!l zS{PXxIGgG^TbLT^nz*?*>N=X6ndut1x;i--0_B{IoNDrm()Dult1@$P67|v`ni&9Z CDk+Nq diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a77a22d87d71807853bd14d17a7753ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6j~d& zx;h&=IUDIZ8#_Adnpm1y>RLEE8tS?kIhnay8n_r4nVZz)7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0pG z8M;|oIveW(8K$}>=9VV97EVT%x<;-Brk19rmaYaa<~8|6>3X^ORhc$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1za zxSF||y1M8(o0>T3nz*?6m{`{27p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Bw z7&@Dp8ae5j7`nOYnwYyf>N;8&nd=%ES-2S+J36}>I9t@@7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k0o* zm^nJRS{m!RnOT_YniyCZ>pGe{x#?OMn3|YaxLP$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1z2 zI+-{-T3F~>IyxHbniv_l=sG$Xy6PG_J6o6-y0}@oxtZ4F7p3dv=2vCrb%7 diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163ca22e3cdd53f2cb638febdcd17e7470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k1!F zIh(sWnpx^P8d{p_nmC!c>N=TOy6PIaI6Imfn_9TKxtP`D7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k59& zJ6jk!yO`@bTDZFDni#qn>N+|Z80s1uSsFOHn3G&2AI DZHOsf diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376ff3cfeb8f2762196a72317aaa4ab836f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5AF z85>wQx|-`67&;l~npj#G>spwYy6PI6m^&Jp8yLG7Il9#37p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~` zIhq?AnHuYwTNs+@nm9YU=vo+=80lIX8Jn7zn3)?`n3&h(7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3}( zx|+M0IvVSmSsIw?nz*`|=~}wDnd@2@n41_|7@1l)xw_Tl7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5Aj z7?~NkxVq{ZyEvQZnwT0n>pEE&80#828JHWGy1AMeJG#{57p3dv=2vCrn+a diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f57872049d5ed87a8cc66a4e29af31db7f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k5BP zIyFZnmC$T>N>iZ80xy38ygvz892H)8ambF7p3dv=2vCr$Vqox1Ojhs@R)|o50+1L3ClDI}@opdn@!tY55x_AdBnYYuq+J^qI7A5ADWagzZ6zUro7#Lcc8W<#-n^_oIyJZ%orsY?F6k3~^ zSvt8IyBg^_TbfwtnwUDf>RMPDx#?OMJDNB;nj5$pIJws37p3dv=2vCr Date: Wed, 3 Mar 2021 22:37:12 +0100 Subject: [PATCH 024/697] added missing explicit update circle method (Not used yet) --- libretroshare/src/retroshare/rsgxscircles.h | 21 +- libretroshare/src/services/p3gxscircles.cc | 219 +++++++++++++------- libretroshare/src/services/p3gxscircles.h | 11 +- libretroshare/src/services/p3idservice.cc | 4 + 4 files changed, 174 insertions(+), 81 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 6ff854360..8b94bd829 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -301,7 +301,26 @@ public: const std::set& gxsIdMembers = std::set(), const std::set& localMembers = std::set() ) = 0; - /** + /** + * @brief Edit an existing circle + * @jsonapi{development} + * @param[in] circleId Optional storage to output created circle id + * @param[in] circleName String containing cirlce name + * @param[in] circleType Circle type + * @param[in] restrictedId Optional id of a pre-existent circle that see the + * created circle. Meaningful only if circleType == EXTERNAL, must be null + * in all other cases. + * @param[in] authorId Optional author of the circle. + * @param[in] gxsIdMembers GXS ids of the members of the circle. + * @param[in] localMembers PGP ids of the members if the circle. + * @return false if something failed, true otherwhise + */ + virtual bool editCircle( const RsGxsCircleId& circleId, const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) =0; + + /** * @brief Edit own existing circle * @jsonapi{development} * @param[inout] cData Circle data with modifications, storage for data diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index b1a3bc5e2..43032db70 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -194,96 +194,111 @@ bool p3GxsCircles::createCircle( { // 1 - Check consistency of the request data - if(circleName.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; - return false; - } - - switch(circleType) - { - case RsGxsCircleType::PUBLIC: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::PUBLIC" - << std::endl; - return false; - } - break; - case RsGxsCircleType::EXTERNAL: - if(restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId can't be null " - << "with RsGxsCircleType::EXTERNAL" << std::endl; - return false; - } - break; - case RsGxsCircleType::NODES_GROUP: - if(localMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " localMembers can't be empty " - << "with RsGxsCircleType::NODES_GROUP" << std::endl; - return false; - } - break; - case RsGxsCircleType::LOCAL: - break; - case RsGxsCircleType::EXT_SELF: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::EXT_SELF" - << std::endl; - return false; - } - if(gxsIdMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " gxsIdMembers can't be empty " - << "with RsGxsCircleType::EXT_SELF" << std::endl; - return false; - } - break; - case RsGxsCircleType::YOUR_EYES_ONLY: - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Invalid circle type: " - << static_cast(circleType) << std::endl; - return false; - } + if(!checkCircleParamConsistency(circleName,circleType,restrictedId,authorId,gxsIdMembers,localMembers)) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; + return false; + } // 2 - Create the actual request - RsGxsCircleGroup cData; - cData.mMeta.mGroupName = circleName; - cData.mMeta.mAuthorId = authorId; - cData.mMeta.mCircleType = static_cast(circleType); - cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - cData.mMeta.mCircleId = restrictedId; - cData.mLocalFriends = localMembers; - cData.mInvitedMembers = gxsIdMembers; + RsGxsCircleGroup cData; + cData.mMeta.mGroupName = circleName; + cData.mMeta.mAuthorId = authorId; + cData.mMeta.mCircleType = static_cast(circleType); + cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; + cData.mMeta.mCircleId = restrictedId; + cData.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ | GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; + cData.mLocalFriends = localMembers; + cData.mInvitedMembers = gxsIdMembers; + // 3 - Send it and wait, for a sync response. - uint32_t token; - createGroup(token, cData); + uint32_t token; + createGroup(token, cData); - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; - return false; - } + if(waitToken(token) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; + return false; + } - if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting created" << " group data." << std::endl; - return false; - } + if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting created" << " group data." << std::endl; + return false; + } - circleId = static_cast(cData.mMeta.mGroupId); - return true; + circleId = static_cast(cData.mMeta.mGroupId); + return true; }; +bool p3GxsCircles::checkCircleParamConsistency( const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) const +{ + if(circleName.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; + return false; + } + + switch(circleType) + { + case RsGxsCircleType::PUBLIC: + if(!restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId + << " must be null with RsGxsCircleType::PUBLIC" + << std::endl; + return false; + } + break; + case RsGxsCircleType::EXTERNAL: + if(restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId can't be null " + << "with RsGxsCircleType::EXTERNAL" << std::endl; + return false; + } + break; + case RsGxsCircleType::NODES_GROUP: + if(localMembers.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " localMembers can't be empty " + << "with RsGxsCircleType::NODES_GROUP" << std::endl; + return false; + } + break; + case RsGxsCircleType::LOCAL: + break; + case RsGxsCircleType::EXT_SELF: + if(!restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId + << " must be null with RsGxsCircleType::EXT_SELF" + << std::endl; + return false; + } + if(gxsIdMembers.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " gxsIdMembers can't be empty " + << "with RsGxsCircleType::EXT_SELF" << std::endl; + return false; + } + break; + case RsGxsCircleType::YOUR_EYES_ONLY: + break; + default: + RsErr() << __PRETTY_FUNCTION__ << " Invalid circle type: " + << static_cast(circleType) << std::endl; + return false; + } + return true; +} + bool p3GxsCircles::editCircle(RsGxsCircleGroup& cData) { uint32_t token; @@ -306,6 +321,52 @@ bool p3GxsCircles::editCircle(RsGxsCircleGroup& cData) return true; } +bool p3GxsCircles::editCircle(const RsGxsCircleId &circleId, const std::string& circleName, RsGxsCircleType circleType, const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) +{ + // 1 - Check consistency of the request data + + if(!checkCircleParamConsistency(circleName,circleType,restrictedId,authorId,gxsIdMembers,localMembers)) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle data is not consistent." << std::endl; + return false; + } + + // 2 - Create the actual request + + RsGxsCircleGroup cData; + cData.mMeta.mGroupId = RsGxsGroupId(circleId); + cData.mMeta.mGroupName = circleName; + cData.mMeta.mAuthorId = authorId; + cData.mMeta.mCircleType = static_cast(circleType); + cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; + cData.mMeta.mCircleId = restrictedId; + cData.mLocalFriends = localMembers; + cData.mInvitedMembers = gxsIdMembers; + + // 3 - Send it and wait, for a sync response. + + uint32_t token; + updateGroup(token, cData); + + if(waitToken(token) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." + << std::endl; + return false; + } + + if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated" + << " group data." << std::endl; + return false; + } + + return true; +}; + bool p3GxsCircles::getCirclesSummaries(std::list& circles) { uint32_t token; diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index a98e09184..3ff041ce1 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -227,7 +227,12 @@ public: const std::set& localMembers = std::set() ) override; - /// @see RsGxsCircles + bool editCircle( const RsGxsCircleId& circleId,const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) override; + + /// @see RsGxsCircles bool editCircle(RsGxsCircleGroup& cData) override; /// @see RsGxsCircles @@ -303,6 +308,10 @@ public: virtual void service_tick() override; protected: + bool checkCircleParamConsistency( const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) const ; // overloads p3Config virtual bool saveList(bool &cleanup, std::list&saveList) override; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d34f406a6..d35d3afe0 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1139,6 +1139,7 @@ bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, co goto LabelUpdateIdentityCleanup; } } + mKeyCache.erase(id); if(!updateGroup(token, group)) { @@ -1154,6 +1155,9 @@ bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, co goto LabelUpdateIdentityCleanup; } + // clean the Identity cache as well + cache_request_load(id); + LabelUpdateIdentityCleanup: if(!pseudonimous && !pgpPassword.empty()) rsNotify->clearPgpPassphrase(); From 15dd72ec7a2e7ae5b188720eced41554e91be5fd Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 3 Mar 2021 22:37:44 +0100 Subject: [PATCH 025/697] fixed internal GRP authentication flags of edited circles --- retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index d0640e4ea..2b9d3b804 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -449,7 +449,9 @@ void CreateCircleDialog::createCircle() case GxsIdChooser::KnowId: case GxsIdChooser::UnKnowId: circle.mMeta.mAuthorId = authorId; -#ifdef DEBUG_CREATE_CIRCLE_DIALOG + circle.mMeta.mAuthenFlags = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; + +#ifdef DEBUG_CREATE_CIRCLE_DIALOG std::cerr << "CreateCircleDialog::createCircle() AuthorId: " << authorId; std::cerr << std::endl; #endif @@ -457,6 +459,8 @@ void CreateCircleDialog::createCircle() break; case GxsIdChooser::NoId: case GxsIdChooser::None: + circle.mMeta.mAuthorId.clear(); + circle.mMeta.mAuthenFlags = 0; default: ; #ifdef DEBUG_CREATE_CIRCLE_DIALOG std::cerr << "CreateCircleDialog::createCircle() No AuthorId Chosen!"; From 66941ecb2108b0d3c0a21af1a611a23321a504e6 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 3 Mar 2021 22:38:05 +0100 Subject: [PATCH 026/697] fixed update interactivity in own identities and circles --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 11 +++++------ retroshare-gui/src/gui/Identity/IdDialog.h | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 016a8cb27..e8c39e75d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -408,9 +408,7 @@ IdDialog::IdDialog(QWidget *parent) connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool))); updateIdTimer.setSingleShot(true); - updateCircleTimer.setSingleShot(true); connect(&updateIdTimer, SIGNAL(timeout()), this, SLOT(updateIdList())); - connect(&updateCircleTimer, SIGNAL(timeout()), this, SLOT(updateCircles())); } void IdDialog::handleEvent_main_thread(std::shared_ptr event) @@ -429,7 +427,10 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsIdentityEventCode::UPDATED_IDENTITY: if (isVisible()) { - updateIdTimer.start(5000); + if(rsIdentity->isOwnId(RsGxsId(e->mIdentityId))) + updateIdList(); + else + updateIdTimer.start(3000); // use a timer for events not generated by local changes } else needUpdateIdsOnNextShow = true; @@ -460,9 +461,7 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsCircleEventCode::CACHE_DATA_UPDATED: if (isVisible()) - { - updateCircleTimer.start(5000); - } + updateCircles(); else needUpdateCirclesOnNextShow = true; default: diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 709fd3692..4e465fc5d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -154,7 +154,6 @@ private: RsEventsHandlerId_t mEventHandlerId_circles; QTimer updateIdTimer; - QTimer updateCircleTimer; bool needUpdateIdsOnNextShow; bool needUpdateCirclesOnNextShow; From 3d9ba341f0db012142a014b350edeffc84b20eff Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 5 Mar 2021 17:39:12 +0100 Subject: [PATCH 027/697] Fix Windows 64b G++ under MSys2 compil. --- libretroshare/src/util/rsthreads.cc | 4 +++- plugins/Common/retroshare_plugin.pri | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/util/rsthreads.cc b/libretroshare/src/util/rsthreads.cc index e931c8f1f..035ad214a 100644 --- a/libretroshare/src/util/rsthreads.cc +++ b/libretroshare/src/util/rsthreads.cc @@ -43,11 +43,13 @@ int RS_pthread_setname_np(pthread_t /*__target_thread*/, const char *__buf) { return pthread_setname_np(__buf); } #else +#ifndef __WIN64__ int __attribute__((weak)) pthread_setname_np(pthread_t __target_thread, const char *__buf) ; +#endif //__WIN64__ int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) { return pthread_setname_np(__target_thread, __buf); } -#endif +#endif //__APPLE__ /******* diff --git a/plugins/Common/retroshare_plugin.pri b/plugins/Common/retroshare_plugin.pri index 77812db81..5159aa9b1 100644 --- a/plugins/Common/retroshare_plugin.pri +++ b/plugins/Common/retroshare_plugin.pri @@ -102,6 +102,8 @@ win32 { for(lib, LIB_DIR):LIBS += -L"$$lib" for(bin, BIN_DIR):LIBS += -L"$$bin" LIBS += -lpthread + + QMAKE_LFLAGS += -Wl,--end-group } macx { From d78316cbd2148e976ed6614ea87c4ca0ee76a235 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 5 Mar 2021 12:10:40 +0100 Subject: [PATCH 028/697] Fix Chat History Browser --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 2 +- .../src/gui/im_history/ImHistoryBrowser.cpp | 14 ++++++-------- retroshare-gui/src/util/HandleRichText.cpp | 10 +++++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 2f43120ac..331aed893 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -403,7 +403,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) continue; QString name; - if (chatId.isLobbyId() || chatId.isDistantChatId()) + if (chatId.isLobbyId() || chatId.isDistantChatId() || chatId.isPeerId()) { RsIdentityDetails details; diff --git a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp index 19ffdac90..9f5f88e74 100644 --- a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp +++ b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp @@ -44,12 +44,8 @@ #define ROLE_PLAINTEXT Qt::UserRole + 1 ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const ChatId& peerId) - : QThread(parent) -{ - m_chatId = peerId; - m_historyBrowser = parent; - stopped = false; -} + : QThread(parent), m_historyBrowser(parent), m_chatId(peerId), stopped(false) +{} ImHistoryBrowserCreateItemsThread::~ImHistoryBrowserCreateItemsThread() { @@ -285,10 +281,12 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg) QString name; if (m_chatId.isLobbyId() || m_chatId.isDistantChatId()) { RsIdentityDetails details; - if (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details)) + if (rsIdentity->getIdDetails(RsGxsId(msg.peerId), details)) name = QString::fromUtf8(details.mNickname.c_str()); - else + else if(!msg.peerName.empty()) name = QString::fromUtf8(msg.peerName.c_str()); + else + name = QString::fromUtf8(msg.peerId.toStdString().c_str()); } else { name = QString::fromUtf8(msg.peerName.c_str()); } diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index b635703d7..dd33495b9 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -618,13 +618,13 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo QString errorMsg; int errorLine; int errorColumn; - QDomDocument doc; + QDomDocument doc; if (doc.setContent(formattedText, &errorMsg, &errorLine, &errorColumn) == false) { - // convert text with QTextBrowser - QTextBrowser textBrowser; - textBrowser.setText(text); - formattedText=textBrowser.toHtml(); + // convert text with QTextDocument + QTextDocument textDoc; + textDoc.setPlainText(text); + formattedText=textDoc.toHtml(); formattedText.remove(0,formattedText.indexOf("<")); formattedText=saveSpace(formattedText); doc.setContent(formattedText, &errorMsg, &errorLine, &errorColumn); From f7e409519d8f40f466dd550d513d97c3d10f4bc4 Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 7 Mar 2021 00:31:05 +0100 Subject: [PATCH 029/697] Wiki Editor and stylesheets fixes --- .../src/gui/WikiPoos/WikiEditDialog.cpp | 13 +++++++------ .../src/gui/WikiPoos/WikiEditDialog.ui | 15 ++++++++++++--- retroshare-gui/src/gui/icons.qrc | 1 + .../src/gui/icons/png/history-clock-blue.png | Bin 0 -> 3056 bytes .../src/gui/icons/png/history-clock-white.png | Bin 0 -> 2644 bytes .../src/gui/qss/stylesheet/Standard.qss | 17 +++++++++++++++++ retroshare-gui/src/qss/qdarkstyle-v2.qss | 2 +- retroshare-gui/src/qss/qdarkstyle.qss | 4 ++-- 8 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 retroshare-gui/src/gui/icons/png/history-clock-blue.png create mode 100644 retroshare-gui/src/gui/icons/png/history-clock-white.png diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 1918df882..077641621 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -88,6 +88,7 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) ui.toolButton_Show->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png"))); ui.toolButton_Hide->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png"))); ui.pushButton_Preview->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/search.png"))); + ui.pushButton_History->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/history-clock-white.png"))); ui.checkBox_OldHistory->setChecked(false); mOldHistoryEnabled = false; @@ -294,12 +295,12 @@ void WikiEditDialog::historyToggle() if (ui.groupBox_History->isHidden()) { ui.groupBox_History->show(); - ui.pushButton_History->setText(tr("Hide Edit History")); + ui.pushButton_History->setToolTip(tr("Hide Edit History")); } else { ui.groupBox_History->hide(); - ui.pushButton_History->setText(tr("Show Edit History")); + ui.pushButton_History->setToolTip(tr("Show Edit History")); } } @@ -409,7 +410,7 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) void WikiEditDialog::setNewPage() { mNewPage = true; - mRepublishMode = false; + mRepublishMode = false; mHistoryLoaded = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); @@ -418,14 +419,14 @@ void WikiEditDialog::setNewPage() redrawPage(); ui.treeWidget_History->clear(); ui.groupBox_History->hide(); - ui.pushButton_History->setText(tr("Show Edit History")); + ui.pushButton_History->setToolTip(tr("Show Edit History")); - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/addpage.png")); + ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/addpage.png")); ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); setWindowTitle(tr("Create New Wiki Page")); /* No need for for REQUIRED ID */ - ui.comboBox_IdChooser->loadIds(0, RsGxsId()); + ui.comboBox_IdChooser->loadIds(0, RsGxsId()); textReset(); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 04ce626fa..9181c9eb6 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -14,10 +14,19 @@ - + 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -246,7 +255,7 @@ - Show Edit History + History diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index 995157b69..48071b201 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -93,6 +93,7 @@ icons/png/forums.png icons/png/fullscreen_arrows.png icons/png/highlight.png + icons/png/history-clock-white.png icons/png/help.png icons/png/home.png icons/png/info.png diff --git a/retroshare-gui/src/gui/icons/png/history-clock-blue.png b/retroshare-gui/src/gui/icons/png/history-clock-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..562667468bf253dd23ed61ed4a7932532344f1c1 GIT binary patch literal 3056 zcmZ`)XIN9q79A40fQ_z(NxuC?zCOii!b2uu`OVK`&ATLF7q` z^cGYE6;M>JG^x^*eoqqh`F_0bn=`X#@3q%nd**!ST(`9`<6swL2LNzbm>b(eD~bBB z!l8NjQ~VmVFrG2AHUyv|cGspm6SNmQZEkN3K&T9aiv(buik}4FJPLrXZUAVd0>F>U zd}gNu04&AU%E1HzfV3Wv+y_!#g5++H*#?RRsGjsLkWQf*Y2CCLGJcJ8$bdrKAe90# zIss`1kL{o7)Y5fJ2&qj$7fNHMSA?7p z_-Chdsq~pHfL^+ndXhgAdq7qTjU4LncOmF4f-2HVL$&CFp(wRzH^}YkFhw>b*fxr8M4GBYV0i+I@lesz7WF*VR!9Jb5!YSZ_nCwLT}XXSK} zBdhhsLY^^$;PtOVvKc=@I5$aq!j~sb>JL6&yT+nELXo<(@@4Vp?ut?^5rnXzcU(=v z%dvE4|jM;tHhC?2_V(7ECGjrmsLytpkGI&^;8G{%m5p!t6hBJ32 z0KnNoeHfAyIE5f53(>;bgk=oQ%+GXC);WX-dDJY74IP4qW;3?XJSNEYi3J4e8)p=J z)PyI2jOKAQH#AgbdbX^?)r>%g#J8l_8rv;$xOVJLv})<^v$C9xvaftxqG+kx$WGL}9lnb@f4%Fn+u5$W?9qLFX0;n+ zz0+1Qu@?9b$e;j$#!^T}&w^3p-KC^|#>U+i4`z`V;t%i+#Ilic5l_i6n zcXWAJbs6`proL!%O7+WTPPW|GqpxYsdsoW_nK>HC&Z$Q|4dPZy${Qy%v2PYM2i*zv z;^FwEOG`KT6U+6vcQJ`x{T>q9&}VWm(e6eqzie{*Ye|V^L8;2`PKy$Xj@VZFtnIes z+L8o545sZ)VcET%hPvd0$pIvWP5P>Ov;{2wrXJs;Pnow17j=z$@ zo6)jrd-`wu;Ko2)jf*9@2+nI@iNG9gQ|Al#wCb2tVKF-h=8ZEBA^^MJ&_I zM)or2&a`V))+gVZn;0!scH{>~FEVSNvyIhY<#cl<#2lkAds}!-%uFh_Dhr)&3?HM6 zGa>WuzUBe!P3ugudS^Uf!u=Uz>2QMpk2G1gw@x4_dRZl%(ZFf`<)IT5M*(u)n3%+Y0mUYe3bce(2R*o#kwbR<-|Sxa z|D)N3@eP*zYx?;-PVBo*BH#wz114(gd&eSJ{N>tT zRU=MC#fh0Fk})SYG)r&0MhvRkqYpMqxW>T5`W>v-URCp93j!EDHQdq;wz7FQ$&20n zCa}rQmoBGH5dYG=KC5uc9!JjW)hJ;k&y|W@$IQSE@X20bEp&{3SBgP(f5zBKhcHjw zi>Od0Hl&=wbC{M7NL*2Gh|hU&l&EyP)MV?0`rbk;AXCYctJ+urhQ6_(8Xf}RK;240N>cMCkdKE)|pE6Wtx^>Q+`R;er*l7Y zH7@K)*4%U9k!`%gxF6d^OxB4nn-eq1OO8qMflZBb&#LN+uFYsDUo?xt>^!-?J}mCG z6Wik|WPaW;wIphjs4%;=*p|FFEc;Q^t)kvlq@e3R+x~xr^%m-Fu((ZR2{B)hyMAOp z=bXZK61K%kDNw~<*P~VZ-iq#Pd~9vVfnv?Nrz-5nm-q(mSL+HAtg>xtKkW0I@~~-K zU(tWvcx;E*s*7*4g8r$}L=z{Xr#sP0>ondAT7U{lMOhK0s)#z|prWdUQq%fNT>*vC zLZJ}c4F~=w!7sqm2OIML6Wnc>f$G literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/icons/png/history-clock-white.png b/retroshare-gui/src/gui/icons/png/history-clock-white.png new file mode 100644 index 0000000000000000000000000000000000000000..95e93d7ae418304c633a7058bd2e475e51e84eaa GIT binary patch literal 2644 zcmZ`*X*kpi7ysLhX{PK9*~yw=s$uNgFc`8%%5KDD9ZN#STq#TTHCvIb>}2R_3^KB2 z33aVEYc9!JyyQ+F-Vg7G_j%4azq9;)&-rwo=OkRWFotlzH~;{EU`!0H=}7$T?9BA& zgRIu21GBdtRu2FgQ^6;0Ec9B;!^9d30QY6+yf^?jrniXe01yfXfDKmwK;;1de_-Jo zD^2=<(cR405CC32kyNEupgaNI7i)6o2y>pVxuIqxGvc*m)ZCrfrP&+@y=QpX-%rBv_@kay^ zscy`rK|@iDc)sp-t@kTV1&MPWwA%N;aEtAe!O||>Hn!#Hx3ybd;?dE2&6%RZz9ZiH zl-`#P1Cx}9FbhiD;_*k$s$0D@K~e*g}8H{(Ca* zTaUhlI_5$x-xctp7(L?mWVh-`JF&Vu{DY<%tQ)K#SQ^h>9E@%um__p~PnNXvXKR`}#nmVQ0 z%wvQd=Jggn_#-sFfxKQ~cAW8UOMEU!lJEsI`kW6gCG`<@fB7jzN+sS@p)Pawf+aER zHIeva3a)U1HNQU4S@UT=T;Or2ysi-F9u?+ZuDm4?Lj_6A|x>Ij55Bg8G~O^Nx=8g701ofll-zZD85onnF8Q6Ofia8 zOm!#aQeBpc4(FXTzB({oQB~j@`d0Ka@#>AyE&}yFc;3qg{N2_(FCQePLfuWi?&pY2 z6sH!qy?X7)A-2N{UM*jBw_<5~xBTe>f>*amQ&F^1R*Avc1c2iiOciZpbg;%m80$(s zzy*Ht{s)Z4#L4pbO6-OnaX!cK)y#~GkaD1N^63y?;dC=Cb5BDH)((M_E1%~?L(R6o4^=)^| za=e)MS+l%GX-9J{%HPhd1IFujtx0nzoEie<$3Rbktt*AFObQSo7pr|u_`@^SUm5mVBju79Oa@8lNtne^WM{`jpPL%>G~W<03{4qAG62^Q zGVL+O47cWm`rCm~s{GOyqmDZjxwYKpo8EG|14t$oT7pWdpDsg5yhW>@xi=g8jRN1N z$Yc7&SjPERX!R}iN3sr_o435jtD7OvRq*`4Ri~L7-9EVd8F?mi5AlgxUcaaOfA;rc_SyI_kl`aEm1zg&GUIy_tf>|X)y%|ovh3#%1j)EAOBv;+g*Q*o8`QF zUW8*#LtqEzN*c@TjBVfztnP76W7lFzf@qH%M>NhrS_X%|znQry5g<4a@FogN(S(w3 zHrTn0OBA&_+kR7x)J?B|S@`V@s|ugIu2J#-P!)n_Yg=&mL*^mBi1F*ce>4{+z$Y87 zP6v^jf+9|?%-v2bXniLdC|{hyJa-iINGq{kBj;+TSmW4mS2K-+2VZdiE+^~WpVyEE zNT(D$+$~OZ>@8#9APWf?xG#%K* z=!{{_2lD%7O6NaWq6wk=xX4+gm89?9f_>j&)yVu+ltwNaC>doCmAYc-#5-413*Fp( zN~t1rFexEM4zhZK+IuCsI2PjSsW1of$NH4DeQ464+0Nk;FBz%?cnVdQ^v@x0(u_^i z7;?+L&_;3Y8fe~e5j^!m?mx1J*xMNbeIW3_uHja8P}tjYmCfyp9d~NYM843{Hnj@c2ZT=D#P`ovH1Ukw+C0=-wz5a<_uWLWQKc&`rH=D# zkj1&O5b|sLl{X8tiN@pLsoXj7F5is0RdhFZ!>7M?819;eBA{N+eOh1mehxn)Rq zjl{uB1_%m*h8vBn@LlYCD?TSe9W&oe4lXf(jd%xh$z|Pwd{oTT4%1q85u;2~ z9JxA)r%ZLjNvfYq!KLirDObBgcG#Uqht<~Es1Wr=)!5@#CFm9z`;=dKZ;cipDKc(6 zw@J>L+!4!(8Wr-*4xazolJB-7hf8 zTaoL3!1Cj0bzVYGG)MZR__{6L)$W&PGoH&$tushOLR$K)sWMeQE)kw=CpaBekg2&w@8^Lwz}urt^ByqO%g1S$3nRk z?O&f;;nU@}GDkH9a$(+3yv{{?b&?E7?q;O`AK r0l1KGw_q Date: Sun, 7 Mar 2021 01:04:27 +0100 Subject: [PATCH 030/697] fixing margin --- retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 9181c9eb6..c971c1398 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -121,6 +121,9 @@ + + 6 + From 6f78952df95b72a10ddb80d96d10890f33e63ce7 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 7 Mar 2021 21:00:53 +0100 Subject: [PATCH 031/697] fixed error msg --- libretroshare/src/services/p3gxscircles.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 43032db70..f1f39a792 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -196,7 +196,7 @@ bool p3GxsCircles::createCircle( if(!checkCircleParamConsistency(circleName,circleType,restrictedId,authorId,gxsIdMembers,localMembers)) { - RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; + RsErr() << __PRETTY_FUNCTION__ << " Circle parameters are inconsistent" << std::endl; return false; } From 0fa8573dbd8d74772fabbd01879ee51a12a7a657 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 7 Mar 2021 21:27:13 +0100 Subject: [PATCH 032/697] removed inconsistent arrows from network list --- retroshare-gui/src/gui/qss/stylesheet/Standard.qss | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index a9c191749..162fbe270 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -1213,14 +1213,3 @@ NewFriendList QTreeView#peerTreeWidget { font-size: 12pt; } -NewFriendList QTreeView::branch:has-children:!has-siblings:closed, -NewFriendList QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-right.png); -} - -NewFriendList QTreeView::branch:open:has-children:!has-siblings, -NewFriendList QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-down.png); -} From 74dc4762820ad31157c0019722cef0495305f298 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 8 Mar 2021 20:07:07 +0100 Subject: [PATCH 033/697] Fix list overwrite in RsGxsNetService::requestGrp When requestGrp was called with different groups for same peer multiple times between ticks the list was overridden and groups from previous call overridden by the new, as a result some requested groups may be never really requested. Fix the bug by using a set instead of a list so the newly requested groups are uniquely added to the set without removing the previously added. --- libretroshare/src/gxs/rsgxsnetservice.cc | 41 +++++++++++------------- libretroshare/src/gxs/rsgxsnetservice.h | 2 +- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 888a54aa2..e1b70a670 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -256,10 +256,8 @@ #include "util/rstime.h" #include "util/rsmemory.h" #include "util/stacktrace.h" - -#ifdef RS_DEEP_CHANNEL_INDEX -# include "deep_search/channelsindex.hpp" -#endif +#include "util/rsdebug.h" +#include "util/cxx17retrocompat.h" /*** * Use the following defines to debug: @@ -4806,43 +4804,40 @@ uint32_t RsGxsNetService::getKeepAge(const RsGxsGroupId& grpId) return locked_getGrpConfig(grpId).msg_keep_delay ; } -int RsGxsNetService::requestGrp(const std::list& grpId, const RsPeerId& peerId) +int RsGxsNetService::requestGrp( + const std::list& grpIds, const RsPeerId& peerId ) { - RS_STACK_MUTEX(mNxsMutex) ; #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peerId) << "RsGxsNetService::requestGrp(): adding explicit group requests to peer " << peerId << std::endl; - - for(std::list::const_iterator it(grpId.begin());it!=grpId.end();++it) - GXSNETDEBUG_PG(peerId,*it) << " Group ID: " << *it << std::endl; + RS_DBG("Adding explicit groups requests to peer: ", peerId); + for(auto& grpId: std::as_const(grpIds)) RS_DBG("\t Group ID: ", grpId); #endif - mExplicitRequest[peerId].assign(grpId.begin(), grpId.end()); + + RS_STACK_MUTEX(mNxsMutex); + mExplicitRequest[peerId].insert(grpIds.begin(), grpIds.end()); return 1; } void RsGxsNetService::processExplicitGroupRequests() { - RS_STACK_MUTEX(mNxsMutex) ; + RS_STACK_MUTEX(mNxsMutex); - std::map >::const_iterator cit = mExplicitRequest.begin(); - - for(; cit != mExplicitRequest.end(); ++cit) + for(auto& cit: std::as_const(mExplicitRequest)) { #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(cit->first) << "RsGxsNetService::sending pending explicit group requests to peer " << cit->first << std::endl; + RS_DBG("sending pending explicit group requests to peer ", cit.first); #endif - const RsPeerId& peerId = cit->first; - const std::list& groupIdList = cit->second; + const RsPeerId& peerId = cit.first; + const std::set& groupIdList = cit.second; std::list grpSyncItems; - std::list::const_iterator git = groupIdList.begin(); uint32_t transN = locked_getTransactionId(); - for(; git != groupIdList.end(); ++git) + for(auto& grpId: std::as_const(groupIdList)) { #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peerId) << " group request for grp ID " << *git << " to peer " << peerId << std::endl; + RS_DBG("\t group request for group ID: ", grpId); #endif - RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType); - item->grpId = *git; + RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType); + item->grpId = grpId; item->PeerId(peerId); item->flag = RsNxsSyncGrpItem::FLAG_REQUEST; item->transactionNumber = transN; diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index b619896b1..295b8232a 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -584,7 +584,7 @@ private: std::vector mPendingResp; std::vector mPendingCircleVets; std::map > mPendingPublishKeyRecipients ; - std::map > mExplicitRequest; + std::map > mExplicitRequest; std::map > mPartialMsgUpdates ; // nxs sync optimisation From 20c313142249d1c9b2857de24bbd9ed6b115e3a1 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 8 Mar 2021 20:12:50 +0100 Subject: [PATCH 034/697] Fix define_default_value in android scripts define_default_value wrongly reported error if the variable was already defined, causing the scripts to fail under bash -e, fix it by reporting corret exit value --- build_scripts/Android/prepare-toolchain-clang.sh | 2 +- build_scripts/Android/start_gdbserver.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 2c64a5186..83c30721b 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -28,7 +28,7 @@ function define_default_value() VAR_NAME="${1}" DEFAULT_VALUE="${2}" - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true } ## You are supposed to provide the following variables according to your system setup diff --git a/build_scripts/Android/start_gdbserver.sh b/build_scripts/Android/start_gdbserver.sh index af25e3be1..1fd751e67 100755 --- a/build_scripts/Android/start_gdbserver.sh +++ b/build_scripts/Android/start_gdbserver.sh @@ -36,7 +36,7 @@ function define_default_value() VAR_NAME="${1}" DEFAULT_VALUE="${2}" - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true } define_default_value ANDROID_APK_PACKAGE "org.retroshare.service" From 8df1f0bf416261a6dce2667df76be0deb8d48c1f Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 8 Mar 2021 20:51:21 +0100 Subject: [PATCH 035/697] fixed crash due to using twice the same method name in p3gxscircles.h wiht json api header --- libretroshare/src/retroshare/rsgxscircles.h | 52 +++++++++++---------- libretroshare/src/services/p3gxscircles.h | 2 +- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 8b94bd829..32bc8e547 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -301,33 +301,35 @@ public: const std::set& gxsIdMembers = std::set(), const std::set& localMembers = std::set() ) = 0; - /** - * @brief Edit an existing circle - * @jsonapi{development} - * @param[in] circleId Optional storage to output created circle id - * @param[in] circleName String containing cirlce name - * @param[in] circleType Circle type - * @param[in] restrictedId Optional id of a pre-existent circle that see the - * created circle. Meaningful only if circleType == EXTERNAL, must be null - * in all other cases. - * @param[in] authorId Optional author of the circle. - * @param[in] gxsIdMembers GXS ids of the members of the circle. - * @param[in] localMembers PGP ids of the members if the circle. - * @return false if something failed, true otherwhise - */ - virtual bool editCircle( const RsGxsCircleId& circleId, const std::string& circleName, RsGxsCircleType circleType, - const RsGxsCircleId& restrictedId, - const RsGxsId& authorId, const std::set& gxsIdMembers, - const std::set& localMembers ) =0; +// TODO. If so, remove the other editCircle that has the same name, otherwise jsonapi will crash +// +// /** +// * @brief Edit an existing circle +// * @jsonapi{development} +// * @param[in] circleId Optional storage to output created circle id +// * @param[in] circleName String containing cirlce name +// * @param[in] circleType Circle type +// * @param[in] restrictedId Optional id of a pre-existent circle that see the +// * created circle. Meaningful only if circleType == EXTERNAL, must be null +// * in all other cases. +// * @param[in] authorId Optional author of the circle. +// * @param[in] gxsIdMembers GXS ids of the members of the circle. +// * @param[in] localMembers PGP ids of the members if the circle. +// * @return false if something failed, true otherwhise +// */ +// virtual bool editCircle( const RsGxsCircleId& circleId, const std::string& circleName, RsGxsCircleType circleType, +// const RsGxsCircleId& restrictedId, +// const RsGxsId& authorId, const std::set& gxsIdMembers, +// const std::set& localMembers ) =0; /** - * @brief Edit own existing circle - * @jsonapi{development} - * @param[inout] cData Circle data with modifications, storage for data - * updatedad during the operation. - * @return false if something failed, true otherwhise - */ - virtual bool editCircle(RsGxsCircleGroup& cData) = 0; + * @brief Edit own existing circle + * @jsonapi{development} + * @param[inout] cData Circle data with modifications, storage for data + * updatedad during the operation. + * @return false if something failed, true otherwhise + */ + virtual bool editCircle(RsGxsCircleGroup& cData) = 0; /** * @brief Get circle details. Memory cached diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index 3ff041ce1..e71e26ed0 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -230,7 +230,7 @@ public: bool editCircle( const RsGxsCircleId& circleId,const std::string& circleName, RsGxsCircleType circleType, const RsGxsCircleId& restrictedId, const RsGxsId& authorId, const std::set& gxsIdMembers, - const std::set& localMembers ) override; + const std::set& localMembers ) ; /// @see RsGxsCircles bool editCircle(RsGxsCircleGroup& cData) override; From 50ed20236fc6a1edce5f741bc97d9574bcccbe32 Mon Sep 17 00:00:00 2001 From: altcoinpirate <62118463+altcoinpirate@users.noreply.github.com> Date: Wed, 10 Mar 2021 01:13:15 +0000 Subject: [PATCH 036/697] Disable animation in file transfer search dialog tree view widget --- retroshare-gui/src/gui/FileTransfer/SearchDialog.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui index ad8c61068..4aa868b56 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui @@ -223,6 +223,9 @@ true + + false + KeyWords @@ -261,6 +264,9 @@ true + + false + Filename From 73355d09e3b52b739fc0c65ec06f62af1a1e0e06 Mon Sep 17 00:00:00 2001 From: altcoinpirate <62118463+altcoinpirate@users.noreply.github.com> Date: Wed, 10 Mar 2021 01:16:50 +0000 Subject: [PATCH 037/697] Disable animation in file transfer shared files tree view widget --- retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui index b1f4ceb9b..8bf177546 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui @@ -366,6 +366,9 @@ border-image: url(:/images/closepressed.png) true + + false + false From 85bfb48890c80f099d8f8630d5fa806db5a06ba2 Mon Sep 17 00:00:00 2001 From: altcoinpirate <62118463+altcoinpirate@users.noreply.github.com> Date: Wed, 10 Mar 2021 01:19:45 +0000 Subject: [PATCH 038/697] Disable animation in ft transfers dialog tree view widget --- retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui index d2e7a9ab6..121af8a85 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui @@ -213,6 +213,9 @@ true + + false + false @@ -280,6 +283,9 @@ true + + false + From 61a79b296efec1575507a40badc76dbcd66cf0e4 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 10 Mar 2021 20:43:43 +0100 Subject: [PATCH 039/697] fixed expanded group items in NewFriendList. Added more debug info --- .../src/gui/common/FriendListModel.cpp | 3 +- .../src/gui/common/NewFriendList.cpp | 64 +++++++++---------- retroshare-gui/src/gui/common/NewFriendList.h | 4 +- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index 0ce266135..a2ae9052d 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -663,7 +663,8 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const else return QVariant(QString::fromUtf8(group->group_info.name.c_str())); - //case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); + case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); + default: return QVariant(); } diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 297217ac9..2ed099511 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -101,6 +101,7 @@ * #define FRIENDS_DEBUG 1 * #define DEBUG_NEW_FRIEND_LIST 1 *****/ +#define DEBUG_NEW_FRIEND_LIST 1 Q_DECLARE_METATYPE(ElidedLabel*) @@ -377,7 +378,7 @@ void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_in #endif for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursSaveExpandedItems(mProxyModel->index(row,0),current_index,QString(),expanded_indexes,sel); + recursSaveExpandedItems(mProxyModel->index(row,0),current_index,QString(),expanded_indexes,sel,0); #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << " selected index: \"" << sel.toStdString() << "\"" << std::endl; @@ -394,54 +395,51 @@ void NewFriendList::restoreExpandedPathsAndSelection(const std::set& ex ui->peerTreeWidget->blockSignals(true) ; for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,index_to_select,selected_index); + recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,index_to_select,selected_index,0); ui->peerTreeWidget->blockSignals(false) ; } -void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QModelIndex& current_index,const QString& parent_path,std::set& exp, QString& sel) +void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QModelIndex& current_index,const QString& parent_path,std::set& exp, QString& sel,int indx) { - QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; + QString local_path = parent_path + (parent_path.isNull()?"":"/") + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() ; #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << " At index " << index.row() << ". data[1]=" << local_path.toStdString() ; + for(int i=0;ipeerTreeWidget->isExpanded(index)) { #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << " Index is expanded." ; + std::cerr << " expanded." << std::endl; #endif if(index.isValid()) exp.insert(local_path) ; for(int row=0;rowrowCount(index);++row) - recursSaveExpandedItems(index.child(row,0),current_index,local_path,exp,sel) ; + recursSaveExpandedItems(index.child(row,0),current_index,local_path,exp,sel,indx+1) ; } #ifdef DEBUG_NEW_FRIEND_LIST else - std::cerr << " not expanded." ; + std::cerr << " not expanded." << std::endl; #endif if(index == current_index) - { -#ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << " adding to selection!" << std::endl; -#endif sel = local_path ; - } -#ifdef DEBUG_NEW_FRIEND_LIST - else - std::cerr << std::endl; -#endif - - } -void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString& sel,QModelIndex& selected_index) +void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString& sel,QModelIndex& selected_index,int indx) { - QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; + QString local_path = parent_path + (parent_path.isNull()?"":"/") + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() ; #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << " At index " << index.row() << ". data[1]=" << local_path.toStdString() ; + for(int i=0;ipeerTreeWidget->setExpanded(index,true) ; for(int row=0;rowrowCount(index);++row) - recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel,selected_index) ; - } - - if(sel == local_path) - { -#ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << " selecting index \"" << local_path.toStdString() << "\"" << std::endl; -#endif - ui->peerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - selected_index = index; + recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel,selected_index,indx+1) ; } #ifdef DEBUG_NEW_FRIEND_LIST else std::cerr << std::endl; #endif - + if(sel == local_path) + { + ui->peerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + selected_index = index; + } } @@ -1126,7 +1119,10 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) saveExpandedPathsAndSelection(expanded_indexes, selected); #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "After collecting selection, selected paths is: \"" << selected.toStdString() << "\"" << std::endl; + std::cerr << "After collecting selection, selected paths is: \"" << selected.toStdString() << "\", " ; + std::cerr << "expanded paths are: " << std::endl; + for(auto path:expanded_indexes) + std::cerr << " \"" << path.toStdString() << "\"" << std::endl; #endif whileBlocking(ui->peerTreeWidget)->clearSelection(); diff --git a/retroshare-gui/src/gui/common/NewFriendList.h b/retroshare-gui/src/gui/common/NewFriendList.h index 67ae9e651..cf2e892b3 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.h +++ b/retroshare-gui/src/gui/common/NewFriendList.h @@ -106,8 +106,8 @@ private: void applyWhileKeepingTree(std::function predicate); void expandGroup(const RsNodeGroupId& gid); - void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString &sel, QModelIndex &selected_index); - void recursSaveExpandedItems(const QModelIndex& index, const QModelIndex& current_index, const QString& parent_path, std::set& exp, QString &sel); + void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString &sel, QModelIndex &selected_index,int indx); + void recursSaveExpandedItems(const QModelIndex& index, const QModelIndex& current_index, const QString& parent_path, std::set& exp, QString &sel,int indx); void saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel); void restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const QString &index_to_select, QModelIndex &selected_index); From e750a3fced899cc5b5c49829635739a60367edc8 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 10 Mar 2021 21:04:23 +0100 Subject: [PATCH 040/697] improved debug output and code in NewFriendList sorting --- retroshare-gui/src/gui/common/NewFriendList.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 2ed099511..9037863c7 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -119,7 +119,7 @@ public: bool lessThan(const QModelIndex& left, const QModelIndex& right) const override { - bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; + bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; bool is_group_2 = right.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; if(is_group_1 ^ is_group_2) // if the two are different, put the group first. @@ -128,10 +128,10 @@ public: bool online1 = (left .data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); bool online2 = (right.data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); - if(online1 != online2 && m_sortByState) + if((online1 != online2) && m_sortByState) return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?online1:online2 ; // always put online nodes first - return left.data(RsFriendListModel::SortRole) < right.data(RsFriendListModel::SortRole) ; + return QSortFilterProxyModel::lessThan(left,right); } bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override @@ -1123,6 +1123,7 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) std::cerr << "expanded paths are: " << std::endl; for(auto path:expanded_indexes) std::cerr << " \"" << path.toStdString() << "\"" << std::endl; + std::cerr << "Current sort column is: " << mLastSortColumn << " and order is " << mLastSortOrder << std::endl; #endif whileBlocking(ui->peerTreeWidget)->clearSelection(); @@ -1140,7 +1141,9 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) col_sizes[i] = ui->peerTreeWidget->columnWidth(i); } - +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Applying predicate..." << std::endl; +#endif mProxyModel->setSourceModel(nullptr); predicate(); @@ -1158,6 +1161,9 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) // restore sorting // sortColumn(mLastSortColumn,mLastSortOrder); +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Sorting again with sort column: " << mLastSortColumn << " and order " << mLastSortOrder << std::endl; +#endif mProxyModel->sort(mLastSortColumn,mLastSortOrder); if(selected_index.isValid()) @@ -1166,6 +1172,9 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) void NewFriendList::sortColumn(int col,Qt::SortOrder so) { +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Sorting with column=" << col << " and order=" << so << std::endl; +#endif std::set expanded_indexes; QString selected; QModelIndex selected_index; From 30e59133cb3cf37dec3370261a7ff53573e8b56f Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 10 Mar 2021 21:43:37 +0100 Subject: [PATCH 041/697] proper loading/saving of onLineFriendsOnTop and showOffLineFriends --- .../src/gui/common/NewFriendList.cpp | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 9037863c7..58d4966e5 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -213,7 +213,7 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par /* Set sort */ sortColumn(RsFriendListModel::COLUMN_THREAD_NAME, Qt::AscendingOrder); - toggleSortByState(false); + // workaround for Qt bug, should be solved in next Qt release 4.7.0 // http://bugreports.qt.nokia.com/browse/QTBUG-8270 QShortcut *Shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->peerTreeWidget, 0, 0, Qt::WidgetShortcut); @@ -236,6 +236,8 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par QHeaderView *h = ui->peerTreeWidget->header(); h->setContextMenuPolicy(Qt::CustomContextMenu); + processSettings(true); + connect(ui->peerTreeWidget->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumn(int,Qt::SortOrder))); connect(ui->peerTreeWidget, SIGNAL(expanded(const QModelIndex&)), this, SLOT(itemExpanded(const QModelIndex&))); @@ -473,20 +475,26 @@ void NewFriendList::processSettings(bool load) if (load) // load settings { std::cerr <<"Re-loading settings..." << std::endl; + // sort + mProxyModel->setSortByState( Settings->value("sortByState", mProxyModel->sortByState()).toBool()); + mProxyModel->setShowOfflineNodes(!Settings->value("hideUnconnected", !mProxyModel->showOfflineNodes()).toBool()); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Loading sortByState=" << mProxyModel->sortByState() << std::endl; +#endif + // states setShowUnconnected(!Settings->value("hideUnconnected", !mProxyModel->showOfflineNodes()).toBool()); - setShowState(Settings->value("showState", mModel->getDisplayStatusString()).toBool()); - setShowGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool()); + + mModel->setDisplayStatusString(Settings->value("showState", mModel->getDisplayStatusString()).toBool()); + mModel->setDisplayGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_IP,Settings->value("showIP", isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP)).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_ID,Settings->value("showID", isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID)).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT,Settings->value("showLastContact", isColumnVisible(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT)).toBool()); ui->peerTreeWidget->header()->restoreState(Settings->value("headers").toByteArray()); - // sort - toggleSortByState(Settings->value("sortByState", mProxyModel->sortByState()).toBool()); - - // open groups + // open groups int arrayIndex = Settings->beginReadArray("Groups"); for (int index = 0; index < arrayIndex; ++index) { Settings->setArrayIndex(index); @@ -511,8 +519,9 @@ void NewFriendList::processSettings(bool load) // sort Settings->setValue("sortByState", mProxyModel->sortByState()); - - Settings->endArray(); +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Saving sortByState=" << mProxyModel->sortByState() << std::endl; +#endif } } @@ -520,6 +529,7 @@ void NewFriendList::toggleSortByState(bool sort) { mProxyModel->setSortByState(sort); mProxyModel->setFilterRegExp(QRegExp(QString(RsFriendListModel::FilterString))) ;// triggers a re-display. + processSettings(false); } void NewFriendList::changeEvent(QEvent *e) @@ -1605,11 +1615,13 @@ void NewFriendList::toggleColumnVisible() void NewFriendList::setShowState(bool show) { applyWhileKeepingTree([show,this]() { mModel->setDisplayStatusString(show) ; }); + processSettings(false); } void NewFriendList::setShowGroups(bool show) { applyWhileKeepingTree([show,this]() { mModel->setDisplayGroups(show) ; }); + processSettings(false); } /** From a5afc2226ce8eb8f7d9520b5448aa88a4fbeeaa7 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 11 Mar 2021 21:12:14 +0100 Subject: [PATCH 042/697] fixed sorting lost issue in Network --- retroshare-gui/src/gui/common/NewFriendList.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 58d4966e5..5c7254606 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -105,6 +105,13 @@ Q_DECLARE_METATYPE(ElidedLabel*) +#ifdef DEBUG_NEW_FRIEND_LIST +static std::ostream& operator<<(std::ostream& o,const QModelIndex& i) +{ + return o << "(" << i.row() << "," << i.column() << ")"; +} +#endif + class FriendListSortFilterProxyModel: public QSortFilterProxyModel { public: @@ -131,6 +138,9 @@ public: if((online1 != online2) && m_sortByState) return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?online1:online2 ; // always put online nodes first +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Comparing index " << left << " with index " << right << std::endl; +#endif return QSortFilterProxyModel::lessThan(left,right); } @@ -1174,7 +1184,9 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << "Sorting again with sort column: " << mLastSortColumn << " and order " << mLastSortOrder << std::endl; #endif + mProxyModel->setSortingEnabled(true); mProxyModel->sort(mLastSortColumn,mLastSortOrder); + mProxyModel->setSortingEnabled(false); if(selected_index.isValid()) ui->peerTreeWidget->scrollTo(selected_index); From bd6148ab0fe626ccc2a334cd56cd2beafd0c9df4 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 11 Mar 2021 23:42:09 +0100 Subject: [PATCH 043/697] removed debug output --- retroshare-gui/src/gui/common/NewFriendList.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 5c7254606..ba794fafe 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -101,7 +101,6 @@ * #define FRIENDS_DEBUG 1 * #define DEBUG_NEW_FRIEND_LIST 1 *****/ -#define DEBUG_NEW_FRIEND_LIST 1 Q_DECLARE_METATYPE(ElidedLabel*) From 21105cac17c13459ea3d81ba6c82fe5e9aad6514 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 13 Mar 2021 11:51:06 +0100 Subject: [PATCH 044/697] Fix HandleRichText --- retroshare-gui/src/util/HandleRichText.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index dd33495b9..409d37aa6 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -623,7 +623,11 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo // convert text with QTextDocument QTextDocument textDoc; - textDoc.setPlainText(text); + if (Qt::mightBeRichText(formattedText)) + textDoc.setHtml(formattedText); + else + textDoc.setPlainText(text); + formattedText=textDoc.toHtml(); formattedText.remove(0,formattedText.indexOf("<")); formattedText=saveSpace(formattedText); From 8ef464e21ee6be0de2c5caec215377d229bf7d29 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 13 Mar 2021 13:05:07 +0100 Subject: [PATCH 045/697] Fix Remove bad RS_ERR in FriendListModel --- retroshare-gui/src/gui/common/FriendListModel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index a2ae9052d..9d2bfa50b 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -236,7 +236,8 @@ RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::parent() const i.node_index = UNDEFINED_NODE_INDEX_VALUE; break; case ENTRY_TYPE_UNKNOWN: - RS_ERR("Unknown Entry type for parent."); + //Can be when request root index. + break; } return i; From c9d7cb7e7ea19cca4a685968b9976a9a18161400 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 13 Mar 2021 22:27:43 +0100 Subject: [PATCH 046/697] fixed wrong define in debug for circles --- libretroshare/src/services/p3gxscircles.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index f1f39a792..0b7bc9570 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -1781,7 +1781,7 @@ rstime_t p3GxsCircles::service_getLastGroupSeenTs(const RsGxsGroupId& gid) } bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) { -#ifdef GXSFORUMS_CHANNELS +#ifdef GXSFORUMS_CIRCLES std::cerr << "p3gxsChannels: Checking unused circles: called by GxsCleaning." << std::endl; #endif @@ -1794,7 +1794,7 @@ bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) auto it = mKnownCircles.find(meta.mGroupId); bool unknown_posted = (it == mKnownCircles.end()); -#ifdef GXSFORUMS_CHANNELS +#ifdef GXSFORUMS_CIRCLES std::cerr << " Circle " << meta.mGroupId ; #endif @@ -1803,7 +1803,7 @@ bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) // This case should normally not happen. It does because this board was never registered since it may // arrived before this code was here -#ifdef GXSFORUMS_CHANNELS +#ifdef GXSFORUMS_CIRCLES std::cerr << ". Not known yet. Adding current time as new TS." << std::endl; #endif mKnownCircles[meta.mGroupId] = now; @@ -1816,18 +1816,20 @@ bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) bool used_by_friends = (now < it->second + CIRCLES_UNUSED_BY_FRIENDS_DELAY); bool subscribed = static_cast(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); +#ifdef GXSFORUMS_CIRCLES std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)"; +#endif if(!subscribed && !used_by_friends) { -#ifdef GXSFORUMS_CHANNELS +#ifdef GXSFORUMS_CIRCLES std::cerr << ". Scheduling for deletion" << std::endl; #endif return false; } else { -#ifdef GXSFORUMS_CHANNELS +#ifdef GXSFORUMS_CIRCLES std::cerr << ". Keeping!" << std::endl; #endif return true; From f1b022a6c1b09d75f2bf0724e2379b621fb74188 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 13 Mar 2021 22:28:06 +0100 Subject: [PATCH 047/697] only print the 50 first characters of undisplayed resources --- retroshare-gui/src/gui/common/RSTextBrowser.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/RSTextBrowser.cpp b/retroshare-gui/src/gui/common/RSTextBrowser.cpp index 96180b874..cd2bd988e 100644 --- a/retroshare-gui/src/gui/common/RSTextBrowser.cpp +++ b/retroshare-gui/src/gui/common/RSTextBrowser.cpp @@ -161,7 +161,11 @@ QVariant RSTextBrowser::loadResource(int type, const QUrl &name) // case 4: otherwise, do not display - std::cerr << "TEXTBROWSER: refusing load ressource request: type=" << type << " scheme=" << name.scheme().toStdString() << ", url=" << name.toString().toStdString() << std::endl; + std::cerr << "TEXTBROWSER: refusing load ressource request: type=" << type << " scheme=" + << name.scheme().toStdString() << ", url=" + << name.toString().left(50).toStdString() + << ((name.toString().length()>50)?"...":"") + << std::endl; if (mImageBlockWidget) mImageBlockWidget->show(); From 4420575a9ae42559931fb875d741a84eae75990c Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 13 Mar 2021 22:28:26 +0100 Subject: [PATCH 048/697] removed debug info about superseded groups --- libretroshare/src/gxstrans/p3gxstrans.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libretroshare/src/gxstrans/p3gxstrans.h b/libretroshare/src/gxstrans/p3gxstrans.h index 688a9cd22..aff7b9eda 100644 --- a/libretroshare/src/gxstrans/p3gxstrans.h +++ b/libretroshare/src/gxstrans/p3gxstrans.h @@ -272,8 +272,7 @@ private: { if(mPreferredGroupId < potentialGrId) { - std::cerr << "supersedePreferredGroup(...) " << potentialGrId - << " supersed " << mPreferredGroupId << std::endl; + // std::cerr << "supersedePreferredGroup(...) " << potentialGrId << " supersed " << mPreferredGroupId << std::endl; mPreferredGroupId = potentialGrId; return true; } From 388140e263aa295a311fb2e024ad573aa61ed319 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 13 Mar 2021 22:28:52 +0100 Subject: [PATCH 049/697] added missing debug ifdef --- retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp b/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp index 7d869ab57..76622625b 100644 --- a/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp +++ b/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp @@ -96,14 +96,18 @@ void RSPermissionMatrixWidget::updateDisplay() void RSPermissionMatrixWidget::mousePressEvent(QMouseEvent *e) { +#ifdef DEBUG_PERMISSION_MATRIX std::cerr << "mouse pressed at x=" << e->x() << ", y=" << e->y() << std::endl; +#endif uint32_t service_id ; RsPeerId peer_id ; if(computeServiceAndPeer(e->x(),e->y(),service_id,peer_id)) { +#ifdef DEBUG_PERMISSION_MATRIX std::cerr << "Peer id: " << peer_id << ", service: " << service_id << std::endl; +#endif // Make sure the service is not globally disabled From c8ab9e0bd507afa0b1b41b62db248d40502037ac Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 14 Mar 2021 00:47:57 +0100 Subject: [PATCH 050/697] attempt to fix --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cfe2eac21..9b0be7fa6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ matrix: sudo: required compiler: gcc - os: osx - osx_image: xcode10.1 + osx_image: xcode10.2 compiler: clang sudo: false From 017f2886b33f07efc289c2b25d86179575bd5c83 Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 16 Mar 2021 11:00:18 +0100 Subject: [PATCH 051/697] Fix Name in Broadcast history restore. --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 331aed893..e330f49d3 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -403,7 +403,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) continue; QString name; - if (chatId.isLobbyId() || chatId.isDistantChatId() || chatId.isPeerId()) + if (!chatId.isNotSet()) { RsIdentityDetails details; From 76f0678820bf5b00b6a3d27b2d2daacc1ab5d7fc Mon Sep 17 00:00:00 2001 From: sehraf Date: Mon, 26 Oct 2020 21:45:03 +0100 Subject: [PATCH 052/697] add fork of libsam3 add funtion to get i2p certificate crypto algo names --- .gitignore | 2 + libretroshare/src/util/i2pcommon.cpp | 113 +- libretroshare/src/util/i2pcommon.h | 9 + supportlibs/libsam3/Makefile | 41 + supportlibs/libsam3/README.md | 18 + supportlibs/libsam3/examples/libsam3 | 1 + supportlibs/libsam3/examples/sam3/README.md | 26 + supportlibs/libsam3/examples/sam3/dgramc.c | 116 ++ supportlibs/libsam3/examples/sam3/dgrams.c | 113 ++ .../libsam3/examples/sam3/namelookup.c | 43 + supportlibs/libsam3/examples/sam3/samtest.c | 51 + supportlibs/libsam3/examples/sam3/streamc.c | 87 + supportlibs/libsam3/examples/sam3/streams.c | 72 + supportlibs/libsam3/examples/sam3a/test00.c | 178 ++ supportlibs/libsam3/examples/sam3a/test_sc.c | 205 ++ supportlibs/libsam3/examples/sam3a/test_ss.c | 236 +++ supportlibs/libsam3/src/ext/tinytest.c | 466 +++++ supportlibs/libsam3/src/ext/tinytest.h | 104 + supportlibs/libsam3/src/ext/tinytest_macros.h | 219 ++ supportlibs/libsam3/src/libsam3/libsam3.c | 1304 ++++++++++++ supportlibs/libsam3/src/libsam3/libsam3.h | 280 +++ supportlibs/libsam3/src/libsam3a/libsam3a.c | 1757 +++++++++++++++++ supportlibs/libsam3/src/libsam3a/libsam3a.h | 361 ++++ supportlibs/libsam3/test/libsam3/test_b32.c | 51 + supportlibs/libsam3/test/test.c | 12 + 25 files changed, 5858 insertions(+), 7 deletions(-) create mode 100644 supportlibs/libsam3/Makefile create mode 100644 supportlibs/libsam3/README.md create mode 120000 supportlibs/libsam3/examples/libsam3 create mode 100644 supportlibs/libsam3/examples/sam3/README.md create mode 100644 supportlibs/libsam3/examples/sam3/dgramc.c create mode 100644 supportlibs/libsam3/examples/sam3/dgrams.c create mode 100644 supportlibs/libsam3/examples/sam3/namelookup.c create mode 100644 supportlibs/libsam3/examples/sam3/samtest.c create mode 100644 supportlibs/libsam3/examples/sam3/streamc.c create mode 100644 supportlibs/libsam3/examples/sam3/streams.c create mode 100644 supportlibs/libsam3/examples/sam3a/test00.c create mode 100644 supportlibs/libsam3/examples/sam3a/test_sc.c create mode 100644 supportlibs/libsam3/examples/sam3a/test_ss.c create mode 100644 supportlibs/libsam3/src/ext/tinytest.c create mode 100644 supportlibs/libsam3/src/ext/tinytest.h create mode 100644 supportlibs/libsam3/src/ext/tinytest_macros.h create mode 100644 supportlibs/libsam3/src/libsam3/libsam3.c create mode 100644 supportlibs/libsam3/src/libsam3/libsam3.h create mode 100644 supportlibs/libsam3/src/libsam3a/libsam3a.c create mode 100644 supportlibs/libsam3/src/libsam3a/libsam3a.h create mode 100644 supportlibs/libsam3/test/libsam3/test_b32.c create mode 100644 supportlibs/libsam3/test/test.c diff --git a/.gitignore b/.gitignore index 2b880085b..6f9356d05 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ Thumbs.db *.pro.user .kdev4 *.kdev4 + +!supportlibs/libsam3/Makefile diff --git a/libretroshare/src/util/i2pcommon.cpp b/libretroshare/src/util/i2pcommon.cpp index ec2ebfd6b..bca7ae110 100644 --- a/libretroshare/src/util/i2pcommon.cpp +++ b/libretroshare/src/util/i2pcommon.cpp @@ -70,13 +70,14 @@ std::string publicKeyFromPrivate(std::string const &priv) uint8_t certType = 0; uint16_t len = 0; uint16_t signingKeyType = 0; - uint16_t cryptKey = 0; + uint16_t cryptKeyType = 0; // only used for easy break do { try { // jump to certificate p += publicKeyLen; + // try to read type and length certType = *p++; len = readTwoBytesBE(p); @@ -87,7 +88,7 @@ std::string publicKeyFromPrivate(std::string const &priv) /* * CertType.Null * type null is followed by 0x00 0x00 - * so has to be 0! + * so len has to be 0! */ RS_DBG("cert is CertType.Null"); publicKeyLen += 3; // add 0x00 0x00 0x00 @@ -119,7 +120,7 @@ std::string publicKeyFromPrivate(std::string const &priv) // likely 7 signingKeyType = readTwoBytesBE(p); - RS_DBG("signing pubkey type ", certType); + RS_DBG("signing pubkey type ", signingKeyType); if (signingKeyType >= 3 && signingKeyType <= 6) { RS_DBG("signing pubkey type ", certType, " has oversize"); // calculate oversize @@ -137,18 +138,18 @@ std::string publicKeyFromPrivate(std::string const &priv) return std::string(); } - publicKeyLen += values.first - 128; // 128 = default DSA key length = the space than can be used before the key must be splitted + publicKeyLen += values.first - 128; // 128 = default DSA key length = the space that can be used before the key must be splitted } // Crypto Public Key // likely 0 - cryptKey = readTwoBytesBE(p); - RS_DBG("crypto pubkey type ", cryptKey); + cryptKeyType = readTwoBytesBE(p); + RS_DBG("crypto pubkey type ", cryptKeyType); // info: these are all smaller than the default 256 bytes, so no oversize calculation is needed break; } catch (const std::out_of_range &e) { - RS_DBG("hit exception! ", e.what()); + RS_DBG("hit an exception! ", e.what()); return std::string(); } } while(false); @@ -160,4 +161,102 @@ std::string publicKeyFromPrivate(std::string const &priv) return pub; } +bool getKeyTypes(const std::string &key, std::string &signingKey, std::string &cryptoKey) +{ + // creat a copy to work on, need to convert it to standard base64 + auto key_copy(key); + std::replace(key_copy.begin(), key_copy.end(), '~', '/'); + // replacing the - with a + is not necessary, as RsBase64 can handle base64url encoding, too + // std::replace(copy.begin(), copy.end(), '-', '+'); + + // get raw data + std::vector data; + RsBase64::decode(key_copy, data); + + auto p = data.cbegin(); + + constexpr size_t publicKeyLen = 256 + 128; // default length (bytes) + uint8_t certType = 0; + uint16_t signingKeyType = 0; + uint16_t cryptKeyType = 0; + + // try to read types + try { + // jump to certificate + p += publicKeyLen; + + // try to read type and skip length + certType = *p++; + p += 2; + + // only 0 and 5 are used / valid at this point + // check for == 0 + if (certType == static_cast::type>(CertType::Null)) { + RS_DBG("cert is CertType.Null"); + + signingKey = "DSA_SHA1"; + cryptoKey = "ElGamal"; + return true; + } + + // check for != 5 + if (certType != static_cast::type>(CertType::Key)) { + // unsupported + RS_DBG("cert type ", certType, " is unsupported"); + return false; + } + + RS_DBG("cert is CertType.Key"); + + // Signing Public Key + // likely 7 + signingKeyType = readTwoBytesBE(p); + RS_DBG("signing pubkey type ", signingKeyType); + + // Crypto Public Key + // likely 0 + cryptKeyType = readTwoBytesBE(p); + RS_DBG("crypto pubkey type ", cryptKeyType); + } catch (const std::out_of_range &e) { + RS_DBG("hit an exception! ", e.what()); + return false; + } + + // now convert to string (this would be easier with c++17) +#define HELPER(a, b, c) \ + case static_cast::type>(a::c): \ + b = "c"; \ + break; + + switch (signingKeyType) { + HELPER(SigningKeyType, signingKey, DSA_SHA1) + HELPER(SigningKeyType, signingKey, ECDSA_SHA256_P256) + HELPER(SigningKeyType, signingKey, ECDSA_SHA384_P384) + HELPER(SigningKeyType, signingKey, ECDSA_SHA512_P521) + HELPER(SigningKeyType, signingKey, RSA_SHA256_2048) + HELPER(SigningKeyType, signingKey, RSA_SHA384_3072) + HELPER(SigningKeyType, signingKey, RSA_SHA512_4096) + HELPER(SigningKeyType, signingKey, EdDSA_SHA512_Ed25519) + HELPER(SigningKeyType, signingKey, EdDSA_SHA512_Ed25519ph) + HELPER(SigningKeyType, signingKey, RedDSA_SHA512_Ed25519) + default: + RsWarn("unkown signing key type:", signingKeyType); + return false; + } + + switch (cryptKeyType) { + HELPER(CryptoKeyType, cryptoKey, ElGamal) + HELPER(CryptoKeyType, cryptoKey, P256) + HELPER(CryptoKeyType, cryptoKey, P384) + HELPER(CryptoKeyType, cryptoKey, P521) + HELPER(CryptoKeyType, cryptoKey, X25519) + default: + RsWarn("unkown crypto key type:", cryptKeyType); + return false; + } +#undef HELPER + + return true; +} + } // namespace i2p diff --git a/libretroshare/src/util/i2pcommon.h b/libretroshare/src/util/i2pcommon.h index 1fd152079..e41b61010 100644 --- a/libretroshare/src/util/i2pcommon.h +++ b/libretroshare/src/util/i2pcommon.h @@ -208,6 +208,15 @@ std::string keyToBase32Addr(const std::string &key); */ std::string publicKeyFromPrivate(const std::string &priv); +/** + * @brief getKeyTypes returns the name of the utilized algorithms used by the key + * @param key public key (private works, too) + * @param signingKey name of the signing key, e.g. DSA_SHA1 + * @param cryptoKey name of the crpyto key, e.g. ElGamal + * @return true on success, false otherwise + */ +bool getKeyTypes(const std::string &key, std::string &signingKey, std::string &cryptoKey); + } // namespace i2p #endif // I2PCOMMON_H diff --git a/supportlibs/libsam3/Makefile b/supportlibs/libsam3/Makefile new file mode 100644 index 000000000..fc6f52245 --- /dev/null +++ b/supportlibs/libsam3/Makefile @@ -0,0 +1,41 @@ +CFLAGS := -Wall -g -O2 -std=gnu99 + +SRCS := \ + src/libsam3/libsam3.c \ + src/libsam3a/libsam3a.c + +TESTS := \ + src/ext/tinytest.c \ + test/test.c \ + test/libsam3/test_b32.c + +LIB_OBJS := ${SRCS:.c=.o} +TEST_OBJS := ${TESTS:.c=.o} + +OBJS := ${LIB_OBJS} ${TEST_OBJS} + +LIB := libsam3.a + + +all: build check + +check: libsam3-tests + ./libsam3-tests + +build: ${LIB} + +${LIB}: ${LIB_OBJS} + ${AR} -sr ${LIB} ${LIB_OBJS} + +libsam3-tests: ${TEST_OBJS} ${LIB} + ${CC} $^ -o $@ + +clean: + rm -f libsam3-tests ${LIB} ${OBJS} examples/sam3/samtest + +%.o: %.c Makefile + ${CC} ${CFLAGS} -c $< -o $@ + +fmt: + find . -name '*.c' -exec clang-format -i {} \; + find . -name '*.h' -exec clang-format -i {} \; diff --git a/supportlibs/libsam3/README.md b/supportlibs/libsam3/README.md new file mode 100644 index 000000000..98dfe4205 --- /dev/null +++ b/supportlibs/libsam3/README.md @@ -0,0 +1,18 @@ +# libsam3 + +[![Build Status](https://travis-ci.org/i2p/libsam3.svg?branch=master)](https://travis-ci.org/i2p/libsam3) + +A C library for the [SAM v3 API](https://geti2p.net/en/docs/api/samv3). + +## Development Status + +Unmaintained, but PRs welcome! + +## Usage + +Copy the two files from one of the following locations into your codebase: + +- `src/libsam3` - Synchronous implementation. +- `src/libsam3a` - Asynchronous implementation. + +See `examples/` for how to use various parts of the API. diff --git a/supportlibs/libsam3/examples/libsam3 b/supportlibs/libsam3/examples/libsam3 new file mode 120000 index 000000000..136138896 --- /dev/null +++ b/supportlibs/libsam3/examples/libsam3 @@ -0,0 +1 @@ +../src/libsam3 \ No newline at end of file diff --git a/supportlibs/libsam3/examples/sam3/README.md b/supportlibs/libsam3/examples/sam3/README.md new file mode 100644 index 000000000..1228e4984 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/README.md @@ -0,0 +1,26 @@ +Examples +======== + +These examples show various ways of using libsam3 to enable i2p in your +application, and are also useful in other ways. If you implement an i2p +application library in another language, making variants basic tools wouldn't be +the worst way to make sure that it works. + +building +-------- + +Once you have build the library in the root of this repository by running make +all, you can build all these examples at once by running + + make + +in this directory. I think it makes things easier to experiment with quickly. + +namelookup +---------- + +Namelookup uses the SAM API to find the base64 destination of an readable "jump" +or base32 i2p address. You can use it like this: + + ./lookup i2p-projekt.i2p + diff --git a/supportlibs/libsam3/examples/sam3/dgramc.c b/supportlibs/libsam3/examples/sam3/dgramc.c new file mode 100644 index 000000000..898a9aec1 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/dgramc.c @@ -0,0 +1,116 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +// comment the following if you don't want to stress UDP with 'big' datagram +// seems that up to 32000 bytes can be used for localhost +// note that we need 516+6+? bytes for header; lets reserve 1024 bytes for it +#define BIG (32000 - 1024) + +#define KEYFILE "dgrams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + char buf[1024]; + char destkey[517] = {0}; // 516 chars + \0 + int sz; + // + libsam3_debug = 1; + // + if (argc < 2) { + FILE *fl = fopen(KEYFILE, "rb"); + // + if (fl != NULL) { + if (fread(destkey, 516, 1, fl) == 1) { + fclose(fl); + goto ok; + } + fclose(fl); + } + printf("usage: dgramc PUBKEY\n"); + return 1; + } else { + if (strlen(argv[1]) != 516) { + fprintf(stderr, "FATAL: invalid key length!\n"); + return 1; + } + strcpy(destkey, argv[1]); + } + // +ok: + printf("creating session...\n"); + /* create TRANSIENT session with temporary disposible destination */ + if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, + SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_DGRAM, 4, + NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + /* send datagram */ + printf("sending test datagram...\n"); + if (sam3DatagramSend(&ses, destkey, "test", 4) < 0) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + /** receive reply */ + if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + /** null terminated string */ + buf[sz] = 0; + printf("received: [%s]\n", buf); + // +#ifdef BIG + { + char *big = calloc(BIG + 1024, sizeof(char)); + /** generate random string */ + sam3GenChannelName(big, BIG + 1023, BIG + 1023); + printf("sending BIG datagram...\n"); + if (sam3DatagramSend(&ses, destkey, big, BIG) < 0) { + free(big); + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + if ((sz = sam3DatagramReceive(&ses, big, BIG + 512)) < 0) { + free(big); + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + big[sz] = 0; + printf("received (%d): [%s]\n", sz, big); + free(big); + } +#endif + // + printf("sending quit datagram...\n"); + if (sam3DatagramSend(&ses, destkey, "quit", 4) < 0) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + buf[sz] = 0; + printf("received: [%s]\n", buf); + // + sam3CloseSession(&ses); + return 0; +error: + sam3CloseSession(&ses); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3/dgrams.c b/supportlibs/libsam3/examples/sam3/dgrams.c new file mode 100644 index 000000000..1fe0fc0f7 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/dgrams.c @@ -0,0 +1,113 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +#define KEYFILE "dgrams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + char privkey[1024], pubkey[1024], buf[33 * 1024]; + + /** quit command */ + const char *quitstr = "quit"; + const size_t quitlen = strlen(quitstr); + + /** reply response */ + const char *replystr = "reply: "; + const size_t replylen = strlen(replystr); + + FILE *fl; + // + libsam3_debug = 1; + // + + /** generate new destination keypair */ + printf("generating keys...\n"); + if (sam3GenerateKeys(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, 4) < 0) { + fprintf(stderr, "FATAL: can't generate keys\n"); + return 1; + } + /** copy keypair into local buffer */ + strncpy(pubkey, ses.pubkey, sizeof(pubkey)); + strncpy(privkey, ses.privkey, sizeof(privkey)); + /** create sam session */ + printf("creating session...\n"); + if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, privkey, + SAM3_SESSION_DGRAM, 5, NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + /** make sure we have the right destination */ + // FIXME: probably not needed + if (strcmp(pubkey, ses.pubkey) != 0) { + fprintf(stderr, "FATAL: destination keys don't match\n"); + sam3CloseSession(&ses); + return 1; + } + /** print destination to stdout */ + printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); + if ((fl = fopen(KEYFILE, "wb")) != NULL) { + /** write public key to keyfile */ + fwrite(pubkey, strlen(pubkey), 1, fl); + fclose(fl); + } + + /* now listen for UDP packets */ + printf("starting main loop...\n"); + for (;;) { + /** save replylen bytes for out reply at begining */ + char *datagramBuf = buf + replylen; + const size_t datagramMaxLen = sizeof(buf) - replylen; + int sz, isquit; + printf("waiting for datagram...\n"); + /** blocks until we get a UDP packet */ + if ((sz = sam3DatagramReceive(&ses, datagramBuf, datagramMaxLen) < 0)) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + /** ensure null terminated string */ + datagramBuf[sz] = 0; + /** print out datagram payload to user */ + printf("FROM\n====\n%s\n====\n", ses.destkey); + printf("SIZE=%d\n", sz); + printf("data: [%s]\n", datagramBuf); + /** check for "quit" */ + isquit = (sz == quitlen && memcmp(datagramBuf, quitstr, quitlen) == 0); + /** echo datagram back to sender with "reply: " at the beginning */ + memcpy(buf, replystr, replylen); + + if (sam3DatagramSend(&ses, ses.destkey, buf, sz + replylen) < 0) { + fprintf(stderr, "ERROR: %s\n", ses.error); + goto error; + } + /** if we got a quit command wait for 10 seconds and break out of the + * mainloop */ + if (isquit) { + printf("shutting down...\n"); + sleep(10); /* let dgram reach it's destination */ + break; + } + } + /** close session and delete keyfile */ + sam3CloseSession(&ses); + unlink(KEYFILE); + return 0; +error: + /** error case, close session, delete keyfile and return exit code 1 */ + sam3CloseSession(&ses); + unlink(KEYFILE); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3/namelookup.c b/supportlibs/libsam3/examples/sam3/namelookup.c new file mode 100644 index 000000000..772e4aceb --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/namelookup.c @@ -0,0 +1,43 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +int main(int argc, char *argv[]) { + Sam3Session ses; + // + // + libsam3_debug = 1; + // + if (argc < 2) { + printf("usage: %s name [name...]\n", argv[0]); + return 1; + } + /** for each name in arguments ... */ + for (int n = 1; n < argc; ++n) { + if (!getenv("I2P_LOOKUP_QUIET")) { + fprintf(stdout, "%s ... ", argv[n]); + fflush(stdout); + } + /** do oneshot name lookup */ + if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >= + 0) { + fprintf(stdout, "%s\n\n", ses.destkey); + } else { + fprintf(stdout, "FAILED [%s]\n", ses.error); + } + } + // + return 0; +} diff --git a/supportlibs/libsam3/examples/sam3/samtest.c b/supportlibs/libsam3/examples/sam3/samtest.c new file mode 100644 index 000000000..b2d0b9983 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/samtest.c @@ -0,0 +1,51 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +int main(int argc, char *argv[]) { + int fd; + SAMFieldList *rep = NULL; + const char *v; + // + libsam3_debug = 1; + // + // + if ((fd = sam3Handshake(NULL, 0, NULL)) < 0) + return 1; + // + if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0) + goto error; + rep = sam3ReadReply(fd); + // sam3DumpFieldList(rep); + if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL)) + goto error; + if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL)) + goto error; + v = sam3FindField(rep, "PUB"); + printf("PUB KEY\n=======\n%s\n", v); + v = sam3FindField(rep, "PRIV"); + printf("PRIV KEY\n========\n%s\n", v); + sam3FreeFieldList(rep); + rep = NULL; + // + sam3FreeFieldList(rep); + sam3tcpDisconnect(fd); + return 0; +error: + sam3FreeFieldList(rep); + sam3tcpDisconnect(fd); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3/streamc.c b/supportlibs/libsam3/examples/sam3/streamc.c new file mode 100644 index 000000000..672831c3a --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/streamc.c @@ -0,0 +1,87 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +#define KEYFILE "streams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + Sam3Connection *conn; + char cmd[1024], destkey[617]; // 616 chars + \0 + // + libsam3_debug = 1; + // + memset(destkey, 0, sizeof(destkey)); + // + if (argc < 2) { + FILE *fl = fopen(KEYFILE, "rb"); + // + if (fl != NULL) { + if (fread(destkey, 616, 1, fl) == 1) { + fclose(fl); + goto ok; + } + fclose(fl); + } + printf("usage: streamc PUBKEY\n"); + return 1; + } else { + if (!sam3CheckValidKeyLength(argv[1])) { + fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1], + strlen(argv[1])); + return 1; + } + strcpy(destkey, argv[1]); + } + // +ok: + printf("creating session...\n"); + // create TRANSIENT session + if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, + SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4, + NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + // + printf("connecting...\n"); + if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) { + fprintf(stderr, "FATAL: can't connect: %s\n", ses.error); + sam3CloseSession(&ses); + return 1; + } + // + // now waiting for incoming connection + printf("sending test command...\n"); + if (sam3tcpPrintf(conn->fd, "test\n") < 0) + goto error; + if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) + goto error; + printf("echo: %s\n", cmd); + // + printf("sending quit command...\n"); + if (sam3tcpPrintf(conn->fd, "quit\n") < 0) + goto error; + // + sam3CloseConnection(conn); + sam3CloseSession(&ses); + return 0; +error: + fprintf(stderr, "FATAL: some error occured!\n"); + sam3CloseConnection(conn); + sam3CloseSession(&ses); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3/streams.c b/supportlibs/libsam3/examples/sam3/streams.c new file mode 100644 index 000000000..2fa000c1c --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/streams.c @@ -0,0 +1,72 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +#define KEYFILE "streams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + Sam3Connection *conn; + FILE *fl; + // + libsam3_debug = 1; + // + printf("creating session...\n"); + // create TRANSIENT session + if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, + SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4, + NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + // + printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); + if ((fl = fopen(KEYFILE, "wb")) != NULL) { + fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl); + fclose(fl); + } + // + printf("starting stream acceptor...\n"); + if ((conn = sam3StreamAccept(&ses)) == NULL) { + fprintf(stderr, "FATAL: can't accept: %s\n", ses.error); + sam3CloseSession(&ses); + return 1; + } + printf("FROM\n====\n%s\n====\n", conn->destkey); + // + printf("starting main loop...\n"); + for (;;) { + char cmd[256]; + // + if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) + goto error; + printf("cmd: [%s]\n", cmd); + if (strcmp(cmd, "quit") == 0) + break; + // echo command + if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0) + goto error; + } + // + sam3CloseSession(&ses); + unlink(KEYFILE); + return 0; +error: + fprintf(stderr, "FATAL: some error occured!\n"); + sam3CloseSession(&ses); + unlink(KEYFILE); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3a/test00.c b/supportlibs/libsam3/examples/sam3a/test00.c new file mode 100644 index 000000000..5596053e9 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3a/test00.c @@ -0,0 +1,178 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../libsam3a/libsam3a.h" + +//////////////////////////////////////////////////////////////////////////////// +static void scbErrorClose(Sam3ASession *ses) { + fprintf(stderr, + "\n===============================\nSESION_ERROR: " + "[%s]\n===============================\n", + ses->error); + sam3aCloseSession(ses); // it's safe here +} + +static void scbNRCreated(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nNAME RESOLVED: [%s]\n", + ses->params); + fprintf(stderr, "PUB: %s\n===============================\n", ses->destkey); + sam3aCloseSession(ses); // it's safe here +} + +static const Sam3ASessionCallbacks scbNR = { + .cbError = scbErrorClose, + .cbCreated = scbNRCreated, + .cbDisconnected = NULL, + .cbDatagramRead = NULL, + .cbDestroy = NULL, +}; + +//////////////////////////////////////////////////////////////////////////////// +static void scbKGCreated(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nKEYS GENERATED\n"); + fprintf(stderr, "\rPRIV: %s\n", ses->privkey); + fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); + sam3aCloseSession(ses); // it's safe here +} + +static const Sam3ASessionCallbacks scbKG = { + .cbError = scbErrorClose, + .cbCreated = scbKGCreated, + .cbDisconnected = NULL, + .cbDatagramRead = NULL, + .cbDestroy = NULL, +}; + +//////////////////////////////////////////////////////////////////////////////// +static void scbError(Sam3ASession *ses) { + fprintf(stderr, + "\n===============================\nSESION_ERROR: " + "[%s]\n===============================\n", + ses->error); +} + +static void scbCreated(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_CREATED\n"); + fprintf(stderr, "\rPRIV: %s\n", ses->privkey); + fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); + sam3aCancelSession(ses); // it's safe here +} + +static void scbDisconnected(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" + "===========================\n"); +} + +static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { + fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" + "============================\n"); +} + +static void scbDestroy(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" + "========================\n"); +} + +/** callbacks for our SAM session */ +static const Sam3ASessionCallbacks scb = { + .cbError = scbError, + .cbCreated = scbCreated, + .cbDisconnected = scbDisconnected, + .cbDatagramRead = scbDGramRead, + .cbDestroy = scbDestroy, +}; + +//////////////////////////////////////////////////////////////////////////////// +#define HOST SAM3A_HOST_DEFAULT +//#define HOST "google.com" + +int main(int argc, char *argv[]) { + Sam3ASession ses, snr, skg; + // + // libsam3a_debug = 1; + // + if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, + SAM3A_DESTINATION_TRANSIENT, + SAM3A_SESSION_STREAM) < 0) { + fprintf(stderr, "FATAL: can't create main session!\n"); + return 1; + } + // generate keys + if (sam3aGenerateKeys(&skg, &scbKG, HOST, SAM3A_PORT_DEFAULT) < 0) { + sam3aCloseSession(&ses); + fprintf(stderr, "FATAL: can't create keygen session!\n"); + return 1; + } + // do a name lookup for zzz.i2p + if (sam3aNameLookup(&snr, &scbNR, HOST, SAM3A_PORT_DEFAULT, "zzz.i2p") < 0) { + sam3aCloseSession(&skg); + sam3aCloseSession(&ses); + fprintf(stderr, "FATAL: can't create name resolving session!\n"); + return 1; + } + // while we have sessions ... + while (sam3aIsActiveSession(&ses) || sam3aIsActiveSession(&snr) || + sam3aIsActiveSession(&skg)) { + fd_set rds, wrs; + int res, maxfd = 0; + struct timeval to; + // set up file descriptors for select() + FD_ZERO(&rds); + FD_ZERO(&wrs); + // obtain the maximum fd for select() + if (sam3aIsActiveSession(&ses) && + (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) + break; + if (sam3aIsActiveSession(&snr) && + (maxfd = sam3aAddSessionToFDS(&snr, -1, &rds, &wrs)) < 0) + break; + if (sam3aIsActiveSession(&skg) && + (maxfd = sam3aAddSessionToFDS(&skg, -1, &rds, &wrs)) < 0) + break; + // set timeout to 1 second + sam3ams2timeval(&to, 1000); + // call select() + res = select(maxfd + 1, &rds, &wrs, NULL, &to); + if (res < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "FATAL: select() error!\n"); + break; + } + if (res == 0) { + // idle, no activity + fprintf(stdout, "."); + fflush(stdout); + } else { + // we have activity, process io + if (sam3aIsActiveSession(&ses)) + sam3aProcessSessionIO(&ses, &rds, &wrs); + if (sam3aIsActiveSession(&snr)) + sam3aProcessSessionIO(&snr, &rds, &wrs); + if (sam3aIsActiveSession(&skg)) + sam3aProcessSessionIO(&skg, &rds, &wrs); + } + } + // close seessions + sam3aCloseSession(&ses); + sam3aCloseSession(&skg); + sam3aCloseSession(&snr); + // exit + return 0; +} diff --git a/supportlibs/libsam3/examples/sam3a/test_sc.c b/supportlibs/libsam3/examples/sam3a/test_sc.c new file mode 100644 index 000000000..8feeb5d52 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3a/test_sc.c @@ -0,0 +1,205 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../libsam3a/libsam3a.h" + +//////////////////////////////////////////////////////////////////////////////// +#define KEYFILE "streams.key" + +//////////////////////////////////////////////////////////////////////////////// +static void ccbError(Sam3AConnection *ct) { + fprintf(stderr, + "\n===============================\nCONNECTION_ERROR: " + "[%s]\n===============================\n", + ct->error); +} + +static void ccbDisconnected(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_" + "DISCONNECTED\n===============================\n"); +} + +static void ccbConnected(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===" + "============================\n"); + // sam3aCancelConnection(ct); // cbSent() will not be called +} + +static void ccbAccepted(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n====" + "===========================\n"); +} + +static void ccbSent(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===" + "============================\n"); + // sam3aCancelConnection(ct); + // sam3aCancelSession(ct->ses); // hehe + fprintf(stderr, "(%p)\n", ct->udata); + // + switch ((intptr_t)ct->udata) { + case 0: + if (sam3aSend(ct, "test\n", -1) < 0) { + fprintf(stderr, "SEND ERROR!\n"); + sam3aCancelSession(ct->ses); // hehe + } + break; + case 1: + if (sam3aSend(ct, "quit\n", -1) < 0) { + fprintf(stderr, "SEND ERROR!\n"); + sam3aCancelSession(ct->ses); // hehe + } + break; + default: + return; + } + ct->udata = (void *)(((intptr_t)ct->udata) + 1); +} + +static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) { + fprintf(stderr, + "\n===============================\nCONNECTION_GOTBYTES " + "(%d)\n===============================\n", + bufsize); +} + +static void ccbDestroy(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n=====" + "==========================\n"); +} + +static const Sam3AConnectionCallbacks ccb = { + .cbError = ccbError, + .cbDisconnected = ccbDisconnected, + .cbConnected = ccbConnected, + .cbAccepted = ccbAccepted, + .cbSent = ccbSent, + .cbRead = ccbRead, + .cbDestroy = ccbDestroy, +}; + +//////////////////////////////////////////////////////////////////////////////// +static void scbError(Sam3ASession *ses) { + fprintf(stderr, + "\n===============================\nSESION_ERROR: " + "[%s]\n===============================\n", + ses->error); +} + +static void scbCreated(Sam3ASession *ses) { + char destkey[517]; + FILE *fl; + // + fprintf(stderr, "\n===============================\nSESION_CREATED\n"); + fprintf(stderr, "\rPRIV: %s\n", ses->privkey); + fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); + // + fl = fopen(KEYFILE, "rb"); + // + if (fl == NULL) { + fprintf(stderr, "ERROR: NO KEY FILE!\n"); + sam3aCancelSession(ses); + return; + } + if (fread(destkey, 516, 1, fl) != 1) { + fprintf(stderr, "ERROR: INVALID KEY FILE!\n"); + fclose(fl); + sam3aCancelSession(ses); + return; + } + fclose(fl); + destkey[516] = 0; + if (sam3aStreamConnect(ses, &ccb, destkey) == NULL) { + fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n"); + sam3aCancelSession(ses); + return; + } + fprintf(stderr, "GOON: creating connection...\n"); +} + +static void scbDisconnected(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" + "===========================\n"); +} + +static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { + fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" + "============================\n"); +} + +static void scbDestroy(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" + "========================\n"); +} + +static const Sam3ASessionCallbacks scb = { + .cbError = scbError, + .cbCreated = scbCreated, + .cbDisconnected = scbDisconnected, + .cbDatagramRead = scbDGramRead, + .cbDestroy = scbDestroy, +}; + +//////////////////////////////////////////////////////////////////////////////// +#define HOST SAM3A_HOST_DEFAULT +//#define HOST "google.com" + +int main(int argc, char *argv[]) { + Sam3ASession ses; + // + libsam3a_debug = 0; + // + if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, + SAM3A_DESTINATION_TRANSIENT, + SAM3A_SESSION_STREAM) < 0) { + fprintf(stderr, "FATAL: can't create main session!\n"); + return 1; + } + // + while (sam3aIsActiveSession(&ses)) { + fd_set rds, wrs; + int res, maxfd = 0; + struct timeval to; + // + FD_ZERO(&rds); + FD_ZERO(&wrs); + if (sam3aIsActiveSession(&ses) && + (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) + break; + sam3ams2timeval(&to, 1000); + res = select(maxfd + 1, &rds, &wrs, NULL, &to); + if (res < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "FATAL: select() error!\n"); + break; + } + if (res == 0) { + fprintf(stdout, "."); + fflush(stdout); + } else { + if (sam3aIsActiveSession(&ses)) + sam3aProcessSessionIO(&ses, &rds, &wrs); + } + } + // + sam3aCloseSession(&ses); + // + return 0; +} diff --git a/supportlibs/libsam3/examples/sam3a/test_ss.c b/supportlibs/libsam3/examples/sam3a/test_ss.c new file mode 100644 index 000000000..c2ff3399c --- /dev/null +++ b/supportlibs/libsam3/examples/sam3a/test_ss.c @@ -0,0 +1,236 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../libsam3a/libsam3a.h" + +//////////////////////////////////////////////////////////////////////////////// +#define KEYFILE "streams.key" + +//////////////////////////////////////////////////////////////////////////////// +typedef struct { + char *str; + int strsize; + int strused; + int doQuit; +} ConnData; + +static void cdAppendChar(ConnData *d, char ch) { + if (d->strused + 1 >= d->strsize) { + // fuck errors + d->strsize = d->strused + 1024; + d->str = realloc(d->str, d->strsize + 1); + } + d->str[d->strused++] = ch; + d->str[d->strused] = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +static void ccbError(Sam3AConnection *ct) { + fprintf(stderr, + "\n===============================\nCONNECTION_ERROR: " + "[%s]\n===============================\n", + ct->error); +} + +static void ccbDisconnected(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_" + "DISCONNECTED\n===============================\n"); +} + +static void ccbConnected(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===" + "============================\n"); + // sam3aCancelConnection(ct); // cbSent() will not be called +} + +static void ccbAccepted(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n====" + "===========================\n"); + fprintf(stderr, "FROM: %s\n===============================\n", ct->destkey); +} + +static void ccbSent(Sam3AConnection *ct) { + ConnData *d = (ConnData *)ct->udata; + // + fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===" + "============================\n"); + if (d->doQuit) { + sam3aCancelSession(ct->ses); // hehe + } +} + +static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) { + const char *b = (const char *)buf; + ConnData *d = (ConnData *)ct->udata; + // + fprintf(stderr, + "\n===============================\nCONNECTION_GOTBYTES " + "(%d)\n===============================\n", + bufsize); + while (bufsize > 0) { + cdAppendChar(ct->udata, *b); + if (*b == '\n') { + fprintf(stderr, "cmd: %s", d->str); + if (strcasecmp(d->str, "quit\n") == 0) + d->doQuit = 1; + if (sam3aSend(ct, d->str, -1) < 0) { + // sam3aCancelConnection(ct); // hehe + sam3aCancelSession(ct->ses); // hehe + return; + } + d->str[0] = 0; + d->strused = 0; + } + ++b; + --bufsize; + } +} + +static void ccbDestroy(Sam3AConnection *ct) { + fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n=====" + "==========================\n"); + if (ct->udata != NULL) { + ConnData *d = (ConnData *)ct->udata; + // + if (d->str != NULL) + free(d->str); + free(d); + } +} + +static const Sam3AConnectionCallbacks ccb = { + .cbError = ccbError, + .cbDisconnected = ccbDisconnected, + .cbConnected = ccbConnected, + .cbAccepted = ccbAccepted, + .cbSent = ccbSent, + .cbRead = ccbRead, + .cbDestroy = ccbDestroy, +}; + +//////////////////////////////////////////////////////////////////////////////// +static void scbError(Sam3ASession *ses) { + fprintf(stderr, + "\n===============================\nSESION_ERROR: " + "[%s]\n===============================\n", + ses->error); +} + +static void scbCreated(Sam3ASession *ses) { + FILE *fl; + Sam3AConnection *conn; + // + fprintf(stderr, "\n===============================\nSESION_CREATED\n"); + fprintf(stderr, "\rPRIV: %s\n", ses->privkey); + fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); + // + fl = fopen(KEYFILE, "wb"); + // + if (fl == NULL) { + fprintf(stderr, "ERROR: CAN'T CREATE KEY FILE!\n"); + sam3aCancelSession(ses); + return; + } + if (fwrite(ses->pubkey, 516, 1, fl) != 1) { + fprintf(stderr, "ERROR: CAN'T WRITE KEY FILE!\n"); + fclose(fl); + sam3aCancelSession(ses); + return; + } + fclose(fl); + if ((conn = sam3aStreamAccept(ses, &ccb)) == NULL) { + fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n"); + sam3aCancelSession(ses); + return; + } + // + conn->udata = calloc(1, sizeof(ConnData)); + fprintf(stderr, "GOON: accepting connection...\n"); +} + +static void scbDisconnected(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" + "===========================\n"); +} + +static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { + fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" + "============================\n"); +} + +static void scbDestroy(Sam3ASession *ses) { + fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" + "========================\n"); +} + +static const Sam3ASessionCallbacks scb = { + .cbError = scbError, + .cbCreated = scbCreated, + .cbDisconnected = scbDisconnected, + .cbDatagramRead = scbDGramRead, + .cbDestroy = scbDestroy, +}; + +//////////////////////////////////////////////////////////////////////////////// +#define HOST SAM3A_HOST_DEFAULT +//#define HOST "google.com" + +int main(int argc, char *argv[]) { + Sam3ASession ses; + // + libsam3a_debug = 0; + // + if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, + SAM3A_DESTINATION_TRANSIENT, + SAM3A_SESSION_STREAM) < 0) { + fprintf(stderr, "FATAL: can't create main session!\n"); + return 1; + } + // + while (sam3aIsActiveSession(&ses)) { + fd_set rds, wrs; + int res, maxfd = 0; + struct timeval to; + // + FD_ZERO(&rds); + FD_ZERO(&wrs); + if (sam3aIsActiveSession(&ses) && + (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) + break; + sam3ams2timeval(&to, 1000); + res = select(maxfd + 1, &rds, &wrs, NULL, &to); + if (res < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "FATAL: select() error!\n"); + break; + } + if (res == 0) { + fprintf(stdout, "."); + fflush(stdout); + } else { + if (sam3aIsActiveSession(&ses)) + sam3aProcessSessionIO(&ses, &rds, &wrs); + } + } + // + sam3aCloseSession(&ses); + // + return 0; +} diff --git a/supportlibs/libsam3/src/ext/tinytest.c b/supportlibs/libsam3/src/ext/tinytest.c new file mode 100644 index 000000000..252f03051 --- /dev/null +++ b/supportlibs/libsam3/src/ext/tinytest.c @@ -0,0 +1,466 @@ +/* tinytest.c -- Copyright 2009-2012 Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef TINYTEST_LOCAL +#include "tinytest_local.h" +#endif + +#include +#include +#include +#include + +#ifndef NO_FORKING + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif + +#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) +#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) +/* Workaround for a stupid bug in OSX 10.6 */ +#define FORK_BREAKS_GCOV +#include +#endif +#endif + +#endif /* !NO_FORKING */ + +#ifndef __GNUC__ +#define __attribute__(x) +#endif + +#include "tinytest.h" +#include "tinytest_macros.h" + +#define LONGEST_TEST_NAME 16384 + +static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/ +static int n_ok = 0; /**< Number of tests that have passed */ +static int n_bad = 0; /**< Number of tests that have failed. */ +static int n_skipped = 0; /**< Number of tests that have been skipped. */ + +static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/ +static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */ +static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */ +const char *verbosity_flag = ""; + +const struct testlist_alias_t *cfg_aliases = NULL; + +enum outcome { SKIP = 2, OK = 1, FAIL = 0 }; +static enum outcome cur_test_outcome = FAIL; +const char *cur_test_prefix = NULL; /**< prefix of the current test group */ +/** Name of the current test, if we haven't logged is yet. Used for --quiet */ +const char *cur_test_name = NULL; + +#ifdef _WIN32 +/* Copy of argv[0] for win32. */ +static char commandname[MAX_PATH + 1]; +#endif + +static void usage(struct testgroup_t *groups, int list_groups) + __attribute__((noreturn)); +static int process_test_option(struct testgroup_t *groups, const char *test); + +static enum outcome testcase_run_bare_(const struct testcase_t *testcase) { + void *env = NULL; + enum outcome outcome; + if (testcase->setup) { + env = testcase->setup->setup_fn(testcase); + if (!env) + return FAIL; + else if (env == (void *)TT_SKIP) + return SKIP; + } + + cur_test_outcome = OK; + testcase->fn(env); + outcome = cur_test_outcome; + + if (testcase->setup) { + if (testcase->setup->cleanup_fn(testcase, env) == 0) + outcome = FAIL; + } + + return outcome; +} + +#define MAGIC_EXITCODE 42 + +#ifndef NO_FORKING + +static enum outcome testcase_run_forked_(const struct testgroup_t *group, + const struct testcase_t *testcase) { +#ifdef _WIN32 + /* Fork? On Win32? How primitive! We'll do what the smart kids do: + we'll invoke our own exe (whose name we recall from the command + line) with a command line that tells it to run just the test we + want, and this time without forking. + + (No, threads aren't an option. The whole point of forking is to + share no state between tests.) + */ + int ok; + char buffer[LONGEST_TEST_NAME + 256]; + STARTUPINFOA si; + PROCESS_INFORMATION info; + DWORD exitcode; + + if (!in_tinytest_main) { + printf("\nERROR. On Windows, testcase_run_forked_ must be" + " called from within tinytest_main.\n"); + abort(); + } + if (opt_verbosity > 0) + printf("[forking] "); + + snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", commandname, + verbosity_flag, group->prefix, testcase->name); + + memset(&si, 0, sizeof(si)); + memset(&info, 0, sizeof(info)); + si.cb = sizeof(si); + + ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, 0, NULL, NULL, &si, + &info); + if (!ok) { + printf("CreateProcess failed!\n"); + return 0; + } + WaitForSingleObject(info.hProcess, INFINITE); + GetExitCodeProcess(info.hProcess, &exitcode); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + if (exitcode == 0) + return OK; + else if (exitcode == MAGIC_EXITCODE) + return SKIP; + else + return FAIL; +#else + int outcome_pipe[2]; + pid_t pid; + (void)group; + + if (pipe(outcome_pipe)) + perror("opening pipe"); + + if (opt_verbosity > 0) + printf("[forking] "); + pid = fork(); +#ifdef FORK_BREAKS_GCOV + vproc_transaction_begin(0); +#endif + if (!pid) { + /* child. */ + int test_r, write_r; + char b[1]; + close(outcome_pipe[0]); + test_r = testcase_run_bare_(testcase); + assert(0 <= (int)test_r && (int)test_r <= 2); + b[0] = "NYS"[test_r]; + write_r = (int)write(outcome_pipe[1], b, 1); + if (write_r != 1) { + perror("write outcome to pipe"); + exit(1); + } + exit(0); + return FAIL; /* unreachable */ + } else { + /* parent */ + int status, r; + char b[1]; + /* Close this now, so that if the other side closes it, + * our read fails. */ + close(outcome_pipe[1]); + r = (int)read(outcome_pipe[0], b, 1); + if (r == 0) { + printf("[Lost connection!] "); + return FAIL; + } else if (r != 1) { + perror("read outcome from pipe"); + } + waitpid(pid, &status, 0); + close(outcome_pipe[0]); + return b[0] == 'Y' ? OK : (b[0] == 'S' ? SKIP : FAIL); + } +#endif +} + +#endif /* !NO_FORKING */ + +int testcase_run_one(const struct testgroup_t *group, + const struct testcase_t *testcase) { + enum outcome outcome; + + if (testcase->flags & (TT_SKIP | TT_OFF_BY_DEFAULT)) { + if (opt_verbosity > 0) + printf("%s%s: %s\n", group->prefix, testcase->name, + (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED"); + ++n_skipped; + return SKIP; + } + + if (opt_verbosity > 0 && !opt_forked) { + printf("%s%s: ", group->prefix, testcase->name); + } else { + if (opt_verbosity == 0) + printf("."); + cur_test_prefix = group->prefix; + cur_test_name = testcase->name; + } + +#ifndef NO_FORKING + if ((testcase->flags & TT_FORK) && !(opt_forked || opt_nofork)) { + outcome = testcase_run_forked_(group, testcase); + } else { +#else + { +#endif + outcome = testcase_run_bare_(testcase); + } + + if (outcome == OK) { + ++n_ok; + if (opt_verbosity > 0 && !opt_forked) + puts(opt_verbosity == 1 ? "OK" : ""); + } else if (outcome == SKIP) { + ++n_skipped; + if (opt_verbosity > 0 && !opt_forked) + puts("SKIPPED"); + } else { + ++n_bad; + if (!opt_forked) + printf("\n [%s FAILED]\n", testcase->name); + } + + if (opt_forked) { + exit(outcome == OK ? 0 : (outcome == SKIP ? MAGIC_EXITCODE : 1)); + return 1; /* unreachable */ + } else { + return (int)outcome; + } +} + +int tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, + unsigned long flag) { + int i, j; + size_t length = LONGEST_TEST_NAME; + char fullname[LONGEST_TEST_NAME]; + int found = 0; + if (strstr(arg, "..")) + length = strstr(arg, "..") - arg; + for (i = 0; groups[i].prefix; ++i) { + for (j = 0; groups[i].cases[j].name; ++j) { + struct testcase_t *testcase = &groups[i].cases[j]; + snprintf(fullname, sizeof(fullname), "%s%s", groups[i].prefix, + testcase->name); + if (!flag) { /* Hack! */ + printf(" %s", fullname); + if (testcase->flags & TT_OFF_BY_DEFAULT) + puts(" (Off by default)"); + else if (testcase->flags & TT_SKIP) + puts(" (DISABLED)"); + else + puts(""); + } + if (!strncmp(fullname, arg, length)) { + if (set) + testcase->flags |= flag; + else + testcase->flags &= ~flag; + ++found; + } + } + } + return found; +} + +static void usage(struct testgroup_t *groups, int list_groups) { + puts("Options are: [--verbose|--quiet|--terse] [--no-fork]"); + puts(" Specify tests by name, or using a prefix ending with '..'"); + puts(" To skip a test, prefix its name with a colon."); + puts(" To enable a disabled test, prefix its name with a plus."); + puts(" Use --list-tests for a list of tests."); + if (list_groups) { + puts("Known tests are:"); + tinytest_set_flag_(groups, "..", 1, 0); + } + exit(0); +} + +static int process_test_alias(struct testgroup_t *groups, const char *test) { + int i, j, n, r; + for (i = 0; cfg_aliases && cfg_aliases[i].name; ++i) { + if (!strcmp(cfg_aliases[i].name, test)) { + n = 0; + for (j = 0; cfg_aliases[i].tests[j]; ++j) { + r = process_test_option(groups, cfg_aliases[i].tests[j]); + if (r < 0) + return -1; + n += r; + } + return n; + } + } + printf("No such test alias as @%s!", test); + return -1; +} + +static int process_test_option(struct testgroup_t *groups, const char *test) { + int flag = TT_ENABLED_; + int n = 0; + if (test[0] == '@') { + return process_test_alias(groups, test + 1); + } else if (test[0] == ':') { + ++test; + flag = TT_SKIP; + } else if (test[0] == '+') { + ++test; + ++n; + if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) { + printf("No such test as %s!\n", test); + return -1; + } + } else { + ++n; + } + if (!tinytest_set_flag_(groups, test, 1, flag)) { + printf("No such test as %s!\n", test); + return -1; + } + return n; +} + +void tinytest_set_aliases(const struct testlist_alias_t *aliases) { + cfg_aliases = aliases; +} + +int tinytest_main(int c, const char **v, struct testgroup_t *groups) { + int i, j, n = 0; + +#ifdef _WIN32 + const char *sp = strrchr(v[0], '.'); + const char *extension = ""; + if (!sp || stricmp(sp, ".exe")) + extension = ".exe"; /* Add an exe so CreateProcess will work */ + snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); + commandname[MAX_PATH] = '\0'; +#endif + for (i = 1; i < c; ++i) { + if (v[i][0] == '-') { + if (!strcmp(v[i], "--RUNNING-FORKED")) { + opt_forked = 1; + } else if (!strcmp(v[i], "--no-fork")) { + opt_nofork = 1; + } else if (!strcmp(v[i], "--quiet")) { + opt_verbosity = -1; + verbosity_flag = "--quiet"; + } else if (!strcmp(v[i], "--verbose")) { + opt_verbosity = 2; + verbosity_flag = "--verbose"; + } else if (!strcmp(v[i], "--terse")) { + opt_verbosity = 0; + verbosity_flag = "--terse"; + } else if (!strcmp(v[i], "--help")) { + usage(groups, 0); + } else if (!strcmp(v[i], "--list-tests")) { + usage(groups, 1); + } else { + printf("Unknown option %s. Try --help\n", v[i]); + return -1; + } + } else { + int r = process_test_option(groups, v[i]); + if (r < 0) + return -1; + n += r; + } + } + if (!n) + tinytest_set_flag_(groups, "..", 1, TT_ENABLED_); + +#ifdef _IONBF + setvbuf(stdout, NULL, _IONBF, 0); +#endif + + ++in_tinytest_main; + for (i = 0; groups[i].prefix; ++i) + for (j = 0; groups[i].cases[j].name; ++j) + if (groups[i].cases[j].flags & TT_ENABLED_) + testcase_run_one(&groups[i], &groups[i].cases[j]); + + --in_tinytest_main; + + if (opt_verbosity == 0) + puts(""); + + if (n_bad) + printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad, n_bad + n_ok, + n_skipped); + else if (opt_verbosity >= 1) + printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped); + + return (n_bad == 0) ? 0 : 1; +} + +int tinytest_get_verbosity_(void) { return opt_verbosity; } + +void tinytest_set_test_failed_(void) { + if (opt_verbosity <= 0 && cur_test_name) { + if (opt_verbosity == 0) + puts(""); + printf("%s%s: ", cur_test_prefix, cur_test_name); + cur_test_name = NULL; + } + cur_test_outcome = FAIL; +} + +void tinytest_set_test_skipped_(void) { + if (cur_test_outcome == OK) + cur_test_outcome = SKIP; +} + +char *tinytest_format_hex_(const void *val_, unsigned long len) { + const unsigned char *val = (unsigned char *)val_; + char *result, *cp; + size_t i; + + if (!val) + return strdup("null"); + if (!(result = (char *)malloc(len * 2 + 1))) + return strdup(""); + cp = result; + for (i = 0; i < len; ++i) { + *cp++ = "0123456789ABCDEF"[val[i] >> 4]; + *cp++ = "0123456789ABCDEF"[val[i] & 0x0f]; + } + *cp = 0; + return result; +} diff --git a/supportlibs/libsam3/src/ext/tinytest.h b/supportlibs/libsam3/src/ext/tinytest.h new file mode 100644 index 000000000..bdddcbb54 --- /dev/null +++ b/supportlibs/libsam3/src/ext/tinytest.h @@ -0,0 +1,104 @@ +/* tinytest.h -- Copyright 2009-2012 Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TINYTEST_H_INCLUDED_ +#define TINYTEST_H_INCLUDED_ + +/** Flag for a test that needs to run in a subprocess. */ +#define TT_FORK (1 << 0) +/** Runtime flag for a test we've decided to skip. */ +#define TT_SKIP (1 << 1) +/** Internal runtime flag for a test we've decided to run. */ +#define TT_ENABLED_ (1 << 2) +/** Flag for a test that's off by default. */ +#define TT_OFF_BY_DEFAULT (1 << 3) +/** If you add your own flags, make them start at this point. */ +#define TT_FIRST_USER_FLAG (1 << 4) + +typedef void (*testcase_fn)(void *); + +struct testcase_t; + +/** Functions to initialize/teardown a structure for a testcase. */ +struct testcase_setup_t { + /** Return a new structure for use by a given testcase. */ + void *(*setup_fn)(const struct testcase_t *); + /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */ + int (*cleanup_fn)(const struct testcase_t *, void *); +}; + +/** A single test-case that you can run. */ +struct testcase_t { + const char *name; /**< An identifier for this case. */ + testcase_fn fn; /**< The function to run to implement this case. */ + unsigned long flags; /**< Bitfield of TT_* flags. */ + const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ + void *setup_data; /**< Extra data usable by setup function */ +}; +#define END_OF_TESTCASES \ + { NULL, NULL, 0, NULL, NULL } + +/** A group of tests that are selectable together. */ +struct testgroup_t { + const char *prefix; /**< Prefix to prepend to testnames. */ + struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */ +}; +#define END_OF_GROUPS \ + { NULL, NULL } + +struct testlist_alias_t { + const char *name; + const char **tests; +}; +#define END_OF_ALIASES \ + { NULL, NULL } + +/** Implementation: called from a test to indicate failure, before logging. */ +void tinytest_set_test_failed_(void); +/** Implementation: called from a test to indicate that we're skipping. */ +void tinytest_set_test_skipped_(void); +/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */ +int tinytest_get_verbosity_(void); +/** Implementation: Set a flag on tests matching a name; returns number + * of tests that matched. */ +int tinytest_set_flag_(struct testgroup_t *, const char *, int set, + unsigned long); +/** Implementation: Put a chunk of memory into hex. */ +char *tinytest_format_hex_(const void *, unsigned long); + +/** Set all tests in 'groups' matching the name 'named' to be skipped. */ +#define tinytest_skip(groups, named) \ + tinytest_set_flag_(groups, named, 1, TT_SKIP) + +/** Run a single testcase in a single group. */ +int testcase_run_one(const struct testgroup_t *, const struct testcase_t *); + +void tinytest_set_aliases(const struct testlist_alias_t *aliases); + +/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups, + as selected from the command line. */ +int tinytest_main(int argc, const char **argv, struct testgroup_t *groups); + +#endif diff --git a/supportlibs/libsam3/src/ext/tinytest_macros.h b/supportlibs/libsam3/src/ext/tinytest_macros.h new file mode 100644 index 000000000..817734020 --- /dev/null +++ b/supportlibs/libsam3/src/ext/tinytest_macros.h @@ -0,0 +1,219 @@ +/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TINYTEST_MACROS_H_INCLUDED_ +#define TINYTEST_MACROS_H_INCLUDED_ + +/* Helpers for defining statement-like macros */ +#define TT_STMT_BEGIN do { +#define TT_STMT_END \ + } \ + while (0) + +/* Redefine this if your test functions want to abort with something besides + * "goto end;" */ +#ifndef TT_EXIT_TEST_FUNCTION +#define TT_EXIT_TEST_FUNCTION \ + TT_STMT_BEGIN goto end; \ + TT_STMT_END +#endif + +/* Redefine this if you want to note success/failure in some different way. */ +#ifndef TT_DECLARE +#define TT_DECLARE(prefix, args) \ + TT_STMT_BEGIN \ + printf("\n %s %s:%d: ", prefix, __FILE__, __LINE__); \ + printf args; \ + TT_STMT_END +#endif + +/* Announce a failure. Args are parenthesized printf args. */ +#define TT_GRIPE(args) TT_DECLARE("FAIL", args) + +/* Announce a non-failure if we're verbose. */ +#define TT_BLATHER(args) \ + TT_STMT_BEGIN \ + if (tinytest_get_verbosity_() > 1) \ + TT_DECLARE(" OK", args); \ + TT_STMT_END + +#define TT_DIE(args) \ + TT_STMT_BEGIN \ + tinytest_set_test_failed_(); \ + TT_GRIPE(args); \ + TT_EXIT_TEST_FUNCTION; \ + TT_STMT_END + +#define TT_FAIL(args) \ + TT_STMT_BEGIN \ + tinytest_set_test_failed_(); \ + TT_GRIPE(args); \ + TT_STMT_END + +/* Fail and abort the current test for the reason in msg */ +#define tt_abort_printf(msg) TT_DIE(msg) +#define tt_abort_perror(op) \ + TT_DIE(("%s: %s [%d]", (op), strerror(errno), errno)) +#define tt_abort_msg(msg) TT_DIE(("%s", msg)) +#define tt_abort() TT_DIE(("%s", "(Failed.)")) + +/* Fail but do not abort the current test for the reason in msg. */ +#define tt_fail_printf(msg) TT_FAIL(msg) +#define tt_fail_perror(op) \ + TT_FAIL(("%s: %s [%d]", (op), strerror(errno), errno)) +#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) +#define tt_fail() TT_FAIL(("%s", "(Failed.)")) + +/* End the current test, and indicate we are skipping it. */ +#define tt_skip() \ + TT_STMT_BEGIN \ + tinytest_set_test_skipped_(); \ + TT_EXIT_TEST_FUNCTION; \ + TT_STMT_END + +#define tt_want_(b, msg, fail) \ + TT_STMT_BEGIN \ + if (!(b)) { \ + tinytest_set_test_failed_(); \ + TT_GRIPE(("%s", msg)); \ + fail; \ + } else { \ + TT_BLATHER(("%s", msg)); \ + } \ + TT_STMT_END + +/* Assert b, but do not stop the test if b fails. Log msg on failure. */ +#define tt_want_msg(b, msg) tt_want_(b, msg, ); + +/* Assert b and stop the test if b fails. Log msg on failure. */ +#define tt_assert_msg(b, msg) tt_want_(b, msg, TT_EXIT_TEST_FUNCTION); + +/* Assert b, but do not stop the test if b fails. */ +#define tt_want(b) tt_want_msg((b), "want(" #b ")") +/* Assert b, and stop the test if b fails. */ +#define tt_assert(b) tt_assert_msg((b), "assert(" #b ")") + +#define tt_assert_test_fmt_type(a, b, str_test, type, test, printf_type, \ + printf_fmt, setup_block, cleanup_block, \ + die_on_fail) \ + TT_STMT_BEGIN \ + type val1_ = (a); \ + type val2_ = (b); \ + int tt_status_ = (test); \ + if (!tt_status_ || tinytest_get_verbosity_() > 1) { \ + printf_type print_; \ + printf_type print1_; \ + printf_type print2_; \ + type value_ = val1_; \ + setup_block; \ + print1_ = print_; \ + value_ = val2_; \ + setup_block; \ + print2_ = print_; \ + TT_DECLARE(tt_status_ ? " OK" : "FAIL", \ + ("assert(%s): " printf_fmt " vs " printf_fmt, str_test, \ + print1_, print2_)); \ + print_ = print1_; \ + cleanup_block; \ + print_ = print2_; \ + cleanup_block; \ + if (!tt_status_) { \ + tinytest_set_test_failed_(); \ + die_on_fail; \ + } \ + } \ + TT_STMT_END + +#define tt_assert_test_type(a, b, str_test, type, test, fmt, die_on_fail) \ + tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \ + { print_ = value_; }, {}, die_on_fail) + +#define tt_assert_test_type_opt(a, b, str_test, type, test, fmt, die_on_fail) \ + tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \ + { print_ = value_ ? value_ : ""; }, {}, \ + die_on_fail) + +/* Helper: assert that a op b, when cast to type. Format the values with + * printf format fmt on failure. */ +#define tt_assert_op_type(a, op, b, type, fmt) \ + tt_assert_test_type(a, b, #a " " #op " " #b, type, (val1_ op val2_), fmt, \ + TT_EXIT_TEST_FUNCTION) + +#define tt_int_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \ + TT_EXIT_TEST_FUNCTION) + +#define tt_uint_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \ + (val1_ op val2_), "%lu", TT_EXIT_TEST_FUNCTION) + +#define tt_ptr_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \ + "%p", TT_EXIT_TEST_FUNCTION) + +#define tt_str_op(a, op, b) \ + tt_assert_test_type_opt(a, b, #a " " #op " " #b, const char *, \ + (val1_ && val2_ && strcmp(val1_, val2_) op 0), \ + "<%s>", TT_EXIT_TEST_FUNCTION) + +#define tt_mem_op(expr1, op, expr2, len) \ + tt_assert_test_fmt_type( \ + expr1, expr2, #expr1 " " #op " " #expr2, const void *, \ + (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \ + { print_ = tinytest_format_hex_(value_, (len)); }, \ + { \ + if (print_) \ + free(print_); \ + }, \ + TT_EXIT_TEST_FUNCTION); + +#define tt_want_int_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \ + (void)0) + +#define tt_want_uint_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \ + (val1_ op val2_), "%lu", (void)0) + +#define tt_want_ptr_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \ + "%p", (void)0) + +#define tt_want_str_op(a, op, b) \ + tt_assert_test_type(a, b, #a " " #op " " #b, const char *, \ + (strcmp(val1_, val2_) op 0), "<%s>", (void)0) + +#define tt_want_mem_op(expr1, op, expr2, len) \ + tt_assert_test_fmt_type( \ + expr1, expr2, #expr1 " " #op " " #expr2, const void *, \ + (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \ + { print_ = tinytest_format_hex_(value_, (len)); }, \ + { \ + if (print_) \ + free(print_); \ + }, \ + (void)0); + +#endif diff --git a/supportlibs/libsam3/src/libsam3/libsam3.c b/supportlibs/libsam3/src/libsam3/libsam3.c new file mode 100644 index 000000000..367949a39 --- /dev/null +++ b/supportlibs/libsam3/src/libsam3/libsam3.c @@ -0,0 +1,1304 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include "libsam3.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +int libsam3_debug = 0; + +//////////////////////////////////////////////////////////////////////////////// +/* convert struct timeval to milliseconds */ +/* +static inline uint64_t timeval2ms (const struct timeval *tv) { + return ((uint64_t)tv->tv_sec)*1000+((uint64_t)tv->tv_usec)/1000; +} +*/ + +/* convert milliseconds to timeval struct */ +static inline void ms2timeval(struct timeval *tv, uint64_t ms) { + tv->tv_sec = ms / 1000; + tv->tv_usec = (ms % 1000) * 1000; +} + +int sam3tcpSetTimeoutSend(int fd, int timeoutms) { + if (fd >= 0 && timeoutms >= 0) { + struct timeval tv; + // + ms2timeval(&tv, timeoutms); + return (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 ? -1 + : 0); + } + return -1; +} + +int sam3tcpSetTimeoutReceive(int fd, int timeoutms) { + if (fd >= 0 && timeoutms >= 0) { + struct timeval tv; + // + ms2timeval(&tv, timeoutms); + return (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ? -1 + : 0); + } + return -1; +} + +int sam3CheckValidKeyLength(const char *pubkey) { + if (strlen(pubkey) >= SAM3_PUBKEY_SIZE && + strlen(pubkey) <= SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE) { + return 1; + } + return 0; +} + +int sam3tcpConnectIP(uint32_t ip, int port) { + struct sockaddr_in addr; + int fd, val = 1; + char ipstr[18]; + // + if (ip == 0 || ip == 0xffffffffUL || port < 1 || port > 65535) + return -1; + // + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if (libsam3_debug) + fprintf(stderr, "ERROR: can't create socket\n"); + return -1; + } + // + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = ip; + // + ipstr[0] = 0; + if (libsam3_debug) { + if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_in), ipstr, + sizeof(ipstr), NULL, 0, NI_NUMERICHOST) == 0) { + fprintf(stderr, "connecting to [%s:%d]...\n", ipstr, port); + } + } + // + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); + // + if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { + if (libsam3_debug) + fprintf(stderr, "ERROR: can't connect\n"); + close(fd); + return -1; + } + // + if (libsam3_debug && ipstr[0]) + fprintf(stderr, "connected to [%s:%d]\n", ipstr, port); + // + return fd; +} + +/* returns fd or -1 */ +int sam3tcpConnect(const char *hostname, int port, uint32_t *ip) { + struct hostent *host = NULL; + // + if (hostname == NULL || !hostname[0] || port < 1 || port > 65535) + return -1; + // + host = gethostbyname(hostname); + if (host == NULL || host->h_name == NULL || !host->h_name[0]) { + if (libsam3_debug) + fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); + return -1; + } + // + if (libsam3_debug) { + char ipstr[18]; + // + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr = *((struct in_addr *)host->h_addr); + // + if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_in), ipstr, + sizeof(ipstr), NULL, 0, NI_NUMERICHOST) == 0) { + fprintf(stderr, "resolving: %s is [%s]...\n", hostname, ipstr); + } + } + // + if (ip != NULL) + *ip = ((struct in_addr *)host->h_addr)->s_addr; + return sam3tcpConnectIP(((struct in_addr *)host->h_addr)->s_addr, port); +} + +// <0: error; 0: ok +int sam3tcpDisconnect(int fd) { + if (fd >= 0) { + shutdown(fd, SHUT_RDWR); + return close(fd); + } + // + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +// <0: error; 0: ok +int sam3tcpSend(int fd, const void *buf, size_t bufSize) { + const char *c = (const char *)buf; + // + if (fd < 0 || (buf == NULL && bufSize > 0)) + return -1; + // + while (bufSize > 0) { + int wr = send(fd, c, bufSize, MSG_NOSIGNAL); + // + if (wr < 0 && errno == EINTR) + continue; // interrupted by signal + if (wr <= 0) + return -1; // either error or + c += wr; + bufSize -= wr; + } + // + return 0; +} + +/* <0: received (-res) bytes; read error */ +/* can return less that requesten bytes even if `allowPartial` is 0 when + * connection is closed */ +ssize_t sam3tcpReceiveEx(int fd, void *buf, size_t bufSize, int allowPartial) { + char *c = (char *)buf; + ssize_t total = 0; + // + if (fd < 0 || (buf == NULL && bufSize > 0)) + return -1; + // + while (bufSize > 0) { + int rd = recv(fd, c, bufSize, 0); + // + if (rd < 0 && errno == EINTR) + continue; // interrupted by signal + if (rd == 0) + return total; + if (rd < 0) + return -total; + c += rd; + total += rd; + bufSize -= rd; + if (allowPartial) + break; + } + // + return total; +} + +ssize_t sam3tcpReceive(int fd, void *buf, size_t bufSize) { + return sam3tcpReceiveEx(fd, buf, bufSize, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +__attribute__((format(printf, 2, 3))) int sam3tcpPrintf(int fd, const char *fmt, + ...) { + int res; + char buf[1024], *p = buf; + int size = sizeof(buf) - 1; + // + for (;;) { + va_list ap; + char *np; + int n; + // + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + // + if (n > -1 && n < size) + break; + if (n > -1) + size = n + 1; + else + size *= 2; + if (p == buf) { + if ((p = malloc(size + 4)) == NULL) + return -1; + } else { + if ((np = realloc(p, size + 4)) == NULL) { + free(p); + return -1; + } + p = np; + } + } + // + if (libsam3_debug) + fprintf(stderr, "SENDING: %s", p); + res = sam3tcpSend(fd, p, strlen(p)); + if (p != buf) + free(p); + return res; +} + +int sam3tcpReceiveStr(int fd, char *dest, size_t maxSize) { + char *d = dest; + // + if (maxSize < 1 || fd < 0 || dest == NULL) + return -1; + memset(dest, 0, maxSize); + while (maxSize > 1) { + char *e; + int rd = recv(fd, d, maxSize - 1, MSG_PEEK); + // + if (rd < 0 && errno == EINTR) + continue; // interrupted by signal + if (rd == 0) { + rd = recv(fd, d, 1, 0); + if (rd < 0 && errno == EINTR) + continue; // interrupted by signal + if (d[0] == '\n') { + d[0] = 0; // remove '\n' + return 0; + } + } else { + if (rd < 0) + return -1; // error or connection closed; alas + } + // check for EOL + d[maxSize - 1] = 0; + if ((e = strchr(d, '\n')) != NULL) { + rd = e - d + 1; // bytes to receive + if (sam3tcpReceive(fd, d, rd) < 0) + return -1; // alas + d[rd - 1] = 0; // remove '\n' + return 0; // done + } else { + // let's receive this part and go on + if (sam3tcpReceive(fd, d, rd) < 0) + return -1; // alas + maxSize -= rd; + d += rd; + } + } + // alas, the string is too big + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3udpSendToIP(uint32_t ip, int port, const void *buf, size_t bufSize) { + // TODO: ipv6 + struct sockaddr_in addr; + int fd, res; + // + if (buf == NULL || bufSize < 1) + return -1; + if (port < 1 || port > 65535) + port = 7655; + // + if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + if (libsam3_debug) + fprintf(stderr, "ERROR: can't create socket\n"); + return -1; + } + // + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = ip; + // + res = sendto(fd, buf, bufSize, 0, (struct sockaddr *)&addr, sizeof(addr)); + // + if (res < 0) { + if (libsam3_debug) { + res = errno; + fprintf(stderr, "UDP ERROR (%d): %s\n", res, strerror(res)); + } + res = -1; + } else { + if (libsam3_debug) + fprintf(stderr, "UDP: %d bytes sent\n", res); + } + // + close(fd); + // + return (res >= 0 ? 0 : -1); +} + +int sam3udpSendTo(const char *hostname, int port, const void *buf, + size_t bufSize, uint32_t *ip) { + struct hostent *host = NULL; + // TODO: ipv6 + if (buf == NULL || bufSize < 1) + return -1; + if (hostname == NULL || !hostname[0]) + hostname = "localhost"; + if (port < 1 || port > 65535) + port = 7655; + // + host = gethostbyname(hostname); + if (host == NULL || host->h_name == NULL || !host->h_name[0]) { + if (libsam3_debug) + fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); + return -1; + } + // + if (ip != NULL) + *ip = ((struct in_addr *)host->h_addr)->s_addr; + return sam3udpSendToIP(((struct in_addr *)host->h_addr)->s_addr, port, buf, + bufSize); +} + +//////////////////////////////////////////////////////////////////////////////// +void sam3FreeFieldList(SAMFieldList *list) { + while (list != NULL) { + SAMFieldList *c = list; + // + list = list->next; + if (c->name != NULL) + free(c->name); + if (c->value != NULL) + free(c->value); + free(c); + } +} + +void sam3DumpFieldList(const SAMFieldList *list) { + for (; list != NULL; list = list->next) { + fprintf(stderr, "%s=[%s]\n", list->name, list->value); + } +} + +const char *sam3FindField(const SAMFieldList *list, const char *field) { + if (list != NULL && field != NULL) { + for (list = list->next; list != NULL; list = list->next) { + if (list->name != NULL && strcmp(field, list->name) == 0) + return list->value; + } + } + return NULL; +} + +static char *xstrdup(const char *s, int len) { + if (len >= 0) { + char *res = malloc(len + 1); + // + if (res != NULL) { + if (len > 0) + memcpy(res, s, len); + res[len] = 0; + } + // + return res; + } + // + return NULL; +} + +// returns NULL if there are no more tokens +static inline const char *xstrtokend(const char *s) { + while (*s && isspace(*s)) + ++s; + // + if (*s) { + char qch = 0; + // + while (*s) { + if (*s == qch) { + qch = 0; + } else if (*s == '"') { + qch = *s; + } else if (qch) { + if (*s == '\\' && s[1]) + ++s; + } else if (isspace(*s)) { + break; + } + ++s; + } + } else { + s = NULL; + } + // + return s; +} + +SAMFieldList *sam3ParseReply(const char *rep) { + SAMFieldList *first = NULL, *last, *c; + const char *p = rep, *e, *e1; + // + // first 2 words + while (*p && isspace(*p)) + ++p; + if ((e = xstrtokend(p)) == NULL) + return NULL; + if ((e1 = xstrtokend(e)) == NULL) + return NULL; + // + if ((first = last = c = malloc(sizeof(SAMFieldList))) == NULL) + return NULL; + c->next = NULL; + c->name = c->value = NULL; + if ((c->name = xstrdup(p, e - p)) == NULL) + goto error; + while (*e && isspace(*e)) + ++e; + if ((c->value = xstrdup(e, e1 - e)) == NULL) + goto error; + // + p = e1; + while (*p) { + while (*p && isspace(*p)) + ++p; + if ((e = xstrtokend(p)) == NULL) + break; // no more tokens + // + if (libsam3_debug) + fprintf(stderr, "<%s>\n", p); + // + if ((c = malloc(sizeof(SAMFieldList))) == NULL) + return NULL; + c->next = NULL; + c->name = c->value = NULL; + last->next = c; + last = c; + // + if ((e1 = memchr(p, '=', e - p)) != NULL) { + // key=value + if ((c->name = xstrdup(p, e1 - p)) == NULL) + goto error; + if ((c->value = xstrdup(e1 + 1, e - e1 - 1)) == NULL) + goto error; + } else { + // only key (there is no such replies in SAMv3, but... + if ((c->name = xstrdup(p, e - p)) == NULL) + goto error; + if ((c->value = strdup("")) == NULL) + goto error; + } + p = e; + } + // + if (libsam3_debug) + sam3DumpFieldList(first); + // + return first; +error: + sam3FreeFieldList(first); + return NULL; +} + +// NULL: error; else: list of fields +// first item is always 2-word reply, with first word in name and second in +// value +SAMFieldList *sam3ReadReply(int fd) { + char rep[2048]; // should be enough for any reply + // + if (sam3tcpReceiveStr(fd, rep, sizeof(rep)) < 0) + return NULL; + if (libsam3_debug) + fprintf(stderr, "SAM REPLY: [%s]\n", rep); + return sam3ParseReply(rep); +} + +// example: +// r0: 'HELLO' +// r1: 'REPLY' +// field: NULL or 'RESULT' +// VALUE: NULL or 'OK' +// returns bool +int sam3IsGoodReply(const SAMFieldList *list, const char *r0, const char *r1, + const char *field, const char *value) { + if (list != NULL && list->name != NULL && list->value != NULL) { + if (r0 != NULL && strcmp(r0, list->name) != 0) + return 0; + if (r1 != NULL && strcmp(r1, list->value) != 0) + return 0; + if (field != NULL) { + for (list = list->next; list != NULL; list = list->next) { + if (list->name == NULL || list->value == NULL) + return 0; // invalid list, heh + if (strcmp(field, list->name) == 0) { + if (value != NULL && strcmp(value, list->value) != 0) + return 0; + return 1; + } + } + } + return 1; + } + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// by Bob Jenkins +// public domain +// http://burtleburtle.net/bob/rand/smallprng.html +// +//////////////////////////////////////////////////////////////////////////////// +typedef struct { + uint32_t a, b, c, d; +} BJRandCtx; + +#define BJPRNG_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) + +static uint32_t bjprngRand(BJRandCtx *x) { + uint32_t e; + /* original: + e = x->a-BJPRNG_ROT(x->b, 27); + x->a = x->b^BJPRNG_ROT(x->c, 17); + x->b = x->c+x->d; + x->c = x->d+e; + x->d = e+x->a; + */ + /* better, but slower at least in idiotic m$vc */ + e = x->a - BJPRNG_ROT(x->b, 23); + x->a = x->b ^ BJPRNG_ROT(x->c, 16); + x->b = x->c + BJPRNG_ROT(x->d, 11); + x->c = x->d + e; + x->d = e + x->a; + // + return x->d; +} + +static void bjprngInit(BJRandCtx *x, uint32_t seed) { + x->a = 0xf1ea5eed; + x->b = x->c = x->d = seed; + for (int i = 0; i < 20; ++i) + bjprngRand(x); +} + +static inline uint32_t hashint(uint32_t a) { + a -= (a << 6); + a ^= (a >> 17); + a -= (a << 9); + a ^= (a << 4); + a -= (a << 3); + a ^= (a << 10); + a ^= (a >> 15); + return a; +} + +static uint32_t genSeed(void) { + uint32_t res; +#ifndef WIN32 + struct sysinfo sy; + pid_t pid = getpid(); + // + sysinfo(&sy); + res = hashint((uint32_t)pid) ^ hashint((uint32_t)time(NULL)) ^ + hashint((uint32_t)sy.sharedram) ^ hashint((uint32_t)sy.bufferram) ^ + hashint((uint32_t)sy.uptime); +#else + res = hashint((uint32_t)GetCurrentProcessId()) ^ + hashint((uint32_t)GetTickCount()); +#endif + return hashint(res); +} + +//////////////////////////////////////////////////////////////////////////////// +size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen) { + BJRandCtx rc; + size_t len; + size_t retlen; + // + if (dest == NULL || minlen < 1 || maxlen < minlen || minlen > 65536 || + maxlen > 65536) + return -1; + bjprngInit(&rc, genSeed()); + len = minlen + (bjprngRand(&rc) % (maxlen - minlen + 1)); + retlen = len; + while (len--) { + int ch = bjprngRand(&rc) % 64; + // + if (ch >= 0 && ch < 10) + ch += '0'; + else if (ch >= 10 && ch < 36) + ch += 'A' - 10; + else if (ch >= 36 && ch < 62) + ch += 'a' - 36; + else if (ch == 62) + ch = '-'; + else if (ch == 63) + ch = '_'; + else if (ch > 64) + abort(); + *dest++ = ch; + } + *dest++ = 0; + return retlen; +} + +//////////////////////////////////////////////////////////////////////////////// +static int sam3HandshakeInternal(int fd) { + SAMFieldList *rep = NULL; + // + if (sam3tcpPrintf(fd, "HELLO VERSION MIN=3.0 MAX=3.1\n") < 0) + goto error; + rep = sam3ReadReply(fd); + if (!sam3IsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK")) + goto error; + sam3FreeFieldList(rep); + return fd; +error: + sam3tcpDisconnect(fd); + if (rep != NULL) + sam3FreeFieldList(rep); + return -1; +} + +int sam3HandshakeIP(uint32_t ip, int port) { + int fd; + // + if ((fd = sam3tcpConnectIP(ip, (port < 1 || port > 65535 ? 7656 : port))) < 0) + return -1; + return sam3HandshakeInternal(fd); +} + +int sam3Handshake(const char *hostname, int port, uint32_t *ip) { + int fd; + // + if ((fd = sam3tcpConnect( + (hostname == NULL || !hostname[0] ? "localhost" : hostname), + (port < 1 || port > 65535 ? 7656 : port), ip)) < 0) + return -1; + return sam3HandshakeInternal(fd); +} + +//////////////////////////////////////////////////////////////////////////////// +static inline void strcpyerr(Sam3Session *ses, const char *errstr) { + memset(ses->error, 0, sizeof(ses->error)); + if (errstr != NULL) + strncpy(ses->error, errstr, sizeof(ses->error) - 1); +} + +int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port, + int sigType) { + if (ses != NULL) { + SAMFieldList *rep = NULL; + int fd, res = -1; + static const char *sigtypes[5] = { + "SIGNATURE_TYPE=DSA_SHA1", "SIGNATURE_TYPE=ECDSA_SHA256_P256", + "SIGNATURE_TYPE=ECDSA_SHA384_P384", "SIGNATURE_TYPE=ECDSA_SHA512_P521", + "SIGNATURE_TYPE=EdDSA_SHA512_Ed25519"}; + // + if ((fd = sam3Handshake(hostname, port, NULL)) < 0) { + strcpyerr(ses, "I2P_ERROR"); + return -1; + } + // + if (sam3tcpPrintf(fd, "DEST GENERATE %s\n", sigtypes[sigType]) >= 0) { + if ((rep = sam3ReadReply(fd)) != NULL && + sam3IsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) { + const char *pub = sam3FindField(rep, "PUB"), + *priv = sam3FindField(rep, "PRIV"); + // + if (pub != NULL && sam3CheckValidKeyLength(pub) && priv != NULL && + strlen(priv) >= SAM3_PRIVKEY_MIN_SIZE) { + strcpy(ses->pubkey, pub); + strcpy(ses->privkey, priv); + res = 0; + } + } + } + // + sam3FreeFieldList(rep); + sam3tcpDisconnect(fd); + // + return res; + } + return -1; +} + +int sam3NameLookup(Sam3Session *ses, const char *hostname, int port, + const char *name) { + if (ses != NULL && name != NULL && name[0]) { + SAMFieldList *rep = NULL; + int fd, res = -1; + // + if ((fd = sam3Handshake(hostname, port, NULL)) < 0) { + strcpyerr(ses, "I2P_ERROR"); + return -1; + } + // + strcpyerr(ses, "I2P_ERROR"); + if (sam3tcpPrintf(fd, "NAMING LOOKUP NAME=%s\n", name) >= 0) { + if ((rep = sam3ReadReply(fd)) != NULL && + sam3IsGoodReply(rep, "NAMING", "REPLY", "RESULT", NULL)) { + const char *rs = sam3FindField(rep, "RESULT"), + *pub = sam3FindField(rep, "VALUE"); + // + if (strcmp(rs, "OK") == 0) { + if (pub != NULL && sam3CheckValidKeyLength(pub)) { + strcpy(ses->destkey, pub); + strcpyerr(ses, NULL); + res = 0; + } + } else if (rs[0]) { + strcpyerr(ses, rs); + } + } + } + // + sam3FreeFieldList(rep); + sam3tcpDisconnect(fd); + // + return res; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +static int sam3CloseConnectionInternal(Sam3Connection *conn) { + return (conn->fd >= 0 ? sam3tcpDisconnect(conn->fd) : 0); +} + +int sam3CloseConnection(Sam3Connection *conn) { + if (conn != NULL) { + int res = sam3CloseConnectionInternal(conn); + // + if (conn->ses != NULL) { + for (Sam3Connection *p = NULL, *c = conn->ses->connlist; c != NULL; + p = c, c = c->next) { + if (c == conn) { + if (p == NULL) + conn->ses->connlist = c->next; + else + p->next = c->next; + break; + } + } + } + free(conn); + // + return res; + } + return -1; +} + +int sam3CloseSession(Sam3Session *ses) { + if (ses != NULL) { + for (Sam3Connection *n, *c = ses->connlist; c != NULL; c = n) { + n = c->next; + sam3CloseConnectionInternal(c); + free(c); + } + if (ses->fwd_fd >= 0) + sam3tcpDisconnect(ses->fwd_fd); + if (ses->fd >= 0) + sam3tcpDisconnect(ses->fd); + memset(ses, 0, sizeof(Sam3Session)); + ses->fd = -1; + return 0; + } + return -1; +} + +int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, + const char *privkey, Sam3SessionType type, + Sam3SigType sigType, const char *params) { + if (ses != NULL) { + static const char *typenames[3] = {"RAW", "DATAGRAM", "STREAM"}; + static const char *sigtypes[5] = { + "SIGNATURE_TYPE=DSA_SHA1", "SIGNATURE_TYPE=ECDSA_SHA256_P256", + "SIGNATURE_TYPE=ECDSA_SHA384_P384", "SIGNATURE_TYPE=ECDSA_SHA512_P521", + "SIGNATURE_TYPE=EdDSA_SHA512_Ed25519"}; + + SAMFieldList *rep; + const char *v = NULL; + const char *pdel = (params != NULL ? " " : ""); + // + memset(ses, 0, sizeof(Sam3Session)); + ses->fd = -1; + ses->fwd_fd = -1; + // + if (privkey != NULL && strlen(privkey) < SAM3_PRIVKEY_MIN_SIZE) + goto error; + if ((int)type < 0 || (int)type > 2) + goto error; + if (privkey == NULL) + privkey = "TRANSIENT"; + // + ses->type = type; + ses->sigType = sigType; + ses->port = (type == SAM3_SESSION_STREAM ? (port ? port : 7656) : 7655); + sam3GenChannelName(ses->channel, 32, 64); + if (libsam3_debug) + fprintf(stderr, "sam3CreateSession: channel=[%s]\n", ses->channel); + // + if ((ses->fd = sam3Handshake(hostname, port, &ses->ip)) < 0) + goto error; + // + if (libsam3_debug) + fprintf(stderr, "sam3CreateSession: creating session (%s)...\n", + typenames[(int)type]); + if (sam3tcpPrintf( + ses->fd, "SESSION CREATE STYLE=%s ID=%s DESTINATION=%s %s %s %s\n", + typenames[(int)type], ses->channel, privkey, sigtypes[(int)sigType], + pdel, (params != NULL ? params : "")) < 0) + goto error; + if ((rep = sam3ReadReply(ses->fd)) == NULL) + goto error; + if (!sam3IsGoodReply(rep, "SESSION", "STATUS", "RESULT", "OK") || + (v = sam3FindField(rep, "DESTINATION")) == NULL || + strlen(v) < SAM3_PRIVKEY_MIN_SIZE) { + if (libsam3_debug) + fprintf(stderr, "sam3CreateSession: invalid reply (%ld)...\n", + (v != NULL ? strlen(v) : -1)); + if (libsam3_debug) + sam3DumpFieldList(rep); + sam3FreeFieldList(rep); + goto error; + } + // save our keys + strcpy(ses->privkey, v); + sam3FreeFieldList(rep); + // get public key + if (sam3tcpPrintf(ses->fd, "NAMING LOOKUP NAME=ME\n") < 0) + goto error; + if ((rep = sam3ReadReply(ses->fd)) == NULL) + goto error; + v = NULL; + if (!sam3IsGoodReply(rep, "NAMING", "REPLY", "RESULT", "OK") || + (v = sam3FindField(rep, "VALUE")) == NULL || + !sam3CheckValidKeyLength(v)) { + if (libsam3_debug) + fprintf(stderr, "sam3CreateSession: invalid NAMING reply (%ld)...\n", + (v != NULL ? strlen(v) : -1)); + if (libsam3_debug) + sam3DumpFieldList(rep); + sam3FreeFieldList(rep); + goto error; + } + strcpy(ses->pubkey, v); + sam3FreeFieldList(rep); + // + if (libsam3_debug) + fprintf(stderr, "sam3CreateSession: complete.\n"); + return 0; + } +error: + sam3CloseSession(ses); + return -1; +} + +Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) { + if (ses != NULL) { + SAMFieldList *rep; + Sam3Connection *conn; + // + if (ses->type != SAM3_SESSION_STREAM) { + strcpyerr(ses, "INVALID_SESSION_TYPE"); + return NULL; + } + if (ses->fd < 0) { + strcpyerr(ses, "INVALID_SESSION"); + return NULL; + } + if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) { + strcpyerr(ses, "INVALID_KEY"); + return NULL; + } + if ((conn = calloc(1, sizeof(Sam3Connection))) == NULL) { + strcpyerr(ses, "NO_MEMORY"); + return NULL; + } + if ((conn->fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { + strcpyerr(ses, "IO_ERROR_SK"); + goto error; + } + if (sam3tcpPrintf(conn->fd, "STREAM CONNECT ID=%s DESTINATION=%s\n", + ses->channel, destkey) < 0) { + strcpyerr(ses, "IO_ERROR"); + goto error; + } + if ((rep = sam3ReadReply(conn->fd)) == NULL) { + strcpyerr(ses, "IO_ERROR"); + goto error; + } + if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR")); + sam3CloseConnectionInternal(conn); + free(conn); + conn = NULL; + } else { + // no error + strcpyerr(ses, NULL); + } + sam3FreeFieldList(rep); + if (conn != NULL) { + strcpy(conn->destkey, destkey); + conn->ses = ses; + conn->next = ses->connlist; + ses->connlist = conn; + } + return conn; + error: + sam3CloseConnectionInternal(conn); + free(conn); + return NULL; + } + return NULL; +} + +Sam3Connection *sam3StreamAccept(Sam3Session *ses) { + if (ses != NULL) { + SAMFieldList *rep = NULL; + char repstr[1024]; + Sam3Connection *conn; + // + if (ses->type != SAM3_SESSION_STREAM) { + strcpyerr(ses, "INVALID_SESSION_TYPE"); + return NULL; + } + if (ses->fd < 0) { + strcpyerr(ses, "INVALID_SESSION"); + return NULL; + } + if ((conn = calloc(1, sizeof(Sam3Connection))) == NULL) { + strcpyerr(ses, "NO_MEMORY"); + return NULL; + } + if ((conn->fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { + strcpyerr(ses, "IO_ERROR_SK"); + goto error; + } + if (sam3tcpPrintf(conn->fd, "STREAM ACCEPT ID=%s\n", ses->channel) < 0) { + strcpyerr(ses, "IO_ERROR_PF"); + goto error; + } + if ((rep = sam3ReadReply(conn->fd)) == NULL) { + strcpyerr(ses, "IO_ERROR_RP"); + goto error; + } + if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); + goto error; + } + if (sam3tcpReceiveStr(conn->fd, repstr, sizeof(repstr)) < 0) { + strcpyerr(ses, "IO_ERROR_RP1"); + goto error; + } + sam3FreeFieldList(rep); + if ((rep = sam3ParseReply(repstr)) != NULL) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES1")); + goto error; + } + if (!sam3CheckValidKeyLength(repstr)) { + strcpyerr(ses, "INVALID_KEY"); + goto error; + } + sam3FreeFieldList(rep); + strcpy(conn->destkey, repstr); + conn->ses = ses; + conn->next = ses->connlist; + ses->connlist = conn; + strcpyerr(ses, NULL); + return conn; + error: + if (rep != NULL) + sam3FreeFieldList(rep); + sam3CloseConnectionInternal(conn); + free(conn); + return NULL; + } + return NULL; +} + +int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) { + if (ses != NULL) { + SAMFieldList *rep = NULL; + // + if (ses->type != SAM3_SESSION_STREAM) { + strcpyerr(ses, "INVALID_SESSION_TYPE"); + return -1; + } + if (ses->fd < 0) { + strcpyerr(ses, "INVALID_SESSION"); + return -1; + } + if (ses->fwd_fd >= 0) { + strcpyerr(ses, "DUPLICATE_FORWARD"); + return -1; + } + if ((ses->fwd_fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { + strcpyerr(ses, "IO_ERROR_SK"); + goto error; + } + if (sam3tcpPrintf(ses->fwd_fd, "STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=true\n", + ses->channel, port, hostname) < 0) { + strcpyerr(ses, "IO_ERROR_PF"); + goto error; + } + if ((rep = sam3ReadReply(ses->fwd_fd)) == NULL) { + strcpyerr(ses, "IO_ERROR_RP"); + goto error; + } + if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); + goto error; + } + sam3FreeFieldList(rep); + strcpyerr(ses, NULL); + return 0; + error: + if (rep != NULL) + sam3FreeFieldList(rep); + return -1; + } + return -1; +} + +int sam3DatagramSend(Sam3Session *ses, const char *destkey, const void *buf, + size_t bufsize) { + if (ses != NULL) { + char *dbuf; + int res, dbufsz; + // + if (ses->type == SAM3_SESSION_STREAM) { + strcpyerr(ses, "INVALID_SESSION_TYPE"); + return -1; + } + if (ses->fd < 0) { + strcpyerr(ses, "INVALID_SESSION"); + return -1; + } + if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) { + strcpyerr(ses, "INVALID_KEY"); + return -1; + } + if (buf == NULL || bufsize < 1 || bufsize > 31744) { + strcpyerr(ses, "INVALID_DATA"); + return -1; + } + dbufsz = bufsize + 4 + SAM3_PUBKEY_SIZE + 1 + strlen(ses->channel) + 1; + if ((dbuf = malloc(dbufsz)) == NULL) { + strcpyerr(ses, "OUT_OF_MEMORY"); + return -1; + } + sprintf(dbuf, "3.0 %s %s\n", ses->channel, destkey); + memcpy(dbuf + strlen(dbuf), buf, bufsize); + res = sam3udpSendToIP(ses->ip, ses->port, dbuf, dbufsz); + free(dbuf); + strcpyerr(ses, (res < 0 ? "IO_ERROR" : NULL)); + return (res < 0 ? -1 : 0); + } + return -1; +} + +ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize) { + if (ses != NULL) { + SAMFieldList *rep; + const char *v; + ssize_t size = 0; + // + if (ses->type == SAM3_SESSION_STREAM) { + strcpyerr(ses, "INVALID_SESSION_TYPE"); + return -1; + } + if (ses->fd < 0) { + strcpyerr(ses, "INVALID_SESSION"); + return -1; + } + if (buf == NULL || bufsize < 1) { + strcpyerr(ses, "INVALID_BUFFER"); + return -1; + } + if ((rep = sam3ReadReply(ses->fd)) == NULL) { + strcpyerr(ses, "IO_ERROR"); + return -1; + } + if (!sam3IsGoodReply(rep, "DATAGRAM", "RECEIVED", "SIZE", NULL)) { + strcpyerr(ses, "I2P_ERROR"); + sam3FreeFieldList(rep); + return -1; + } + // + if ((v = sam3FindField(rep, "DESTINATION")) != NULL && + sam3CheckValidKeyLength(v)) + strncpy(ses->destkey, v, sizeof(ses->destkey)); + v = sam3FindField(rep, "SIZE"); // we have this field -- for sure + if (!v[0] || !isdigit(*v)) { + strcpyerr(ses, "I2P_ERROR_SIZE"); + sam3FreeFieldList(rep); + return -1; + } + // + while (*v && isdigit(*v)) { + if ((size = size * 10 + v[0] - '0') > bufsize) { + strcpyerr(ses, "I2P_ERROR_BUFFER_TOO_SMALL"); + sam3FreeFieldList(rep); + return -1; + } + ++v; + } + // + if (*v) { + strcpyerr(ses, "I2P_ERROR_SIZE"); + sam3FreeFieldList(rep); + return -1; + } + sam3FreeFieldList(rep); + // + if (sam3tcpReceive(ses->fd, buf, size) != size) { + strcpyerr(ses, "IO_ERROR"); + return -1; + } + strcpyerr(ses, NULL); + return size; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +// output 8 bytes for every 5 input +// return size or <0 on error +ssize_t sam3Base32Encode(char *dest, size_t destsz, const void *srcbuf, + size_t srcsize) { + if (dest != NULL && srcbuf != NULL && srcsize >= 0) { + static const char *const b32chars = "abcdefghijklmnopqrstuvwxyz234567="; + const unsigned char *src = (const unsigned char *)srcbuf; + ssize_t destsize = 0; + // + while (srcsize > 0) { + int blksize = (srcsize < 5 ? srcsize : 5); + unsigned char n[8]; + // + memset(n, 0, sizeof(n)); + switch (blksize) { + case 5: + n[7] = (src[4] & 0x1f); + n[6] = ((src[4] & 0xe0) >> 5); + case 4: + n[6] |= ((src[3] & 0x03) << 3); + n[5] = ((src[3] & 0x7c) >> 2); + n[4] = ((src[3] & 0x80) >> 7); + case 3: + n[4] |= ((src[2] & 0x0f) << 1); + n[3] = ((src[2] & 0xf0) >> 4); + case 2: + n[3] |= ((src[1] & 0x01) << 4); + n[2] = ((src[1] & 0x3e) >> 1); + n[1] = ((src[1] & 0xc0) >> 6); + case 1: + n[1] |= ((src[0] & 0x07) << 2); + n[0] = ((src[0] & 0xf8) >> 3); + break; + } + src += blksize; + srcsize -= blksize; + // pad + switch (blksize) { + case 1: + n[2] = n[3] = 32; + case 2: + n[4] = 32; + case 3: + n[5] = n[6] = 32; + case 4: + n[7] = 32; + case 5: + break; + } + // output + if (destsize + 8 <= destsz) { + for (int f = 0; f < 8; ++f) + *dest++ = b32chars[n[f]]; + } + destsize += 8; + } + if (destsize <= destsz) { + *dest++ = 0; // make valid asciiz string + } + return destsize; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +// output 8 bytes for every 5 input +// return size or <0 on error +ssize_t sam3Base32Decode(char *dest, size_t destsz, const void *srcbuf, + size_t srcsize) { + if (dest != NULL && srcbuf != NULL && srcsize >= 0) { + static const char *const b32chars = "abcdefghijklmnopqrstuvwxyz234567="; + const unsigned char *src = (const unsigned char *)srcbuf; + int destsize = 0; + // + while (srcsize > 0) { + int blksize = (srcsize < 5 ? srcsize : 5); + unsigned char n[8]; + // + memset(n, 0, sizeof(n)); + switch (blksize) { + case 5: + n[7] = (src[4] & 0x1f); + n[6] = ((src[4] & 0xe0) >> 5); + case 4: + n[6] |= ((src[3] & 0x03) << 3); + n[5] = ((src[3] & 0x7c) >> 2); + n[4] = ((src[3] & 0x80) >> 7); + case 3: + n[4] |= ((src[2] & 0x0f) << 1); + n[3] = ((src[2] & 0xf0) >> 4); + case 2: + n[3] |= ((src[1] & 0x01) << 4); + n[2] = ((src[1] & 0x3e) >> 1); + n[1] = ((src[1] & 0xc0) >> 6); + case 1: + n[1] |= ((src[0] & 0x07) << 2); + n[0] = ((src[0] & 0xf8) >> 3); + break; + } + src += blksize; + srcsize -= blksize; + // pad + switch (blksize) { + case 1: + n[2] = n[3] = 32; + case 2: + n[4] = 32; + case 3: + n[5] = n[6] = 32; + case 4: + n[7] = 32; + case 5: + break; + } + // output + if (destsize + 8 <= destsz) { + for (int f = 0; f < 8; ++f) + *dest++ = b32chars[n[f]]; + } + destsize += 8; + } + if (destsize <= destsz) { + *dest++ = 0; // make valid asciiz string + } + return destsize; + } + return -1; +} diff --git a/supportlibs/libsam3/src/libsam3/libsam3.h b/supportlibs/libsam3/src/libsam3/libsam3.h new file mode 100644 index 000000000..3eb261d89 --- /dev/null +++ b/supportlibs/libsam3/src/libsam3/libsam3.h @@ -0,0 +1,280 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#ifndef LIBSAM3_H +#define LIBSAM3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////// +extern int libsam3_debug; + +//////////////////////////////////////////////////////////////////////////////// +#define SAM3_HOST_DEFAULT (NULL) +#define SAM3_PORT_DEFAULT (0) + +#define SAM3_DESTINATION_TRANSIENT (NULL) + +#define SAM3_PUBKEY_SIZE (516) +#define SAM3_CERT_SIZE (100) +#define SAM3_PRIVKEY_MIN_SIZE (884) + +//////////////////////////////////////////////////////////////////////////////// +/* returns fd or -1 */ +/* 'ip': host IP; can be NULL */ +extern int sam3tcpConnect(const char *hostname, int port, uint32_t *ip); +extern int sam3tcpConnectIP(uint32_t ip, int port); + +/* <0: error; 0: ok */ +extern int sam3tcpDisconnect(int fd); + +/* <0: error; 0: ok */ +extern int sam3tcpSetTimeoutSend(int fd, int timeoutms); + +/* <0: error; 0: ok */ +extern int sam3tcpSetTimeoutReceive(int fd, int timeoutms); + +/* <0: error; 0: ok */ +/* sends the whole buffer */ +extern int sam3tcpSend(int fd, const void *buf, size_t bufSize); + +/* <0: received (-res) bytes; read error */ +/* can return less that requesten bytes even if `allowPartial` is 0 when + * connection is closed */ +extern ssize_t sam3tcpReceiveEx(int fd, void *buf, size_t bufSize, + int allowPartial); + +extern ssize_t sam3tcpReceive(int fd, void *buf, size_t bufSize); + +extern int sam3tcpPrintf(int fd, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); + +extern int sam3tcpReceiveStr(int fd, char *dest, size_t maxSize); + +/* pass NULL for 'localhost' and 0 for 7655 */ +/* 'ip': host IP; can be NULL */ +extern int sam3udpSendTo(const char *hostname, int port, const void *buf, + size_t bufSize, uint32_t *ip); +extern int sam3udpSendToIP(uint32_t ip, int port, const void *buf, + size_t bufSize); + +//////////////////////////////////////////////////////////////////////////////// +typedef struct SAMFieldList { + char *name; + char *value; + struct SAMFieldList *next; +} SAMFieldList; + +extern void sam3FreeFieldList(SAMFieldList *list); +extern void sam3DumpFieldList(const SAMFieldList *list); + +/* read and parse SAM reply */ +/* NULL: error; else: list of fields */ +/* first item is always 2-word reply, with first word in name and second in + * value */ +extern SAMFieldList *sam3ReadReply(int fd); + +extern SAMFieldList *sam3ParseReply(const char *rep); + +/* + * example: + * r0: 'HELLO' + * r1: 'REPLY' + * field: NULL or 'RESULT' + * VALUE: NULL or 'OK' + * returns bool + */ +extern int sam3IsGoodReply(const SAMFieldList *list, const char *r0, + const char *r1, const char *field, + const char *value); + +extern const char *sam3FindField(const SAMFieldList *list, const char *field); + +//////////////////////////////////////////////////////////////////////////////// +/* pass NULL for 'localhost' and 0 for 7656 */ +/* returns <0 on error or socket fd on success */ +extern int sam3Handshake(const char *hostname, int port, uint32_t *ip); +extern int sam3HandshakeIP(uint32_t ip, int port); + +//////////////////////////////////////////////////////////////////////////////// +typedef enum { + SAM3_SESSION_RAW, + SAM3_SESSION_DGRAM, + SAM3_SESSION_STREAM +} Sam3SessionType; + +typedef enum { + DSA_SHA1, + ECDSA_SHA256_P256, + ECDSA_SHA384_P384, + ECDSA_SHA512_P521, + EdDSA_SHA512_Ed25519 +} Sam3SigType; + +typedef struct Sam3Session { + Sam3SessionType type; + Sam3SigType sigType; + int fd; + char privkey[SAM3_PRIVKEY_MIN_SIZE + 1]; // destination private key (asciiz) + char pubkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + + 1]; // destination public key (asciiz) + char channel[66]; // name of this sam session (asciiz) + char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + + 1]; // for DGRAM sessions (asciiz) + // int destsig; + char error[32]; // error message (asciiz) + uint32_t ip; + int port; // this will be changed to UDP port for DRAM/RAW (can be 0) + struct Sam3Connection *connlist; // list of opened connections + int fwd_fd; +} Sam3Session; + +typedef struct Sam3Connection { + Sam3Session *ses; + struct Sam3Connection *next; + int fd; + char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + + 1]; // remote destination public key (asciiz) + int destcert; + char error[32]; // error message (asciiz) +} Sam3Connection; + +//////////////////////////////////////////////////////////////////////////////// +/* + * create SAM session + * pass NULL as hostname for 'localhost' and 0 as port for 7656 + * pass NULL as privkey to create TRANSIENT session + * 'params' can be NULL + * see http://www.i2p2.i2p/i2cp.html#options for common options, + * and http://www.i2p2.i2p/streaming.html#options for STREAM options + * if result<0: error, 'ses' fields are undefined, no need to call + * sam3CloseSession() if result==0: ok, all 'ses' fields are filled + * TODO: don't clear 'error' field on error (and set it to something meaningful) + */ +extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, + const char *privkey, Sam3SessionType type, + Sam3SigType sigType, const char *params); + +/* + * close SAM session (and all it's connections) + * returns <0 on error, 0 on ok + * 'ses' must be properly initialized + */ +extern int sam3CloseSession(Sam3Session *ses); + +/* + * Check to make sure that the destination in use is of a valid length, returns + * 1 if true and 0 if false. + */ +int sam3CheckValidKeyLength(const char *pubkey); + +/* + * open stream connection to 'destkey' endpoint + * 'destkey' is 516-byte public key (asciiz) + * returns <0 on error, fd on ok + * you still have to call sam3CloseSession() on failure + * sets ses->error on error + */ +extern Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey); + +/* + * accepts stream connection and sets 'destkey' + * 'destkey' is 516-byte public key + * returns <0 on error, fd on ok + * you still have to call sam3CloseSession() on failure + * sets ses->error on error + * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() + */ +extern Sam3Connection *sam3StreamAccept(Sam3Session *ses); + +/* + * sets up forwarding stream connection + * returns <0 on error, 0 on ok + * you still have to call sam3CloseSession() on failure + * sets ses->error on error + * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() + */ +extern int sam3StreamForward(Sam3Session *ses, const char *hostname, int port); + +/* + * close SAM connection + * returns <0 on error, 0 on ok + * 'conn' must be properly initialized + * 'conn' is invalid after call + */ +extern int sam3CloseConnection(Sam3Connection *conn); + +//////////////////////////////////////////////////////////////////////////////// +/* + * generate new keypair + * fills 'privkey' and 'pubkey' only + * you should not call sam3CloseSession() on 'ses' + * will not set 'error' field + * returns <0 on error, 0 on ok + */ +extern int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port, + int sigType); + +/* + * do name lookup (something like gethostbyname()) + * fills 'destkey' only + * you should not call sam3CloseSession() on 'ses' + * will set 'error' field + * returns <0 on error, 0 on ok + */ +extern int sam3NameLookup(Sam3Session *ses, const char *hostname, int port, + const char *name); + +//////////////////////////////////////////////////////////////////////////////// +/* + * sends datagram to 'destkey' endpoint + * 'destkey' is 516-byte public key + * returns <0 on error, 0 on ok + * you still have to call sam3CloseSession() on failure + * sets ses->error on error + * don't send datagrams bigger than 31KB! + */ +extern int sam3DatagramSend(Sam3Session *ses, const char *destkey, + const void *buf, size_t bufsize); + +/* + * receives datagram and sets 'destkey' to source pubkey (if not RAW) + * returns <0 on error (buffer too small is error too) or number of bytes + * written to 'buf' you still have to call sam3CloseSession() on failure sets + * ses->error on error will necer receive datagrams bigger than 31KB (32KB for + * RAW) + */ +extern ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize); + +/* + * generate random sam channel name + * return the size of the string + */ +extern size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen); + +//////////////////////////////////////////////////////////////////////////////// +// NOT including '\0' terminator +static inline size_t sam3Base32EncodedLength(size_t size) { + return (((size + 5 - 1) / 5) * 8); +} + +// output 8 bytes for every 5 input +// return size or <0 on error +extern ssize_t sam3Base32Encode(char *dest, size_t destsz, const void *srcbuf, + size_t srcsize); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.c b/supportlibs/libsam3/src/libsam3a/libsam3a.c new file mode 100644 index 000000000..40921e6ba --- /dev/null +++ b/supportlibs/libsam3/src/libsam3a/libsam3a.c @@ -0,0 +1,1757 @@ +/* async SAMv3 library + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include "libsam3a.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +int libsam3a_debug = 0; + +#define DEFAULT_TCP_PORT (7656) +#define DEFAULT_UDP_PORT (7655) + +//////////////////////////////////////////////////////////////////////////////// +uint64_t sam3atimeval2ms(const struct timeval *tv) { + return ((uint64_t)tv->tv_sec) * 1000 + ((uint64_t)tv->tv_usec) / 1000; +} + +void sam3ams2timeval(struct timeval *tv, uint64_t ms) { + tv->tv_sec = ms / 1000; + tv->tv_usec = (ms % 1000) * 1000; +} + +//////////////////////////////////////////////////////////////////////////////// +static inline int isValidKeyChar(char ch) { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || + (ch >= '0' && ch <= '9') || ch == '-' || ch == '~'; +} + +int sam3aIsValidPubKey(const char *key) { + if (key != NULL && strlen(key) == SAM3A_PUBKEY_SIZE) { + for (int f = 0; f < SAM3A_PUBKEY_SIZE; ++f) + if (!isValidKeyChar(key[f])) + return 0; + return 1; + } + return 0; +} + +int sam3aIsValidPrivKey(const char *key) { + if (key != NULL && strlen(key) == SAM3A_PRIVKEY_SIZE) { + for (int f = 0; f < SAM3A_PRIVKEY_SIZE; ++f) + if (!isValidKeyChar(key[f])) + return 0; + return 1; + } + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +/* +static int sam3aSocketSetTimeoutSend (int fd, int timeoutms) { + if (fd >= 0 && timeoutms >= 0) { + struct timeval tv; + // + ms2timeval(&tv, timeoutms); + return (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 ? -1 : +0); + } + return -1; +} + + +static int sam3aSocketSetTimeoutReceive (int fd, int timeoutms) { + if (fd >= 0 && timeoutms >= 0) { + struct timeval tv; + // + ms2timeval(&tv, timeoutms); + return (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ? -1 : +0); + } + return -1; +} +*/ + +static int sam3aBytesAvail(int fd) { + int av = 0; + // + if (ioctl(fd, FIONREAD, &av) < 0) + return -1; + return av; +} + +static uint32_t sam3aResolveHost(const char *hostname) { + struct hostent *host; + // + if (hostname == NULL || !hostname[0]) + return 0; + if ((host = gethostbyname(hostname)) == NULL || host->h_name == NULL || + !host->h_addr_list[0][0]) { + if (libsam3a_debug) + fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); + return 0; + } + return ((struct in_addr *)host->h_addr_list[0])->s_addr; +} + +static int sam3aConnect(uint32_t ip, int port, int *complete) { + int fd, val = 1; + // + if (complete != NULL) + *complete = 0; + if (ip == 0 || ip == 0xffffffffUL || port < 1 || port > 65535) + return -1; + // + // yes, this is Linux-specific; you know what? i don't care. + if ((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)) < 0) + return -1; + // + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); + // + for (;;) { + struct sockaddr_in addr; + // + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = ip; + // + if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { + if (errno == EINPROGRESS) + break; // the process is started + if (errno != EINTR) { + close(fd); + return -1; + } + } else { + // connection complete + if (complete != NULL) + *complete = 1; + break; + } + } + // + return fd; +} + +// <0: error; 0: ok +static int sam3aDisconnect(int fd) { + if (fd >= 0) { + shutdown(fd, SHUT_RDWR); + return close(fd); + } + // + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +// <0: error; >=0: bytes sent +static int sam3aSendBytes(int fd, const void *buf, int bufSize) { + const char *c = (const char *)buf; + int total = 0; + // + if (fd < 0 || (buf == NULL && bufSize > 0)) + return -1; + // + while (bufSize > 0) { + int wr = send(fd, c, bufSize, MSG_NOSIGNAL); + // + if (wr < 0) { + if (errno == EINTR) + continue; // interrupted by signal + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // bufSize is too big + if (bufSize == 1) + break; // can't send anything + // try to send a half of a buffer + if ((wr = sam3aSendBytes(fd, c, bufSize / 2)) < 0) + return wr; // error + } else { + return -1; // alas + } + } + // + if (wr == 0) + break; // can't send anything + c += wr; + bufSize -= wr; + total += wr; + } + // + return total; +} + +/* <0: error; >=0: bytes received */ +/* note that you should call this function when there is some bytes to read, so + * 0 means 'connection closed' */ +/* +static int sam3aReceive (int fd, void *buf, int bufSize) { + char *c = (char *)buf; + int total = 0; + // + if (fd < 0 || (buf == NULL && bufSize > 0)) return -1; + // + while (bufSize > 0) { + int av = sam3aBytesAvail(fd), rd; + // + if (av == 0) break; // no more + if (av > bufSize) av = bufSize; + rd = recv(fd, c, av, 0); + if (rd < 0) { + if (errno == EINTR) continue; // interrupted by signal + if (errno == EAGAIN || errno == EWOULDBLOCK) break; // the thing that +should not be return -1; // error + } + if (rd == 0) break; + c += rd; + bufSize -= rd; + total += rd; + } + // + return total; +} +*/ + +//////////////////////////////////////////////////////////////////////////////// +char *sam3PrintfVA(int *plen, const char *fmt, va_list app) { + char buf[1024], *p = buf; + int size = sizeof(buf) - 1, len = 0; + // + if (plen != NULL) + *plen = 0; + for (;;) { + va_list ap; + char *np; + int n; + // + va_copy(ap, app); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + // + if (n > -1 && n < size) { + len = n; + break; + } + if (n > -1) + size = n + 1; + else + size *= 2; + if (p == buf) { + if ((p = malloc(size)) == NULL) + return NULL; + } else { + if ((np = realloc(p, size)) == NULL) { + free(p); + return NULL; + } + p = np; + } + } + // + if (p == buf) { + if ((p = malloc(len + 1)) == NULL) + return NULL; + memcpy(p, buf, len + 1); + } + if (plen != NULL) + *plen = len; + return p; +} + +__attribute__((format(printf, 2, 3))) char *sam3Printf(int *plen, + const char *fmt, ...) { + va_list ap; + char *res; + // + va_start(ap, fmt); + res = sam3PrintfVA(plen, fmt, ap); + va_end(ap); + // + return res; +} + +/* + * check if we have EOL in received socket data + * this function should be called when sam3aBytesAvail() result > 0 + * return: <0: error; 0: no EOL in bytes2check, else: # of bytes to EOL + * (including EOL itself) + */ +/* +static int sam3aCheckEOL (int fd, int bytes2check) { + char *d = dest; + // + if (bytes2check < 0 || fd < 0) return -1; + memset(dest, 0, maxSize); + while (maxSize > 1) { + char *e; + int rd = recv(fd, d, maxSize-1, MSG_PEEK); + // + if (rd < 0 && errno == EINTR) continue; // interrupted by signal + if (rd == 0) { + rd = recv(fd, d, 1, 0); + if (rd < 0 && errno == EINTR) continue; // interrupted by signal + if (d[0] == '\n') { + d[0] = 0; // remove '\n' + return 0; + } + } else { + if (rd < 0) return -1; // error or connection closed; alas + } + // check for EOL + d[maxSize-1] = 0; + if ((e = strchr(d, '\n')) != NULL) { + rd = e-d+1; // bytes to receive + if (sam3atcpReceive(fd, d, rd) < 0) return -1; // alas + d[rd-1] = 0; // remove '\n' + return 0; // done + } else { + // let's receive this part and go on + if (sam3atcpReceive(fd, d, rd) < 0) return -1; // alas + maxSize -= rd; + d += rd; + } + } + // alas, the string is too big + return -1; +} +*/ + +//////////////////////////////////////////////////////////////////////////////// +/* +int sam3audpSendToIP (uint32_t ip, int port, const void *buf, int bufSize) { + struct sockaddr_in addr; + int fd, res; + // + if (buf == NULL || bufSize < 1) return -1; + if (port < 1 || port > 65535) port = 7655; + // + if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + if (libsam3a_debug) fprintf(stderr, "ERROR: can't create socket\n"); + return -1; + } + // + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = ip; + // + res = sendto(fd, buf, bufSize, 0, (struct sockaddr *)&addr, sizeof(addr)); + // + if (res < 0) { + if (libsam3a_debug) { + res = errno; + fprintf(stderr, "UDP ERROR (%d): %s\n", res, strerror(res)); + } + res = -1; + } else { + if (libsam3a_debug) fprintf(stderr, "UDP: %d bytes sent\n", res); + } + // + close(fd); + // + return (res >= 0 ? 0 : -1); +} + + +int sam3audpSendTo (const char *hostname, int port, const void *buf, int +bufSize, uint32_t *ip) { struct hostent *host = NULL; + // + if (buf == NULL || bufSize < 1) return -1; + if (hostname == NULL || !hostname[0]) hostname = "localhost"; + if (port < 1 || port > 65535) port = 7655; + // + host = gethostbyname(hostname); + if (host == NULL || host->h_name == NULL || !host->h_name[0]) { + if (libsam3a_debug) fprintf(stderr, "ERROR: can't resolve '%s'\n", +hostname); return -1; + } + // + if (ip != NULL) *ip = ((struct in_addr *)host->h_addr)->s_addr; + return sam3audpSendToIP(((struct in_addr *)host->h_addr)->s_addr, port, buf, +bufSize); +} +*/ + +//////////////////////////////////////////////////////////////////////////////// +typedef struct SAMFieldList { + char *name; + char *value; + struct SAMFieldList *next; +} SAMFieldList; + +static void sam3aFreeFieldList(SAMFieldList *list) { + while (list != NULL) { + SAMFieldList *c = list; + // + list = list->next; + if (c->name != NULL) + free(c->name); + if (c->value != NULL) + free(c->value); + free(c); + } +} + +static void sam3aDumpFieldList(const SAMFieldList *list) { + for (; list != NULL; list = list->next) { + fprintf(stderr, "%s=[%s]\n", list->name, list->value); + } +} + +static const char *sam3aFindField(const SAMFieldList *list, const char *field) { + if (list != NULL && field != NULL) { + for (list = list->next; list != NULL; list = list->next) { + if (list->name != NULL && strcmp(field, list->name) == 0) + return list->value; + } + } + return NULL; +} + +static char *xstrdup(const char *s, int len) { + if (len >= 0) { + char *res = malloc(len + 1); + // + if (res != NULL) { + if (len > 0) + memcpy(res, s, len); + res[len] = 0; + } + // + return res; + } + // + return NULL; +} + +// returns NULL if there are no more tokens +static inline const char *xstrtokend(const char *s) { + while (*s && isspace(*s)) + ++s; + // + if (*s) { + char qch = 0; + // + while (*s) { + if (*s == qch) { + qch = 0; + } else if (*s == '"') { + qch = *s; + } else if (qch) { + if (*s == '\\' && s[1]) + ++s; + } else if (isspace(*s)) { + break; + } + ++s; + } + } else { + s = NULL; + } + // + return s; +} + +SAMFieldList *sam3aParseReply(const char *rep) { + SAMFieldList *first = NULL, *last, *c; + const char *p = rep, *e, *e1; + // + // first 2 words + while (*p && isspace(*p)) + ++p; + if ((e = xstrtokend(p)) == NULL) + return NULL; + if ((e1 = xstrtokend(e)) == NULL) + return NULL; + // + if ((first = last = c = malloc(sizeof(SAMFieldList))) == NULL) + return NULL; + c->next = NULL; + c->name = c->value = NULL; + if ((c->name = xstrdup(p, e - p)) == NULL) + goto error; + while (*e && isspace(*e)) + ++e; + if ((c->value = xstrdup(e, e1 - e)) == NULL) + goto error; + // + p = e1; + while (*p) { + while (*p && isspace(*p)) + ++p; + if ((e = xstrtokend(p)) == NULL) + break; // no more tokens + // + if (libsam3a_debug) + fprintf(stderr, "<%s>\n", p); + // + if ((c = malloc(sizeof(SAMFieldList))) == NULL) + return NULL; + c->next = NULL; + c->name = c->value = NULL; + last->next = c; + last = c; + // + if ((e1 = memchr(p, '=', e - p)) != NULL) { + // key=value + if ((c->name = xstrdup(p, e1 - p)) == NULL) + goto error; + if ((c->value = xstrdup(e1 + 1, e - e1 - 1)) == NULL) + goto error; + } else { + // only key (there is no such replies in SAMv3, but... + if ((c->name = xstrdup(p, e - p)) == NULL) + goto error; + if ((c->value = strdup("")) == NULL) + goto error; + } + p = e; + } + // + if (libsam3a_debug) + sam3aDumpFieldList(first); + // + return first; +error: + sam3aFreeFieldList(first); + return NULL; +} + +// example: +// r0: 'HELLO' +// r1: 'REPLY' +// field: NULL or 'RESULT' +// VALUE: NULL or 'OK' +// returns bool +int sam3aIsGoodReply(const SAMFieldList *list, const char *r0, const char *r1, + const char *field, const char *value) { + if (list != NULL && list->name != NULL && list->value != NULL) { + if (r0 != NULL && strcmp(r0, list->name) != 0) + return 0; + if (r1 != NULL && strcmp(r1, list->value) != 0) + return 0; + if (field != NULL) { + for (list = list->next; list != NULL; list = list->next) { + if (list->name == NULL || list->value == NULL) + return 0; // invalid list, heh + if (strcmp(field, list->name) == 0) { + if (value != NULL && strcmp(value, list->value) != 0) + return 0; + return 1; + } + } + } + return 1; + } + return 0; +} + +// NULL: error; else: list of fields +// first item is always 2-word reply, with first word in name and second in +// value +/* +SAMFieldList *sam3aReadReply (int fd) { + char rep[2048]; // should be enough for any reply + // + if (sam3atcpReceiveStr(fd, rep, sizeof(rep)) < 0) return NULL; + if (libsam3a_debug) fprintf(stderr, "SAM REPLY: [%s]\n", rep); + return sam3aParseReply(rep); +} +*/ + +//////////////////////////////////////////////////////////////////////////////// +// by Bob Jenkins +// public domain +// http://burtleburtle.net/bob/rand/smallprng.html +// +//////////////////////////////////////////////////////////////////////////////// +typedef struct { + uint32_t a, b, c, d; +} BJRandCtx; + +#define BJPRNG_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) + +static uint32_t bjprngRand(BJRandCtx *x) { + uint32_t e; + /* original: + e = x->a-BJPRNG_ROT(x->b, 27); + x->a = x->b^BJPRNG_ROT(x->c, 17); + x->b = x->c+x->d; + x->c = x->d+e; + x->d = e+x->a; + */ + /* better, but slower at least in idiotic m$vc */ + e = x->a - BJPRNG_ROT(x->b, 23); + x->a = x->b ^ BJPRNG_ROT(x->c, 16); + x->b = x->c + BJPRNG_ROT(x->d, 11); + x->c = x->d + e; + x->d = e + x->a; + // + return x->d; +} + +static void bjprngInit(BJRandCtx *x, uint32_t seed) { + x->a = 0xf1ea5eed; + x->b = x->c = x->d = seed; + for (int i = 0; i < 20; ++i) + bjprngRand(x); +} + +static inline uint32_t hashint(uint32_t a) { + a -= (a << 6); + a ^= (a >> 17); + a -= (a << 9); + a ^= (a << 4); + a -= (a << 3); + a ^= (a << 10); + a ^= (a >> 15); + return a; +} + +static uint32_t genSeed(void) { + volatile uint32_t seed = 1; + uint32_t res; +#ifndef WIN32 + struct sysinfo sy; + pid_t pid = getpid(); + // + sysinfo(&sy); + res = hashint((uint32_t)pid) ^ hashint((uint32_t)time(NULL)) ^ + hashint((uint32_t)sy.sharedram) ^ hashint((uint32_t)sy.bufferram) ^ + hashint((uint32_t)sy.uptime); +#else + res = hashint((uint32_t)GetCurrentProcessId()) ^ + hashint((uint32_t)GetTickCount()); +#endif + res += __sync_fetch_and_add(&seed, 1); + // + return hashint(res); +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aGenChannelName(char *dest, int minlen, int maxlen) { + BJRandCtx rc; + int len; + // + if (dest == NULL || minlen < 1 || maxlen < minlen || minlen > 65536 || + maxlen > 65536) + return -1; + bjprngInit(&rc, genSeed()); + len = minlen + (bjprngRand(&rc) % (maxlen - minlen + 1)); + while (len-- > 0) { + int ch = bjprngRand(&rc) % 64; + // + if (ch >= 0 && ch < 10) + ch += '0'; + else if (ch >= 10 && ch < 36) + ch += 'A' - 10; + else if (ch >= 36 && ch < 62) + ch += 'a' - 36; + else if (ch == 62) + ch = '-'; + else if (ch == 63) + ch = '_'; + else if (ch > 64) + abort(); + *dest++ = ch; + } + *dest++ = 0; + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aIsActiveSession(const Sam3ASession *ses) { + return (ses != NULL && ses->fd >= 0 && !ses->cancelled); +} + +int sam3aIsActiveConnection(const Sam3AConnection *conn) { + return (conn != NULL && conn->fd >= 0 && !conn->cancelled); +} + +//////////////////////////////////////////////////////////////////////////////// +static inline void strcpyerrs(Sam3ASession *ses, const char *errstr) { + // memset(ses->error, 0, sizeof(ses->error)); + ses->error[sizeof(ses->error) - 1] = 0; + if (errstr != NULL) + strncpy(ses->error, errstr, sizeof(ses->error) - 1); +} + +static inline void strcpyerrc(Sam3AConnection *conn, const char *errstr) { + // memset(conn->error, 0, sizeof(conn->error)); + conn->error[sizeof(conn->error) - 1] = 0; + if (errstr != NULL) + strncpy(conn->error, errstr, sizeof(conn->error) - 1); +} + +static void connDisconnect(Sam3AConnection *conn) { + conn->cbAIOProcessorR = conn->cbAIOProcessorW = NULL; + if (conn->aio.data != NULL) { + free(conn->aio.data); + conn->aio.data = NULL; + } + if (!conn->cancelled && conn->fd >= 0) { + conn->cancelled = 1; + shutdown(conn->fd, SHUT_RDWR); + if (conn->callDisconnectCB && conn->cb.cbDisconnected != NULL) + conn->cb.cbDisconnected(conn); + } +} + +static void sesDisconnect(Sam3ASession *ses) { + ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; + if (ses->aio.data != NULL) { + free(ses->aio.data); + ses->aio.data = NULL; + } + if (!ses->cancelled && ses->fd >= 0) { + ses->cancelled = 1; + shutdown(ses->fd, SHUT_RDWR); + for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) + connDisconnect(c); + if (ses->callDisconnectCB && ses->cb.cbDisconnected != NULL) + ses->cb.cbDisconnected(ses); + } +} + +static void sesError(Sam3ASession *ses, const char *errstr) { + if (errstr == NULL || !errstr[0]) + errstr = "I2P_ERROR"; + strcpyerrs(ses, errstr); + if (ses->cb.cbError != NULL) + ses->cb.cbError(ses); + sesDisconnect(ses); +} + +static void connError(Sam3AConnection *conn, const char *errstr) { + if (errstr == NULL || !errstr[0]) + errstr = "I2P_ERROR"; + strcpyerrc(conn, errstr); + if (conn->cb.cbError != NULL) + conn->cb.cbError(conn); + connDisconnect(conn); +} + +//////////////////////////////////////////////////////////////////////////////// +static int aioSender(int fd, Sam3AIO *aio) { + int wr = sam3aSendBytes(fd, aio->data + aio->dataPos, + aio->dataUsed - aio->dataPos); + // + if (wr < 0) + return -1; + aio->dataPos += wr; + return 0; +} + +// dataUsed: max line size (with '\n') +// dataSize: must be at least (dataUsed+1) +static int aioLineReader(int fd, Sam3AIO *aio) { + // + for (;;) { + int av = sam3aBytesAvail(fd), rd; + // + if (av < 0) + return -1; + if (av == 0) + return 0; // do nothing + if (aio->dataPos >= aio->dataUsed - 1) + return -1; // line too long + if ((rd = (aio->dataUsed - 1) - aio->dataPos) > av) + rd = av; + if ((rd = recv(fd, aio->data + aio->dataPos, rd, MSG_PEEK)) < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (rd == 0) + return 0; // do nothing + // now look for '\n' + for (int f = aio->dataPos; f < aio->dataPos + rd; ++f) { + if (aio->data[f] == '\n') { + // got it! + if (recv(fd, aio->data + aio->dataPos, f - aio->dataPos + 1, 0) != + f + 1) + return -1; // the thing that should not be + aio->data[f] = 0; // convert to asciiz + aio->dataUsed = aio->dataPos = f; // length + return 1; // '\n' found! + } + if (!aio->data[f]) + return -1; // there should not be zero bytes + } + // no '\n' found + if (recv(fd, aio->data + aio->dataPos, rd, 0) != rd) + return -1; // the thing that should not be + aio->dataPos += rd; + } +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioSesCmdReplyReader(Sam3ASession *ses) { + int res = aioLineReader(ses->fd, &ses->aio); + // + if (res < 0) { + sesError(ses, "IO_ERROR"); + return; + } + if (res > 0) { + // we got full line + if (libsam3a_debug) + fprintf(stderr, "CMDREPLY: %s\n", ses->aio.data); + if (ses->aio.cbReplyCheckSes != NULL) + ses->aio.cbReplyCheckSes(ses); + } +} + +static void aioSesCmdSender(Sam3ASession *ses) { + if (ses->aio.dataPos < ses->aio.dataUsed) { + if (aioSender(ses->fd, &ses->aio) < 0) { + sesError(ses, "IO_ERROR"); + return; + } + } + // + if (ses->aio.dataPos == ses->aio.dataUsed) { + // hello sent, now wait for reply + // 2048 bytes of reply line should be enough + if (ses->aio.dataSize < 2049) { + char *n = realloc(ses->aio.data, 2049); + // + if (n == NULL) { + sesError(ses, "MEMORY_ERROR"); + return; + } + ses->aio.data = n; + ses->aio.dataSize = 2049; + } + ses->aio.dataUsed = 2048; + ses->aio.dataPos = 0; + ses->cbAIOProcessorR = aioSesCmdReplyReader; + ses->cbAIOProcessorW = NULL; + } +} + +static __attribute__((format(printf, 3, 4))) int +aioSesSendCmdWaitReply(Sam3ASession *ses, void (*cbCheck)(Sam3ASession *ses), + const char *fmt, ...) { + va_list ap; + char *str; + int len; + // + va_start(ap, fmt); + str = sam3PrintfVA(&len, fmt, ap); + va_end(ap); + // + if (str == NULL) + return -1; + if (ses->aio.data != NULL) + free(ses->aio.data); + ses->aio.data = str; + ses->aio.dataUsed = len; + ses->aio.dataSize = len + 1; + ses->aio.dataPos = 0; + ses->aio.cbReplyCheckSes = cbCheck; + ses->cbAIOProcessorR = NULL; + ses->cbAIOProcessorW = aioSesCmdSender; + // + if (libsam3a_debug) + fprintf(stderr, "CMD: %s", str); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioSesHelloChecker(Sam3ASession *ses) { + SAMFieldList *rep = sam3aParseReply(ses->aio.data); + // + if (rep != NULL && sam3aIsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK") && + sam3aIsGoodReply(rep, NULL, NULL, "VERSION", "3.0")) { + ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; + sam3aFreeFieldList(rep); + if (ses->aio.udata != NULL) { + void (*cbComplete)(Sam3ASession * ses) = ses->aio.udata; + // + cbComplete(ses); + } + } else { + sam3aFreeFieldList(rep); + sesError(ses, NULL); + } +} + +static int sam3aSesStartHandshake(Sam3ASession *ses, + void (*cbComplete)(Sam3ASession *ses)) { + if (cbComplete != NULL) + ses->aio.udata = cbComplete; + if (aioSesSendCmdWaitReply(ses, aioSesHelloChecker, "%s\n", + "HELLO VERSION MIN=3.0 MAX=3.0") < 0) + return -1; + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioSesNameMeChecker(Sam3ASession *ses) { + SAMFieldList *rep = sam3aParseReply(ses->aio.data); + const char *v = NULL; + // + if (rep == NULL) { + sesError(ses, NULL); + return; + } + if (!sam3aIsGoodReply(rep, "NAMING", "REPLY", "RESULT", "OK") || + (v = sam3aFindField(rep, "VALUE")) == NULL || + strlen(v) != SAM3A_PUBKEY_SIZE) { + // if (libsam3a_debug) fprintf(stderr, "sam3aCreateSession: invalid NAMING + // reply (%d)...\n", (v != NULL ? strlen(v) : -1)); + if ((v = sam3aFindField(rep, "RESULT")) != NULL && strcmp(v, "OK") == 0) + v = NULL; + sesError(ses, v); + sam3aFreeFieldList(rep); + return; + } + strcpy(ses->pubkey, v); + sam3aFreeFieldList(rep); + // + ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; + ses->callDisconnectCB = 1; + if (ses->cb.cbCreated != NULL) + ses->cb.cbCreated(ses); +} + +static void aioSesCreateChecker(Sam3ASession *ses) { + SAMFieldList *rep = sam3aParseReply(ses->aio.data); + const char *v; + // + if (rep == NULL) { + sesError(ses, NULL); + return; + } + if (!sam3aIsGoodReply(rep, "SESSION", "STATUS", "RESULT", "OK") || + (v = sam3aFindField(rep, "DESTINATION")) == NULL || + strlen(v) != SAM3A_PRIVKEY_SIZE) { + sam3aFreeFieldList(rep); + if ((v = sam3aFindField(rep, "RESULT")) != NULL && strcmp(v, "OK") == 0) + v = NULL; + sesError(ses, v); + return; + } + // ok + // fprintf(stderr, "\nPK: %s\n", v); + strcpy(ses->privkey, v); + sam3aFreeFieldList(rep); + // get our public key + if (aioSesSendCmdWaitReply(ses, aioSesNameMeChecker, "%s\n", + "NAMING LOOKUP NAME=ME") < 0) { + sesError(ses, "MEMORY_ERROR"); + } +} + +// handshake for SESSION CREATE complete +static void aioSesHandshacked(Sam3ASession *ses) { + static const char *typenames[3] = {"RAW", "DATAGRAM", "STREAM"}; + // + if (aioSesSendCmdWaitReply( + ses, aioSesCreateChecker, + "SESSION CREATE STYLE=%s ID=%s DESTINATION=%s%s%s\n", + typenames[(int)ses->type], ses->channel, ses->privkey, + (ses->params != NULL ? " " : ""), + (ses->params != NULL ? ses->params : "")) < 0) { + sesError(ses, "MEMORY_ERROR"); + } +} + +static void aioSesConnected(Sam3ASession *ses) { + int res; + socklen_t len = sizeof(res); + // + if (getsockopt(ses->fd, SOL_SOCKET, SO_ERROR, &res, &len) == 0 && res == 0) { + // ok, connected + if (sam3aSesStartHandshake(ses, NULL) < 0) + sesError(ses, NULL); + } else { + // connection error + sesError(ses, "CONNECTION_ERROR"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aCreateSessionEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, + const char *hostname, int port, const char *privkey, + Sam3ASessionType type, const char *params, + int timeoutms) { + if (ses != NULL) { + // int complete = 0; + // + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + if (cb != NULL) + ses->cb = *cb; + if (hostname == NULL || !hostname[0]) + hostname = "127.0.0.1"; + if (port < 0 || port > 65535) + goto error; + if (privkey != NULL && strlen(privkey) != SAM3A_PRIVKEY_SIZE) + goto error; + if ((int)type < 0 || (int)type > 2) + goto error; + if (privkey == NULL) + privkey = "TRANSIENT"; + strcpy(ses->privkey, privkey); + if (params != NULL && (ses->params = strdup(params)) == NULL) + goto error; + ses->timeoutms = timeoutms; + // + if (!port) + port = DEFAULT_TCP_PORT; + ses->type = type; + ses->port = (type == SAM3A_SESSION_STREAM ? port : DEFAULT_UDP_PORT); + if ((ses->ip = sam3aResolveHost(hostname)) == 0) + goto error; + sam3aGenChannelName(ses->channel, 32, 64); + if (libsam3a_debug) + fprintf(stderr, "sam3aCreateSession: channel=[%s]\n", ses->channel); + // + ses->aio.udata = aioSesHandshacked; + ses->cbAIOProcessorW = aioSesConnected; + if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) + goto error; + /* + if (complete) { + ses->cbAIOProcessorW(ses); + if (!sam3aIsActiveSession(ses)) return -1; + } + */ + // + return 0; // ok, connection process initiated + error: + if (ses->fd >= 0) + sam3aDisconnect(ses->fd); + if (ses->params != NULL) + free(ses->params); + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aCancelSession(Sam3ASession *ses) { + if (ses != NULL) { + sesDisconnect(ses); + return 0; + } + return -1; +} + +int sam3aCloseSession(Sam3ASession *ses) { + if (ses != NULL) { + sam3aCancelSession(ses); + while (ses->connlist != NULL) + sam3aCloseConnection(ses->connlist); + if (ses->cb.cbDestroy != NULL) + ses->cb.cbDestroy(ses); + if (ses->params != NULL) { + free(ses->params); + ses->params = NULL; + } + memset(ses, 0, sizeof(Sam3ASession)); + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioSesKeyGenChecker(Sam3ASession *ses) { + SAMFieldList *rep = sam3aParseReply(ses->aio.data); + // + if (rep == NULL) { + sesError(ses, NULL); + return; + } + if (sam3aIsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) { + const char *pub = sam3aFindField(rep, "PUB"), + *priv = sam3aFindField(rep, "PRIV"); + // + if (pub != NULL && strlen(pub) == SAM3A_PUBKEY_SIZE && priv != NULL && + strlen(priv) == SAM3A_PRIVKEY_SIZE) { + strcpy(ses->pubkey, pub); + strcpy(ses->privkey, priv); + sam3aFreeFieldList(rep); + if (ses->cb.cbCreated != NULL) + ses->cb.cbCreated(ses); + sam3aCancelSession(ses); + return; + } + } + sam3aFreeFieldList(rep); + sesError(ses, NULL); +} + +// handshake for SESSION CREATE complete +static void aioSesKeyGenHandshacked(Sam3ASession *ses) { + if (aioSesSendCmdWaitReply(ses, aioSesKeyGenChecker, "%s\n", + "DEST GENERATE") < 0) { + sesError(ses, "MEMORY_ERROR"); + } +} + +int sam3aGenerateKeysEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, + const char *hostname, int port, int timeoutms) { + if (ses != NULL) { + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + if (cb != NULL) + ses->cb = *cb; + if (hostname == NULL || !hostname[0]) + hostname = "127.0.0.1"; + if (port < 0 || port > 65535) + goto error; + ses->timeoutms = timeoutms; + // + if (!port) + port = DEFAULT_TCP_PORT; + ses->port = port; + if ((ses->ip = sam3aResolveHost(hostname)) == 0) + goto error; + // + ses->aio.udata = aioSesKeyGenHandshacked; + ses->cbAIOProcessorW = aioSesConnected; + if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) + goto error; + // + return 0; // ok, connection process initiated + error: + if (ses->fd >= 0) + sam3aDisconnect(ses->fd); + if (ses->params != NULL) + free(ses->params); + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioSesNameResChecker(Sam3ASession *ses) { + SAMFieldList *rep = sam3aParseReply(ses->aio.data); + // + if (rep == NULL) { + sesError(ses, NULL); + return; + } + if (sam3aIsGoodReply(rep, "NAMING", "REPLY", "RESULT", NULL)) { + const char *rs = sam3aFindField(rep, "RESULT"), + *pub = sam3aFindField(rep, "VALUE"); + // + if (strcmp(rs, "OK") == 0) { + if (pub != NULL && strlen(pub) == SAM3A_PUBKEY_SIZE) { + strcpy(ses->destkey, pub); + sam3aFreeFieldList(rep); + if (ses->cb.cbCreated != NULL) + ses->cb.cbCreated(ses); + sam3aCancelSession(ses); + return; + } + sam3aFreeFieldList(rep); + sesError(ses, NULL); + } else { + sesError(ses, rs); + sam3aFreeFieldList(rep); + } + } +} + +// handshake for SESSION CREATE complete +static void aioSesNameResHandshacked(Sam3ASession *ses) { + if (aioSesSendCmdWaitReply(ses, aioSesNameResChecker, + "NAMING LOOKUP NAME=%s\n", ses->params) < 0) { + sesError(ses, "MEMORY_ERROR"); + } +} + +int sam3aNameLookupEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, + const char *hostname, int port, const char *name, + int timeoutms) { + if (ses != NULL) { + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + if (cb != NULL) + ses->cb = *cb; + if (name == NULL || !name[0] || + (name[0] && toupper(name[0]) == 'M' && name[1] && + toupper(name[1]) == 'E' && (!name[2] || isspace(name[2])))) + goto error; + if (hostname == NULL || !hostname[0]) + hostname = "127.0.0.1"; + if (port < 0 || port > 65535) + goto error; + if ((ses->params = strdup(name)) == NULL) + goto error; + ses->timeoutms = timeoutms; + // + if (!port) + port = DEFAULT_TCP_PORT; + ses->port = port; + if ((ses->ip = sam3aResolveHost(hostname)) == 0) + goto error; + // + ses->aio.udata = aioSesNameResHandshacked; + ses->cbAIOProcessorW = aioSesConnected; + if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) + goto error; + // + return 0; // ok, connection process initiated + error: + if (ses->fd >= 0) + sam3aDisconnect(ses->fd); + if (ses->params != NULL) + free(ses->params); + memset(ses, 0, sizeof(Sam3ASession)); + ses->fd = -1; + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioConnCmdReplyReader(Sam3AConnection *conn) { + int res = aioLineReader(conn->fd, &conn->aio); + // + if (res < 0) { + connError(conn, "IO_ERROR"); + return; + } + if (res > 0) { + // we got full line + if (libsam3a_debug) + fprintf(stderr, "CMDREPLY: %s\n", conn->aio.data); + if (conn->aio.cbReplyCheckConn != NULL) + conn->aio.cbReplyCheckConn(conn); + } +} + +static void aioConnCmdSender(Sam3AConnection *conn) { + if (conn->aio.dataPos < conn->aio.dataUsed) { + if (aioSender(conn->fd, &conn->aio) < 0) { + connError(conn, "IO_ERROR"); + return; + } + } + // + if (conn->aio.dataPos == conn->aio.dataUsed) { + // hello sent, now wait for reply + // 2048 bytes of reply line should be enough + if (conn->aio.dataSize < 2049) { + char *n = realloc(conn->aio.data, 2049); + // + if (n == NULL) { + connError(conn, "MEMORY_ERROR"); + return; + } + conn->aio.data = n; + conn->aio.dataSize = 2049; + } + conn->aio.dataUsed = 2048; + conn->aio.dataPos = 0; + conn->cbAIOProcessorR = aioConnCmdReplyReader; + conn->cbAIOProcessorW = NULL; + } +} + +static __attribute__((format(printf, 3, 4))) int +aioConnSendCmdWaitReply(Sam3AConnection *conn, + void (*cbCheck)(Sam3AConnection *conn), const char *fmt, + ...) { + va_list ap; + char *str; + int len; + // + va_start(ap, fmt); + str = sam3PrintfVA(&len, fmt, ap); + va_end(ap); + // + if (str == NULL) + return -1; + if (conn->aio.data != NULL) + free(conn->aio.data); + conn->aio.data = str; + conn->aio.dataUsed = len; + conn->aio.dataSize = len + 1; + conn->aio.dataPos = 0; + conn->aio.cbReplyCheckConn = cbCheck; + conn->cbAIOProcessorR = NULL; + conn->cbAIOProcessorW = aioConnCmdSender; + // + if (libsam3a_debug) + fprintf(stderr, "CMD: %s", str); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioConnDataReader(Sam3AConnection *conn) { + char *buf = NULL; + int bufsz = 0; + // + while (sam3aIsActiveConnection(conn)) { + int av = sam3aBytesAvail(conn->fd), rd; + // + if (av < 0) { + if (buf != NULL) + free(buf); + connError(conn, "IO_ERROR"); + return; + } + if (av == 0) + av = 1; + if (bufsz < av) { + char *n = realloc(buf, av + 1); + // + if (n == NULL) { + if (buf != NULL) + free(buf); + connError(conn, "IO_ERROR"); + return; + } + buf = n; + bufsz = av; + } + memset(buf, 0, av + 1); + // + rd = recv(conn->fd, buf, av, 0); + // + if (rd < 0) { + if (errno == EINTR) + continue; // interrupted by signal + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; // no more data + free(buf); + connError(conn, "IO_ERROR"); + return; + } + // + if (rd == 0) { + // connection closed + free(buf); + connDisconnect(conn); + return; + } + // + if (conn->cb.cbRead != NULL) + conn->cb.cbRead(conn, buf, rd); + } + free(buf); +} + +static void aioConnDataWriter(Sam3AConnection *conn) { + if (!sam3aIsActiveConnection(conn)) { + conn->aio.dataPos = conn->aio.dataUsed = 0; + return; + } + // + if (conn->aio.dataPos >= conn->aio.dataUsed) { + conn->aio.dataPos = conn->aio.dataUsed = 0; + return; + } + // + while (sam3aIsActiveConnection(conn) && + conn->aio.dataPos < conn->aio.dataUsed) { + int wr = sam3aSendBytes(conn->fd, conn->aio.data + conn->aio.dataPos, + conn->aio.dataUsed - conn->aio.dataPos); + // + if (wr < 0) { + connError(conn, "IO_ERROR"); + return; + } + if (wr == 0) + break; // can't write more bytes + conn->aio.dataPos += wr; + if (conn->aio.dataPos < conn->aio.dataUsed) { + memmove(conn->aio.data, conn->aio.data + conn->aio.dataPos, + conn->aio.dataUsed - conn->aio.dataPos); + conn->aio.dataUsed -= conn->aio.dataPos; + conn->aio.dataPos = 0; + } + } + // + if (conn->aio.dataPos >= conn->aio.dataUsed) { + conn->aio.dataPos = conn->aio.dataUsed = 0; + if (conn->cb.cbSent != NULL) + conn->cb.cbSent(conn); + if (conn->aio.dataSize > 8192) { + // shrink buffer + char *nn = realloc(conn->aio.data, 8192); + // + if (nn != NULL) { + conn->aio.data = nn; + conn->aio.dataSize = 8192; + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioConnHelloChecker(Sam3AConnection *conn) { + SAMFieldList *rep = sam3aParseReply(conn->aio.data); + // + if (rep != NULL && sam3aIsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK") && + sam3aIsGoodReply(rep, NULL, NULL, "VERSION", "3.0")) { + conn->cbAIOProcessorR = conn->cbAIOProcessorW = NULL; + sam3aFreeFieldList(rep); + if (conn->aio.udata != NULL) { + void (*cbComplete)(Sam3AConnection * conn) = conn->aio.udata; + // + cbComplete(conn); + } + } else { + sam3aFreeFieldList(rep); + connError(conn, NULL); + } +} + +static int sam3aConnStartHandshake(Sam3AConnection *conn, + void (*cbComplete)(Sam3AConnection *conn)) { + if (cbComplete != NULL) + conn->aio.udata = cbComplete; + if (aioConnSendCmdWaitReply(conn, aioConnHelloChecker, "%s\n", + "HELLO VERSION MIN=3.0 MAX=3.0") < 0) + return -1; + return 0; +} + +static void aioConnConnected(Sam3AConnection *conn) { + int res; + socklen_t len = sizeof(res); + // + if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &res, &len) == 0 && res == 0) { + // ok, connected + if (sam3aConnStartHandshake(conn, NULL) < 0) + connError(conn, NULL); + } else { + // connection error + connError(conn, "CONNECTION_ERROR"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioConnConnectChecker(Sam3AConnection *conn) { + SAMFieldList *rep = sam3aParseReply(conn->aio.data); + // + if (rep == NULL) { + connError(conn, NULL); + return; + } + if (!sam3aIsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3aFindField(rep, "RESULT"); + // + connError(conn, v); + sam3aFreeFieldList(rep); + } else { + // no error + sam3aFreeFieldList(rep); + conn->callDisconnectCB = 1; + conn->cbAIOProcessorR = aioConnDataReader; + conn->cbAIOProcessorW = aioConnDataWriter; + conn->aio.dataPos = conn->aio.dataUsed = 0; + if (conn->cb.cbConnected != NULL) + conn->cb.cbConnected(conn); + // indicate that we are ready for new data + if (sam3aIsActiveConnection(conn) && conn->cb.cbSent != NULL) + conn->cb.cbSent(conn); + } +} + +// handshake for SESSION CREATE complete +static void aioConConnectHandshacked(Sam3AConnection *conn) { + if (aioConnSendCmdWaitReply(conn, aioConnConnectChecker, + "STREAM CONNECT ID=%s DESTINATION=%s\n", + conn->ses->channel, conn->destkey) < 0) { + connError(conn, "MEMORY_ERROR"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +Sam3AConnection *sam3aStreamConnectEx(Sam3ASession *ses, + const Sam3AConnectionCallbacks *cb, + const char *destkey, int timeoutms) { + if (sam3aIsActiveSession(ses) && ses->type == SAM3A_SESSION_STREAM && + destkey != NULL && strlen(destkey) == SAM3A_PUBKEY_SIZE) { + Sam3AConnection *conn = calloc(1, sizeof(Sam3AConnection)); + // + if (conn == NULL) + return NULL; + if (cb != NULL) + conn->cb = *cb; + strcpy(conn->destkey, destkey); + conn->timeoutms = timeoutms; + // + conn->aio.udata = aioConConnectHandshacked; + conn->cbAIOProcessorW = aioConnConnected; + if ((conn->fd = sam3aConnect(ses->ip, ses->port, NULL)) < 0) + goto error; + // + conn->ses = ses; + conn->next = ses->connlist; + ses->connlist = conn; + return conn; // ok, connection process initiated + error: + if (conn->fd >= 0) + sam3aDisconnect(conn->fd); + memset(conn, 0, sizeof(Sam3AConnection)); + free(conn); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +static void aioConnAcceptCheckerA(Sam3AConnection *conn) { + SAMFieldList *rep = sam3aParseReply(conn->aio.data); + // + if (rep != NULL || strlen(conn->aio.data) != SAM3A_PUBKEY_SIZE || + !sam3aIsValidPubKey(conn->aio.data)) { + sam3aFreeFieldList(rep); + connError(conn, NULL); + return; + } + sam3aFreeFieldList(rep); + strcpy(conn->destkey, conn->aio.data); + conn->callDisconnectCB = 1; + conn->cbAIOProcessorR = aioConnDataReader; + conn->cbAIOProcessorW = aioConnDataWriter; + conn->aio.dataPos = conn->aio.dataUsed = 0; + if (conn->cb.cbAccepted != NULL) + conn->cb.cbAccepted(conn); + // indicate that we are ready for new data + if (sam3aIsActiveConnection(conn) && conn->cb.cbSent != NULL) + conn->cb.cbSent(conn); +} + +static void aioConnAcceptChecker(Sam3AConnection *conn) { + SAMFieldList *rep = sam3aParseReply(conn->aio.data); + // + if (rep == NULL) { + connError(conn, NULL); + return; + } + if (!sam3aIsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3aFindField(rep, "RESULT"); + // + connError(conn, v); + sam3aFreeFieldList(rep); + } else { + // no error + sam3aFreeFieldList(rep); + // 2048 bytes of reply line should be enough + if (conn->aio.dataSize < 2049) { + char *n = realloc(conn->aio.data, 2049); + // + if (n == NULL) { + connError(conn, "MEMORY_ERROR"); + return; + } + conn->aio.data = n; + conn->aio.dataSize = 2049; + } + conn->aio.dataUsed = 2048; + conn->aio.dataPos = 0; + conn->cbAIOProcessorR = aioConnCmdReplyReader; + conn->cbAIOProcessorW = NULL; + conn->aio.cbReplyCheckConn = aioConnAcceptCheckerA; + } +} + +// handshake for SESSION CREATE complete +static void aioConAcceptHandshacked(Sam3AConnection *conn) { + if (aioConnSendCmdWaitReply(conn, aioConnAcceptChecker, + "STREAM ACCEPT ID=%s\n", + conn->ses->channel) < 0) { + connError(conn, "MEMORY_ERROR"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +Sam3AConnection *sam3aStreamAcceptEx(Sam3ASession *ses, + const Sam3AConnectionCallbacks *cb, + int timeoutms) { + if (sam3aIsActiveSession(ses) && ses->type == SAM3A_SESSION_STREAM) { + Sam3AConnection *conn = calloc(1, sizeof(Sam3AConnection)); + // + if (conn == NULL) + return NULL; + if (cb != NULL) + conn->cb = *cb; + conn->timeoutms = timeoutms; + // + conn->aio.udata = aioConAcceptHandshacked; + conn->cbAIOProcessorW = aioConnConnected; + if ((conn->fd = sam3aConnect(ses->ip, ses->port, NULL)) < 0) + goto error; + // + conn->ses = ses; + conn->next = ses->connlist; + ses->connlist = conn; + return conn; // ok, connection process initiated + error: + if (conn->fd >= 0) + sam3aDisconnect(conn->fd); + memset(conn, 0, sizeof(Sam3AConnection)); + free(conn); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aSend(Sam3AConnection *conn, const void *data, int datasize) { + if (datasize == -1) + datasize = (data != NULL ? strlen((const char *)data) : 0); + // + if (sam3aIsActiveConnection(conn) && conn->callDisconnectCB && + conn->cbAIOProcessorW != NULL && + ((datasize > 0 && data != NULL) || datasize == 0)) { + // try to add data to send buffer + if (datasize > 0) { + if (conn->aio.dataUsed + datasize > conn->aio.dataSize) { + // we need more pepper! + int newsz = conn->aio.dataUsed + datasize; + char *nb = realloc(conn->aio.data, newsz); + // + if (nb == NULL) + return -1; // alas + conn->aio.data = nb; + conn->aio.dataSize = newsz; + } + // + memcpy(conn->aio.data + conn->aio.dataUsed, data, datasize); + conn->aio.dataUsed += datasize; + } + return 0; + } + // + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aIsHaveActiveConnections(const Sam3ASession *ses) { + if (sam3aIsActiveSession(ses)) { + for (const Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { + if (sam3aIsActiveConnection(c)) + return 1; + } + } + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aCancelConnection(Sam3AConnection *conn) { + if (conn != NULL) { + connDisconnect(conn); + return 0; + } + return -1; +} + +int sam3aCloseConnection(Sam3AConnection *conn) { + if (conn != NULL) { + sam3aCancelConnection(conn); + if (conn->cb.cbDestroy != NULL) + conn->cb.cbDestroy(conn); + for (Sam3AConnection *p = NULL, *c = conn->ses->connlist; c != NULL; + p = c, c = c->next) { + if (c == conn) { + // got it! + if (p == NULL) + c->ses->connlist = c->next; + else + p->next = c->next; + break; + } + } + if (conn->params != NULL) { + free(conn->params); + conn->params = NULL; + } + memset(conn, 0, sizeof(Sam3AConnection)); + free(conn); + } + return -1; +} + +//////////////////////////////////////////////////////////////////////////////// +int sam3aAddSessionToFDS(Sam3ASession *ses, int maxfd, fd_set *rds, + fd_set *wrs) { + if (ses != NULL) { + if (sam3aIsActiveSession(ses)) { + if (rds != NULL && ses->cbAIOProcessorR != NULL) { + if (maxfd < ses->fd) + maxfd = ses->fd; + FD_SET(ses->fd, rds); + } + // + if (wrs != NULL && ses->cbAIOProcessorW != NULL) { + if (maxfd < ses->fd) + maxfd = ses->fd; + FD_SET(ses->fd, wrs); + } + // + for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { + if (sam3aIsActiveConnection(c)) { + if (rds != NULL && c->cbAIOProcessorR != NULL) { + if (maxfd < c->fd) + maxfd = c->fd; + FD_SET(c->fd, rds); + } + // + if (wrs != NULL && c->cbAIOProcessorW != NULL) { + if (!c->callDisconnectCB || (c->aio.dataPos < c->aio.dataUsed)) + if (maxfd < c->fd) + maxfd = c->fd; + FD_SET(c->fd, wrs); + } + } + } + } + return maxfd; + } + // + return -1; +} + +void sam3aProcessSessionIO(Sam3ASession *ses, fd_set *rds, fd_set *wrs) { + if (sam3aIsActiveSession(ses)) { + if (ses->fd >= 0 && !ses->cancelled && ses->cbAIOProcessorR != NULL && + rds != NULL && FD_ISSET(ses->fd, rds)) + ses->cbAIOProcessorR(ses); + if (ses->fd >= 0 && !ses->cancelled && ses->cbAIOProcessorW != NULL && + wrs != NULL && FD_ISSET(ses->fd, wrs)) + ses->cbAIOProcessorW(ses); + // + for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { + if (c->fd >= 0 && !c->cancelled && c->cbAIOProcessorR != NULL && + rds != NULL && FD_ISSET(c->fd, rds)) + c->cbAIOProcessorR(c); + if (c->fd >= 0 && !c->cancelled && c->cbAIOProcessorW != NULL && + wrs != NULL && FD_ISSET(c->fd, wrs)) + c->cbAIOProcessorW(c); + } + } +} diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.h b/supportlibs/libsam3/src/libsam3a/libsam3a.h new file mode 100644 index 000000000..4ddec7952 --- /dev/null +++ b/supportlibs/libsam3/src/libsam3a/libsam3a.h @@ -0,0 +1,361 @@ +/* async SAMv3 library + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#ifndef LIBSAM3A_H +#define LIBSAM3A_H + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////// +/* + * TODO: + * [.] block sam3aClose*() in callbacks + */ + +//////////////////////////////////////////////////////////////////////////////// +extern int libsam3a_debug; + +//////////////////////////////////////////////////////////////////////////////// +#define SAM3A_HOST_DEFAULT (NULL) +#define SAM3A_PORT_DEFAULT (0) + +#define SAM3A_DESTINATION_TRANSIENT (NULL) + +#define SAM3A_PUBKEY_SIZE (516) +#define SAM3A_PRIVKEY_SIZE (884) + +//////////////////////////////////////////////////////////////////////////////// +extern uint64_t sam3atimeval2ms(const struct timeval *tv); +extern void sam3ams2timeval(struct timeval *tv, uint64_t ms); + +//////////////////////////////////////////////////////////////////////////////// +extern int sam3aIsValidPubKey(const char *key); +extern int sam3aIsValidPrivKey(const char *key); + +//////////////////////////////////////////////////////////////////////////////// +typedef struct Sam3ASession Sam3ASession; +typedef struct Sam3AConnection Sam3AConnection; + +typedef enum { + SAM3A_SESSION_RAW, + SAM3A_SESSION_DGRAM, + SAM3A_SESSION_STREAM +} Sam3ASessionType; + +typedef struct { + char *data; + int dataSize; + int dataUsed; + int dataPos; + void *udata; + union { + void (*cbReplyCheckSes)(Sam3ASession *ses); + void (*cbReplyCheckConn)(Sam3AConnection *conn); + }; +} Sam3AIO; + +/** session callback functions */ +typedef struct { + void (*cbError)(Sam3ASession *ses); /** called on error */ + void (*cbCreated)( + Sam3ASession *ses); /** called when we created the session */ + void (*cbDisconnected)(Sam3ASession *ses); /* call when closed; will called + only after cbCreated() */ + void (*cbDatagramRead)(Sam3ASession *ses, const void *buf, + int bufsize); /* called when we got a datagram; bufsize + >= 0; destkey set */ + void (*cbDestroy)(Sam3ASession *ses); /* called when fd is already closed, but + keys is not cleared */ +} Sam3ASessionCallbacks; + +struct Sam3ASession { + Sam3ASessionType type; /** session type */ + int fd; /** socket file descriptor */ + int cancelled; /** fd was shutdown()ed, but not closed yet */ + char privkey[SAM3A_PRIVKEY_SIZE + 1]; /** private key (asciiz) */ + char pubkey[SAM3A_PUBKEY_SIZE + 1]; /** public key (asciiz) */ + char channel[66]; /** channel name (asciiz) */ + char destkey[SAM3A_PUBKEY_SIZE + 1]; /** for DGRAM sessions (asciiz) */ + char error[64]; /** error message (asciiz) */ + uint32_t ip; /** ipv4 address of sam api interface */ + int port; /** UDP port for DRAM/RAW (can be 0) */ + Sam3AConnection *connlist; /** list of opened connections */ + + /** begin internal members */ + // for async i/o + Sam3AIO aio; + void (*cbAIOProcessorR)(Sam3ASession *ses); // internal + void (*cbAIOProcessorW)(Sam3ASession *ses); // internal + int callDisconnectCB; + char *params; // will be cleared only by sam3aCloseSession() + int timeoutms; + + /** end internal members */ + + Sam3ASessionCallbacks cb; + void *udata; +}; + +/** connection callbacks for data sockets */ +typedef struct { + /** called on error */ + void (*cbError)(Sam3AConnection *ct); + /** called when closed or only after cbConnected()/cbAccepted(); note that + * force disconnect is ok */ + void (*cbDisconnected)(Sam3AConnection *ct); + /** called when connected */ + void (*cbConnected)(Sam3AConnection *ct); + /** called instead of cbConnected() for sam3aStreamAccept*(), destkey filled + * with remote destination */ + void (*cbAccepted)(Sam3AConnection *ct); + /** send callback, data sent, can add new data; will be called after + * connect/accept */ + void (*cbSent)(Sam3AConnection *ct); + /** read callback, data read from socket (bufsize is always > 0) */ + void (*cbRead)(Sam3AConnection *ct, const void *buf, int bufsize); + /** fd already closed, but keys is not cleared */ + void (*cbDestroy)(Sam3AConnection *ct); +} Sam3AConnectionCallbacks; + +struct Sam3AConnection { + /** parent session */ + Sam3ASession *ses; + Sam3AConnection *next; + /** file descriptor */ + int fd; + int cancelled; // fd was shutdown()ed, but not closed yet + char destkey[SAM3A_PUBKEY_SIZE + 1]; // (asciiz) + char error[32]; // (asciiz) + + /** begin internal members */ + // for async i/o + Sam3AIO aio; + void (*cbAIOProcessorR)(Sam3AConnection *ct); // internal + void (*cbAIOProcessorW)(Sam3AConnection *ct); // internal + int callDisconnectCB; + char *params; // will be cleared only by sam3aCloseConnection() + int timeoutms; + /** end internal members */ + + /** callbacks */ + Sam3AConnectionCallbacks cb; + /** user data */ + void *udata; +}; + +//////////////////////////////////////////////////////////////////////////////// +/* + * check if session is active (i.e. have opened socket) + * returns bool + */ +extern int sam3aIsActiveSession(const Sam3ASession *ses); + +/* + * check if connection is active (i.e. have opened socket) + * returns bool + */ +extern int sam3aIsActiveConnection(const Sam3AConnection *conn); + +//////////////////////////////////////////////////////////////////////////////// +/* + * note, that return error codes indicates invalid structure, pointer or fd + * (i.e. immediate errors); all network errors indicated with cbError() callback + */ + +/* + * create SAM session + * pass NULL as hostname for 'localhost' and 0 as port for 7656 + * pass NULL as privkey to create TRANSIENT session + * 'params' can be NULL + * see http://www.i2p2.i2p/i2cp.html#options for common options, + * and http://www.i2p2.i2p/streaming.html#options for STREAM options + * if result<0: error, 'ses' fields are undefined, no need to call + * sam3aCloseSession() if result==0: ok, all 'ses' fields are filled + * TODO: don't clear 'error' field on error (and set it to something meaningful) + */ +extern int sam3aCreateSessionEx(Sam3ASession *ses, + const Sam3ASessionCallbacks *cb, + const char *hostname, int port, + const char *privkey, Sam3ASessionType type, + const char *params, int timeoutms); + +static inline int sam3aCreateSession(Sam3ASession *ses, + const Sam3ASessionCallbacks *cb, + const char *hostname, int port, + const char *privkey, + Sam3ASessionType type) { + return sam3aCreateSessionEx(ses, cb, hostname, port, privkey, type, NULL, -1); +} + +/* returns <0 on error, 0 if no, >0 if yes */ +extern int sam3aIsHaveActiveConnections(const Sam3ASession *ses); + +/* + * close SAM session (and all it's connections) + * returns <0 on error, 0 on ok + * 'ses' must be properly initialized + */ +extern int sam3aCloseSession(Sam3ASession *ses); + +/* + * cancel SAM session (and all it's connections), but don't free() or clear + * anything except fds returns <0 on error, 0 on ok 'ses' must be properly + * initialized + */ +extern int sam3aCancelSession(Sam3ASession *ses); + +/* + * open stream connection to 'destkey' endpoint + * 'destkey' is 516-byte public key (asciiz) + * returns <0 on error + * sets ses->error on memory or socket creation error + */ +extern Sam3AConnection *sam3aStreamConnectEx(Sam3ASession *ses, + const Sam3AConnectionCallbacks *cb, + const char *destkey, + int timeoutms); + +static inline Sam3AConnection * +sam3aStreamConnect(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb, + const char *destkey) { + return sam3aStreamConnectEx(ses, cb, destkey, -1); +} + +/* + * accepts stream connection and sets 'destkey' + * 'destkey' is 516-byte public key + * returns <0 on error, fd on ok + * you still have to call sam3aCloseSession() on failure + * sets ses->error on error + * note that there is no timeouts for now, but you can use sam3atcpSetTimeout*() + */ +extern Sam3AConnection *sam3aStreamAcceptEx(Sam3ASession *ses, + const Sam3AConnectionCallbacks *cb, + int timeoutms); + +static inline Sam3AConnection * +sam3aStreamAccept(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb) { + return sam3aStreamAcceptEx(ses, cb, -1); +} + +/* + * close SAM connection, remove it from session and free memory + * returns <0 on error, 0 on ok + * 'conn' must be properly initialized + * 'conn' is invalid after call + */ +extern int sam3aCloseConnection(Sam3AConnection *conn); + +/* + * cancel SAM connection, but don't free() or clear anything except fd + * returns <0 on error, 0 on ok + * 'conn' must be properly initialized + * 'conn' is invalid after call + */ +extern int sam3aCancelConnection(Sam3AConnection *conn); + +//////////////////////////////////////////////////////////////////////////////// +/* + * send data + * this function can be used in cbSent() callback + * + * return: <0: error; 0: ok + */ +extern int sam3aSend(Sam3AConnection *conn, const void *data, int datasize); + +/* + * sends datagram to 'destkey' endpoint + * 'destkey' is 516-byte public key + * returns <0 on error, 0 on ok + * you still have to call sam3aCloseSession() on failure + * sets ses->error on error + * don't send datagrams bigger than 31KB! + */ +extern int sam3aDatagramSend(Sam3ASession *ses, const char *destkey, + const void *buf, int bufsize); + +//////////////////////////////////////////////////////////////////////////////// +/* + * generate random channel name + * dest should be at least (maxlen+1) bytes big + */ +extern int sam3aGenChannelName(char *dest, int minlen, int maxlen); + +//////////////////////////////////////////////////////////////////////////////// +/* + * generate new keypair + * fills 'privkey' and 'pubkey' only + * you should call sam3aCloseSession() on 'ses' + * cbCreated callback will be called when keys generated + * returns <0 on error, 0 on ok + */ +extern int sam3aGenerateKeysEx(Sam3ASession *ses, + const Sam3ASessionCallbacks *cb, + const char *hostname, int port, int timeoutms); + +static inline int sam3aGenerateKeys(Sam3ASession *ses, + const Sam3ASessionCallbacks *cb, + const char *hostname, int port) { + return sam3aGenerateKeysEx(ses, cb, hostname, port, -1); +} + +/* + * do name lookup (something like gethostbyname()) + * fills 'destkey' only + * you should call sam3aCloseSession() on 'ses' + * cbCreated callback will be called when keys generated, ses->destkey will be + * set returns <0 on error, 0 on ok + */ +extern int sam3aNameLookupEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, + const char *hostname, int port, const char *name, + int timeoutms); + +static inline int sam3aNameLookup(Sam3ASession *ses, + const Sam3ASessionCallbacks *cb, + const char *hostname, int port, + const char *name) { + return sam3aNameLookupEx(ses, cb, hostname, port, name, -1); +} + +//////////////////////////////////////////////////////////////////////////////// +/* + * append session fd to read and write sets if necessary + * adds all alive session connections too + * returns maxfd or -1 + * TODO: should keep fd count so it will not exceed FD_SETSIZE! + */ +extern int sam3aAddSessionToFDS(Sam3ASession *ses, int maxfd, fd_set *rds, + fd_set *wrs); + +/* + * process session i/o (and all session connections i/o) + * should be called after successful select() + */ +extern void sam3aProcessSessionIO(Sam3ASession *ses, fd_set *rds, fd_set *wrs); + +//////////////////////////////////////////////////////////////////////////////// +/* return malloc()ed buffer and len in 'plen' (if plen != NULL) */ +extern char *sam3PrintfVA(int *plen, const char *fmt, va_list app); +extern char *sam3Printf(int *plen, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/supportlibs/libsam3/test/libsam3/test_b32.c b/supportlibs/libsam3/test/libsam3/test_b32.c new file mode 100644 index 000000000..9a852853d --- /dev/null +++ b/supportlibs/libsam3/test/libsam3/test_b32.c @@ -0,0 +1,51 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include + +#include "../../src/ext/tinytest.h" +#include "../../src/ext/tinytest_macros.h" +#include "../../src/libsam3/libsam3.h" + +static int testb32(const char *src, const char *res) { + size_t dlen = sam3Base32EncodedLength(strlen(src)), len; + char dest[128]; + // + len = sam3Base32Encode(dest, sizeof(dest), src, strlen(src)); + tt_int_op(len, ==, dlen); + tt_int_op(len, ==, strlen(res)); + tt_str_op(res, ==, dest); + return 1; + +end: + return 0; +} + +void test_b32_encode(void *data) { + (void)data; /* This testcase takes no data. */ + + tt_assert(testb32("", "")); + tt_assert(testb32("f", "my======")); + tt_assert(testb32("fo", "mzxq====")); + tt_assert(testb32("foo", "mzxw6===")); + tt_assert(testb32("foob", "mzxw6yq=")); + tt_assert(testb32("fooba", "mzxw6ytb")); + tt_assert(testb32("foobar", "mzxw6ytboi======")); + +end:; +} + +struct testcase_t b32_tests[] = {{ + "encode", + test_b32_encode, + }, + END_OF_TESTCASES}; diff --git a/supportlibs/libsam3/test/test.c b/supportlibs/libsam3/test/test.c new file mode 100644 index 000000000..9e7357962 --- /dev/null +++ b/supportlibs/libsam3/test/test.c @@ -0,0 +1,12 @@ +#include + +#include "../src/ext/tinytest.h" +#include "../src/ext/tinytest_macros.h" + +extern struct testcase_t b32_tests[]; + +struct testgroup_t test_groups[] = {{"b32/", b32_tests}, END_OF_GROUPS}; + +int main(int argc, const char **argv) { + return tinytest_main(argc, argv, test_groups); +} From 42bc295d1a3cdd8f568ca01369cca32c34d96000 Mon Sep 17 00:00:00 2001 From: sehraf Date: Tue, 15 Dec 2020 21:42:48 +0100 Subject: [PATCH 053/697] add i2psam3 --- .../src/gui/settings/ServerPage.cpp | 408 +++++++++++------- retroshare-gui/src/gui/settings/ServerPage.h | 30 +- 2 files changed, 266 insertions(+), 172 deletions(-) diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index e17fc9919..62928f701 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -47,6 +47,8 @@ #include #include +#include + #define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" #define ICON_STATUS_WORKING ":/images/yellowled.png" #define ICON_STATUS_OK ":/images/ledon1.png" @@ -66,7 +68,7 @@ // Tabs numbers *after* non relevant tabs are removed. So do not use them to add/remove tabs!! const static uint32_t TAB_HIDDEN_SERVICE_OUTGOING = 0; const static uint32_t TAB_HIDDEN_SERVICE_INCOMING = 1; -const static uint32_t TAB_HIDDEN_SERVICE_I2P_BOB = 2; +const static uint32_t TAB_HIDDEN_SERVICE_I2P = 2; const static uint32_t TAB_NETWORK = 0; const static uint32_t TAB_HIDDEN_SERVICE = 1; @@ -79,14 +81,14 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) , manager(NULL), mOngoingConnectivityCheck(-1) , mIsHiddenNode(false), mHiddenType(RS_HIDDEN_TYPE_NONE) - , mBobAccessible(false) + , mSamAccessible(false) , mEventHandlerId(0) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); #ifndef RS_USE_I2P_BOB - ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P_BOB); // warning: the order of operation here is very important. + ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P); // warning: the order of operation here is very important. #endif if(RsAccounts::isHiddenNode()) @@ -166,14 +168,14 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.filteredIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedBlackListIP(int,int,int,int))); QObject::connect(ui.whiteListIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedWhiteListIP(int,int,int,int))); - QObject::connect(ui.pbBobStart, SIGNAL(clicked()), this, SLOT(startBOB())); - QObject::connect(ui.pbBobRestart, SIGNAL(clicked()), this, SLOT(restartBOB())); - QObject::connect(ui.pbBobStop, SIGNAL(clicked()), this, SLOT(stopBOB())); + QObject::connect(ui.pbBobStart, SIGNAL(clicked()), this, SLOT(startSam())); + QObject::connect(ui.pbBobRestart, SIGNAL(clicked()), this, SLOT(restartSam())); + QObject::connect(ui.pbBobStop, SIGNAL(clicked()), this, SLOT(stopSam())); QObject::connect(ui.pbBobGenAddr, SIGNAL(clicked()), this, SLOT(getNewKey())); QObject::connect(ui.pbBobLoadKey, SIGNAL(clicked()), this, SLOT(loadKey())); - QObject::connect(ui.cb_enableBob, SIGNAL(toggled(bool)), this, SLOT(enableBob(bool))); + QObject::connect(ui.cb_enableBob, SIGNAL(toggled(bool)), this, SLOT(enableSam(bool))); - QObject::connect(ui.cbBobAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleBobAdvancedSettings(bool))); + QObject::connect(ui.cbBobAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleSamAdvancedSettings(bool))); QObject::connect(ui.sbBobLengthIn, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); QObject::connect(ui.sbBobLengthOut, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); @@ -184,11 +186,11 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) // These two spin boxes are used for the same thing - keep them in sync! QObject::connect(ui.hiddenpage_proxyPort_i2p, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortNormal(int))); - QObject::connect(ui.hiddenpage_proxyPort_i2p_2, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortBob(int))); + QObject::connect(ui.hiddenpage_proxyPort_i2p_2, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortSam(int))); // These two line edits are used for the same thing - keep them in sync! QObject::connect(ui.hiddenpage_proxyAddress_i2p, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrNormal(QString))); - QObject::connect(ui.hiddenpage_proxyAddress_i2p_2, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrBob(QString))); + QObject::connect(ui.hiddenpage_proxyAddress_i2p_2, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrSam(QString))); connect(NotifyQt::getInstance(), SIGNAL(connectionWithoutCert()), this, SLOT(connectionWithoutCert())); @@ -373,7 +375,7 @@ void ServerPage::load() } mIsHiddenNode = (detail.netMode == RS_NETMODE_HIDDEN); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, &mSamSettings); loadCommon(); updateStatus(); @@ -870,9 +872,9 @@ void ServerPage::updateStatus() loadFilteredIps() ; - updateStatusBob(); + updateStatusSam(); - // this is used by BOB + // this is used by SAM if (mOngoingConnectivityCheck > 0) { mOngoingConnectivityCheck--; @@ -1349,32 +1351,33 @@ void ServerPage::updateOutProxyIndicator() ui.iconlabel_tor_outgoing->setToolTip(tr("Tor proxy is not enabled")) ; } - // I2P - socket.connectToHost(ui.hiddenpage_proxyAddress_i2p->text(),ui.hiddenpage_proxyPort_i2p->text().toInt()); - if(socket.waitForConnected(500)) - { - socket.disconnectFromHost(); - ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; - ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; - } - else - { - ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; - } + // I2P - SAM + // Note: there is only "the SAM port", there is no additional proxy port! + samStatus ss; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::status, &ss); + if(ss.state == samStatus::samState::online) + { + socket.disconnectFromHost(); + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; + } + else + { + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; + } - // I2P - BOB - socket.connectToHost(ui.hiddenpage_proxyAddress_i2p_2->text(), 2827); - if(true == (mBobAccessible = socket.waitForConnected(500))) + socket.connectToHost(ui.hiddenpage_proxyAddress_i2p_2->text(), 7656); + if(true == (mSamAccessible = socket.waitForConnected(1000))) { socket.disconnectFromHost(); ui.iconlabel_i2p_outgoing_2->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; - ui.iconlabel_i2p_outgoing_2->setToolTip(tr("BOB is running and accessible")) ; + ui.iconlabel_i2p_outgoing_2->setToolTip(tr("SAMv3 is running and accessible")) ; } else { ui.iconlabel_i2p_outgoing_2->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_i2p_outgoing_2->setToolTip(tr("BOB is not accessible! Is it running?")) ; + ui.iconlabel_i2p_outgoing_2->setToolTip(tr("SAMv3 is not accessible! Is i2p running and SAM enabled?")) ; } } @@ -1385,28 +1388,18 @@ void ServerPage::updateInProxyIndicator() if(!mIsHiddenNode) return ; - //ui.iconlabel_tor_incoming->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + //ui.iconlabel_tor_incoming->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; //ui.testIncomingTor_PB->setIcon(FilesDefs::getIconFromQtResourcePath(":/loader/circleball-16.gif")) ; QMovie *movie = new QMovie(":/images/loader/circleball-16.gif"); ui.iconlabel_service_incoming->setMovie(movie); movie->start(); - if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enable) { - - QTcpSocket tcpSocket; - - const QString host = ui.hiddenpage_proxyAddress_i2p->text(); - qint16 port = ui.hiddenpage_proxyPort_i2p->text().toInt(); - QByteArray addr = ui.leBobB32Addr->text().toUtf8(); - addr.push_back('\n'); - - mOngoingConnectivityCheck = 5; // timeout in sec - - tcpSocket.connectToHost(host, port); - tcpSocket.write(addr); // write addr - tcpSocket.write(addr); // trigger connection error since RS expects a tls connection - tcpSocket.close(); - tcpSocket.waitForDisconnected(5 * 1000); + if (mHiddenType == RS_HIDDEN_TYPE_I2P && mSamSettings.enable) { + // there is no inproxy for SAMv3, since every connection goes through sam itself + auto secw = new samEstablishConnectionWrapper(); + secw->address = mSamSettings.address; + secw->connection = nullptr; + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::establishConnection, this, secw); return; } @@ -1419,18 +1412,10 @@ void ServerPage::updateInProxyIndicator() QNetworkProxy proxy ; proxy.setType(QNetworkProxy::Socks5Proxy); - switch (mHiddenType) { - case RS_HIDDEN_TYPE_I2P: - proxy.setHostName(ui.hiddenpage_proxyAddress_i2p->text()); - proxy.setPort(ui.hiddenpage_proxyPort_i2p->text().toInt()); - break; - case RS_HIDDEN_TYPE_TOR: - proxy.setHostName(ui.hiddenpage_proxyAddress_tor->text()); - proxy.setPort(ui.hiddenpage_proxyPort_tor->text().toInt()); - break; - default: - return; - } + + proxy.setHostName(ui.hiddenpage_proxyAddress_tor->text()); + proxy.setPort(ui.hiddenpage_proxyPort_tor->text().toInt()); + proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability | proxy.capabilities()) ; QNetworkProxy::setApplicationProxy(proxy) ; @@ -1445,53 +1430,60 @@ void ServerPage::updateInProxyIndicator() QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy) ; } -void ServerPage::startBOB() +void ServerPage::startSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::start); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::start); updateStatus(); } -void ServerPage::restartBOB() +void ServerPage::restartSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::stop); - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::start); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::stop); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::start); updateStatus(); } -void ServerPage::stopBOB() +void ServerPage::stopSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::stop); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::stop); updateStatus(); } void ServerPage::getNewKey() { - bobSettings *bs = new bobSettings(); - - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::receiveKey, this, bs); + i2p::address *addr = new i2p::address(); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::receiveKey, this, addr); updateStatus(); } void ServerPage::loadKey() { - mBobSettings.address.privateKey = ui.pteBobServerKey->toPlainText().toStdString(); - mBobSettings.address.publicKey = i2p::publicKeyFromPrivate(mBobSettings.address.privateKey); - mBobSettings.address.base32 = i2p::keyToBase32Addr(mBobSettings.address.publicKey); + auto priv = ui.pteBobServerKey->toPlainText().toStdString(); + auto pub = i2p::publicKeyFromPrivate(priv); + if (pub.empty()) { + // something went wrong! + ui.pteBobServerKey->setPlainText("FAILED! Something went wrong while parsing the key!"); + return; + } - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + mSamSettings.address.privateKey = priv; + mSamSettings.address.publicKey = pub; + mSamSettings.address.base32 = i2p::keyToBase32Addr(mSamSettings.address.publicKey); + + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); } -void ServerPage::enableBob(bool checked) +void ServerPage::enableSam(bool checked) { - mBobSettings.enable = checked; + mSamSettings.enable = checked; - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); - setUpBobElements(); + setUpSamElements(); } int8_t fitRange(int i, int min, int max) { @@ -1513,21 +1505,21 @@ void ServerPage::tunnelSettingsChanged(int) vi = ui.sbBobVarianceIn->value(); vo = ui.sbBobVarianceOut->value(); - mBobSettings.inLength = fitRange(li, 0, 7); - mBobSettings.outLength = fitRange(lo, 0, 7); - mBobSettings.inQuantity = fitRange(qi, 1, 16); - mBobSettings.outQuantity = fitRange(qo, 1, 16); - mBobSettings.inVariance = fitRange(vi, -1, 2); - mBobSettings.outVariance = fitRange(vo, -1, 2); + mSamSettings.inLength = fitRange(li, 0, 7); + mSamSettings.outLength = fitRange(lo, 0, 7); + mSamSettings.inQuantity = fitRange(qi, 1, 16); + mSamSettings.outQuantity = fitRange(qo, 1, 16); + mSamSettings.inVariance = fitRange(vi, -1, 2); + mSamSettings.outVariance = fitRange(vo, -1, 2); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); } -void ServerPage::toggleBobAdvancedSettings(bool checked) +void ServerPage::toggleSamAdvancedSettings(bool checked) { ui.swBobAdvanced->setCurrentIndex(checked ? 1 : 0); - if (!mBobSettings.address.privateKey.empty()) { + if (!mSamSettings.address.privateKey.empty()) { if (checked) { ui.pbBobGenAddr->show(); } else { @@ -1541,13 +1533,13 @@ void ServerPage::syncI2PProxyPortNormal(int i) ui.hiddenpage_proxyPort_i2p_2->setValue(i); } -void ServerPage::syncI2PProxyPortBob(int i) +void ServerPage::syncI2PProxyPortSam(int i) { ui.hiddenpage_proxyPort_i2p->setValue(i); - // update port - saveBob(); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::reloadConfig); + // update port, not necessary for same, we just want to keep it consistent + saveSam(); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::reloadConfig); } void ServerPage::syncI2PProxyAddrNormal(QString t) @@ -1555,38 +1547,70 @@ void ServerPage::syncI2PProxyAddrNormal(QString t) ui.hiddenpage_proxyAddress_i2p_2->setText(t); } -void ServerPage::syncI2PProxyAddrBob(QString t) +void ServerPage::syncI2PProxyAddrSam(QString t) { ui.hiddenpage_proxyAddress_i2p->setText(t); // update addr - saveBob(); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::reloadConfig); + saveSam(); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::reloadConfig); } void ServerPage::taskFinished(taskTicket *&ticket) { - if (ticket->task == autoProxyTask::receiveKey) { - bobSettings *s = NULL; - switch (ticket->types.front()) { - case autoProxyType::I2PBOB: - // update settings - s = (struct bobSettings *)ticket->data; - mBobSettings = *s; - delete s; - s = NULL; - ticket->data = NULL; - break; - default: - break; - } - } + switch (ticket->task) { + case autoProxyTask::receiveKey: + { + i2p::address *addr = nullptr; + addr = static_cast(ticket->data); + + if (ticket->types.front() != autoProxyType::I2PSAM3) + RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); + else { + // update settings + mSamSettings.address = *addr; + } + + delete addr; + addr = nullptr; + ticket->data = nullptr; + + updateStatusSam(); + break; + } + case autoProxyTask::establishConnection: + { + samEstablishConnectionWrapper *secw = nullptr; + secw = static_cast(ticket->data); + + if (ticket->types.front() != autoProxyType::I2PSAM3) + RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); + else { + // update settings + if (secw->connection->ses) { + updateInProxyIndicatorResult(true); + sam3CloseConnection(secw->connection); + secw->connection = nullptr; // freed by above call + } else + updateInProxyIndicatorResult(false); + } + + if (secw->connection) + delete secw->connection; + delete secw; + secw = nullptr; + ticket->data = nullptr; + break; + } + default: + RS_DBG("unsupported task!", ticket->task); + } if (ticket->data) std::cerr << "(WW) ServerPage::taskFinished data set. This should NOT happen - check the code!" << std::endl; delete ticket; - ticket = NULL; + ticket = nullptr; } void ServerPage::connectionWithoutCert() @@ -1613,14 +1637,14 @@ void ServerPage::loadCommon() // I2P rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, proxyaddr, proxyport, status); whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr)); - whileBlocking(ui.hiddenpage_proxyAddress_i2p_2)->setText(QString::fromStdString(proxyaddr)); // this one is for bob tab + whileBlocking(ui.hiddenpage_proxyAddress_i2p_2)->setText(QString::fromStdString(proxyaddr)); // this one is for sam tab whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); - whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab + whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for sam tab // don't use whileBlocking here - ui.cb_enableBob->setChecked(mBobSettings.enable); + ui.cb_enableBob->setChecked(mSamSettings.enable); - if (!mBobSettings.address.privateKey.empty()) { + if (!mSamSettings.address.privateKey.empty()) { ui.lBobB32Addr->show(); ui.leBobB32Addr->show(); } @@ -1642,10 +1666,10 @@ void ServerPage::saveCommon() rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, new_proxyaddr, new_proxyport); } - saveBob(); + saveSam(); } -void ServerPage::saveBob() +void ServerPage::saveSam() { std::string orig_proxyaddr, new_proxyaddr; uint16_t orig_proxyport, new_proxyport; @@ -1656,20 +1680,29 @@ void ServerPage::saveBob() new_proxyaddr = ui.hiddenpage_proxyAddress_i2p -> text().toStdString(); new_proxyport = ui.hiddenpage_proxyPort_i2p -> value(); - if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) { + // SAMv3 has no proxy port, everything goes through the SAM port. + if ((new_proxyaddr != orig_proxyaddr) /* || (new_proxyport != orig_proxyport) */) { rsPeers->setProxyServer(RS_HIDDEN_TYPE_I2P, new_proxyaddr, new_proxyport); } } -void ServerPage::updateStatusBob() +void ServerPage::updateStatusSam() { - QString addr = QString::fromStdString(mBobSettings.address.base32); + QString addr = QString::fromStdString(mSamSettings.address.base32); if (ui.leBobB32Addr->text() != addr) { ui.leBobB32Addr->setText(addr); ui.hiddenpage_serviceAddress->setText(addr); - ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey)); + ui.pteBobServerKey->setPlainText(QString::fromStdString(mSamSettings.address.privateKey)); - if (!mBobSettings.address.privateKey.empty()) { + std::string signingKeyType, cryptoKeyType; + if (i2p::getKeyTypes(mSamSettings.address.publicKey, signingKeyType, cryptoKeyType)) + ui.samKeyInfo->setText(tr("Your key uses the following algorithms: %1 and %2"). + arg(QString::fromStdString(signingKeyType)). + arg(QString::fromStdString(cryptoKeyType))); + else + ui.samKeyInfo->setText(tr("unkown key type")); + + if (!mSamSettings.address.privateKey.empty()) { // we have an addr -> show fields ui.lBobB32Addr->show(); ui.leBobB32Addr->show(); @@ -1689,18 +1722,68 @@ void ServerPage::updateStatusBob() saveAddresses(); } - bobStates bs; - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::status, &bs); + samStatus ss; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::status, &ss); QString bobSimpleText = QString(); - bobSimpleText.append(tr("RetroShare uses BOB to set up a %1 tunnel at %2:%3 (named %4)\n\n" - "When changing options (e.g. port) use the buttons at the bottom to restart BOB.\n\n"). - arg(mBobSettings.address.privateKey.empty() ? tr("client") : tr("server"), + bobSimpleText.append(tr("RetroShare uses SAMv3 to set up a %1 tunnel at %2:%3\n(id: %4)\n\n" + "When changing options (e.g. port) use the buttons at the bottom to restart SAMv3.\n\n"). + arg(mSamSettings.address.privateKey.empty() ? tr("client") : tr("server"), ui.hiddenpage_proxyAddress_i2p_2->text(), - ui.hiddenpage_proxyPort_i2p_2->text(), - bs.tunnelName.empty() ? tr("unknown") : - QString::fromStdString(bs.tunnelName))); + "7656", + ss.sessionName.empty() ? tr("unknown") : + QString::fromStdString(ss.sessionName))); + // update SAM UI based on state + QString s; + QString icon; + switch (ss.state) { + case samStatus::samState::offline: + enableSamElements(false); + + ui.pbBobStart->setEnabled(true); + ui.pbBobRestart->setEnabled(false); + ui.pbBobStop->setEnabled(false); + + s = tr("Offline, no SAM session is established yet.\n"); + icon = ICON_STATUS_ERROR; + break; + case samStatus::samState::connectSession: + enableSamElements(false); + + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(false); + ui.pbBobStop->setEnabled(true); + + s = tr("SAM is trying to establish a session ... this can take some time.\n"); + icon = ICON_STATUS_WORKING; + break; + case samStatus::samState::connectForward: + enableSamElements(false); + + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(false); + ui.pbBobStop->setEnabled(true); + + s = tr("SAM session established! Now setting up a forward session ...\n"); + icon = ICON_STATUS_WORKING; + break; + case samStatus::samState::online: + enableSamElements(true); + + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(true); + ui.pbBobStop->setEnabled(true); + + s = tr("Online, SAM is working as exptected\n"); + icon = ICON_STATUS_OK; + break; + } + ui.iconlabel_i2p_bob->setPixmap(icon); + ui.iconlabel_i2p_bob->setToolTip(s); + bobSimpleText.append(s); + + /* // update BOB UI based on state std::string errorString; switch (bs.cs) { @@ -1711,7 +1794,7 @@ void ServerPage::updateStatusBob() ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); - enableBobElements(false); + enableSamElements(false); { QString s; @@ -1744,7 +1827,7 @@ void ServerPage::updateStatusBob() ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_ERROR)); ui.iconlabel_i2p_bob->setToolTip(tr("BOB is broken\n") + QString::fromStdString(errorString)); - enableBobElements(false); + enableSamElements(false); bobSimpleText.append(tr("BOB encountered an error:\n")); bobSimpleText.append(QString::fromStdString(errorString)); @@ -1760,7 +1843,7 @@ void ServerPage::updateStatusBob() ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)); ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is running")); - enableBobElements(false); + enableSamElements(false); bobSimpleText.append(tr("BOB is working fine: tunnel established")); @@ -1773,7 +1856,7 @@ void ServerPage::updateStatusBob() ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); - enableBobElements(false); + enableSamElements(false); bobSimpleText.append(tr("BOB is processing a request")); @@ -1786,7 +1869,7 @@ void ServerPage::updateStatusBob() ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)); ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is not running")); - enableBobElements(true); + enableSamElements(true); bobSimpleText.append(tr("BOB is inactive: tunnel closed")); @@ -1798,16 +1881,18 @@ void ServerPage::updateStatusBob() break; } - ui.pteBobSimple->setPlainText(bobSimpleText); + */ + ui.pteBobSimple->setPlainText(bobSimpleText); + // disable elements when BOB is not accessible - if (!mBobAccessible) { + if (!mSamAccessible) { ui.pbBobStart->setEnabled(false); - ui.pbBobStart->setToolTip("BOB is not accessible"); + ui.pbBobStart->setToolTip("SAMv3 is not accessible"); ui.pbBobRestart->setEnabled(false); - ui.pbBobRestart->setToolTip("BOB is not accessible"); - // don't disable the stop button! (in case bob is running you are otherwise unable to stop and disable it) - ui.pbBobStop->setToolTip("BOB is not accessible"); + ui.pbBobRestart->setToolTip("SAMv3 is not accessible"); + // don't disable the stop button! (in case SAM is running you are otherwise unable to stop and disable it) + ui.pbBobStop->setToolTip("SAMv3 is not accessible"); } else { ui.pbBobStart->setToolTip(""); ui.pbBobRestart->setToolTip(""); @@ -1815,26 +1900,34 @@ void ServerPage::updateStatusBob() } } -void ServerPage::setUpBobElements() +void ServerPage::setUpSamElements() { - ui.gbBob->setEnabled(mBobSettings.enable); - if (mBobSettings.enable) { + ui.gbBob->setEnabled(mSamSettings.enable); + if (mSamSettings.enable) { ui.hiddenpage_proxyAddress_i2p->setEnabled(false); - ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P/BOB settings to change this value"); + ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P settings to change this value"); ui.hiddenpage_proxyPort_i2p->setEnabled(false); - ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P/BOB settings to change this value"); + ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P settings to change this value"); - ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.address.base32)); - ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey)); + ui.leBobB32Addr->setText(QString::fromStdString(mSamSettings.address.base32)); + ui.pteBobServerKey->setPlainText(QString::fromStdString(mSamSettings.address.privateKey)); + + std::string signingKeyType, cryptoKeyType; + if (i2p::getKeyTypes(mSamSettings.address.publicKey, signingKeyType, cryptoKeyType)) + ui.samKeyInfo->setText(tr("You key uses %1 for signing and %2 for crypto"). + arg(QString::fromStdString(signingKeyType)). + arg(QString::fromStdString(cryptoKeyType))); + else + ui.samKeyInfo->setText(tr("unkown key type")); // cast to int to avoid problems int li, lo, qi, qo, vi, vo; - li = mBobSettings.inLength; - lo = mBobSettings.outLength; - qi = mBobSettings.inQuantity; - qo = mBobSettings.outQuantity; - vi = mBobSettings.inVariance; - vo = mBobSettings.outVariance; + li = mSamSettings.inLength; + lo = mSamSettings.outLength; + qi = mSamSettings.inQuantity; + qo = mSamSettings.outQuantity; + vi = mSamSettings.inVariance; + vo = mSamSettings.outVariance; ui.sbBobLengthIn ->setValue(li); ui.sbBobLengthOut ->setValue(lo); @@ -1850,7 +1943,7 @@ void ServerPage::setUpBobElements() } } -void ServerPage::enableBobElements(bool enable) +void ServerPage::enableSamElements(bool enable) { if (enable) { ui.pbBobGenAddr->setEnabled(true); @@ -1863,13 +1956,13 @@ void ServerPage::enableBobElements(bool enable) ui.cb_enableBob->setToolTip(tr("")); } else { ui.pbBobGenAddr->setEnabled(false); - ui.pbBobGenAddr->setToolTip(tr("stop BOB tunnel first to generate a new key")); + ui.pbBobGenAddr->setToolTip(tr("stop SAM tunnel first to generate a new key")); ui.pbBobLoadKey->setEnabled(false); - ui.pbBobLoadKey->setToolTip(tr("stop BOB tunnel first to load a key")); + ui.pbBobLoadKey->setToolTip(tr("stop SAM tunnel first to load a key")); ui.cb_enableBob->setEnabled(false); - ui.cb_enableBob->setToolTip(tr("stop BOB tunnel first to disable BOB")); + ui.cb_enableBob->setToolTip(tr("stop SAM tunnel first to disable SAM")); } } @@ -1896,6 +1989,7 @@ void ServerPage::handleNetworkReply(QNetworkReply *reply) { int error = reply->error() ; + RS_INFO("error:", error); if(reply->isOpen() && error == QNetworkReply::SslHandshakeFailedError) updateInProxyIndicatorResult(true); else diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index de971881b..a4bacfa40 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -34,7 +34,7 @@ #endif #include -#include +#include #include "retroshare-gui/configpage.h" #include "retroshare-gui/RsAutoUpdatePage.h" @@ -97,22 +97,22 @@ private slots: void handleNetworkReply(QNetworkReply *reply); void updateInProxyIndicator(); - // i2p bob - void startBOB(); - void restartBOB(); - void stopBOB(); + // i2p SAMv3 + void startSam(); + void restartSam(); + void stopSam(); void getNewKey(); void loadKey(); - void enableBob(bool checked); + void enableSam(bool checked); void tunnelSettingsChanged(int); - void toggleBobAdvancedSettings(bool checked); + void toggleSamAdvancedSettings(bool checked); void syncI2PProxyPortNormal(int i); - void syncI2PProxyPortBob(int i); + void syncI2PProxyPortSam(int i); void syncI2PProxyAddrNormal(QString); - void syncI2PProxyAddrBob(QString); + void syncI2PProxyAddrSam(QString); void connectionWithoutCert(); @@ -133,11 +133,11 @@ public: private: void loadCommon(); void saveCommon(); - void saveBob(); - void updateStatusBob(); + void saveSam(); + void updateStatusSam(); - void setUpBobElements(); - void enableBobElements(bool enable); + void setUpSamElements(); + void enableSamElements(bool enable); void updateInProxyIndicatorResult(bool success); @@ -160,8 +160,8 @@ private: bool mIsHiddenNode; uint32_t mHiddenType; - bobSettings mBobSettings; - bool mBobAccessible; // keeps track wether bob is accessable or not to en/disable the corresponding buttons + samSettings mSamSettings; + bool mSamAccessible; // keeps track wether SAM is accessable or not to en/disable the corresponding buttons RsEventsHandlerId_t mEventHandlerId; void handleEvent(std::shared_ptr event); From 10189ba4d0f5a9e16e0d705097435675c476bec3 Mon Sep 17 00:00:00 2001 From: sehraf Date: Sun, 25 Oct 2020 12:50:55 +0100 Subject: [PATCH 054/697] add i2psam3 --- libretroshare/src/libretroshare.pro | 27 +- libretroshare/src/pqi/pqissl.cc | 1 + libretroshare/src/pqi/pqissli2psam3.cpp | 304 ++++++ libretroshare/src/pqi/pqissli2psam3.h | 53 ++ libretroshare/src/pqi/pqissllistener.h | 4 +- libretroshare/src/pqi/pqisslpersongrp.cc | 20 +- libretroshare/src/retroshare/rsinit.h | 2 +- libretroshare/src/rsserver/p3face.h | 6 +- libretroshare/src/rsserver/rsinit.cc | 51 +- .../src/services/autoproxy/p3i2psam3.cpp | 894 ++++++++++++++++++ .../src/services/autoproxy/p3i2psam3.h | 128 +++ .../services/autoproxy/rsautoproxymonitor.cc | 20 +- .../services/autoproxy/rsautoproxymonitor.h | 24 +- libretroshare/src/use_libretroshare.pri | 9 + libretroshare/src/util/i2pcommon.cpp | 7 +- libretroshare/src/util/i2pcommon.h | 2 +- plugins/plugins.pro | 2 +- retroshare-gui/src/gui/GenCertDialog.cpp | 6 +- retroshare-gui/src/gui/settings/ServerPage.ui | 29 +- retroshare.pri | 21 +- supportlibs/libsam3/src/libsam3/libsam3.c | 18 +- 21 files changed, 1543 insertions(+), 85 deletions(-) create mode 100644 libretroshare/src/pqi/pqissli2psam3.cpp create mode 100644 libretroshare/src/pqi/pqissli2psam3.h create mode 100644 libretroshare/src/services/autoproxy/p3i2psam3.cpp create mode 100644 libretroshare/src/services/autoproxy/p3i2psam3.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..c8f9c4b95 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -157,7 +157,7 @@ rs_webui { HEADERS += plugins/pluginmanager.h \ plugins/dlfcn_win32.h \ - rsitems/rspluginitems.h \ + rsitems/rspluginitems.h \ util/i2pcommon.h \ util/rsinitedptr.h @@ -1014,6 +1014,31 @@ rs_broadcast_discovery { } } +rs_sam3 { + SOURCES += \ + services/autoproxy/p3i2psam3.cpp \ + pqi/pqissli2psam3.cpp \ + + HEADERS += \ + services/autoproxy/p3i2psam3.h \ + pqi/pqissli2psam3.h \ +} + +rs_sam3_libsam3 { + DUMMYQMAKECOMPILERINPUT = FORCE + libsam3.name = Generating libsam3. + libsam3.input = DUMMYQMAKECOMPILERINPUT + libsam3.output = $$clean_path($${LIBSAM3_BUILD_PATH}/libsam3.a) + libsam3.CONFIG += target_predeps combine + libsam3.variable_out = PRE_TARGETDEPS + libsam3.commands = \ + cd $${RS_SRC_PATH} && \ + cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} && \ + cd $${LIBSAM3_BUILD_PATH} && \ + $(MAKE) build + QMAKE_EXTRA_COMPILERS += libsam3 +} + ########################################################################################################### # OLD CONFIG OPTIONS. # Not used much - but might be useful one day. diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 76d447cc8..8ba82a105 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1742,6 +1742,7 @@ bool pqissl::moretoread(uint32_t usec) { rslog(RSL_ALERT, pqisslzone, "pqissl::moretoread() Select ERROR!"); + RS_WARN(errno); return 0; } diff --git a/libretroshare/src/pqi/pqissli2psam3.cpp b/libretroshare/src/pqi/pqissli2psam3.cpp new file mode 100644 index 000000000..ec6497e36 --- /dev/null +++ b/libretroshare/src/pqi/pqissli2psam3.cpp @@ -0,0 +1,304 @@ +#include "pqissli2psam3.h" + +#ifdef RS_USE_I2P_SAM3_I2PSAM +#include "util/i2psam.h" +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 +#include +#endif + +RS_SET_CONTEXT_DEBUG_LEVEL(2) + +static constexpr int pqiDone = 1; +static constexpr int pqiWait = 0; +static constexpr int pqiError = -1; + +pqissli2psam3::pqissli2psam3(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) + : pqissl(l, parent, lm), mState(pqisslSam3State::NONE), mI2pAddrB32(), mI2pAddrLong() +{ + RS_DBG4(); + mConn = nullptr; +} + +bool pqissli2psam3::connect_parameter(uint32_t type, const std::string &value) +{ + RS_DBG4(); + + if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS) + { + RS_DBG1("got addr:", value); + RS_STACK_MUTEX(mSslMtx); + mI2pAddrB32 = value; + return true; + } + + return pqissl::connect_parameter(type, value); +} + +int pqissli2psam3::Initiate_Connection() +{ + RS_DBG4(); + + if(waiting != WAITING_DELAY) + { + RS_ERR("Already Attempt in Progress!"); + return pqiError; + } + + switch (mState) { + case(pqisslSam3State::NONE): + RS_DBG2("NONE"); + { + if(mConn) { + // how did we end up here? +#ifdef RS_USE_I2P_SAM3_I2PSAM + unix_close(mConn); +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + sam3CloseConnection(mConn); +#endif + } + mConn = 0; + // get SAM session + mConn = 0; + samSettings ss; + ss.session = nullptr; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, static_cast(&ss)); + +#ifdef RS_USE_I2P_SAM3_I2PSAM + if (!!ss.session && !ss.session->isSick()) { +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + if (!!ss.session) { +#endif + RS_DBG3("NONE->DO_LOOKUP"); + mState = pqisslSam3State::DO_LOOKUP; + } else { + RS_DBG3("NONE->DO_LOOKUP NOPE", ss.session); + } + } + break; + case(pqisslSam3State::DO_LOOKUP): + RS_DBG1("DO_LOOKUP"); + + if (!mI2pAddrLong.empty()) { + // skip lookup, it is highly unlikely/impossible for a public key to change (isn't it?) + mState = pqisslSam3State::WAIT_LOOKUP; + break; + } + + { + i2p::address *addr = new i2p::address; + addr->clear(); + addr->base32 = mI2pAddrB32; + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::lookupKey, this, static_cast(addr)); + } + mState = pqisslSam3State::WAIT_LOOKUP; + break; + case(pqisslSam3State::DO_CONNECT): + RS_DBG2("DO_CONNECT"); + + { + auto wrapper = new samEstablishConnectionWrapper(); + wrapper->address.clear(); + wrapper->address.publicKey = mI2pAddrLong; +#ifdef RS_USE_I2P_SAM3_I2PSAM + wrapper->socket = 0; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + wrapper->connection = nullptr; +#endif + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::establishConnection, this, static_cast(wrapper)); + } + mState = pqisslSam3State::WAIT_CONNECT; + break; + case(pqisslSam3State::DONE): + RS_DBG2("DONE"); + + if (setupSocket()) + return pqiDone; + return pqiError; + + /* waiting */ + case(pqisslSam3State::WAIT_LOOKUP): + RS_DBG3("WAIT_LOOKUP"); + break; + case(pqisslSam3State::WAIT_CONNECT): + RS_DBG3("WAIT_CONNECT"); + break; + } + return pqiWait; +} + +int pqissli2psam3::net_internal_close(int fd) +{ + RS_DBG4(); + + // sanity check +#ifdef RS_USE_I2P_SAM3_I2PSAM + if (mConn && fd != mConn) { +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + if (mConn && fd != mConn->fd) { +#endif + // this should never happen! +//#ifdef RS_USE_I2P_SAM3_I2PSAM +// unix_close(mConn); +//#endif +//#ifdef RS_USE_I2P_SAM3_LIBSAM3 + RS_ERR("fd != mConn"); +// sam3CloseConnection(mConn); +//#endif + } + + // now to the actuall closing + int ret = pqissl::net_internal_close(fd); +// int ret = 0; +//#ifdef RS_USE_I2P_SAM3_LIBSAM3 +// if (mConn) +// ret = sam3CloseConnection(mConn); +//#endif + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::closeConnection, this, mConn), + + // finally cleanup + mConn = 0; + mState = pqisslSam3State::NONE; + + return ret; +} + +void pqissli2psam3::taskFinished(taskTicket *&ticket) +{ + RS_DBG4(); + + switch (ticket->task) { + case autoProxyTask::lookupKey: + { + auto addr = static_cast(ticket->data); + + RS_STACK_MUTEX(mSslMtx); + if (ticket->result == autoProxyStatus::ok) { + mI2pAddrLong = addr->publicKey; + mState = pqisslSam3State::DO_CONNECT; + } else { + waiting = WAITING_FAIL_INTERFACE; + } + + delete addr; + ticket->data = nullptr; + addr = nullptr; + } + break; + case autoProxyTask::establishConnection: + { + auto wrapper = static_cast(ticket->data); + + RS_STACK_MUTEX(mSslMtx); + if (ticket->result == autoProxyStatus::ok) { +#ifdef RS_USE_I2P_SAM3_I2PSAM + mConn = wrapper->socket; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + mConn = wrapper->connection; +#endif + mState = pqisslSam3State::DONE; + } else { + waiting = WAITING_FAIL_INTERFACE; + } + + delete wrapper; + ticket->data = nullptr; + wrapper = nullptr; + } + break; + case autoProxyTask::closeConnection: + // nothing to do here + break; + default: + RS_WARN("unkown task", ticket->task); + } + + // clean up! + delete ticket; + ticket = nullptr; +} + +bool pqissli2psam3::setupSocket() +{ + /* + * This function contains the generis part from pqissl::Initiate_Connection() + */ + int err; +#ifdef RS_USE_I2P_SAM3_I2PSAM + int osock = mConn; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + int osock = mConn->fd; +#endif + + err = unix_fcntl_nonblock(osock); + if (err < 0) + { + RS_ERR("Cannot make socket NON-Blocking:", err); + + waiting = WAITING_FAIL_INTERFACE; + net_internal_close(osock); + return false; + } + +#ifdef WINDOWS_SYS + /* Set TCP buffer size for Windows systems */ + + int sockbufsize = 0; + int size = sizeof(int); + + err = getsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &size); +#ifdef PQISSL_DEBUG + if (err == 0) { + std::cerr << "pqissl::Initiate_Connection: Current TCP receive buffer size " << sockbufsize << std::endl; + } else { + std::cerr << "pqissl::Initiate_Connection: Error getting TCP receive buffer size. Error " << err << std::endl; + } +#endif + + sockbufsize = 0; + + err = getsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, &size); +#ifdef PQISSL_DEBUG + if (err == 0) { + std::cerr << "pqissl::Initiate_Connection: Current TCP send buffer size " << sockbufsize << std::endl; + } else { + std::cerr << "pqissl::Initiate_Connection: Error getting TCP send buffer size. Error " << err << std::endl; + } +#endif + + sockbufsize = WINDOWS_TCP_BUFFER_SIZE; + + err = setsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, sizeof(sockbufsize)); +#ifdef PQISSL_DEBUG + if (err == 0) { + std::cerr << "pqissl::Initiate_Connection: TCP receive buffer size set to " << sockbufsize << std::endl; + } else { + std::cerr << "pqissl::Initiate_Connection: Error setting TCP receive buffer size. Error " << err << std::endl; + } +#endif + + err = setsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, sizeof(sockbufsize)); +#ifdef PQISSL_DEBUG + if (err == 0) { + std::cerr << "pqissl::Initiate_Connection: TCP send buffer size set to " << sockbufsize << std::endl; + } else { + std::cerr << "pqissl::Initiate_Connection: Error setting TCP send buffer size. Error " << err << std::endl; + } +#endif +#endif // WINDOWS_SYS + + + mTimeoutTS = time(NULL) + mConnectTimeout; + //std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl; + + waiting = WAITING_SOCK_CONNECT; + sockfd = osock; + + return true; +} diff --git a/libretroshare/src/pqi/pqissli2psam3.h b/libretroshare/src/pqi/pqissli2psam3.h new file mode 100644 index 000000000..83cba419f --- /dev/null +++ b/libretroshare/src/pqi/pqissli2psam3.h @@ -0,0 +1,53 @@ +#ifndef PQISSLI2PSAM3_H +#define PQISSLI2PSAM3_H + +#include "pqi/pqissl.h" +#include "services/autoproxy/rsautoproxymonitor.h" +#include "services/autoproxy/p3i2psam3.h" + +// Use a state machine as the whole pqi code is designed around them and some operation (like lookup) might be blocking +enum class pqisslSam3State : uint8_t { + NONE = 0, + DO_LOOKUP, + WAIT_LOOKUP, + DO_CONNECT, + WAIT_CONNECT, + DONE +}; + +class pqissli2psam3 : public pqissl, public autoProxyCallback +{ +public: + pqissli2psam3(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm); + + // NetInterface interface +public: + bool connect_parameter(uint32_t type, const std::string &value); + + // pqissl interface +protected: + int Initiate_Connection(); + int net_internal_close(int fd); + + // autoProxyCallback interface +public: + void taskFinished(taskTicket *&ticket); + +private: + bool setupSocket(); + +private: + pqisslSam3State mState; + std::string mI2pAddrB32; + std::string mI2pAddrLong; + +// samSession *mSs; +#ifdef RS_USE_I2P_SAM3_I2PSAM + int mConn; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + Sam3Connection *mConn; +#endif +}; + +#endif // PQISSLI2PSAM3_H diff --git a/libretroshare/src/pqi/pqissllistener.h b/libretroshare/src/pqi/pqissllistener.h index 85af2d869..800ca876b 100644 --- a/libretroshare/src/pqi/pqissllistener.h +++ b/libretroshare/src/pqi/pqissllistener.h @@ -186,8 +186,8 @@ public: virtual int finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const sockaddr_storage &raddr); + RS_SET_CONTEXT_DEBUG_LEVEL(2) + private: std::map listenaddr; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) }; diff --git a/libretroshare/src/pqi/pqisslpersongrp.cc b/libretroshare/src/pqi/pqisslpersongrp.cc index 7016a2fa6..16112c744 100644 --- a/libretroshare/src/pqi/pqisslpersongrp.cc +++ b/libretroshare/src/pqi/pqisslpersongrp.cc @@ -46,7 +46,7 @@ static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersong #endif #include "pqi/pqisslproxy.h" -#include "pqi/pqissli2pbob.h" +#include "pqi/pqissli2psam3.h" pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr) { @@ -74,26 +74,26 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener std::cerr << std::endl; #endif - // Use pqicI2PBOB for I2P - pqiconnect *pqicSOCKSProxy, *pqicI2PBOB; + // Use pqicI2P for I2P + pqiconnect *pqicSOCKSProxy, *pqicI2P; { 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)) + + if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PSAM3)) { - pqissli2pbob *pqis = new pqissli2pbob((pqissllistener *) listener, pqip, mLinkMgr); + pqissli2psam3 *pqis = new pqissli2psam3((pqissllistener *) listener, pqip, mLinkMgr); RsSerialiser *rss = new RsSerialiser(); rss->addSerialType(new RsRawSerialiser()); - pqicI2PBOB = new pqiconnect(pqip, rss, pqis); + pqicI2P = new pqiconnect(pqip, rss, pqis); } else { - pqicI2PBOB = pqicSOCKSProxy; + pqicI2P = pqicSOCKSProxy; } - /* first select type based on peer */ uint32_t typePeer = mPeerMgr->getHiddenType(id); switch (typePeer) { @@ -101,7 +101,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy); break; case RS_HIDDEN_TYPE_I2P: - pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB); + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2P); break; default: /* peer is not a hidden one but we are */ @@ -109,7 +109,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, pqicI2PBOB); + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2P); break; default: /* this case shouldn't happen! */ diff --git a/libretroshare/src/retroshare/rsinit.h b/libretroshare/src/retroshare/rsinit.h index 73fea2684..d26e7ac05 100644 --- a/libretroshare/src/retroshare/rsinit.h +++ b/libretroshare/src/retroshare/rsinit.h @@ -195,7 +195,7 @@ public: /* * Setup Hidden Location; */ - static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob); + static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useI2p); static bool LoadPassword(const std::string& passwd) ; diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h index 661cb244f..648e39123 100644 --- a/libretroshare/src/rsserver/p3face.h +++ b/libretroshare/src/rsserver/p3face.h @@ -43,7 +43,7 @@ class p3heartbeat; class p3discovery2; -class p3I2pBob; +class p3I2pSam3; /* GXS Classes - just declare the classes. so we don't have to totally recompile to switch */ @@ -161,8 +161,8 @@ public: p3ChatService *chatSrv; p3StatusService *mStatusSrv; p3GxsTunnelService *mGxsTunnels; -#ifdef RS_USE_I2P_BOB - p3I2pBob *mI2pBob; +#ifdef RS_USE_I2P_SAM3 + p3I2pSam3 *mI2pSam3; #endif // This list contains all threaded services. It will be used to shut them down properly. diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..864099f01 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -170,7 +170,7 @@ struct RsInitConfig std::string hiddenNodeAddress; uint16_t hiddenNodePort; - bool hiddenNodeI2PBOB; + bool hiddenNodeI2P; /* Logging */ bool haveLogFile; @@ -664,13 +664,13 @@ void RsInit::setAutoLogin(bool autoLogin){ } /* Setup Hidden Location; */ -void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob) +void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useI2p) { /* parse the bugger (todo) */ rsInitConfig->hiddenNodeSet = true; rsInitConfig->hiddenNodeAddress = hiddenaddress; rsInitConfig->hiddenNodePort = port; - rsInitConfig->hiddenNodeI2PBOB = useBob; + rsInitConfig->hiddenNodeI2P = useI2p; } @@ -718,6 +718,7 @@ RsGRouter *rsGRouter = NULL ; #endif // def RS_USE_LIBUPNP #include "services/autoproxy/p3i2pbob.h" +#include "services/autoproxy/p3i2psam3.h" #include "services/autoproxy/rsautoproxymonitor.h" #include "services/p3gxsreputation.h" @@ -923,9 +924,9 @@ int RsServer::StartupRetroShare() mNetMgr->setManagers(mPeerMgr, mLinkMgr); rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance(); -#ifdef RS_USE_I2P_BOB - mI2pBob = new p3I2pBob(mPeerMgr); - autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob); +#ifdef RS_USE_I2P_SAM3 + mI2pSam3 = new p3I2pSam3(mPeerMgr); + autoProxy->addProxy(autoProxyType::I2PSAM3, mI2pSam3); #endif //load all the SSL certs as friends @@ -1655,8 +1656,9 @@ int RsServer::StartupRetroShare() mConfigMgr->addConfiguration("wire.cfg", wire_ns); #endif #endif //RS_ENABLE_GXS -#ifdef RS_USE_I2P_BOB - mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob); +#ifdef RS_USE_I2P_SAM3 + // to make migration easiert, SAM will use BOBs configuration, as they are compatible / the same. + mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pSam3); #endif mPluginsManager->addConfigurations(mConfigMgr) ; @@ -1709,34 +1711,33 @@ int RsServer::StartupRetroShare() { std::cout << "RsServer::StartupRetroShare setting up hidden locations" << std::endl; - if (rsInitConfig->hiddenNodeI2PBOB) { - std::cout << "RsServer::StartupRetroShare setting up BOB" << std::endl; + if (rsInitConfig->hiddenNodeI2P) { + std::cout << "RsServer::StartupRetroShare setting up SAMv3" << 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 + uint16_t port; // unused by SAM - bool r = autoProxy->initialSetup(autoProxyType::I2PBOB, addr, port); + bool r = autoProxy->initialSetup(autoProxyType::I2PSAM3, addr, port); if (r && !addr.empty()) { mPeerMgr->setupHiddenNode(addr, port); - // now enable bob - bobSettings bs; - autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs); - bs.enable = true; - autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs); + // now enable SAM + samSettings ss; + autoProxy->taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, &ss); + ss.enable = true; + autoProxy->taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &ss); } else { std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl; - /// TODO add notify for failed bob setup + /// TODO add notify for failed i2p setup } } else { mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort); @@ -1758,19 +1759,17 @@ int RsServer::StartupRetroShare() if (rsInitConfig->hiddenNodeSet) { // newly created location // mNetMgr->checkNetAddress() will setup ports for us + +#if 0 // this was used for BOB but is not requires for SAMv3 // trigger updates for auto proxy services std::vector types; - - // i2p bob need to rebuild its command map - types.push_back(autoProxyType::I2PBOB); - rsAutoProxyMonitor::taskSync(types, autoProxyTask::reloadConfig); +#endif } /**************************************************************************/ /* startup (stuff dependent on Ids/peers is after this point) */ /**************************************************************************/ - autoProxy->startAll(); pqih->init_listener(); @@ -1803,8 +1802,8 @@ int RsServer::StartupRetroShare() /**************************************************************************/ // auto proxy threads -#ifdef RS_USE_I2P_BOB - startServiceThread(mI2pBob, "I2P-BOB"); +#ifdef RS_USE_I2P_SAM3 + startServiceThread(mI2pSam3, "I2P-SAM3"); #endif #ifdef RS_ENABLE_GXS diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp new file mode 100644 index 000000000..215f23964 --- /dev/null +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -0,0 +1,894 @@ +#include "p3i2psam3.h" + +#ifdef RS_USE_I2P_SAM3_LIBSAM3 +#include +#endif +#ifdef RS_USE_I2P_SAM3_I2PSAM +#include "util/i2psam.h" +#endif + +#include "pqi/p3peermgr.h" +#include "rsitems/rsconfigitems.h" + + +static const std::string kConfigKeySAM3Enable = "SAM3_ENABLE"; + +static const std::string kConfigKeyDestPriv = "DEST_PRIV"; + +static const std::string kConfigKeyInLength = "IN_LENGTH"; +static const std::string kConfigKeyInQuantity = "IN_QUANTITY"; +static const std::string kConfigKeyInVariance = "IN_VARIANCE"; +static const std::string kConfigKeyInBackupQuantity = "IN_BACKUPQUANTITY"; + +static const std::string kConfigKeyOutLength = "OUT_LENGTH"; +static const std::string kConfigKeyOutQuantity = "OUT_QUANTITY"; +static const std::string kConfigKeyOutVariance = "OUT_VARIANCE"; +static const std::string kConfigKeyOutBackupQuantity = "OUT_BACKUPQUANTITY"; + +#ifdef RS_I2P_SAM3_BOB_COMPAT +// used for migration from BOB to SAM +static const std::string kConfigKeyBOBEnable = "BOB_ENABLE"; +static const std::string kConfigKeyBOBKey = "BOB_KEY"; +static const std::string kConfigKeyBOBAddr = "BOB_ADDR"; +#endif + +static constexpr bool kDefaultSAM3Enable = false; + +RS_SET_CONTEXT_DEBUG_LEVEL(4) + +// copy from i2psam.cpp +//#define I2P_DESTINATION_SIZE 516 + +static void inline doSleep(std::chrono::duration> timeToSleepMS) { + std::this_thread::sleep_for(timeToSleepMS); +} + +p3I2pSam3::p3I2pSam3(p3PeerMgr *peerMgr) : + mConfigLoaded(false), mPeerMgr(peerMgr), mPending(), mLock("p3i2p-sam3") +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + , mLockSam3Access("p3i2p-sam3-access") +#endif +{ + RS_DBG4(); + + // set defaults + mSetting.initDefault(); + mSetting.enable = kDefaultSAM3Enable; + mSetting.session = nullptr; + + libsam3_debug = 1; +} + +bool p3I2pSam3::isEnabled() +{ + RS_STACK_MUTEX(mLock); + return mSetting.enable; +} + +bool p3I2pSam3::initialSetup(std::string &addr, uint16_t &/*port*/) +{ + RS_DBG4(); + + RS_STACK_MUTEX(mLock); + + if (!mSetting.address.publicKey.empty() || !mSetting.address.privateKey.empty()) + RS_DBG("overwriting keys!"); + + bool success = generateKey(mSetting.address.publicKey, mSetting.address.privateKey); + + if (!success) { + RS_DBG("failed to retrieve keys"); + return false; + } else { + std::string s, c; + i2p::getKeyTypes(mSetting.address.publicKey, s, c); + RS_INFO("received key", s, c); + + IndicateConfigChanged(); + } + + addr = mSetting.address.base32 = i2p::keyToBase32Addr(mSetting.address.publicKey); + return true; +} + +void p3I2pSam3::processTaskAsync(taskTicket *ticket) +{ + RS_DBG4(); + + switch (ticket->task) { + case autoProxyTask::stop: [[fallthrough]]; + case autoProxyTask::start: [[fallthrough]]; + case autoProxyTask::receiveKey: [[fallthrough]]; + case autoProxyTask::lookupKey: [[fallthrough]]; + case autoProxyTask::proxyStatusCheck: [[fallthrough]]; + case autoProxyTask::establishConnection: [[fallthrough]]; + case autoProxyTask::closeConnection: + { + RS_STACK_MUTEX(mLock); + mPending.push(ticket); + } + break; + case autoProxyTask::status: [[fallthrough]]; + case autoProxyTask::getSettings: [[fallthrough]]; + case autoProxyTask::setSettings: [[fallthrough]]; + case autoProxyTask::getErrorInfo: [[fallthrough]]; + case autoProxyTask::reloadConfig: + // These are supposed to be sync! + RS_DBG("unknown task or sync one!"); + rsAutoProxyMonitor::taskError(ticket); + break; + } +} + +void p3I2pSam3::processTaskSync(taskTicket *ticket) +{ +// RS_DBG4(); + + const bool data = !!ticket->data; + + switch (ticket->task) { + case autoProxyTask::status: + { + samStatus *ss = static_cast(ticket->data); + RS_STACK_MUTEX(mLock); + ss->state = mState; + if (mSetting.session) + ss->sessionName = mSetting.session->channel; + else + ss->sessionName = "none"; + } + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + + break; + case autoProxyTask::getSettings: + // check if everything needed is set + if (!data) { + RS_DBG("autoProxyTask::getSettings data is missing"); + rsAutoProxyMonitor::taskError(ticket); + break; + } + + // get settings + { + RS_STACK_MUTEX(mLock); + *static_cast(ticket->data) = mSetting; + } + + // finish task + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + break; + case autoProxyTask::setSettings: + // check if everything needed is set + if (!data) { + RS_DBG("autoProxyTask::setSettings data is missing"); + rsAutoProxyMonitor::taskError(ticket); + break; + } + + // set settings + { + RS_STACK_MUTEX(mLock); + mSetting = *static_cast(ticket->data); + updateSettings_locked(); + } + + // finish task + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + break; + case autoProxyTask::getErrorInfo: +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + *static_cast(ticket->data) = mSetting.session->error; + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); +#else + rsAutoProxyMonitor::taskError(ticket); +#endif + break; + case autoProxyTask::reloadConfig: + { + RS_STACK_MUTEX(mLock); + updateSettings_locked(); + } + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + break; + case autoProxyTask::stop: +#if 0 // doesn't seem to work, socket stays "CLOSE_WAIT" + // there can be a case where libsam3 will block forever because for some reason it does not detect that the socket it has is dead + // as a workaroung kill it from here + if (mState == samStatus::samState::connectSession || mState == samStatus::samState::connectForward) { + // lock should be held by the main thread + if (!mTmpSession) { + // now it's getting weird + RS_WARN("session is nullptr but mState says it is connecting."); + // no break! just ignore for now ... + } else { + // just close it from here, libsam3 is not thread safe. + // a bit of a hack but should do the trick +// sam3CloseSession(mSetting.session); + sam3tcpDisconnect(mTmpSession->fd); + // no break! continue as usual to keep everything in line + } + } +#endif + [[fallthrough]]; + case autoProxyTask::start: [[fallthrough]]; + case autoProxyTask::receiveKey: [[fallthrough]]; + case autoProxyTask::lookupKey: [[fallthrough]]; + case autoProxyTask::proxyStatusCheck: [[fallthrough]]; + case autoProxyTask::establishConnection: [[fallthrough]]; + case autoProxyTask::closeConnection: + // These are supposed to be async! + RS_WARN("unknown task or async one!"); + rsAutoProxyMonitor::taskError(ticket); + break; + } +} + +void p3I2pSam3::threadTick() +{ +// { +// RS_STACK_MUTEX(mLock); +// Dbg4() << __PRETTY_FUNCTION__ << " mPending: " << mPending.size() << std::endl; +// } + + if(mPending.empty()) { + // sleep outisde of lock! + doSleep(std::chrono::milliseconds(250)); + return; + } + + // get task + taskTicket *tt = nullptr; + { + RS_STACK_MUTEX(mLock); + tt = mPending.front(); + mPending.pop(); + } + + switch (tt->task) { + case autoProxyTask::stop: + mState = samStatus::samState::offline; + stopForwarding(); + stopSession(); + rsAutoProxyMonitor::taskDone(tt, autoProxyStatus::offline); + break; + + case autoProxyTask::start: + { + if (!mSetting.enable) { + rsAutoProxyMonitor::taskDone(tt, autoProxyStatus::disabled); + break; + } + + // create main session + mState = samStatus::samState::connectSession; + bool ret = startSession(); + if (!ret) { + mState = samStatus::samState::offline; + + rsAutoProxyMonitor::taskError(tt); + break; + } + + // start forwarding + mState = samStatus::samState::connectForward; + ret = startForwarding(); + + // finish ticket + if (ret) { + mState = samStatus::samState::online; + rsAutoProxyMonitor::taskDone(tt, autoProxyStatus::online); + } else { + mState = samStatus::samState::offline; + rsAutoProxyMonitor::taskError(tt); + } + } + break; + + case autoProxyTask::receiveKey: + { + i2p::address *addr = static_cast(tt->data); + if (generateKey(addr->publicKey, addr->privateKey)) { + addr->base32 = i2p::keyToBase32Addr(addr->publicKey); + rsAutoProxyMonitor::taskDone(tt, autoProxyStatus::ok); + } else { + rsAutoProxyMonitor::taskError(tt); + } + } + break; + + case autoProxyTask::lookupKey: + lookupKey(tt); +#ifdef RS_USE_I2P_SAM3_I2PSAM + // artificially delay following operations as i2psam uses time(null) as rng seed + doSleep(std::chrono::seconds(1)); +#endif + break; + + case autoProxyTask::proxyStatusCheck: + { + // TODO better detection of status + bool ok; +#ifdef RS_USE_I2P_SAM3_I2PSAM + ok = !mSetting.session->isSick(); +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + ok = !!mSetting.session->fd; + ok &= !!mSetting.session->fwd_fd; +#endif // RS_USE_I2P_SAM3_LIBSAM3 + *static_cast(tt->data) = ok; + rsAutoProxyMonitor::taskDone(tt, ok ? autoProxyStatus::ok : autoProxyStatus::error); + } + break; + + case autoProxyTask::establishConnection: + establishConnection(tt); + break; + case autoProxyTask::closeConnection: + closeConnection(tt); + break; + case autoProxyTask::status: [[fallthrough]]; + case autoProxyTask::getSettings: [[fallthrough]]; + case autoProxyTask::setSettings: [[fallthrough]]; + case autoProxyTask::getErrorInfo: [[fallthrough]]; + case autoProxyTask::reloadConfig: + RS_ERR("unable to handle! This is a bug! task:", tt->task); + rsAutoProxyMonitor::taskError(tt); + break; + } + tt = nullptr; + + // give i2p backend some time + doSleep(std::chrono::milliseconds(100)); +} + +RsSerialiser *p3I2pSam3::setupSerialiser() +{ + RsSerialiser* rsSerialiser = new RsSerialiser(); + rsSerialiser->addSerialType(new RsGeneralConfigSerialiser()); + + return rsSerialiser; +} + +#define addKVS(_key, _value) \ + kv.key = _key;\ + kv.value = _value;\ + vitem->tlvkvs.pairs.push_back(kv); + +#define addKVSInt(_key, _value) \ + kv.key = _key;\ + rs_sprintf(kv.value, "%d", _value);\ + vitem->tlvkvs.pairs.push_back(kv); + +bool p3I2pSam3::saveList(bool &cleanup, std::list &lst) +{ + RS_DBG4(); + + cleanup = true; + RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet; + RsTlvKeyValue kv; + + RS_STACK_MUTEX(mLock); + addKVS(kConfigKeySAM3Enable, mSetting.enable ? "TRUE" : "FALSE") + addKVS(kConfigKeyDestPriv, mSetting.address.privateKey); + + addKVSInt(kConfigKeyInLength, mSetting.inLength) + addKVSInt(kConfigKeyInQuantity, mSetting.inQuantity) + addKVSInt(kConfigKeyInVariance, mSetting.inVariance) + addKVSInt(kConfigKeyInBackupQuantity, mSetting.inBackupQuantity) + + addKVSInt(kConfigKeyOutLength, mSetting.outLength) + addKVSInt(kConfigKeyOutQuantity, mSetting.outQuantity) + addKVSInt(kConfigKeyOutVariance, mSetting.outVariance) + addKVSInt(kConfigKeyOutBackupQuantity, mSetting.outBackupQuantity) + +#ifdef RS_I2P_SAM3_BOB_COMPAT + // these allow SAMv3 users to switch back to BOB + // remove after some time + addKVS(kConfigKeyBOBEnable, mSetting.enable ? "TRUE" : "FALSE") + addKVS(kConfigKeyBOBKey, mSetting.address.privateKey) + addKVS(kConfigKeyBOBAddr, mSetting.address.base32) +#endif + lst.push_back(vitem); + return true; +} + +#undef addKVS +#undef addKVSUInt + +#define getKVSUInt(_kit, _key, _value) \ + else if (_kit->key == _key) {\ + std::istringstream is(_kit->value);\ + int tmp;\ + is >> tmp;\ + _value = (int8_t)tmp;\ + } + +bool p3I2pSam3::loadList(std::list &load) +{ + RS_DBG4(); + + std::string priv; + priv.clear(); + + for(std::list::const_iterator it = load.begin(); it!=load.end(); ++it) { + RsConfigKeyValueSet *vitem = dynamic_cast(*it); + if(vitem != NULL) { + RS_STACK_MUTEX(mLock); + for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) { + if (kit->key == kConfigKeySAM3Enable) + mSetting.enable = kit->value == "TRUE"; + else if (kit->key == kConfigKeyDestPriv) + priv = kit->value; + getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength) + getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity) + getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance) + getKVSUInt(kit, kConfigKeyInBackupQuantity, mSetting.inBackupQuantity) + + getKVSUInt(kit, kConfigKeyOutLength, mSetting.outLength) + getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity) + getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance) + getKVSUInt(kit, kConfigKeyOutBackupQuantity, mSetting.outBackupQuantity) + +#ifdef RS_I2P_SAM3_BOB_COMPAT + // import BOB settings + else if (kit->key == kConfigKeyBOBEnable) + mSetting.enable = kit->value == "TRUE"; + else if (kit->key == kConfigKeyBOBKey) { + // don't overwirte, just import when not set already! + if (priv.empty()) + priv = kit->value; + } +#endif + else + RS_INFO("unknown key:", kit->key); + } + } + delete vitem; + } + + // get the pub key + std::string pub = i2p::publicKeyFromPrivate(priv); + if (pub.empty() || priv.empty()) + RS_DBG("no destination to load"); + else { + RS_STACK_MUTEX(mLock); + + mSetting.address.publicKey = pub; + mSetting.address.privateKey = priv; + mSetting.address.base32 = i2p::keyToBase32Addr(pub); + } + + RS_STACK_MUTEX(mLock); + mConfigLoaded = true; + + return true; +} + +#undef getKVSUInt + +bool p3I2pSam3::startSession() +{ + RS_DBG4(); + + constexpr size_t len = 8; + const std::string location = RsRandom::alphaNumeric(len); + const std::string nick = "RetroShare-" + location; + + std::vector params; + { + RS_STACK_MUTEX(mLock); + + // length + params.push_back(i2p::makeOption("inbound.length", mSetting.inLength)); + params.push_back(i2p::makeOption("outbound.length", mSetting.outLength)); + // variance + params.push_back(i2p::makeOption("inbound.lengthVariance", + mSetting.inVariance)); + params.push_back(i2p::makeOption("outbound.lengthVariance", + mSetting.outVariance)); + // quantity + params.push_back(i2p::makeOption("inbound.quantity", + mSetting.inQuantity)); + params.push_back(i2p::makeOption("outbound.quantity", + mSetting.outQuantity)); + // backup quantity + params.push_back(i2p::makeOption("inbound.backupQuantity", + mSetting.inBackupQuantity)); + params.push_back(i2p::makeOption("outbound.backupQuantity", + mSetting.outBackupQuantity)); + } + + std::string paramsStr; + for (auto &&p : params) + paramsStr.append(p + " "); + // keep trailing space for easier extending when necessary + +#ifdef RS_USE_I2P_SAM3_I2PSAM + if(mSetting.session) { + RS_STACK_MUTEX(mLock); + + delete mSetting.session; // stopForwardingAll(); is called in destructor + mSetting.session = nullptr; + } + + SAM::StreamSession *session; + + if(!mSetting.address.privateKey.empty()) { + Dbg3() << __PRETTY_FUNCTION__ << " with destination" << std::endl; + session = new SAM::StreamSession(nick, SAM_DEFAULT_ADDRESS, SAM_DEFAULT_PORT, mSetting.address.privateKey, paramsStr); + } else { + Dbg3() << __PRETTY_FUNCTION__ << " without destination" << std::endl; + session = new SAM::StreamSession(nick, SAM_DEFAULT_ADDRESS, SAM_DEFAULT_PORT, SAM_GENERATE_MY_DESTINATION, paramsStr, "DSA_SHA1"); + } + + if (!session || session->isSick()) { + return false; + } + + /* + * i2psam is sometimes unable to reliable read the public key, which is crucial to base32 address generation + * (due to the fact that is assumes it's length wrongly) + * + * The following are attempts to reliable receive our public key + */ + + const auto dest = session->getMyDestination(); +// auto copy = dest; + std::string pubKey1 = dest.pub; + std::string pubKey2(dest.pub); + i2p::validatePubkeyFromPrivKey(pubKey2, dest.priv); + + /* + * pubkeys: + * 1: from initial call (== dest.pub) + * 2: from parsing (was == dest.pub + */ + Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 " << pubKey1 << std::endl; + Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p2 " << pubKey2 << std::endl; + if (pubKey1 == pubKey2) { + // unchanged + Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 == p2" << std::endl; + } else { + // parsed pub key is different, prefer parsed one + pubKey1 = pubKey2; + Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 != p2" << std::endl; + } + SAM::FullDestination dest2(pubKey1, dest.priv, true); + + // populate settings + RS_STACK_MUTEX(mLock); + mSetting.session = session; + if (!mSetting.address.publicKey.empty() && mSetting.address.publicKey != dest2.pub) + // This should be ok for non hidden locations. This should be a problem for hidden i2p locations... + RsDbg() << __PRETTY_FUNCTION__ << " public key changed! Yet unsure if this is ok or a problem" << std::endl; + mSetting.address.publicKey = dest2.pub; + mSetting.address.base32 = i2p::keyToBase32Addr(dest2.pub); + // do not overwrite the private key, if any!! + +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + int ret; + + if (mSetting.session) { + stopSession(); + } + + auto session = new Sam3Session(); + + // add nick + paramsStr.append("inbound.nickname=" + nick); // leading space is already there + + { + RS_STACK_MUTEX(mLockSam3Access); + + if(!mSetting.address.privateKey.empty()) { + RS_DBG3("with destination"); + ret = sam3CreateSilentSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, mSetting.address.privateKey.c_str(), Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); + } else { + RS_DBG("without destination"); + ret = sam3CreateSilentSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); + } + } + + if (ret != 0) { + delete session; + session = nullptr; + return false; + } + +#if 0 // this check is useless. For non i2p hidden locations the public key is temporal anyway and for i2p hidden ones, it is part of the (fixed) private key. + if (!mSetting.address.publicKey.empty() && mSetting.address.publicKey != session->pubkey) + // This should be ok for non hidden locations. This should be a problem for hidden i2p locations... + RS_DBG("public key changed! Yet unsure if this is ok or a problem. Should be fine for non i2p hidden locations or clear net."); +#endif + /* + * Note: sam3CreateSession will issue a name looup of "ME" to receive its public key, thus it is always correct. + * No need to use i2p::publicKeyFromPrivate() + */ + RS_STACK_MUTEX(mLock); + mSetting.session = session; + mSetting.address.publicKey = session->pubkey; + mSetting.address.base32 = i2p::keyToBase32Addr(session->pubkey); + // do not overwrite the private key, if any!! +#endif + + RS_DBG1("nick:", nick, "address:", mSetting.address.base32); + RS_DBG2(" myDestination.pub ", mSetting.address.publicKey); + RS_DBG2(" myDestination.priv", mSetting.address.privateKey); + return true; +} + +bool p3I2pSam3::startForwarding() +{ + RS_DBG4(); + + if(mSetting.address.privateKey.empty()) { + RS_DBG3("no private key set"); + // IMPORANT: return true here! + // since there is no forward session for non hidden nodes, this funtion is successfull by doing nothing + return true; + } + + if (!mSetting.session) { + RS_WARN("no session found!"); + return false; + } + + peerState ps; + mPeerMgr->getOwnNetStatus(ps); + +#ifdef RS_USE_I2P_SAM3_I2PSAM + auto ret = mSetting.session->forward(sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr), true); + if (!ret.isOk) + RsDbg() << __PRETTY_FUNCTION__ << " forward failed" << std::endl; + else + Dbg2() << __PRETTY_FUNCTION__ << " forward successfull" << std::endl; + + return ret.isOk; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + RS_STACK_MUTEX(mLockSam3Access); + + int ret = sam3StreamForward(mSetting.session, sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr)); + + if (ret < 0) { + RS_DBG("forward failed, due to", mSetting.session->error); + return false; + } +#endif + return true; +} + +void p3I2pSam3::stopSession() +{ + RS_DBG4(); + + { + RS_STACK_MUTEX(mLock); + if (!mSetting.session) + return; +#ifdef RS_USE_I2P_SAM3_I2PSAM + // TODO cleanup sockets + delete mSetting.session; // will stop forwarding, too +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + // swap connections + mInvalidConnections = mValidConnections; + mValidConnections.clear(); + + RS_STACK_MUTEX(mLockSam3Access); + sam3CloseSession(mSetting.session); + delete mSetting.session; +#endif + + mSetting.session = nullptr; + mState = samStatus::samState::offline; + } + + // At least i2pd doesn't like to instantaniously stop and (re)start a session, wait here just a little bit. + // Not ideal but does the trick. + // (This happens when using the "restart" button in the settings.) + doSleep(std::chrono::seconds(10)); +} + +void p3I2pSam3::stopForwarding() +{ + // nothing to do here, forwarding is stop when closing the seassion +} + +bool p3I2pSam3::generateKey(std::string &pub, std::string &priv) +{ + RS_DBG4(); + + pub.clear(); + priv.clear(); + +#ifdef RS_USE_I2P_SAM3_I2PSAM + auto ss = new SAM::StreamSession("RS-destgen"); + auto ret = ss->destGenerate(); + if (!ret.isOk) + return false; + + auto dest = ret.value; + pub = std::string(dest.pub); + priv = std::string(dest.priv); + +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + // The session is only usef for transporting the data + Sam3Session ss; + + if (0 > sam3GenerateKeys(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, Sam3SigType::EdDSA_SHA512_Ed25519)) { + RS_DBG("got error:", ss.error); + return false; + } + pub = std::string(ss.pubkey); + priv = std::string(ss.privkey); +#endif + + RS_DBG2("publuc key / address", pub); + RS_DBG2("private key", priv); + + return true; +} + +void p3I2pSam3::lookupKey(taskTicket *ticket) +{ + // this can be called independend of the main SAM session! + + auto addr = static_cast(ticket->data); + if (addr->base32.empty()) { + RS_ERR("lookupKey: called with empty address"); + rsAutoProxyMonitor::taskError(ticket); + return; + } +#ifdef RS_USE_I2P_SAM3_I2PSAM + auto sam = mSetting.session; + RsThread::async([ticket, sam]() +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + RsThread::async([ticket]() +#endif + { + auto addr = static_cast(ticket->data); + +#ifdef RS_USE_I2P_SAM3_I2PSAM + auto r = sam->namingLookup(addr->base32); + if (!r.isOk) { + // get error + RsDbg() << __PRETTY_FUNCTION__ << " key: " << addr->base32 << std::endl; + RsDbg() << __PRETTY_FUNCTION__ << " got error!" << std::endl; + rsAutoProxyMonitor::taskError(ticket); + } else { + addr->publicKey = r.value; + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + Dbg1() << __PRETTY_FUNCTION__ << " success " << std::endl; + } +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + // The session is only usef for transporting the data + Sam3Session ss; + int ret = sam3NameLookup(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, addr->base32.c_str()); + if (ret < 0) { + // get error + RS_DBG("key:", addr->base32); + RS_DBG("got error:", ss.error); + rsAutoProxyMonitor::taskError(ticket); + } else { + addr->publicKey = ss.destkey; + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + RS_DBG1("success"); + } +#endif + }); +} + +void p3I2pSam3::establishConnection(taskTicket *ticket) +{ + if (mState != samStatus::samState::online || !mSetting.session) { + RS_WARN("no session found!"); + rsAutoProxyMonitor::taskError(ticket); + return; + } + + samEstablishConnectionWrapper *wrapper = static_cast(ticket->data); + if (wrapper->address.publicKey.empty()) { + RS_ERR("no public key given"); + rsAutoProxyMonitor::taskError(ticket); + return; + } + + RsThread::async([ticket, this]() { + auto wrapper = static_cast(ticket->data); +#ifdef RS_USE_I2P_SAM3_I2PSAM + auto r = this->mSetting.session->connect(wrapper->address.publicKey.c_str(), false); // silent=true is broken! + if (!r.isOk) { + // get error + RsDbg() << __PRETTY_FUNCTION__ << " got error!" << std::endl; + rsAutoProxyMonitor::taskError(ticket); + } else { + // extract socket + wrapper->socket = r.value.get()->release(); + Dbg1() << __PRETTY_FUNCTION__ << " success " << std::endl; + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + } +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + struct Sam3Connection *connection; + { + auto l = this->mLockSam3Access; + RS_STACK_MUTEX(l); + connection = sam3StreamConnect(this->mSetting.session, wrapper->address.publicKey.c_str()); + } + + if (!connection) { + // get error + RS_DBG("got error:", this->mSetting.session->error); + rsAutoProxyMonitor::taskError(ticket); + } else { + wrapper->connection = connection; + { + auto l = this->mLockSam3Access; + RS_STACK_MUTEX(l); + this->mValidConnections.push_back(connection); + } + RS_DBG1("success"); + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + } +#endif + }); +} + +void p3I2pSam3::closeConnection(taskTicket *ticket) +{ + Sam3Connection *con = static_cast(ticket->data); + + if (mState == samStatus::samState::offline || !mSetting.session) { + // no session found, sam was likel stopped + } else { + RS_STACK_MUTEX(mLock); + + bool callClose = true; + // search in current connections + auto it = std::find(mValidConnections.begin(), mValidConnections.end(), con); + if (it != mValidConnections.end()) { + mValidConnections.erase(it); + } else { + // search in old connections + it = std::find(mInvalidConnections.begin(), mInvalidConnections.end(), con); + if (it != mInvalidConnections.end()) { + // old connection, just ignore. *should* be freed already + callClose = false; + con = nullptr; + } else { + // weird + RS_WARN("could'n find connection!"); + + // best thing we can do here + callClose = false; + con = nullptr; + } + } + + if (callClose) { + RS_STACK_MUTEX(mLockSam3Access); + sam3CloseConnection(con); + con = nullptr; // freed by above call + } + } + + if (con) { + delete con; + con = nullptr; + } + ticket->data = nullptr; + rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); + return; +} + +void p3I2pSam3::updateSettings_locked() +{ + RS_DBG4(); + IndicateConfigChanged(); + +#if 0 // TODO recreat session when active, can we just recreat it? + if (mSs) { + stopSession(); + startSession(); + } +#endif +} diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.h b/libretroshare/src/services/autoproxy/p3i2psam3.h new file mode 100644 index 000000000..bbf13c143 --- /dev/null +++ b/libretroshare/src/services/autoproxy/p3i2psam3.h @@ -0,0 +1,128 @@ +#ifndef P3I2PSAM3_H +#define P3I2PSAM3_H + +#include +#include + +#include "services/autoproxy/rsautoproxymonitor.h" +#include "pqi/p3cfgmgr.h" +#include "util/i2pcommon.h" +#include "util/rsthreads.h" + +/* + * This class implements I2P SAMv3 (Simple Anonymous Messaging) to allow RS + * to automatically setup tunnel to and from I2P. + * SAMv3 is a simple text-based interface: https://geti2p.net/de/docs/api/samv3 + * + * For the actual SAM commands / low level stuff libsam3 (https://github.com/i2p/libsam3) + * is used with some minor adjustments, for exmaple, the FORWARD session is always silent. + * + * SAM in a nutshell works like this: + * 1) setup main/control session which configures everything (destination ID, tunnel number, hops number, and so on) + * 2) setup a forward session, so that I2P will establish a connection to RS for each incoming connection to our i2p destination + * 3a) query/lookup the destination (public key) for a given i2p address + * 3b) connect to the given destination + * + * An established connection (both incoming or outgoing) are then handed over to RS. + * The lifetime of a session (and its subordinates connections) is bound to their tcp socket. When the socket closes, the session is closed, too. + * + */ + +class p3PeerMgr; + +// typedef samSession is used to unify access to the session independent of the underlying library +#ifdef RS_USE_I2P_SAM3_I2PSAM +namespace SAM { +class StreamSession; +class I2pSocket; +} + +typedef SAM::StreamSession samSession; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 +class Sam3Session; +class Sam3Connection; + +typedef Sam3Session samSession; +#endif + +struct samSettings : i2p::settings { + samSession *session; +}; + +struct samEstablishConnectionWrapper { + i2p::address address; +#ifdef RS_USE_I2P_SAM3_I2PSAM + int socket; +#endif +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + Sam3Connection *connection; +#endif +}; + +struct samStatus { + std::string sessionName; + enum samState { + offline, + connectSession, + connectForward, + online + } state; // the name is kinda redundant ... +}; + +class p3I2pSam3 : public RsTickingThread, public p3Config, public autoProxyService +{ +public: + p3I2pSam3(p3PeerMgr *peerMgr); + + // autoProxyService interface +public: + bool isEnabled(); + bool initialSetup(std::string &addr, uint16_t &port); + void processTaskAsync(taskTicket *ticket); + void processTaskSync(taskTicket *ticket); + + // RsTickingThread interface +public: + void threadTick(); /// @see RsTickingThread + + // p3Config interface +protected: + RsSerialiser *setupSerialiser(); + bool saveList(bool &cleanup, std::list &); + bool loadList(std::list &load); + +private: + bool startSession(); + bool startForwarding(); + void stopSession(); + void stopForwarding(); + + bool generateKey(std::string &pub, std::string &priv); + void lookupKey(taskTicket *ticket); + void establishConnection(taskTicket *ticket); + void closeConnection(taskTicket *ticket); + void updateSettings_locked(); + + bool mConfigLoaded; + + samSettings mSetting; + p3PeerMgr *mPeerMgr; + std::queue mPending; + + // Used to report the state to the gui + // (Since the create session call/will can block and there is no easy way from outside the main thread to see + // what is going on, it is easier to store the current state in an extra variable independen from the main thread) + samStatus::samState mState; + + // used to keep track of connections, libsam3 does it internally but it can be unreliable since pointers are shared + std::list mValidConnections, mInvalidConnections; + + // mutex + RsMutex mLock; +#ifdef RS_USE_I2P_SAM3_LIBSAM3 + RsMutex mLockSam3Access; // libsam3 is not thread safe! (except for key lookup) +#endif +}; + +#endif // P3I2PSAM3_H diff --git a/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc b/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc index d58c871e3..b2d71571e 100644 --- a/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc +++ b/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc @@ -329,14 +329,22 @@ autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType bool rsAutoProxyMonitor::isAsyncTask(autoProxyTask::autoProxyTask_enum t) { + // Explicit list all values, so that missing ones will be detected by the compiler. switch (t) { - case autoProxyTask::start: - case autoProxyTask::stop: - case autoProxyTask::receiveKey: + case autoProxyTask::start: [[fallthrough]]; + case autoProxyTask::stop: [[fallthrough]]; + case autoProxyTask::receiveKey: [[fallthrough]]; + case autoProxyTask::lookupKey: [[fallthrough]]; + case autoProxyTask::establishConnection: [[fallthrough]]; + case autoProxyTask::closeConnection: return true; - break; - default: - break; + case autoProxyTask::status: [[fallthrough]]; + case autoProxyTask::getSettings: [[fallthrough]]; + case autoProxyTask::setSettings: [[fallthrough]]; + case autoProxyTask::getErrorInfo: [[fallthrough]]; + case autoProxyTask::reloadConfig: [[fallthrough]]; + case autoProxyTask::proxyStatusCheck: + return false; } return false; } diff --git a/libretroshare/src/services/autoproxy/rsautoproxymonitor.h b/libretroshare/src/services/autoproxy/rsautoproxymonitor.h index d9a4c16aa..e08692947 100644 --- a/libretroshare/src/services/autoproxy/rsautoproxymonitor.h +++ b/libretroshare/src/services/autoproxy/rsautoproxymonitor.h @@ -31,23 +31,27 @@ class autoProxyCallback; namespace autoProxyType { enum autoProxyType_enum { - I2PBOB +// I2PBOB, + I2PSAM3 }; } 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 + start, ///< start up proxy + stop, ///< shut down proxy + receiveKey, ///< renew proxy key (if any) + lookupKey, ///< look up a base32 addr + proxyStatusCheck, ///< use to check if the proxy is still running + establishConnection, ///< create a connection to a given public key or base32 address + closeConnection, ///< closes a connection /* 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 + 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 }; } diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index b76c4a5da..63009745f 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -90,6 +90,15 @@ rs_broadcast_discovery { win32-g++|win32-clang-g++:dLibs *= wsock32 } +rs_sam3_libsam3 { + LIBSAM3_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/libsam3/) + LIBSAM3_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/libsam3/) + INCLUDEPATH *= $$clean_path($${LIBSAM3_SRC_PATH}/src/libsam3/) + DEPENDPATH *= $$clean_path($${LIBSAM3_BUILD_PATH}) + QMAKE_LIBDIR *= $$clean_path($${LIBSAM3_BUILD_PATH}) + LIBS *= -L$$clean_path($${LIBSAM3_BUILD_PATH}) -lsam3 +} + static { sLibs *= $$mLibs } else { diff --git a/libretroshare/src/util/i2pcommon.cpp b/libretroshare/src/util/i2pcommon.cpp index bca7ae110..0733a807d 100644 --- a/libretroshare/src/util/i2pcommon.cpp +++ b/libretroshare/src/util/i2pcommon.cpp @@ -50,7 +50,7 @@ std::string publicKeyFromPrivate(std::string const &priv) * https://geti2p.net/spec/common-structures#keysandcert * https://geti2p.net/spec/common-structures#certificate */ - if (priv.length() < 884) // base64 ( = 663 bytes = KeyCert + priv Keys) + if (priv.empty() || priv.length() < 884) // base64 ( = 663 bytes = KeyCert + priv Keys) return std::string(); // creat a copy to work on, need to convert it to standard base64 @@ -163,6 +163,9 @@ std::string publicKeyFromPrivate(std::string const &priv) bool getKeyTypes(const std::string &key, std::string &signingKey, std::string &cryptoKey) { + if (key.length() < 522) // base64 (391 bytes = 384 bytes + 7 bytes = KeysAndCert + Certificate) + return false; + // creat a copy to work on, need to convert it to standard base64 auto key_copy(key); std::replace(key_copy.begin(), key_copy.end(), '~', '/'); @@ -225,7 +228,7 @@ bool getKeyTypes(const std::string &key, std::string &signingKey, std::string &c // now convert to string (this would be easier with c++17) #define HELPER(a, b, c) \ case static_cast::type>(a::c): \ - b = "c"; \ + b = #c; \ break; switch (signingKeyType) { diff --git a/libretroshare/src/util/i2pcommon.h b/libretroshare/src/util/i2pcommon.h index e41b61010..0a76fa080 100644 --- a/libretroshare/src/util/i2pcommon.h +++ b/libretroshare/src/util/i2pcommon.h @@ -210,7 +210,7 @@ std::string publicKeyFromPrivate(const std::string &priv); /** * @brief getKeyTypes returns the name of the utilized algorithms used by the key - * @param key public key (private works, too) + * @param key public key * @param signingKey name of the signing key, e.g. DSA_SHA1 * @param cryptoKey name of the crpyto key, e.g. ElGamal * @return true on success, false otherwise diff --git a/plugins/plugins.pro b/plugins/plugins.pro index 209b82898..7ecbc32c7 100644 --- a/plugins/plugins.pro +++ b/plugins/plugins.pro @@ -19,5 +19,5 @@ TEMPLATE = subdirs SUBDIRS += \ - VOIP \ + VOIP \ FeedReader diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e106146fb..68ff05c42 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -539,12 +539,12 @@ void GenCertDialog::genPerson() std::string hl = ui.hiddenaddr_input->text().toStdString(); uint16_t port = ui.hiddenport_spinBox->value(); - bool useBob = ui.cbUseBob->isChecked(); + bool useI2p = ui.cbUseBob->isChecked(); - if (useBob && hl.empty()) + if (useI2p && hl.empty()) hl = "127.0.0.1"; - RsInit::SetHiddenLocation(hl, port, useBob); /* parses it */ + RsInit::SetHiddenLocation(hl, port, useI2p); /* parses it */ } diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 5ef7308b1..9d506bf38 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -6,8 +6,8 @@ 0 0 - 712 - 502 + 726 + 579 @@ -908,9 +908,9 @@ If you have issues connecting over Tor check the Tor logs too. - + - Automatic I2P/BOB + Automatic I2P @@ -918,7 +918,7 @@ If you have issues connecting over Tor check the Tor logs too. - Enable I2P BOB - changing this requires a restart to fully take effect + Enable I2P SAMv3 - changing this requires a restart to fully take effect @@ -950,7 +950,7 @@ If you have issues connecting over Tor check the Tor logs too. - I2P Basic Open Bridge + I2P Simple Anonymous Messaging @@ -990,6 +990,12 @@ If you have issues connecting over Tor check the Tor logs too. + + false + + + Not required for SAMv3 + 10 @@ -1016,7 +1022,7 @@ If you have issues connecting over Tor check the Tor logs too. <html><head/><body><p>This led is green when the port listen on the left is active on your computer. It does not</p><p>mean that your Retroshare traffic transits though I2P. It will do so only if </p><p>you connect to Hidden nodes, or if you are running a Hidden node yourself.</p></body></html> - BOB accessible + SAM accessible @@ -1304,6 +1310,13 @@ If you have issues connecting over Tor check the Tor logs too. + + + + <key info> + + + @@ -1359,7 +1372,7 @@ If you have issues connecting over Tor check the Tor logs too. - BOB status + SAM status diff --git a/retroshare.pri b/retroshare.pri index 2c2201ef3..825d5d49e 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -140,11 +140,6 @@ rs_macos10.15:CONFIG -= rs_macos10.11 CONFIG *= no_rs_jsonapi rs_jsonapi:CONFIG -= no_rs_jsonapi -# Disable i2p BOB support for automatically setting up an i2p tunnel for RS -# "CONFIG+=no_rs_bob" -CONFIG *= rs_bob -no_rs_bob:CONFIG -= rs_bob - # To enable channel indexing append the following assignation to qmake command # line "CONFIG+=rs_deep_channels_index" CONFIG *= no_rs_deep_channels_index @@ -209,6 +204,10 @@ no_rs_dh_init_check:CONFIG -= rs_dh_init_check # many exported symbols. retroshare_plugins:win32:CONFIG *= libretroshare_shared +CONFIG+=rs_sam3 +CONFIG+=rs_sam3_libsam3 +#CONFIG+=rs_sam3_i2psam + # Specify host precompiled jsonapi-generator path, appending the following # assignation to qmake command line # 'JSONAPI_GENERATOR_EXE=/myBuildDir/jsonapi-generator'. Required for JSON API @@ -559,10 +558,6 @@ rs_webui { DEFINES *= RS_WEBUI } -rs_bob { - DEFINES *= RS_USE_I2P_BOB -} - rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX @@ -576,6 +571,14 @@ rs_broadcast_discovery:DEFINES *= RS_BROADCAST_DISCOVERY no_rs_dh_init_check:DEFINES *= RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK +rs_sam3: { + DEFINES *= RS_USE_I2P_SAM3 + # this allows a downgrade from a SAMv3 build to a BOB build, can be removed in the future + DEFINES *= RS_I2P_SAM3_BOB_COMPAT +} +rs_sam3_libsam3: DEFINES *= RS_USE_I2P_SAM3_LIBSAM3 +rs_sam3_i2psam: DEFINES *= RS_USE_I2P_SAM3_I2PSAM + debug { rs_mutex_debug:DEFINES *= RS_MUTEX_DEBUG diff --git a/supportlibs/libsam3/src/libsam3/libsam3.c b/supportlibs/libsam3/src/libsam3/libsam3.c index 367949a39..476372a0b 100644 --- a/supportlibs/libsam3/src/libsam3/libsam3.c +++ b/supportlibs/libsam3/src/libsam3/libsam3.c @@ -26,6 +26,10 @@ #include #include +#ifdef WINDOWS_SYS +#include +#endif // WINDOWS_SYS + //////////////////////////////////////////////////////////////////////////////// int libsam3_debug = 0; @@ -100,6 +104,11 @@ int sam3tcpConnectIP(uint32_t ip, int port) { } } // + // Set this for all outgoing SAM connections. Most SAM commands should be answered rather fast except CREATE SESSION maybe. + // This should be enough to let SAM establish a session. + sam3tcpSetTimeoutSend(fd, 5 * 60 * 1000); + sam3tcpSetTimeoutReceive(fd, 5 * 60 * 1000); + // setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); // if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { @@ -152,8 +161,13 @@ int sam3tcpConnect(const char *hostname, int port, uint32_t *ip) { // <0: error; 0: ok int sam3tcpDisconnect(int fd) { if (fd >= 0) { - shutdown(fd, SHUT_RDWR); - return close(fd); +#ifndef WINDOWS_SYS // ie UNIX + shutdown(fd, SHUT_RDWR); + return close(fd); +#else + return closesocket(fd); +#endif + } // return -1; From eb0aa340e3cfa254c4a9851e035b3501271c067e Mon Sep 17 00:00:00 2001 From: sehraf Date: Wed, 4 Nov 2020 17:47:29 +0100 Subject: [PATCH 055/697] remove i2psam (library) support --- libretroshare/src/pqi/pqissli2psam3.cpp | 50 +----- libretroshare/src/pqi/pqissli2psam3.h | 6 - .../src/services/autoproxy/p3i2psam3.cpp | 156 +----------------- .../src/services/autoproxy/p3i2psam3.h | 18 -- retroshare.pri | 2 - 5 files changed, 7 insertions(+), 225 deletions(-) diff --git a/libretroshare/src/pqi/pqissli2psam3.cpp b/libretroshare/src/pqi/pqissli2psam3.cpp index ec6497e36..41087a893 100644 --- a/libretroshare/src/pqi/pqissli2psam3.cpp +++ b/libretroshare/src/pqi/pqissli2psam3.cpp @@ -1,11 +1,6 @@ #include "pqissli2psam3.h" -#ifdef RS_USE_I2P_SAM3_I2PSAM -#include "util/i2psam.h" -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 #include -#endif RS_SET_CONTEXT_DEBUG_LEVEL(2) @@ -51,12 +46,7 @@ int pqissli2psam3::Initiate_Connection() { if(mConn) { // how did we end up here? -#ifdef RS_USE_I2P_SAM3_I2PSAM - unix_close(mConn); -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 - sam3CloseConnection(mConn); -#endif + RS_ERR("state is NONE but a connection is existing?!"); } mConn = 0; // get SAM session @@ -65,12 +55,7 @@ int pqissli2psam3::Initiate_Connection() ss.session = nullptr; rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, static_cast(&ss)); -#ifdef RS_USE_I2P_SAM3_I2PSAM - if (!!ss.session && !ss.session->isSick()) { -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 if (!!ss.session) { -#endif RS_DBG3("NONE->DO_LOOKUP"); mState = pqisslSam3State::DO_LOOKUP; } else { @@ -102,12 +87,8 @@ int pqissli2psam3::Initiate_Connection() auto wrapper = new samEstablishConnectionWrapper(); wrapper->address.clear(); wrapper->address.publicKey = mI2pAddrLong; -#ifdef RS_USE_I2P_SAM3_I2PSAM - wrapper->socket = 0; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 wrapper->connection = nullptr; -#endif + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::establishConnection, this, static_cast(wrapper)); } mState = pqisslSam3State::WAIT_CONNECT; @@ -135,29 +116,14 @@ int pqissli2psam3::net_internal_close(int fd) RS_DBG4(); // sanity check -#ifdef RS_USE_I2P_SAM3_I2PSAM - if (mConn && fd != mConn) { -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 if (mConn && fd != mConn->fd) { -#endif // this should never happen! -//#ifdef RS_USE_I2P_SAM3_I2PSAM -// unix_close(mConn); -//#endif -//#ifdef RS_USE_I2P_SAM3_LIBSAM3 RS_ERR("fd != mConn"); // sam3CloseConnection(mConn); -//#endif } // now to the actuall closing - int ret = pqissl::net_internal_close(fd); -// int ret = 0; -//#ifdef RS_USE_I2P_SAM3_LIBSAM3 -// if (mConn) -// ret = sam3CloseConnection(mConn); -//#endif + int ret = pqissl::net_internal_close(fd); rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::closeConnection, this, mConn), // finally cleanup @@ -195,12 +161,7 @@ void pqissli2psam3::taskFinished(taskTicket *&ticket) RS_STACK_MUTEX(mSslMtx); if (ticket->result == autoProxyStatus::ok) { -#ifdef RS_USE_I2P_SAM3_I2PSAM - mConn = wrapper->socket; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 mConn = wrapper->connection; -#endif mState = pqisslSam3State::DONE; } else { waiting = WAITING_FAIL_INTERFACE; @@ -229,12 +190,7 @@ bool pqissli2psam3::setupSocket() * This function contains the generis part from pqissl::Initiate_Connection() */ int err; -#ifdef RS_USE_I2P_SAM3_I2PSAM - int osock = mConn; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 int osock = mConn->fd; -#endif err = unix_fcntl_nonblock(osock); if (err < 0) diff --git a/libretroshare/src/pqi/pqissli2psam3.h b/libretroshare/src/pqi/pqissli2psam3.h index 83cba419f..90fdff6e0 100644 --- a/libretroshare/src/pqi/pqissli2psam3.h +++ b/libretroshare/src/pqi/pqissli2psam3.h @@ -41,13 +41,7 @@ private: std::string mI2pAddrB32; std::string mI2pAddrLong; -// samSession *mSs; -#ifdef RS_USE_I2P_SAM3_I2PSAM - int mConn; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 Sam3Connection *mConn; -#endif }; #endif // PQISSLI2PSAM3_H diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index 215f23964..ed2b51ccd 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -1,11 +1,6 @@ #include "p3i2psam3.h" -#ifdef RS_USE_I2P_SAM3_LIBSAM3 #include -#endif -#ifdef RS_USE_I2P_SAM3_I2PSAM -#include "util/i2psam.h" -#endif #include "pqi/p3peermgr.h" #include "rsitems/rsconfigitems.h" @@ -36,9 +31,6 @@ static constexpr bool kDefaultSAM3Enable = false; RS_SET_CONTEXT_DEBUG_LEVEL(4) -// copy from i2psam.cpp -//#define I2P_DESTINATION_SIZE 516 - static void inline doSleep(std::chrono::duration> timeToSleepMS) { std::this_thread::sleep_for(timeToSleepMS); } @@ -176,12 +168,8 @@ void p3I2pSam3::processTaskSync(taskTicket *ticket) rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); break; case autoProxyTask::getErrorInfo: -#ifdef RS_USE_I2P_SAM3_LIBSAM3 *static_cast(ticket->data) = mSetting.session->error; rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); -#else - rsAutoProxyMonitor::taskError(ticket); -#endif break; case autoProxyTask::reloadConfig: { @@ -298,23 +286,14 @@ void p3I2pSam3::threadTick() case autoProxyTask::lookupKey: lookupKey(tt); -#ifdef RS_USE_I2P_SAM3_I2PSAM - // artificially delay following operations as i2psam uses time(null) as rng seed - doSleep(std::chrono::seconds(1)); -#endif break; case autoProxyTask::proxyStatusCheck: { // TODO better detection of status bool ok; -#ifdef RS_USE_I2P_SAM3_I2PSAM - ok = !mSetting.session->isSick(); -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 ok = !!mSetting.session->fd; ok &= !!mSetting.session->fwd_fd; -#endif // RS_USE_I2P_SAM3_LIBSAM3 *static_cast(tt->data) = ok; rsAutoProxyMonitor::taskDone(tt, ok ? autoProxyStatus::ok : autoProxyStatus::error); } @@ -497,70 +476,6 @@ bool p3I2pSam3::startSession() paramsStr.append(p + " "); // keep trailing space for easier extending when necessary -#ifdef RS_USE_I2P_SAM3_I2PSAM - if(mSetting.session) { - RS_STACK_MUTEX(mLock); - - delete mSetting.session; // stopForwardingAll(); is called in destructor - mSetting.session = nullptr; - } - - SAM::StreamSession *session; - - if(!mSetting.address.privateKey.empty()) { - Dbg3() << __PRETTY_FUNCTION__ << " with destination" << std::endl; - session = new SAM::StreamSession(nick, SAM_DEFAULT_ADDRESS, SAM_DEFAULT_PORT, mSetting.address.privateKey, paramsStr); - } else { - Dbg3() << __PRETTY_FUNCTION__ << " without destination" << std::endl; - session = new SAM::StreamSession(nick, SAM_DEFAULT_ADDRESS, SAM_DEFAULT_PORT, SAM_GENERATE_MY_DESTINATION, paramsStr, "DSA_SHA1"); - } - - if (!session || session->isSick()) { - return false; - } - - /* - * i2psam is sometimes unable to reliable read the public key, which is crucial to base32 address generation - * (due to the fact that is assumes it's length wrongly) - * - * The following are attempts to reliable receive our public key - */ - - const auto dest = session->getMyDestination(); -// auto copy = dest; - std::string pubKey1 = dest.pub; - std::string pubKey2(dest.pub); - i2p::validatePubkeyFromPrivKey(pubKey2, dest.priv); - - /* - * pubkeys: - * 1: from initial call (== dest.pub) - * 2: from parsing (was == dest.pub - */ - Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 " << pubKey1 << std::endl; - Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p2 " << pubKey2 << std::endl; - if (pubKey1 == pubKey2) { - // unchanged - Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 == p2" << std::endl; - } else { - // parsed pub key is different, prefer parsed one - pubKey1 = pubKey2; - Dbg3() << __PRETTY_FUNCTION__ << " figuring out our pubKey: p1 != p2" << std::endl; - } - SAM::FullDestination dest2(pubKey1, dest.priv, true); - - // populate settings - RS_STACK_MUTEX(mLock); - mSetting.session = session; - if (!mSetting.address.publicKey.empty() && mSetting.address.publicKey != dest2.pub) - // This should be ok for non hidden locations. This should be a problem for hidden i2p locations... - RsDbg() << __PRETTY_FUNCTION__ << " public key changed! Yet unsure if this is ok or a problem" << std::endl; - mSetting.address.publicKey = dest2.pub; - mSetting.address.base32 = i2p::keyToBase32Addr(dest2.pub); - // do not overwrite the private key, if any!! - -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 int ret; if (mSetting.session) { @@ -604,7 +519,6 @@ bool p3I2pSam3::startSession() mSetting.address.publicKey = session->pubkey; mSetting.address.base32 = i2p::keyToBase32Addr(session->pubkey); // do not overwrite the private key, if any!! -#endif RS_DBG1("nick:", nick, "address:", mSetting.address.base32); RS_DBG2(" myDestination.pub ", mSetting.address.publicKey); @@ -631,16 +545,6 @@ bool p3I2pSam3::startForwarding() peerState ps; mPeerMgr->getOwnNetStatus(ps); -#ifdef RS_USE_I2P_SAM3_I2PSAM - auto ret = mSetting.session->forward(sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr), true); - if (!ret.isOk) - RsDbg() << __PRETTY_FUNCTION__ << " forward failed" << std::endl; - else - Dbg2() << __PRETTY_FUNCTION__ << " forward successfull" << std::endl; - - return ret.isOk; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 RS_STACK_MUTEX(mLockSam3Access); int ret = sam3StreamForward(mSetting.session, sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr)); @@ -649,7 +553,7 @@ bool p3I2pSam3::startForwarding() RS_DBG("forward failed, due to", mSetting.session->error); return false; } -#endif + return true; } @@ -661,11 +565,7 @@ void p3I2pSam3::stopSession() RS_STACK_MUTEX(mLock); if (!mSetting.session) return; -#ifdef RS_USE_I2P_SAM3_I2PSAM - // TODO cleanup sockets - delete mSetting.session; // will stop forwarding, too -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 + // swap connections mInvalidConnections = mValidConnections; mValidConnections.clear(); @@ -673,7 +573,6 @@ void p3I2pSam3::stopSession() RS_STACK_MUTEX(mLockSam3Access); sam3CloseSession(mSetting.session); delete mSetting.session; -#endif mSetting.session = nullptr; mState = samStatus::samState::offline; @@ -697,18 +596,6 @@ bool p3I2pSam3::generateKey(std::string &pub, std::string &priv) pub.clear(); priv.clear(); -#ifdef RS_USE_I2P_SAM3_I2PSAM - auto ss = new SAM::StreamSession("RS-destgen"); - auto ret = ss->destGenerate(); - if (!ret.isOk) - return false; - - auto dest = ret.value; - pub = std::string(dest.pub); - priv = std::string(dest.priv); - -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 // The session is only usef for transporting the data Sam3Session ss; @@ -718,7 +605,6 @@ bool p3I2pSam3::generateKey(std::string &pub, std::string &priv) } pub = std::string(ss.pubkey); priv = std::string(ss.privkey); -#endif RS_DBG2("publuc key / address", pub); RS_DBG2("private key", priv); @@ -736,30 +622,11 @@ void p3I2pSam3::lookupKey(taskTicket *ticket) rsAutoProxyMonitor::taskError(ticket); return; } -#ifdef RS_USE_I2P_SAM3_I2PSAM - auto sam = mSetting.session; - RsThread::async([ticket, sam]() -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 + RsThread::async([ticket]() -#endif { auto addr = static_cast(ticket->data); -#ifdef RS_USE_I2P_SAM3_I2PSAM - auto r = sam->namingLookup(addr->base32); - if (!r.isOk) { - // get error - RsDbg() << __PRETTY_FUNCTION__ << " key: " << addr->base32 << std::endl; - RsDbg() << __PRETTY_FUNCTION__ << " got error!" << std::endl; - rsAutoProxyMonitor::taskError(ticket); - } else { - addr->publicKey = r.value; - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - Dbg1() << __PRETTY_FUNCTION__ << " success " << std::endl; - } -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 // The session is only usef for transporting the data Sam3Session ss; int ret = sam3NameLookup(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, addr->base32.c_str()); @@ -773,7 +640,6 @@ void p3I2pSam3::lookupKey(taskTicket *ticket) rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); RS_DBG1("success"); } -#endif }); } @@ -794,20 +660,7 @@ void p3I2pSam3::establishConnection(taskTicket *ticket) RsThread::async([ticket, this]() { auto wrapper = static_cast(ticket->data); -#ifdef RS_USE_I2P_SAM3_I2PSAM - auto r = this->mSetting.session->connect(wrapper->address.publicKey.c_str(), false); // silent=true is broken! - if (!r.isOk) { - // get error - RsDbg() << __PRETTY_FUNCTION__ << " got error!" << std::endl; - rsAutoProxyMonitor::taskError(ticket); - } else { - // extract socket - wrapper->socket = r.value.get()->release(); - Dbg1() << __PRETTY_FUNCTION__ << " success " << std::endl; - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - } -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 + struct Sam3Connection *connection; { auto l = this->mLockSam3Access; @@ -829,7 +682,6 @@ void p3I2pSam3::establishConnection(taskTicket *ticket) RS_DBG1("success"); rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); } -#endif }); } diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.h b/libretroshare/src/services/autoproxy/p3i2psam3.h index bbf13c143..c6b57615e 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.h +++ b/libretroshare/src/services/autoproxy/p3i2psam3.h @@ -30,21 +30,10 @@ class p3PeerMgr; -// typedef samSession is used to unify access to the session independent of the underlying library -#ifdef RS_USE_I2P_SAM3_I2PSAM -namespace SAM { -class StreamSession; -class I2pSocket; -} - -typedef SAM::StreamSession samSession; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 class Sam3Session; class Sam3Connection; typedef Sam3Session samSession; -#endif struct samSettings : i2p::settings { samSession *session; @@ -52,12 +41,7 @@ struct samSettings : i2p::settings { struct samEstablishConnectionWrapper { i2p::address address; -#ifdef RS_USE_I2P_SAM3_I2PSAM - int socket; -#endif -#ifdef RS_USE_I2P_SAM3_LIBSAM3 Sam3Connection *connection; -#endif }; struct samStatus { @@ -120,9 +104,7 @@ private: // mutex RsMutex mLock; -#ifdef RS_USE_I2P_SAM3_LIBSAM3 RsMutex mLockSam3Access; // libsam3 is not thread safe! (except for key lookup) -#endif }; #endif // P3I2PSAM3_H diff --git a/retroshare.pri b/retroshare.pri index 825d5d49e..da7a451c8 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -206,7 +206,6 @@ retroshare_plugins:win32:CONFIG *= libretroshare_shared CONFIG+=rs_sam3 CONFIG+=rs_sam3_libsam3 -#CONFIG+=rs_sam3_i2psam # Specify host precompiled jsonapi-generator path, appending the following # assignation to qmake command line @@ -577,7 +576,6 @@ rs_sam3: { DEFINES *= RS_I2P_SAM3_BOB_COMPAT } rs_sam3_libsam3: DEFINES *= RS_USE_I2P_SAM3_LIBSAM3 -rs_sam3_i2psam: DEFINES *= RS_USE_I2P_SAM3_I2PSAM debug { rs_mutex_debug:DEFINES *= RS_MUTEX_DEBUG From e4336a8a417ecc61dc25c8d471233fca5049d9b4 Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 6 Nov 2020 15:45:47 +0100 Subject: [PATCH 056/697] GUI: remove i2p proxy port, there is none with SAM --- retroshare-gui/src/gui/GenCertDialog.cpp | 10 +++---- retroshare-gui/src/gui/GenCertDialog.h | 2 +- retroshare-gui/src/gui/GenCertDialog.ui | 4 +-- .../src/gui/settings/ServerPage.cpp | 21 +------------- retroshare-gui/src/gui/settings/ServerPage.h | 3 -- retroshare-gui/src/gui/settings/ServerPage.ui | 28 ++++++------------- 6 files changed, 18 insertions(+), 50 deletions(-) diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index 68ff05c42..2aae87d09 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -150,7 +150,7 @@ 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)));; + connect(ui.cbUseBob, SIGNAL(clicked(bool)), this, SLOT(useI2pChecked(bool)));; entropy_timer = new QTimer ; entropy_timer->start(20) ; @@ -341,9 +341,9 @@ void GenCertDialog::setupState() ui.hiddenport_spinBox->setVisible(hidden_state && !tor_auto); ui.cbUseBob->setVisible(hidden_state && !tor_auto); -#ifndef RS_USE_I2P_BOB +#ifndef RS_USE_I2P_SAM3 ui.cbUseBob->setDisabled(true); - ui.cbUseBob->setToolTip(tr("BOB support is not available")); + ui.cbUseBob->setToolTip(tr("SAMv3 support is not available")); #endif if(!mAllFieldsOk) @@ -440,10 +440,10 @@ void GenCertDialog::updateCheckLabels() setupState(); } -void GenCertDialog::useBobChecked(bool checked) +void GenCertDialog::useI2pChecked(bool checked) { if (checked) { - ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with BOB enabled")); + ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with SAMv3 enabled")); ui.hiddenaddr_label->setText(tr("I2P instance address")); ui.hiddenport_spinBox->setEnabled(false); diff --git a/retroshare-gui/src/gui/GenCertDialog.h b/retroshare-gui/src/gui/GenCertDialog.h index afd82e5f0..5bef44485 100644 --- a/retroshare-gui/src/gui/GenCertDialog.h +++ b/retroshare-gui/src/gui/GenCertDialog.h @@ -44,7 +44,7 @@ private slots: void switchReuseExistingNode(); void grabMouse(); void updateCheckLabels(); - void useBobChecked(bool checked); + void useI2pChecked(bool checked); private: void initKeyList(); diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 96f09cae2..482150beb 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -496,7 +496,7 @@ - Use BOB + Use I2P @@ -764,8 +764,8 @@ importIdentity_PB - + diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 62928f701..ee71a9b44 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -184,10 +184,6 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.sbBobVarianceIn, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); QObject::connect(ui.sbBobVarianceOut, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); - // These two spin boxes are used for the same thing - keep them in sync! - QObject::connect(ui.hiddenpage_proxyPort_i2p, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortNormal(int))); - QObject::connect(ui.hiddenpage_proxyPort_i2p_2, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortSam(int))); - // These two line edits are used for the same thing - keep them in sync! QObject::connect(ui.hiddenpage_proxyAddress_i2p, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrNormal(QString))); QObject::connect(ui.hiddenpage_proxyAddress_i2p_2, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrSam(QString))); @@ -1528,20 +1524,6 @@ void ServerPage::toggleSamAdvancedSettings(bool checked) } } -void ServerPage::syncI2PProxyPortNormal(int i) -{ - ui.hiddenpage_proxyPort_i2p_2->setValue(i); -} - -void ServerPage::syncI2PProxyPortSam(int i) -{ - ui.hiddenpage_proxyPort_i2p->setValue(i); - - // update port, not necessary for same, we just want to keep it consistent - saveSam(); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::reloadConfig); -} - void ServerPage::syncI2PProxyAddrNormal(QString t) { ui.hiddenpage_proxyAddress_i2p_2->setText(t); @@ -1639,7 +1621,6 @@ void ServerPage::loadCommon() whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr)); whileBlocking(ui.hiddenpage_proxyAddress_i2p_2)->setText(QString::fromStdString(proxyaddr)); // this one is for sam tab whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); - whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for sam tab // don't use whileBlocking here ui.cb_enableBob->setChecked(mSamSettings.enable); @@ -1727,7 +1708,7 @@ void ServerPage::updateStatusSam() QString bobSimpleText = QString(); bobSimpleText.append(tr("RetroShare uses SAMv3 to set up a %1 tunnel at %2:%3\n(id: %4)\n\n" - "When changing options (e.g. port) use the buttons at the bottom to restart SAMv3.\n\n"). + "When changing options use the buttons at the bottom to restart SAMv3.\n\n"). arg(mSamSettings.address.privateKey.empty() ? tr("client") : tr("server"), ui.hiddenpage_proxyAddress_i2p_2->text(), "7656", diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index a4bacfa40..7d82f2190 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -108,9 +108,6 @@ private slots: void toggleSamAdvancedSettings(bool checked); - void syncI2PProxyPortNormal(int i); - void syncI2PProxyPortSam(int i); - void syncI2PProxyAddrNormal(QString); void syncI2PProxyAddrSam(QString); diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 9d506bf38..6fad339c1 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -982,27 +982,17 @@ If you have issues connecting over Tor check the Tor logs too. - - - I2P proxy port + + + Qt::Horizontal - - - - - - false + + + 40 + 20 + - - Not required for SAMv3 - - - 10 - - - 65535 - - + From 25cb152a7e6200915107ca234036bbae95a591cc Mon Sep 17 00:00:00 2001 From: sehraf Date: Sat, 7 Nov 2020 10:20:17 +0100 Subject: [PATCH 057/697] make pqissl notice bad file descriptor --- libretroshare/src/pqi/pqissl.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 8ba82a105..1cfff8fbd 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1742,7 +1742,13 @@ bool pqissl::moretoread(uint32_t usec) { rslog(RSL_ALERT, pqisslzone, "pqissl::moretoread() Select ERROR!"); - RS_WARN(errno); + RS_WARN(strerror(errno)); + + if (errno == EBADF) { + // happens when SAM is shut down + rslog(RSL_ALERT, pqisslzone, "pqissl::moretoread() -> calling reset()"); + reset_locked(); + } return 0; } From 47a4b726a3f218cfcbed9af85886169c63718d60 Mon Sep 17 00:00:00 2001 From: sehraf Date: Thu, 19 Nov 2020 17:12:15 +0100 Subject: [PATCH 058/697] update libsam3 --- supportlibs/libsam3/Makefile | 6 +- supportlibs/libsam3/README.md | 36 ++++++- supportlibs/libsam3/examples/sam3/streamcs.c | 87 ++++++++++++++++ supportlibs/libsam3/examples/sam3/streamss.c | 72 +++++++++++++ supportlibs/libsam3/src/libsam3/libsam3.c | 101 ++++++++++++------- supportlibs/libsam3/src/libsam3/libsam3.h | 34 +++++++ supportlibs/libsam3/src/libsam3a/libsam3a.c | 18 +++- supportlibs/libsam3/src/libsam3a/libsam3a.h | 11 ++ 8 files changed, 323 insertions(+), 42 deletions(-) create mode 100644 supportlibs/libsam3/examples/sam3/streamcs.c create mode 100644 supportlibs/libsam3/examples/sam3/streamss.c diff --git a/supportlibs/libsam3/Makefile b/supportlibs/libsam3/Makefile index fc6f52245..f8d92a090 100644 --- a/supportlibs/libsam3/Makefile +++ b/supportlibs/libsam3/Makefile @@ -16,7 +16,6 @@ OBJS := ${LIB_OBJS} ${TEST_OBJS} LIB := libsam3.a - all: build check check: libsam3-tests @@ -34,8 +33,11 @@ clean: rm -f libsam3-tests ${LIB} ${OBJS} examples/sam3/samtest %.o: %.c Makefile - ${CC} ${CFLAGS} -c $< -o $@ + ${CC} ${CFLAGS} $(LDFLAGS) -c $< -o $@ fmt: find . -name '*.c' -exec clang-format -i {} \; find . -name '*.h' -exec clang-format -i {} \; + +info: + @echo $(AR) diff --git a/supportlibs/libsam3/README.md b/supportlibs/libsam3/README.md index 98dfe4205..cd6b291a5 100644 --- a/supportlibs/libsam3/README.md +++ b/supportlibs/libsam3/README.md @@ -6,7 +6,7 @@ A C library for the [SAM v3 API](https://geti2p.net/en/docs/api/samv3). ## Development Status -Unmaintained, but PRs welcome! +Maintained by idk, PRs are accepted on [I2P gitlab](https://i2pgit.org/i2p-hackers/libsam3)/[I2P gitlab](http://git.idk.i2p/i2p-hackers/libsam3), and on github at the official mirror repository: [i2p/libsam3](https://github.com/i2p/libsam3). ## Usage @@ -16,3 +16,37 @@ Copy the two files from one of the following locations into your codebase: - `src/libsam3a` - Asynchronous implementation. See `examples/` for how to use various parts of the API. + +## Cross-Compiling for Windows from debian: + +Set your cross-compiler up: + +``` sh +export CC=x86_64-w64-mingw32-gcc +export CFLAGS='-Wall -O2 ' +export LDFLAGS='-lmingw32 -lws2_32 -lwsock32 -mwindows' +``` + +and run `make build`. Only libsam3 is available for Windows, libsam3a will be +made available at a later date. +` + +## Linker(Windows) + +When building for Windows remember to set the flags to link to the Winsock and Windows +libraries. + +`-lmingw32 -lws2_32 -lwsock32 -mwindows` + +This may apply when cross-compiling or compiling from Windows with mingw. + +## Cool Projects using libsam3 + +Are you using libsam3 to provide an a cool I2P based feature to your project? Let us know about it(and how +it uses libsam3) and we'll think about adding it here*! + + 1. [Retroshare](https://retroshare.cc) + +*Projects which are listed here must be actively maintained. Those which intentionally violate +the law or the rights of a person or persons directly won't be considered. Neither will obvious +trolling. The maintainer will make the final decision. diff --git a/supportlibs/libsam3/examples/sam3/streamcs.c b/supportlibs/libsam3/examples/sam3/streamcs.c new file mode 100644 index 000000000..25bd22072 --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/streamcs.c @@ -0,0 +1,87 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +#define KEYFILE "streams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + Sam3Connection *conn; + char cmd[1024], destkey[617]; // 616 chars + \0 + // + libsam3_debug = 1; + // + memset(destkey, 0, sizeof(destkey)); + // + if (argc < 2) { + FILE *fl = fopen(KEYFILE, "rb"); + // + if (fl != NULL) { + if (fread(destkey, 616, 1, fl) == 1) { + fclose(fl); + goto ok; + } + fclose(fl); + } + printf("usage: streamc PUBKEY\n"); + return 1; + } else { + if (!sam3CheckValidKeyLength(argv[1])) { + fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1], + strlen(argv[1])); + return 1; + } + strcpy(destkey, argv[1]); + } + // +ok: + printf("creating session...\n"); + // create TRANSIENT session + if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, + SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, + 4, NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + // + printf("connecting...\n"); + if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) { + fprintf(stderr, "FATAL: can't connect: %s\n", ses.error); + sam3CloseSession(&ses); + return 1; + } + // + // now waiting for incoming connection + printf("sending test command...\n"); + if (sam3tcpPrintf(conn->fd, "test\n") < 0) + goto error; + if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) + goto error; + printf("echo: %s\n", cmd); + // + printf("sending quit command...\n"); + if (sam3tcpPrintf(conn->fd, "quit\n") < 0) + goto error; + // + sam3CloseConnection(conn); + sam3CloseSession(&ses); + return 0; +error: + fprintf(stderr, "FATAL: some error occured!\n"); + sam3CloseConnection(conn); + sam3CloseSession(&ses); + return 1; +} diff --git a/supportlibs/libsam3/examples/sam3/streamss.c b/supportlibs/libsam3/examples/sam3/streamss.c new file mode 100644 index 000000000..ffbc974da --- /dev/null +++ b/supportlibs/libsam3/examples/sam3/streamss.c @@ -0,0 +1,72 @@ +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + * + * I2P-Bote: + * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV + * we are the Borg. */ +#include +#include +#include +#include +#include + +#include "../libsam3/libsam3.h" + +#define KEYFILE "streams.key" + +int main(int argc, char *argv[]) { + Sam3Session ses; + Sam3Connection *conn; + FILE *fl; + // + libsam3_debug = 1; + // + printf("creating session...\n"); + // create TRANSIENT session + if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, + SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, + 4, NULL) < 0) { + fprintf(stderr, "FATAL: can't create session\n"); + return 1; + } + // + printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); + if ((fl = fopen(KEYFILE, "wb")) != NULL) { + fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl); + fclose(fl); + } + // + printf("starting stream acceptor...\n"); + if ((conn = sam3StreamAccept(&ses)) == NULL) { + fprintf(stderr, "FATAL: can't accept: %s\n", ses.error); + sam3CloseSession(&ses); + return 1; + } + printf("FROM\n====\n%s\n====\n", conn->destkey); + // + printf("starting main loop...\n"); + for (;;) { + char cmd[256]; + // + if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) + goto error; + printf("cmd: [%s]\n", cmd); + if (strcmp(cmd, "quit") == 0) + break; + // echo command + if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0) + goto error; + } + // + sam3CloseSession(&ses); + unlink(KEYFILE); + return 0; +error: + fprintf(stderr, "FATAL: some error occured!\n"); + sam3CloseSession(&ses); + unlink(KEYFILE); + return 1; +} diff --git a/supportlibs/libsam3/src/libsam3/libsam3.c b/supportlibs/libsam3/src/libsam3/libsam3.c index 476372a0b..5a645806f 100644 --- a/supportlibs/libsam3/src/libsam3/libsam3.c +++ b/supportlibs/libsam3/src/libsam3/libsam3.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -20,16 +19,27 @@ #include #include +#ifdef __MINGW32__ +//#include +#include +#include +#include +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif +#ifndef SHUT_RDWR +#define SHUT_RDWR 2 +#endif +#endif + +#ifdef __unix__ #include +#include #include #include #include #include - -#ifdef WINDOWS_SYS -#include -#endif // WINDOWS_SYS - +#endif //////////////////////////////////////////////////////////////////////////////// int libsam3_debug = 0; @@ -104,11 +114,6 @@ int sam3tcpConnectIP(uint32_t ip, int port) { } } // - // Set this for all outgoing SAM connections. Most SAM commands should be answered rather fast except CREATE SESSION maybe. - // This should be enough to let SAM establish a session. - sam3tcpSetTimeoutSend(fd, 5 * 60 * 1000); - sam3tcpSetTimeoutReceive(fd, 5 * 60 * 1000); - // setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); // if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { @@ -161,13 +166,8 @@ int sam3tcpConnect(const char *hostname, int port, uint32_t *ip) { // <0: error; 0: ok int sam3tcpDisconnect(int fd) { if (fd >= 0) { -#ifndef WINDOWS_SYS // ie UNIX - shutdown(fd, SHUT_RDWR); - return close(fd); -#else - return closesocket(fd); -#endif - + shutdown(fd, SHUT_RDWR); + return close(fd); } // return -1; @@ -823,6 +823,18 @@ int sam3CloseSession(Sam3Session *ses) { return -1; } +int sam3CreateSilentSession(Sam3Session *ses, const char *hostname, int port, + const char *privkey, Sam3SessionType type, + Sam3SigType sigType, const char *params) { + int r = + sam3CreateSession(ses, hostname, port, privkey, type, sigType, params); + if (r != 0) { + return r; + } + ses->silent = true; + return 0; +} + int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, const char *privkey, Sam3SessionType type, Sam3SigType sigType, const char *params) { @@ -840,6 +852,7 @@ int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, memset(ses, 0, sizeof(Sam3Session)); ses->fd = -1; ses->fwd_fd = -1; + ses->silent = false; // if (privkey != NULL && strlen(privkey) < SAM3_PRIVKEY_MIN_SIZE) goto error; @@ -936,8 +949,9 @@ Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) { strcpyerr(ses, "IO_ERROR_SK"); goto error; } - if (sam3tcpPrintf(conn->fd, "STREAM CONNECT ID=%s DESTINATION=%s\n", - ses->channel, destkey) < 0) { + if (sam3tcpPrintf(conn->fd, + "STREAM CONNECT ID=%s DESTINATION=%s SILENT=%s\n", + ses->channel, destkey, checkIsSilent(ses)) < 0) { strcpyerr(ses, "IO_ERROR"); goto error; } @@ -945,16 +959,18 @@ Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) { strcpyerr(ses, "IO_ERROR"); goto error; } - if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR")); - sam3CloseConnectionInternal(conn); - free(conn); - conn = NULL; - } else { - // no error - strcpyerr(ses, NULL); + if (!ses->silent) { + if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR")); + sam3CloseConnectionInternal(conn); + free(conn); + conn = NULL; + } else { + // no error + strcpyerr(ses, NULL); + } } sam3FreeFieldList(rep); if (conn != NULL) { @@ -1002,11 +1018,13 @@ Sam3Connection *sam3StreamAccept(Sam3Session *ses) { strcpyerr(ses, "IO_ERROR_RP"); goto error; } - if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); - goto error; + if (!ses->silent) { + if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { + const char *v = sam3FindField(rep, "RESULT"); + // + strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); + goto error; + } } if (sam3tcpReceiveStr(conn->fd, repstr, sizeof(repstr)) < 0) { strcpyerr(ses, "IO_ERROR_RP1"); @@ -1040,6 +1058,14 @@ Sam3Connection *sam3StreamAccept(Sam3Session *ses) { return NULL; } +const char *checkIsSilent(Sam3Session *ses) { + if (ses->silent == true) { + return "true"; + } else { + return "false"; + } +} + int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) { if (ses != NULL) { SAMFieldList *rep = NULL; @@ -1060,8 +1086,9 @@ int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) { strcpyerr(ses, "IO_ERROR_SK"); goto error; } - if (sam3tcpPrintf(ses->fwd_fd, "STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=true\n", - ses->channel, port, hostname) < 0) { + if (sam3tcpPrintf(ses->fwd_fd, + "STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=%s\n", + ses->channel, port, hostname, checkIsSilent(ses)) < 0) { strcpyerr(ses, "IO_ERROR_PF"); goto error; } diff --git a/supportlibs/libsam3/src/libsam3/libsam3.h b/supportlibs/libsam3/src/libsam3/libsam3.h index 3eb261d89..16942f594 100644 --- a/supportlibs/libsam3/src/libsam3/libsam3.h +++ b/supportlibs/libsam3/src/libsam3/libsam3.h @@ -10,9 +10,19 @@ #ifndef LIBSAM3_H #define LIBSAM3_H +#include #include #include +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 +typedef signed int64 ssize_t; +typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ + #ifdef __cplusplus extern "C" { #endif @@ -138,6 +148,7 @@ typedef struct Sam3Session { int port; // this will be changed to UDP port for DRAM/RAW (can be 0) struct Sam3Connection *connlist; // list of opened connections int fwd_fd; + bool silent; } Sam3Session; typedef struct Sam3Connection { @@ -166,6 +177,22 @@ extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, const char *privkey, Sam3SessionType type, Sam3SigType sigType, const char *params); +/* + * create SAM session with SILENT=True + * pass NULL as hostname for 'localhost' and 0 as port for 7656 + * pass NULL as privkey to create TRANSIENT session + * 'params' can be NULL + * see http://www.i2p2.i2p/i2cp.html#options for common options, + * and http://www.i2p2.i2p/streaming.html#options for STREAM options + * if result<0: error, 'ses' fields are undefined, no need to call + * sam3CloseSession() if result==0: ok, all 'ses' fields are filled + * TODO: don't clear 'error' field on error (and set it to something meaningful) + */ +extern int sam3CreateSilentSession(Sam3Session *ses, const char *hostname, + int port, const char *privkey, + Sam3SessionType type, Sam3SigType sigType, + const char *params); + /* * close SAM session (and all it's connections) * returns <0 on error, 0 on ok @@ -173,6 +200,13 @@ extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, */ extern int sam3CloseSession(Sam3Session *ses); +/* + * check to see if a SAM session is silent and output + * characters for use with sam3tcpPrintf() checkIsSilent + */ + +const char *checkIsSilent(Sam3Session *ses); + /* * Check to make sure that the destination in use is of a valid length, returns * 1 if true and 0 if false. diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.c b/supportlibs/libsam3/src/libsam3a/libsam3a.c index 40921e6ba..e5983b008 100644 --- a/supportlibs/libsam3/src/libsam3a/libsam3a.c +++ b/supportlibs/libsam3/src/libsam3a/libsam3a.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -22,13 +21,28 @@ #include #include +#ifdef __MINGW32__ +//#include +#include +#include +#include +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif +#ifndef SHUT_RDWR +#define SHUT_RDWR 2 +#endif +#endif + +#ifdef __unix__ #include +#include #include #include #include #include #include - +#endif //////////////////////////////////////////////////////////////////////////////// int libsam3a_debug = 0; diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.h b/supportlibs/libsam3/src/libsam3a/libsam3a.h index 4ddec7952..dfd4c0cba 100644 --- a/supportlibs/libsam3/src/libsam3a/libsam3a.h +++ b/supportlibs/libsam3/src/libsam3a/libsam3a.h @@ -18,6 +18,17 @@ #include +#ifdef __MINGW32__ +//#include +#include +#include +#include +//#define SOCK_CLOEXEC O_CLOEXEC +//#define SOCK_NONBLOCK O_NONBLOCK +#define SOCK_CLOEXEC 02000000 +#define SOCK_NONBLOCK FIONBIO +#endif + #ifdef __cplusplus extern "C" { #endif From c869b9757f3ea0de4db955a977d13324728ba546 Mon Sep 17 00:00:00 2001 From: sehraf Date: Sat, 21 Nov 2020 15:00:40 +0100 Subject: [PATCH 059/697] drop BOB code --- libretroshare/src/libretroshare.pro | 5 +- libretroshare/src/pqi/pqissli2pbob.cpp | 52 - libretroshare/src/pqi/pqissli2pbob.h | 52 - libretroshare/src/rsserver/rsinit.cc | 1 - .../src/services/autoproxy/p3i2pbob.cc | 1117 ----------------- .../src/services/autoproxy/p3i2pbob.h | 256 ---- 6 files changed, 1 insertion(+), 1482 deletions(-) delete mode 100644 libretroshare/src/pqi/pqissli2pbob.cpp delete mode 100644 libretroshare/src/pqi/pqissli2pbob.h delete mode 100644 libretroshare/src/services/autoproxy/p3i2pbob.cc delete mode 100644 libretroshare/src/services/autoproxy/p3i2pbob.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index c8f9c4b95..0a8ba44a7 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -394,7 +394,6 @@ HEADERS += pqi/authssl.h \ pqi/pqissl.h \ pqi/pqissllistener.h \ pqi/pqisslpersongrp.h \ - pqi/pqissli2pbob.h \ pqi/pqisslproxy.h \ pqi/pqistore.h \ pqi/pqistreamer.h \ @@ -456,7 +455,7 @@ HEADERS += rsitems/rsitem.h \ rsitems/rsgxsupdateitems.h \ rsitems/rsserviceinfoitems.h \ -HEADERS += services/autoproxy/p3i2pbob.h \ +HEADERS += \ services/rseventsservice.h \ services/autoproxy/rsautoproxymonitor.h \ services/p3msgservice.h \ @@ -560,7 +559,6 @@ SOURCES += pqi/authgpg.cc \ pqi/pqissl.cc \ pqi/pqissllistener.cc \ pqi/pqisslpersongrp.cc \ - pqi/pqissli2pbob.cpp \ pqi/pqisslproxy.cc \ pqi/pqistore.cc \ pqi/pqistreamer.cc \ @@ -618,7 +616,6 @@ SOURCES += serialiser/rsbaseserial.cc \ SOURCES += services/autoproxy/rsautoproxymonitor.cc \ services/rseventsservice.cc \ - services/autoproxy/p3i2pbob.cc \ services/p3msgservice.cc \ services/p3service.cc \ services/p3statusservice.cc \ diff --git a/libretroshare/src/pqi/pqissli2pbob.cpp b/libretroshare/src/pqi/pqissli2pbob.cpp deleted file mode 100644 index 5551ce788..000000000 --- a/libretroshare/src/pqi/pqissli2pbob.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissli2pbob.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#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; -} diff --git a/libretroshare/src/pqi/pqissli2pbob.h b/libretroshare/src/pqi/pqissli2pbob.h deleted file mode 100644 index b1a643a75..000000000 --- a/libretroshare/src/pqi/pqissli2pbob.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissli2pbob.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#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 diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 864099f01..ad39f46a1 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -717,7 +717,6 @@ RsGRouter *rsGRouter = NULL ; # include "rs_upnp/upnphandler_miniupnp.h" #endif // def RS_USE_LIBUPNP -#include "services/autoproxy/p3i2pbob.h" #include "services/autoproxy/p3i2psam3.h" #include "services/autoproxy/rsautoproxymonitor.h" diff --git a/libretroshare/src/services/autoproxy/p3i2pbob.cc b/libretroshare/src/services/autoproxy/p3i2pbob.cc deleted file mode 100644 index f9eb3d9b3..000000000 --- a/libretroshare/src/services/autoproxy/p3i2pbob.cc +++ /dev/null @@ -1,1117 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: p3i2pbob.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include /* for usleep() */ - -#include "p3i2pbob.h" - -#include "pqi/p3peermgr.h" -#include "rsitems/rsconfigitems.h" -#include "util/radix32.h" -#include "util/radix64.h" -#include "util/rsdebug.h" -#include "util/rstime.h" -#include "util/rsprint.h" -#include "util/rsrandom.h" - -static const std::string kConfigKeyBOBEnable = "BOB_ENABLE"; -static const std::string kConfigKeyBOBKey = "BOB_KEY"; -static const std::string kConfigKeyBOBAddr = "BOB_ADDR"; -static const std::string kConfigKeyInLength = "IN_LENGTH"; -static const std::string kConfigKeyInQuantity = "IN_QUANTITY"; -static const std::string kConfigKeyInVariance = "IN_VARIANCE"; -static const std::string kConfigKeyOutLength = "OUT_LENGTH"; -static const std::string kConfigKeyOutQuantity = "OUT_QUANTITY"; -static const std::string kConfigKeyOutVariance = "OUT_VARIANCE"; - -/// Sleep duration for receiving loop in error/no-data case -static const useconds_t sleepTimeRecv = 250; // times 1000 = 250ms -/// Sleep duration for everything else -static const useconds_t sleepTimeWait = 50; // times 1000 = 50ms or 0.05s -static const int sleepFactorDefault = 10; // 0.5s -static const int sleepFactorFast = 1; // 0.05s -static const int sleepFactorSlow = 20; // 1s - -static const rstime_t selfCheckPeroid = 30; - -void doSleep(useconds_t timeToSleepMS) { - rstime::rs_usleep((useconds_t) (timeToSleepMS * 1000)); -} - -p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr) - : RsTickingThread(), p3Config(), - mState(csIdel), mTask(ctIdle), - mStateOld(csIdel), mTaskOld(ctIdle), - mBOBState(bsCleared), mPeerMgr(peerMgr), - mConfigLoaded(false), mSocket(0), - mLastProxyCheck(time(NULL)), - mProcessing(NULL), mLock("I2P-BOB") -{ - // set defaults - mSetting.initDefault(); - - mCommands.clear(); -} - -bool p3I2pBob::isEnabled() -{ - RS_STACK_MUTEX(mLock); - return mSetting.enable; -} - -bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/) -{ - RS_DBG(""); - - // update config - { - RS_STACK_MUTEX(mLock); - if (!mConfigLoaded) { - finalizeSettings_locked(); - mConfigLoaded = true; - } else { - updateSettings_locked(); - } - } - - RS_DBG("config updated"); - - // request keys - // p3I2pBob::stateMachineBOB expects mProcessing to be set therefore - // we create this fake ticket without a callback or data - // ticket gets deleted later by this service - taskTicket *fakeTicket = rsAutoProxyMonitor::getTicket(); - fakeTicket->task = autoProxyTask::receiveKey; - processTaskAsync(fakeTicket); - - RS_DBG("fakeTicket requested"); - - // now start thread - start("I2P-BOB gen key"); - - RS_DBG("thread started"); - - int counter = 0; - // wait for keys - for(;;) { - doSleep(sleepTimeWait * sleepFactorDefault); - - RS_STACK_MUTEX(mLock); - - // wait for tast change - if (mTask != ctRunGetKeys) - break; - - if (++counter > 30) { - RS_DBG4("timeout!"); - return false; - } - } - - RS_DBG("got keys"); - - // stop thread - fullstop(); - - RS_DBG("thread stopped"); - - { - RS_STACK_MUTEX(mLock); - addr = mSetting.address.base32; - } - - RS_DBG4("addr ", addr); - - return true; -} - -void p3I2pBob::processTaskAsync(taskTicket *ticket) -{ - switch (ticket->task) { - case autoProxyTask::start: - case autoProxyTask::stop: - case autoProxyTask::receiveKey: - case autoProxyTask::proxyStatusCheck: - { - RS_STACK_MUTEX(mLock); - mPending.push(ticket); - } - break; - default: - RS_DBG("unknown task"); - rsAutoProxyMonitor::taskError(ticket); - break; - } -} - -void p3I2pBob::processTaskSync(taskTicket *ticket) -{ - bool data = !!ticket->data; - - // check wether we can process the task immediately or have to queue it - switch (ticket->task) { - case autoProxyTask::status: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::status data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // get states - getStates((struct bobStates*)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::getSettings: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::getSettings data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // get settings - getBOBSettings((struct bobSettings *)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::setSettings: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::setSettings data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // set settings - setBOBSettings((struct bobSettings *)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::reloadConfig: - { - RS_STACK_MUTEX(mLock); - updateSettings_locked(); - } - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::getErrorInfo: - if (!data) { - RS_DBG("autoProxyTask::getErrorInfo data is missing"); - rsAutoProxyMonitor::taskError(ticket); - } else { - RS_STACK_MUTEX(mLock); - *(std::string *)ticket->data = mErrorMsg; - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - } - break; - default: - RS_DBG("unknown task"); - rsAutoProxyMonitor::taskError(ticket); - break; - } -} - -bool inline isAnswerOk(const std::string &answer) { - return (answer.compare(0, 2, "OK") == 0); -} - -bool inline isTunnelActiveError(const std::string &answer) { - return answer.compare(0, 22, "ERROR tunnel is active") == 0; -} - -void p3I2pBob::threadTick() -{ - int sleepTime = 0; - { - RS_STACK_MUTEX(mLock); - RS_DBG4("data_tick mState: ", mState, " mTask: ", mTask, " mBOBState: ", mBOBState, " mPending: ", mPending.size()); - } - - sleepTime += stateMachineController(); - sleepTime += stateMachineBOB(); - - sleepTime >>= 1; - - // sleep outisde of lock! - doSleep(sleepTime * sleepTimeWait); -} - -int p3I2pBob::stateMachineBOB() -{ - std::string answer; - bobStateInfo currentState; - - { - RS_STACK_MUTEX(mLock); - if (mBOBState == bsCleared || !mConfigLoaded) { - // we don't have work to do - sleep longer - return sleepFactorSlow; - } - - // get next command - currentState = mCommands[mBOBState]; - } - - // this call can take a while - // do NOT hold the lock - answer = executeCommand(currentState.command); - - // can hold the lock for the rest of the function - RS_STACK_MUTEX(mLock); - - // special state first - if (mBOBState == bsList) { - int counter = 0; - while (answer.find("OK Listing done") == std::string::npos) { - RS_DBG3("stateMachineBOB status check: read loop, counter: ", counter); - answer += recv(); - counter++; - } - - if (answer.find(mTunnelName) == std::string::npos) { - RS_DBG("status check: tunnel down!"); - // signal error - *((bool *)mProcessing->data) = true; - } - - mBOBState = currentState.nextState; - } else if (isAnswerOk(answer)) { - // check for other special states - std::string key; - switch (mBOBState) { - case bsNewkeysN: - key = answer.substr(3, answer.length()-3); - mSetting.address.base32 = i2p::keyToBase32Addr(key); - IndicateConfigChanged(); - break; - case bsGetkeys: - key = answer.substr(3, answer.length()-3); - mSetting.address.privateKey = key; - IndicateConfigChanged(); - break; - default: - break; - } - - // goto next command - mBOBState = currentState.nextState; - } else { - return stateMachineBOB_locked_failure(answer, currentState); - } - return sleepFactorFast; -} - -int p3I2pBob::stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo ¤tState) -{ - // wait in case of active tunnel - // happens when trying to clear a stopping tunnel - if (isTunnelActiveError(answer)) { - return sleepFactorDefault; - } - - RS_DBG("FAILED to run command: ", currentState.command); - RS_DBG("answer: ", answer); - - mErrorMsg.append("FAILED to run command '" + currentState.command + "'" + '\n'); - mErrorMsg.append("reason '" + answer + "'" + '\n'); - - // this error handling needs testing! - mStateOld = mState; - mState = csError; - switch (mBOBState) { - case bsGetnick: - // failed getting nick - // tunnel is probably non existing - case bsClear: - // tunnel is cleared - mBOBState = bsQuit; - break; - case bsStop: - // failed stopping - // tunnel us probably not running - // continue to clearing - mBOBState = bsClear; - break; - case bsQuit: - // this can happen when the - // connection is somehow broken - // just try to disconnect - disconnectI2P(); - mBOBState = bsCleared; - break; - default: - // try to recover - mBOBState = bsGetnick; - break; - } - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController() -{ - RS_STACK_MUTEX(mLock); - - switch (mState) { - case csIdel: - return stateMachineController_locked_idle(); - case csDoConnect: - if (!connectI2P()) { - RS_DBG("doConnect: unable to connect"); - mStateOld = mState; - mState = csError; - mErrorMsg = "unable to connect to BOB port"; - return sleepFactorSlow; - } - - RS_DBG4("doConnect: connected"); - mState = csConnected; - break; - case csConnected: - return stateMachineController_locked_connected(); - case csWaitForBob: - // check connection problems - if (mSocket == 0) { - RS_DBG("waitForBob: conection lost"); - mStateOld = mState; - mState = csError; - mErrorMsg = "connection lost to BOB"; - return sleepFactorDefault; - } - - // check for finished BOB protocol - if (mBOBState == bsCleared) { - // done - RS_DBG4("waitForBob: mBOBState == bsCleared"); - mState = csDoDisconnect; - } - break; - case csDoDisconnect: - if (!disconnectI2P() || mSocket != 0) { - // just in case - RS_DBG("doDisconnect: can't disconnect"); - mStateOld = mState; - mState = csError; - mErrorMsg = "unable to disconnect from BOB"; - return sleepFactorDefault; - } - - RS_DBG4("doDisconnect: disconnected"); - mState = csDisconnected; - break; - case csDisconnected: - return stateMachineController_locked_disconnected(); - case csError: - return stateMachineController_locked_error(); - } - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_idle() -{ - // do some sanity checks - // use asserts becasue these things indicate wrong/broken state machines that need to be fixed ASAP! - assert(mBOBState == bsCleared); - assert(mSocket == 0); - assert(mState == csIdel || mState == csDisconnected); - - controllerTask oldTask = mTask; - // check for new task - if (mProcessing == NULL && !mPending.empty()) { - mProcessing = mPending.front(); - mPending.pop(); - - if (!mSetting.enable && ( - mProcessing->task == autoProxyTask::start || - mProcessing->task == autoProxyTask::stop || - mProcessing->task == autoProxyTask::proxyStatusCheck)) { - // skip since we are not enabled - RS_DBG1("disabled -> skipping ticket"); - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::disabled); - mProcessing = NULL; - } else { - // set states - switch (mProcessing->task) { - case autoProxyTask::start: - mLastProxyCheck = time(NULL); - mTask = ctRunSetUp; - break; - case autoProxyTask::stop: - mTask = ctRunShutDown; - break; - case autoProxyTask::receiveKey: - mTaskOld = mTask; - mTask = ctRunGetKeys; - break; - case autoProxyTask::proxyStatusCheck: - mTaskOld = mTask; - mTask = ctRunCheck; - break; - default: - RS_DBG1("unknown async task"); - rsAutoProxyMonitor::taskError(mProcessing); - mProcessing = NULL; - break; - } - } - - mErrorMsg.clear(); - } - - // periodically check - if (mTask == ctRunSetUp && mLastProxyCheck < time(NULL) - selfCheckPeroid) { - taskTicket *tt = rsAutoProxyMonitor::getTicket(); - tt->task = autoProxyTask::proxyStatusCheck; - tt->data = (void *) new bool; - - *((bool *)tt->data) = false; - - mPending.push(tt); - - mLastProxyCheck = time(NULL); - } - - // wait for new task - if (!!mProcessing) { - // check if task was changed - if (mTask != oldTask) { - mState = csDoConnect; - } else { - // A ticket shall be processed but the state didn't change. - // This means that what ever is requested in the ticket - // was requested before already. - // -> set mState to csDisconnected to answer the ticket - mState = csDisconnected; - } - return sleepFactorFast; - } - - return sleepFactorSlow; -} - -int p3I2pBob::stateMachineController_locked_connected() -{ - // set proper bob state - switch (mTask) { - case ctRunSetUp: - // when we have a key use it for server tunnel! - if(mSetting.address.privateKey.empty()) { - RS_DBG4("setting mBOBState = setnickC"); - mBOBState = bsSetnickC; - } else { - RS_DBG4("setting mBOBState = setnickS"); - mBOBState = bsSetnickS; - } - break; - case ctRunShutDown: - // shut down existing tunnel - RS_DBG4("setting mBOBState = getnick"); - mBOBState = bsGetnick; - break; - case ctRunCheck: - RS_DBG4("setting mBOBState = list"); - mBOBState = bsList; - break; - case ctRunGetKeys: - RS_DBG4("setting mBOBState = setnickN"); - mBOBState = bsSetnickN; - break; - case ctIdle: - RS_DBG("task is idle. This should not happen!"); - break; - } - - mState = csWaitForBob; - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_disconnected() -{ - // check if we had an error - bool errorHappened = (mStateOld == csError); - - if(errorHappened) { - // reset old state - mStateOld = csIdel; - RS_DBG("error during process!"); - } - - // answer ticket - controllerState newState = csIdel; - switch (mTask) { - case ctRunSetUp: - if (errorHappened) { - rsAutoProxyMonitor::taskError(mProcessing); - // switch to error - newState = csError; - } else { - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::online); - } - break; - case ctRunShutDown: - // don't care about error here - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::offline); - break; - case ctRunCheck: - // get result and delete dummy ticket - errorHappened |= *((bool *)mProcessing->data); - delete (bool *)mProcessing->data; - delete mProcessing; - - // restore old task - mTask = mTaskOld; - - if (!errorHappened) { - RS_DBG4("run check result: ok"); - break; - } - // switch to error - newState = csError; - RS_DBG("run check result: error"); - mErrorMsg = "Connection check failed. Will try to restart tunnel."; - - break; - case ctRunGetKeys: - if (!errorHappened) { - // rebuild commands - updateSettings_locked(); - - if (mProcessing->data) - *((struct bobSettings *)mProcessing->data) = mSetting; - - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::ok); - } else { - rsAutoProxyMonitor::taskError(mProcessing); - // switch to error - newState = csError; - } - - // restore old task - mTask = mTaskOld; - break; - case ctIdle: - RS_DBG("task is idle. This should not happen!"); - rsAutoProxyMonitor::taskError(mProcessing); - } - mProcessing = NULL; - mState = newState; - - if (newState == csError) - mLastProxyCheck = time(NULL); - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_error() -{ - // wait for bob protocoll - if (mBOBState != bsCleared) { - RS_DBG4("waiting for BOB"); - return sleepFactorFast; - } - -#if 0 - RS_DBG4("stateMachineController_locked_error: mProcessing: ", (mProcessing ? "not null" : "null")); -#endif - - // try to finish ticket - if (mProcessing) { - switch (mTask) { - case ctRunCheck: - // connection check failed at some point - RS_DBG("failed to check proxy status (it's likely dead)!"); - *((bool *)mProcessing->data) = true; - mState = csDoDisconnect; - mStateOld = csIdel; - // keep the error message - break; - case ctRunShutDown: - // not a big deal though - RS_DBG("failed to shut down tunnel (it's likely dead though)!"); - mState = csDoDisconnect; - mStateOld = csIdel; - mErrorMsg.clear(); - break; - case ctIdle: - // should not happen but we need to deal with it - // this will produce some error messages in the log and finish the task (marked as failed) - RS_DBG("task is idle. This should not happen!"); - mState = csDoDisconnect; - mStateOld = csIdel; - mErrorMsg.clear(); - break; - case ctRunGetKeys: - case ctRunSetUp: - RS_DBG("failed to receive key / start up"); - mStateOld = csError; - mState = csDoDisconnect; - // keep the error message - break; - } - return sleepFactorFast; - } - - // periodically retry - if (mLastProxyCheck < time(NULL) - (selfCheckPeroid >> 1) && mTask == ctRunSetUp) { - RS_DBG("retrying"); - - mLastProxyCheck = time(NULL); - mErrorMsg.clear(); - - // create fake ticket - taskTicket *tt = rsAutoProxyMonitor::getTicket(); - tt->task = autoProxyTask::start; - mPending.push(tt); - } - - // check for new tickets - if (!mPending.empty()) { - RS_DBG4("processing new ticket"); - - // reset and try new task - mTask = ctIdle; - mState = csIdel; - return sleepFactorFast; - } - - return sleepFactorDefault; -} - -RsSerialiser *p3I2pBob::setupSerialiser() -{ - RsSerialiser* rsSerialiser = new RsSerialiser(); - rsSerialiser->addSerialType(new RsGeneralConfigSerialiser()); - - return rsSerialiser; -} - -#define addKVS(_vitem, _kv, _key, _value) \ - _kv.key = _key;\ - _kv.value = _value;\ - _vitem->tlvkvs.pairs.push_back(_kv); - -#define addKVSInt(_vitem, _kv, _key, _value) \ - _kv.key = _key;\ - rs_sprintf(_kv.value, "%d", _value);\ - _vitem->tlvkvs.pairs.push_back(_kv); - -bool p3I2pBob::saveList(bool &cleanup, std::list &lst) -{ - RS_DBG4(""); - - cleanup = true; - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet; - RsTlvKeyValue kv; - - RS_STACK_MUTEX(mLock); - addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enable ? "TRUE" : "FALSE") - addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.address.privateKey) - addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.address.base32) - addKVSInt(vitem, kv, kConfigKeyInLength, mSetting.inLength) - addKVSInt(vitem, kv, kConfigKeyInQuantity, mSetting.inQuantity) - addKVSInt(vitem, kv, kConfigKeyInVariance, mSetting.inVariance) - addKVSInt(vitem, kv, kConfigKeyOutLength, mSetting.outLength) - addKVSInt(vitem, kv, kConfigKeyOutQuantity, mSetting.outQuantity) - addKVSInt(vitem, kv, kConfigKeyOutVariance, mSetting.outVariance) - - lst.push_back(vitem); - - return true; -} - -#undef addKVS -#undef addKVSUInt - -#define getKVSUInt(_kit, _key, _value) \ - else if (_kit->key == _key) {\ - std::istringstream is(_kit->value);\ - int tmp;\ - is >> tmp;\ - _value = (int8_t)tmp;\ - } - -bool p3I2pBob::loadList(std::list &load) -{ - RS_DBG4(""); - - for(std::list::const_iterator it = load.begin(); it!=load.end(); ++it) { - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - if(vitem != NULL) { - RS_STACK_MUTEX(mLock); - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) { - if (kit->key == kConfigKeyBOBEnable) - mSetting.enable = kit->value == "TRUE"; - else if (kit->key == kConfigKeyBOBKey) - mSetting.address.privateKey = kit->value; - else if (kit->key == kConfigKeyBOBAddr) - mSetting.address.base32 = kit->value; - getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength) - getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity) - getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance) - getKVSUInt(kit, kConfigKeyOutLength, mSetting.outLength) - getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity) - getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance) - else - RS_DBG("unknown key: ", kit->key); - } - } - delete vitem; - } - - RS_STACK_MUTEX(mLock); - finalizeSettings_locked(); - mConfigLoaded = true; - - return true; -} - -#undef getKVSUInt - -void p3I2pBob::getBOBSettings(bobSettings *settings) -{ - if (settings == NULL) - return; - - RS_STACK_MUTEX(mLock); - *settings = mSetting; - -} - -void p3I2pBob::setBOBSettings(const bobSettings *settings) -{ - if (settings == NULL) - return; - - RS_STACK_MUTEX(mLock); - mSetting = *settings; - - IndicateConfigChanged(); - - // Note: - // We don't take care of updating a running BOB session here - // This can be done manually by stoping and restarting the session - - // Note2: - // In case there is no config yet to load - // finalize settings here instead - if (!mConfigLoaded) { - finalizeSettings_locked(); - mConfigLoaded = true; - } else { - updateSettings_locked(); - } -} - -void p3I2pBob::getStates(bobStates *bs) -{ - if (bs == NULL) - return; - - RS_STACK_MUTEX(mLock); - bs->cs = mState; - bs->ct = mTask; - bs->bs = mBOBState; - bs->tunnelName = mTunnelName; -} - -std::string p3I2pBob::executeCommand(const std::string &command) -{ - RS_DBG4("running: ", command); - - std::string copy = command; - copy.push_back('\n'); - - // send command - // there is only one thread that touches mSocket - no need for a lock - ::send(mSocket, copy.c_str(), copy.size(), 0); - - // receive answer (trailing new line is already removed!) - std::string ans = recv(); - - RS_DBG4("answer: ", ans); - - return ans; -} - -bool p3I2pBob::connectI2P() -{ - // there is only one thread that touches mSocket - no need for a lock - - if (mSocket != 0) { - RS_DBG("mSocket != 0"); - return false; - } - - // create socket - mSocket = unix_socket(PF_INET, SOCK_STREAM, 0); - if (mSocket < 0) - { - RS_DBG("Failed to open socket! Socket Error: ", socket_errorType(errno)); - return false; - } - - // connect - int err = unix_connect(mSocket, mI2PProxyAddr); - if (err != 0) { - RS_DBG("Failed to connect to BOB! Socket Error: ", socket_errorType(errno)); - return false; - } - - // receive hello msg - recv(); - - RS_DBG4("done"); - return true; -} - -bool p3I2pBob::disconnectI2P() -{ - // there is only one thread that touches mSocket - no need for a lock - - if (mSocket == 0) { - RS_DBG("mSocket == 0"); - return true; - } - - int err = unix_close(mSocket); - if (err != 0) { - RS_DBG("Failed to close socket! Socket Error: ", socket_errorType(errno)); - return false; - } - - RS_DBG4("done"); - mSocket = 0; - return true; -} - -std::string toString(const std::string &a, const int b) { - std::ostringstream oss; - oss << b; - return a + oss.str();; -} - -std::string toString(const std::string &a, const uint16_t b) { - return toString(a, (int)b); -} - -std::string toString(const std::string &a, const int8_t b) { - return toString(a, (int)b); -} - -void p3I2pBob::finalizeSettings_locked() -{ - RS_DBG4(""); - - sockaddr_storage_clear(mI2PProxyAddr); - // get i2p proxy addr - sockaddr_storage proxy; - mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy); - - // overwrite port to bob port - sockaddr_storage_setipv4(mI2PProxyAddr, (sockaddr_in*)&proxy); - sockaddr_storage_setport(mI2PProxyAddr, 2827); - - RS_DBG4("using ", mI2PProxyAddr); - RS_DBG4("using ", mSetting.address.base32); - - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - // setup commands - // new lines are appended later! - - // generate 8 characater long random suffix for name - constexpr size_t len = 8; - const std::string location = RsRandom::alphaNumeric(len); - RS_DBG4("using suffix ", location); - mTunnelName = "RetroShare-" + location; - - const std::string setnick = "setnick RetroShare-" + location; - const std::string getnick = "getnick RetroShare-" + location; - const std::string newkeys = "newkeys"; - const std::string getkeys = "getkeys"; - const std::string setkeys = "setkeys " + mSetting.address.privateKey; - const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy); - const std::string inport = toString("inport ", sockaddr_storage_port(proxy)); - const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr); - const std::string outport = toString("outport ", sockaddr_storage_port(ps.localaddr)); - // length - const std::string inlength = toString("option inbound.length=", mSetting.inLength); - const std::string outlength = toString("option outbound.length=", mSetting.outLength); - // variance - const std::string invariance = toString("option inbound.lengthVariance=", mSetting.inVariance); - const std::string outvariance= toString("option outbound.lengthVariance=", mSetting.outVariance); - // quantity - const std::string inquantity = toString("option inbound.quantity=", mSetting.inQuantity); - const std::string outquantity= toString("option outbound.quantity=", mSetting.outQuantity); - const std::string quiet = "quiet true"; - const std::string start = "start"; - const std::string stop = "stop"; - const std::string clear = "clear"; - const std::string list = "list"; - const std::string quit = "quit"; - - // setup state machine - - // start chain - // -> A: server and client tunnel - mCommands[bsSetnickS] = {setnick, bsSetkeys}; - mCommands[bsSetkeys] = {setkeys, bsOuthost}; - mCommands[bsOuthost] = {outhost, bsOutport}; - mCommands[bsOutport] = {outport, bsInhost}; - // -> B: only client tunnel - mCommands[bsSetnickC] = {setnick, bsNewkeysC}; - mCommands[bsNewkeysC] = {newkeys, bsInhost}; - // -> both - mCommands[bsInhost] = {inhost, bsInport}; - mCommands[bsInport] = {inport, bsInlength}; - mCommands[bsInlength] = {inlength, bsOutlength}; - mCommands[bsOutlength] = {outlength, bsInvariance}; - mCommands[bsInvariance] = {invariance, bsOutvariance}; - mCommands[bsOutvariance]= {outvariance,bsInquantity}; - mCommands[bsInquantity] = {inquantity, bsOutquantity}; - mCommands[bsOutquantity]= {outquantity,bsQuiet}; - mCommands[bsQuiet] = {quiet, bsStart}; - mCommands[bsStart] = {start, bsQuit}; - mCommands[bsQuit] = {quit, bsCleared}; - - // stop chain - mCommands[bsGetnick] = {getnick, bsStop}; - mCommands[bsStop] = {stop, bsClear}; - mCommands[bsClear] = {clear, bsQuit}; - - // getkeys chain - mCommands[bsSetnickN] = {setnick, bsNewkeysN}; - mCommands[bsNewkeysN] = {newkeys, bsGetkeys}; - mCommands[bsGetkeys] = {getkeys, bsClear}; - - // list chain - mCommands[bsList] = {list, bsQuit}; -} - -void p3I2pBob::updateSettings_locked() -{ - RS_DBG4(""); - - sockaddr_storage proxy; - mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy); - - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - const std::string setkeys = "setkeys " + mSetting.address.privateKey; - const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy); - const std::string inport = toString("inport ", sockaddr_storage_port(proxy)); - const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr); - const std::string outport = toString("outport ", sockaddr_storage_port(ps.localaddr)); - - // length - const std::string inlength = toString("option inbound.length=", mSetting.inLength); - const std::string outlength = toString("option outbound.length=", mSetting.outLength); - // variance - const std::string invariance = toString("option inbound.lengthVariance=", mSetting.inVariance); - const std::string outvariance= toString("option outbound.lengthVariance=", mSetting.outVariance); - // quantity - const std::string inquantity = toString("option inbound.quantity=", mSetting.inQuantity); - const std::string outquantity= toString("option outbound.quantity=", mSetting.outQuantity); - - mCommands[bsSetkeys] = {setkeys, bsOuthost}; - mCommands[bsOuthost] = {outhost, bsOutport}; - mCommands[bsOutport] = {outport, bsInhost}; - mCommands[bsInhost] = {inhost, bsInport}; - mCommands[bsInport] = {inport, bsInlength}; - - mCommands[bsInlength] = {inlength, bsOutlength}; - mCommands[bsOutlength] = {outlength, bsInvariance}; - mCommands[bsInvariance] = {invariance, bsOutvariance}; - mCommands[bsOutvariance]= {outvariance,bsInquantity}; - mCommands[bsInquantity] = {inquantity, bsOutquantity}; - mCommands[bsOutquantity]= {outquantity,bsQuiet}; -} - -std::string p3I2pBob::recv() -{ - // BOB works line based - // -> \n indicates and of the line - - constexpr uint16_t bufferSize = 128; - char buffer[bufferSize]; - - std::string ans; - uint16_t retry = 10; - - do { - memset(buffer, 0, bufferSize); - - // peek at data - auto length = ::recv(mSocket, buffer, bufferSize, MSG_PEEK); - if (length <= 0) { - if (length < 0) { - // error - perror(__PRETTY_FUNCTION__); - } - retry--; - doSleep(sleepTimeRecv); - continue; - } - - // at least one byte was read - - // search for new line - auto bufferStr = std::string(buffer); - size_t pos = bufferStr.find('\n'); - - if (pos == std::string::npos) { - // no new line found -> more to read - - // sanity check - if (length != bufferSize) { - // expectation: a full buffer was peeked) - RS_DBG1("peeked less than bufferSize but also didn't found a new line character"); - } - // this should never happen - assert(length <= bufferSize); - } else { - // new line found -> end of message - - // calculate how much there is to read, read the \n, too! - length = pos + 1; - - // end loop - retry = 0; - } - - // now read for real - memset(buffer, 0, bufferSize); - length = ::recv(mSocket, buffer, length, 0); - bufferStr = std::string(buffer); - ans.append(bufferStr); - } while(retry > 0); - - return ans; -} diff --git a/libretroshare/src/services/autoproxy/p3i2pbob.h b/libretroshare/src/services/autoproxy/p3i2pbob.h deleted file mode 100644 index 29bcbcb61..000000000 --- a/libretroshare/src/services/autoproxy/p3i2pbob.h +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: p3i2pbob.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3I2PBOB_H -#define P3I2PBOB_H - -#include -#include -#include -#include "util/rstime.h" -#ifndef WINDOWS_SYS - #include -#endif - -#include "pqi/p3cfgmgr.h" -#include "services/autoproxy/rsautoproxymonitor.h" -#include "util/rsthreads.h" -#include "util/i2pcommon.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 random 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 machine 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 : i2p::settings {}; - -/// -/// \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: - explicit p3I2pBob(p3PeerMgr *peerMgr); - - // autoProxyService interface -public: - bool isEnabled(); - bool initialSetup(std::string &addr, uint16_t &); - void processTaskAsync(taskTicket *ticket); - void processTaskSync(taskTicket *ticket); - - void threadTick() override; /// @see RsTickingThread - -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 &lst); - bool loadList(std::list &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; - rstime_t mLastProxyCheck; - sockaddr_storage mI2PProxyAddr; - std::map mCommands; - std::string mErrorMsg; - std::string mTunnelName; - - std::queue mPending; - taskTicket *mProcessing; - - // mutex - RsMutex mLock; -}; - -#endif // P3I2PBOB_H From 1fa16aa6eb93e8a254a7b1087ff35b19df1b5916 Mon Sep 17 00:00:00 2001 From: sehraf Date: Sun, 22 Nov 2020 11:52:48 +0100 Subject: [PATCH 060/697] SAM3: fix double free --- libretroshare/src/pqi/pqissli2psam3.cpp | 3 +- .../src/services/autoproxy/p3i2psam3.cpp | 62 +++++++++++++++---- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/pqi/pqissli2psam3.cpp b/libretroshare/src/pqi/pqissli2psam3.cpp index 41087a893..1e0f5d433 100644 --- a/libretroshare/src/pqi/pqissli2psam3.cpp +++ b/libretroshare/src/pqi/pqissli2psam3.cpp @@ -124,7 +124,8 @@ int pqissli2psam3::net_internal_close(int fd) // now to the actuall closing int ret = pqissl::net_internal_close(fd); - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::closeConnection, this, mConn), + + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::closeConnection, this, mConn); // finally cleanup mConn = 0; diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index ed2b51ccd..0a0121df0 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -76,6 +76,13 @@ bool p3I2pSam3::initialSetup(std::string &addr, uint16_t &/*port*/) i2p::getKeyTypes(mSetting.address.publicKey, s, c); RS_INFO("received key", s, c); + // sanity check + auto pub = i2p::publicKeyFromPrivate(mSetting.address.privateKey); + if (pub != mSetting.address.publicKey) { + RS_WARN("public key does not match private key! fixing ..."); + mSetting.address.privateKey = pub; + } + IndicateConfigChanged(); } @@ -482,7 +489,7 @@ bool p3I2pSam3::startSession() stopSession(); } - auto session = new Sam3Session(); + auto session = (Sam3Session*)rs_malloc(sizeof (Sam3Session)); // add nick paramsStr.append("inbound.nickname=" + nick); // leading space is already there @@ -572,7 +579,7 @@ void p3I2pSam3::stopSession() RS_STACK_MUTEX(mLockSam3Access); sam3CloseSession(mSetting.session); - delete mSetting.session; + free(mSetting.session); mSetting.session = nullptr; mState = samStatus::samState::offline; @@ -687,46 +694,75 @@ void p3I2pSam3::establishConnection(taskTicket *ticket) void p3I2pSam3::closeConnection(taskTicket *ticket) { - Sam3Connection *con = static_cast(ticket->data); + Sam3Connection *conn = static_cast(ticket->data); if (mState == samStatus::samState::offline || !mSetting.session) { - // no session found, sam was likel stopped + // no session found, sam was likely stopped + RS_DBG2("no session found"); + + auto it = std::find(mInvalidConnections.begin(), mInvalidConnections.end(), conn); + if (it != mInvalidConnections.end()) { + // this is the expected case + mInvalidConnections.erase(it); + } else { + // this is unexpected but not a big deal, just warn + RS_WARN("cannot find connection in mInvalidConnections"); + + it = std::find(mValidConnections.begin(), mValidConnections.end(), conn); + if (it != mValidConnections.end()) { + mValidConnections.erase(it); + + // now it is getting even weirder, still not a big deal, just warn + RS_WARN("found connection in mValidConnections"); + } + } + + // when libsam3 has already handled closing of the connection - which should be the case here - the memory has been freed already (-> pointer is invalid) + conn = nullptr; } else { RS_STACK_MUTEX(mLock); bool callClose = true; // search in current connections - auto it = std::find(mValidConnections.begin(), mValidConnections.end(), con); + auto it = std::find(mValidConnections.begin(), mValidConnections.end(), conn); if (it != mValidConnections.end()) { + RS_DBG2("found valid connection"); mValidConnections.erase(it); } else { // search in old connections - it = std::find(mInvalidConnections.begin(), mInvalidConnections.end(), con); + it = std::find(mInvalidConnections.begin(), mInvalidConnections.end(), conn); if (it != mInvalidConnections.end()) { // old connection, just ignore. *should* be freed already + mInvalidConnections.erase(it); + + RS_DBG2("found old (invalid) connection"); + callClose = false; - con = nullptr; + conn = nullptr; } else { // weird RS_WARN("could'n find connection!"); // best thing we can do here callClose = false; - con = nullptr; + conn = nullptr; } } if (callClose) { + RS_DBG2("closing connection"); + RS_STACK_MUTEX(mLockSam3Access); - sam3CloseConnection(con); - con = nullptr; // freed by above call + sam3CloseConnection(conn); + conn = nullptr; // freed by above call } } - if (con) { - delete con; - con = nullptr; + if (conn) { + free(conn); + conn = nullptr; } + ticket->data = nullptr; rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); return; From 36e238951f3d3d1063364a8f4ad15f82cfe19de2 Mon Sep 17 00:00:00 2001 From: sehraf Date: Thu, 26 Nov 2020 21:05:25 +0100 Subject: [PATCH 061/697] update p3i2psam --- .../src/services/autoproxy/p3i2psam3.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index 0a0121df0..97e8b392c 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -74,19 +74,26 @@ bool p3I2pSam3::initialSetup(std::string &addr, uint16_t &/*port*/) } else { std::string s, c; i2p::getKeyTypes(mSetting.address.publicKey, s, c); - RS_INFO("received key", s, c); + RS_INFO("received key ", s, " ", c); + RS_INFO("public key: ", mSetting.address.publicKey); + RS_INFO("private key: ", mSetting.address.privateKey); + RS_INFO("address: ", i2p::keyToBase32Addr(mSetting.address.publicKey)); // sanity check auto pub = i2p::publicKeyFromPrivate(mSetting.address.privateKey); + RS_INFO("pub key derived: ", pub); + RS_INFO("address: ", i2p::keyToBase32Addr(pub)); if (pub != mSetting.address.publicKey) { RS_WARN("public key does not match private key! fixing ..."); - mSetting.address.privateKey = pub; + mSetting.address.publicKey = pub; } + mSetting.address.base32 = i2p::keyToBase32Addr(mSetting.address.publicKey); + IndicateConfigChanged(); } - addr = mSetting.address.base32 = i2p::keyToBase32Addr(mSetting.address.publicKey); + addr = mSetting.address.base32; return true; } @@ -527,9 +534,9 @@ bool p3I2pSam3::startSession() mSetting.address.base32 = i2p::keyToBase32Addr(session->pubkey); // do not overwrite the private key, if any!! - RS_DBG1("nick:", nick, "address:", mSetting.address.base32); - RS_DBG2(" myDestination.pub ", mSetting.address.publicKey); - RS_DBG2(" myDestination.priv", mSetting.address.privateKey); + RS_DBG1("nick: ", nick, " address: ", mSetting.address.base32); + RS_DBG2(" myDestination.pub ", mSetting.address.publicKey); + RS_DBG2(" myDestination.priv ", mSetting.address.privateKey); return true; } @@ -555,7 +562,6 @@ bool p3I2pSam3::startForwarding() RS_STACK_MUTEX(mLockSam3Access); int ret = sam3StreamForward(mSetting.session, sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr)); - if (ret < 0) { RS_DBG("forward failed, due to", mSetting.session->error); return false; @@ -639,8 +645,8 @@ void p3I2pSam3::lookupKey(taskTicket *ticket) int ret = sam3NameLookup(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, addr->base32.c_str()); if (ret < 0) { // get error - RS_DBG("key:", addr->base32); - RS_DBG("got error:", ss.error); + RS_DBG("key: ", addr->base32); + RS_DBG("got error: ", ss.error); rsAutoProxyMonitor::taskError(ticket); } else { addr->publicKey = ss.destkey; From 719adaae9bf7c6ce31aad74b059d1dc501f40565 Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 27 Nov 2020 15:24:44 +0100 Subject: [PATCH 062/697] update i2psam3 --- libretroshare/src/services/autoproxy/p3i2psam3.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index 97e8b392c..47123328a 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -64,12 +64,12 @@ bool p3I2pSam3::initialSetup(std::string &addr, uint16_t &/*port*/) RS_STACK_MUTEX(mLock); if (!mSetting.address.publicKey.empty() || !mSetting.address.privateKey.empty()) - RS_DBG("overwriting keys!"); + RS_WARN("overwriting keys!"); bool success = generateKey(mSetting.address.publicKey, mSetting.address.privateKey); if (!success) { - RS_DBG("failed to retrieve keys"); + RS_WARN("failed to retrieve keys"); return false; } else { std::string s, c; @@ -613,14 +613,14 @@ bool p3I2pSam3::generateKey(std::string &pub, std::string &priv) Sam3Session ss; if (0 > sam3GenerateKeys(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, Sam3SigType::EdDSA_SHA512_Ed25519)) { - RS_DBG("got error:", ss.error); + RS_DBG("got error: ", ss.error); return false; } pub = std::string(ss.pubkey); priv = std::string(ss.privkey); - RS_DBG2("publuc key / address", pub); - RS_DBG2("private key", priv); + RS_DBG2("publuc key / address ", pub); + RS_DBG2("private key ", priv); return true; } From 59fa96eb5ff6d225ee5548d2017a703f20c3794d Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 27 Nov 2020 15:44:49 +0100 Subject: [PATCH 063/697] remove own copy of libsam3 --- supportlibs/libsam3/Makefile | 43 - supportlibs/libsam3/README.md | 52 - supportlibs/libsam3/examples/libsam3 | 1 - supportlibs/libsam3/examples/sam3/README.md | 26 - supportlibs/libsam3/examples/sam3/dgramc.c | 116 -- supportlibs/libsam3/examples/sam3/dgrams.c | 113 -- .../libsam3/examples/sam3/namelookup.c | 43 - supportlibs/libsam3/examples/sam3/samtest.c | 51 - supportlibs/libsam3/examples/sam3/streamc.c | 87 - supportlibs/libsam3/examples/sam3/streamcs.c | 87 - supportlibs/libsam3/examples/sam3/streams.c | 72 - supportlibs/libsam3/examples/sam3/streamss.c | 72 - supportlibs/libsam3/examples/sam3a/test00.c | 178 -- supportlibs/libsam3/examples/sam3a/test_sc.c | 205 -- supportlibs/libsam3/examples/sam3a/test_ss.c | 236 --- supportlibs/libsam3/src/ext/tinytest.c | 466 ----- supportlibs/libsam3/src/ext/tinytest.h | 104 - supportlibs/libsam3/src/ext/tinytest_macros.h | 219 -- supportlibs/libsam3/src/libsam3/libsam3.c | 1345 ------------- supportlibs/libsam3/src/libsam3/libsam3.h | 314 --- supportlibs/libsam3/src/libsam3a/libsam3a.c | 1771 ----------------- supportlibs/libsam3/src/libsam3a/libsam3a.h | 372 ---- supportlibs/libsam3/test/libsam3/test_b32.c | 51 - supportlibs/libsam3/test/test.c | 12 - 24 files changed, 6036 deletions(-) delete mode 100644 supportlibs/libsam3/Makefile delete mode 100644 supportlibs/libsam3/README.md delete mode 120000 supportlibs/libsam3/examples/libsam3 delete mode 100644 supportlibs/libsam3/examples/sam3/README.md delete mode 100644 supportlibs/libsam3/examples/sam3/dgramc.c delete mode 100644 supportlibs/libsam3/examples/sam3/dgrams.c delete mode 100644 supportlibs/libsam3/examples/sam3/namelookup.c delete mode 100644 supportlibs/libsam3/examples/sam3/samtest.c delete mode 100644 supportlibs/libsam3/examples/sam3/streamc.c delete mode 100644 supportlibs/libsam3/examples/sam3/streamcs.c delete mode 100644 supportlibs/libsam3/examples/sam3/streams.c delete mode 100644 supportlibs/libsam3/examples/sam3/streamss.c delete mode 100644 supportlibs/libsam3/examples/sam3a/test00.c delete mode 100644 supportlibs/libsam3/examples/sam3a/test_sc.c delete mode 100644 supportlibs/libsam3/examples/sam3a/test_ss.c delete mode 100644 supportlibs/libsam3/src/ext/tinytest.c delete mode 100644 supportlibs/libsam3/src/ext/tinytest.h delete mode 100644 supportlibs/libsam3/src/ext/tinytest_macros.h delete mode 100644 supportlibs/libsam3/src/libsam3/libsam3.c delete mode 100644 supportlibs/libsam3/src/libsam3/libsam3.h delete mode 100644 supportlibs/libsam3/src/libsam3a/libsam3a.c delete mode 100644 supportlibs/libsam3/src/libsam3a/libsam3a.h delete mode 100644 supportlibs/libsam3/test/libsam3/test_b32.c delete mode 100644 supportlibs/libsam3/test/test.c diff --git a/supportlibs/libsam3/Makefile b/supportlibs/libsam3/Makefile deleted file mode 100644 index f8d92a090..000000000 --- a/supportlibs/libsam3/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -CFLAGS := -Wall -g -O2 -std=gnu99 - -SRCS := \ - src/libsam3/libsam3.c \ - src/libsam3a/libsam3a.c - -TESTS := \ - src/ext/tinytest.c \ - test/test.c \ - test/libsam3/test_b32.c - -LIB_OBJS := ${SRCS:.c=.o} -TEST_OBJS := ${TESTS:.c=.o} - -OBJS := ${LIB_OBJS} ${TEST_OBJS} - -LIB := libsam3.a - -all: build check - -check: libsam3-tests - ./libsam3-tests - -build: ${LIB} - -${LIB}: ${LIB_OBJS} - ${AR} -sr ${LIB} ${LIB_OBJS} - -libsam3-tests: ${TEST_OBJS} ${LIB} - ${CC} $^ -o $@ - -clean: - rm -f libsam3-tests ${LIB} ${OBJS} examples/sam3/samtest - -%.o: %.c Makefile - ${CC} ${CFLAGS} $(LDFLAGS) -c $< -o $@ - -fmt: - find . -name '*.c' -exec clang-format -i {} \; - find . -name '*.h' -exec clang-format -i {} \; - -info: - @echo $(AR) diff --git a/supportlibs/libsam3/README.md b/supportlibs/libsam3/README.md deleted file mode 100644 index cd6b291a5..000000000 --- a/supportlibs/libsam3/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# libsam3 - -[![Build Status](https://travis-ci.org/i2p/libsam3.svg?branch=master)](https://travis-ci.org/i2p/libsam3) - -A C library for the [SAM v3 API](https://geti2p.net/en/docs/api/samv3). - -## Development Status - -Maintained by idk, PRs are accepted on [I2P gitlab](https://i2pgit.org/i2p-hackers/libsam3)/[I2P gitlab](http://git.idk.i2p/i2p-hackers/libsam3), and on github at the official mirror repository: [i2p/libsam3](https://github.com/i2p/libsam3). - -## Usage - -Copy the two files from one of the following locations into your codebase: - -- `src/libsam3` - Synchronous implementation. -- `src/libsam3a` - Asynchronous implementation. - -See `examples/` for how to use various parts of the API. - -## Cross-Compiling for Windows from debian: - -Set your cross-compiler up: - -``` sh -export CC=x86_64-w64-mingw32-gcc -export CFLAGS='-Wall -O2 ' -export LDFLAGS='-lmingw32 -lws2_32 -lwsock32 -mwindows' -``` - -and run `make build`. Only libsam3 is available for Windows, libsam3a will be -made available at a later date. -` - -## Linker(Windows) - -When building for Windows remember to set the flags to link to the Winsock and Windows -libraries. - -`-lmingw32 -lws2_32 -lwsock32 -mwindows` - -This may apply when cross-compiling or compiling from Windows with mingw. - -## Cool Projects using libsam3 - -Are you using libsam3 to provide an a cool I2P based feature to your project? Let us know about it(and how -it uses libsam3) and we'll think about adding it here*! - - 1. [Retroshare](https://retroshare.cc) - -*Projects which are listed here must be actively maintained. Those which intentionally violate -the law or the rights of a person or persons directly won't be considered. Neither will obvious -trolling. The maintainer will make the final decision. diff --git a/supportlibs/libsam3/examples/libsam3 b/supportlibs/libsam3/examples/libsam3 deleted file mode 120000 index 136138896..000000000 --- a/supportlibs/libsam3/examples/libsam3 +++ /dev/null @@ -1 +0,0 @@ -../src/libsam3 \ No newline at end of file diff --git a/supportlibs/libsam3/examples/sam3/README.md b/supportlibs/libsam3/examples/sam3/README.md deleted file mode 100644 index 1228e4984..000000000 --- a/supportlibs/libsam3/examples/sam3/README.md +++ /dev/null @@ -1,26 +0,0 @@ -Examples -======== - -These examples show various ways of using libsam3 to enable i2p in your -application, and are also useful in other ways. If you implement an i2p -application library in another language, making variants basic tools wouldn't be -the worst way to make sure that it works. - -building --------- - -Once you have build the library in the root of this repository by running make -all, you can build all these examples at once by running - - make - -in this directory. I think it makes things easier to experiment with quickly. - -namelookup ----------- - -Namelookup uses the SAM API to find the base64 destination of an readable "jump" -or base32 i2p address. You can use it like this: - - ./lookup i2p-projekt.i2p - diff --git a/supportlibs/libsam3/examples/sam3/dgramc.c b/supportlibs/libsam3/examples/sam3/dgramc.c deleted file mode 100644 index 898a9aec1..000000000 --- a/supportlibs/libsam3/examples/sam3/dgramc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -// comment the following if you don't want to stress UDP with 'big' datagram -// seems that up to 32000 bytes can be used for localhost -// note that we need 516+6+? bytes for header; lets reserve 1024 bytes for it -#define BIG (32000 - 1024) - -#define KEYFILE "dgrams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - char buf[1024]; - char destkey[517] = {0}; // 516 chars + \0 - int sz; - // - libsam3_debug = 1; - // - if (argc < 2) { - FILE *fl = fopen(KEYFILE, "rb"); - // - if (fl != NULL) { - if (fread(destkey, 516, 1, fl) == 1) { - fclose(fl); - goto ok; - } - fclose(fl); - } - printf("usage: dgramc PUBKEY\n"); - return 1; - } else { - if (strlen(argv[1]) != 516) { - fprintf(stderr, "FATAL: invalid key length!\n"); - return 1; - } - strcpy(destkey, argv[1]); - } - // -ok: - printf("creating session...\n"); - /* create TRANSIENT session with temporary disposible destination */ - if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, - SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_DGRAM, 4, - NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - /* send datagram */ - printf("sending test datagram...\n"); - if (sam3DatagramSend(&ses, destkey, "test", 4) < 0) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - /** receive reply */ - if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - /** null terminated string */ - buf[sz] = 0; - printf("received: [%s]\n", buf); - // -#ifdef BIG - { - char *big = calloc(BIG + 1024, sizeof(char)); - /** generate random string */ - sam3GenChannelName(big, BIG + 1023, BIG + 1023); - printf("sending BIG datagram...\n"); - if (sam3DatagramSend(&ses, destkey, big, BIG) < 0) { - free(big); - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - if ((sz = sam3DatagramReceive(&ses, big, BIG + 512)) < 0) { - free(big); - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - big[sz] = 0; - printf("received (%d): [%s]\n", sz, big); - free(big); - } -#endif - // - printf("sending quit datagram...\n"); - if (sam3DatagramSend(&ses, destkey, "quit", 4) < 0) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - buf[sz] = 0; - printf("received: [%s]\n", buf); - // - sam3CloseSession(&ses); - return 0; -error: - sam3CloseSession(&ses); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/dgrams.c b/supportlibs/libsam3/examples/sam3/dgrams.c deleted file mode 100644 index 1fe0fc0f7..000000000 --- a/supportlibs/libsam3/examples/sam3/dgrams.c +++ /dev/null @@ -1,113 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -#define KEYFILE "dgrams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - char privkey[1024], pubkey[1024], buf[33 * 1024]; - - /** quit command */ - const char *quitstr = "quit"; - const size_t quitlen = strlen(quitstr); - - /** reply response */ - const char *replystr = "reply: "; - const size_t replylen = strlen(replystr); - - FILE *fl; - // - libsam3_debug = 1; - // - - /** generate new destination keypair */ - printf("generating keys...\n"); - if (sam3GenerateKeys(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, 4) < 0) { - fprintf(stderr, "FATAL: can't generate keys\n"); - return 1; - } - /** copy keypair into local buffer */ - strncpy(pubkey, ses.pubkey, sizeof(pubkey)); - strncpy(privkey, ses.privkey, sizeof(privkey)); - /** create sam session */ - printf("creating session...\n"); - if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, privkey, - SAM3_SESSION_DGRAM, 5, NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - /** make sure we have the right destination */ - // FIXME: probably not needed - if (strcmp(pubkey, ses.pubkey) != 0) { - fprintf(stderr, "FATAL: destination keys don't match\n"); - sam3CloseSession(&ses); - return 1; - } - /** print destination to stdout */ - printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); - if ((fl = fopen(KEYFILE, "wb")) != NULL) { - /** write public key to keyfile */ - fwrite(pubkey, strlen(pubkey), 1, fl); - fclose(fl); - } - - /* now listen for UDP packets */ - printf("starting main loop...\n"); - for (;;) { - /** save replylen bytes for out reply at begining */ - char *datagramBuf = buf + replylen; - const size_t datagramMaxLen = sizeof(buf) - replylen; - int sz, isquit; - printf("waiting for datagram...\n"); - /** blocks until we get a UDP packet */ - if ((sz = sam3DatagramReceive(&ses, datagramBuf, datagramMaxLen) < 0)) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - /** ensure null terminated string */ - datagramBuf[sz] = 0; - /** print out datagram payload to user */ - printf("FROM\n====\n%s\n====\n", ses.destkey); - printf("SIZE=%d\n", sz); - printf("data: [%s]\n", datagramBuf); - /** check for "quit" */ - isquit = (sz == quitlen && memcmp(datagramBuf, quitstr, quitlen) == 0); - /** echo datagram back to sender with "reply: " at the beginning */ - memcpy(buf, replystr, replylen); - - if (sam3DatagramSend(&ses, ses.destkey, buf, sz + replylen) < 0) { - fprintf(stderr, "ERROR: %s\n", ses.error); - goto error; - } - /** if we got a quit command wait for 10 seconds and break out of the - * mainloop */ - if (isquit) { - printf("shutting down...\n"); - sleep(10); /* let dgram reach it's destination */ - break; - } - } - /** close session and delete keyfile */ - sam3CloseSession(&ses); - unlink(KEYFILE); - return 0; -error: - /** error case, close session, delete keyfile and return exit code 1 */ - sam3CloseSession(&ses); - unlink(KEYFILE); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/namelookup.c b/supportlibs/libsam3/examples/sam3/namelookup.c deleted file mode 100644 index 772e4aceb..000000000 --- a/supportlibs/libsam3/examples/sam3/namelookup.c +++ /dev/null @@ -1,43 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -int main(int argc, char *argv[]) { - Sam3Session ses; - // - // - libsam3_debug = 1; - // - if (argc < 2) { - printf("usage: %s name [name...]\n", argv[0]); - return 1; - } - /** for each name in arguments ... */ - for (int n = 1; n < argc; ++n) { - if (!getenv("I2P_LOOKUP_QUIET")) { - fprintf(stdout, "%s ... ", argv[n]); - fflush(stdout); - } - /** do oneshot name lookup */ - if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >= - 0) { - fprintf(stdout, "%s\n\n", ses.destkey); - } else { - fprintf(stdout, "FAILED [%s]\n", ses.error); - } - } - // - return 0; -} diff --git a/supportlibs/libsam3/examples/sam3/samtest.c b/supportlibs/libsam3/examples/sam3/samtest.c deleted file mode 100644 index b2d0b9983..000000000 --- a/supportlibs/libsam3/examples/sam3/samtest.c +++ /dev/null @@ -1,51 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -int main(int argc, char *argv[]) { - int fd; - SAMFieldList *rep = NULL; - const char *v; - // - libsam3_debug = 1; - // - // - if ((fd = sam3Handshake(NULL, 0, NULL)) < 0) - return 1; - // - if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0) - goto error; - rep = sam3ReadReply(fd); - // sam3DumpFieldList(rep); - if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL)) - goto error; - if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL)) - goto error; - v = sam3FindField(rep, "PUB"); - printf("PUB KEY\n=======\n%s\n", v); - v = sam3FindField(rep, "PRIV"); - printf("PRIV KEY\n========\n%s\n", v); - sam3FreeFieldList(rep); - rep = NULL; - // - sam3FreeFieldList(rep); - sam3tcpDisconnect(fd); - return 0; -error: - sam3FreeFieldList(rep); - sam3tcpDisconnect(fd); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/streamc.c b/supportlibs/libsam3/examples/sam3/streamc.c deleted file mode 100644 index 672831c3a..000000000 --- a/supportlibs/libsam3/examples/sam3/streamc.c +++ /dev/null @@ -1,87 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -#define KEYFILE "streams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - Sam3Connection *conn; - char cmd[1024], destkey[617]; // 616 chars + \0 - // - libsam3_debug = 1; - // - memset(destkey, 0, sizeof(destkey)); - // - if (argc < 2) { - FILE *fl = fopen(KEYFILE, "rb"); - // - if (fl != NULL) { - if (fread(destkey, 616, 1, fl) == 1) { - fclose(fl); - goto ok; - } - fclose(fl); - } - printf("usage: streamc PUBKEY\n"); - return 1; - } else { - if (!sam3CheckValidKeyLength(argv[1])) { - fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1], - strlen(argv[1])); - return 1; - } - strcpy(destkey, argv[1]); - } - // -ok: - printf("creating session...\n"); - // create TRANSIENT session - if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, - SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4, - NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - // - printf("connecting...\n"); - if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) { - fprintf(stderr, "FATAL: can't connect: %s\n", ses.error); - sam3CloseSession(&ses); - return 1; - } - // - // now waiting for incoming connection - printf("sending test command...\n"); - if (sam3tcpPrintf(conn->fd, "test\n") < 0) - goto error; - if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) - goto error; - printf("echo: %s\n", cmd); - // - printf("sending quit command...\n"); - if (sam3tcpPrintf(conn->fd, "quit\n") < 0) - goto error; - // - sam3CloseConnection(conn); - sam3CloseSession(&ses); - return 0; -error: - fprintf(stderr, "FATAL: some error occured!\n"); - sam3CloseConnection(conn); - sam3CloseSession(&ses); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/streamcs.c b/supportlibs/libsam3/examples/sam3/streamcs.c deleted file mode 100644 index 25bd22072..000000000 --- a/supportlibs/libsam3/examples/sam3/streamcs.c +++ /dev/null @@ -1,87 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -#define KEYFILE "streams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - Sam3Connection *conn; - char cmd[1024], destkey[617]; // 616 chars + \0 - // - libsam3_debug = 1; - // - memset(destkey, 0, sizeof(destkey)); - // - if (argc < 2) { - FILE *fl = fopen(KEYFILE, "rb"); - // - if (fl != NULL) { - if (fread(destkey, 616, 1, fl) == 1) { - fclose(fl); - goto ok; - } - fclose(fl); - } - printf("usage: streamc PUBKEY\n"); - return 1; - } else { - if (!sam3CheckValidKeyLength(argv[1])) { - fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1], - strlen(argv[1])); - return 1; - } - strcpy(destkey, argv[1]); - } - // -ok: - printf("creating session...\n"); - // create TRANSIENT session - if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, - SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, - 4, NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - // - printf("connecting...\n"); - if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) { - fprintf(stderr, "FATAL: can't connect: %s\n", ses.error); - sam3CloseSession(&ses); - return 1; - } - // - // now waiting for incoming connection - printf("sending test command...\n"); - if (sam3tcpPrintf(conn->fd, "test\n") < 0) - goto error; - if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) - goto error; - printf("echo: %s\n", cmd); - // - printf("sending quit command...\n"); - if (sam3tcpPrintf(conn->fd, "quit\n") < 0) - goto error; - // - sam3CloseConnection(conn); - sam3CloseSession(&ses); - return 0; -error: - fprintf(stderr, "FATAL: some error occured!\n"); - sam3CloseConnection(conn); - sam3CloseSession(&ses); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/streams.c b/supportlibs/libsam3/examples/sam3/streams.c deleted file mode 100644 index 2fa000c1c..000000000 --- a/supportlibs/libsam3/examples/sam3/streams.c +++ /dev/null @@ -1,72 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -#define KEYFILE "streams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - Sam3Connection *conn; - FILE *fl; - // - libsam3_debug = 1; - // - printf("creating session...\n"); - // create TRANSIENT session - if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, - SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4, - NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - // - printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); - if ((fl = fopen(KEYFILE, "wb")) != NULL) { - fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl); - fclose(fl); - } - // - printf("starting stream acceptor...\n"); - if ((conn = sam3StreamAccept(&ses)) == NULL) { - fprintf(stderr, "FATAL: can't accept: %s\n", ses.error); - sam3CloseSession(&ses); - return 1; - } - printf("FROM\n====\n%s\n====\n", conn->destkey); - // - printf("starting main loop...\n"); - for (;;) { - char cmd[256]; - // - if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) - goto error; - printf("cmd: [%s]\n", cmd); - if (strcmp(cmd, "quit") == 0) - break; - // echo command - if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0) - goto error; - } - // - sam3CloseSession(&ses); - unlink(KEYFILE); - return 0; -error: - fprintf(stderr, "FATAL: some error occured!\n"); - sam3CloseSession(&ses); - unlink(KEYFILE); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3/streamss.c b/supportlibs/libsam3/examples/sam3/streamss.c deleted file mode 100644 index ffbc974da..000000000 --- a/supportlibs/libsam3/examples/sam3/streamss.c +++ /dev/null @@ -1,72 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include "../libsam3/libsam3.h" - -#define KEYFILE "streams.key" - -int main(int argc, char *argv[]) { - Sam3Session ses; - Sam3Connection *conn; - FILE *fl; - // - libsam3_debug = 1; - // - printf("creating session...\n"); - // create TRANSIENT session - if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, - SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, - 4, NULL) < 0) { - fprintf(stderr, "FATAL: can't create session\n"); - return 1; - } - // - printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey); - if ((fl = fopen(KEYFILE, "wb")) != NULL) { - fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl); - fclose(fl); - } - // - printf("starting stream acceptor...\n"); - if ((conn = sam3StreamAccept(&ses)) == NULL) { - fprintf(stderr, "FATAL: can't accept: %s\n", ses.error); - sam3CloseSession(&ses); - return 1; - } - printf("FROM\n====\n%s\n====\n", conn->destkey); - // - printf("starting main loop...\n"); - for (;;) { - char cmd[256]; - // - if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) - goto error; - printf("cmd: [%s]\n", cmd); - if (strcmp(cmd, "quit") == 0) - break; - // echo command - if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0) - goto error; - } - // - sam3CloseSession(&ses); - unlink(KEYFILE); - return 0; -error: - fprintf(stderr, "FATAL: some error occured!\n"); - sam3CloseSession(&ses); - unlink(KEYFILE); - return 1; -} diff --git a/supportlibs/libsam3/examples/sam3a/test00.c b/supportlibs/libsam3/examples/sam3a/test00.c deleted file mode 100644 index 5596053e9..000000000 --- a/supportlibs/libsam3/examples/sam3a/test00.c +++ /dev/null @@ -1,178 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../libsam3a/libsam3a.h" - -//////////////////////////////////////////////////////////////////////////////// -static void scbErrorClose(Sam3ASession *ses) { - fprintf(stderr, - "\n===============================\nSESION_ERROR: " - "[%s]\n===============================\n", - ses->error); - sam3aCloseSession(ses); // it's safe here -} - -static void scbNRCreated(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nNAME RESOLVED: [%s]\n", - ses->params); - fprintf(stderr, "PUB: %s\n===============================\n", ses->destkey); - sam3aCloseSession(ses); // it's safe here -} - -static const Sam3ASessionCallbacks scbNR = { - .cbError = scbErrorClose, - .cbCreated = scbNRCreated, - .cbDisconnected = NULL, - .cbDatagramRead = NULL, - .cbDestroy = NULL, -}; - -//////////////////////////////////////////////////////////////////////////////// -static void scbKGCreated(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nKEYS GENERATED\n"); - fprintf(stderr, "\rPRIV: %s\n", ses->privkey); - fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); - sam3aCloseSession(ses); // it's safe here -} - -static const Sam3ASessionCallbacks scbKG = { - .cbError = scbErrorClose, - .cbCreated = scbKGCreated, - .cbDisconnected = NULL, - .cbDatagramRead = NULL, - .cbDestroy = NULL, -}; - -//////////////////////////////////////////////////////////////////////////////// -static void scbError(Sam3ASession *ses) { - fprintf(stderr, - "\n===============================\nSESION_ERROR: " - "[%s]\n===============================\n", - ses->error); -} - -static void scbCreated(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_CREATED\n"); - fprintf(stderr, "\rPRIV: %s\n", ses->privkey); - fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); - sam3aCancelSession(ses); // it's safe here -} - -static void scbDisconnected(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" - "===========================\n"); -} - -static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { - fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" - "============================\n"); -} - -static void scbDestroy(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" - "========================\n"); -} - -/** callbacks for our SAM session */ -static const Sam3ASessionCallbacks scb = { - .cbError = scbError, - .cbCreated = scbCreated, - .cbDisconnected = scbDisconnected, - .cbDatagramRead = scbDGramRead, - .cbDestroy = scbDestroy, -}; - -//////////////////////////////////////////////////////////////////////////////// -#define HOST SAM3A_HOST_DEFAULT -//#define HOST "google.com" - -int main(int argc, char *argv[]) { - Sam3ASession ses, snr, skg; - // - // libsam3a_debug = 1; - // - if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, - SAM3A_DESTINATION_TRANSIENT, - SAM3A_SESSION_STREAM) < 0) { - fprintf(stderr, "FATAL: can't create main session!\n"); - return 1; - } - // generate keys - if (sam3aGenerateKeys(&skg, &scbKG, HOST, SAM3A_PORT_DEFAULT) < 0) { - sam3aCloseSession(&ses); - fprintf(stderr, "FATAL: can't create keygen session!\n"); - return 1; - } - // do a name lookup for zzz.i2p - if (sam3aNameLookup(&snr, &scbNR, HOST, SAM3A_PORT_DEFAULT, "zzz.i2p") < 0) { - sam3aCloseSession(&skg); - sam3aCloseSession(&ses); - fprintf(stderr, "FATAL: can't create name resolving session!\n"); - return 1; - } - // while we have sessions ... - while (sam3aIsActiveSession(&ses) || sam3aIsActiveSession(&snr) || - sam3aIsActiveSession(&skg)) { - fd_set rds, wrs; - int res, maxfd = 0; - struct timeval to; - // set up file descriptors for select() - FD_ZERO(&rds); - FD_ZERO(&wrs); - // obtain the maximum fd for select() - if (sam3aIsActiveSession(&ses) && - (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) - break; - if (sam3aIsActiveSession(&snr) && - (maxfd = sam3aAddSessionToFDS(&snr, -1, &rds, &wrs)) < 0) - break; - if (sam3aIsActiveSession(&skg) && - (maxfd = sam3aAddSessionToFDS(&skg, -1, &rds, &wrs)) < 0) - break; - // set timeout to 1 second - sam3ams2timeval(&to, 1000); - // call select() - res = select(maxfd + 1, &rds, &wrs, NULL, &to); - if (res < 0) { - if (errno == EINTR) - continue; - fprintf(stderr, "FATAL: select() error!\n"); - break; - } - if (res == 0) { - // idle, no activity - fprintf(stdout, "."); - fflush(stdout); - } else { - // we have activity, process io - if (sam3aIsActiveSession(&ses)) - sam3aProcessSessionIO(&ses, &rds, &wrs); - if (sam3aIsActiveSession(&snr)) - sam3aProcessSessionIO(&snr, &rds, &wrs); - if (sam3aIsActiveSession(&skg)) - sam3aProcessSessionIO(&skg, &rds, &wrs); - } - } - // close seessions - sam3aCloseSession(&ses); - sam3aCloseSession(&skg); - sam3aCloseSession(&snr); - // exit - return 0; -} diff --git a/supportlibs/libsam3/examples/sam3a/test_sc.c b/supportlibs/libsam3/examples/sam3a/test_sc.c deleted file mode 100644 index 8feeb5d52..000000000 --- a/supportlibs/libsam3/examples/sam3a/test_sc.c +++ /dev/null @@ -1,205 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../libsam3a/libsam3a.h" - -//////////////////////////////////////////////////////////////////////////////// -#define KEYFILE "streams.key" - -//////////////////////////////////////////////////////////////////////////////// -static void ccbError(Sam3AConnection *ct) { - fprintf(stderr, - "\n===============================\nCONNECTION_ERROR: " - "[%s]\n===============================\n", - ct->error); -} - -static void ccbDisconnected(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_" - "DISCONNECTED\n===============================\n"); -} - -static void ccbConnected(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===" - "============================\n"); - // sam3aCancelConnection(ct); // cbSent() will not be called -} - -static void ccbAccepted(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n====" - "===========================\n"); -} - -static void ccbSent(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===" - "============================\n"); - // sam3aCancelConnection(ct); - // sam3aCancelSession(ct->ses); // hehe - fprintf(stderr, "(%p)\n", ct->udata); - // - switch ((intptr_t)ct->udata) { - case 0: - if (sam3aSend(ct, "test\n", -1) < 0) { - fprintf(stderr, "SEND ERROR!\n"); - sam3aCancelSession(ct->ses); // hehe - } - break; - case 1: - if (sam3aSend(ct, "quit\n", -1) < 0) { - fprintf(stderr, "SEND ERROR!\n"); - sam3aCancelSession(ct->ses); // hehe - } - break; - default: - return; - } - ct->udata = (void *)(((intptr_t)ct->udata) + 1); -} - -static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) { - fprintf(stderr, - "\n===============================\nCONNECTION_GOTBYTES " - "(%d)\n===============================\n", - bufsize); -} - -static void ccbDestroy(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n=====" - "==========================\n"); -} - -static const Sam3AConnectionCallbacks ccb = { - .cbError = ccbError, - .cbDisconnected = ccbDisconnected, - .cbConnected = ccbConnected, - .cbAccepted = ccbAccepted, - .cbSent = ccbSent, - .cbRead = ccbRead, - .cbDestroy = ccbDestroy, -}; - -//////////////////////////////////////////////////////////////////////////////// -static void scbError(Sam3ASession *ses) { - fprintf(stderr, - "\n===============================\nSESION_ERROR: " - "[%s]\n===============================\n", - ses->error); -} - -static void scbCreated(Sam3ASession *ses) { - char destkey[517]; - FILE *fl; - // - fprintf(stderr, "\n===============================\nSESION_CREATED\n"); - fprintf(stderr, "\rPRIV: %s\n", ses->privkey); - fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); - // - fl = fopen(KEYFILE, "rb"); - // - if (fl == NULL) { - fprintf(stderr, "ERROR: NO KEY FILE!\n"); - sam3aCancelSession(ses); - return; - } - if (fread(destkey, 516, 1, fl) != 1) { - fprintf(stderr, "ERROR: INVALID KEY FILE!\n"); - fclose(fl); - sam3aCancelSession(ses); - return; - } - fclose(fl); - destkey[516] = 0; - if (sam3aStreamConnect(ses, &ccb, destkey) == NULL) { - fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n"); - sam3aCancelSession(ses); - return; - } - fprintf(stderr, "GOON: creating connection...\n"); -} - -static void scbDisconnected(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" - "===========================\n"); -} - -static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { - fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" - "============================\n"); -} - -static void scbDestroy(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" - "========================\n"); -} - -static const Sam3ASessionCallbacks scb = { - .cbError = scbError, - .cbCreated = scbCreated, - .cbDisconnected = scbDisconnected, - .cbDatagramRead = scbDGramRead, - .cbDestroy = scbDestroy, -}; - -//////////////////////////////////////////////////////////////////////////////// -#define HOST SAM3A_HOST_DEFAULT -//#define HOST "google.com" - -int main(int argc, char *argv[]) { - Sam3ASession ses; - // - libsam3a_debug = 0; - // - if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, - SAM3A_DESTINATION_TRANSIENT, - SAM3A_SESSION_STREAM) < 0) { - fprintf(stderr, "FATAL: can't create main session!\n"); - return 1; - } - // - while (sam3aIsActiveSession(&ses)) { - fd_set rds, wrs; - int res, maxfd = 0; - struct timeval to; - // - FD_ZERO(&rds); - FD_ZERO(&wrs); - if (sam3aIsActiveSession(&ses) && - (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) - break; - sam3ams2timeval(&to, 1000); - res = select(maxfd + 1, &rds, &wrs, NULL, &to); - if (res < 0) { - if (errno == EINTR) - continue; - fprintf(stderr, "FATAL: select() error!\n"); - break; - } - if (res == 0) { - fprintf(stdout, "."); - fflush(stdout); - } else { - if (sam3aIsActiveSession(&ses)) - sam3aProcessSessionIO(&ses, &rds, &wrs); - } - } - // - sam3aCloseSession(&ses); - // - return 0; -} diff --git a/supportlibs/libsam3/examples/sam3a/test_ss.c b/supportlibs/libsam3/examples/sam3a/test_ss.c deleted file mode 100644 index c2ff3399c..000000000 --- a/supportlibs/libsam3/examples/sam3a/test_ss.c +++ /dev/null @@ -1,236 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../libsam3a/libsam3a.h" - -//////////////////////////////////////////////////////////////////////////////// -#define KEYFILE "streams.key" - -//////////////////////////////////////////////////////////////////////////////// -typedef struct { - char *str; - int strsize; - int strused; - int doQuit; -} ConnData; - -static void cdAppendChar(ConnData *d, char ch) { - if (d->strused + 1 >= d->strsize) { - // fuck errors - d->strsize = d->strused + 1024; - d->str = realloc(d->str, d->strsize + 1); - } - d->str[d->strused++] = ch; - d->str[d->strused] = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -static void ccbError(Sam3AConnection *ct) { - fprintf(stderr, - "\n===============================\nCONNECTION_ERROR: " - "[%s]\n===============================\n", - ct->error); -} - -static void ccbDisconnected(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_" - "DISCONNECTED\n===============================\n"); -} - -static void ccbConnected(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===" - "============================\n"); - // sam3aCancelConnection(ct); // cbSent() will not be called -} - -static void ccbAccepted(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n====" - "===========================\n"); - fprintf(stderr, "FROM: %s\n===============================\n", ct->destkey); -} - -static void ccbSent(Sam3AConnection *ct) { - ConnData *d = (ConnData *)ct->udata; - // - fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===" - "============================\n"); - if (d->doQuit) { - sam3aCancelSession(ct->ses); // hehe - } -} - -static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) { - const char *b = (const char *)buf; - ConnData *d = (ConnData *)ct->udata; - // - fprintf(stderr, - "\n===============================\nCONNECTION_GOTBYTES " - "(%d)\n===============================\n", - bufsize); - while (bufsize > 0) { - cdAppendChar(ct->udata, *b); - if (*b == '\n') { - fprintf(stderr, "cmd: %s", d->str); - if (strcasecmp(d->str, "quit\n") == 0) - d->doQuit = 1; - if (sam3aSend(ct, d->str, -1) < 0) { - // sam3aCancelConnection(ct); // hehe - sam3aCancelSession(ct->ses); // hehe - return; - } - d->str[0] = 0; - d->strused = 0; - } - ++b; - --bufsize; - } -} - -static void ccbDestroy(Sam3AConnection *ct) { - fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n=====" - "==========================\n"); - if (ct->udata != NULL) { - ConnData *d = (ConnData *)ct->udata; - // - if (d->str != NULL) - free(d->str); - free(d); - } -} - -static const Sam3AConnectionCallbacks ccb = { - .cbError = ccbError, - .cbDisconnected = ccbDisconnected, - .cbConnected = ccbConnected, - .cbAccepted = ccbAccepted, - .cbSent = ccbSent, - .cbRead = ccbRead, - .cbDestroy = ccbDestroy, -}; - -//////////////////////////////////////////////////////////////////////////////// -static void scbError(Sam3ASession *ses) { - fprintf(stderr, - "\n===============================\nSESION_ERROR: " - "[%s]\n===============================\n", - ses->error); -} - -static void scbCreated(Sam3ASession *ses) { - FILE *fl; - Sam3AConnection *conn; - // - fprintf(stderr, "\n===============================\nSESION_CREATED\n"); - fprintf(stderr, "\rPRIV: %s\n", ses->privkey); - fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); - // - fl = fopen(KEYFILE, "wb"); - // - if (fl == NULL) { - fprintf(stderr, "ERROR: CAN'T CREATE KEY FILE!\n"); - sam3aCancelSession(ses); - return; - } - if (fwrite(ses->pubkey, 516, 1, fl) != 1) { - fprintf(stderr, "ERROR: CAN'T WRITE KEY FILE!\n"); - fclose(fl); - sam3aCancelSession(ses); - return; - } - fclose(fl); - if ((conn = sam3aStreamAccept(ses, &ccb)) == NULL) { - fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n"); - sam3aCancelSession(ses); - return; - } - // - conn->udata = calloc(1, sizeof(ConnData)); - fprintf(stderr, "GOON: accepting connection...\n"); -} - -static void scbDisconnected(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n====" - "===========================\n"); -} - -static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) { - fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===" - "============================\n"); -} - -static void scbDestroy(Sam3ASession *ses) { - fprintf(stderr, "\n===============================\nSESION_DESTROYED\n=======" - "========================\n"); -} - -static const Sam3ASessionCallbacks scb = { - .cbError = scbError, - .cbCreated = scbCreated, - .cbDisconnected = scbDisconnected, - .cbDatagramRead = scbDGramRead, - .cbDestroy = scbDestroy, -}; - -//////////////////////////////////////////////////////////////////////////////// -#define HOST SAM3A_HOST_DEFAULT -//#define HOST "google.com" - -int main(int argc, char *argv[]) { - Sam3ASession ses; - // - libsam3a_debug = 0; - // - if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, - SAM3A_DESTINATION_TRANSIENT, - SAM3A_SESSION_STREAM) < 0) { - fprintf(stderr, "FATAL: can't create main session!\n"); - return 1; - } - // - while (sam3aIsActiveSession(&ses)) { - fd_set rds, wrs; - int res, maxfd = 0; - struct timeval to; - // - FD_ZERO(&rds); - FD_ZERO(&wrs); - if (sam3aIsActiveSession(&ses) && - (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) - break; - sam3ams2timeval(&to, 1000); - res = select(maxfd + 1, &rds, &wrs, NULL, &to); - if (res < 0) { - if (errno == EINTR) - continue; - fprintf(stderr, "FATAL: select() error!\n"); - break; - } - if (res == 0) { - fprintf(stdout, "."); - fflush(stdout); - } else { - if (sam3aIsActiveSession(&ses)) - sam3aProcessSessionIO(&ses, &rds, &wrs); - } - } - // - sam3aCloseSession(&ses); - // - return 0; -} diff --git a/supportlibs/libsam3/src/ext/tinytest.c b/supportlibs/libsam3/src/ext/tinytest.c deleted file mode 100644 index 252f03051..000000000 --- a/supportlibs/libsam3/src/ext/tinytest.c +++ /dev/null @@ -1,466 +0,0 @@ -/* tinytest.c -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef TINYTEST_LOCAL -#include "tinytest_local.h" -#endif - -#include -#include -#include -#include - -#ifndef NO_FORKING - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#endif - -#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) -/* Workaround for a stupid bug in OSX 10.6 */ -#define FORK_BREAKS_GCOV -#include -#endif -#endif - -#endif /* !NO_FORKING */ - -#ifndef __GNUC__ -#define __attribute__(x) -#endif - -#include "tinytest.h" -#include "tinytest_macros.h" - -#define LONGEST_TEST_NAME 16384 - -static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/ -static int n_ok = 0; /**< Number of tests that have passed */ -static int n_bad = 0; /**< Number of tests that have failed. */ -static int n_skipped = 0; /**< Number of tests that have been skipped. */ - -static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/ -static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */ -static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */ -const char *verbosity_flag = ""; - -const struct testlist_alias_t *cfg_aliases = NULL; - -enum outcome { SKIP = 2, OK = 1, FAIL = 0 }; -static enum outcome cur_test_outcome = FAIL; -const char *cur_test_prefix = NULL; /**< prefix of the current test group */ -/** Name of the current test, if we haven't logged is yet. Used for --quiet */ -const char *cur_test_name = NULL; - -#ifdef _WIN32 -/* Copy of argv[0] for win32. */ -static char commandname[MAX_PATH + 1]; -#endif - -static void usage(struct testgroup_t *groups, int list_groups) - __attribute__((noreturn)); -static int process_test_option(struct testgroup_t *groups, const char *test); - -static enum outcome testcase_run_bare_(const struct testcase_t *testcase) { - void *env = NULL; - enum outcome outcome; - if (testcase->setup) { - env = testcase->setup->setup_fn(testcase); - if (!env) - return FAIL; - else if (env == (void *)TT_SKIP) - return SKIP; - } - - cur_test_outcome = OK; - testcase->fn(env); - outcome = cur_test_outcome; - - if (testcase->setup) { - if (testcase->setup->cleanup_fn(testcase, env) == 0) - outcome = FAIL; - } - - return outcome; -} - -#define MAGIC_EXITCODE 42 - -#ifndef NO_FORKING - -static enum outcome testcase_run_forked_(const struct testgroup_t *group, - const struct testcase_t *testcase) { -#ifdef _WIN32 - /* Fork? On Win32? How primitive! We'll do what the smart kids do: - we'll invoke our own exe (whose name we recall from the command - line) with a command line that tells it to run just the test we - want, and this time without forking. - - (No, threads aren't an option. The whole point of forking is to - share no state between tests.) - */ - int ok; - char buffer[LONGEST_TEST_NAME + 256]; - STARTUPINFOA si; - PROCESS_INFORMATION info; - DWORD exitcode; - - if (!in_tinytest_main) { - printf("\nERROR. On Windows, testcase_run_forked_ must be" - " called from within tinytest_main.\n"); - abort(); - } - if (opt_verbosity > 0) - printf("[forking] "); - - snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", commandname, - verbosity_flag, group->prefix, testcase->name); - - memset(&si, 0, sizeof(si)); - memset(&info, 0, sizeof(info)); - si.cb = sizeof(si); - - ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, 0, NULL, NULL, &si, - &info); - if (!ok) { - printf("CreateProcess failed!\n"); - return 0; - } - WaitForSingleObject(info.hProcess, INFINITE); - GetExitCodeProcess(info.hProcess, &exitcode); - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - if (exitcode == 0) - return OK; - else if (exitcode == MAGIC_EXITCODE) - return SKIP; - else - return FAIL; -#else - int outcome_pipe[2]; - pid_t pid; - (void)group; - - if (pipe(outcome_pipe)) - perror("opening pipe"); - - if (opt_verbosity > 0) - printf("[forking] "); - pid = fork(); -#ifdef FORK_BREAKS_GCOV - vproc_transaction_begin(0); -#endif - if (!pid) { - /* child. */ - int test_r, write_r; - char b[1]; - close(outcome_pipe[0]); - test_r = testcase_run_bare_(testcase); - assert(0 <= (int)test_r && (int)test_r <= 2); - b[0] = "NYS"[test_r]; - write_r = (int)write(outcome_pipe[1], b, 1); - if (write_r != 1) { - perror("write outcome to pipe"); - exit(1); - } - exit(0); - return FAIL; /* unreachable */ - } else { - /* parent */ - int status, r; - char b[1]; - /* Close this now, so that if the other side closes it, - * our read fails. */ - close(outcome_pipe[1]); - r = (int)read(outcome_pipe[0], b, 1); - if (r == 0) { - printf("[Lost connection!] "); - return FAIL; - } else if (r != 1) { - perror("read outcome from pipe"); - } - waitpid(pid, &status, 0); - close(outcome_pipe[0]); - return b[0] == 'Y' ? OK : (b[0] == 'S' ? SKIP : FAIL); - } -#endif -} - -#endif /* !NO_FORKING */ - -int testcase_run_one(const struct testgroup_t *group, - const struct testcase_t *testcase) { - enum outcome outcome; - - if (testcase->flags & (TT_SKIP | TT_OFF_BY_DEFAULT)) { - if (opt_verbosity > 0) - printf("%s%s: %s\n", group->prefix, testcase->name, - (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED"); - ++n_skipped; - return SKIP; - } - - if (opt_verbosity > 0 && !opt_forked) { - printf("%s%s: ", group->prefix, testcase->name); - } else { - if (opt_verbosity == 0) - printf("."); - cur_test_prefix = group->prefix; - cur_test_name = testcase->name; - } - -#ifndef NO_FORKING - if ((testcase->flags & TT_FORK) && !(opt_forked || opt_nofork)) { - outcome = testcase_run_forked_(group, testcase); - } else { -#else - { -#endif - outcome = testcase_run_bare_(testcase); - } - - if (outcome == OK) { - ++n_ok; - if (opt_verbosity > 0 && !opt_forked) - puts(opt_verbosity == 1 ? "OK" : ""); - } else if (outcome == SKIP) { - ++n_skipped; - if (opt_verbosity > 0 && !opt_forked) - puts("SKIPPED"); - } else { - ++n_bad; - if (!opt_forked) - printf("\n [%s FAILED]\n", testcase->name); - } - - if (opt_forked) { - exit(outcome == OK ? 0 : (outcome == SKIP ? MAGIC_EXITCODE : 1)); - return 1; /* unreachable */ - } else { - return (int)outcome; - } -} - -int tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, - unsigned long flag) { - int i, j; - size_t length = LONGEST_TEST_NAME; - char fullname[LONGEST_TEST_NAME]; - int found = 0; - if (strstr(arg, "..")) - length = strstr(arg, "..") - arg; - for (i = 0; groups[i].prefix; ++i) { - for (j = 0; groups[i].cases[j].name; ++j) { - struct testcase_t *testcase = &groups[i].cases[j]; - snprintf(fullname, sizeof(fullname), "%s%s", groups[i].prefix, - testcase->name); - if (!flag) { /* Hack! */ - printf(" %s", fullname); - if (testcase->flags & TT_OFF_BY_DEFAULT) - puts(" (Off by default)"); - else if (testcase->flags & TT_SKIP) - puts(" (DISABLED)"); - else - puts(""); - } - if (!strncmp(fullname, arg, length)) { - if (set) - testcase->flags |= flag; - else - testcase->flags &= ~flag; - ++found; - } - } - } - return found; -} - -static void usage(struct testgroup_t *groups, int list_groups) { - puts("Options are: [--verbose|--quiet|--terse] [--no-fork]"); - puts(" Specify tests by name, or using a prefix ending with '..'"); - puts(" To skip a test, prefix its name with a colon."); - puts(" To enable a disabled test, prefix its name with a plus."); - puts(" Use --list-tests for a list of tests."); - if (list_groups) { - puts("Known tests are:"); - tinytest_set_flag_(groups, "..", 1, 0); - } - exit(0); -} - -static int process_test_alias(struct testgroup_t *groups, const char *test) { - int i, j, n, r; - for (i = 0; cfg_aliases && cfg_aliases[i].name; ++i) { - if (!strcmp(cfg_aliases[i].name, test)) { - n = 0; - for (j = 0; cfg_aliases[i].tests[j]; ++j) { - r = process_test_option(groups, cfg_aliases[i].tests[j]); - if (r < 0) - return -1; - n += r; - } - return n; - } - } - printf("No such test alias as @%s!", test); - return -1; -} - -static int process_test_option(struct testgroup_t *groups, const char *test) { - int flag = TT_ENABLED_; - int n = 0; - if (test[0] == '@') { - return process_test_alias(groups, test + 1); - } else if (test[0] == ':') { - ++test; - flag = TT_SKIP; - } else if (test[0] == '+') { - ++test; - ++n; - if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) { - printf("No such test as %s!\n", test); - return -1; - } - } else { - ++n; - } - if (!tinytest_set_flag_(groups, test, 1, flag)) { - printf("No such test as %s!\n", test); - return -1; - } - return n; -} - -void tinytest_set_aliases(const struct testlist_alias_t *aliases) { - cfg_aliases = aliases; -} - -int tinytest_main(int c, const char **v, struct testgroup_t *groups) { - int i, j, n = 0; - -#ifdef _WIN32 - const char *sp = strrchr(v[0], '.'); - const char *extension = ""; - if (!sp || stricmp(sp, ".exe")) - extension = ".exe"; /* Add an exe so CreateProcess will work */ - snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); - commandname[MAX_PATH] = '\0'; -#endif - for (i = 1; i < c; ++i) { - if (v[i][0] == '-') { - if (!strcmp(v[i], "--RUNNING-FORKED")) { - opt_forked = 1; - } else if (!strcmp(v[i], "--no-fork")) { - opt_nofork = 1; - } else if (!strcmp(v[i], "--quiet")) { - opt_verbosity = -1; - verbosity_flag = "--quiet"; - } else if (!strcmp(v[i], "--verbose")) { - opt_verbosity = 2; - verbosity_flag = "--verbose"; - } else if (!strcmp(v[i], "--terse")) { - opt_verbosity = 0; - verbosity_flag = "--terse"; - } else if (!strcmp(v[i], "--help")) { - usage(groups, 0); - } else if (!strcmp(v[i], "--list-tests")) { - usage(groups, 1); - } else { - printf("Unknown option %s. Try --help\n", v[i]); - return -1; - } - } else { - int r = process_test_option(groups, v[i]); - if (r < 0) - return -1; - n += r; - } - } - if (!n) - tinytest_set_flag_(groups, "..", 1, TT_ENABLED_); - -#ifdef _IONBF - setvbuf(stdout, NULL, _IONBF, 0); -#endif - - ++in_tinytest_main; - for (i = 0; groups[i].prefix; ++i) - for (j = 0; groups[i].cases[j].name; ++j) - if (groups[i].cases[j].flags & TT_ENABLED_) - testcase_run_one(&groups[i], &groups[i].cases[j]); - - --in_tinytest_main; - - if (opt_verbosity == 0) - puts(""); - - if (n_bad) - printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad, n_bad + n_ok, - n_skipped); - else if (opt_verbosity >= 1) - printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped); - - return (n_bad == 0) ? 0 : 1; -} - -int tinytest_get_verbosity_(void) { return opt_verbosity; } - -void tinytest_set_test_failed_(void) { - if (opt_verbosity <= 0 && cur_test_name) { - if (opt_verbosity == 0) - puts(""); - printf("%s%s: ", cur_test_prefix, cur_test_name); - cur_test_name = NULL; - } - cur_test_outcome = FAIL; -} - -void tinytest_set_test_skipped_(void) { - if (cur_test_outcome == OK) - cur_test_outcome = SKIP; -} - -char *tinytest_format_hex_(const void *val_, unsigned long len) { - const unsigned char *val = (unsigned char *)val_; - char *result, *cp; - size_t i; - - if (!val) - return strdup("null"); - if (!(result = (char *)malloc(len * 2 + 1))) - return strdup(""); - cp = result; - for (i = 0; i < len; ++i) { - *cp++ = "0123456789ABCDEF"[val[i] >> 4]; - *cp++ = "0123456789ABCDEF"[val[i] & 0x0f]; - } - *cp = 0; - return result; -} diff --git a/supportlibs/libsam3/src/ext/tinytest.h b/supportlibs/libsam3/src/ext/tinytest.h deleted file mode 100644 index bdddcbb54..000000000 --- a/supportlibs/libsam3/src/ext/tinytest.h +++ /dev/null @@ -1,104 +0,0 @@ -/* tinytest.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_H_INCLUDED_ -#define TINYTEST_H_INCLUDED_ - -/** Flag for a test that needs to run in a subprocess. */ -#define TT_FORK (1 << 0) -/** Runtime flag for a test we've decided to skip. */ -#define TT_SKIP (1 << 1) -/** Internal runtime flag for a test we've decided to run. */ -#define TT_ENABLED_ (1 << 2) -/** Flag for a test that's off by default. */ -#define TT_OFF_BY_DEFAULT (1 << 3) -/** If you add your own flags, make them start at this point. */ -#define TT_FIRST_USER_FLAG (1 << 4) - -typedef void (*testcase_fn)(void *); - -struct testcase_t; - -/** Functions to initialize/teardown a structure for a testcase. */ -struct testcase_setup_t { - /** Return a new structure for use by a given testcase. */ - void *(*setup_fn)(const struct testcase_t *); - /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */ - int (*cleanup_fn)(const struct testcase_t *, void *); -}; - -/** A single test-case that you can run. */ -struct testcase_t { - const char *name; /**< An identifier for this case. */ - testcase_fn fn; /**< The function to run to implement this case. */ - unsigned long flags; /**< Bitfield of TT_* flags. */ - const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ - void *setup_data; /**< Extra data usable by setup function */ -}; -#define END_OF_TESTCASES \ - { NULL, NULL, 0, NULL, NULL } - -/** A group of tests that are selectable together. */ -struct testgroup_t { - const char *prefix; /**< Prefix to prepend to testnames. */ - struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */ -}; -#define END_OF_GROUPS \ - { NULL, NULL } - -struct testlist_alias_t { - const char *name; - const char **tests; -}; -#define END_OF_ALIASES \ - { NULL, NULL } - -/** Implementation: called from a test to indicate failure, before logging. */ -void tinytest_set_test_failed_(void); -/** Implementation: called from a test to indicate that we're skipping. */ -void tinytest_set_test_skipped_(void); -/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */ -int tinytest_get_verbosity_(void); -/** Implementation: Set a flag on tests matching a name; returns number - * of tests that matched. */ -int tinytest_set_flag_(struct testgroup_t *, const char *, int set, - unsigned long); -/** Implementation: Put a chunk of memory into hex. */ -char *tinytest_format_hex_(const void *, unsigned long); - -/** Set all tests in 'groups' matching the name 'named' to be skipped. */ -#define tinytest_skip(groups, named) \ - tinytest_set_flag_(groups, named, 1, TT_SKIP) - -/** Run a single testcase in a single group. */ -int testcase_run_one(const struct testgroup_t *, const struct testcase_t *); - -void tinytest_set_aliases(const struct testlist_alias_t *aliases); - -/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups, - as selected from the command line. */ -int tinytest_main(int argc, const char **argv, struct testgroup_t *groups); - -#endif diff --git a/supportlibs/libsam3/src/ext/tinytest_macros.h b/supportlibs/libsam3/src/ext/tinytest_macros.h deleted file mode 100644 index 817734020..000000000 --- a/supportlibs/libsam3/src/ext/tinytest_macros.h +++ /dev/null @@ -1,219 +0,0 @@ -/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_MACROS_H_INCLUDED_ -#define TINYTEST_MACROS_H_INCLUDED_ - -/* Helpers for defining statement-like macros */ -#define TT_STMT_BEGIN do { -#define TT_STMT_END \ - } \ - while (0) - -/* Redefine this if your test functions want to abort with something besides - * "goto end;" */ -#ifndef TT_EXIT_TEST_FUNCTION -#define TT_EXIT_TEST_FUNCTION \ - TT_STMT_BEGIN goto end; \ - TT_STMT_END -#endif - -/* Redefine this if you want to note success/failure in some different way. */ -#ifndef TT_DECLARE -#define TT_DECLARE(prefix, args) \ - TT_STMT_BEGIN \ - printf("\n %s %s:%d: ", prefix, __FILE__, __LINE__); \ - printf args; \ - TT_STMT_END -#endif - -/* Announce a failure. Args are parenthesized printf args. */ -#define TT_GRIPE(args) TT_DECLARE("FAIL", args) - -/* Announce a non-failure if we're verbose. */ -#define TT_BLATHER(args) \ - TT_STMT_BEGIN \ - if (tinytest_get_verbosity_() > 1) \ - TT_DECLARE(" OK", args); \ - TT_STMT_END - -#define TT_DIE(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define TT_FAIL(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_STMT_END - -/* Fail and abort the current test for the reason in msg */ -#define tt_abort_printf(msg) TT_DIE(msg) -#define tt_abort_perror(op) \ - TT_DIE(("%s: %s [%d]", (op), strerror(errno), errno)) -#define tt_abort_msg(msg) TT_DIE(("%s", msg)) -#define tt_abort() TT_DIE(("%s", "(Failed.)")) - -/* Fail but do not abort the current test for the reason in msg. */ -#define tt_fail_printf(msg) TT_FAIL(msg) -#define tt_fail_perror(op) \ - TT_FAIL(("%s: %s [%d]", (op), strerror(errno), errno)) -#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) -#define tt_fail() TT_FAIL(("%s", "(Failed.)")) - -/* End the current test, and indicate we are skipping it. */ -#define tt_skip() \ - TT_STMT_BEGIN \ - tinytest_set_test_skipped_(); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define tt_want_(b, msg, fail) \ - TT_STMT_BEGIN \ - if (!(b)) { \ - tinytest_set_test_failed_(); \ - TT_GRIPE(("%s", msg)); \ - fail; \ - } else { \ - TT_BLATHER(("%s", msg)); \ - } \ - TT_STMT_END - -/* Assert b, but do not stop the test if b fails. Log msg on failure. */ -#define tt_want_msg(b, msg) tt_want_(b, msg, ); - -/* Assert b and stop the test if b fails. Log msg on failure. */ -#define tt_assert_msg(b, msg) tt_want_(b, msg, TT_EXIT_TEST_FUNCTION); - -/* Assert b, but do not stop the test if b fails. */ -#define tt_want(b) tt_want_msg((b), "want(" #b ")") -/* Assert b, and stop the test if b fails. */ -#define tt_assert(b) tt_assert_msg((b), "assert(" #b ")") - -#define tt_assert_test_fmt_type(a, b, str_test, type, test, printf_type, \ - printf_fmt, setup_block, cleanup_block, \ - die_on_fail) \ - TT_STMT_BEGIN \ - type val1_ = (a); \ - type val2_ = (b); \ - int tt_status_ = (test); \ - if (!tt_status_ || tinytest_get_verbosity_() > 1) { \ - printf_type print_; \ - printf_type print1_; \ - printf_type print2_; \ - type value_ = val1_; \ - setup_block; \ - print1_ = print_; \ - value_ = val2_; \ - setup_block; \ - print2_ = print_; \ - TT_DECLARE(tt_status_ ? " OK" : "FAIL", \ - ("assert(%s): " printf_fmt " vs " printf_fmt, str_test, \ - print1_, print2_)); \ - print_ = print1_; \ - cleanup_block; \ - print_ = print2_; \ - cleanup_block; \ - if (!tt_status_) { \ - tinytest_set_test_failed_(); \ - die_on_fail; \ - } \ - } \ - TT_STMT_END - -#define tt_assert_test_type(a, b, str_test, type, test, fmt, die_on_fail) \ - tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \ - { print_ = value_; }, {}, die_on_fail) - -#define tt_assert_test_type_opt(a, b, str_test, type, test, fmt, die_on_fail) \ - tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \ - { print_ = value_ ? value_ : ""; }, {}, \ - die_on_fail) - -/* Helper: assert that a op b, when cast to type. Format the values with - * printf format fmt on failure. */ -#define tt_assert_op_type(a, op, b, type, fmt) \ - tt_assert_test_type(a, b, #a " " #op " " #b, type, (val1_ op val2_), fmt, \ - TT_EXIT_TEST_FUNCTION) - -#define tt_int_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \ - TT_EXIT_TEST_FUNCTION) - -#define tt_uint_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \ - (val1_ op val2_), "%lu", TT_EXIT_TEST_FUNCTION) - -#define tt_ptr_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \ - "%p", TT_EXIT_TEST_FUNCTION) - -#define tt_str_op(a, op, b) \ - tt_assert_test_type_opt(a, b, #a " " #op " " #b, const char *, \ - (val1_ && val2_ && strcmp(val1_, val2_) op 0), \ - "<%s>", TT_EXIT_TEST_FUNCTION) - -#define tt_mem_op(expr1, op, expr2, len) \ - tt_assert_test_fmt_type( \ - expr1, expr2, #expr1 " " #op " " #expr2, const void *, \ - (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \ - { print_ = tinytest_format_hex_(value_, (len)); }, \ - { \ - if (print_) \ - free(print_); \ - }, \ - TT_EXIT_TEST_FUNCTION); - -#define tt_want_int_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \ - (void)0) - -#define tt_want_uint_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \ - (val1_ op val2_), "%lu", (void)0) - -#define tt_want_ptr_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \ - "%p", (void)0) - -#define tt_want_str_op(a, op, b) \ - tt_assert_test_type(a, b, #a " " #op " " #b, const char *, \ - (strcmp(val1_, val2_) op 0), "<%s>", (void)0) - -#define tt_want_mem_op(expr1, op, expr2, len) \ - tt_assert_test_fmt_type( \ - expr1, expr2, #expr1 " " #op " " #expr2, const void *, \ - (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \ - { print_ = tinytest_format_hex_(value_, (len)); }, \ - { \ - if (print_) \ - free(print_); \ - }, \ - (void)0); - -#endif diff --git a/supportlibs/libsam3/src/libsam3/libsam3.c b/supportlibs/libsam3/src/libsam3/libsam3.c deleted file mode 100644 index 5a645806f..000000000 --- a/supportlibs/libsam3/src/libsam3/libsam3.c +++ /dev/null @@ -1,1345 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include "libsam3.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -//#include -#include -#include -#include -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif -#ifndef SHUT_RDWR -#define SHUT_RDWR 2 -#endif -#endif - -#ifdef __unix__ -#include -#include -#include -#include -#include -#include -#endif -//////////////////////////////////////////////////////////////////////////////// -int libsam3_debug = 0; - -//////////////////////////////////////////////////////////////////////////////// -/* convert struct timeval to milliseconds */ -/* -static inline uint64_t timeval2ms (const struct timeval *tv) { - return ((uint64_t)tv->tv_sec)*1000+((uint64_t)tv->tv_usec)/1000; -} -*/ - -/* convert milliseconds to timeval struct */ -static inline void ms2timeval(struct timeval *tv, uint64_t ms) { - tv->tv_sec = ms / 1000; - tv->tv_usec = (ms % 1000) * 1000; -} - -int sam3tcpSetTimeoutSend(int fd, int timeoutms) { - if (fd >= 0 && timeoutms >= 0) { - struct timeval tv; - // - ms2timeval(&tv, timeoutms); - return (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 ? -1 - : 0); - } - return -1; -} - -int sam3tcpSetTimeoutReceive(int fd, int timeoutms) { - if (fd >= 0 && timeoutms >= 0) { - struct timeval tv; - // - ms2timeval(&tv, timeoutms); - return (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ? -1 - : 0); - } - return -1; -} - -int sam3CheckValidKeyLength(const char *pubkey) { - if (strlen(pubkey) >= SAM3_PUBKEY_SIZE && - strlen(pubkey) <= SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE) { - return 1; - } - return 0; -} - -int sam3tcpConnectIP(uint32_t ip, int port) { - struct sockaddr_in addr; - int fd, val = 1; - char ipstr[18]; - // - if (ip == 0 || ip == 0xffffffffUL || port < 1 || port > 65535) - return -1; - // - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - if (libsam3_debug) - fprintf(stderr, "ERROR: can't create socket\n"); - return -1; - } - // - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = ip; - // - ipstr[0] = 0; - if (libsam3_debug) { - if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_in), ipstr, - sizeof(ipstr), NULL, 0, NI_NUMERICHOST) == 0) { - fprintf(stderr, "connecting to [%s:%d]...\n", ipstr, port); - } - } - // - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); - // - if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { - if (libsam3_debug) - fprintf(stderr, "ERROR: can't connect\n"); - close(fd); - return -1; - } - // - if (libsam3_debug && ipstr[0]) - fprintf(stderr, "connected to [%s:%d]\n", ipstr, port); - // - return fd; -} - -/* returns fd or -1 */ -int sam3tcpConnect(const char *hostname, int port, uint32_t *ip) { - struct hostent *host = NULL; - // - if (hostname == NULL || !hostname[0] || port < 1 || port > 65535) - return -1; - // - host = gethostbyname(hostname); - if (host == NULL || host->h_name == NULL || !host->h_name[0]) { - if (libsam3_debug) - fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); - return -1; - } - // - if (libsam3_debug) { - char ipstr[18]; - // - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr = *((struct in_addr *)host->h_addr); - // - if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_in), ipstr, - sizeof(ipstr), NULL, 0, NI_NUMERICHOST) == 0) { - fprintf(stderr, "resolving: %s is [%s]...\n", hostname, ipstr); - } - } - // - if (ip != NULL) - *ip = ((struct in_addr *)host->h_addr)->s_addr; - return sam3tcpConnectIP(((struct in_addr *)host->h_addr)->s_addr, port); -} - -// <0: error; 0: ok -int sam3tcpDisconnect(int fd) { - if (fd >= 0) { - shutdown(fd, SHUT_RDWR); - return close(fd); - } - // - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// <0: error; 0: ok -int sam3tcpSend(int fd, const void *buf, size_t bufSize) { - const char *c = (const char *)buf; - // - if (fd < 0 || (buf == NULL && bufSize > 0)) - return -1; - // - while (bufSize > 0) { - int wr = send(fd, c, bufSize, MSG_NOSIGNAL); - // - if (wr < 0 && errno == EINTR) - continue; // interrupted by signal - if (wr <= 0) - return -1; // either error or - c += wr; - bufSize -= wr; - } - // - return 0; -} - -/* <0: received (-res) bytes; read error */ -/* can return less that requesten bytes even if `allowPartial` is 0 when - * connection is closed */ -ssize_t sam3tcpReceiveEx(int fd, void *buf, size_t bufSize, int allowPartial) { - char *c = (char *)buf; - ssize_t total = 0; - // - if (fd < 0 || (buf == NULL && bufSize > 0)) - return -1; - // - while (bufSize > 0) { - int rd = recv(fd, c, bufSize, 0); - // - if (rd < 0 && errno == EINTR) - continue; // interrupted by signal - if (rd == 0) - return total; - if (rd < 0) - return -total; - c += rd; - total += rd; - bufSize -= rd; - if (allowPartial) - break; - } - // - return total; -} - -ssize_t sam3tcpReceive(int fd, void *buf, size_t bufSize) { - return sam3tcpReceiveEx(fd, buf, bufSize, 0); -} - -//////////////////////////////////////////////////////////////////////////////// -__attribute__((format(printf, 2, 3))) int sam3tcpPrintf(int fd, const char *fmt, - ...) { - int res; - char buf[1024], *p = buf; - int size = sizeof(buf) - 1; - // - for (;;) { - va_list ap; - char *np; - int n; - // - va_start(ap, fmt); - n = vsnprintf(p, size, fmt, ap); - va_end(ap); - // - if (n > -1 && n < size) - break; - if (n > -1) - size = n + 1; - else - size *= 2; - if (p == buf) { - if ((p = malloc(size + 4)) == NULL) - return -1; - } else { - if ((np = realloc(p, size + 4)) == NULL) { - free(p); - return -1; - } - p = np; - } - } - // - if (libsam3_debug) - fprintf(stderr, "SENDING: %s", p); - res = sam3tcpSend(fd, p, strlen(p)); - if (p != buf) - free(p); - return res; -} - -int sam3tcpReceiveStr(int fd, char *dest, size_t maxSize) { - char *d = dest; - // - if (maxSize < 1 || fd < 0 || dest == NULL) - return -1; - memset(dest, 0, maxSize); - while (maxSize > 1) { - char *e; - int rd = recv(fd, d, maxSize - 1, MSG_PEEK); - // - if (rd < 0 && errno == EINTR) - continue; // interrupted by signal - if (rd == 0) { - rd = recv(fd, d, 1, 0); - if (rd < 0 && errno == EINTR) - continue; // interrupted by signal - if (d[0] == '\n') { - d[0] = 0; // remove '\n' - return 0; - } - } else { - if (rd < 0) - return -1; // error or connection closed; alas - } - // check for EOL - d[maxSize - 1] = 0; - if ((e = strchr(d, '\n')) != NULL) { - rd = e - d + 1; // bytes to receive - if (sam3tcpReceive(fd, d, rd) < 0) - return -1; // alas - d[rd - 1] = 0; // remove '\n' - return 0; // done - } else { - // let's receive this part and go on - if (sam3tcpReceive(fd, d, rd) < 0) - return -1; // alas - maxSize -= rd; - d += rd; - } - } - // alas, the string is too big - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3udpSendToIP(uint32_t ip, int port, const void *buf, size_t bufSize) { - // TODO: ipv6 - struct sockaddr_in addr; - int fd, res; - // - if (buf == NULL || bufSize < 1) - return -1; - if (port < 1 || port > 65535) - port = 7655; - // - if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - if (libsam3_debug) - fprintf(stderr, "ERROR: can't create socket\n"); - return -1; - } - // - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = ip; - // - res = sendto(fd, buf, bufSize, 0, (struct sockaddr *)&addr, sizeof(addr)); - // - if (res < 0) { - if (libsam3_debug) { - res = errno; - fprintf(stderr, "UDP ERROR (%d): %s\n", res, strerror(res)); - } - res = -1; - } else { - if (libsam3_debug) - fprintf(stderr, "UDP: %d bytes sent\n", res); - } - // - close(fd); - // - return (res >= 0 ? 0 : -1); -} - -int sam3udpSendTo(const char *hostname, int port, const void *buf, - size_t bufSize, uint32_t *ip) { - struct hostent *host = NULL; - // TODO: ipv6 - if (buf == NULL || bufSize < 1) - return -1; - if (hostname == NULL || !hostname[0]) - hostname = "localhost"; - if (port < 1 || port > 65535) - port = 7655; - // - host = gethostbyname(hostname); - if (host == NULL || host->h_name == NULL || !host->h_name[0]) { - if (libsam3_debug) - fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); - return -1; - } - // - if (ip != NULL) - *ip = ((struct in_addr *)host->h_addr)->s_addr; - return sam3udpSendToIP(((struct in_addr *)host->h_addr)->s_addr, port, buf, - bufSize); -} - -//////////////////////////////////////////////////////////////////////////////// -void sam3FreeFieldList(SAMFieldList *list) { - while (list != NULL) { - SAMFieldList *c = list; - // - list = list->next; - if (c->name != NULL) - free(c->name); - if (c->value != NULL) - free(c->value); - free(c); - } -} - -void sam3DumpFieldList(const SAMFieldList *list) { - for (; list != NULL; list = list->next) { - fprintf(stderr, "%s=[%s]\n", list->name, list->value); - } -} - -const char *sam3FindField(const SAMFieldList *list, const char *field) { - if (list != NULL && field != NULL) { - for (list = list->next; list != NULL; list = list->next) { - if (list->name != NULL && strcmp(field, list->name) == 0) - return list->value; - } - } - return NULL; -} - -static char *xstrdup(const char *s, int len) { - if (len >= 0) { - char *res = malloc(len + 1); - // - if (res != NULL) { - if (len > 0) - memcpy(res, s, len); - res[len] = 0; - } - // - return res; - } - // - return NULL; -} - -// returns NULL if there are no more tokens -static inline const char *xstrtokend(const char *s) { - while (*s && isspace(*s)) - ++s; - // - if (*s) { - char qch = 0; - // - while (*s) { - if (*s == qch) { - qch = 0; - } else if (*s == '"') { - qch = *s; - } else if (qch) { - if (*s == '\\' && s[1]) - ++s; - } else if (isspace(*s)) { - break; - } - ++s; - } - } else { - s = NULL; - } - // - return s; -} - -SAMFieldList *sam3ParseReply(const char *rep) { - SAMFieldList *first = NULL, *last, *c; - const char *p = rep, *e, *e1; - // - // first 2 words - while (*p && isspace(*p)) - ++p; - if ((e = xstrtokend(p)) == NULL) - return NULL; - if ((e1 = xstrtokend(e)) == NULL) - return NULL; - // - if ((first = last = c = malloc(sizeof(SAMFieldList))) == NULL) - return NULL; - c->next = NULL; - c->name = c->value = NULL; - if ((c->name = xstrdup(p, e - p)) == NULL) - goto error; - while (*e && isspace(*e)) - ++e; - if ((c->value = xstrdup(e, e1 - e)) == NULL) - goto error; - // - p = e1; - while (*p) { - while (*p && isspace(*p)) - ++p; - if ((e = xstrtokend(p)) == NULL) - break; // no more tokens - // - if (libsam3_debug) - fprintf(stderr, "<%s>\n", p); - // - if ((c = malloc(sizeof(SAMFieldList))) == NULL) - return NULL; - c->next = NULL; - c->name = c->value = NULL; - last->next = c; - last = c; - // - if ((e1 = memchr(p, '=', e - p)) != NULL) { - // key=value - if ((c->name = xstrdup(p, e1 - p)) == NULL) - goto error; - if ((c->value = xstrdup(e1 + 1, e - e1 - 1)) == NULL) - goto error; - } else { - // only key (there is no such replies in SAMv3, but... - if ((c->name = xstrdup(p, e - p)) == NULL) - goto error; - if ((c->value = strdup("")) == NULL) - goto error; - } - p = e; - } - // - if (libsam3_debug) - sam3DumpFieldList(first); - // - return first; -error: - sam3FreeFieldList(first); - return NULL; -} - -// NULL: error; else: list of fields -// first item is always 2-word reply, with first word in name and second in -// value -SAMFieldList *sam3ReadReply(int fd) { - char rep[2048]; // should be enough for any reply - // - if (sam3tcpReceiveStr(fd, rep, sizeof(rep)) < 0) - return NULL; - if (libsam3_debug) - fprintf(stderr, "SAM REPLY: [%s]\n", rep); - return sam3ParseReply(rep); -} - -// example: -// r0: 'HELLO' -// r1: 'REPLY' -// field: NULL or 'RESULT' -// VALUE: NULL or 'OK' -// returns bool -int sam3IsGoodReply(const SAMFieldList *list, const char *r0, const char *r1, - const char *field, const char *value) { - if (list != NULL && list->name != NULL && list->value != NULL) { - if (r0 != NULL && strcmp(r0, list->name) != 0) - return 0; - if (r1 != NULL && strcmp(r1, list->value) != 0) - return 0; - if (field != NULL) { - for (list = list->next; list != NULL; list = list->next) { - if (list->name == NULL || list->value == NULL) - return 0; // invalid list, heh - if (strcmp(field, list->name) == 0) { - if (value != NULL && strcmp(value, list->value) != 0) - return 0; - return 1; - } - } - } - return 1; - } - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// by Bob Jenkins -// public domain -// http://burtleburtle.net/bob/rand/smallprng.html -// -//////////////////////////////////////////////////////////////////////////////// -typedef struct { - uint32_t a, b, c, d; -} BJRandCtx; - -#define BJPRNG_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) - -static uint32_t bjprngRand(BJRandCtx *x) { - uint32_t e; - /* original: - e = x->a-BJPRNG_ROT(x->b, 27); - x->a = x->b^BJPRNG_ROT(x->c, 17); - x->b = x->c+x->d; - x->c = x->d+e; - x->d = e+x->a; - */ - /* better, but slower at least in idiotic m$vc */ - e = x->a - BJPRNG_ROT(x->b, 23); - x->a = x->b ^ BJPRNG_ROT(x->c, 16); - x->b = x->c + BJPRNG_ROT(x->d, 11); - x->c = x->d + e; - x->d = e + x->a; - // - return x->d; -} - -static void bjprngInit(BJRandCtx *x, uint32_t seed) { - x->a = 0xf1ea5eed; - x->b = x->c = x->d = seed; - for (int i = 0; i < 20; ++i) - bjprngRand(x); -} - -static inline uint32_t hashint(uint32_t a) { - a -= (a << 6); - a ^= (a >> 17); - a -= (a << 9); - a ^= (a << 4); - a -= (a << 3); - a ^= (a << 10); - a ^= (a >> 15); - return a; -} - -static uint32_t genSeed(void) { - uint32_t res; -#ifndef WIN32 - struct sysinfo sy; - pid_t pid = getpid(); - // - sysinfo(&sy); - res = hashint((uint32_t)pid) ^ hashint((uint32_t)time(NULL)) ^ - hashint((uint32_t)sy.sharedram) ^ hashint((uint32_t)sy.bufferram) ^ - hashint((uint32_t)sy.uptime); -#else - res = hashint((uint32_t)GetCurrentProcessId()) ^ - hashint((uint32_t)GetTickCount()); -#endif - return hashint(res); -} - -//////////////////////////////////////////////////////////////////////////////// -size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen) { - BJRandCtx rc; - size_t len; - size_t retlen; - // - if (dest == NULL || minlen < 1 || maxlen < minlen || minlen > 65536 || - maxlen > 65536) - return -1; - bjprngInit(&rc, genSeed()); - len = minlen + (bjprngRand(&rc) % (maxlen - minlen + 1)); - retlen = len; - while (len--) { - int ch = bjprngRand(&rc) % 64; - // - if (ch >= 0 && ch < 10) - ch += '0'; - else if (ch >= 10 && ch < 36) - ch += 'A' - 10; - else if (ch >= 36 && ch < 62) - ch += 'a' - 36; - else if (ch == 62) - ch = '-'; - else if (ch == 63) - ch = '_'; - else if (ch > 64) - abort(); - *dest++ = ch; - } - *dest++ = 0; - return retlen; -} - -//////////////////////////////////////////////////////////////////////////////// -static int sam3HandshakeInternal(int fd) { - SAMFieldList *rep = NULL; - // - if (sam3tcpPrintf(fd, "HELLO VERSION MIN=3.0 MAX=3.1\n") < 0) - goto error; - rep = sam3ReadReply(fd); - if (!sam3IsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK")) - goto error; - sam3FreeFieldList(rep); - return fd; -error: - sam3tcpDisconnect(fd); - if (rep != NULL) - sam3FreeFieldList(rep); - return -1; -} - -int sam3HandshakeIP(uint32_t ip, int port) { - int fd; - // - if ((fd = sam3tcpConnectIP(ip, (port < 1 || port > 65535 ? 7656 : port))) < 0) - return -1; - return sam3HandshakeInternal(fd); -} - -int sam3Handshake(const char *hostname, int port, uint32_t *ip) { - int fd; - // - if ((fd = sam3tcpConnect( - (hostname == NULL || !hostname[0] ? "localhost" : hostname), - (port < 1 || port > 65535 ? 7656 : port), ip)) < 0) - return -1; - return sam3HandshakeInternal(fd); -} - -//////////////////////////////////////////////////////////////////////////////// -static inline void strcpyerr(Sam3Session *ses, const char *errstr) { - memset(ses->error, 0, sizeof(ses->error)); - if (errstr != NULL) - strncpy(ses->error, errstr, sizeof(ses->error) - 1); -} - -int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port, - int sigType) { - if (ses != NULL) { - SAMFieldList *rep = NULL; - int fd, res = -1; - static const char *sigtypes[5] = { - "SIGNATURE_TYPE=DSA_SHA1", "SIGNATURE_TYPE=ECDSA_SHA256_P256", - "SIGNATURE_TYPE=ECDSA_SHA384_P384", "SIGNATURE_TYPE=ECDSA_SHA512_P521", - "SIGNATURE_TYPE=EdDSA_SHA512_Ed25519"}; - // - if ((fd = sam3Handshake(hostname, port, NULL)) < 0) { - strcpyerr(ses, "I2P_ERROR"); - return -1; - } - // - if (sam3tcpPrintf(fd, "DEST GENERATE %s\n", sigtypes[sigType]) >= 0) { - if ((rep = sam3ReadReply(fd)) != NULL && - sam3IsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) { - const char *pub = sam3FindField(rep, "PUB"), - *priv = sam3FindField(rep, "PRIV"); - // - if (pub != NULL && sam3CheckValidKeyLength(pub) && priv != NULL && - strlen(priv) >= SAM3_PRIVKEY_MIN_SIZE) { - strcpy(ses->pubkey, pub); - strcpy(ses->privkey, priv); - res = 0; - } - } - } - // - sam3FreeFieldList(rep); - sam3tcpDisconnect(fd); - // - return res; - } - return -1; -} - -int sam3NameLookup(Sam3Session *ses, const char *hostname, int port, - const char *name) { - if (ses != NULL && name != NULL && name[0]) { - SAMFieldList *rep = NULL; - int fd, res = -1; - // - if ((fd = sam3Handshake(hostname, port, NULL)) < 0) { - strcpyerr(ses, "I2P_ERROR"); - return -1; - } - // - strcpyerr(ses, "I2P_ERROR"); - if (sam3tcpPrintf(fd, "NAMING LOOKUP NAME=%s\n", name) >= 0) { - if ((rep = sam3ReadReply(fd)) != NULL && - sam3IsGoodReply(rep, "NAMING", "REPLY", "RESULT", NULL)) { - const char *rs = sam3FindField(rep, "RESULT"), - *pub = sam3FindField(rep, "VALUE"); - // - if (strcmp(rs, "OK") == 0) { - if (pub != NULL && sam3CheckValidKeyLength(pub)) { - strcpy(ses->destkey, pub); - strcpyerr(ses, NULL); - res = 0; - } - } else if (rs[0]) { - strcpyerr(ses, rs); - } - } - } - // - sam3FreeFieldList(rep); - sam3tcpDisconnect(fd); - // - return res; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -static int sam3CloseConnectionInternal(Sam3Connection *conn) { - return (conn->fd >= 0 ? sam3tcpDisconnect(conn->fd) : 0); -} - -int sam3CloseConnection(Sam3Connection *conn) { - if (conn != NULL) { - int res = sam3CloseConnectionInternal(conn); - // - if (conn->ses != NULL) { - for (Sam3Connection *p = NULL, *c = conn->ses->connlist; c != NULL; - p = c, c = c->next) { - if (c == conn) { - if (p == NULL) - conn->ses->connlist = c->next; - else - p->next = c->next; - break; - } - } - } - free(conn); - // - return res; - } - return -1; -} - -int sam3CloseSession(Sam3Session *ses) { - if (ses != NULL) { - for (Sam3Connection *n, *c = ses->connlist; c != NULL; c = n) { - n = c->next; - sam3CloseConnectionInternal(c); - free(c); - } - if (ses->fwd_fd >= 0) - sam3tcpDisconnect(ses->fwd_fd); - if (ses->fd >= 0) - sam3tcpDisconnect(ses->fd); - memset(ses, 0, sizeof(Sam3Session)); - ses->fd = -1; - return 0; - } - return -1; -} - -int sam3CreateSilentSession(Sam3Session *ses, const char *hostname, int port, - const char *privkey, Sam3SessionType type, - Sam3SigType sigType, const char *params) { - int r = - sam3CreateSession(ses, hostname, port, privkey, type, sigType, params); - if (r != 0) { - return r; - } - ses->silent = true; - return 0; -} - -int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, - const char *privkey, Sam3SessionType type, - Sam3SigType sigType, const char *params) { - if (ses != NULL) { - static const char *typenames[3] = {"RAW", "DATAGRAM", "STREAM"}; - static const char *sigtypes[5] = { - "SIGNATURE_TYPE=DSA_SHA1", "SIGNATURE_TYPE=ECDSA_SHA256_P256", - "SIGNATURE_TYPE=ECDSA_SHA384_P384", "SIGNATURE_TYPE=ECDSA_SHA512_P521", - "SIGNATURE_TYPE=EdDSA_SHA512_Ed25519"}; - - SAMFieldList *rep; - const char *v = NULL; - const char *pdel = (params != NULL ? " " : ""); - // - memset(ses, 0, sizeof(Sam3Session)); - ses->fd = -1; - ses->fwd_fd = -1; - ses->silent = false; - // - if (privkey != NULL && strlen(privkey) < SAM3_PRIVKEY_MIN_SIZE) - goto error; - if ((int)type < 0 || (int)type > 2) - goto error; - if (privkey == NULL) - privkey = "TRANSIENT"; - // - ses->type = type; - ses->sigType = sigType; - ses->port = (type == SAM3_SESSION_STREAM ? (port ? port : 7656) : 7655); - sam3GenChannelName(ses->channel, 32, 64); - if (libsam3_debug) - fprintf(stderr, "sam3CreateSession: channel=[%s]\n", ses->channel); - // - if ((ses->fd = sam3Handshake(hostname, port, &ses->ip)) < 0) - goto error; - // - if (libsam3_debug) - fprintf(stderr, "sam3CreateSession: creating session (%s)...\n", - typenames[(int)type]); - if (sam3tcpPrintf( - ses->fd, "SESSION CREATE STYLE=%s ID=%s DESTINATION=%s %s %s %s\n", - typenames[(int)type], ses->channel, privkey, sigtypes[(int)sigType], - pdel, (params != NULL ? params : "")) < 0) - goto error; - if ((rep = sam3ReadReply(ses->fd)) == NULL) - goto error; - if (!sam3IsGoodReply(rep, "SESSION", "STATUS", "RESULT", "OK") || - (v = sam3FindField(rep, "DESTINATION")) == NULL || - strlen(v) < SAM3_PRIVKEY_MIN_SIZE) { - if (libsam3_debug) - fprintf(stderr, "sam3CreateSession: invalid reply (%ld)...\n", - (v != NULL ? strlen(v) : -1)); - if (libsam3_debug) - sam3DumpFieldList(rep); - sam3FreeFieldList(rep); - goto error; - } - // save our keys - strcpy(ses->privkey, v); - sam3FreeFieldList(rep); - // get public key - if (sam3tcpPrintf(ses->fd, "NAMING LOOKUP NAME=ME\n") < 0) - goto error; - if ((rep = sam3ReadReply(ses->fd)) == NULL) - goto error; - v = NULL; - if (!sam3IsGoodReply(rep, "NAMING", "REPLY", "RESULT", "OK") || - (v = sam3FindField(rep, "VALUE")) == NULL || - !sam3CheckValidKeyLength(v)) { - if (libsam3_debug) - fprintf(stderr, "sam3CreateSession: invalid NAMING reply (%ld)...\n", - (v != NULL ? strlen(v) : -1)); - if (libsam3_debug) - sam3DumpFieldList(rep); - sam3FreeFieldList(rep); - goto error; - } - strcpy(ses->pubkey, v); - sam3FreeFieldList(rep); - // - if (libsam3_debug) - fprintf(stderr, "sam3CreateSession: complete.\n"); - return 0; - } -error: - sam3CloseSession(ses); - return -1; -} - -Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) { - if (ses != NULL) { - SAMFieldList *rep; - Sam3Connection *conn; - // - if (ses->type != SAM3_SESSION_STREAM) { - strcpyerr(ses, "INVALID_SESSION_TYPE"); - return NULL; - } - if (ses->fd < 0) { - strcpyerr(ses, "INVALID_SESSION"); - return NULL; - } - if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) { - strcpyerr(ses, "INVALID_KEY"); - return NULL; - } - if ((conn = calloc(1, sizeof(Sam3Connection))) == NULL) { - strcpyerr(ses, "NO_MEMORY"); - return NULL; - } - if ((conn->fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { - strcpyerr(ses, "IO_ERROR_SK"); - goto error; - } - if (sam3tcpPrintf(conn->fd, - "STREAM CONNECT ID=%s DESTINATION=%s SILENT=%s\n", - ses->channel, destkey, checkIsSilent(ses)) < 0) { - strcpyerr(ses, "IO_ERROR"); - goto error; - } - if ((rep = sam3ReadReply(conn->fd)) == NULL) { - strcpyerr(ses, "IO_ERROR"); - goto error; - } - if (!ses->silent) { - if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR")); - sam3CloseConnectionInternal(conn); - free(conn); - conn = NULL; - } else { - // no error - strcpyerr(ses, NULL); - } - } - sam3FreeFieldList(rep); - if (conn != NULL) { - strcpy(conn->destkey, destkey); - conn->ses = ses; - conn->next = ses->connlist; - ses->connlist = conn; - } - return conn; - error: - sam3CloseConnectionInternal(conn); - free(conn); - return NULL; - } - return NULL; -} - -Sam3Connection *sam3StreamAccept(Sam3Session *ses) { - if (ses != NULL) { - SAMFieldList *rep = NULL; - char repstr[1024]; - Sam3Connection *conn; - // - if (ses->type != SAM3_SESSION_STREAM) { - strcpyerr(ses, "INVALID_SESSION_TYPE"); - return NULL; - } - if (ses->fd < 0) { - strcpyerr(ses, "INVALID_SESSION"); - return NULL; - } - if ((conn = calloc(1, sizeof(Sam3Connection))) == NULL) { - strcpyerr(ses, "NO_MEMORY"); - return NULL; - } - if ((conn->fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { - strcpyerr(ses, "IO_ERROR_SK"); - goto error; - } - if (sam3tcpPrintf(conn->fd, "STREAM ACCEPT ID=%s\n", ses->channel) < 0) { - strcpyerr(ses, "IO_ERROR_PF"); - goto error; - } - if ((rep = sam3ReadReply(conn->fd)) == NULL) { - strcpyerr(ses, "IO_ERROR_RP"); - goto error; - } - if (!ses->silent) { - if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); - goto error; - } - } - if (sam3tcpReceiveStr(conn->fd, repstr, sizeof(repstr)) < 0) { - strcpyerr(ses, "IO_ERROR_RP1"); - goto error; - } - sam3FreeFieldList(rep); - if ((rep = sam3ParseReply(repstr)) != NULL) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES1")); - goto error; - } - if (!sam3CheckValidKeyLength(repstr)) { - strcpyerr(ses, "INVALID_KEY"); - goto error; - } - sam3FreeFieldList(rep); - strcpy(conn->destkey, repstr); - conn->ses = ses; - conn->next = ses->connlist; - ses->connlist = conn; - strcpyerr(ses, NULL); - return conn; - error: - if (rep != NULL) - sam3FreeFieldList(rep); - sam3CloseConnectionInternal(conn); - free(conn); - return NULL; - } - return NULL; -} - -const char *checkIsSilent(Sam3Session *ses) { - if (ses->silent == true) { - return "true"; - } else { - return "false"; - } -} - -int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) { - if (ses != NULL) { - SAMFieldList *rep = NULL; - // - if (ses->type != SAM3_SESSION_STREAM) { - strcpyerr(ses, "INVALID_SESSION_TYPE"); - return -1; - } - if (ses->fd < 0) { - strcpyerr(ses, "INVALID_SESSION"); - return -1; - } - if (ses->fwd_fd >= 0) { - strcpyerr(ses, "DUPLICATE_FORWARD"); - return -1; - } - if ((ses->fwd_fd = sam3HandshakeIP(ses->ip, ses->port)) < 0) { - strcpyerr(ses, "IO_ERROR_SK"); - goto error; - } - if (sam3tcpPrintf(ses->fwd_fd, - "STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=%s\n", - ses->channel, port, hostname, checkIsSilent(ses)) < 0) { - strcpyerr(ses, "IO_ERROR_PF"); - goto error; - } - if ((rep = sam3ReadReply(ses->fwd_fd)) == NULL) { - strcpyerr(ses, "IO_ERROR_RP"); - goto error; - } - if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3FindField(rep, "RESULT"); - // - strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES")); - goto error; - } - sam3FreeFieldList(rep); - strcpyerr(ses, NULL); - return 0; - error: - if (rep != NULL) - sam3FreeFieldList(rep); - return -1; - } - return -1; -} - -int sam3DatagramSend(Sam3Session *ses, const char *destkey, const void *buf, - size_t bufsize) { - if (ses != NULL) { - char *dbuf; - int res, dbufsz; - // - if (ses->type == SAM3_SESSION_STREAM) { - strcpyerr(ses, "INVALID_SESSION_TYPE"); - return -1; - } - if (ses->fd < 0) { - strcpyerr(ses, "INVALID_SESSION"); - return -1; - } - if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) { - strcpyerr(ses, "INVALID_KEY"); - return -1; - } - if (buf == NULL || bufsize < 1 || bufsize > 31744) { - strcpyerr(ses, "INVALID_DATA"); - return -1; - } - dbufsz = bufsize + 4 + SAM3_PUBKEY_SIZE + 1 + strlen(ses->channel) + 1; - if ((dbuf = malloc(dbufsz)) == NULL) { - strcpyerr(ses, "OUT_OF_MEMORY"); - return -1; - } - sprintf(dbuf, "3.0 %s %s\n", ses->channel, destkey); - memcpy(dbuf + strlen(dbuf), buf, bufsize); - res = sam3udpSendToIP(ses->ip, ses->port, dbuf, dbufsz); - free(dbuf); - strcpyerr(ses, (res < 0 ? "IO_ERROR" : NULL)); - return (res < 0 ? -1 : 0); - } - return -1; -} - -ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize) { - if (ses != NULL) { - SAMFieldList *rep; - const char *v; - ssize_t size = 0; - // - if (ses->type == SAM3_SESSION_STREAM) { - strcpyerr(ses, "INVALID_SESSION_TYPE"); - return -1; - } - if (ses->fd < 0) { - strcpyerr(ses, "INVALID_SESSION"); - return -1; - } - if (buf == NULL || bufsize < 1) { - strcpyerr(ses, "INVALID_BUFFER"); - return -1; - } - if ((rep = sam3ReadReply(ses->fd)) == NULL) { - strcpyerr(ses, "IO_ERROR"); - return -1; - } - if (!sam3IsGoodReply(rep, "DATAGRAM", "RECEIVED", "SIZE", NULL)) { - strcpyerr(ses, "I2P_ERROR"); - sam3FreeFieldList(rep); - return -1; - } - // - if ((v = sam3FindField(rep, "DESTINATION")) != NULL && - sam3CheckValidKeyLength(v)) - strncpy(ses->destkey, v, sizeof(ses->destkey)); - v = sam3FindField(rep, "SIZE"); // we have this field -- for sure - if (!v[0] || !isdigit(*v)) { - strcpyerr(ses, "I2P_ERROR_SIZE"); - sam3FreeFieldList(rep); - return -1; - } - // - while (*v && isdigit(*v)) { - if ((size = size * 10 + v[0] - '0') > bufsize) { - strcpyerr(ses, "I2P_ERROR_BUFFER_TOO_SMALL"); - sam3FreeFieldList(rep); - return -1; - } - ++v; - } - // - if (*v) { - strcpyerr(ses, "I2P_ERROR_SIZE"); - sam3FreeFieldList(rep); - return -1; - } - sam3FreeFieldList(rep); - // - if (sam3tcpReceive(ses->fd, buf, size) != size) { - strcpyerr(ses, "IO_ERROR"); - return -1; - } - strcpyerr(ses, NULL); - return size; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// output 8 bytes for every 5 input -// return size or <0 on error -ssize_t sam3Base32Encode(char *dest, size_t destsz, const void *srcbuf, - size_t srcsize) { - if (dest != NULL && srcbuf != NULL && srcsize >= 0) { - static const char *const b32chars = "abcdefghijklmnopqrstuvwxyz234567="; - const unsigned char *src = (const unsigned char *)srcbuf; - ssize_t destsize = 0; - // - while (srcsize > 0) { - int blksize = (srcsize < 5 ? srcsize : 5); - unsigned char n[8]; - // - memset(n, 0, sizeof(n)); - switch (blksize) { - case 5: - n[7] = (src[4] & 0x1f); - n[6] = ((src[4] & 0xe0) >> 5); - case 4: - n[6] |= ((src[3] & 0x03) << 3); - n[5] = ((src[3] & 0x7c) >> 2); - n[4] = ((src[3] & 0x80) >> 7); - case 3: - n[4] |= ((src[2] & 0x0f) << 1); - n[3] = ((src[2] & 0xf0) >> 4); - case 2: - n[3] |= ((src[1] & 0x01) << 4); - n[2] = ((src[1] & 0x3e) >> 1); - n[1] = ((src[1] & 0xc0) >> 6); - case 1: - n[1] |= ((src[0] & 0x07) << 2); - n[0] = ((src[0] & 0xf8) >> 3); - break; - } - src += blksize; - srcsize -= blksize; - // pad - switch (blksize) { - case 1: - n[2] = n[3] = 32; - case 2: - n[4] = 32; - case 3: - n[5] = n[6] = 32; - case 4: - n[7] = 32; - case 5: - break; - } - // output - if (destsize + 8 <= destsz) { - for (int f = 0; f < 8; ++f) - *dest++ = b32chars[n[f]]; - } - destsize += 8; - } - if (destsize <= destsz) { - *dest++ = 0; // make valid asciiz string - } - return destsize; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// output 8 bytes for every 5 input -// return size or <0 on error -ssize_t sam3Base32Decode(char *dest, size_t destsz, const void *srcbuf, - size_t srcsize) { - if (dest != NULL && srcbuf != NULL && srcsize >= 0) { - static const char *const b32chars = "abcdefghijklmnopqrstuvwxyz234567="; - const unsigned char *src = (const unsigned char *)srcbuf; - int destsize = 0; - // - while (srcsize > 0) { - int blksize = (srcsize < 5 ? srcsize : 5); - unsigned char n[8]; - // - memset(n, 0, sizeof(n)); - switch (blksize) { - case 5: - n[7] = (src[4] & 0x1f); - n[6] = ((src[4] & 0xe0) >> 5); - case 4: - n[6] |= ((src[3] & 0x03) << 3); - n[5] = ((src[3] & 0x7c) >> 2); - n[4] = ((src[3] & 0x80) >> 7); - case 3: - n[4] |= ((src[2] & 0x0f) << 1); - n[3] = ((src[2] & 0xf0) >> 4); - case 2: - n[3] |= ((src[1] & 0x01) << 4); - n[2] = ((src[1] & 0x3e) >> 1); - n[1] = ((src[1] & 0xc0) >> 6); - case 1: - n[1] |= ((src[0] & 0x07) << 2); - n[0] = ((src[0] & 0xf8) >> 3); - break; - } - src += blksize; - srcsize -= blksize; - // pad - switch (blksize) { - case 1: - n[2] = n[3] = 32; - case 2: - n[4] = 32; - case 3: - n[5] = n[6] = 32; - case 4: - n[7] = 32; - case 5: - break; - } - // output - if (destsize + 8 <= destsz) { - for (int f = 0; f < 8; ++f) - *dest++ = b32chars[n[f]]; - } - destsize += 8; - } - if (destsize <= destsz) { - *dest++ = 0; // make valid asciiz string - } - return destsize; - } - return -1; -} diff --git a/supportlibs/libsam3/src/libsam3/libsam3.h b/supportlibs/libsam3/src/libsam3/libsam3.h deleted file mode 100644 index 16942f594..000000000 --- a/supportlibs/libsam3/src/libsam3/libsam3.h +++ /dev/null @@ -1,314 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#ifndef LIBSAM3_H -#define LIBSAM3_H - -#include -#include -#include - -#ifndef _SSIZE_T_DEFINED -#define _SSIZE_T_DEFINED -#undef ssize_t -#ifdef _WIN64 -typedef signed int64 ssize_t; -typedef int ssize_t; -#endif /* _WIN64 */ -#endif /* _SSIZE_T_DEFINED */ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////////////// -extern int libsam3_debug; - -//////////////////////////////////////////////////////////////////////////////// -#define SAM3_HOST_DEFAULT (NULL) -#define SAM3_PORT_DEFAULT (0) - -#define SAM3_DESTINATION_TRANSIENT (NULL) - -#define SAM3_PUBKEY_SIZE (516) -#define SAM3_CERT_SIZE (100) -#define SAM3_PRIVKEY_MIN_SIZE (884) - -//////////////////////////////////////////////////////////////////////////////// -/* returns fd or -1 */ -/* 'ip': host IP; can be NULL */ -extern int sam3tcpConnect(const char *hostname, int port, uint32_t *ip); -extern int sam3tcpConnectIP(uint32_t ip, int port); - -/* <0: error; 0: ok */ -extern int sam3tcpDisconnect(int fd); - -/* <0: error; 0: ok */ -extern int sam3tcpSetTimeoutSend(int fd, int timeoutms); - -/* <0: error; 0: ok */ -extern int sam3tcpSetTimeoutReceive(int fd, int timeoutms); - -/* <0: error; 0: ok */ -/* sends the whole buffer */ -extern int sam3tcpSend(int fd, const void *buf, size_t bufSize); - -/* <0: received (-res) bytes; read error */ -/* can return less that requesten bytes even if `allowPartial` is 0 when - * connection is closed */ -extern ssize_t sam3tcpReceiveEx(int fd, void *buf, size_t bufSize, - int allowPartial); - -extern ssize_t sam3tcpReceive(int fd, void *buf, size_t bufSize); - -extern int sam3tcpPrintf(int fd, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); - -extern int sam3tcpReceiveStr(int fd, char *dest, size_t maxSize); - -/* pass NULL for 'localhost' and 0 for 7655 */ -/* 'ip': host IP; can be NULL */ -extern int sam3udpSendTo(const char *hostname, int port, const void *buf, - size_t bufSize, uint32_t *ip); -extern int sam3udpSendToIP(uint32_t ip, int port, const void *buf, - size_t bufSize); - -//////////////////////////////////////////////////////////////////////////////// -typedef struct SAMFieldList { - char *name; - char *value; - struct SAMFieldList *next; -} SAMFieldList; - -extern void sam3FreeFieldList(SAMFieldList *list); -extern void sam3DumpFieldList(const SAMFieldList *list); - -/* read and parse SAM reply */ -/* NULL: error; else: list of fields */ -/* first item is always 2-word reply, with first word in name and second in - * value */ -extern SAMFieldList *sam3ReadReply(int fd); - -extern SAMFieldList *sam3ParseReply(const char *rep); - -/* - * example: - * r0: 'HELLO' - * r1: 'REPLY' - * field: NULL or 'RESULT' - * VALUE: NULL or 'OK' - * returns bool - */ -extern int sam3IsGoodReply(const SAMFieldList *list, const char *r0, - const char *r1, const char *field, - const char *value); - -extern const char *sam3FindField(const SAMFieldList *list, const char *field); - -//////////////////////////////////////////////////////////////////////////////// -/* pass NULL for 'localhost' and 0 for 7656 */ -/* returns <0 on error or socket fd on success */ -extern int sam3Handshake(const char *hostname, int port, uint32_t *ip); -extern int sam3HandshakeIP(uint32_t ip, int port); - -//////////////////////////////////////////////////////////////////////////////// -typedef enum { - SAM3_SESSION_RAW, - SAM3_SESSION_DGRAM, - SAM3_SESSION_STREAM -} Sam3SessionType; - -typedef enum { - DSA_SHA1, - ECDSA_SHA256_P256, - ECDSA_SHA384_P384, - ECDSA_SHA512_P521, - EdDSA_SHA512_Ed25519 -} Sam3SigType; - -typedef struct Sam3Session { - Sam3SessionType type; - Sam3SigType sigType; - int fd; - char privkey[SAM3_PRIVKEY_MIN_SIZE + 1]; // destination private key (asciiz) - char pubkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + - 1]; // destination public key (asciiz) - char channel[66]; // name of this sam session (asciiz) - char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + - 1]; // for DGRAM sessions (asciiz) - // int destsig; - char error[32]; // error message (asciiz) - uint32_t ip; - int port; // this will be changed to UDP port for DRAM/RAW (can be 0) - struct Sam3Connection *connlist; // list of opened connections - int fwd_fd; - bool silent; -} Sam3Session; - -typedef struct Sam3Connection { - Sam3Session *ses; - struct Sam3Connection *next; - int fd; - char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE + - 1]; // remote destination public key (asciiz) - int destcert; - char error[32]; // error message (asciiz) -} Sam3Connection; - -//////////////////////////////////////////////////////////////////////////////// -/* - * create SAM session - * pass NULL as hostname for 'localhost' and 0 as port for 7656 - * pass NULL as privkey to create TRANSIENT session - * 'params' can be NULL - * see http://www.i2p2.i2p/i2cp.html#options for common options, - * and http://www.i2p2.i2p/streaming.html#options for STREAM options - * if result<0: error, 'ses' fields are undefined, no need to call - * sam3CloseSession() if result==0: ok, all 'ses' fields are filled - * TODO: don't clear 'error' field on error (and set it to something meaningful) - */ -extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port, - const char *privkey, Sam3SessionType type, - Sam3SigType sigType, const char *params); - -/* - * create SAM session with SILENT=True - * pass NULL as hostname for 'localhost' and 0 as port for 7656 - * pass NULL as privkey to create TRANSIENT session - * 'params' can be NULL - * see http://www.i2p2.i2p/i2cp.html#options for common options, - * and http://www.i2p2.i2p/streaming.html#options for STREAM options - * if result<0: error, 'ses' fields are undefined, no need to call - * sam3CloseSession() if result==0: ok, all 'ses' fields are filled - * TODO: don't clear 'error' field on error (and set it to something meaningful) - */ -extern int sam3CreateSilentSession(Sam3Session *ses, const char *hostname, - int port, const char *privkey, - Sam3SessionType type, Sam3SigType sigType, - const char *params); - -/* - * close SAM session (and all it's connections) - * returns <0 on error, 0 on ok - * 'ses' must be properly initialized - */ -extern int sam3CloseSession(Sam3Session *ses); - -/* - * check to see if a SAM session is silent and output - * characters for use with sam3tcpPrintf() checkIsSilent - */ - -const char *checkIsSilent(Sam3Session *ses); - -/* - * Check to make sure that the destination in use is of a valid length, returns - * 1 if true and 0 if false. - */ -int sam3CheckValidKeyLength(const char *pubkey); - -/* - * open stream connection to 'destkey' endpoint - * 'destkey' is 516-byte public key (asciiz) - * returns <0 on error, fd on ok - * you still have to call sam3CloseSession() on failure - * sets ses->error on error - */ -extern Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey); - -/* - * accepts stream connection and sets 'destkey' - * 'destkey' is 516-byte public key - * returns <0 on error, fd on ok - * you still have to call sam3CloseSession() on failure - * sets ses->error on error - * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() - */ -extern Sam3Connection *sam3StreamAccept(Sam3Session *ses); - -/* - * sets up forwarding stream connection - * returns <0 on error, 0 on ok - * you still have to call sam3CloseSession() on failure - * sets ses->error on error - * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() - */ -extern int sam3StreamForward(Sam3Session *ses, const char *hostname, int port); - -/* - * close SAM connection - * returns <0 on error, 0 on ok - * 'conn' must be properly initialized - * 'conn' is invalid after call - */ -extern int sam3CloseConnection(Sam3Connection *conn); - -//////////////////////////////////////////////////////////////////////////////// -/* - * generate new keypair - * fills 'privkey' and 'pubkey' only - * you should not call sam3CloseSession() on 'ses' - * will not set 'error' field - * returns <0 on error, 0 on ok - */ -extern int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port, - int sigType); - -/* - * do name lookup (something like gethostbyname()) - * fills 'destkey' only - * you should not call sam3CloseSession() on 'ses' - * will set 'error' field - * returns <0 on error, 0 on ok - */ -extern int sam3NameLookup(Sam3Session *ses, const char *hostname, int port, - const char *name); - -//////////////////////////////////////////////////////////////////////////////// -/* - * sends datagram to 'destkey' endpoint - * 'destkey' is 516-byte public key - * returns <0 on error, 0 on ok - * you still have to call sam3CloseSession() on failure - * sets ses->error on error - * don't send datagrams bigger than 31KB! - */ -extern int sam3DatagramSend(Sam3Session *ses, const char *destkey, - const void *buf, size_t bufsize); - -/* - * receives datagram and sets 'destkey' to source pubkey (if not RAW) - * returns <0 on error (buffer too small is error too) or number of bytes - * written to 'buf' you still have to call sam3CloseSession() on failure sets - * ses->error on error will necer receive datagrams bigger than 31KB (32KB for - * RAW) - */ -extern ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize); - -/* - * generate random sam channel name - * return the size of the string - */ -extern size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen); - -//////////////////////////////////////////////////////////////////////////////// -// NOT including '\0' terminator -static inline size_t sam3Base32EncodedLength(size_t size) { - return (((size + 5 - 1) / 5) * 8); -} - -// output 8 bytes for every 5 input -// return size or <0 on error -extern ssize_t sam3Base32Encode(char *dest, size_t destsz, const void *srcbuf, - size_t srcsize); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.c b/supportlibs/libsam3/src/libsam3a/libsam3a.c deleted file mode 100644 index e5983b008..000000000 --- a/supportlibs/libsam3/src/libsam3a/libsam3a.c +++ /dev/null @@ -1,1771 +0,0 @@ -/* async SAMv3 library - * - * This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include "libsam3a.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -//#include -#include -#include -#include -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif -#ifndef SHUT_RDWR -#define SHUT_RDWR 2 -#endif -#endif - -#ifdef __unix__ -#include -#include -#include -#include -#include -#include -#include -#endif -//////////////////////////////////////////////////////////////////////////////// -int libsam3a_debug = 0; - -#define DEFAULT_TCP_PORT (7656) -#define DEFAULT_UDP_PORT (7655) - -//////////////////////////////////////////////////////////////////////////////// -uint64_t sam3atimeval2ms(const struct timeval *tv) { - return ((uint64_t)tv->tv_sec) * 1000 + ((uint64_t)tv->tv_usec) / 1000; -} - -void sam3ams2timeval(struct timeval *tv, uint64_t ms) { - tv->tv_sec = ms / 1000; - tv->tv_usec = (ms % 1000) * 1000; -} - -//////////////////////////////////////////////////////////////////////////////// -static inline int isValidKeyChar(char ch) { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || - (ch >= '0' && ch <= '9') || ch == '-' || ch == '~'; -} - -int sam3aIsValidPubKey(const char *key) { - if (key != NULL && strlen(key) == SAM3A_PUBKEY_SIZE) { - for (int f = 0; f < SAM3A_PUBKEY_SIZE; ++f) - if (!isValidKeyChar(key[f])) - return 0; - return 1; - } - return 0; -} - -int sam3aIsValidPrivKey(const char *key) { - if (key != NULL && strlen(key) == SAM3A_PRIVKEY_SIZE) { - for (int f = 0; f < SAM3A_PRIVKEY_SIZE; ++f) - if (!isValidKeyChar(key[f])) - return 0; - return 1; - } - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -/* -static int sam3aSocketSetTimeoutSend (int fd, int timeoutms) { - if (fd >= 0 && timeoutms >= 0) { - struct timeval tv; - // - ms2timeval(&tv, timeoutms); - return (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 ? -1 : -0); - } - return -1; -} - - -static int sam3aSocketSetTimeoutReceive (int fd, int timeoutms) { - if (fd >= 0 && timeoutms >= 0) { - struct timeval tv; - // - ms2timeval(&tv, timeoutms); - return (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0 ? -1 : -0); - } - return -1; -} -*/ - -static int sam3aBytesAvail(int fd) { - int av = 0; - // - if (ioctl(fd, FIONREAD, &av) < 0) - return -1; - return av; -} - -static uint32_t sam3aResolveHost(const char *hostname) { - struct hostent *host; - // - if (hostname == NULL || !hostname[0]) - return 0; - if ((host = gethostbyname(hostname)) == NULL || host->h_name == NULL || - !host->h_addr_list[0][0]) { - if (libsam3a_debug) - fprintf(stderr, "ERROR: can't resolve '%s'\n", hostname); - return 0; - } - return ((struct in_addr *)host->h_addr_list[0])->s_addr; -} - -static int sam3aConnect(uint32_t ip, int port, int *complete) { - int fd, val = 1; - // - if (complete != NULL) - *complete = 0; - if (ip == 0 || ip == 0xffffffffUL || port < 1 || port > 65535) - return -1; - // - // yes, this is Linux-specific; you know what? i don't care. - if ((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)) < 0) - return -1; - // - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); - // - for (;;) { - struct sockaddr_in addr; - // - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = ip; - // - if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { - if (errno == EINPROGRESS) - break; // the process is started - if (errno != EINTR) { - close(fd); - return -1; - } - } else { - // connection complete - if (complete != NULL) - *complete = 1; - break; - } - } - // - return fd; -} - -// <0: error; 0: ok -static int sam3aDisconnect(int fd) { - if (fd >= 0) { - shutdown(fd, SHUT_RDWR); - return close(fd); - } - // - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// <0: error; >=0: bytes sent -static int sam3aSendBytes(int fd, const void *buf, int bufSize) { - const char *c = (const char *)buf; - int total = 0; - // - if (fd < 0 || (buf == NULL && bufSize > 0)) - return -1; - // - while (bufSize > 0) { - int wr = send(fd, c, bufSize, MSG_NOSIGNAL); - // - if (wr < 0) { - if (errno == EINTR) - continue; // interrupted by signal - if (errno == EAGAIN || errno == EWOULDBLOCK) { - // bufSize is too big - if (bufSize == 1) - break; // can't send anything - // try to send a half of a buffer - if ((wr = sam3aSendBytes(fd, c, bufSize / 2)) < 0) - return wr; // error - } else { - return -1; // alas - } - } - // - if (wr == 0) - break; // can't send anything - c += wr; - bufSize -= wr; - total += wr; - } - // - return total; -} - -/* <0: error; >=0: bytes received */ -/* note that you should call this function when there is some bytes to read, so - * 0 means 'connection closed' */ -/* -static int sam3aReceive (int fd, void *buf, int bufSize) { - char *c = (char *)buf; - int total = 0; - // - if (fd < 0 || (buf == NULL && bufSize > 0)) return -1; - // - while (bufSize > 0) { - int av = sam3aBytesAvail(fd), rd; - // - if (av == 0) break; // no more - if (av > bufSize) av = bufSize; - rd = recv(fd, c, av, 0); - if (rd < 0) { - if (errno == EINTR) continue; // interrupted by signal - if (errno == EAGAIN || errno == EWOULDBLOCK) break; // the thing that -should not be return -1; // error - } - if (rd == 0) break; - c += rd; - bufSize -= rd; - total += rd; - } - // - return total; -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -char *sam3PrintfVA(int *plen, const char *fmt, va_list app) { - char buf[1024], *p = buf; - int size = sizeof(buf) - 1, len = 0; - // - if (plen != NULL) - *plen = 0; - for (;;) { - va_list ap; - char *np; - int n; - // - va_copy(ap, app); - n = vsnprintf(p, size, fmt, ap); - va_end(ap); - // - if (n > -1 && n < size) { - len = n; - break; - } - if (n > -1) - size = n + 1; - else - size *= 2; - if (p == buf) { - if ((p = malloc(size)) == NULL) - return NULL; - } else { - if ((np = realloc(p, size)) == NULL) { - free(p); - return NULL; - } - p = np; - } - } - // - if (p == buf) { - if ((p = malloc(len + 1)) == NULL) - return NULL; - memcpy(p, buf, len + 1); - } - if (plen != NULL) - *plen = len; - return p; -} - -__attribute__((format(printf, 2, 3))) char *sam3Printf(int *plen, - const char *fmt, ...) { - va_list ap; - char *res; - // - va_start(ap, fmt); - res = sam3PrintfVA(plen, fmt, ap); - va_end(ap); - // - return res; -} - -/* - * check if we have EOL in received socket data - * this function should be called when sam3aBytesAvail() result > 0 - * return: <0: error; 0: no EOL in bytes2check, else: # of bytes to EOL - * (including EOL itself) - */ -/* -static int sam3aCheckEOL (int fd, int bytes2check) { - char *d = dest; - // - if (bytes2check < 0 || fd < 0) return -1; - memset(dest, 0, maxSize); - while (maxSize > 1) { - char *e; - int rd = recv(fd, d, maxSize-1, MSG_PEEK); - // - if (rd < 0 && errno == EINTR) continue; // interrupted by signal - if (rd == 0) { - rd = recv(fd, d, 1, 0); - if (rd < 0 && errno == EINTR) continue; // interrupted by signal - if (d[0] == '\n') { - d[0] = 0; // remove '\n' - return 0; - } - } else { - if (rd < 0) return -1; // error or connection closed; alas - } - // check for EOL - d[maxSize-1] = 0; - if ((e = strchr(d, '\n')) != NULL) { - rd = e-d+1; // bytes to receive - if (sam3atcpReceive(fd, d, rd) < 0) return -1; // alas - d[rd-1] = 0; // remove '\n' - return 0; // done - } else { - // let's receive this part and go on - if (sam3atcpReceive(fd, d, rd) < 0) return -1; // alas - maxSize -= rd; - d += rd; - } - } - // alas, the string is too big - return -1; -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -/* -int sam3audpSendToIP (uint32_t ip, int port, const void *buf, int bufSize) { - struct sockaddr_in addr; - int fd, res; - // - if (buf == NULL || bufSize < 1) return -1; - if (port < 1 || port > 65535) port = 7655; - // - if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - if (libsam3a_debug) fprintf(stderr, "ERROR: can't create socket\n"); - return -1; - } - // - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = ip; - // - res = sendto(fd, buf, bufSize, 0, (struct sockaddr *)&addr, sizeof(addr)); - // - if (res < 0) { - if (libsam3a_debug) { - res = errno; - fprintf(stderr, "UDP ERROR (%d): %s\n", res, strerror(res)); - } - res = -1; - } else { - if (libsam3a_debug) fprintf(stderr, "UDP: %d bytes sent\n", res); - } - // - close(fd); - // - return (res >= 0 ? 0 : -1); -} - - -int sam3audpSendTo (const char *hostname, int port, const void *buf, int -bufSize, uint32_t *ip) { struct hostent *host = NULL; - // - if (buf == NULL || bufSize < 1) return -1; - if (hostname == NULL || !hostname[0]) hostname = "localhost"; - if (port < 1 || port > 65535) port = 7655; - // - host = gethostbyname(hostname); - if (host == NULL || host->h_name == NULL || !host->h_name[0]) { - if (libsam3a_debug) fprintf(stderr, "ERROR: can't resolve '%s'\n", -hostname); return -1; - } - // - if (ip != NULL) *ip = ((struct in_addr *)host->h_addr)->s_addr; - return sam3audpSendToIP(((struct in_addr *)host->h_addr)->s_addr, port, buf, -bufSize); -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -typedef struct SAMFieldList { - char *name; - char *value; - struct SAMFieldList *next; -} SAMFieldList; - -static void sam3aFreeFieldList(SAMFieldList *list) { - while (list != NULL) { - SAMFieldList *c = list; - // - list = list->next; - if (c->name != NULL) - free(c->name); - if (c->value != NULL) - free(c->value); - free(c); - } -} - -static void sam3aDumpFieldList(const SAMFieldList *list) { - for (; list != NULL; list = list->next) { - fprintf(stderr, "%s=[%s]\n", list->name, list->value); - } -} - -static const char *sam3aFindField(const SAMFieldList *list, const char *field) { - if (list != NULL && field != NULL) { - for (list = list->next; list != NULL; list = list->next) { - if (list->name != NULL && strcmp(field, list->name) == 0) - return list->value; - } - } - return NULL; -} - -static char *xstrdup(const char *s, int len) { - if (len >= 0) { - char *res = malloc(len + 1); - // - if (res != NULL) { - if (len > 0) - memcpy(res, s, len); - res[len] = 0; - } - // - return res; - } - // - return NULL; -} - -// returns NULL if there are no more tokens -static inline const char *xstrtokend(const char *s) { - while (*s && isspace(*s)) - ++s; - // - if (*s) { - char qch = 0; - // - while (*s) { - if (*s == qch) { - qch = 0; - } else if (*s == '"') { - qch = *s; - } else if (qch) { - if (*s == '\\' && s[1]) - ++s; - } else if (isspace(*s)) { - break; - } - ++s; - } - } else { - s = NULL; - } - // - return s; -} - -SAMFieldList *sam3aParseReply(const char *rep) { - SAMFieldList *first = NULL, *last, *c; - const char *p = rep, *e, *e1; - // - // first 2 words - while (*p && isspace(*p)) - ++p; - if ((e = xstrtokend(p)) == NULL) - return NULL; - if ((e1 = xstrtokend(e)) == NULL) - return NULL; - // - if ((first = last = c = malloc(sizeof(SAMFieldList))) == NULL) - return NULL; - c->next = NULL; - c->name = c->value = NULL; - if ((c->name = xstrdup(p, e - p)) == NULL) - goto error; - while (*e && isspace(*e)) - ++e; - if ((c->value = xstrdup(e, e1 - e)) == NULL) - goto error; - // - p = e1; - while (*p) { - while (*p && isspace(*p)) - ++p; - if ((e = xstrtokend(p)) == NULL) - break; // no more tokens - // - if (libsam3a_debug) - fprintf(stderr, "<%s>\n", p); - // - if ((c = malloc(sizeof(SAMFieldList))) == NULL) - return NULL; - c->next = NULL; - c->name = c->value = NULL; - last->next = c; - last = c; - // - if ((e1 = memchr(p, '=', e - p)) != NULL) { - // key=value - if ((c->name = xstrdup(p, e1 - p)) == NULL) - goto error; - if ((c->value = xstrdup(e1 + 1, e - e1 - 1)) == NULL) - goto error; - } else { - // only key (there is no such replies in SAMv3, but... - if ((c->name = xstrdup(p, e - p)) == NULL) - goto error; - if ((c->value = strdup("")) == NULL) - goto error; - } - p = e; - } - // - if (libsam3a_debug) - sam3aDumpFieldList(first); - // - return first; -error: - sam3aFreeFieldList(first); - return NULL; -} - -// example: -// r0: 'HELLO' -// r1: 'REPLY' -// field: NULL or 'RESULT' -// VALUE: NULL or 'OK' -// returns bool -int sam3aIsGoodReply(const SAMFieldList *list, const char *r0, const char *r1, - const char *field, const char *value) { - if (list != NULL && list->name != NULL && list->value != NULL) { - if (r0 != NULL && strcmp(r0, list->name) != 0) - return 0; - if (r1 != NULL && strcmp(r1, list->value) != 0) - return 0; - if (field != NULL) { - for (list = list->next; list != NULL; list = list->next) { - if (list->name == NULL || list->value == NULL) - return 0; // invalid list, heh - if (strcmp(field, list->name) == 0) { - if (value != NULL && strcmp(value, list->value) != 0) - return 0; - return 1; - } - } - } - return 1; - } - return 0; -} - -// NULL: error; else: list of fields -// first item is always 2-word reply, with first word in name and second in -// value -/* -SAMFieldList *sam3aReadReply (int fd) { - char rep[2048]; // should be enough for any reply - // - if (sam3atcpReceiveStr(fd, rep, sizeof(rep)) < 0) return NULL; - if (libsam3a_debug) fprintf(stderr, "SAM REPLY: [%s]\n", rep); - return sam3aParseReply(rep); -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -// by Bob Jenkins -// public domain -// http://burtleburtle.net/bob/rand/smallprng.html -// -//////////////////////////////////////////////////////////////////////////////// -typedef struct { - uint32_t a, b, c, d; -} BJRandCtx; - -#define BJPRNG_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) - -static uint32_t bjprngRand(BJRandCtx *x) { - uint32_t e; - /* original: - e = x->a-BJPRNG_ROT(x->b, 27); - x->a = x->b^BJPRNG_ROT(x->c, 17); - x->b = x->c+x->d; - x->c = x->d+e; - x->d = e+x->a; - */ - /* better, but slower at least in idiotic m$vc */ - e = x->a - BJPRNG_ROT(x->b, 23); - x->a = x->b ^ BJPRNG_ROT(x->c, 16); - x->b = x->c + BJPRNG_ROT(x->d, 11); - x->c = x->d + e; - x->d = e + x->a; - // - return x->d; -} - -static void bjprngInit(BJRandCtx *x, uint32_t seed) { - x->a = 0xf1ea5eed; - x->b = x->c = x->d = seed; - for (int i = 0; i < 20; ++i) - bjprngRand(x); -} - -static inline uint32_t hashint(uint32_t a) { - a -= (a << 6); - a ^= (a >> 17); - a -= (a << 9); - a ^= (a << 4); - a -= (a << 3); - a ^= (a << 10); - a ^= (a >> 15); - return a; -} - -static uint32_t genSeed(void) { - volatile uint32_t seed = 1; - uint32_t res; -#ifndef WIN32 - struct sysinfo sy; - pid_t pid = getpid(); - // - sysinfo(&sy); - res = hashint((uint32_t)pid) ^ hashint((uint32_t)time(NULL)) ^ - hashint((uint32_t)sy.sharedram) ^ hashint((uint32_t)sy.bufferram) ^ - hashint((uint32_t)sy.uptime); -#else - res = hashint((uint32_t)GetCurrentProcessId()) ^ - hashint((uint32_t)GetTickCount()); -#endif - res += __sync_fetch_and_add(&seed, 1); - // - return hashint(res); -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aGenChannelName(char *dest, int minlen, int maxlen) { - BJRandCtx rc; - int len; - // - if (dest == NULL || minlen < 1 || maxlen < minlen || minlen > 65536 || - maxlen > 65536) - return -1; - bjprngInit(&rc, genSeed()); - len = minlen + (bjprngRand(&rc) % (maxlen - minlen + 1)); - while (len-- > 0) { - int ch = bjprngRand(&rc) % 64; - // - if (ch >= 0 && ch < 10) - ch += '0'; - else if (ch >= 10 && ch < 36) - ch += 'A' - 10; - else if (ch >= 36 && ch < 62) - ch += 'a' - 36; - else if (ch == 62) - ch = '-'; - else if (ch == 63) - ch = '_'; - else if (ch > 64) - abort(); - *dest++ = ch; - } - *dest++ = 0; - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aIsActiveSession(const Sam3ASession *ses) { - return (ses != NULL && ses->fd >= 0 && !ses->cancelled); -} - -int sam3aIsActiveConnection(const Sam3AConnection *conn) { - return (conn != NULL && conn->fd >= 0 && !conn->cancelled); -} - -//////////////////////////////////////////////////////////////////////////////// -static inline void strcpyerrs(Sam3ASession *ses, const char *errstr) { - // memset(ses->error, 0, sizeof(ses->error)); - ses->error[sizeof(ses->error) - 1] = 0; - if (errstr != NULL) - strncpy(ses->error, errstr, sizeof(ses->error) - 1); -} - -static inline void strcpyerrc(Sam3AConnection *conn, const char *errstr) { - // memset(conn->error, 0, sizeof(conn->error)); - conn->error[sizeof(conn->error) - 1] = 0; - if (errstr != NULL) - strncpy(conn->error, errstr, sizeof(conn->error) - 1); -} - -static void connDisconnect(Sam3AConnection *conn) { - conn->cbAIOProcessorR = conn->cbAIOProcessorW = NULL; - if (conn->aio.data != NULL) { - free(conn->aio.data); - conn->aio.data = NULL; - } - if (!conn->cancelled && conn->fd >= 0) { - conn->cancelled = 1; - shutdown(conn->fd, SHUT_RDWR); - if (conn->callDisconnectCB && conn->cb.cbDisconnected != NULL) - conn->cb.cbDisconnected(conn); - } -} - -static void sesDisconnect(Sam3ASession *ses) { - ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; - if (ses->aio.data != NULL) { - free(ses->aio.data); - ses->aio.data = NULL; - } - if (!ses->cancelled && ses->fd >= 0) { - ses->cancelled = 1; - shutdown(ses->fd, SHUT_RDWR); - for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) - connDisconnect(c); - if (ses->callDisconnectCB && ses->cb.cbDisconnected != NULL) - ses->cb.cbDisconnected(ses); - } -} - -static void sesError(Sam3ASession *ses, const char *errstr) { - if (errstr == NULL || !errstr[0]) - errstr = "I2P_ERROR"; - strcpyerrs(ses, errstr); - if (ses->cb.cbError != NULL) - ses->cb.cbError(ses); - sesDisconnect(ses); -} - -static void connError(Sam3AConnection *conn, const char *errstr) { - if (errstr == NULL || !errstr[0]) - errstr = "I2P_ERROR"; - strcpyerrc(conn, errstr); - if (conn->cb.cbError != NULL) - conn->cb.cbError(conn); - connDisconnect(conn); -} - -//////////////////////////////////////////////////////////////////////////////// -static int aioSender(int fd, Sam3AIO *aio) { - int wr = sam3aSendBytes(fd, aio->data + aio->dataPos, - aio->dataUsed - aio->dataPos); - // - if (wr < 0) - return -1; - aio->dataPos += wr; - return 0; -} - -// dataUsed: max line size (with '\n') -// dataSize: must be at least (dataUsed+1) -static int aioLineReader(int fd, Sam3AIO *aio) { - // - for (;;) { - int av = sam3aBytesAvail(fd), rd; - // - if (av < 0) - return -1; - if (av == 0) - return 0; // do nothing - if (aio->dataPos >= aio->dataUsed - 1) - return -1; // line too long - if ((rd = (aio->dataUsed - 1) - aio->dataPos) > av) - rd = av; - if ((rd = recv(fd, aio->data + aio->dataPos, rd, MSG_PEEK)) < 0) { - if (errno == EINTR) - continue; - return -1; - } - if (rd == 0) - return 0; // do nothing - // now look for '\n' - for (int f = aio->dataPos; f < aio->dataPos + rd; ++f) { - if (aio->data[f] == '\n') { - // got it! - if (recv(fd, aio->data + aio->dataPos, f - aio->dataPos + 1, 0) != - f + 1) - return -1; // the thing that should not be - aio->data[f] = 0; // convert to asciiz - aio->dataUsed = aio->dataPos = f; // length - return 1; // '\n' found! - } - if (!aio->data[f]) - return -1; // there should not be zero bytes - } - // no '\n' found - if (recv(fd, aio->data + aio->dataPos, rd, 0) != rd) - return -1; // the thing that should not be - aio->dataPos += rd; - } -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioSesCmdReplyReader(Sam3ASession *ses) { - int res = aioLineReader(ses->fd, &ses->aio); - // - if (res < 0) { - sesError(ses, "IO_ERROR"); - return; - } - if (res > 0) { - // we got full line - if (libsam3a_debug) - fprintf(stderr, "CMDREPLY: %s\n", ses->aio.data); - if (ses->aio.cbReplyCheckSes != NULL) - ses->aio.cbReplyCheckSes(ses); - } -} - -static void aioSesCmdSender(Sam3ASession *ses) { - if (ses->aio.dataPos < ses->aio.dataUsed) { - if (aioSender(ses->fd, &ses->aio) < 0) { - sesError(ses, "IO_ERROR"); - return; - } - } - // - if (ses->aio.dataPos == ses->aio.dataUsed) { - // hello sent, now wait for reply - // 2048 bytes of reply line should be enough - if (ses->aio.dataSize < 2049) { - char *n = realloc(ses->aio.data, 2049); - // - if (n == NULL) { - sesError(ses, "MEMORY_ERROR"); - return; - } - ses->aio.data = n; - ses->aio.dataSize = 2049; - } - ses->aio.dataUsed = 2048; - ses->aio.dataPos = 0; - ses->cbAIOProcessorR = aioSesCmdReplyReader; - ses->cbAIOProcessorW = NULL; - } -} - -static __attribute__((format(printf, 3, 4))) int -aioSesSendCmdWaitReply(Sam3ASession *ses, void (*cbCheck)(Sam3ASession *ses), - const char *fmt, ...) { - va_list ap; - char *str; - int len; - // - va_start(ap, fmt); - str = sam3PrintfVA(&len, fmt, ap); - va_end(ap); - // - if (str == NULL) - return -1; - if (ses->aio.data != NULL) - free(ses->aio.data); - ses->aio.data = str; - ses->aio.dataUsed = len; - ses->aio.dataSize = len + 1; - ses->aio.dataPos = 0; - ses->aio.cbReplyCheckSes = cbCheck; - ses->cbAIOProcessorR = NULL; - ses->cbAIOProcessorW = aioSesCmdSender; - // - if (libsam3a_debug) - fprintf(stderr, "CMD: %s", str); - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioSesHelloChecker(Sam3ASession *ses) { - SAMFieldList *rep = sam3aParseReply(ses->aio.data); - // - if (rep != NULL && sam3aIsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK") && - sam3aIsGoodReply(rep, NULL, NULL, "VERSION", "3.0")) { - ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; - sam3aFreeFieldList(rep); - if (ses->aio.udata != NULL) { - void (*cbComplete)(Sam3ASession * ses) = ses->aio.udata; - // - cbComplete(ses); - } - } else { - sam3aFreeFieldList(rep); - sesError(ses, NULL); - } -} - -static int sam3aSesStartHandshake(Sam3ASession *ses, - void (*cbComplete)(Sam3ASession *ses)) { - if (cbComplete != NULL) - ses->aio.udata = cbComplete; - if (aioSesSendCmdWaitReply(ses, aioSesHelloChecker, "%s\n", - "HELLO VERSION MIN=3.0 MAX=3.0") < 0) - return -1; - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioSesNameMeChecker(Sam3ASession *ses) { - SAMFieldList *rep = sam3aParseReply(ses->aio.data); - const char *v = NULL; - // - if (rep == NULL) { - sesError(ses, NULL); - return; - } - if (!sam3aIsGoodReply(rep, "NAMING", "REPLY", "RESULT", "OK") || - (v = sam3aFindField(rep, "VALUE")) == NULL || - strlen(v) != SAM3A_PUBKEY_SIZE) { - // if (libsam3a_debug) fprintf(stderr, "sam3aCreateSession: invalid NAMING - // reply (%d)...\n", (v != NULL ? strlen(v) : -1)); - if ((v = sam3aFindField(rep, "RESULT")) != NULL && strcmp(v, "OK") == 0) - v = NULL; - sesError(ses, v); - sam3aFreeFieldList(rep); - return; - } - strcpy(ses->pubkey, v); - sam3aFreeFieldList(rep); - // - ses->cbAIOProcessorR = ses->cbAIOProcessorW = NULL; - ses->callDisconnectCB = 1; - if (ses->cb.cbCreated != NULL) - ses->cb.cbCreated(ses); -} - -static void aioSesCreateChecker(Sam3ASession *ses) { - SAMFieldList *rep = sam3aParseReply(ses->aio.data); - const char *v; - // - if (rep == NULL) { - sesError(ses, NULL); - return; - } - if (!sam3aIsGoodReply(rep, "SESSION", "STATUS", "RESULT", "OK") || - (v = sam3aFindField(rep, "DESTINATION")) == NULL || - strlen(v) != SAM3A_PRIVKEY_SIZE) { - sam3aFreeFieldList(rep); - if ((v = sam3aFindField(rep, "RESULT")) != NULL && strcmp(v, "OK") == 0) - v = NULL; - sesError(ses, v); - return; - } - // ok - // fprintf(stderr, "\nPK: %s\n", v); - strcpy(ses->privkey, v); - sam3aFreeFieldList(rep); - // get our public key - if (aioSesSendCmdWaitReply(ses, aioSesNameMeChecker, "%s\n", - "NAMING LOOKUP NAME=ME") < 0) { - sesError(ses, "MEMORY_ERROR"); - } -} - -// handshake for SESSION CREATE complete -static void aioSesHandshacked(Sam3ASession *ses) { - static const char *typenames[3] = {"RAW", "DATAGRAM", "STREAM"}; - // - if (aioSesSendCmdWaitReply( - ses, aioSesCreateChecker, - "SESSION CREATE STYLE=%s ID=%s DESTINATION=%s%s%s\n", - typenames[(int)ses->type], ses->channel, ses->privkey, - (ses->params != NULL ? " " : ""), - (ses->params != NULL ? ses->params : "")) < 0) { - sesError(ses, "MEMORY_ERROR"); - } -} - -static void aioSesConnected(Sam3ASession *ses) { - int res; - socklen_t len = sizeof(res); - // - if (getsockopt(ses->fd, SOL_SOCKET, SO_ERROR, &res, &len) == 0 && res == 0) { - // ok, connected - if (sam3aSesStartHandshake(ses, NULL) < 0) - sesError(ses, NULL); - } else { - // connection error - sesError(ses, "CONNECTION_ERROR"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aCreateSessionEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, - const char *hostname, int port, const char *privkey, - Sam3ASessionType type, const char *params, - int timeoutms) { - if (ses != NULL) { - // int complete = 0; - // - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - if (cb != NULL) - ses->cb = *cb; - if (hostname == NULL || !hostname[0]) - hostname = "127.0.0.1"; - if (port < 0 || port > 65535) - goto error; - if (privkey != NULL && strlen(privkey) != SAM3A_PRIVKEY_SIZE) - goto error; - if ((int)type < 0 || (int)type > 2) - goto error; - if (privkey == NULL) - privkey = "TRANSIENT"; - strcpy(ses->privkey, privkey); - if (params != NULL && (ses->params = strdup(params)) == NULL) - goto error; - ses->timeoutms = timeoutms; - // - if (!port) - port = DEFAULT_TCP_PORT; - ses->type = type; - ses->port = (type == SAM3A_SESSION_STREAM ? port : DEFAULT_UDP_PORT); - if ((ses->ip = sam3aResolveHost(hostname)) == 0) - goto error; - sam3aGenChannelName(ses->channel, 32, 64); - if (libsam3a_debug) - fprintf(stderr, "sam3aCreateSession: channel=[%s]\n", ses->channel); - // - ses->aio.udata = aioSesHandshacked; - ses->cbAIOProcessorW = aioSesConnected; - if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) - goto error; - /* - if (complete) { - ses->cbAIOProcessorW(ses); - if (!sam3aIsActiveSession(ses)) return -1; - } - */ - // - return 0; // ok, connection process initiated - error: - if (ses->fd >= 0) - sam3aDisconnect(ses->fd); - if (ses->params != NULL) - free(ses->params); - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aCancelSession(Sam3ASession *ses) { - if (ses != NULL) { - sesDisconnect(ses); - return 0; - } - return -1; -} - -int sam3aCloseSession(Sam3ASession *ses) { - if (ses != NULL) { - sam3aCancelSession(ses); - while (ses->connlist != NULL) - sam3aCloseConnection(ses->connlist); - if (ses->cb.cbDestroy != NULL) - ses->cb.cbDestroy(ses); - if (ses->params != NULL) { - free(ses->params); - ses->params = NULL; - } - memset(ses, 0, sizeof(Sam3ASession)); - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioSesKeyGenChecker(Sam3ASession *ses) { - SAMFieldList *rep = sam3aParseReply(ses->aio.data); - // - if (rep == NULL) { - sesError(ses, NULL); - return; - } - if (sam3aIsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) { - const char *pub = sam3aFindField(rep, "PUB"), - *priv = sam3aFindField(rep, "PRIV"); - // - if (pub != NULL && strlen(pub) == SAM3A_PUBKEY_SIZE && priv != NULL && - strlen(priv) == SAM3A_PRIVKEY_SIZE) { - strcpy(ses->pubkey, pub); - strcpy(ses->privkey, priv); - sam3aFreeFieldList(rep); - if (ses->cb.cbCreated != NULL) - ses->cb.cbCreated(ses); - sam3aCancelSession(ses); - return; - } - } - sam3aFreeFieldList(rep); - sesError(ses, NULL); -} - -// handshake for SESSION CREATE complete -static void aioSesKeyGenHandshacked(Sam3ASession *ses) { - if (aioSesSendCmdWaitReply(ses, aioSesKeyGenChecker, "%s\n", - "DEST GENERATE") < 0) { - sesError(ses, "MEMORY_ERROR"); - } -} - -int sam3aGenerateKeysEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, - const char *hostname, int port, int timeoutms) { - if (ses != NULL) { - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - if (cb != NULL) - ses->cb = *cb; - if (hostname == NULL || !hostname[0]) - hostname = "127.0.0.1"; - if (port < 0 || port > 65535) - goto error; - ses->timeoutms = timeoutms; - // - if (!port) - port = DEFAULT_TCP_PORT; - ses->port = port; - if ((ses->ip = sam3aResolveHost(hostname)) == 0) - goto error; - // - ses->aio.udata = aioSesKeyGenHandshacked; - ses->cbAIOProcessorW = aioSesConnected; - if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) - goto error; - // - return 0; // ok, connection process initiated - error: - if (ses->fd >= 0) - sam3aDisconnect(ses->fd); - if (ses->params != NULL) - free(ses->params); - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioSesNameResChecker(Sam3ASession *ses) { - SAMFieldList *rep = sam3aParseReply(ses->aio.data); - // - if (rep == NULL) { - sesError(ses, NULL); - return; - } - if (sam3aIsGoodReply(rep, "NAMING", "REPLY", "RESULT", NULL)) { - const char *rs = sam3aFindField(rep, "RESULT"), - *pub = sam3aFindField(rep, "VALUE"); - // - if (strcmp(rs, "OK") == 0) { - if (pub != NULL && strlen(pub) == SAM3A_PUBKEY_SIZE) { - strcpy(ses->destkey, pub); - sam3aFreeFieldList(rep); - if (ses->cb.cbCreated != NULL) - ses->cb.cbCreated(ses); - sam3aCancelSession(ses); - return; - } - sam3aFreeFieldList(rep); - sesError(ses, NULL); - } else { - sesError(ses, rs); - sam3aFreeFieldList(rep); - } - } -} - -// handshake for SESSION CREATE complete -static void aioSesNameResHandshacked(Sam3ASession *ses) { - if (aioSesSendCmdWaitReply(ses, aioSesNameResChecker, - "NAMING LOOKUP NAME=%s\n", ses->params) < 0) { - sesError(ses, "MEMORY_ERROR"); - } -} - -int sam3aNameLookupEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, - const char *hostname, int port, const char *name, - int timeoutms) { - if (ses != NULL) { - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - if (cb != NULL) - ses->cb = *cb; - if (name == NULL || !name[0] || - (name[0] && toupper(name[0]) == 'M' && name[1] && - toupper(name[1]) == 'E' && (!name[2] || isspace(name[2])))) - goto error; - if (hostname == NULL || !hostname[0]) - hostname = "127.0.0.1"; - if (port < 0 || port > 65535) - goto error; - if ((ses->params = strdup(name)) == NULL) - goto error; - ses->timeoutms = timeoutms; - // - if (!port) - port = DEFAULT_TCP_PORT; - ses->port = port; - if ((ses->ip = sam3aResolveHost(hostname)) == 0) - goto error; - // - ses->aio.udata = aioSesNameResHandshacked; - ses->cbAIOProcessorW = aioSesConnected; - if ((ses->fd = sam3aConnect(ses->ip, port, NULL)) < 0) - goto error; - // - return 0; // ok, connection process initiated - error: - if (ses->fd >= 0) - sam3aDisconnect(ses->fd); - if (ses->params != NULL) - free(ses->params); - memset(ses, 0, sizeof(Sam3ASession)); - ses->fd = -1; - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioConnCmdReplyReader(Sam3AConnection *conn) { - int res = aioLineReader(conn->fd, &conn->aio); - // - if (res < 0) { - connError(conn, "IO_ERROR"); - return; - } - if (res > 0) { - // we got full line - if (libsam3a_debug) - fprintf(stderr, "CMDREPLY: %s\n", conn->aio.data); - if (conn->aio.cbReplyCheckConn != NULL) - conn->aio.cbReplyCheckConn(conn); - } -} - -static void aioConnCmdSender(Sam3AConnection *conn) { - if (conn->aio.dataPos < conn->aio.dataUsed) { - if (aioSender(conn->fd, &conn->aio) < 0) { - connError(conn, "IO_ERROR"); - return; - } - } - // - if (conn->aio.dataPos == conn->aio.dataUsed) { - // hello sent, now wait for reply - // 2048 bytes of reply line should be enough - if (conn->aio.dataSize < 2049) { - char *n = realloc(conn->aio.data, 2049); - // - if (n == NULL) { - connError(conn, "MEMORY_ERROR"); - return; - } - conn->aio.data = n; - conn->aio.dataSize = 2049; - } - conn->aio.dataUsed = 2048; - conn->aio.dataPos = 0; - conn->cbAIOProcessorR = aioConnCmdReplyReader; - conn->cbAIOProcessorW = NULL; - } -} - -static __attribute__((format(printf, 3, 4))) int -aioConnSendCmdWaitReply(Sam3AConnection *conn, - void (*cbCheck)(Sam3AConnection *conn), const char *fmt, - ...) { - va_list ap; - char *str; - int len; - // - va_start(ap, fmt); - str = sam3PrintfVA(&len, fmt, ap); - va_end(ap); - // - if (str == NULL) - return -1; - if (conn->aio.data != NULL) - free(conn->aio.data); - conn->aio.data = str; - conn->aio.dataUsed = len; - conn->aio.dataSize = len + 1; - conn->aio.dataPos = 0; - conn->aio.cbReplyCheckConn = cbCheck; - conn->cbAIOProcessorR = NULL; - conn->cbAIOProcessorW = aioConnCmdSender; - // - if (libsam3a_debug) - fprintf(stderr, "CMD: %s", str); - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioConnDataReader(Sam3AConnection *conn) { - char *buf = NULL; - int bufsz = 0; - // - while (sam3aIsActiveConnection(conn)) { - int av = sam3aBytesAvail(conn->fd), rd; - // - if (av < 0) { - if (buf != NULL) - free(buf); - connError(conn, "IO_ERROR"); - return; - } - if (av == 0) - av = 1; - if (bufsz < av) { - char *n = realloc(buf, av + 1); - // - if (n == NULL) { - if (buf != NULL) - free(buf); - connError(conn, "IO_ERROR"); - return; - } - buf = n; - bufsz = av; - } - memset(buf, 0, av + 1); - // - rd = recv(conn->fd, buf, av, 0); - // - if (rd < 0) { - if (errno == EINTR) - continue; // interrupted by signal - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; // no more data - free(buf); - connError(conn, "IO_ERROR"); - return; - } - // - if (rd == 0) { - // connection closed - free(buf); - connDisconnect(conn); - return; - } - // - if (conn->cb.cbRead != NULL) - conn->cb.cbRead(conn, buf, rd); - } - free(buf); -} - -static void aioConnDataWriter(Sam3AConnection *conn) { - if (!sam3aIsActiveConnection(conn)) { - conn->aio.dataPos = conn->aio.dataUsed = 0; - return; - } - // - if (conn->aio.dataPos >= conn->aio.dataUsed) { - conn->aio.dataPos = conn->aio.dataUsed = 0; - return; - } - // - while (sam3aIsActiveConnection(conn) && - conn->aio.dataPos < conn->aio.dataUsed) { - int wr = sam3aSendBytes(conn->fd, conn->aio.data + conn->aio.dataPos, - conn->aio.dataUsed - conn->aio.dataPos); - // - if (wr < 0) { - connError(conn, "IO_ERROR"); - return; - } - if (wr == 0) - break; // can't write more bytes - conn->aio.dataPos += wr; - if (conn->aio.dataPos < conn->aio.dataUsed) { - memmove(conn->aio.data, conn->aio.data + conn->aio.dataPos, - conn->aio.dataUsed - conn->aio.dataPos); - conn->aio.dataUsed -= conn->aio.dataPos; - conn->aio.dataPos = 0; - } - } - // - if (conn->aio.dataPos >= conn->aio.dataUsed) { - conn->aio.dataPos = conn->aio.dataUsed = 0; - if (conn->cb.cbSent != NULL) - conn->cb.cbSent(conn); - if (conn->aio.dataSize > 8192) { - // shrink buffer - char *nn = realloc(conn->aio.data, 8192); - // - if (nn != NULL) { - conn->aio.data = nn; - conn->aio.dataSize = 8192; - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioConnHelloChecker(Sam3AConnection *conn) { - SAMFieldList *rep = sam3aParseReply(conn->aio.data); - // - if (rep != NULL && sam3aIsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK") && - sam3aIsGoodReply(rep, NULL, NULL, "VERSION", "3.0")) { - conn->cbAIOProcessorR = conn->cbAIOProcessorW = NULL; - sam3aFreeFieldList(rep); - if (conn->aio.udata != NULL) { - void (*cbComplete)(Sam3AConnection * conn) = conn->aio.udata; - // - cbComplete(conn); - } - } else { - sam3aFreeFieldList(rep); - connError(conn, NULL); - } -} - -static int sam3aConnStartHandshake(Sam3AConnection *conn, - void (*cbComplete)(Sam3AConnection *conn)) { - if (cbComplete != NULL) - conn->aio.udata = cbComplete; - if (aioConnSendCmdWaitReply(conn, aioConnHelloChecker, "%s\n", - "HELLO VERSION MIN=3.0 MAX=3.0") < 0) - return -1; - return 0; -} - -static void aioConnConnected(Sam3AConnection *conn) { - int res; - socklen_t len = sizeof(res); - // - if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &res, &len) == 0 && res == 0) { - // ok, connected - if (sam3aConnStartHandshake(conn, NULL) < 0) - connError(conn, NULL); - } else { - // connection error - connError(conn, "CONNECTION_ERROR"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioConnConnectChecker(Sam3AConnection *conn) { - SAMFieldList *rep = sam3aParseReply(conn->aio.data); - // - if (rep == NULL) { - connError(conn, NULL); - return; - } - if (!sam3aIsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3aFindField(rep, "RESULT"); - // - connError(conn, v); - sam3aFreeFieldList(rep); - } else { - // no error - sam3aFreeFieldList(rep); - conn->callDisconnectCB = 1; - conn->cbAIOProcessorR = aioConnDataReader; - conn->cbAIOProcessorW = aioConnDataWriter; - conn->aio.dataPos = conn->aio.dataUsed = 0; - if (conn->cb.cbConnected != NULL) - conn->cb.cbConnected(conn); - // indicate that we are ready for new data - if (sam3aIsActiveConnection(conn) && conn->cb.cbSent != NULL) - conn->cb.cbSent(conn); - } -} - -// handshake for SESSION CREATE complete -static void aioConConnectHandshacked(Sam3AConnection *conn) { - if (aioConnSendCmdWaitReply(conn, aioConnConnectChecker, - "STREAM CONNECT ID=%s DESTINATION=%s\n", - conn->ses->channel, conn->destkey) < 0) { - connError(conn, "MEMORY_ERROR"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -Sam3AConnection *sam3aStreamConnectEx(Sam3ASession *ses, - const Sam3AConnectionCallbacks *cb, - const char *destkey, int timeoutms) { - if (sam3aIsActiveSession(ses) && ses->type == SAM3A_SESSION_STREAM && - destkey != NULL && strlen(destkey) == SAM3A_PUBKEY_SIZE) { - Sam3AConnection *conn = calloc(1, sizeof(Sam3AConnection)); - // - if (conn == NULL) - return NULL; - if (cb != NULL) - conn->cb = *cb; - strcpy(conn->destkey, destkey); - conn->timeoutms = timeoutms; - // - conn->aio.udata = aioConConnectHandshacked; - conn->cbAIOProcessorW = aioConnConnected; - if ((conn->fd = sam3aConnect(ses->ip, ses->port, NULL)) < 0) - goto error; - // - conn->ses = ses; - conn->next = ses->connlist; - ses->connlist = conn; - return conn; // ok, connection process initiated - error: - if (conn->fd >= 0) - sam3aDisconnect(conn->fd); - memset(conn, 0, sizeof(Sam3AConnection)); - free(conn); - } - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -static void aioConnAcceptCheckerA(Sam3AConnection *conn) { - SAMFieldList *rep = sam3aParseReply(conn->aio.data); - // - if (rep != NULL || strlen(conn->aio.data) != SAM3A_PUBKEY_SIZE || - !sam3aIsValidPubKey(conn->aio.data)) { - sam3aFreeFieldList(rep); - connError(conn, NULL); - return; - } - sam3aFreeFieldList(rep); - strcpy(conn->destkey, conn->aio.data); - conn->callDisconnectCB = 1; - conn->cbAIOProcessorR = aioConnDataReader; - conn->cbAIOProcessorW = aioConnDataWriter; - conn->aio.dataPos = conn->aio.dataUsed = 0; - if (conn->cb.cbAccepted != NULL) - conn->cb.cbAccepted(conn); - // indicate that we are ready for new data - if (sam3aIsActiveConnection(conn) && conn->cb.cbSent != NULL) - conn->cb.cbSent(conn); -} - -static void aioConnAcceptChecker(Sam3AConnection *conn) { - SAMFieldList *rep = sam3aParseReply(conn->aio.data); - // - if (rep == NULL) { - connError(conn, NULL); - return; - } - if (!sam3aIsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) { - const char *v = sam3aFindField(rep, "RESULT"); - // - connError(conn, v); - sam3aFreeFieldList(rep); - } else { - // no error - sam3aFreeFieldList(rep); - // 2048 bytes of reply line should be enough - if (conn->aio.dataSize < 2049) { - char *n = realloc(conn->aio.data, 2049); - // - if (n == NULL) { - connError(conn, "MEMORY_ERROR"); - return; - } - conn->aio.data = n; - conn->aio.dataSize = 2049; - } - conn->aio.dataUsed = 2048; - conn->aio.dataPos = 0; - conn->cbAIOProcessorR = aioConnCmdReplyReader; - conn->cbAIOProcessorW = NULL; - conn->aio.cbReplyCheckConn = aioConnAcceptCheckerA; - } -} - -// handshake for SESSION CREATE complete -static void aioConAcceptHandshacked(Sam3AConnection *conn) { - if (aioConnSendCmdWaitReply(conn, aioConnAcceptChecker, - "STREAM ACCEPT ID=%s\n", - conn->ses->channel) < 0) { - connError(conn, "MEMORY_ERROR"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -Sam3AConnection *sam3aStreamAcceptEx(Sam3ASession *ses, - const Sam3AConnectionCallbacks *cb, - int timeoutms) { - if (sam3aIsActiveSession(ses) && ses->type == SAM3A_SESSION_STREAM) { - Sam3AConnection *conn = calloc(1, sizeof(Sam3AConnection)); - // - if (conn == NULL) - return NULL; - if (cb != NULL) - conn->cb = *cb; - conn->timeoutms = timeoutms; - // - conn->aio.udata = aioConAcceptHandshacked; - conn->cbAIOProcessorW = aioConnConnected; - if ((conn->fd = sam3aConnect(ses->ip, ses->port, NULL)) < 0) - goto error; - // - conn->ses = ses; - conn->next = ses->connlist; - ses->connlist = conn; - return conn; // ok, connection process initiated - error: - if (conn->fd >= 0) - sam3aDisconnect(conn->fd); - memset(conn, 0, sizeof(Sam3AConnection)); - free(conn); - } - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aSend(Sam3AConnection *conn, const void *data, int datasize) { - if (datasize == -1) - datasize = (data != NULL ? strlen((const char *)data) : 0); - // - if (sam3aIsActiveConnection(conn) && conn->callDisconnectCB && - conn->cbAIOProcessorW != NULL && - ((datasize > 0 && data != NULL) || datasize == 0)) { - // try to add data to send buffer - if (datasize > 0) { - if (conn->aio.dataUsed + datasize > conn->aio.dataSize) { - // we need more pepper! - int newsz = conn->aio.dataUsed + datasize; - char *nb = realloc(conn->aio.data, newsz); - // - if (nb == NULL) - return -1; // alas - conn->aio.data = nb; - conn->aio.dataSize = newsz; - } - // - memcpy(conn->aio.data + conn->aio.dataUsed, data, datasize); - conn->aio.dataUsed += datasize; - } - return 0; - } - // - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aIsHaveActiveConnections(const Sam3ASession *ses) { - if (sam3aIsActiveSession(ses)) { - for (const Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { - if (sam3aIsActiveConnection(c)) - return 1; - } - } - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aCancelConnection(Sam3AConnection *conn) { - if (conn != NULL) { - connDisconnect(conn); - return 0; - } - return -1; -} - -int sam3aCloseConnection(Sam3AConnection *conn) { - if (conn != NULL) { - sam3aCancelConnection(conn); - if (conn->cb.cbDestroy != NULL) - conn->cb.cbDestroy(conn); - for (Sam3AConnection *p = NULL, *c = conn->ses->connlist; c != NULL; - p = c, c = c->next) { - if (c == conn) { - // got it! - if (p == NULL) - c->ses->connlist = c->next; - else - p->next = c->next; - break; - } - } - if (conn->params != NULL) { - free(conn->params); - conn->params = NULL; - } - memset(conn, 0, sizeof(Sam3AConnection)); - free(conn); - } - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -int sam3aAddSessionToFDS(Sam3ASession *ses, int maxfd, fd_set *rds, - fd_set *wrs) { - if (ses != NULL) { - if (sam3aIsActiveSession(ses)) { - if (rds != NULL && ses->cbAIOProcessorR != NULL) { - if (maxfd < ses->fd) - maxfd = ses->fd; - FD_SET(ses->fd, rds); - } - // - if (wrs != NULL && ses->cbAIOProcessorW != NULL) { - if (maxfd < ses->fd) - maxfd = ses->fd; - FD_SET(ses->fd, wrs); - } - // - for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { - if (sam3aIsActiveConnection(c)) { - if (rds != NULL && c->cbAIOProcessorR != NULL) { - if (maxfd < c->fd) - maxfd = c->fd; - FD_SET(c->fd, rds); - } - // - if (wrs != NULL && c->cbAIOProcessorW != NULL) { - if (!c->callDisconnectCB || (c->aio.dataPos < c->aio.dataUsed)) - if (maxfd < c->fd) - maxfd = c->fd; - FD_SET(c->fd, wrs); - } - } - } - } - return maxfd; - } - // - return -1; -} - -void sam3aProcessSessionIO(Sam3ASession *ses, fd_set *rds, fd_set *wrs) { - if (sam3aIsActiveSession(ses)) { - if (ses->fd >= 0 && !ses->cancelled && ses->cbAIOProcessorR != NULL && - rds != NULL && FD_ISSET(ses->fd, rds)) - ses->cbAIOProcessorR(ses); - if (ses->fd >= 0 && !ses->cancelled && ses->cbAIOProcessorW != NULL && - wrs != NULL && FD_ISSET(ses->fd, wrs)) - ses->cbAIOProcessorW(ses); - // - for (Sam3AConnection *c = ses->connlist; c != NULL; c = c->next) { - if (c->fd >= 0 && !c->cancelled && c->cbAIOProcessorR != NULL && - rds != NULL && FD_ISSET(c->fd, rds)) - c->cbAIOProcessorR(c); - if (c->fd >= 0 && !c->cancelled && c->cbAIOProcessorW != NULL && - wrs != NULL && FD_ISSET(c->fd, wrs)) - c->cbAIOProcessorW(c); - } - } -} diff --git a/supportlibs/libsam3/src/libsam3a/libsam3a.h b/supportlibs/libsam3/src/libsam3a/libsam3a.h deleted file mode 100644 index dfd4c0cba..000000000 --- a/supportlibs/libsam3/src/libsam3a/libsam3a.h +++ /dev/null @@ -1,372 +0,0 @@ -/* async SAMv3 library - * - * This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#ifndef LIBSAM3A_H -#define LIBSAM3A_H - -#include -#include -#include - -#include - -#ifdef __MINGW32__ -//#include -#include -#include -#include -//#define SOCK_CLOEXEC O_CLOEXEC -//#define SOCK_NONBLOCK O_NONBLOCK -#define SOCK_CLOEXEC 02000000 -#define SOCK_NONBLOCK FIONBIO -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////////////// -/* - * TODO: - * [.] block sam3aClose*() in callbacks - */ - -//////////////////////////////////////////////////////////////////////////////// -extern int libsam3a_debug; - -//////////////////////////////////////////////////////////////////////////////// -#define SAM3A_HOST_DEFAULT (NULL) -#define SAM3A_PORT_DEFAULT (0) - -#define SAM3A_DESTINATION_TRANSIENT (NULL) - -#define SAM3A_PUBKEY_SIZE (516) -#define SAM3A_PRIVKEY_SIZE (884) - -//////////////////////////////////////////////////////////////////////////////// -extern uint64_t sam3atimeval2ms(const struct timeval *tv); -extern void sam3ams2timeval(struct timeval *tv, uint64_t ms); - -//////////////////////////////////////////////////////////////////////////////// -extern int sam3aIsValidPubKey(const char *key); -extern int sam3aIsValidPrivKey(const char *key); - -//////////////////////////////////////////////////////////////////////////////// -typedef struct Sam3ASession Sam3ASession; -typedef struct Sam3AConnection Sam3AConnection; - -typedef enum { - SAM3A_SESSION_RAW, - SAM3A_SESSION_DGRAM, - SAM3A_SESSION_STREAM -} Sam3ASessionType; - -typedef struct { - char *data; - int dataSize; - int dataUsed; - int dataPos; - void *udata; - union { - void (*cbReplyCheckSes)(Sam3ASession *ses); - void (*cbReplyCheckConn)(Sam3AConnection *conn); - }; -} Sam3AIO; - -/** session callback functions */ -typedef struct { - void (*cbError)(Sam3ASession *ses); /** called on error */ - void (*cbCreated)( - Sam3ASession *ses); /** called when we created the session */ - void (*cbDisconnected)(Sam3ASession *ses); /* call when closed; will called - only after cbCreated() */ - void (*cbDatagramRead)(Sam3ASession *ses, const void *buf, - int bufsize); /* called when we got a datagram; bufsize - >= 0; destkey set */ - void (*cbDestroy)(Sam3ASession *ses); /* called when fd is already closed, but - keys is not cleared */ -} Sam3ASessionCallbacks; - -struct Sam3ASession { - Sam3ASessionType type; /** session type */ - int fd; /** socket file descriptor */ - int cancelled; /** fd was shutdown()ed, but not closed yet */ - char privkey[SAM3A_PRIVKEY_SIZE + 1]; /** private key (asciiz) */ - char pubkey[SAM3A_PUBKEY_SIZE + 1]; /** public key (asciiz) */ - char channel[66]; /** channel name (asciiz) */ - char destkey[SAM3A_PUBKEY_SIZE + 1]; /** for DGRAM sessions (asciiz) */ - char error[64]; /** error message (asciiz) */ - uint32_t ip; /** ipv4 address of sam api interface */ - int port; /** UDP port for DRAM/RAW (can be 0) */ - Sam3AConnection *connlist; /** list of opened connections */ - - /** begin internal members */ - // for async i/o - Sam3AIO aio; - void (*cbAIOProcessorR)(Sam3ASession *ses); // internal - void (*cbAIOProcessorW)(Sam3ASession *ses); // internal - int callDisconnectCB; - char *params; // will be cleared only by sam3aCloseSession() - int timeoutms; - - /** end internal members */ - - Sam3ASessionCallbacks cb; - void *udata; -}; - -/** connection callbacks for data sockets */ -typedef struct { - /** called on error */ - void (*cbError)(Sam3AConnection *ct); - /** called when closed or only after cbConnected()/cbAccepted(); note that - * force disconnect is ok */ - void (*cbDisconnected)(Sam3AConnection *ct); - /** called when connected */ - void (*cbConnected)(Sam3AConnection *ct); - /** called instead of cbConnected() for sam3aStreamAccept*(), destkey filled - * with remote destination */ - void (*cbAccepted)(Sam3AConnection *ct); - /** send callback, data sent, can add new data; will be called after - * connect/accept */ - void (*cbSent)(Sam3AConnection *ct); - /** read callback, data read from socket (bufsize is always > 0) */ - void (*cbRead)(Sam3AConnection *ct, const void *buf, int bufsize); - /** fd already closed, but keys is not cleared */ - void (*cbDestroy)(Sam3AConnection *ct); -} Sam3AConnectionCallbacks; - -struct Sam3AConnection { - /** parent session */ - Sam3ASession *ses; - Sam3AConnection *next; - /** file descriptor */ - int fd; - int cancelled; // fd was shutdown()ed, but not closed yet - char destkey[SAM3A_PUBKEY_SIZE + 1]; // (asciiz) - char error[32]; // (asciiz) - - /** begin internal members */ - // for async i/o - Sam3AIO aio; - void (*cbAIOProcessorR)(Sam3AConnection *ct); // internal - void (*cbAIOProcessorW)(Sam3AConnection *ct); // internal - int callDisconnectCB; - char *params; // will be cleared only by sam3aCloseConnection() - int timeoutms; - /** end internal members */ - - /** callbacks */ - Sam3AConnectionCallbacks cb; - /** user data */ - void *udata; -}; - -//////////////////////////////////////////////////////////////////////////////// -/* - * check if session is active (i.e. have opened socket) - * returns bool - */ -extern int sam3aIsActiveSession(const Sam3ASession *ses); - -/* - * check if connection is active (i.e. have opened socket) - * returns bool - */ -extern int sam3aIsActiveConnection(const Sam3AConnection *conn); - -//////////////////////////////////////////////////////////////////////////////// -/* - * note, that return error codes indicates invalid structure, pointer or fd - * (i.e. immediate errors); all network errors indicated with cbError() callback - */ - -/* - * create SAM session - * pass NULL as hostname for 'localhost' and 0 as port for 7656 - * pass NULL as privkey to create TRANSIENT session - * 'params' can be NULL - * see http://www.i2p2.i2p/i2cp.html#options for common options, - * and http://www.i2p2.i2p/streaming.html#options for STREAM options - * if result<0: error, 'ses' fields are undefined, no need to call - * sam3aCloseSession() if result==0: ok, all 'ses' fields are filled - * TODO: don't clear 'error' field on error (and set it to something meaningful) - */ -extern int sam3aCreateSessionEx(Sam3ASession *ses, - const Sam3ASessionCallbacks *cb, - const char *hostname, int port, - const char *privkey, Sam3ASessionType type, - const char *params, int timeoutms); - -static inline int sam3aCreateSession(Sam3ASession *ses, - const Sam3ASessionCallbacks *cb, - const char *hostname, int port, - const char *privkey, - Sam3ASessionType type) { - return sam3aCreateSessionEx(ses, cb, hostname, port, privkey, type, NULL, -1); -} - -/* returns <0 on error, 0 if no, >0 if yes */ -extern int sam3aIsHaveActiveConnections(const Sam3ASession *ses); - -/* - * close SAM session (and all it's connections) - * returns <0 on error, 0 on ok - * 'ses' must be properly initialized - */ -extern int sam3aCloseSession(Sam3ASession *ses); - -/* - * cancel SAM session (and all it's connections), but don't free() or clear - * anything except fds returns <0 on error, 0 on ok 'ses' must be properly - * initialized - */ -extern int sam3aCancelSession(Sam3ASession *ses); - -/* - * open stream connection to 'destkey' endpoint - * 'destkey' is 516-byte public key (asciiz) - * returns <0 on error - * sets ses->error on memory or socket creation error - */ -extern Sam3AConnection *sam3aStreamConnectEx(Sam3ASession *ses, - const Sam3AConnectionCallbacks *cb, - const char *destkey, - int timeoutms); - -static inline Sam3AConnection * -sam3aStreamConnect(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb, - const char *destkey) { - return sam3aStreamConnectEx(ses, cb, destkey, -1); -} - -/* - * accepts stream connection and sets 'destkey' - * 'destkey' is 516-byte public key - * returns <0 on error, fd on ok - * you still have to call sam3aCloseSession() on failure - * sets ses->error on error - * note that there is no timeouts for now, but you can use sam3atcpSetTimeout*() - */ -extern Sam3AConnection *sam3aStreamAcceptEx(Sam3ASession *ses, - const Sam3AConnectionCallbacks *cb, - int timeoutms); - -static inline Sam3AConnection * -sam3aStreamAccept(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb) { - return sam3aStreamAcceptEx(ses, cb, -1); -} - -/* - * close SAM connection, remove it from session and free memory - * returns <0 on error, 0 on ok - * 'conn' must be properly initialized - * 'conn' is invalid after call - */ -extern int sam3aCloseConnection(Sam3AConnection *conn); - -/* - * cancel SAM connection, but don't free() or clear anything except fd - * returns <0 on error, 0 on ok - * 'conn' must be properly initialized - * 'conn' is invalid after call - */ -extern int sam3aCancelConnection(Sam3AConnection *conn); - -//////////////////////////////////////////////////////////////////////////////// -/* - * send data - * this function can be used in cbSent() callback - * - * return: <0: error; 0: ok - */ -extern int sam3aSend(Sam3AConnection *conn, const void *data, int datasize); - -/* - * sends datagram to 'destkey' endpoint - * 'destkey' is 516-byte public key - * returns <0 on error, 0 on ok - * you still have to call sam3aCloseSession() on failure - * sets ses->error on error - * don't send datagrams bigger than 31KB! - */ -extern int sam3aDatagramSend(Sam3ASession *ses, const char *destkey, - const void *buf, int bufsize); - -//////////////////////////////////////////////////////////////////////////////// -/* - * generate random channel name - * dest should be at least (maxlen+1) bytes big - */ -extern int sam3aGenChannelName(char *dest, int minlen, int maxlen); - -//////////////////////////////////////////////////////////////////////////////// -/* - * generate new keypair - * fills 'privkey' and 'pubkey' only - * you should call sam3aCloseSession() on 'ses' - * cbCreated callback will be called when keys generated - * returns <0 on error, 0 on ok - */ -extern int sam3aGenerateKeysEx(Sam3ASession *ses, - const Sam3ASessionCallbacks *cb, - const char *hostname, int port, int timeoutms); - -static inline int sam3aGenerateKeys(Sam3ASession *ses, - const Sam3ASessionCallbacks *cb, - const char *hostname, int port) { - return sam3aGenerateKeysEx(ses, cb, hostname, port, -1); -} - -/* - * do name lookup (something like gethostbyname()) - * fills 'destkey' only - * you should call sam3aCloseSession() on 'ses' - * cbCreated callback will be called when keys generated, ses->destkey will be - * set returns <0 on error, 0 on ok - */ -extern int sam3aNameLookupEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb, - const char *hostname, int port, const char *name, - int timeoutms); - -static inline int sam3aNameLookup(Sam3ASession *ses, - const Sam3ASessionCallbacks *cb, - const char *hostname, int port, - const char *name) { - return sam3aNameLookupEx(ses, cb, hostname, port, name, -1); -} - -//////////////////////////////////////////////////////////////////////////////// -/* - * append session fd to read and write sets if necessary - * adds all alive session connections too - * returns maxfd or -1 - * TODO: should keep fd count so it will not exceed FD_SETSIZE! - */ -extern int sam3aAddSessionToFDS(Sam3ASession *ses, int maxfd, fd_set *rds, - fd_set *wrs); - -/* - * process session i/o (and all session connections i/o) - * should be called after successful select() - */ -extern void sam3aProcessSessionIO(Sam3ASession *ses, fd_set *rds, fd_set *wrs); - -//////////////////////////////////////////////////////////////////////////////// -/* return malloc()ed buffer and len in 'plen' (if plen != NULL) */ -extern char *sam3PrintfVA(int *plen, const char *fmt, va_list app); -extern char *sam3Printf(int *plen, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/supportlibs/libsam3/test/libsam3/test_b32.c b/supportlibs/libsam3/test/libsam3/test_b32.c deleted file mode 100644 index 9a852853d..000000000 --- a/supportlibs/libsam3/test/libsam3/test_b32.c +++ /dev/null @@ -1,51 +0,0 @@ -/* This program is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - * - * I2P-Bote: - * 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV - * we are the Borg. */ -#include -#include -#include -#include - -#include "../../src/ext/tinytest.h" -#include "../../src/ext/tinytest_macros.h" -#include "../../src/libsam3/libsam3.h" - -static int testb32(const char *src, const char *res) { - size_t dlen = sam3Base32EncodedLength(strlen(src)), len; - char dest[128]; - // - len = sam3Base32Encode(dest, sizeof(dest), src, strlen(src)); - tt_int_op(len, ==, dlen); - tt_int_op(len, ==, strlen(res)); - tt_str_op(res, ==, dest); - return 1; - -end: - return 0; -} - -void test_b32_encode(void *data) { - (void)data; /* This testcase takes no data. */ - - tt_assert(testb32("", "")); - tt_assert(testb32("f", "my======")); - tt_assert(testb32("fo", "mzxq====")); - tt_assert(testb32("foo", "mzxw6===")); - tt_assert(testb32("foob", "mzxw6yq=")); - tt_assert(testb32("fooba", "mzxw6ytb")); - tt_assert(testb32("foobar", "mzxw6ytboi======")); - -end:; -} - -struct testcase_t b32_tests[] = {{ - "encode", - test_b32_encode, - }, - END_OF_TESTCASES}; diff --git a/supportlibs/libsam3/test/test.c b/supportlibs/libsam3/test/test.c deleted file mode 100644 index 9e7357962..000000000 --- a/supportlibs/libsam3/test/test.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include "../src/ext/tinytest.h" -#include "../src/ext/tinytest_macros.h" - -extern struct testcase_t b32_tests[]; - -struct testgroup_t test_groups[] = {{"b32/", b32_tests}, END_OF_GROUPS}; - -int main(int argc, const char **argv) { - return tinytest_main(argc, argv, test_groups); -} From 9c71177d3b6c8f8072e620b275e682277bc9f3ec Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 27 Nov 2020 17:09:02 +0100 Subject: [PATCH 064/697] add workaround for i2p/libsam3#15 --- libretroshare/src/services/autoproxy/p3i2psam3.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index 47123328a..a708517e2 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -616,9 +616,17 @@ bool p3I2pSam3::generateKey(std::string &pub, std::string &priv) RS_DBG("got error: ", ss.error); return false; } + pub = std::string(ss.pubkey); priv = std::string(ss.privkey); + // sanity check + auto p = i2p::publicKeyFromPrivate(priv); + if (p != pub) { + RS_WARN("public key does not match private key! fixing ..."); + pub = p; + } + RS_DBG2("publuc key / address ", pub); RS_DBG2("private key ", priv); From 8a2efe3e586c63a5d3618fb913da31d37970a3fe Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 27 Nov 2020 20:07:51 +0100 Subject: [PATCH 065/697] use libsam3 git submodule --- .gitmodules | 3 +++ libretroshare/src/libretroshare.pro | 5 ++++- supportlibs/libsam3 | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) create mode 160000 supportlibs/libsam3 diff --git a/.gitmodules b/.gitmodules index c35876fc6..2f69bb7b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,6 @@ [submodule "supportlibs/rapidjson"] path = supportlibs/rapidjson url = https://github.com/Tencent/rapidjson.git +[submodule "supportlibs/libsam3"] + path = supportlibs/libsam3 + url = https://github.com/i2p/libsam3.git diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0a8ba44a7..40183772a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1029,7 +1029,10 @@ rs_sam3_libsam3 { libsam3.CONFIG += target_predeps combine libsam3.variable_out = PRE_TARGETDEPS libsam3.commands = \ - cd $${RS_SRC_PATH} && \ + cd $${RS_SRC_PATH} && ( \ + git submodule update --init supportlibs/libsam3 || \ + true ) && \ + mkdir -p $${UDP_DISCOVERY_BUILD_PATH} && \ cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} && \ cd $${LIBSAM3_BUILD_PATH} && \ $(MAKE) build diff --git a/supportlibs/libsam3 b/supportlibs/libsam3 new file mode 160000 index 000000000..8623304b6 --- /dev/null +++ b/supportlibs/libsam3 @@ -0,0 +1 @@ +Subproject commit 8623304b62294dafbe477573f321a464fef721dd From aef993de55e01cfc1ccb0d3b4f174a580aca59c9 Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 27 Nov 2020 20:09:59 +0100 Subject: [PATCH 066/697] reduce log --- libretroshare/src/services/autoproxy/p3i2psam3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index a708517e2..949de2a00 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -29,7 +29,7 @@ static const std::string kConfigKeyBOBAddr = "BOB_ADDR"; static constexpr bool kDefaultSAM3Enable = false; -RS_SET_CONTEXT_DEBUG_LEVEL(4) +RS_SET_CONTEXT_DEBUG_LEVEL(2) static void inline doSleep(std::chrono::duration> timeToSleepMS) { std::this_thread::sleep_for(timeToSleepMS); @@ -48,7 +48,7 @@ p3I2pSam3::p3I2pSam3(p3PeerMgr *peerMgr) : mSetting.enable = kDefaultSAM3Enable; mSetting.session = nullptr; - libsam3_debug = 1; + libsam3_debug = 0; } bool p3I2pSam3::isEnabled() From 54184839346f707d3cc5a353281f91c16d4aff7b Mon Sep 17 00:00:00 2001 From: sehraf Date: Sat, 28 Nov 2020 11:16:55 +0100 Subject: [PATCH 067/697] fixed wrong size check --- libretroshare/src/util/i2pcommon.cpp | 8 +++++-- libretroshare/src/util/i2pcommon.h | 33 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/util/i2pcommon.cpp b/libretroshare/src/util/i2pcommon.cpp index 0733a807d..524219eb3 100644 --- a/libretroshare/src/util/i2pcommon.cpp +++ b/libretroshare/src/util/i2pcommon.cpp @@ -50,8 +50,10 @@ std::string publicKeyFromPrivate(std::string const &priv) * https://geti2p.net/spec/common-structures#keysandcert * https://geti2p.net/spec/common-structures#certificate */ - if (priv.empty() || priv.length() < 884) // base64 ( = 663 bytes = KeyCert + priv Keys) + if (priv.length() < privKeyMinLenth_b64) { + RS_WARN("key to short!"); return std::string(); + } // creat a copy to work on, need to convert it to standard base64 auto priv_copy(priv); @@ -163,8 +165,10 @@ std::string publicKeyFromPrivate(std::string const &priv) bool getKeyTypes(const std::string &key, std::string &signingKey, std::string &cryptoKey) { - if (key.length() < 522) // base64 (391 bytes = 384 bytes + 7 bytes = KeysAndCert + Certificate) + if (key.length() < pubKeyMinLenth_b64) { + RS_WARN("key to short!"); return false; + } // creat a copy to work on, need to convert it to standard base64 auto key_copy(key); diff --git a/libretroshare/src/util/i2pcommon.h b/libretroshare/src/util/i2pcommon.h index 0a76fa080..f0da0322b 100644 --- a/libretroshare/src/util/i2pcommon.h +++ b/libretroshare/src/util/i2pcommon.h @@ -186,6 +186,39 @@ static const std::array, 12> signingKeyLengths { /*SigningKeyType::RedDSA_SHA512_Ed25519 */ std::make_pair( 32, 32), }; +/* + * Key length infos: + * + * BOB private key + * len b64: 884 + * len pln: 663 + * + * BOB public key / destination + * len b64: 516 + * len pln: 387 + * + * SAMv3 private key + * len b64: 908 + * len pln: 679 + * + * SAMv3 public key + * len b64: 516 + * len pln: 387 + * + * Example: + * in bytes, public key only + * 384 (Key) + 3 (Null certificate) = 387 bytes + * 384 (Key) + 7 (key certificate) = 391 bytes + * + * in bytes public + private key + * 384 (Key) + 3 (Null certificate) + 256 (ElGamal) + 20 (DSA_SHA1) = 663 bytes + * 384 (Key) + 7 (key certificate) + 256 (ElGamal) + 32 (EdDSA_SHA512_Ed25519) = 679 bytes + */ +constexpr size_t pubKeyMinLenth_b64 = 516; +constexpr size_t pubKeyMinLenth_bin = 387; +constexpr size_t privKeyMinLenth_b64 = 884; +constexpr size_t privKeyMinLenth_bin = 663; + /** * @brief makeOption Creates the string "lhs=rhs" used by BOB and SAM. Converts rhs * @param lhs option to set From 27fa8a35b0d1d98cccf380d67e24f4b4428cb7f6 Mon Sep 17 00:00:00 2001 From: sehraf Date: Tue, 15 Dec 2020 21:44:01 +0100 Subject: [PATCH 068/697] fix key generation and cleanup --- .../src/gui/settings/ServerPage.cpp | 128 +++--------------- 1 file changed, 21 insertions(+), 107 deletions(-) diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index ee71a9b44..8963ed28b 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -1452,8 +1452,6 @@ void ServerPage::getNewKey() { i2p::address *addr = new i2p::address(); rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::receiveKey, this, addr); - - updateStatus(); } void ServerPage::loadKey() @@ -1550,14 +1548,22 @@ void ServerPage::taskFinished(taskTicket *&ticket) RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); else { // update settings - mSamSettings.address = *addr; + auto copy = *addr; + RsQThreadUtils::postToObject( + [this, copy]() + { + mSamSettings.address = copy; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); + updateStatusSam(); + + }); } delete addr; addr = nullptr; ticket->data = nullptr; - updateStatusSam(); + break; } case autoProxyTask::establishConnection: @@ -1568,13 +1574,19 @@ void ServerPage::taskFinished(taskTicket *&ticket) if (ticket->types.front() != autoProxyType::I2PSAM3) RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); else { + bool res = ticket->result == autoProxyStatus::ok && !!secw->connection->ses; // update settings - if (secw->connection->ses) { - updateInProxyIndicatorResult(true); + if (res) { sam3CloseConnection(secw->connection); secw->connection = nullptr; // freed by above call - } else - updateInProxyIndicatorResult(false); + } + + RsQThreadUtils::postToObject( + [this, res]() + { + updateInProxyIndicatorResult(res); + + }); } if (secw->connection) @@ -1700,7 +1712,7 @@ void ServerPage::updateStatusSam() ui.pbBobGenAddr->hide(); } - saveAddresses(); + saveAddresses(); } samStatus ss; @@ -1764,105 +1776,7 @@ void ServerPage::updateStatusSam() ui.iconlabel_i2p_bob->setToolTip(s); bobSimpleText.append(s); - /* - // update BOB UI based on state - std::string errorString; - switch (bs.cs) { - case csDoConnect: - case csConnected: - case csDoDisconnect: - case csWaitForBob: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); - enableSamElements(false); - - { - QString s; - switch (bs.ct) { - case ctRunCheck: - s = tr("connectivity check"); - break; - case ctRunGetKeys: - s = tr("generating key"); - break; - case ctRunSetUp: - s = tr("starting up"); - break; - case ctRunShutDown: - s = tr("shuting down"); - default: - break; - } - bobSimpleText.append(tr("BOB is processing a request: %1").arg(s)); - } - - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - case csError: - // get error msg from bob - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::getErrorInfo, &errorString); - - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_ERROR)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is broken\n") + QString::fromStdString(errorString)); - - enableSamElements(false); - - bobSimpleText.append(tr("BOB encountered an error:\n")); - bobSimpleText.append(QString::fromStdString(errorString)); - - ui.pbBobStart->setEnabled(true); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(true); - break; - case csDisconnected: - case csIdel: - switch (bs.ct) { - case ctRunSetUp: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is running")); - - enableSamElements(false); - - bobSimpleText.append(tr("BOB is working fine: tunnel established")); - - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(true); - ui.pbBobStop->setEnabled(true); - break; - case ctRunCheck: - case ctRunGetKeys: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); - - enableSamElements(false); - - bobSimpleText.append(tr("BOB is processing a request")); - - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - case ctRunShutDown: - case ctIdle: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is not running")); - - enableSamElements(true); - - bobSimpleText.append(tr("BOB is inactive: tunnel closed")); - - ui.pbBobStart->setEnabled(true); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - } - break; - - } - */ ui.pteBobSimple->setPlainText(bobSimpleText); From 911cbeb61a52d812b5773507ab6f2e12f62415f0 Mon Sep 17 00:00:00 2001 From: sehraf Date: Sat, 28 Nov 2020 11:32:53 +0100 Subject: [PATCH 069/697] fix key generation and cleanup --- libretroshare/src/services/autoproxy/p3i2psam3.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/services/autoproxy/p3i2psam3.cpp b/libretroshare/src/services/autoproxy/p3i2psam3.cpp index 949de2a00..c9e77273e 100644 --- a/libretroshare/src/services/autoproxy/p3i2psam3.cpp +++ b/libretroshare/src/services/autoproxy/p3i2psam3.cpp @@ -506,10 +506,10 @@ bool p3I2pSam3::startSession() if(!mSetting.address.privateKey.empty()) { RS_DBG3("with destination"); - ret = sam3CreateSilentSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, mSetting.address.privateKey.c_str(), Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); + ret = sam3CreateSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, mSetting.address.privateKey.c_str(), Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); } else { RS_DBG("without destination"); - ret = sam3CreateSilentSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); + ret = sam3CreateSession(session, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, Sam3SessionType::SAM3_SESSION_STREAM, Sam3SigType::EdDSA_SHA512_Ed25519, paramsStr.c_str()); } } @@ -561,6 +561,7 @@ bool p3I2pSam3::startForwarding() RS_STACK_MUTEX(mLockSam3Access); + mSetting.session->silent = true; int ret = sam3StreamForward(mSetting.session, sockaddr_storage_iptostring(ps.localaddr).c_str(), sockaddr_storage_port(ps.localaddr)); if (ret < 0) { RS_DBG("forward failed, due to", mSetting.session->error); @@ -686,6 +687,7 @@ void p3I2pSam3::establishConnection(taskTicket *ticket) { auto l = this->mLockSam3Access; RS_STACK_MUTEX(l); + mSetting.session->silent = false; connection = sam3StreamConnect(this->mSetting.session, wrapper->address.publicKey.c_str()); } From feaea75847793af13c0bcc4e0c609a1321679e44 Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 18 Dec 2020 18:53:28 +0100 Subject: [PATCH 070/697] fixup rebase --- retroshare-gui/src/gui/settings/ServerPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 8963ed28b..5755b4015 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -87,7 +87,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); -#ifndef RS_USE_I2P_BOB +#ifndef RS_USE_I2P_SAM3 ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P); // warning: the order of operation here is very important. #endif From 5b1b0cadf9a5056a6a6edfcd5f4003f4536238b5 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 16 Mar 2021 21:36:26 +0100 Subject: [PATCH 071/697] Moved tor binaries into subfolder "tor" for Windows build --- build_scripts/Windows-msys2/build/pack.bat | 10 ++++++++-- build_scripts/Windows/build/pack.bat | 3 ++- build_scripts/Windows/installer/retroshare-Qt5.nsi | 2 +- retroshare-gui/src/TorControl/TorManager.cpp | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build_scripts/Windows-msys2/build/pack.bat b/build_scripts/Windows-msys2/build/pack.bat index 75a66af3c..3bf53ea75 100644 --- a/build_scripts/Windows-msys2/build/pack.bat +++ b/build_scripts/Windows-msys2/build/pack.bat @@ -132,8 +132,14 @@ del /Q "%RsDeployPath%\imageformats\*d?.dll" %Quite% if "%ParamTor%"=="1" ( echo copy tor - copy "%RsMinGWPath%\bin\tor.exe" "%RsDeployPath%" %Quite% - copy "%RsMinGWPath%\bin\tor-gencert.exe" "%RsDeployPath%" %Quite% + if not exist "%RsDeployPath%\tor" mkdir "%RsDeployPath%\tor" + copy "%RsMinGWPath%\bin\tor.exe" "%RsDeployPath%\tor" %Quite% + copy "%RsMinGWPath%\bin\tor-gencert.exe" "%RsDeployPath%\tor" %Quite% + + echo copy tor dependencies + for /R "%RsDeployPath%\tor" %%D in (*.exe) do ( + call :copy_dependencies "%%D" "%RsDeployPath%\tor" + ) ) echo copy dependencies diff --git a/build_scripts/Windows/build/pack.bat b/build_scripts/Windows/build/pack.bat index 8a82f35e3..a48c71d58 100644 --- a/build_scripts/Windows/build/pack.bat +++ b/build_scripts/Windows/build/pack.bat @@ -173,7 +173,8 @@ if exist "%SourcePath%\libresapi\src\webui" ( if "%ParamTor%"=="1" ( echo copy tor - echo n | copy /-y "%EnvTorPath%\Tor\*.*" "%RsDeployPath%" %Quite% + if not exist "%RsDeployPath%\tor" mkdir "%RsDeployPath%\tor" + echo n | copy /-y "%EnvTorPath%\Tor\*.*" "%RsDeployPath%\tor" %Quite% ) rem pack files diff --git a/build_scripts/Windows/installer/retroshare-Qt5.nsi b/build_scripts/Windows/installer/retroshare-Qt5.nsi index a6ebbc81b..4e989b956 100644 --- a/build_scripts/Windows/installer/retroshare-Qt5.nsi +++ b/build_scripts/Windows/installer/retroshare-Qt5.nsi @@ -285,7 +285,7 @@ SectionEnd # Tor !ifdef TOR_EXISTS Section /o $(Section_Tor) Section_Tor - SetOutPath "$INSTDIR" + SetOutPath "$INSTDIR\tor" File /r "${TORDIR}\*" SectionEnd !endif diff --git a/retroshare-gui/src/TorControl/TorManager.cpp b/retroshare-gui/src/TorControl/TorManager.cpp index 221a55935..9f31777e6 100644 --- a/retroshare-gui/src/TorControl/TorManager.cpp +++ b/retroshare-gui/src/TorControl/TorManager.cpp @@ -465,7 +465,7 @@ QString TorManagerPrivate::torExecutablePath() const return path; #ifdef Q_OS_WIN - QString filename(QStringLiteral("/tor.exe")); + QString filename(QStringLiteral("/tor/tor.exe")); #else QString filename(QStringLiteral("/tor")); #endif From bf41f8ad92d45f3cdac7a4735fe4a730a97da1ed Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Fri, 19 Mar 2021 23:10:43 +0530 Subject: [PATCH 072/697] add CORS headers to rsEvents/registerEventsHandler --- libretroshare/src/jsonapi/jsonapi.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index 3fc54f6b0..4b003f225 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -361,11 +361,9 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), [this](const std::shared_ptr session) { const std::weak_ptr weakService(mService); - const std::multimap headers - { - { "Connection", "keep-alive" }, - { "Content-Type", "text/event-stream" } - }; + auto headers = corsHeaders; + headers.insert({ "Connection", "keep-alive" }); + headers.insert({ "Content-Type", "text/event-stream" }); session->yield(rb::OK, headers); size_t reqSize = static_cast( From 505a963212d947fc4f365f8956b66bfa2fec3ba9 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 22 Mar 2021 19:11:23 +0100 Subject: [PATCH 073/697] removed the old macos instructions --- ...MacOS.10.6_RS_Compilation_Instructions.txt | 60 ------------ .../OSX/OSX_RS_Compilation_Instructions.txt | 66 ------------- build_scripts/OSX/retroshare-mac-build.patch | 94 ------------------- 3 files changed, 220 deletions(-) delete mode 100644 build_scripts/OSX/MacOS.10.6_RS_Compilation_Instructions.txt delete mode 100644 build_scripts/OSX/OSX_RS_Compilation_Instructions.txt delete mode 100644 build_scripts/OSX/retroshare-mac-build.patch diff --git a/build_scripts/OSX/MacOS.10.6_RS_Compilation_Instructions.txt b/build_scripts/OSX/MacOS.10.6_RS_Compilation_Instructions.txt deleted file mode 100644 index 3c2c73219..000000000 --- a/build_scripts/OSX/MacOS.10.6_RS_Compilation_Instructions.txt +++ /dev/null @@ -1,60 +0,0 @@ -Hi there, - -I heard about RetroShare recently (on Slashdot) and really like the goal of the program; it's something I've been wanting for a long time now. I'm a software developer so I figured I could help contribute to the project. I started by getting a build up and running on my mac, which was non-trivial as it looks like the Mac build hasn't been maintained (or maybe it's just targetting older OS X version?). Anyway, I have instructions and patches to get a build going on OS X 10.6, if you want to put them up on the wiki or something. The steps I used boiled down to running the following commands in a directory that also contains the retroshare-mac-build.patch file, which I posted at https://staktrace.com/pub/retroshare-mac-build.patch (you can also see the changes at https://github.com/staktrace/retroshare/commit/51f554f909086f4baca7be215d5edacab744dea4) - -sudo port selfupdate -sudo port install qt4-mac -sudo port install wget - -wget ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.10.tar.bz2 -tar xjf libgpg-error-1.10.tar.bz2 -rm libgpg-error-1.10.tar.bz2 -pushd libgpg-error-1.10 -./configure --prefix=$PWD/build --enable-static=yes --enable-shared=no -make -make install -popd - -wget ftp://ftp.gnupg.org/gcrypt/gpgme/gpgme-1.3.1.tar.bz2 -tar xjf gpgme-1.3.1.tar.bz2 -rm gpgme-1.3.1.tar.bz2 -pushd gpgme-1.3.1 -./configure --prefix=$PWD/build --enable-static=yes --enable-shared=no --with-gpg-error-prefix=$PWD/../libgpg-error-1.10/build -make -make install -popd - -wget http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.3.tar.gz -tar xzf miniupnpc-1.3.tar.gz -rm miniupnpc-1.3.tar.gz -pushd miniupnpc-1.3 -make upnpc-static -popd - -git clone https://github.com/kigeia/retroshare -pushd retroshare -git apply ../retroshare-mac-build.patch -popd - -pushd retroshare/libbitdht/src -qmake -make -popd - -pushd retroshare/libretroshare/src -qmake -make -popd - -pushd retroshare/retroshare-gui/src -qmake -make -popd - -At the end there is a RetroShare.App in the retroshare/retroshare-gui/ folder which seems to work as expected. - -Now that I've gotten it building and working, I'd like to start working on adding features. One that I would like to see is taking advantage of the RetroShare platform to enable F2F games. A while back I wrote a P2P collaborative crossword solver app in Java; porting that to work as a RetroShare plugin would probably be a good start for me. I looked briefly at the existing plugins in the source tree but haven't yet had time to peruse the rsplugin.h API in detail; if you have any tips or pointers before I dive in, please do let me know. I'll probably start work on it in a couple of days and progress might be a little slow because I'm also fairly busy with other things right now. - -Cheers, -kats - diff --git a/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt b/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt deleted file mode 100644 index 684c45f3e..000000000 --- a/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt +++ /dev/null @@ -1,66 +0,0 @@ - -Mac OSX Build Instructions. -------------------------------------------- - -There are several complications with building Retroshare under OSX. - 1) Support Libraries must be built and installed seperately. - 2) Universal and OSX 10.5 support is a little tricky, mainly due to the support libraries. - -Additional Libraries ---------------------- - - * GnuPG Package, that comes with Retroshare OSX install image. (GnuPG-1.4.9.dmg) - -GPG Development libraries - * libassuan (I'm using 2.0.1) - * libgpg-error (I'm using 1.9) - * libgpgme (I'm using 1.3.0) - -These libraries use standard UNIX installation systems: AUTOCONF/AUTOMAKE (configure, make, etc) -Unfortunately, this makes it difficult and a little manual to compile Universal and 10.5 libraries. - -UPNPC (for OSX and windows) - * miniupnpc (I'm using 1.0) - -You will also need to install - * XCode (available on the Apple Install CDs) - * Qt4 (from trolltech.com) - -First Compilation... --------------------- - -The First challenge is to build Retroshare on your Mac. For this first compilation, -we only build for your specific machine, and not attempt a Generic / 10.5 / Univeral build. - - -1) Install / Compile all the packages listed above. - be sure to use a configure command like this where applicable to only create a static library. - ./configure --enable-static=yes --enable-shared=no CFLAGS="-arch i386" CPPFLAGS="-arch i386" - -2) Check out the Retroshare SVN. - -3) compile libbitdht: - cd libbitdht/src - qmake - - This recreates a xcodeproj file for compilation using XCode. - Open with Xcode, and build. - -4) compile libretroshare: same way. -5) compile retroshare-gui: same way. - - -Creating Retroshare OSX Distribution Packages. ------------------------------------------------ - TODO, once I've got feedback on First Compilation! - - - - - - - - - - - diff --git a/build_scripts/OSX/retroshare-mac-build.patch b/build_scripts/OSX/retroshare-mac-build.patch deleted file mode 100644 index 7023ad7c2..000000000 --- a/build_scripts/OSX/retroshare-mac-build.patch +++ /dev/null @@ -1,94 +0,0 @@ -commit 51f554f909086f4baca7be215d5edacab744dea4 -Author: Kartikaya Gupta -Date: Wed Mar 7 23:30:48 2012 -0500 - - Modifications needed to get build working on Mac OS X 10.6 - -diff --git a/.gitignore b/.gitignore -new file mode 100644 -index 0000000..3e90033 ---- /dev/null -+++ b/.gitignore -@@ -0,0 +1,6 @@ -+*.o -+Makefile -+libbitdht/src/lib/ -+libretroshare/src/lib/ -+retroshare-gui/src/RetroShare.app/ -+retroshare-gui/src/temp/ -diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro -index 6f35e01..267cc91 100644 ---- a/libretroshare/src/libretroshare.pro -+++ b/libretroshare/src/libretroshare.pro -@@ -312,7 +312,7 @@ mac { - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW -- #DEFINES *= MINIUPNPC_VERSION=13 -+ DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - #miniupnp implementation files -@@ -326,12 +326,11 @@ mac { - # Beautiful Hack to fix 64bit file access. - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs - -- UPNPC_DIR = ../../../miniupnpc-1.0 -- GPG_ERROR_DIR = ../../../../libgpg-error-1.7 -- GPGME_DIR = ../../../../gpgme-1.1.8 -+ UPNPC_DIR = ../../../miniupnpc-1.3 -+ GPG_ERROR_DIR = ../../../libgpg-error-1.10 -+ GPGME_DIR = ../../../gpgme-1.3.1 - -- INCLUDEPATH += . $${UPNPC_DIR} -- #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src -+ INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src - } - - ################################# FreeBSD ########################################## -diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc -index 2588cb8..305433f 100644 ---- a/libretroshare/src/pqi/sslfns.cc -+++ b/libretroshare/src/pqi/sslfns.cc -@@ -586,8 +586,8 @@ X509 *loadX509FromDER(const uint8_t *ptr, uint32_t len) - X509 *tmp = NULL; - #ifdef __APPLE__ - // This depends on which version you are compiling for... OSX10.5 doesn't have consts (old OpenSSL!) -- unsigned char **certptr = (unsigned char **) &ptr; -- //const unsigned char **certptr = (const unsigned char **) &ptr; -+ //unsigned char **certptr = (unsigned char **) &ptr; -+ const unsigned char **certptr = (const unsigned char **) &ptr; - #else - const unsigned char **certptr = (const unsigned char **) &ptr; - #endif -diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro -index adcb5a0..ffbf669 100644 ---- a/retroshare-gui/src/RetroShare.pro -+++ b/retroshare-gui/src/RetroShare.pro -@@ -140,19 +140,21 @@ win32 { - - macx { - # ENABLE THIS OPTION FOR Univeral Binary BUILD. -- CONFIG += ppc x86 -- QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 -+ # CONFIG += ppc x86 -+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 - - CONFIG += version_detail_bash_script - LIBS += ../../libretroshare/src/lib/libretroshare.a -- LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan -- LIBS += ../../../miniupnpc-1.0/libminiupnpc.a -+ LIBS += ../../../libgpg-error-1.10/build/lib/libgpg-error.a -+ LIBS += ../../../gpgme-1.3.1/build/lib/libgpgme.a -+ LIBS += ../../../miniupnpc-1.3/libminiupnpc.a -+ LIBS += -lssl -lcrypto -lz -lassuan - LIBS += -framework CoreFoundation - LIBS += -framework Security - - # LIBS += -framework CoreServices - -- INCLUDEPATH += . -+ INCLUDEPATH += . ../../../gpgme-1.3.1/src - #DEFINES* = MAC_IDLE # for idle feature - CONFIG -= uitools - From 67c607cb3228e1282dd2375ec46a8b9be9295742 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 23 Mar 2021 23:04:10 +0100 Subject: [PATCH 074/697] Fix Android compilation --- build_scripts/Android/README.asciidoc | 6 +++--- libretroshare/src/pqi/pqinetwork.cc | 14 +++++++------- libretroshare/src/use_libretroshare.pri | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build_scripts/Android/README.asciidoc b/build_scripts/Android/README.asciidoc index 3f978cfd1..d5670e10c 100644 --- a/build_scripts/Android/README.asciidoc +++ b/build_scripts/Android/README.asciidoc @@ -75,7 +75,7 @@ deployment) [source,makefile] ------------------------------------------------------------------------------- -CONFIG+=retroshare_service CONFIG+=rs_jsonapi CONFIG+=rs_deep_search +CONFIG+=retroshare_service CONFIG+=rs_jsonapi CONFIG+=no_keywords RS_UPNP_LIB=miniupnpc JSONAPI_GENERATOR_EXE=Your_Path/jsonapi-generator/src/jsonapi-generator NATIVE_LIBS_TOOLCHAIN_PATH=Your_Path/retroshare-android-16-arm/ @@ -391,8 +391,8 @@ https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/android/app/build.g == License -Copyright (C) 2016-2020 Gioacchino Mazzurco + -Copyright (C) 2020 Asociación Civil Altermundi + +Copyright (C) 2016-2021 Gioacchino Mazzurco + +Copyright (C) 2020-2021 Asociación Civil Altermundi + This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 18fe71fc0..a5ca76035 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * + * Copyright (C) 2015-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -30,14 +31,13 @@ # include #endif // def __ANDROID__ -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" - -#include +#include #include -#include +#include #include +#include "pqi/pqinetwork.h" +#include "util/rsnet.h" #include "util/rsdebug.h" #include "util/rsstring.h" #include "util/rsnet.h" @@ -325,7 +325,7 @@ bool getLocalAddresses(std::vector& addrs) } free(adapter_addresses); #elif defined(__ANDROID__) && __ANDROID_API__ < 24 - foreach(QHostAddress qAddr, QNetworkInterface::allAddresses()) + for(auto& qAddr: QNetworkInterface::allAddresses()) { sockaddr_storage tmpAddr; sockaddr_storage_clear(tmpAddr); diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index b76c4a5da..ee8872104 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -59,7 +59,7 @@ linux-* { mLibs += dl } -rs_deep_channels_index | rs_deep_files_index { +rs_deep_channels_index | rs_deep_files_index | rs_deep_forums_index { mLibs += xapian win32-g++|win32-clang-g++:mLibs += rpcrt4 } From 2064d7c6ffc3411dc30be703bbc18f23eaf35d85 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 24 Mar 2021 17:48:19 +0100 Subject: [PATCH 075/697] Update OBS submodule --- build_scripts/OBS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/OBS b/build_scripts/OBS index b0d7ae39f..6d6ee4aab 160000 --- a/build_scripts/OBS +++ b/build_scripts/OBS @@ -1 +1 @@ -Subproject commit b0d7ae39fe9d9192848bbf7b8902d2188da895c9 +Subproject commit 6d6ee4aab171c23c603f7e813ba66d22192393ad From bb6841370ff9467b6ea925e85ea968647f1dde89 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Thu, 25 Mar 2021 18:20:11 +0100 Subject: [PATCH 076/697] Fix: WebUI truncating binary files. Fixes font files not loading properly in the webui problem. --- libretroshare/src/jsonapi/p3webui.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/jsonapi/p3webui.cc b/libretroshare/src/jsonapi/p3webui.cc index 60fc63ea9..acb907c5d 100644 --- a/libretroshare/src/jsonapi/p3webui.cc +++ b/libretroshare/src/jsonapi/p3webui.cc @@ -76,21 +76,21 @@ public: std::string resource_filename = _base_directory + "/" + directory + filename; RsDbg() << "Reading file: \"" << resource_filename << "\"" << std::endl; - std::ifstream stream( resource_filename, std::ifstream::in ); + std::ifstream stream( resource_filename, std::ifstream::binary); if(stream.is_open()) { - const std::string body = std::string( + const std::vector body = std::vector( std::istreambuf_iterator(stream), std::istreambuf_iterator() ); RsDbg() << __PRETTY_FUNCTION__ - << " body length=" << body.length() << std::endl; + << " body length=" << body.size() << std::endl; const std::multimap headers { { "Content-Type", mime_types[MIME_TYPE_INDEX] }, - { "Content-Length", std::to_string(body.length()) } + { "Content-Length", std::to_string(body.size()) } }; session->close(restbed::OK, body, headers); From a783ffac75392df4a00b4622c6697c10abdc2f2e Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 26 Mar 2021 12:06:10 +0100 Subject: [PATCH 077/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 79 +++++++++++++++-------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 8ab94b605..5e33e14eb 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -8,7 +8,7 @@ Use default options. And add Qt Script support. Add to the PATH environment variable by editing your *~/.profile* file. - export PATH="/users/$USER/Qt/5.5/clang_64/bin:$PATH" + export PATH="/users/$USER/Qt/5.14.1/clang_64/bin:$PATH." Depends on which version of Qt you use. @@ -22,15 +22,15 @@ Start XCode to get it updated and to able C compiler to create executables. #### Install libraries - $sudo port -v selfupdate - $sudo port install openssl - $sudo port install miniupnpc - $sudo port install libmicrohttpd + $ sudo port -v selfupdate + $ sudo port install openssl + $ sudo port install miniupnpc + $ sudo port install libmicrohttpd For VOIP Plugin: - $sudo port install speex-devel - $sudo port install opencv + $ sudo port install speex-devel + $ sudo port install opencv Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) @@ -46,9 +46,11 @@ Start XCode to get it updated and to able C compiler to create executables. #### Install libraries - $brew install openssl - $brew install miniupnpc - $brew install libmicrohttpd + $ brew install openssl + $ brew install miniupnpc + $ brew install libmicrohttpd + $ brew install rapidjson + $ brew install sqlcipher If you have error in linking, run this: @@ -56,29 +58,52 @@ If you have error in linking, run this: For VOIP Plugin: - $brew install speex - $brew install speexdsp - $brew install homebrew/science/opencv - $brew install ffmpeg + $ brew install speex + $ brew install speexdsp + $ brew install homebrew/science/opencv + $ brew install ffmpeg Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) ## Last Settings -In QtCreator Option Git select "Pull" with "Rebase" +In QtCreator Option Git add his path: -## Compil missing libraries -### SQLCipher - - cd - git clone https://github.com/sqlcipher/sqlcipher.git - cd sqlcipher - ./configure --disable-shared --disable-tcl --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I/opt/local/include" LDFLAGS="-lcrypto" - make - sudo make install + /usr/local/bin + +select "Pull" with "Rebase" + +## Set your Mac OS SDK version + +Edit RetroShare.pro + + CONFIG += c++14 rs_macos11.1 + +and then retroshare.pri + + macx:CONFIG *= rs_macos11.1 + rs_macos10.8:CONFIG -= rs_macos11.1 + rs_macos10.9:CONFIG -= rs_macos11.1 + rs_macos10.10:CONFIG -= rs_macos11.1 + rs_macos10.12:CONFIG -= rs_macos11.1 + rs_macos10.13:CONFIG -= rs_macos11.1 + rs_macos10.14:CONFIG -= rs_macos11.1 + rs_macos10.15:CONFIG -= rs_macos11.1 + + +## Link Include & Libraries + +Edit your retroshare.pri and add to macx-* section + + INCLUDEPATH += "/usr/local/opt/openssl/include" + QMAKE_LIBDIR += "/usr/local/opt/openssl/lib" + QMAKE_LIBDIR += "/usr/local/opt/sqlcipher/lib" + QMAKE_LIBDIR += "/usr/local/opt/miniupnpc/lib" + +alternative via Terminal + +$ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" -NOTE, might be necessary to *chmod 000 /usr/local/ssl* temporarily during *./configure* if -homebrew uses newer, non-stock ssl dependencies found there. Configure might get confused. You can now compile RS into Qt Creator or with terminal @@ -89,4 +114,4 @@ You can now compile RS into Qt Creator or with terminal You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK -You can find compiled application on *./retroshare/retroshare-gui/src/retroshare.app* +You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app* From f17d2eb4df968c0ccbd375efcc84b4c5f0bcc0a4 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 26 Mar 2021 12:49:08 +0100 Subject: [PATCH 078/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 5e33e14eb..05b09f89d 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -67,7 +67,7 @@ Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SD ## Last Settings -In QtCreator Option Git add his path: +In QtCreator Option Git add this path: /usr/local/bin From a7c2ec43a353e38ea1457270d223c63b0abb5922 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 26 Mar 2021 17:36:01 +0100 Subject: [PATCH 079/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 05b09f89d..17dbf2c71 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -73,6 +73,10 @@ In QtCreator Option Git add this path: select "Pull" with "Rebase" +In QtCreator Projects -> Build Settings -> Build Steps -> Add Additional arguments: + + "CONFIG+=rs_autologin" "CONFIG+=rs_use_native_dialogs" + ## Set your Mac OS SDK version Edit RetroShare.pro From 43eeca57b9a9b01ad0d7730241793917872fe4f5 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 26 Mar 2021 21:22:48 +0100 Subject: [PATCH 080/697] Added to ship gui and chat styles for macOS --- retroshare-gui/src/retroshare-gui.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 11bb33dca..e547ad659 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -280,6 +280,14 @@ macx { mac_icon.files = $$files($$PWD/rsMacIcon.icns) mac_icon.path = Contents/Resources QMAKE_BUNDLE_DATA += mac_icon + dplQSS.files = $$PWD/qss + dplQSS.path = Contents/Resources + QMAKE_BUNDLE_DATA += dplQSS + dplChatStyles.files = \ + $$PWD/gui/qss/chat/Bubble \ + $$PWD/gui/qss/chat/Bubble_Compact + dplChatStyles.path = Contents/Resources/stylesheets + QMAKE_BUNDLE_DATA += dplChatStyles # mac_webui.files = $$files($$PWD/../../libresapi/src/webui) # mac_webui.path = Contents/Resources # QMAKE_BUNDLE_DATA += mac_webui From dca887ab9e09498eb215705cbccd19bcb342dfda Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 26 Mar 2021 23:03:58 +0100 Subject: [PATCH 081/697] Added OBJECTS_DIR for macOS section --- retroshare-gui/src/retroshare-gui.pro | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index e547ad659..654efd170 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -292,9 +292,10 @@ macx { # mac_webui.path = Contents/Resources # QMAKE_BUNDLE_DATA += mac_webui + OBJECTS_DIR = temp/obj + CONFIG += version_detail_bash_script - LIBS += -lssl -lcrypto -lz - #LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan + LIBS += -lssl -lcrypto -lz for(lib, LIB_DIR):exists($$lib/libminiupnpc.a){ LIBS += $$lib/libminiupnpc.a} LIBS += -framework CoreFoundation LIBS += -framework Security From bfc045673029bbecfc5debe4a91f90ebbcdaae7d Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 27 Mar 2021 13:42:47 +0100 Subject: [PATCH 082/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 17dbf2c71..d7b5154d3 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -8,7 +8,7 @@ Use default options. And add Qt Script support. Add to the PATH environment variable by editing your *~/.profile* file. - export PATH="/users/$USER/Qt/5.14.1/clang_64/bin:$PATH." + export PATH="/users/$USER/Qt/5.14.1/clang_64/bin:$PATH" Depends on which version of Qt you use. @@ -63,6 +63,10 @@ For VOIP Plugin: $ brew install homebrew/science/opencv $ brew install ffmpeg +For FeedReader Plugin: + + $ brew install libxml2 + Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) ## Last Settings @@ -108,6 +112,9 @@ alternative via Terminal $ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" +For FeedReader Plugin: + + INCLUDEPATH += "/usr/local/Cellar/libxml2/2.9.10_2/include/libxml2" You can now compile RS into Qt Creator or with terminal From f90692f8f25b90cd02fae9bfb862bd2222238c27 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sat, 27 Mar 2021 22:13:58 +0100 Subject: [PATCH 083/697] Fixed avatar tooltip --- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 2 +- retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp | 3 +++ retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp | 3 +++ retroshare-gui/src/gui/msgs/MessageModel.cpp | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index 51dbcf2bc..338c8aabf 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -1104,7 +1104,7 @@ QString nickname ; nickname = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; - comment = QString("%1:%2
%3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"), + comment = QString("%1: %2
%3: %4").arg(QApplication::translate("GxsIdDetails", "Identity name"), nickname, QApplication::translate("GxsIdDetails", "Identity Id"), QString::fromStdString(details.mId.toStdString())); diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index 0a8b9271b..c14d21024 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -170,7 +170,10 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const QString embeddedImage; if ( RsHtml::makeEmbeddedImage( pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation ).toImage(), embeddedImage, 8*S * 8*S ) ) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); t = "
" + embeddedImage + "" + t + "
"; + } return t; } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index 3d168acf7..2f22067eb 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -567,7 +567,10 @@ QVariant RsGxsForumModel::toolTipRole(const ForumModelPostEntry& fmpe,int column QString embeddedImage; if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
" + embeddedImage + "" + comment + "
"; + } return comment; } diff --git a/retroshare-gui/src/gui/msgs/MessageModel.cpp b/retroshare-gui/src/gui/msgs/MessageModel.cpp index 3d3367553..c71609ca4 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.cpp +++ b/retroshare-gui/src/gui/msgs/MessageModel.cpp @@ -403,7 +403,10 @@ QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int co QString embeddedImage; if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
" + embeddedImage + "" + comment + "
"; + } return comment; } From 4d6aa8ab5b26032642d4d22f181896159141f423 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sat, 27 Mar 2021 23:32:47 +0100 Subject: [PATCH 084/697] Raise avatar size to better match the amount of text --- retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp | 2 +- retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp | 4 ++-- retroshare-gui/src/gui/msgs/MessageModel.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index c14d21024..4c1715a39 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -169,7 +169,7 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const QString embeddedImage; - if ( RsHtml::makeEmbeddedImage( pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation ).toImage(), embeddedImage, 8*S * 8*S ) ) + if ( RsHtml::makeEmbeddedImage( pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation ).toImage(), embeddedImage, -1 ) ) { embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); t = "
" + embeddedImage + "" + t + "
"; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index 2f22067eb..07d44ca1b 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -563,10 +563,10 @@ QVariant RsGxsForumModel::toolTipRole(const ForumModelPostEntry& fmpe,int column return QVariant(); int S = QFontMetricsF(QApplication::font()).height(); - QImage pix( (*icons.begin()).pixmap(QSize(4*S,4*S)).toImage()); + QImage pix( (*icons.begin()).pixmap(QSize(5*S,5*S)).toImage()); QString embeddedImage; - if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, -1)) { embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
" + embeddedImage + "" + comment + "
"; diff --git a/retroshare-gui/src/gui/msgs/MessageModel.cpp b/retroshare-gui/src/gui/msgs/MessageModel.cpp index c71609ca4..5196764a3 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.cpp +++ b/retroshare-gui/src/gui/msgs/MessageModel.cpp @@ -399,10 +399,10 @@ QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int co return QVariant(); int S = QFontMetricsF(QApplication::font()).height(); - QImage pix( (*icons.begin()).pixmap(QSize(4*S,4*S)).toImage()); + QImage pix( (*icons.begin()).pixmap(QSize(5*S,5*S)).toImage()); QString embeddedImage; - if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, -1)) { embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
" + embeddedImage + "" + comment + "
"; From b4a3d6748666a13227d7ad6425d190e9f78896cf Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Mar 2021 13:26:49 +0200 Subject: [PATCH 085/697] fixed use of no avatar instead of default avatar image when creating a new ID --- .../src/gui/Identity/IdEditDialog.cpp | 18 +++++++++--------- retroshare-gui/src/gui/Identity/IdEditDialog.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 7f9f179cb..20e169306 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -46,6 +46,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) : ui(new(Ui::IdEditDialog)) { mIsNew = true; + mAvatarIsSet = false; ui->setupUi(this); @@ -126,6 +127,7 @@ void IdEditDialog::changeAvatar() ui->avatarLabel->setPicture(QPixmap::fromImage(img)); ui->avatarLabel->setEnableZoom(true); ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + mAvatarIsSet = true; // shows the tooltip for a while QToolTip::showText( ui->avatarLabel->mapToGlobal( QPoint( 0, 0 ) ), ui->avatarLabel->toolTip() ); @@ -211,10 +213,12 @@ void IdEditDialog::setAvatar(const QPixmap &avatar) if (!mAvatar.isNull()) { ui->avatarLabel->setPicture(avatar); + mAvatarIsSet = true; } else { // we need to use the default pixmap here, generated from the ID - ui->avatarLabel->setPicture(GxsIdDetails::makeDefaultIcon(RsGxsId(mEditGroup.mMeta.mGroupId))); - } + ui->avatarLabel->setText(tr("No avatar chosen\ndefault will\nbe used")); + mAvatarIsSet = false; + } } void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId) @@ -517,13 +521,9 @@ void IdEditDialog::loadRecognTags() void IdEditDialog::submit() { if (mIsNew) - { createId(); - } else - { updateId(); - } } void IdEditDialog::createId() @@ -551,10 +551,10 @@ void IdEditDialog::createId() params.nickname = groupname.toUtf8().constData(); params.isPgpLinked = (ui->radioButton_GpgId->isChecked()); - mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); - - if (!mAvatar.isNull()) + if(mAvatarIsSet) { + mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); + QByteArray ba; QBuffer buffer(&ba); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index 36eed2891..f3d49601f 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -84,6 +84,7 @@ protected: RsGxsGroupId mGroupId; QPixmap mAvatar; // Avatar from identity (not calculated) + bool mAvatarIsSet; }; #endif From 9a500dc62ff94bbb7c03bf43009050b150c03119 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 29 Mar 2021 18:22:32 +0200 Subject: [PATCH 086/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index d7b5154d3..1c6fdea02 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -110,7 +110,7 @@ Edit your retroshare.pri and add to macx-* section alternative via Terminal -$ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" + $ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" For FeedReader Plugin: From 9617ee5135f0ab20273dbac6ff1473bdbbd69124 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 29 Mar 2021 22:25:03 +0200 Subject: [PATCH 087/697] added the possibility to clear the avatar when editing --- .../src/gui/Identity/IdEditDialog.cpp | 16 ++++++++++++++-- .../src/gui/Identity/IdEditDialog.h | 1 + .../src/gui/Identity/IdEditDialog.ui | 3 +++ .../gxschannels/GxsChannelPostThumbnail.cpp | 19 +++++++++++++++++++ .../gui/gxschannels/GxsChannelPostThumbnail.h | 7 ++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 20e169306..a77713e1e 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -89,6 +89,11 @@ IdEditDialog::IdEditDialog(QWidget *parent) : connect(ui->toolButton_Tag5, SIGNAL(clicked(bool)), this, SLOT(rmTag5())); connect(ui->avatarButton, SIGNAL(clicked(bool)), this, SLOT(changeAvatar())); + connect(ui->avatarLabel,SIGNAL(cleared()),this,SLOT(avatarCleared())); + + ui->avatarLabel->setEnableClear(true); + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); + /* Initialize ui */ ui->lineEdit_Nickname->setMaxLength(RSID_MAXIMUM_NICKNAME_SIZE); @@ -126,7 +131,7 @@ void IdEditDialog::changeAvatar() ui->avatarLabel->setPicture(QPixmap::fromImage(img)); ui->avatarLabel->setEnableZoom(true); - ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); mAvatarIsSet = true; // shows the tooltip for a while @@ -207,6 +212,11 @@ void IdEditDialog::updateIdType(bool pseudo) } } +void IdEditDialog::avatarCleared() +{ + setAvatar(QPixmap()); +} + void IdEditDialog::setAvatar(const QPixmap &avatar) { mAvatar = avatar; @@ -214,10 +224,12 @@ void IdEditDialog::setAvatar(const QPixmap &avatar) if (!mAvatar.isNull()) { ui->avatarLabel->setPicture(avatar); mAvatarIsSet = true; + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); } else { // we need to use the default pixmap here, generated from the ID - ui->avatarLabel->setText(tr("No avatar chosen\ndefault will\nbe used")); + ui->avatarLabel->setText(tr("No avatar chosen")); // This clears up the image mAvatarIsSet = false; + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); } } diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index f3d49601f..8ee6b15c9 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -51,6 +51,7 @@ public: private slots: void idTypeToggled(bool checked); void submit(); + void avatarCleared(); void changeAvatar(); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.ui b/retroshare-gui/src/gui/Identity/IdEditDialog.ui index fee114a9d..e30c12d8a 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.ui @@ -310,6 +310,9 @@ 128 + + Qt::StrongFocus + QFrame::Box diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp index eb890b075..ee40e1465 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp @@ -217,6 +217,25 @@ float ChannelPostThumbnailView::thumbnail_h() const } } +void ZoomableLabel::keyPressEvent(QKeyEvent *e) +{ + switch(e->key()) + { + case Qt::Key_Delete: + + if(mClearEnabled) + { + mFullImage = QPixmap(); + emit cleared(); + e->accept(); + updateView(); + } + break; + default: + QLabel::keyPressEvent(e); + } +} + void ZoomableLabel::reset() { mCenterX = mFullImage.width()/2.0; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h index d89fd5eca..7e8bab4b0 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h @@ -40,18 +40,22 @@ class ZoomableLabel: public QLabel Q_OBJECT public: - ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true) {} + ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true),mClearEnabled(false) {} void setPicture(const QPixmap& pix); void setEnableZoom(bool b) { mZoomEnabled = b; } + void setEnableClear(bool b) { mClearEnabled = b; } void reset(); QPixmap extractCroppedScaledPicture() const; void updateView(); + virtual void keyPressEvent(QKeyEvent *ev) override; + const QPixmap& originalImage() const { return mFullImage ; } signals: void clicked(); + void cleared(); protected: void mousePressEvent(QMouseEvent *ev) override; @@ -73,6 +77,7 @@ protected: int mLastX,mLastY; bool mMoving; bool mZoomEnabled; + bool mClearEnabled; }; // Class to paint the thumbnails with title From 5274a060e5efb37e727d036c587ebe0e8852c496 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 28 Mar 2021 13:26:49 +0200 Subject: [PATCH 088/697] fixed use of no avatar instead of default avatar image when creating a new ID --- .../src/gui/Identity/IdEditDialog.cpp | 18 +++++++++--------- retroshare-gui/src/gui/Identity/IdEditDialog.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 7f9f179cb..20e169306 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -46,6 +46,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) : ui(new(Ui::IdEditDialog)) { mIsNew = true; + mAvatarIsSet = false; ui->setupUi(this); @@ -126,6 +127,7 @@ void IdEditDialog::changeAvatar() ui->avatarLabel->setPicture(QPixmap::fromImage(img)); ui->avatarLabel->setEnableZoom(true); ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + mAvatarIsSet = true; // shows the tooltip for a while QToolTip::showText( ui->avatarLabel->mapToGlobal( QPoint( 0, 0 ) ), ui->avatarLabel->toolTip() ); @@ -211,10 +213,12 @@ void IdEditDialog::setAvatar(const QPixmap &avatar) if (!mAvatar.isNull()) { ui->avatarLabel->setPicture(avatar); + mAvatarIsSet = true; } else { // we need to use the default pixmap here, generated from the ID - ui->avatarLabel->setPicture(GxsIdDetails::makeDefaultIcon(RsGxsId(mEditGroup.mMeta.mGroupId))); - } + ui->avatarLabel->setText(tr("No avatar chosen\ndefault will\nbe used")); + mAvatarIsSet = false; + } } void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId) @@ -517,13 +521,9 @@ void IdEditDialog::loadRecognTags() void IdEditDialog::submit() { if (mIsNew) - { createId(); - } else - { updateId(); - } } void IdEditDialog::createId() @@ -551,10 +551,10 @@ void IdEditDialog::createId() params.nickname = groupname.toUtf8().constData(); params.isPgpLinked = (ui->radioButton_GpgId->isChecked()); - mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); - - if (!mAvatar.isNull()) + if(mAvatarIsSet) { + mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); + QByteArray ba; QBuffer buffer(&ba); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index 36eed2891..f3d49601f 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -84,6 +84,7 @@ protected: RsGxsGroupId mGroupId; QPixmap mAvatar; // Avatar from identity (not calculated) + bool mAvatarIsSet; }; #endif From fd5766a5fb1fcefc4aba98f6747df829c188e90d Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 29 Mar 2021 22:25:03 +0200 Subject: [PATCH 089/697] added the possibility to clear the avatar when editing --- .../src/gui/Identity/IdEditDialog.cpp | 16 ++++++++++++++-- .../src/gui/Identity/IdEditDialog.h | 1 + .../src/gui/Identity/IdEditDialog.ui | 3 +++ .../gxschannels/GxsChannelPostThumbnail.cpp | 19 +++++++++++++++++++ .../gui/gxschannels/GxsChannelPostThumbnail.h | 7 ++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 20e169306..a77713e1e 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -89,6 +89,11 @@ IdEditDialog::IdEditDialog(QWidget *parent) : connect(ui->toolButton_Tag5, SIGNAL(clicked(bool)), this, SLOT(rmTag5())); connect(ui->avatarButton, SIGNAL(clicked(bool)), this, SLOT(changeAvatar())); + connect(ui->avatarLabel,SIGNAL(cleared()),this,SLOT(avatarCleared())); + + ui->avatarLabel->setEnableClear(true); + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); + /* Initialize ui */ ui->lineEdit_Nickname->setMaxLength(RSID_MAXIMUM_NICKNAME_SIZE); @@ -126,7 +131,7 @@ void IdEditDialog::changeAvatar() ui->avatarLabel->setPicture(QPixmap::fromImage(img)); ui->avatarLabel->setEnableZoom(true); - ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); mAvatarIsSet = true; // shows the tooltip for a while @@ -207,6 +212,11 @@ void IdEditDialog::updateIdType(bool pseudo) } } +void IdEditDialog::avatarCleared() +{ + setAvatar(QPixmap()); +} + void IdEditDialog::setAvatar(const QPixmap &avatar) { mAvatar = avatar; @@ -214,10 +224,12 @@ void IdEditDialog::setAvatar(const QPixmap &avatar) if (!mAvatar.isNull()) { ui->avatarLabel->setPicture(avatar); mAvatarIsSet = true; + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); } else { // we need to use the default pixmap here, generated from the ID - ui->avatarLabel->setText(tr("No avatar chosen\ndefault will\nbe used")); + ui->avatarLabel->setText(tr("No avatar chosen")); // This clears up the image mAvatarIsSet = false; + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); } } diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index f3d49601f..8ee6b15c9 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -51,6 +51,7 @@ public: private slots: void idTypeToggled(bool checked); void submit(); + void avatarCleared(); void changeAvatar(); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.ui b/retroshare-gui/src/gui/Identity/IdEditDialog.ui index fee114a9d..e30c12d8a 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.ui @@ -310,6 +310,9 @@ 128 + + Qt::StrongFocus + QFrame::Box diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp index eb890b075..ee40e1465 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp @@ -217,6 +217,25 @@ float ChannelPostThumbnailView::thumbnail_h() const } } +void ZoomableLabel::keyPressEvent(QKeyEvent *e) +{ + switch(e->key()) + { + case Qt::Key_Delete: + + if(mClearEnabled) + { + mFullImage = QPixmap(); + emit cleared(); + e->accept(); + updateView(); + } + break; + default: + QLabel::keyPressEvent(e); + } +} + void ZoomableLabel::reset() { mCenterX = mFullImage.width()/2.0; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h index d89fd5eca..7e8bab4b0 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h @@ -40,18 +40,22 @@ class ZoomableLabel: public QLabel Q_OBJECT public: - ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true) {} + ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true),mClearEnabled(false) {} void setPicture(const QPixmap& pix); void setEnableZoom(bool b) { mZoomEnabled = b; } + void setEnableClear(bool b) { mClearEnabled = b; } void reset(); QPixmap extractCroppedScaledPicture() const; void updateView(); + virtual void keyPressEvent(QKeyEvent *ev) override; + const QPixmap& originalImage() const { return mFullImage ; } signals: void clicked(); + void cleared(); protected: void mousePressEvent(QMouseEvent *ev) override; @@ -73,6 +77,7 @@ protected: int mLastX,mLastY; bool mMoving; bool mZoomEnabled; + bool mClearEnabled; }; // Class to paint the thumbnails with title From cd61ec8635433078191f46263379c635da59ca88 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 31 Mar 2021 22:31:00 +0200 Subject: [PATCH 090/697] move initialization of UI at the top in NewsFeed --- retroshare-gui/src/gui/NewsFeed.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 4d552735e..afef19b16 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -83,7 +83,10 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), RsEventType::MAIL_STATUS }) { - for(uint32_t i=0;isetupUi(this); + + for(uint32_t i=0;iregisterEventsHandler( @@ -91,9 +94,6 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), mEventHandlerIds.back(), mEventTypes[i] ); } - /* Invoke the Qt Designer generated object setup routine */ - ui->setupUi(this); - if (!instance) { instance = this; } From 0683bd27175c6738a14048975f8c5fb4f08749eb Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 2 Apr 2021 12:02:01 +0200 Subject: [PATCH 091/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 24 +++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 1c6fdea02..df28ce21b 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -60,7 +60,7 @@ For VOIP Plugin: $ brew install speex $ brew install speexdsp - $ brew install homebrew/science/opencv + $ brew install opencv $ brew install ffmpeg For FeedReader Plugin: @@ -116,7 +116,27 @@ For FeedReader Plugin: INCLUDEPATH += "/usr/local/Cellar/libxml2/2.9.10_2/include/libxml2" -You can now compile RS into Qt Creator or with terminal +For building RetroShare with plugins: + + $ qmake \ + INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" \ + INCLUDEPATH+="/usr/local/opt/opencv/include/opencv4" QMAKE_LIBDIR+="/usr/local/opt/opencv/lib" \ + INCLUDEPATH+="/usr/local/opt/speex/include" QMAKE_LIBDIR+="/usr/local/opt/speex/lib/" \ + INCLUDEPATH+="/usr/local/opt/speexdsp/include" QMAKE_LIBDIR+="/usr/local/opt/speexdsp/lib/" \ + INCLUDEPATH+="/usr/local/opt/libxslt/include" QMAKE_LIBDIR+="/usr/local/opt/libxslt/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/ffmpeg/lib" \ + LIBS+=-lopencv_videoio \ + CONFIG+=retroshare_plugins \ + CONFIG+=rs_autologin \ + CONFIG+=rs_use_native_dialogs \ + CONFIG+=release \ + .. + +## Compile RetroShare + +You can now compile RetroShare into Qt Creator or with Terminal cd git clone https://github.com/RetroShare/RetroShare.git retroshare From 729f36c792bf4afef6bde244e99beeca91f52d0b Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 2 Apr 2021 12:29:21 +0200 Subject: [PATCH 092/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index df28ce21b..9e2089baf 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -31,6 +31,7 @@ For VOIP Plugin: $ sudo port install speex-devel $ sudo port install opencv + $ sudo port install ffmpeg Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) From bba3051a54c07d9fc9c202a2fad2c20c7f0a71de Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 2 Apr 2021 12:45:19 +0200 Subject: [PATCH 093/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 9e2089baf..fca911faf 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -66,7 +66,7 @@ For VOIP Plugin: For FeedReader Plugin: - $ brew install libxml2 + $ brew install libxslt Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) @@ -115,7 +115,7 @@ alternative via Terminal For FeedReader Plugin: - INCLUDEPATH += "/usr/local/Cellar/libxml2/2.9.10_2/include/libxml2" + INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2" For building RetroShare with plugins: @@ -147,3 +147,11 @@ You can now compile RetroShare into Qt Creator or with Terminal You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app* + +## Copy Plugins + + $ cp \ + ./plugins/FeedReader/lib/libFeedReader.dylib \ + ./plugins/VOIP/lib/libVOIP.dylib \ + ./plugins/RetroChess/lib/libRetroChess.dylib \ + ./retroshare-gui/src/RetroShare.app/Contents/Resources/ From 4fe3c955a36a5657cd5839e977a06d98d46a9d28 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 2 Apr 2021 23:00:10 +0200 Subject: [PATCH 094/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index fca911faf..13f3e4d73 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -12,6 +12,24 @@ Add to the PATH environment variable by editing your *~/.profile* file. Depends on which version of Qt you use. +## Get RetroShare + +In Qt Creator Projects -> New -> Import Project -> Git Clone -> Choose +Add Repository and Continoue + + Repository: https://github.com/RetroShare/RetroShare.git + +via Terminal: + + cd + git clone https://github.com/RetroShare/RetroShare.git retroshare + +via GitHub Desktop: [GitHub Desktop Download](https://central.github.com/deployments/desktop/desktop/latest/darwin) + +In GitHub Desktop -> Clone Repository -> URL + + Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone + ## ***Choose if you use MacPort or HomeBrew*** ### MacPort Installation @@ -139,8 +157,6 @@ For building RetroShare with plugins: You can now compile RetroShare into Qt Creator or with Terminal - cd - git clone https://github.com/RetroShare/RetroShare.git retroshare cd retroshare qmake; make From 7702ad69f30ac00589067a92eb126d61c3cfc554 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 3 Apr 2021 11:24:49 +0200 Subject: [PATCH 095/697] Update MacOS_X_InstallGuide.md --- build_scripts/OSX/MacOS_X_InstallGuide.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build_scripts/OSX/MacOS_X_InstallGuide.md b/build_scripts/OSX/MacOS_X_InstallGuide.md index 13f3e4d73..6dafd63c0 100644 --- a/build_scripts/OSX/MacOS_X_InstallGuide.md +++ b/build_scripts/OSX/MacOS_X_InstallGuide.md @@ -90,13 +90,15 @@ Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SD ## Last Settings -In QtCreator Option Git add this path: +In QtCreator Projects -> Manage Kits > Version Control > Git: + + select "Pull with rebase" + +In QtCreator Projects -> Build -> Build Settings -> Build Environment -> Add this path: /usr/local/bin -select "Pull" with "Rebase" - -In QtCreator Projects -> Build Settings -> Build Steps -> Add Additional arguments: +In QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additional arguments: "CONFIG+=rs_autologin" "CONFIG+=rs_use_native_dialogs" From b2f9ac5b71bf624ff319d238a99af0ebaed6b4e5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 4 Apr 2021 14:40:15 +0200 Subject: [PATCH 096/697] fixed VOIP compilation on ubuntu 20.04 --- plugins/VOIP/VOIP.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index 8186c48ec..66e20cdee 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -53,7 +53,7 @@ linux-* { PKGCONFIG += libavcodec libavutil PKGCONFIG += speex speexdsp - PKGCONFIG += opencv + PKGCONFIG += opencv4 } else { LIBS += -lspeex -lspeexdsp -lavcodec -lavutil } From b4be02c57b9245e37f3ab666f1d0243da6915be9 Mon Sep 17 00:00:00 2001 From: sehraf Date: Fri, 9 Apr 2021 16:15:40 +0200 Subject: [PATCH 097/697] rebase on 0.6.6 --- retroshare-gui/src/gui/settings/ServerPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 5755b4015..cdbe5c3e3 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -113,7 +113,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) ui.hiddenpage_outHeader->setText(tr("Tor has been automatically configured by Retroshare. You shouldn't need to change anything here.")) ; ui.hiddenpage_inHeader->setText(tr("Tor has been automatically configured by Retroshare. You shouldn't need to change anything here.")) ; - ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P_BOB); // warning: the order of operation here is very important. + ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P); // warning: the order of operation here is very important. } } else From fe53ee48423cc370f4d732a63c78b0f55b4487b6 Mon Sep 17 00:00:00 2001 From: howdy-partner <3364866+howdy-partner@users.noreply.github.com> Date: Sun, 25 Apr 2021 23:38:00 +0300 Subject: [PATCH 098/697] Fix libupnp autodetection for qmake --- retroshare.pri | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare.pri b/retroshare.pri index 2c2201ef3..8e59df32d 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -609,6 +609,8 @@ linux-* { isEmpty(RS_PLUGIN_DIR) : RS_PLUGIN_DIR = "$${PREFIX}/lib/retroshare/extensions6" QMAKE_LIBDIR *= "$$RS_LIB_DIR" + QMAKE_LIBDIR += "$${PREFIX}/lib64" + QMAKE_LIBDIR += "$${PREFIX}/lib/x86_64-linux-gnu" rs_autologin { # try libsecret first since it is not limited to gnome keyring and libgnome-keyring is deprecated From 8539dd503ae7342b9bb0347459d3936a10636cba Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 4 May 2021 19:49:47 +0200 Subject: [PATCH 099/697] fixed deadlock caused by wrong order in mutex lock --- libretroshare/src/gxs/rsgxsnettunnel.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnettunnel.cc b/libretroshare/src/gxs/rsgxsnettunnel.cc index 380491c5d..9b7a3089a 100644 --- a/libretroshare/src/gxs/rsgxsnettunnel.cc +++ b/libretroshare/src/gxs/rsgxsnettunnel.cc @@ -1028,12 +1028,18 @@ bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_d max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH ; std::list results ; + RsNetworkExchangeService *service = nullptr; - RS_STACK_MUTEX(mGxsNetTunnelMtx); + { + RS_STACK_MUTEX(mGxsNetTunnelMtx); - auto it = mSearchableServices.find(substring_sr->service) ; + auto it = mSearchableServices.find(substring_sr->service) ; - if(it != mSearchableServices.end() && it->second->search(substring_sr->substring_match,results)) + if(it != mSearchableServices.end()) + service = it->second; + } + + if(service != nullptr && service->search(substring_sr->substring_match,results)) { RsGxsNetTunnelTurtleSearchGroupSummaryItem search_result_item ; From 0de9c877b80d5fd05019497441959d3d5cec1efe Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 12 May 2021 09:40:42 +0200 Subject: [PATCH 100/697] switched video capture to QCamera and removed opencv dependency --- plugins/VOIP/VOIP.pro | 56 +------------ plugins/VOIP/VOIPPlugin.cpp | 3 - plugins/VOIP/gui/QVideoDevice.cpp | 125 ++++++++++++++++++++---------- plugins/VOIP/gui/QVideoDevice.h | 18 ++++- 4 files changed, 98 insertions(+), 104 deletions(-) diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index 66e20cdee..7dac8b2d9 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -53,7 +53,6 @@ linux-* { PKGCONFIG += libavcodec libavutil PKGCONFIG += speex speexdsp - PKGCONFIG += opencv4 } else { LIBS += -lspeex -lspeexdsp -lavcodec -lavutil } @@ -66,37 +65,10 @@ win32 { INCLUDEPATH += . $$INC_DIR USE_PRECOMPILED_LIBS = - for(lib, RS_LIB_DIR) { -#message(Scanning $$lib) - isEmpty(USE_PRECOMPILED_LIBS) { - exists($$lib/opencv/libopencv_core.a) { - message(Get pre-compiled opencv libraries here:) - message($$lib/opencv) - LIBS += -L"$$lib/opencv" - USE_PRECOMPILED_LIBS = 1 - } - exists($$lib/libopencv_core.dll.a) { - message(Get pre-compiled opencv libraries here:) - message($$lib) - LIBS += -L"$$lib" - USE_PRECOMPILED_LIBS = 1 - } - } - } - isEmpty(USE_PRECOMPILED_LIBS) { - message(Use system opencv libraries.) - } - LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs -llibwebp -llibtiff -llibpng -llibopenjp2 -lIlmImf + # Should we keep these after removing opencv?? LIBS += -lole32 -loleaut32 -luuid -lvfw32 - - # Check for msys2 - !isEmpty(PREFIX_MSYS2) { - message(Use msys2 opencv4.) - INCLUDEPATH += "$${PREFIX_MSYS2}/include/opencv4" - } else { - LIBS += -llibjpeg-turbo -lzlib - } + LIBS += -llibjpeg-turbo -lzlib } #################################### MacOSX ##################################### @@ -105,30 +77,6 @@ macx { DEPENDPATH += . $$INC_DIR INCLUDEPATH += . $$INC_DIR - - #OPENCV_VERSION = "249" - USE_PRECOMPILED_LIBS = - for(lib, LIB_DIR) { -#message(Scanning $$lib) - exists( $$lib/opencv/libopencv_core*.dylib) { - isEmpty(USE_PRECOMPILED_LIBS) { - message(Get pre-compiled opencv libraries here:) - message($$lib) - LIBS += -L"$$lib/opencv" - LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc - USE_PRECOMPILED_LIBS = 1 - } - } - exists( $$lib/libopencv_videoio*.dylib) { - message(videoio found in opencv libraries.) - message($$lib) - LIBS += -lopencv_videoio - } - } - isEmpty(USE_PRECOMPILED_LIBS) { - message(Use system opencv libraries.) - LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc - } } diff --git a/plugins/VOIP/VOIPPlugin.cpp b/plugins/VOIP/VOIPPlugin.cpp index e5b412858..2f6f0d2e1 100644 --- a/plugins/VOIP/VOIPPlugin.cpp +++ b/plugins/VOIP/VOIPPlugin.cpp @@ -38,7 +38,6 @@ #include "gui/SoundManager.h" #include "gui/chat/ChatWidget.h" -#include #include #define IMAGE_VOIP ":/images/talking_on.svg" @@ -188,8 +187,6 @@ std::string VOIPPlugin::getPluginName() const void VOIPPlugin::getLibraries(std::list &libraries) { - libraries.push_back(RsLibraryInfo("OpenCV", CV_VERSION)); - const char *speexVersion = NULL; if (speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &speexVersion) == 0 && speexVersion) { libraries.push_back(RsLibraryInfo("Speex", speexVersion)); diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index 1a3d084db..1e81841b8 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -18,12 +18,13 @@ * * *******************************************************************************/ -#include -#include -#include - #include #include +#include +#include +#include +#include +#include #include "QVideoDevice.h" #include "VideoProcessor.h" @@ -36,6 +37,16 @@ QVideoInputDevice::QVideoInputDevice(QWidget *parent) _echo_output_device = NULL ; } +QVideoInputDevice::~QVideoInputDevice() +{ + stop() ; + _video_processor = NULL ; + + delete _image_capture; + delete _capture_device; + delete _timer; +} + bool QVideoInputDevice::stopped() { return _timer == NULL ; @@ -45,7 +56,7 @@ void QVideoInputDevice::stop() { if(_timer != NULL) { - QObject::disconnect(_timer,SIGNAL(timeout()),this,SLOT(grabFrame())) ; + _capture_device->stop(); _timer->stop() ; delete _timer ; _timer = NULL ; @@ -53,10 +64,12 @@ void QVideoInputDevice::stop() if(_capture_device != NULL) { // the camera will be deinitialized automatically in VideoCapture destructor - _capture_device->release(); - delete _capture_device ; + delete _image_capture ; + delete _capture_device ; + _capture_device = NULL ; - } + _image_capture = NULL ; + } } void QVideoInputDevice::start() { @@ -65,45 +78,78 @@ void QVideoInputDevice::start() stop() ; // Initialise la capture - static const int cam_id = 0 ; - _capture_device = new cv::VideoCapture(cam_id); + QCameraInfo caminfo = QCameraInfo::defaultCamera(); - if(!_capture_device->isOpened()) - { - std::cerr << "Cannot initialise camera. Something's wrong." << std::endl; - return ; - } + if(caminfo.isNull()) + { + std::cerr << "No video camera available in this system!" << std::endl; + return ; + } + _capture_device = new QCamera(caminfo); - _timer = new QTimer ; - QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(grabFrame())) ; + if(_capture_device->error() != QCamera::NoError) + { + emit cameraCaptureInfo(CANNOT_INITIALIZE_CAMERA,_capture_device->error()); + std::cerr << "Cannot initialise camera. Something's wrong." << std::endl; + return; + } + _capture_device->setCaptureMode(QCamera::CaptureStillImage); - _timer->start(50) ; // 10 images per second. + if(_capture_device->error() == QCamera::NoError) + emit cameraCaptureInfo(CAMERA_IS_READY,QCamera::NoError); + + _image_capture = new QCameraImageCapture(_capture_device); + + if(!_image_capture->isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer)) + { + emit cameraCaptureInfo(CAMERA_IS_READY,QCamera::NoError); + + delete _capture_device; + delete _image_capture; + return; + } + + _image_capture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer); + + QObject::connect(_image_capture,SIGNAL(imageAvailable(int,QVideoFrame)),this,SLOT(grabFrame(int,QVideoFrame))); + QObject::connect(this,SIGNAL(cameraCaptureInfo(CameraStatus,QCamera::Error)),this,SLOT(errorHandling(CameraStatus,QCamera::Error))); + + _timer = new QTimer ; + QObject::connect(_timer,SIGNAL(timeout()),_image_capture,SLOT(capture())) ; + + _timer->start(50) ; // 10 images per second. + + _capture_device->start(); } -void QVideoInputDevice::grabFrame() +void QVideoInputDevice::errorHandling(CameraStatus status,QCamera::Error error) { - if(!_timer) - return ; + std::cerr << "Received msg from camera capture: status=" << (int)status << " error=" << (int)error << std::endl; - cv::Mat frame; - if(!_capture_device->read(frame)) + if(status == CANNOT_INITIALIZE_CAMERA) { - std::cerr << "(EE) Cannot capture image from camera. Something's wrong." << std::endl; - return ; + std::cerr << "Cannot initialize camera. Make sure to install package libqt5multimedia5-plugins, as this is a common cause for camera not being found." << std::endl; + } +} + +void QVideoInputDevice::grabFrame(int id,QVideoFrame frame) +{ + if(frame.size().isEmpty()) + { + std::cerr << "Empty frame!" ; + return; } - // get the image data + frame.map(QAbstractVideoBuffer::ReadOnly); + QByteArray data((const char *)frame.bits(), frame.mappedBytes()); + QBuffer buffer; + buffer.setData(data); + buffer.open(QIODevice::ReadOnly); + QImageReader reader(&buffer, "JPG"); + reader.setScaledSize(QSize(640,480)); + QImage image(reader.read()); - if(frame.channels() != 3) - { - std::cerr << "(EE) expected 3 channels. Got " << frame.channels() << std::endl; - return ; - } - - // convert to RGB and copy to new buffer, because cvQueryFrame tells us to not modify the buffer - cv::Mat img_rgb; - cv::cvtColor(frame, img_rgb, CV_BGR2RGB); - QImage image = QImage(img_rgb.data,img_rgb.cols,img_rgb.rows,QImage::Format_RGB888); + std::cerr << "Frame " << id << ". Pixel format: " << frame.pixelFormat() << ". Size: " << image.size().width() << " x " << image.size().height() << std::endl; // if(frame.pixelFormat() != QVideoFrame::Format_Jpeg) if(_video_processor != NULL) { @@ -131,13 +177,6 @@ uint32_t QVideoInputDevice::currentBandwidth() const return _video_processor->currentBandwidthOut() ; } -QVideoInputDevice::~QVideoInputDevice() -{ - stop() ; - _video_processor = NULL ; -} - - QVideoOutputDevice::QVideoOutputDevice(QWidget *parent) : QLabel(parent) { diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index e0c21778e..40c606f37 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -21,13 +21,13 @@ #pragma once #include +#include #include "interface/rsVOIP.h" -#include "opencv2/opencv.hpp" - #include "gui/VideoProcessor.h" class VideoEncoder ; +class QCameraImageCapture; // Responsible from displaying the video. The source of the video is // a VideoDecoder object, which uses a codec. @@ -74,16 +74,26 @@ class QVideoInputDevice: public QObject void start() ; void stop() ; bool stopped(); + + enum CameraStatus { + CAMERA_IS_READY = 0x00, + CANNOT_INITIALIZE_CAMERA = 0x01, + CAMERA_CANNOT_GRAB_FRAMES = 0x02 + }; + protected slots: - void grabFrame() ; + void grabFrame(int id, QVideoFrame f) ; + void errorHandling(CameraStatus status,QCamera::Error error); signals: void networkPacketReady() ; + void cameraCaptureInfo(CameraStatus status,QCamera::Error qt_cam_err_code); private: VideoProcessor *_video_processor ; QTimer *_timer ; - cv::VideoCapture *_capture_device ; + QCamera *_capture_device; + QCameraImageCapture *_image_capture; QVideoOutputDevice *_echo_output_device ; From c4fbd3a4f51c4364ada787235edb788d65266ffc Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 12 May 2021 21:44:25 +0200 Subject: [PATCH 101/697] renamed AudioInputConfig into VOIPConfigPanel --- plugins/VOIP/VOIP.pro | 7 +++-- plugins/VOIP/VOIPPlugin.cpp | 4 +-- plugins/VOIP/gui/AudioStats.cpp | 2 +- ...dioInputConfig.cpp => VOIPConfigPanel.cpp} | 30 +++++++++---------- .../{AudioInputConfig.h => VOIPConfigPanel.h} | 6 ++-- ...AudioInputConfig.ui => VOIPConfigPanel.ui} | 0 6 files changed, 25 insertions(+), 24 deletions(-) rename plugins/VOIP/gui/{AudioInputConfig.cpp => VOIPConfigPanel.cpp} (93%) rename plugins/VOIP/gui/{AudioInputConfig.h => VOIPConfigPanel.h} (96%) rename plugins/VOIP/gui/{AudioInputConfig.ui => VOIPConfigPanel.ui} (100%) diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index 7dac8b2d9..3f675c1a1 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -86,9 +86,9 @@ QMAKE_CXXFLAGS += -D__STDC_CONSTANT_MACROS QMAKE_CXXFLAGS *= -Wall SOURCES = VOIPPlugin.cpp \ + gui/VOIPConfigPanel.cpp \ services/p3VOIP.cc \ services/rsVOIPItems.cc \ - gui/AudioInputConfig.cpp \ gui/AudioStats.cpp \ gui/AudioWizard.cpp \ gui/SpeexProcessor.cpp \ @@ -102,9 +102,9 @@ SOURCES = VOIPPlugin.cpp \ gui/VOIPToasterNotify.cpp HEADERS = VOIPPlugin.h \ + gui/VOIPConfigPanel.h \ services/p3VOIP.h \ services/rsVOIPItems.h \ - gui/AudioInputConfig.h \ gui/AudioStats.h \ gui/AudioWizard.h \ gui/SpeexProcessor.h \ @@ -118,9 +118,10 @@ HEADERS = VOIPPlugin.h \ gui/VOIPToasterNotify.h \ interface/rsVOIP.h -FORMS = gui/AudioInputConfig.ui \ +FORMS = \ gui/AudioStats.ui \ gui/AudioWizard.ui \ + gui/VOIPConfigPanel.ui \ gui/VOIPToasterItem.ui TARGET = VOIP diff --git a/plugins/VOIP/VOIPPlugin.cpp b/plugins/VOIP/VOIPPlugin.cpp index 2f6f0d2e1..75719e156 100644 --- a/plugins/VOIP/VOIPPlugin.cpp +++ b/plugins/VOIP/VOIPPlugin.cpp @@ -31,7 +31,7 @@ #include "VOIPPlugin.h" #include "interface/rsVOIP.h" -#include "gui/AudioInputConfig.h" +#include "gui/VOIPConfigPanel.h" #include "gui/VOIPChatWidgetHolder.h" #include "gui/VOIPGUIHandler.h" #include "gui/VOIPNotify.h" @@ -112,7 +112,7 @@ ConfigPage *VOIPPlugin::qt_config_page() const // The config pages are deleted when config is closed, so it's important not to static the // created object. // - return new AudioInputConfig() ; + return new VOIPConfigPanel() ; } QDialog *VOIPPlugin::qt_about_page() const diff --git a/plugins/VOIP/gui/AudioStats.cpp b/plugins/VOIP/gui/AudioStats.cpp index 536cf0a1d..96ea93b83 100644 --- a/plugins/VOIP/gui/AudioStats.cpp +++ b/plugins/VOIP/gui/AudioStats.cpp @@ -25,7 +25,7 @@ #include #include "AudioStats.h" -#include "AudioInputConfig.h" +#include "VOIPConfigPanel.h" //#include "Global.h" //#include "smallft.h" diff --git a/plugins/VOIP/gui/AudioInputConfig.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp similarity index 93% rename from plugins/VOIP/gui/AudioInputConfig.cpp rename to plugins/VOIP/gui/VOIPConfigPanel.cpp index b063d5e48..d776d8abd 100644 --- a/plugins/VOIP/gui/AudioInputConfig.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -80,7 +80,7 @@ voipGraph::voipGraph(QWidget *parent) } /** Constructor */ -AudioInputConfig::AudioInputConfig(QWidget * parent, Qt::WindowFlags flags) +VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) { std::cerr << "Creating audioInputConfig object" << std::endl; @@ -118,13 +118,13 @@ AudioInputConfig::AudioInputConfig(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ; } -void AudioInputConfig::updateAvailableBW(double r) +void VOIPConfigPanel::updateAvailableBW(double r) { std::cerr << "Setting max bandwidth to " << r << " KB/s" << std::endl; videoProcessor->setMaximumBandwidth((uint32_t)(r*1024)) ; } -void AudioInputConfig::togglePreview(bool b) +void VOIPConfigPanel::togglePreview(bool b) { if(b) { @@ -138,7 +138,7 @@ void AudioInputConfig::togglePreview(bool b) } } -AudioInputConfig::~AudioInputConfig() +VOIPConfigPanel::~VOIPConfigPanel() { disconnect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); @@ -166,7 +166,7 @@ AudioInputConfig::~AudioInputConfig() } /** Loads the settings for this page */ -void AudioInputConfig::load() +void VOIPConfigPanel::load() { //connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); //connect( ui.allowTunnelConnectionCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) ); @@ -199,7 +199,7 @@ void AudioInputConfig::load() } -void AudioInputConfig::loadSettings() { +void VOIPConfigPanel::loadSettings() { /*QList keys; if (AudioInputRegistrar::qmNew) @@ -258,7 +258,7 @@ void AudioInputConfig::loadSettings() { videoInput->start() ; } -bool AudioInputConfig::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime +bool VOIPConfigPanel::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime //s.iQuality = qsQuality->value(); rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); @@ -272,14 +272,14 @@ bool AudioInputConfig::save(QString &/*errmsg*/) {//mainly useless beacause savi return true; } -void AudioInputConfig::on_qsTransmitHold_valueChanged(int v) { +void VOIPConfigPanel::on_qsTransmitHold_valueChanged(int v) { float val = static_cast(v * FRAME_SIZE); val = val / SAMPLING_RATE; ui.qlTransmitHold->setText(tr("%1 s").arg(val, 0, 'f', 2)); rsVOIP->setVoipVoiceHold(v); } -void AudioInputConfig::on_qsNoise_valueChanged(int v) { +void VOIPConfigPanel::on_qsNoise_valueChanged(int v) { QPalette pal; if (v < 15) { @@ -292,19 +292,19 @@ void AudioInputConfig::on_qsNoise_valueChanged(int v) { rsVOIP->setVoipiNoiseSuppress(- ui.qsNoise->value()); } -void AudioInputConfig::on_qsAmp_valueChanged(int v) { +void VOIPConfigPanel::on_qsAmp_valueChanged(int v) { v = 20000 - v; float d = 20000.0f/static_cast(v); ui.qlAmp->setText(QString::fromLatin1("%1").arg(d, 0, 'f', 2)); rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); } -void AudioInputConfig::on_qcbEchoCancel_clicked() { +void VOIPConfigPanel::on_qcbEchoCancel_clicked() { rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); } -void AudioInputConfig::on_qcbTransmit_currentIndexChanged(int v) { +void VOIPConfigPanel::on_qcbTransmit_currentIndexChanged(int v) { switch (v) { case 0: ui.qswTransmit->setCurrentWidget(ui.qwContinuous); @@ -321,7 +321,7 @@ void AudioInputConfig::on_qcbTransmit_currentIndexChanged(int v) { } -void AudioInputConfig::on_Tick_timeout() +void VOIPConfigPanel::on_Tick_timeout() { if (!inputAudioProcessor) { @@ -356,13 +356,13 @@ void AudioInputConfig::on_Tick_timeout() } } -void AudioInputConfig::emptyBuffer() { +void VOIPConfigPanel::emptyBuffer() { while(inputAudioProcessor->hasPendingPackets()) { inputAudioProcessor->getNetworkPacket(); //that will purge the buffer } } -void AudioInputConfig::on_qpbAudioWizard_clicked() { +void VOIPConfigPanel::on_qpbAudioWizard_clicked() { AudioWizard aw(this); aw.exec(); loadSettings(); diff --git a/plugins/VOIP/gui/AudioInputConfig.h b/plugins/VOIP/gui/VOIPConfigPanel.h similarity index 96% rename from plugins/VOIP/gui/AudioInputConfig.h rename to plugins/VOIP/gui/VOIPConfigPanel.h index 3dd2cecae..bcee0a4d6 100644 --- a/plugins/VOIP/gui/AudioInputConfig.h +++ b/plugins/VOIP/gui/VOIPConfigPanel.h @@ -48,7 +48,7 @@ private: #include "ui_AudioInputConfig.h" -class AudioInputConfig : public ConfigPage +class VOIPConfigPanel : public ConfigPage { Q_OBJECT @@ -72,9 +72,9 @@ class AudioInputConfig : public ConfigPage public: /** Default Constructor */ - AudioInputConfig(QWidget * parent = 0, Qt::WindowFlags flags = 0); + VOIPConfigPanel(QWidget * parent = 0, Qt::WindowFlags flags = 0); /** Default Destructor */ - ~AudioInputConfig(); + ~VOIPConfigPanel(); /** Saves the changes on this page */ virtual bool save(QString &errmsg); diff --git a/plugins/VOIP/gui/AudioInputConfig.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui similarity index 100% rename from plugins/VOIP/gui/AudioInputConfig.ui rename to plugins/VOIP/gui/VOIPConfigPanel.ui From d7ecd775ebd8f9bda953bc1198825a5a9d0087d6 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 12 May 2021 23:05:15 +0200 Subject: [PATCH 102/697] made camera/audio only active when config panel is shown --- plugins/VOIP/gui/VOIPConfigPanel.cpp | 246 +++++++++++++-------------- plugins/VOIP/gui/VOIPConfigPanel.h | 15 +- plugins/VOIP/gui/VOIPConfigPanel.ui | 4 +- 3 files changed, 132 insertions(+), 133 deletions(-) diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index d776d8abd..b5ae020d0 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -22,7 +22,7 @@ #pragma once #include "AudioStats.h" -#include "AudioInputConfig.h" +#include "VOIPConfigPanel.h" #include "audiodevicehelper.h" #include "AudioWizard.h" #include "gui/VideoProcessor.h" @@ -95,16 +95,47 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) abSpeech = NULL; qtTick = NULL; + ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); + ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD); + ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk); + + abSpeech = new AudioBar(); + abSpeech->qcBelow = Qt::red; + abSpeech->qcInside = Qt::yellow; + abSpeech->qcAbove = Qt::green; + //abSpeech->setGeometry(9,20,50,10); + ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0); + + connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); + connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); + connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); + connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) ); +} + +void VOIPConfigPanel::showEvent(QShowEvent *) +{ + std::cerr << "Creating the audio pipeline" << std::endl; + + inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); + inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); + + inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); + inputAudioDevice->start(inputAudioProcessor); + + connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer())); + + std::cerr << "Creating the video pipeline" << std::endl; + // Create the video pipeline. // + videoInput = new QVideoInputDevice(this) ; - videoInput->setEchoVideoTarget(ui.videoDisplay) ; videoProcessor = new VideoProcessor() ; videoProcessor->setDisplayTarget(NULL) ; videoProcessor->setMaximumBandwidth(ui.availableBW_SB->value()) ; - + videoInput->setVideoProcessor(videoProcessor) ; graph_source = new voipGraphSource ; @@ -114,8 +145,34 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) graph_source->setCollectionTimeLimit(1000*300) ; graph_source->start() ; + if(ui.showEncoded_CB->isChecked()) + { + videoInput->setEchoVideoTarget(nullptr) ; + videoProcessor->setDisplayTarget(ui.videoDisplay) ; + } + else + { + videoInput->setEchoVideoTarget(ui.videoDisplay) ; + videoProcessor->setDisplayTarget(nullptr); + } + QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ; QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ; + + loadSettings(); + + qtTick = new RsProtectedTimer(this); + connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); + qtTick->start(20); + + videoInput->start(); +} + +void VOIPConfigPanel::hideEvent(QHideEvent *) +{ + std::cerr << "Deleting the video pipeline" << std::endl; + + clearPipeline(); } void VOIPConfigPanel::updateAvailableBW(double r) @@ -140,136 +197,86 @@ void VOIPConfigPanel::togglePreview(bool b) VOIPConfigPanel::~VOIPConfigPanel() { - disconnect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); - - graph_source->stop() ; - graph_source->setVideoInput(NULL) ; - + clearPipeline(); +} + +void VOIPConfigPanel::clearPipeline() +{ + delete qtTick; + + graph_source->stop() ; + graph_source->setVideoInput(NULL) ; + graph_source=nullptr; // is deleted by setSource below. This is a bad design. + + ui.voipBwGraph->setSource(nullptr); + std::cerr << "Deleting audioInputConfig object" << std::endl; if(videoInput != NULL) { videoInput->stop() ; delete videoInput ; + + videoInput = nullptr; } + delete videoProcessor; + videoProcessor = nullptr; if (inputAudioDevice) { inputAudioDevice->stop(); delete inputAudioDevice ; - inputAudioDevice = NULL ; + inputAudioDevice = nullptr ; } if(inputAudioProcessor) { delete inputAudioProcessor ; - inputAudioProcessor = NULL ; + inputAudioProcessor = nullptr ; } } -/** Loads the settings for this page */ void VOIPConfigPanel::load() { - //connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); - //connect( ui.allowTunnelConnectionCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) ); - - qtTick = new RsProtectedTimer(this); - connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); - qtTick->start(20); - /*if (AudioInputRegistrar::qmNew) { - QList keys = AudioInputRegistrar::qmNew->keys(); - foreach(QString key, keys) { - qcbSystem->addItem(key); - } - } - qcbSystem->setEnabled(qcbSystem->count() > 1);*/ - - ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); - ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD); - ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk); - - abSpeech = new AudioBar(); - abSpeech->qcBelow = Qt::red; - abSpeech->qcInside = Qt::yellow; - abSpeech->qcAbove = Qt::green; - //abSpeech->setGeometry(9,20,50,10); - ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0); - - //on_qcbPushClick_clicked(g.s.bPushClick); - //ui.on_Tick_timeout(); - loadSettings(); } +/** Loads the settings for this page */ -void VOIPConfigPanel::loadSettings() { - /*QList keys; +void VOIPConfigPanel::loadSettings() +{ + ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit()); + on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit()); + ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold()); + on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold()); + ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin()); + ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax()); + ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel()); - if (AudioInputRegistrar::qmNew) - keys=AudioInputRegistrar::qmNew->keys(); - else - keys.clear(); - i=keys.indexOf(AudioInputRegistrar::current); - if (i >= 0) - loadComboBox(qcbSystem, i); + if (rsVOIP->getVoipiNoiseSuppress() != 0) + ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress()); + else + ui.qsNoise->setValue(14); - loadCheckBox(qcbExclusive, r.bExclusiveInput);*/ + on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress()); - //qlePushClickPathOn->setText(r.qsPushClickOn); - //qlePushClickPathOff->setText(r.qsPushClickOff); + ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness()); + on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness()); - /*loadComboBox(qcbTransmit, r.atTransmit); - loadSlider(qsTransmitHold, r.iVoiceHold); - loadSlider(qsTransmitMin, iroundf(r.fVADmin * 32767.0f + 0.5f)); - loadSlider(qsTransmitMax, iroundf(r.fVADmax * 32767.0f + 0.5f)); - loadSlider(qsFrames, (r.iFramesPerPacket == 1) ? 1 : (r.iFramesPerPacket/2 + 1)); - loadSlider(qsDoublePush, iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f));*/ - ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit()); - on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit()); - ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold()); - on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold()); - ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin()); - ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax()); - ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel()); - //ui.qsDoublePush->setValue(iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f)); - - //loadCheckBox(qcbPushClick, r.bPushClick); - //loadSlider(qsQuality, r.iQuality); - if (rsVOIP->getVoipiNoiseSuppress() != 0) - ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress()); - else - ui.qsNoise->setValue(14); - - on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress()); - - ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness()); - on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness()); - //loadSlider(qsIdle, r.iIdleTime); - - /*int echo = 0; - if (r.bEcho) - echo = r.bEchoMulti ? 2 : 1; - - loadComboBox(qcbEcho, echo);*/ - connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); - connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); - connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); - connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) ); - loaded = true; - - std::cerr << "AudioInputConfig:: starting video." << std::endl; - videoInput->start() ; + loaded = true; } -bool VOIPConfigPanel::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime - //s.iQuality = qsQuality->value(); - rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); - rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); - rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value()); - rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); - /*s.uiDoublePush = qsDoublePush->value() * 1000;*/ - rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); - rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); +bool VOIPConfigPanel::save(QString &/*errmsg*/) +{ + //mainly useless beacause saving occurs in realtime + //s.iQuality = qsQuality->value(); + rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); + rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); + rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value()); + rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); + /*s.uiDoublePush = qsDoublePush->value() * 1000;*/ + rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); + rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); - return true; + return true; } void VOIPConfigPanel::on_qsTransmitHold_valueChanged(int v) { @@ -323,32 +330,23 @@ void VOIPConfigPanel::on_qcbTransmit_currentIndexChanged(int v) { void VOIPConfigPanel::on_Tick_timeout() { - if (!inputAudioProcessor) - { - inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); - inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); + // update the sound capture bar - if (!inputAudioDevice) { - inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); - } - inputAudioDevice->start(inputAudioProcessor); - connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer())); - } + abSpeech->iBelow = ui.qsTransmitMin->value(); + abSpeech->iAbove = ui.qsTransmitMax->value(); - abSpeech->iBelow = ui.qsTransmitMin->value(); - abSpeech->iAbove = ui.qsTransmitMax->value(); - if (loaded) { - rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); - } + if (loaded) { + rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); + } - abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); + abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); + abSpeech->update(); + + // also transmit encoded video - abSpeech->update(); - - // also transmit encoded video RsVOIPDataChunk chunk ; - + while((!videoInput->stopped()) && videoInput->getNextEncodedPacket(chunk)) { videoProcessor->receiveEncodedData(chunk) ; diff --git a/plugins/VOIP/gui/VOIPConfigPanel.h b/plugins/VOIP/gui/VOIPConfigPanel.h index bcee0a4d6..0df5d882f 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.h +++ b/plugins/VOIP/gui/VOIPConfigPanel.h @@ -67,9 +67,8 @@ class VOIPConfigPanel : public ConfigPage protected: QTimer *qtTick; - /*void hideEvent(QHideEvent *event); - void showEvent(QShowEvent *event);*/ + void clearPipeline(); public: /** Default Constructor */ VOIPConfigPanel(QWidget * parent = 0, Qt::WindowFlags flags = 0); @@ -77,14 +76,16 @@ class VOIPConfigPanel : public ConfigPage ~VOIPConfigPanel(); /** Saves the changes on this page */ - virtual bool save(QString &errmsg); + virtual bool save(QString &errmsg)override ; /** Loads the settings for this page */ - virtual void load(); + virtual void load()override ; - virtual QPixmap iconPixmap() const { return QPixmap(":/images/talking_on.svg") ; } - virtual QString pageName() const { return tr("VOIP") ; } - virtual QString helpText() const { return ""; } + virtual QPixmap iconPixmap() const override { return QPixmap(":/images/talking_on.svg") ; } + virtual QString pageName() const override { return tr("VOIP") ; } + virtual QString helpText() const override { return ""; } + virtual void showEvent(QShowEvent *) override; + virtual void hideEvent(QHideEvent *event) override; private slots: void updateAvailableBW(double r); void loadSettings(); diff --git a/plugins/VOIP/gui/VOIPConfigPanel.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui index 62e8c98a6..ab1849358 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.ui +++ b/plugins/VOIP/gui/VOIPConfigPanel.ui @@ -239,7 +239,7 @@ - Audio Processing + Audio @@ -353,7 +353,7 @@ - Video Processing + Video From d3f75234a7077d8898fbe9f07d370e1367f1cbb1 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 12 May 2021 23:24:57 +0200 Subject: [PATCH 103/697] moved abSpeech audio bar to main panel --- plugins/VOIP/gui/AudioWizard.ui | 11 +++- plugins/VOIP/gui/VOIPConfigPanel.cpp | 19 +++--- plugins/VOIP/gui/VOIPConfigPanel.h | 5 +- plugins/VOIP/gui/VOIPConfigPanel.ui | 91 +++++++++++++++------------- 4 files changed, 69 insertions(+), 57 deletions(-) diff --git a/plugins/VOIP/gui/AudioWizard.ui b/plugins/VOIP/gui/AudioWizard.ui index dfe9578f6..22d848fc4 100644 --- a/plugins/VOIP/gui/AudioWizard.ui +++ b/plugins/VOIP/gui/AudioWizard.ui @@ -202,7 +202,16 @@ - + + 0 + + + 0 + + + 0 + + 0 diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index b5ae020d0..3fbd9e895 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -19,7 +19,6 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#pragma once #include "AudioStats.h" #include "VOIPConfigPanel.h" @@ -92,19 +91,15 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) inputAudioProcessor = NULL; inputAudioDevice = NULL; - abSpeech = NULL; qtTick = NULL; ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD); ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk); - abSpeech = new AudioBar(); - abSpeech->qcBelow = Qt::red; - abSpeech->qcInside = Qt::yellow; - abSpeech->qcAbove = Qt::green; - //abSpeech->setGeometry(9,20,50,10); - ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0); + ui.abSpeech->qcBelow = Qt::red; + ui.abSpeech->qcInside = Qt::yellow; + ui.abSpeech->qcAbove = Qt::green; connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); @@ -332,16 +327,16 @@ void VOIPConfigPanel::on_Tick_timeout() { // update the sound capture bar - abSpeech->iBelow = ui.qsTransmitMin->value(); - abSpeech->iAbove = ui.qsTransmitMax->value(); + ui.abSpeech->iBelow = ui.qsTransmitMin->value(); + ui.abSpeech->iAbove = ui.qsTransmitMax->value(); if (loaded) { rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); } - abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); - abSpeech->update(); + ui.abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); + ui.abSpeech->update(); // also transmit encoded video diff --git a/plugins/VOIP/gui/VOIPConfigPanel.h b/plugins/VOIP/gui/VOIPConfigPanel.h index 0df5d882f..4985cb5b7 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.h +++ b/plugins/VOIP/gui/VOIPConfigPanel.h @@ -19,7 +19,6 @@ * * *******************************************************************************/ #pragma once -#pragma once #include #include @@ -46,9 +45,9 @@ private: voipGraphSource *_src ; }; -#include "ui_AudioInputConfig.h" +#include "ui_VOIPConfigPanel.h" -class VOIPConfigPanel : public ConfigPage +class VOIPConfigPanel : public ConfigPage { Q_OBJECT diff --git a/plugins/VOIP/gui/VOIPConfigPanel.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui index ab1849358..3687dbb89 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.ui +++ b/plugins/VOIP/gui/VOIPConfigPanel.ui @@ -53,7 +53,7 @@ - 2 + 1 @@ -242,13 +242,39 @@ Audio - - + + + + + 30 + 0 + + - Noise Suppression + + + + + + + + Amplification - qsNoise + qsAmp + + + + + + + + 30 + 0 + + + + @@ -277,26 +303,23 @@ - - - - - 30 - 0 - - + + - + Echo Cancellation Processing + + + false - - + + - Amplification + Noise Suppression - qsAmp + qsNoise @@ -322,28 +345,8 @@ - - - - - 30 - 0 - - - - - - - - - - - Echo Cancellation Processing - - - false - - + + @@ -459,7 +462,13 @@ voipGraph QFrame -
gui/AudioInputConfig.h
+
gui/VOIPConfigPanel.h
+ 1 +
+ + AudioBar + QWidget +
gui/AudioStats.h
1
From 7b5be347bf43e9d88613ab6e7dcf4d7840894e38 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 15 May 2021 21:37:11 +0200 Subject: [PATCH 104/697] refactored the UI of VOIP config panel and added list of available devices (not used yet) --- plugins/VOIP/gui/QVideoDevice.cpp | 26 +- plugins/VOIP/gui/QVideoDevice.h | 8 +- plugins/VOIP/gui/VOIPConfigPanel.cpp | 7 + plugins/VOIP/gui/VOIPConfigPanel.ui | 496 ++++++++++++++------------- 4 files changed, 303 insertions(+), 234 deletions(-) diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index 1e81841b8..9052c5306 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -71,14 +71,34 @@ void QVideoInputDevice::stop() _image_capture = NULL ; } } -void QVideoInputDevice::start() +void QVideoInputDevice::getAvailableDevices(QList& device_desc) +{ + device_desc.clear(); + + QList dev_list = QCameraInfo::availableCameras(); + + for(auto& cam:dev_list) + device_desc.push_back(cam.deviceName()); +} + +void QVideoInputDevice::start(const QString& description) { // make sure everything is re-initialised // stop() ; - // Initialise la capture - QCameraInfo caminfo = QCameraInfo::defaultCamera(); + QCameraInfo caminfo ; + + if(description.isNull()) + caminfo = QCameraInfo::defaultCamera(); + else + { + auto cam_list = QCameraInfo::availableCameras(); + + for(auto& s:cam_list) + if(s.deviceName() == description) + caminfo = s; + } if(caminfo.isNull()) { diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index 40c606f37..f23fd8aa5 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -49,7 +49,7 @@ class QVideoInputDevice: public QObject Q_OBJECT public: - QVideoInputDevice(QWidget *parent = 0) ; + QVideoInputDevice(QWidget *parent = 0) ; ~QVideoInputDevice() ; // Captured images are sent to this encoder. Can be NULL. @@ -71,7 +71,7 @@ class QVideoInputDevice: public QObject // control - void start() ; + void start(const QString &description = QString()) ; void stop() ; bool stopped(); @@ -81,6 +81,10 @@ class QVideoInputDevice: public QObject CAMERA_CANNOT_GRAB_FRAMES = 0x02 }; + // Gets the list of available devices. The id string for each device can be used when creating a QVideoDevice + + static void getAvailableDevices(QList& device_desc); + protected slots: void grabFrame(int id, QVideoFrame f) ; void errorHandling(CameraStatus status,QCamera::Error error); diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index 3fbd9e895..5b93db0cd 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -101,10 +101,17 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) ui.abSpeech->qcInside = Qt::yellow; ui.abSpeech->qcAbove = Qt::green; + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + ui.inputDevice_CB->clear(); + for(auto& s:input_devices) + ui.inputDevice_CB->addItem(s,QVariant(s)); + connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) ); + connect( ui.inputDevice_CB, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_changedCurrentInputDevice(int) ) ); } void VOIPConfigPanel::showEvent(QShowEvent *) diff --git a/plugins/VOIP/gui/VOIPConfigPanel.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui index 3687dbb89..178436808 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.ui +++ b/plugins/VOIP/gui/VOIPConfigPanel.ui @@ -10,48 +10,287 @@ 832 - + - - - Audio Wizard + + + Video + + + + + + + + 170 + 128 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + Input device: + + + + + + + + + + + 0 + 0 + + + + Available bandwidth: + + + + + + + <html><head/><body><p>Use this field to simulate the maximum bandwidth available so as to preview what the encoded video will look like with the corresponding compression rate.</p></body></html> + + + KB/s + + + 1 + + + 2.000000000000000 + + + 200.000000000000000 + + + 30.000000000000000 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Display encoded (and then decoded) frame, to check the codec's quality. If not selected, the image above only shows the frame that is grabbed from your camera.</p></body></html> + + + preview + + + + + + - - - - 0 - 0 - - + - Transmission + Audio - - - - - &Transmit + + + + + + 30 + 0 + - - qcbTransmit + + - - + + + + true + - When to transmit your speech + Noise suppression - <b>This sets when speech should be transmitted.</b><br /><i>Continuous</i> - All the time<br /><i>Voice Activity</i> - When you are speaking clearly.<br /><i>Push To Talk</i> - When you hold down the hotkey set under <i>Shortcuts</i>. + <b>This sets the amount of noise suppression to apply.</b><br />The higher this value, the more aggressively stationary noise will be suppressed. + + + 14 + + + 60 + + + 5 + + + Qt::Horizontal - + + + + Noise Suppression + + + qsNoise + + + + + + + + 30 + 0 + + + + + + + + + + + Maximum amplification of input sound + + + <b>Maximum amplification of input.</b><br />RetroShare normalizes the input volume before compressing, and this sets how much it's allowed to amplify.<br />The actual level is continually updated based on your current speech pattern, but it will never go above the level specified here.<br />If the <i>Microphone loudness</i> level of the audio statistics hover around 100%, you probably want to set this to 2.0 or so, but if, like most people, you are unable to reach 100%, set this to something much higher.<br />Ideally, set it so <i>Microphone Loudness * Amplification Factor >= 100</i>, even when you're speaking really soft.<br /><br />Note that there is no harm in setting this to maximum, but RetroShare will start picking up other conversations if you leave it to auto-tune to that level. + + + 19500 + + + 500 + + + 2000 + + + Qt::Horizontal + + + + + + + Amplification + + + qsAmp + + + + + + + + + + 0 + 0 + + + + Echo Cancellation Processing + + + false + + + + + + + + + + 0 + 0 + + + + &Transmit: + + + qcbTransmit + + + + + + + When to transmit your speech + + + <b>This sets when speech should be transmitted.</b><br /><i>Continuous</i> - All the time<br /><i>Voice Activity</i> - When you are speaking clearly.<br /><i>Push To Talk</i> - When you hold down the hotkey set under <i>Shortcuts</i>. + + + + + + + + + + 0 + 0 + + + + Audio Wizard + + + + + + + + + 0 + 0 + + 1 @@ -231,221 +470,21 @@ - - - - - - - - - Audio - - - - - - - 30 - 0 - - - - - - - - - - - Amplification - - - qsAmp - - - - - - - - 30 - 0 - - - - - - - - - - - true - - - Noise suppression - - - <b>This sets the amount of noise suppression to apply.</b><br />The higher this value, the more aggressively stationary noise will be suppressed. - - - 14 - - - 60 - - - 5 - - - Qt::Horizontal - - - - - - - Echo Cancellation Processing - - - false - - - - - - - Noise Suppression - - - qsNoise - - - - - - - Maximum amplification of input sound - - - <b>Maximum amplification of input.</b><br />RetroShare normalizes the input volume before compressing, and this sets how much it's allowed to amplify.<br />The actual level is continually updated based on your current speech pattern, but it will never go above the level specified here.<br />If the <i>Microphone loudness</i> level of the audio statistics hover around 100%, you probably want to set this to 2.0 or so, but if, like most people, you are unable to reach 100%, set this to something much higher.<br />Ideally, set it so <i>Microphone Loudness * Amplification Factor >= 100</i>, even when you're speaking really soft.<br /><br />Note that there is no harm in setting this to maximum, but RetroShare will start picking up other conversations if you leave it to auto-tune to that level. - - - 19500 - - - 500 - - - 2000 - - - Qt::Horizontal - - - - - - - - - - - - - - - Video - - - - - - 170 - 128 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - + - - - - - Available bandwidth: - - - - - - - <html><head/><body><p>Use this field to simulate the maximum bandwidth available so as to preview what the encoded video will look like with the corresponding compression rate.</p></body></html> - - - KB/s - - - 1 - - - 2.000000000000000 - - - 200.000000000000000 - - - 30.000000000000000 - - - - - - - - - <html><head/><body><p>Display encoded (and then decoded) frame, to check the codec's quality. If not selected, the image above only shows the frame that is grabbed from your camera.</p></body></html> - - - preview - - - - - + Qt::Vertical - 1 - 151 + 20 + 40 @@ -473,7 +512,6 @@ - qcbTransmit qsDoublePush qsTransmitHold qsTransmitMin From b78f7f11de46de5366af3960e3f260a85311d090 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 27 May 2021 21:21:26 +0200 Subject: [PATCH 105/697] added the possiblity to choose which camera to use --- plugins/VOIP/gui/QVideoDevice.cpp | 14 +++- plugins/VOIP/gui/QVideoDevice.h | 3 + plugins/VOIP/gui/VOIPConfigPanel.cpp | 96 +++++++++++++++++++++++++++- plugins/VOIP/gui/VOIPConfigPanel.h | 7 +- 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index 9052c5306..ae149bfc5 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -28,6 +28,8 @@ #include "QVideoDevice.h" #include "VideoProcessor.h" +// #define DEBUG_QVIDEODEVICE 1 + QVideoInputDevice::QVideoInputDevice(QWidget *parent) :QObject(parent) { @@ -54,6 +56,8 @@ bool QVideoInputDevice::stopped() void QVideoInputDevice::stop() { + _capture_device_info = QCameraInfo(); + if(_timer != NULL) { _capture_device->stop(); @@ -70,6 +74,8 @@ void QVideoInputDevice::stop() _capture_device = NULL ; _image_capture = NULL ; } + if(_echo_output_device != NULL) + _echo_output_device->showFrameOff() ; } void QVideoInputDevice::getAvailableDevices(QList& device_desc) { @@ -105,6 +111,7 @@ void QVideoInputDevice::start(const QString& description) std::cerr << "No video camera available in this system!" << std::endl; return ; } + _capture_device_info = caminfo; _capture_device = new QCamera(caminfo); if(_capture_device->error() != QCamera::NoError) @@ -144,8 +151,9 @@ void QVideoInputDevice::start(const QString& description) void QVideoInputDevice::errorHandling(CameraStatus status,QCamera::Error error) { +#ifdef DEBUG_QVIDEODEVICE std::cerr << "Received msg from camera capture: status=" << (int)status << " error=" << (int)error << std::endl; - +#endif if(status == CANNOT_INITIALIZE_CAMERA) { std::cerr << "Cannot initialize camera. Make sure to install package libqt5multimedia5-plugins, as this is a common cause for camera not being found." << std::endl; @@ -169,7 +177,9 @@ void QVideoInputDevice::grabFrame(int id,QVideoFrame frame) reader.setScaledSize(QSize(640,480)); QImage image(reader.read()); +#ifdef DEBUG_QVIDEODEVICE std::cerr << "Frame " << id << ". Pixel format: " << frame.pixelFormat() << ". Size: " << image.size().width() << " x " << image.size().height() << std::endl; // if(frame.pixelFormat() != QVideoFrame::Format_Jpeg) +#endif if(_video_processor != NULL) { @@ -211,7 +221,9 @@ void QVideoOutputDevice::showFrameOff() void QVideoOutputDevice::showFrame(const QImage& img) { +#ifdef DEBUG_QVIDEODEVICE std::cerr << "img.size = " << img.width() << " x " << img.height() << std::endl; +#endif setPixmap(QPixmap::fromImage(img).scaled( QSize(height()*4/3,height()),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)) ; } diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index f23fd8aa5..0935c2730 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -22,6 +22,7 @@ #include #include +#include #include "interface/rsVOIP.h" #include "gui/VideoProcessor.h" @@ -85,6 +86,7 @@ class QVideoInputDevice: public QObject static void getAvailableDevices(QList& device_desc); + QString currentCameraDescriptionString() const { return _capture_device_info.deviceName(); } protected slots: void grabFrame(int id, QVideoFrame f) ; void errorHandling(CameraStatus status,QCamera::Error error); @@ -98,6 +100,7 @@ protected slots: QTimer *_timer ; QCamera *_capture_device; QCameraImageCapture *_image_capture; + QCameraInfo _capture_device_info; QVideoOutputDevice *_echo_output_device ; diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index 5b93db0cd..b30df639c 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -25,7 +25,8 @@ #include "audiodevicehelper.h" #include "AudioWizard.h" #include "gui/VideoProcessor.h" -#include "gui/common/RSGraphWidget.h" +#include "gui/VideoProcessor.h" +#include "util/misc.h" #include "util/RsProtectedTimer.h" #include @@ -104,9 +105,13 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) QList input_devices; QVideoInputDevice::getAvailableDevices(input_devices); ui.inputDevice_CB->clear(); + ui.inputDevice_CB->addItem(tr("[No video]"),QString("")); for(auto& s:input_devices) ui.inputDevice_CB->addItem(s,QVariant(s)); + if(!input_devices.empty()) + whileBlocking(ui.inputDevice_CB)->setCurrentIndex(1); // select default cam + connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); @@ -367,3 +372,92 @@ void VOIPConfigPanel::on_qpbAudioWizard_clicked() { aw.exec(); loadSettings(); } + +void VOIPConfigPanel::on_changedCurrentInputDevice(int i) +{ + QString s = dynamic_cast(sender())->itemData(i).toString(); + + videoInput->stop(); + + // check that the camera still exists + + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + + for(const QString& cams:input_devices) + if(s == cams) + { + std::cerr << "Switching to camera \"" << s.toStdString() << "\"" << std::endl; + + videoInput->start(s); + + return; + } + + // if not, re-create the ComboBox + + checkAvailableCameras(); +} + +void VOIPConfigPanel::checkAvailableCameras() +{ + // save current camera + QString current_cam = videoInput->currentCameraDescriptionString(); + + // Check that the list of cams we had previously is the same than the list of available camera. + + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + + bool same = true; + if(input_devices.size() != ui.inputDevice_CB->count()) + same = false; + + if(same) + { + int n=0; + for(auto& s:input_devices) + { + if(ui.inputDevice_CB->itemData(n).toString() != s) + { + same = false; + break; + } + n++; + } + } + + // If not, re-add them to the comboBox and make sure to re-select the same camera. + + if(!same) + { + whileBlocking(ui.inputDevice_CB)->clear(); // remove existing entries + whileBlocking(ui.inputDevice_CB)->addItem(tr("[No video]"),QString("")); + int n=0; + int found_index = -1; + + for(auto& s:input_devices) + { + whileBlocking(ui.inputDevice_CB)->addItem(s,QVariant(s)); + + if(s == current_cam) + found_index = n; + + n++; + } + + if(found_index >= 0) + ui.inputDevice_CB->setCurrentIndex(found_index); + else + ui.inputDevice_CB->setCurrentIndex(0); // no video + } +} + + + + + + + + + diff --git a/plugins/VOIP/gui/VOIPConfigPanel.h b/plugins/VOIP/gui/VOIPConfigPanel.h index 4985cb5b7..dcfc0323b 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.h +++ b/plugins/VOIP/gui/VOIPConfigPanel.h @@ -59,8 +59,9 @@ class VOIPConfigPanel : public ConfigPage //VideoDecoder *videoDecoder ; //VideoEncoder *videoEncoder ; QVideoInputDevice *videoInput ; - VideoProcessor *videoProcessor ; + VideoProcessor *videoProcessor ; bool loaded; + QString currentCameraDescription; voipGraphSource *graph_source ; @@ -86,7 +87,9 @@ class VOIPConfigPanel : public ConfigPage virtual void showEvent(QShowEvent *) override; virtual void hideEvent(QHideEvent *event) override; private slots: - void updateAvailableBW(double r); + void on_changedCurrentInputDevice(int i); + void checkAvailableCameras(); + void updateAvailableBW(double r); void loadSettings(); void emptyBuffer(); void togglePreview(bool) ; From 90bc88089c977cb7204897f1bf2dad568dd5a4f4 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 27 May 2021 21:45:56 +0200 Subject: [PATCH 106/697] fixed up bandwidth display when no video is selected --- plugins/VOIP/gui/QVideoDevice.cpp | 7 +++++-- plugins/VOIP/gui/QVideoDevice.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index ae149bfc5..57fa12d51 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -49,7 +49,7 @@ QVideoInputDevice::~QVideoInputDevice() delete _timer; } -bool QVideoInputDevice::stopped() +bool QVideoInputDevice::stopped() const { return _timer == NULL ; } @@ -204,7 +204,10 @@ bool QVideoInputDevice::getNextEncodedPacket(RsVOIPDataChunk& chunk) uint32_t QVideoInputDevice::currentBandwidth() const { - return _video_processor->currentBandwidthOut() ; + if(stopped()) + return 0; + else + return _video_processor->currentBandwidthOut() ; } QVideoOutputDevice::QVideoOutputDevice(QWidget *parent) diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index 0935c2730..63d83b4e1 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -74,7 +74,7 @@ class QVideoInputDevice: public QObject void start(const QString &description = QString()) ; void stop() ; - bool stopped(); + bool stopped() const; enum CameraStatus { CAMERA_IS_READY = 0x00, From 0db2f3a53e293ad1e3e51f4e6466424a12c87551 Mon Sep 17 00:00:00 2001 From: howdy-partner <3364866+howdy-partner@users.noreply.github.com> Date: Thu, 10 Jun 2021 00:41:42 +0300 Subject: [PATCH 107/697] fix smiley bug --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index e330f49d3..491d2ca21 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -1583,7 +1583,12 @@ void ChatWidget::addSmiley() smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) QString plainText = ui->chatTextEdit->toPlainText(); - QChar start = plainText[ui->chatTextEdit->textCursor().position() - 1]; + + int startPosition = ui->chatTextEdit->textCursor().position(); + if (startPosition > 0) + startPosition -= 1; + + QChar start = plainText[startPosition]; if(!ui->chatTextEdit->textCursor().atStart() && start != QChar(' ')) smiley = QString(" ") + smiley; From 476180dc14ab9311dc781b4d56cc6d23d738bbc2 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 14 Jun 2021 11:53:27 +0200 Subject: [PATCH 108/697] Files extra list optimization and cleanup Improve performances and fix compiler warnings --- libretroshare/src/ft/ftextralist.cc | 90 +++++++++++------------------ libretroshare/src/ft/ftextralist.h | 20 +++---- 2 files changed, 42 insertions(+), 68 deletions(-) diff --git a/libretroshare/src/ft/ftextralist.cc b/libretroshare/src/ft/ftextralist.cc index 3912cc1b3..a68a5c7d1 100644 --- a/libretroshare/src/ft/ftextralist.cc +++ b/libretroshare/src/ft/ftextralist.cc @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2008 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -42,49 +43,34 @@ * #define DEBUG_ELIST 1 *****/ -ftExtraList::ftExtraList() - :p3Config(), extMutex("p3Config") -{ - cleanup = 0; - return; -} - +ftExtraList::ftExtraList(): p3Config(), extMutex("p3Config"), mNextCleanupTS(0) +{} void ftExtraList::threadTick() { - bool todo = false; - rstime_t now = time(NULL); + bool haveFilesToHash = false; + rstime_t now = time(nullptr); - { - RsStackMutex stack(extMutex); + { + RS_STACK_MUTEX(extMutex); + haveFilesToHash = !mToHash.empty(); + } - todo = (mToHash.size() > 0); - } + if (haveFilesToHash) + { + hashAFile(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + else + { + if (mNextCleanupTS < now) + { + cleanupOldFiles(); + mNextCleanupTS = now + CLEANUP_PERIOD; + } - if (todo) - { - /* Hash a file */ - hashAFile(); - - /* microsleep */ - rstime::rs_usleep(10); - } - else - { - /* cleanup */ - if (cleanup < now) - { - cleanupOldFiles(); - cleanup = now + CLEANUP_PERIOD; - } - - /* sleep */ -#ifdef WIN32 - Sleep(1000); -#else - sleep(1); -#endif - } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } } @@ -98,15 +84,11 @@ void ftExtraList::hashAFile() /* extract entry from the queue */ FileDetails details; - { RS_STACK_MUTEX(extMutex); - - if (mToHash.empty()) - return; - + if (mToHash.empty()) return; details = mToHash.front(); - mToHash.pop_front(); + mToHash.pop(); } #ifdef DEBUG_ELIST @@ -114,26 +96,24 @@ void ftExtraList::hashAFile() std::cerr << std::endl; #endif - /* hash it! */ - std::string name, hash; - //uint64_t size; - if (RsDirUtil::hashFile(details.info.path, details.info.fname, details.info.hash, details.info.size)) + if(RsDirUtil::hashFile( + details.info.path, details.info.fname, details.info.hash, + details.info.size )) { RS_STACK_MUTEX(extMutex); /* stick it in the available queue */ mFiles[details.info.hash] = details; - mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; + mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash; /* add to the path->hash map */ mHashedList[details.info.path] = details.info.hash; IndicateConfigChanged(); - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED; - if(rsEvents) - rsEvents->postEvent(ev); + auto ev = std::make_shared(); + ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED; + rsEvents->postEvent(ev); } } @@ -304,7 +284,7 @@ bool ftExtraList::hashExtraFile( { RS_STACK_MUTEX(extMutex); - mToHash.push_back(details); /* add into queue */ + mToHash.push(details); /* add into queue */ } return true; @@ -420,8 +400,6 @@ RsSerialiser *ftExtraList::setupSerialiser() bool ftExtraList::saveList(bool &cleanup, std::list& sList) { - - cleanup = true; /* called after each item is added */ diff --git a/libretroshare/src/ft/ftextralist.h b/libretroshare/src/ft/ftextralist.h index 229c0fe3c..7f96364b8 100644 --- a/libretroshare/src/ft/ftextralist.h +++ b/libretroshare/src/ft/ftextralist.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2008 by Robert Fernie * + * Copyright (C) 2008 Robert Fernie * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -20,8 +22,7 @@ * * *******************************************************************************/ -#ifndef FT_FILE_EXTRA_LIST_HEADER -#define FT_FILE_EXTRA_LIST_HEADER +#pragma once /* * ftFileExtraList @@ -50,7 +51,7 @@ * */ -#include +#include #include #include @@ -159,7 +160,7 @@ public: protected: virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); + virtual bool saveList(bool& cleanup, std::list&); virtual bool loadList(std::list& load); static RsFileHash makeEncryptedHash(const RsFileHash& hash); @@ -172,16 +173,11 @@ private: mutable RsMutex extMutex; - std::list mToHash; + std::queue mToHash; std::map mHashedList; /* path -> hash ( not saved ) */ std::map mFiles; std::map mHashOfHash; /* sha1(hash) map so as to answer requests to encrypted transfers */ - rstime_t cleanup ; + rstime_t mNextCleanupTS; }; - - - - -#endif From d7fb3d8bf4622be397462a18631828278f177385 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 19 Jun 2021 15:34:46 +0200 Subject: [PATCH 109/697] moved TorControl files into libretroshare. Not compiling yet. --- libretroshare/src/libretroshare.pro | 40 +++++++ .../src/tor}/AddOnionCommand.cpp | 0 .../src/tor}/AddOnionCommand.h | 17 ++- .../src/tor}/AuthenticateCommand.cpp | 0 .../src/tor}/AuthenticateCommand.h | 0 .../src/tor}/CryptoKey.cpp | 46 +++---- .../src/tor}/CryptoKey.h | 15 ++- .../src/tor}/GetConfCommand.cpp | 25 ++-- .../src/tor}/GetConfCommand.h | 16 ++- .../src/tor}/HiddenService.cpp | 2 +- .../src/tor}/HiddenService.h | 47 ++++---- .../src/tor}/PendingOperation.cpp | 0 .../src/tor}/PendingOperation.h | 0 .../src/tor}/ProtocolInfoCommand.cpp | 0 .../src/tor}/ProtocolInfoCommand.h | 31 +++-- .../src/tor}/SecureRNG.cpp | 31 +++-- .../src/tor}/SecureRNG.h | 10 +- .../src/tor}/SetConfCommand.cpp | 0 .../src/tor}/SetConfCommand.h | 0 .../src/tor}/Settings.cpp | 0 .../src/tor}/Settings.h | 0 .../src/tor}/StrUtil.cpp | 12 +- .../src/tor}/StrUtil.h | 6 +- .../src/tor}/TorControl.cpp | 0 .../src/tor}/TorControl.h | 0 .../src/tor}/TorControlCommand.cpp | 0 .../src/tor}/TorControlCommand.h | 19 ++- .../src/tor}/TorControlSocket.cpp | 0 .../src/tor}/TorControlSocket.h | 0 .../src/tor}/TorManager.cpp | 0 .../src/tor}/TorManager.h | 0 .../src/tor}/TorProcess.cpp | 0 .../src/tor}/TorProcess.h | 0 .../src/tor}/TorProcess_p.h | 0 .../src/tor}/TorSocket.cpp | 0 .../src/tor}/TorSocket.h | 0 libretroshare/src/tor/TorTypes.h | 112 ++++++++++++++++++ .../src/tor}/Useful.h | 0 .../{ => gui}/TorControl/TorControlWindow.cpp | 0 .../{ => gui}/TorControl/TorControlWindow.h | 0 .../{ => gui}/TorControl/TorControlWindow.ui | 0 retroshare-gui/src/retroshare-gui.pro | 40 ------- 42 files changed, 294 insertions(+), 175 deletions(-) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AddOnionCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AddOnionCommand.h (89%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AuthenticateCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AuthenticateCommand.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/CryptoKey.cpp (93%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/CryptoKey.h (90%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/GetConfCommand.cpp (87%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/GetConfCommand.h (89%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/HiddenService.cpp (98%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/HiddenService.h (72%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/PendingOperation.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/PendingOperation.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/ProtocolInfoCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/ProtocolInfoCommand.h (83%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SecureRNG.cpp (84%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SecureRNG.h (88%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SetConfCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SetConfCommand.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Settings.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Settings.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/StrUtil.cpp (91%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/StrUtil.h (94%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControl.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControl.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlCommand.h (85%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlSocket.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlSocket.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorManager.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorManager.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess_p.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorSocket.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorSocket.h (100%) create mode 100644 libretroshare/src/tor/TorTypes.h rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Useful.h (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.cpp (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.h (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.ui (100%) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..5276bda9b 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -719,6 +719,46 @@ SOURCES += rsitems/rsnxsitems.cc \ gxs/rsgxsutil.cc \ gxs/rsgxsrequesttypes.cc +# Tor +HEADERS += tor/AddOnionCommand.h \ + tor/AuthenticateCommand.h \ + tor/CryptoKey.h \ + tor/GetConfCommand.h \ + tor/HiddenService.h \ + tor/PendingOperation.h \ + tor/ProtocolInfoCommand.h \ + tor/SecureRNG.h \ + tor/TorTypes.h \ + tor/SetConfCommand.h \ + tor/Settings.h \ + tor/StrUtil.h \ + tor/TorControl.h \ + tor/TorControlCommand.h \ + tor/TorControlSocket.h \ + tor/TorManager.h \ + tor/TorProcess.h \ + tor/TorProcess_p.h \ + tor/TorSocket.h \ + tor/Useful.h + +SOURCES += tor/AddOnionCommand.cpp \ + tor/AuthenticateCommand.cpp \ + tor/GetConfCommand.cpp \ + tor/HiddenService.cpp \ + tor/ProtocolInfoCommand.cpp \ + tor/SetConfCommand.cpp \ + tor/TorControlCommand.cpp \ + tor/TorControl.cpp \ + tor/TorControlSocket.cpp \ + tor/TorManager.cpp \ + tor/TorProcess.cpp \ + tor/TorSocket.cpp \ + tor/CryptoKey.cpp \ + tor/PendingOperation.cpp \ + tor/SecureRNG.cpp \ + tor/Settings.cpp \ + tor/StrUtil.cpp + # gxs tunnels HEADERS += gxstunnel/p3gxstunnel.h \ gxstunnel/rsgxstunnelitems.h \ diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/AddOnionCommand.cpp rename to libretroshare/src/tor/AddOnionCommand.cpp diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h similarity index 89% rename from retroshare-gui/src/TorControl/AddOnionCommand.h rename to libretroshare/src/tor/AddOnionCommand.h index 7c0afaf5e..a51888b2f 100644 --- a/retroshare-gui/src/TorControl/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -34,9 +34,7 @@ #define ADDONIONCOMMAND_H #include "TorControlCommand.h" -#include -#include -#include +#include namespace Tor { @@ -45,27 +43,28 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(AddOnionCommand) - - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) +#ifdef NO_TOR_CONTROL_PROPERTIES + Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) Q_PROPERTY(bool successful READ isSuccessful CONSTANT) +#endif public: AddOnionCommand(HiddenService *service); QByteArray build(); - QString errorMessage() const { return m_errorMessage; } + std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; +#ifdef NO_TOR_CONTROL_SIGNALS signals: void succeeded(); void failed(int code); +#endif protected: HiddenService *m_service; - QString m_errorMessage; + std::string m_errorMessage; virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.cpp b/libretroshare/src/tor/AuthenticateCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/AuthenticateCommand.cpp rename to libretroshare/src/tor/AuthenticateCommand.cpp diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.h b/libretroshare/src/tor/AuthenticateCommand.h similarity index 100% rename from retroshare-gui/src/TorControl/AuthenticateCommand.h rename to libretroshare/src/tor/AuthenticateCommand.h diff --git a/retroshare-gui/src/TorControl/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp similarity index 93% rename from retroshare-gui/src/TorControl/CryptoKey.cpp rename to libretroshare/src/tor/CryptoKey.cpp index 9be9a6699..d5b66c988 100644 --- a/retroshare-gui/src/TorControl/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -31,13 +31,13 @@ */ #include +#include #include "CryptoKey.h" #include "SecureRNG.h" #include "Useful.h" -#include -#include -#include +#include "TorTypes.h" + #include #include #include @@ -120,17 +120,23 @@ bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat for } #endif -bool CryptoKey::loadFromFile(const QString& path) +bool CryptoKey::loadFromFile(const std::string &path) { - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) + FILE *f = fopen(path.c_str(),"r"); + + if(!f) { - qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); + std::cerr << "Failed to open Tor key file " << path << std::endl; return false; } - QByteArray data = file.readAll(); - file.close(); + Tor::TorByteArray data ; + int c; + + while( EOF != (c=fgetc(f))) + data += (unsigned char)c; + + fclose(f); if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) { @@ -146,14 +152,14 @@ bool CryptoKey::loadFromFile(const QString& path) } std::cerr << "Have read the following key: " << std::endl; - std::cerr << QString(data).toStdString() << std::endl; + std::cerr << data.toStdString() << std::endl; key_data = data; return true; } -bool CryptoKey::loadFromTorMessage(const QByteArray& b) +bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) { // note: We should probably check the structure a bit more, for security. @@ -163,7 +169,7 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) std::cerr << " type: RSA-1024 (Tor v2)" << std::endl; else if(b.startsWith("ED25519-V3")) std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; - else if(b.indexOf(':')) + else if(b.indexOf(':') >= 0) { std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; return false; @@ -174,22 +180,22 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) } /* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -QByteArray torControlHashedPassword(const QByteArray &password) +Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) { - QByteArray salt = SecureRNG::random(8); + Tor::TorByteArray salt = SecureRNG::random(8); if (salt.isNull()) - return QByteArray(); + return Tor::TorByteArray(); int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); SHA_CTX hash; SHA1_Init(&hash); - QByteArray tmp = salt + password; + Tor::TorByteArray tmp = salt + password; while (count) { - int c = qMin(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); + int c = std::min(count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); count -= c; } @@ -197,8 +203,8 @@ QByteArray torControlHashedPassword(const QByteArray &password) SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + - QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); + return Tor::TorByteArray("16:") + salt.toHex().toUpper() + Tor::TorByteArray("60") + + Tor::TorByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); } diff --git a/retroshare-gui/src/TorControl/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h similarity index 90% rename from retroshare-gui/src/TorControl/CryptoKey.h rename to libretroshare/src/tor/CryptoKey.h index c99703444..57c22476f 100644 --- a/retroshare-gui/src/TorControl/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -33,9 +33,7 @@ #ifndef CRYPTOKEY_H #define CRYPTOKEY_H -#include -#include -#include +#include "tor/TorTypes.h" class CryptoKey { @@ -57,12 +55,13 @@ public: bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); #endif - bool loadFromFile(const QString &path); + bool loadFromFile(const std::string& path); void clear(); - const QByteArray bytes() const { return key_data; } - bool loadFromTorMessage(const QByteArray& b); - bool isLoaded() const { return !key_data.isNull(); } + const Tor::TorByteArray& bytes() const { return key_data; } + bool loadFromTorMessage(const Tor::TorByteArray& b); + bool isLoaded() const { return !key_data.empty(); } + #ifdef TO_REMOVE bool isPrivate() const; @@ -101,6 +100,6 @@ private: #endif }; -QByteArray torControlHashedPassword(const QByteArray &password); +Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password); #endif // CRYPTOKEY_H diff --git a/retroshare-gui/src/TorControl/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp similarity index 87% rename from retroshare-gui/src/TorControl/GetConfCommand.cpp rename to libretroshare/src/tor/GetConfCommand.cpp index 933def562..7da0a46cc 100644 --- a/retroshare-gui/src/TorControl/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -30,9 +30,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + +#include "TorTypes.h" #include "GetConfCommand.h" #include "StrUtil.h" -#include using namespace Tor; @@ -43,27 +45,28 @@ GetConfCommand::GetConfCommand(Type t) QByteArray GetConfCommand::build(const QByteArray &key) { - return build(QList() << key); + return build(std::list{key}); } -QByteArray GetConfCommand::build(const QList &keys) +QByteArray GetConfCommand::build(const std::list &keys) { QByteArray out; if (type == GetConf) { - out = "GETCONF"; + out = QByteArray("GETCONF"); } else if (type == GetInfo) { - out = "GETINFO"; + out = QByteArray("GETINFO"); } else { - Q_ASSERT(false); + throw std::runtime_error("Unsupported build type in GetConfCommand"); return out; } - foreach (const QByteArray &key, keys) { - out.append(' '); - out.append(key); + for(const QByteArray& key: keys) + { + out += (' '); + out += key; } - out.append("\r\n"); + out += std::string("\r\n"); return out; } @@ -74,7 +77,7 @@ void GetConfCommand::onReply(int statusCode, const QByteArray &data) return; int kep = data.indexOf('='); - QString key = QString::fromLatin1(data.mid(0, kep)); + std::string key = QString::fromLatin1(data.mid(0, kep)); QVariant value; if (kep >= 0) value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); diff --git a/retroshare-gui/src/TorControl/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h similarity index 89% rename from retroshare-gui/src/TorControl/GetConfCommand.h rename to libretroshare/src/tor/GetConfCommand.h index 0de97d1b7..0289d5e40 100644 --- a/retroshare-gui/src/TorControl/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -34,18 +34,16 @@ #define GETCONFCOMMAND_H #include "TorControlCommand.h" -#include -#include +#include namespace Tor { class GetConfCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(GetConfCommand) - +#ifdef NO_TOR_CONTROL_PROPERTIES Q_PROPERTY(QVariantMap results READ results CONSTANT) +#endif public: enum Type { @@ -57,10 +55,10 @@ public: GetConfCommand(Type type); QByteArray build(const QByteArray &key); - QByteArray build(const QList &keys); + QByteArray build(const std::list &keys); - const QVariantMap &results() const { return m_results; } - QVariant get(const QByteArray &key) const; + const QVariantMap& results() const { return m_results; } + QVariant get(const QByteArray& key) const; protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -69,7 +67,7 @@ protected: private: QVariantMap m_results; - QString m_lastKey; + std::string m_lastKey; }; } diff --git a/retroshare-gui/src/TorControl/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp similarity index 98% rename from retroshare-gui/src/TorControl/HiddenService.cpp rename to libretroshare/src/tor/HiddenService.cpp index b2b58626a..6b28ebd6f 100644 --- a/retroshare-gui/src/TorControl/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -90,7 +90,7 @@ void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, q m_targets.append(t); } -void HiddenService::setServiceId(const QByteArray& sid) +void HiddenService::setServiceId(const TorByteArray &sid) { m_service_id = sid; m_hostname = sid + ".onion"; diff --git a/retroshare-gui/src/TorControl/HiddenService.h b/libretroshare/src/tor/HiddenService.h similarity index 72% rename from retroshare-gui/src/TorControl/HiddenService.h rename to libretroshare/src/tor/HiddenService.h index 20fa1d851..19f1e561d 100644 --- a/retroshare-gui/src/TorControl/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -33,28 +33,25 @@ #ifndef HIDDENSERVICE_H #define HIDDENSERVICE_H -#include -#include -#include -#include "CryptoKey.h" +#include +#include + +#include "tor/CryptoKey.h" +#include "tor/TorTypes.h" namespace Tor { - class TorSocket; -class HiddenService : public QObject +class HiddenService : public NonCopiable { - Q_OBJECT - Q_DISABLE_COPY(HiddenService) - friend class TorControlPrivate; public: struct Target { - QHostAddress targetAddress; - quint16 servicePort, targetPort; + TorHostAddress targetAddress; + unsigned short servicePort, targetPort; }; enum Status @@ -64,24 +61,25 @@ public: Online /* Published */ }; - HiddenService(QObject *parent = 0); - HiddenService(const QString &dataPath, QObject *parent = 0); - HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); + HiddenService(); + HiddenService(const std::string& dataPath); + HiddenService(const CryptoKey& privateKey, const std::string& dataPath = std::string()); Status status() const { return m_status; } - const QString& hostname() const { return m_hostname; } - const QString serviceId() const { return QString(m_service_id); } - const QString& dataPath() const { return m_dataPath; } + const std::string& hostname() const { return m_hostname; } + const std::string serviceId() const { return std::string(m_service_id.data()); } + const std::string& dataPath() const { return m_dataPath; } CryptoKey privateKey() { return m_privateKey; } void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const QByteArray& sid); + void setServiceId(const TorByteArray& sid); - const QList &targets() const { return m_targets; } + const std::list& targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); + void addTarget(unsigned short servicePort, TorHostAddress targetAddress, unsigned short targetPort); +#ifdef NO_TOR_CONTROL_SIGNALS signals: void statusChanged(int newStatus, int oldStatus); void serviceOnline(); @@ -90,14 +88,15 @@ signals: private slots: void servicePublished(); +#endif private: - QString m_dataPath; - QList m_targets; - QString m_hostname; + std::string m_dataPath; + std::list m_targets; + std::string m_hostname; Status m_status; CryptoKey m_privateKey; - QByteArray m_service_id; + TorByteArray m_service_id; void loadPrivateKey(); void setStatus(Status newStatus); diff --git a/retroshare-gui/src/TorControl/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp similarity index 100% rename from retroshare-gui/src/TorControl/PendingOperation.cpp rename to libretroshare/src/tor/PendingOperation.cpp diff --git a/retroshare-gui/src/TorControl/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h similarity index 100% rename from retroshare-gui/src/TorControl/PendingOperation.h rename to libretroshare/src/tor/PendingOperation.h diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp rename to libretroshare/src/tor/ProtocolInfoCommand.cpp diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h similarity index 83% rename from retroshare-gui/src/TorControl/ProtocolInfoCommand.h rename to libretroshare/src/tor/ProtocolInfoCommand.h index 7789cfefd..1ead20d29 100644 --- a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -33,8 +33,17 @@ #ifndef PROTOCOLINFOCOMMAND_H #define PROTOCOLINFOCOMMAND_H +#include #include "TorControlCommand.h" -#include + +enum class AuthMethods: uint8_t +{ + AuthUnknown = 0x0, + AuthNull = 0x1, + AuthHashedPassword = 0x2, + AuthCookie = 0x4 +}; +RS_REGISTER_ENUM_FLAGS_TYPE(AuthMethods) namespace Tor { @@ -43,25 +52,13 @@ class TorControl; class ProtocolInfoCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(ProtocolInfoCommand) - public: - enum AuthMethod - { - AuthUnknown = 0, - AuthNull = 0x1, - AuthHashedPassword = 0x2, - AuthCookie = 0x4 - }; - Q_DECLARE_FLAGS(AuthMethods, AuthMethod) - ProtocolInfoCommand(TorControl *manager); QByteArray build(); AuthMethods authMethods() const { return m_authMethods; } - QString torVersion() const { return m_torVersion; } - QString cookieFile() const { return m_cookieFile; } + std::string torVersion() const { return m_torVersion; } + std::string cookieFile() const { return m_cookieFile; } protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -69,8 +66,8 @@ protected: private: TorControl *manager; AuthMethods m_authMethods; - QString m_torVersion; - QString m_cookieFile; + std::string m_torVersion; + std::string m_cookieFile; }; } diff --git a/retroshare-gui/src/TorControl/SecureRNG.cpp b/libretroshare/src/tor/SecureRNG.cpp similarity index 84% rename from retroshare-gui/src/TorControl/SecureRNG.cpp rename to libretroshare/src/tor/SecureRNG.cpp index 60cf3c048..e07ef8e72 100644 --- a/retroshare-gui/src/TorControl/SecureRNG.cpp +++ b/libretroshare/src/tor/SecureRNG.cpp @@ -31,10 +31,12 @@ */ #include "SecureRNG.h" -#include + #include #include #include +#include +#include #ifdef Q_OS_WIN #include @@ -82,7 +84,7 @@ bool SecureRNG::seed() #else if (!RAND_poll()) { - qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); + std::cerr << "OpenSSL RNG seed failed:" << ERR_get_error(); return false; } #endif @@ -94,11 +96,16 @@ bool SecureRNG::seed() return true; } -void SecureRNG::random(char *buf, int size) +void SecureRNG::random(unsigned char *buf, int size) { - int r = RAND_bytes(reinterpret_cast(buf), size); + int r = RAND_bytes(buf, size); + if (r <= 0) - qFatal("RNG failed: %lu", ERR_get_error()); + { + std::ostringstream s; + s << "RNG failed: " << ERR_get_error() ; + throw std::runtime_error(s.str()); + } } QByteArray SecureRNG::random(int size) @@ -111,7 +118,7 @@ QByteArray SecureRNG::random(int size) QByteArray SecureRNG::randomPrintable(int length) { QByteArray re(length, 0); - for (int i = 0; i < re.size(); i++) + for (uint32_t i = 0; i < re.size(); i++) re[i] = randomInt(95) + 32; return re; } @@ -123,24 +130,24 @@ unsigned SecureRNG::randomInt(unsigned max) for (;;) { - random(reinterpret_cast(&value), sizeof(value)); + random(reinterpret_cast(&value), sizeof(value)); if (value < cutoff) return value % max; } } #ifndef UINT64_MAX -#define UINT64_MAX ((quint64)-1) +#define UINT64_MAX ((uint64_t)-1) #endif -quint64 SecureRNG::randomInt64(quint64 max) +uint64_t SecureRNG::randomInt64(uint64_t max) { - quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); - quint64 value = 0; + uint64_t cutoff = UINT64_MAX - (UINT64_MAX % max); + uint64_t value = 0; for (;;) { - random(reinterpret_cast(value), sizeof(value)); + random(reinterpret_cast(value), sizeof(value)); if (value < cutoff) return value % max; } diff --git a/retroshare-gui/src/TorControl/SecureRNG.h b/libretroshare/src/tor/SecureRNG.h similarity index 88% rename from retroshare-gui/src/TorControl/SecureRNG.h rename to libretroshare/src/tor/SecureRNG.h index f3b2a4b64..cce43cec5 100644 --- a/retroshare-gui/src/TorControl/SecureRNG.h +++ b/libretroshare/src/tor/SecureRNG.h @@ -33,19 +33,19 @@ #ifndef SECURERNG_H #define SECURERNG_H -#include +#include "TorTypes.h" class SecureRNG { public: static bool seed(); - static void random(char *buf, int size); - static QByteArray random(int size); + static void random(unsigned char *buf, int size); + static Tor::TorByteArray random(int size); - static QByteArray randomPrintable(int length); + static Tor::TorByteArray randomPrintable(int length); static unsigned randomInt(unsigned max); - static quint64 randomInt64(quint64 max); + static uint64_t randomInt64(uint64_t max); }; #endif // SECURERNG_H diff --git a/retroshare-gui/src/TorControl/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/SetConfCommand.cpp rename to libretroshare/src/tor/SetConfCommand.cpp diff --git a/retroshare-gui/src/TorControl/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h similarity index 100% rename from retroshare-gui/src/TorControl/SetConfCommand.h rename to libretroshare/src/tor/SetConfCommand.h diff --git a/retroshare-gui/src/TorControl/Settings.cpp b/libretroshare/src/tor/Settings.cpp similarity index 100% rename from retroshare-gui/src/TorControl/Settings.cpp rename to libretroshare/src/tor/Settings.cpp diff --git a/retroshare-gui/src/TorControl/Settings.h b/libretroshare/src/tor/Settings.h similarity index 100% rename from retroshare-gui/src/TorControl/Settings.h rename to libretroshare/src/tor/Settings.h diff --git a/retroshare-gui/src/TorControl/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp similarity index 91% rename from retroshare-gui/src/TorControl/StrUtil.cpp rename to libretroshare/src/tor/StrUtil.cpp index 81de151b0..b78b50ae5 100644 --- a/retroshare-gui/src/TorControl/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -32,14 +32,14 @@ #include "StrUtil.h" -QByteArray quotedString(const QByteArray &string) +QByteArray quotedString(const QByteArray& string) { QByteArray out; out.reserve(string.size() * 2); - out.append('"'); + out += '"'; - for (int i = 0; i < string.size(); ++i) + for (uint32_t i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -67,7 +67,7 @@ QByteArray unquotedString(const QByteArray &string) QByteArray out; out.reserve(string.size() - 2); - for (int i = 1; i < string.size(); ++i) + for (uint32_t i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -85,9 +85,9 @@ QByteArray unquotedString(const QByteArray &string) return out; } -QList splitQuotedStrings(const QByteArray &input, char separator) +std::list splitQuotedStrings(const QByteArray &input, char separator) { - QList out; + std::list out; bool inquote = false; int start = 0; diff --git a/retroshare-gui/src/TorControl/StrUtil.h b/libretroshare/src/tor/StrUtil.h similarity index 94% rename from retroshare-gui/src/TorControl/StrUtil.h rename to libretroshare/src/tor/StrUtil.h index c86d2c6ec..ba9b5ac3a 100644 --- a/retroshare-gui/src/TorControl/StrUtil.h +++ b/libretroshare/src/tor/StrUtil.h @@ -33,14 +33,14 @@ #ifndef STRINGUTIL_H #define STRINGUTIL_H -#include -#include +#include "TorTypes.h" +#include QByteArray quotedString(const QByteArray &string); /* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ QByteArray unquotedString(const QByteArray &string); -QList splitQuotedStrings(const QByteArray &input, char separator); +std::list splitQuotedStrings(const QByteArray &input, char separator); #endif // STRINGUTIL_H diff --git a/retroshare-gui/src/TorControl/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControl.cpp rename to libretroshare/src/tor/TorControl.cpp diff --git a/retroshare-gui/src/TorControl/TorControl.h b/libretroshare/src/tor/TorControl.h similarity index 100% rename from retroshare-gui/src/TorControl/TorControl.h rename to libretroshare/src/tor/TorControl.h diff --git a/retroshare-gui/src/TorControl/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControlCommand.cpp rename to libretroshare/src/tor/TorControlCommand.cpp diff --git a/retroshare-gui/src/TorControl/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h similarity index 85% rename from retroshare-gui/src/TorControl/TorControlCommand.h rename to libretroshare/src/tor/TorControlCommand.h index 894381054..6c8693682 100644 --- a/retroshare-gui/src/TorControl/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -33,32 +33,31 @@ #ifndef TORCONTROLCOMMAND_H #define TORCONTROLCOMMAND_H -#include -#include +#include +#include "tor/TorTypes.h" namespace Tor { - -class TorControlCommand : public QObject +class TorControlCommand : public NonCopiable { - Q_OBJECT - Q_DISABLE_COPY(TorControlCommand) - friend class TorControlSocket; public: TorControlCommand(); + virtual ~TorControlCommand() {} int statusCode() const { return m_finalStatus; } +#ifdef NO_TOR_CONTROL_SIGNALS signals: - void replyLine(int statusCode, const QByteArray &data); + void replyLine(int statusCode, const TorByteArray& data); void finished(); +#endif protected: - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const TorByteArray& data); virtual void onFinished(int statusCode); - virtual void onDataLine(const QByteArray &data); + virtual void onDataLine(const TorByteArray& data); virtual void onDataFinished(); private: diff --git a/retroshare-gui/src/TorControl/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControlSocket.cpp rename to libretroshare/src/tor/TorControlSocket.cpp diff --git a/retroshare-gui/src/TorControl/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h similarity index 100% rename from retroshare-gui/src/TorControl/TorControlSocket.h rename to libretroshare/src/tor/TorControlSocket.h diff --git a/retroshare-gui/src/TorControl/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorManager.cpp rename to libretroshare/src/tor/TorManager.cpp diff --git a/retroshare-gui/src/TorControl/TorManager.h b/libretroshare/src/tor/TorManager.h similarity index 100% rename from retroshare-gui/src/TorControl/TorManager.h rename to libretroshare/src/tor/TorManager.h diff --git a/retroshare-gui/src/TorControl/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess.cpp rename to libretroshare/src/tor/TorProcess.cpp diff --git a/retroshare-gui/src/TorControl/TorProcess.h b/libretroshare/src/tor/TorProcess.h similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess.h rename to libretroshare/src/tor/TorProcess.h diff --git a/retroshare-gui/src/TorControl/TorProcess_p.h b/libretroshare/src/tor/TorProcess_p.h similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess_p.h rename to libretroshare/src/tor/TorProcess_p.h diff --git a/retroshare-gui/src/TorControl/TorSocket.cpp b/libretroshare/src/tor/TorSocket.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorSocket.cpp rename to libretroshare/src/tor/TorSocket.cpp diff --git a/retroshare-gui/src/TorControl/TorSocket.h b/libretroshare/src/tor/TorSocket.h similarity index 100% rename from retroshare-gui/src/TorControl/TorSocket.h rename to libretroshare/src/tor/TorSocket.h diff --git a/libretroshare/src/tor/TorTypes.h b/libretroshare/src/tor/TorTypes.h new file mode 100644 index 000000000..a3ebb523a --- /dev/null +++ b/libretroshare/src/tor/TorTypes.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include + +namespace Tor +{ + +class NonCopiable { +public: + NonCopiable(){} + virtual ~NonCopiable()=default; +private: + NonCopiable(const NonCopiable& nc) {} + virtual NonCopiable& operator=(const NonCopiable& nc) { return *this ; } +}; + +class TorByteArray: public std::vector +{ +public: + TorByteArray(const std::string& s = std::string()) + { + clear(); + for(uint32_t i=0;i size()) + return false; + + for(uint32_t i=0;i size()) + return false; + + for(uint32_t i=0;i Date: Tue, 22 Jun 2021 08:24:11 +0200 Subject: [PATCH 110/697] Avoid JSON operations on RsGxsIdGroup::mPgpIdSign The field is actually a raw memory chunk even if declared as an std::string as result the produced JSON is broken and JSON API clients cannot parse the output of methods like rsIdentity/getIdentitiesInfo A proper fix would be refactoring the whole code to use a proper raw memory buffer for that field but given there is no usage for a raw PGP signature on a client app as RetroShare library already verify it internally workaround the issue by just ignoring that field in JSON serial operations. --- libretroshare/src/retroshare/rsidentity.h | 31 +++++++++++++---------- libretroshare/src/rsitems/rsgxsiditems.h | 28 +++++++++++--------- libretroshare/src/services/p3idservice.cc | 19 ++++++++++++-- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 0c8c364e3..36b1f4bb8 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -131,23 +132,25 @@ struct RsGxsIdGroup : RsSerializable // ??? 160 bits. Sha1CheckSum mPgpIdHash; - // Need a signature as proof - otherwise anyone could add others Hashes. - // This is a string, as the length is variable. - std::string mPgpIdSign; - // Recognition Strings. MAX# defined above. + /** Need a signature as proof - otherwise anyone could add others Hashes. + * This is a string, as the length is variable. + * TODO: Thing like this should actually be a byte array (pointer+size), + * using an std::string breaks the JSON serialization, as a workaround this + * field is ignored by JSON serial operations */ + std::string mPgpIdSign; + + /// Unused RS_DEPRECATED std::list mRecognTags; - // Avatar - RsGxsImage mImage ; - rstime_t mLastUsageTS ; + RsGxsImage mImage; /// Avatar + rstime_t mLastUsageTS; - // Not Serialised - for GUI's benefit. - bool mPgpLinked; - bool mPgpKnown; - bool mIsAContact; // change that into flags one day - RsPgpId mPgpId; - GxsReputation mReputation; + bool mPgpLinked; + bool mPgpKnown; + bool mIsAContact; + RsPgpId mPgpId; + GxsReputation mReputation; /// @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j, diff --git a/libretroshare/src/rsitems/rsgxsiditems.h b/libretroshare/src/rsitems/rsgxsiditems.h index 440247403..e18ae9759 100644 --- a/libretroshare/src/rsitems/rsgxsiditems.h +++ b/libretroshare/src/rsitems/rsgxsiditems.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright (C) 2012 Robert Fernie * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,8 +21,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RS_GXS_IDENTITY_ITEMS_H -#define RS_GXS_IDENTITY_ITEMS_H +#pragma once #include @@ -57,15 +58,20 @@ public: bool toGxsIdGroup(RsGxsIdGroup &group, bool moveImage); Sha1CheckSum mPgpIdHash; - // Need a signature as proof - otherwise anyone could add others Hashes. - // This is a string, as the length is variable. - std::string mPgpIdSign; - // Recognition Strings. MAX# defined above. - std::list mRecognTags; + /** Need a signature as proof - otherwise anyone could add others Hashes. + * This is a string, as the length is variable. + * TODO: this should actually be a byte array (pointer+size), using an + * std::string breaks the JSON serialization. + * Be careful refactoring this as it may break retrocompatibility as this + * item is sent over the network */ + std::string mPgpIdSign; - // Avatar - RsTlvImage mImage ; + /// Unused + RS_DEPRECATED std::list mRecognTags; + + /// Avatar + RsTlvImage mImage; }; struct RsGxsIdLocalInfoItem : public RsGxsIdItem @@ -89,5 +95,3 @@ public: virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; }; - -#endif /* RS_GXS_IDENTITY_ITEMS_H */ diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d35d3afe0..7182b6a25 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -2,7 +2,8 @@ * libretroshare/src/services: p3idservice.cc * * * * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2017-2019 Gioacchino Mazzurco * + * Copyright (C) 2017-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -4960,7 +4961,21 @@ void RsGxsIdGroup::serial_process( { RS_SERIAL_PROCESS(mMeta); RS_SERIAL_PROCESS(mPgpIdHash); - RS_SERIAL_PROCESS(mPgpIdSign); + switch(j) + { + /* mPgpIdSign is declared as std::string but it is a disguised raw memory + * chunk, serializing it as plain string breaks JSON and eventually + * teminals if it get printed, it should have been declared as a raw memory + * chunk in the first place, but as of today just ignoring it in *JSON and + * PRINT operations seems a reasonable workaround */ + case RsGenericSerializer::SerializeJob::PRINT: // [[fallthrough]] + case RsGenericSerializer::SerializeJob::TO_JSON: // [[fallthrough]] + case RsGenericSerializer::SerializeJob::FROM_JSON: + break; + default: + RS_SERIAL_PROCESS(mPgpIdSign); + break; + } RS_SERIAL_PROCESS(mImage); RS_SERIAL_PROCESS(mLastUsageTS); RS_SERIAL_PROCESS(mPgpKnown); From f13b0cbe9f9104e4931d7784ee2e7b38807d3d28 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 25 Jun 2021 21:46:00 +0200 Subject: [PATCH 111/697] keeping Qt internally for a while and making RsTor Qt-free --- libretroshare/src/libretroshare.pro | 9 ++- libretroshare/src/retroshare/rsevents.h | 5 +- libretroshare/src/tor/AddOnionCommand.h | 17 ++--- libretroshare/src/tor/CryptoKey.cpp | 46 ++++++------ libretroshare/src/tor/CryptoKey.h | 15 ++-- libretroshare/src/tor/GetConfCommand.cpp | 25 +++---- libretroshare/src/tor/GetConfCommand.h | 16 +++-- libretroshare/src/tor/HiddenService.cpp | 2 +- libretroshare/src/tor/HiddenService.h | 47 ++++++------ libretroshare/src/tor/ProtocolInfoCommand.h | 31 ++++---- libretroshare/src/tor/SecureRNG.cpp | 31 ++++---- libretroshare/src/tor/SecureRNG.h | 10 +-- libretroshare/src/tor/StrUtil.cpp | 12 ++-- libretroshare/src/tor/StrUtil.h | 6 +- libretroshare/src/tor/TorControlCommand.h | 19 ++--- libretroshare/src/tor/TorManager.cpp | 49 +++++++++++-- libretroshare/src/tor/TorManager.h | 7 +- libretroshare/src/tor/TorTypes.h | 80 ++++++++++++++------- retroshare-gui/src/gui/GenCertDialog.cpp | 12 ++-- retroshare-gui/src/main.cpp | 2 +- 20 files changed, 258 insertions(+), 183 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5276bda9b..0d3889708 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -9,13 +9,18 @@ libretroshare_shared { } else { CONFIG += staticlib } -CONFIG -= qt +CONFIG += qt + +QT += network + TARGET = retroshare TARGET_PRL = libretroshare DESTDIR = lib !include("use_libretroshare.pri"):error("Including") +QMAKE_CXXFLAGS += -fPIC + # treat warnings as error for better removing #QMAKE_CFLAGS += -Werror #QMAKE_CXXFLAGS += -Werror @@ -720,6 +725,8 @@ SOURCES += rsitems/rsnxsitems.cc \ gxs/rsgxsrequesttypes.cc # Tor +HEADERS += retroshare/rstor.h + HEADERS += tor/AddOnionCommand.h \ tor/AuthenticateCommand.h \ tor/CryptoKey.h \ diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index ec2e7b97f..a1ea3b399 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -103,7 +103,10 @@ enum class RsEventType : uint32_t /// @see rspeers.h NETWORK = 16, - __MAX /// Used internally, keep last + /// @see rspeers.h + TOR_MANAGER = 17, + + __MAX /// Used internally, keep last }; enum class RsEventsErrorNum : int32_t diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index a51888b2f..7c0afaf5e 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -34,7 +34,9 @@ #define ADDONIONCOMMAND_H #include "TorControlCommand.h" -#include +#include +#include +#include namespace Tor { @@ -43,28 +45,27 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { -#ifdef NO_TOR_CONTROL_PROPERTIES - Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) + Q_OBJECT + Q_DISABLE_COPY(AddOnionCommand) + + Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) Q_PROPERTY(bool successful READ isSuccessful CONSTANT) -#endif public: AddOnionCommand(HiddenService *service); QByteArray build(); - std::string errorMessage() const { return m_errorMessage; } + QString errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -#ifdef NO_TOR_CONTROL_SIGNALS signals: void succeeded(); void failed(int code); -#endif protected: HiddenService *m_service; - std::string m_errorMessage; + QString m_errorMessage; virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index d5b66c988..9be9a6699 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -31,13 +31,13 @@ */ #include -#include #include "CryptoKey.h" #include "SecureRNG.h" #include "Useful.h" -#include "TorTypes.h" - +#include +#include +#include #include #include #include @@ -120,23 +120,17 @@ bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat for } #endif -bool CryptoKey::loadFromFile(const std::string &path) +bool CryptoKey::loadFromFile(const QString& path) { - FILE *f = fopen(path.c_str(),"r"); - - if(!f) + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { - std::cerr << "Failed to open Tor key file " << path << std::endl; + qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); return false; } - Tor::TorByteArray data ; - int c; - - while( EOF != (c=fgetc(f))) - data += (unsigned char)c; - - fclose(f); + QByteArray data = file.readAll(); + file.close(); if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) { @@ -152,14 +146,14 @@ bool CryptoKey::loadFromFile(const std::string &path) } std::cerr << "Have read the following key: " << std::endl; - std::cerr << data.toStdString() << std::endl; + std::cerr << QString(data).toStdString() << std::endl; key_data = data; return true; } -bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) +bool CryptoKey::loadFromTorMessage(const QByteArray& b) { // note: We should probably check the structure a bit more, for security. @@ -169,7 +163,7 @@ bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) std::cerr << " type: RSA-1024 (Tor v2)" << std::endl; else if(b.startsWith("ED25519-V3")) std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; - else if(b.indexOf(':') >= 0) + else if(b.indexOf(':')) { std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; return false; @@ -180,22 +174,22 @@ bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) } /* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) +QByteArray torControlHashedPassword(const QByteArray &password) { - Tor::TorByteArray salt = SecureRNG::random(8); + QByteArray salt = SecureRNG::random(8); if (salt.isNull()) - return Tor::TorByteArray(); + return QByteArray(); int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); SHA_CTX hash; SHA1_Init(&hash); - Tor::TorByteArray tmp = salt + password; + QByteArray tmp = salt + password; while (count) { - int c = std::min(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); + int c = qMin(count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); count -= c; } @@ -203,8 +197,8 @@ Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return Tor::TorByteArray("16:") + salt.toHex().toUpper() + Tor::TorByteArray("60") + - Tor::TorByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); + return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + + QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); } diff --git a/libretroshare/src/tor/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h index 57c22476f..c99703444 100644 --- a/libretroshare/src/tor/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -33,7 +33,9 @@ #ifndef CRYPTOKEY_H #define CRYPTOKEY_H -#include "tor/TorTypes.h" +#include +#include +#include class CryptoKey { @@ -55,13 +57,12 @@ public: bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); #endif - bool loadFromFile(const std::string& path); + bool loadFromFile(const QString &path); void clear(); - const Tor::TorByteArray& bytes() const { return key_data; } - bool loadFromTorMessage(const Tor::TorByteArray& b); - bool isLoaded() const { return !key_data.empty(); } - + const QByteArray bytes() const { return key_data; } + bool loadFromTorMessage(const QByteArray& b); + bool isLoaded() const { return !key_data.isNull(); } #ifdef TO_REMOVE bool isPrivate() const; @@ -100,6 +101,6 @@ private: #endif }; -Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password); +QByteArray torControlHashedPassword(const QByteArray &password); #endif // CRYPTOKEY_H diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index 7da0a46cc..933def562 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -30,11 +30,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include - -#include "TorTypes.h" #include "GetConfCommand.h" #include "StrUtil.h" +#include using namespace Tor; @@ -45,28 +43,27 @@ GetConfCommand::GetConfCommand(Type t) QByteArray GetConfCommand::build(const QByteArray &key) { - return build(std::list{key}); + return build(QList() << key); } -QByteArray GetConfCommand::build(const std::list &keys) +QByteArray GetConfCommand::build(const QList &keys) { QByteArray out; if (type == GetConf) { - out = QByteArray("GETCONF"); + out = "GETCONF"; } else if (type == GetInfo) { - out = QByteArray("GETINFO"); + out = "GETINFO"; } else { - throw std::runtime_error("Unsupported build type in GetConfCommand"); + Q_ASSERT(false); return out; } - for(const QByteArray& key: keys) - { - out += (' '); - out += key; + foreach (const QByteArray &key, keys) { + out.append(' '); + out.append(key); } - out += std::string("\r\n"); + out.append("\r\n"); return out; } @@ -77,7 +74,7 @@ void GetConfCommand::onReply(int statusCode, const QByteArray &data) return; int kep = data.indexOf('='); - std::string key = QString::fromLatin1(data.mid(0, kep)); + QString key = QString::fromLatin1(data.mid(0, kep)); QVariant value; if (kep >= 0) value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index 0289d5e40..0de97d1b7 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -34,16 +34,18 @@ #define GETCONFCOMMAND_H #include "TorControlCommand.h" -#include +#include +#include namespace Tor { class GetConfCommand : public TorControlCommand { -#ifdef NO_TOR_CONTROL_PROPERTIES + Q_OBJECT + Q_DISABLE_COPY(GetConfCommand) + Q_PROPERTY(QVariantMap results READ results CONSTANT) -#endif public: enum Type { @@ -55,10 +57,10 @@ public: GetConfCommand(Type type); QByteArray build(const QByteArray &key); - QByteArray build(const std::list &keys); + QByteArray build(const QList &keys); - const QVariantMap& results() const { return m_results; } - QVariant get(const QByteArray& key) const; + const QVariantMap &results() const { return m_results; } + QVariant get(const QByteArray &key) const; protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -67,7 +69,7 @@ protected: private: QVariantMap m_results; - std::string m_lastKey; + QString m_lastKey; }; } diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index 6b28ebd6f..b2b58626a 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -90,7 +90,7 @@ void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, q m_targets.append(t); } -void HiddenService::setServiceId(const TorByteArray &sid) +void HiddenService::setServiceId(const QByteArray& sid) { m_service_id = sid; m_hostname = sid + ".onion"; diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 19f1e561d..20fa1d851 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -33,25 +33,28 @@ #ifndef HIDDENSERVICE_H #define HIDDENSERVICE_H -#include -#include - -#include "tor/CryptoKey.h" -#include "tor/TorTypes.h" +#include +#include +#include +#include "CryptoKey.h" namespace Tor { + class TorSocket; -class HiddenService : public NonCopiable +class HiddenService : public QObject { + Q_OBJECT + Q_DISABLE_COPY(HiddenService) + friend class TorControlPrivate; public: struct Target { - TorHostAddress targetAddress; - unsigned short servicePort, targetPort; + QHostAddress targetAddress; + quint16 servicePort, targetPort; }; enum Status @@ -61,25 +64,24 @@ public: Online /* Published */ }; - HiddenService(); - HiddenService(const std::string& dataPath); - HiddenService(const CryptoKey& privateKey, const std::string& dataPath = std::string()); + HiddenService(QObject *parent = 0); + HiddenService(const QString &dataPath, QObject *parent = 0); + HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); Status status() const { return m_status; } - const std::string& hostname() const { return m_hostname; } - const std::string serviceId() const { return std::string(m_service_id.data()); } - const std::string& dataPath() const { return m_dataPath; } + const QString& hostname() const { return m_hostname; } + const QString serviceId() const { return QString(m_service_id); } + const QString& dataPath() const { return m_dataPath; } CryptoKey privateKey() { return m_privateKey; } void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const TorByteArray& sid); + void setServiceId(const QByteArray& sid); - const std::list& targets() const { return m_targets; } + const QList &targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(unsigned short servicePort, TorHostAddress targetAddress, unsigned short targetPort); + void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); -#ifdef NO_TOR_CONTROL_SIGNALS signals: void statusChanged(int newStatus, int oldStatus); void serviceOnline(); @@ -88,15 +90,14 @@ signals: private slots: void servicePublished(); -#endif private: - std::string m_dataPath; - std::list m_targets; - std::string m_hostname; + QString m_dataPath; + QList m_targets; + QString m_hostname; Status m_status; CryptoKey m_privateKey; - TorByteArray m_service_id; + QByteArray m_service_id; void loadPrivateKey(); void setStatus(Status newStatus); diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index 1ead20d29..7789cfefd 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -33,17 +33,8 @@ #ifndef PROTOCOLINFOCOMMAND_H #define PROTOCOLINFOCOMMAND_H -#include #include "TorControlCommand.h" - -enum class AuthMethods: uint8_t -{ - AuthUnknown = 0x0, - AuthNull = 0x1, - AuthHashedPassword = 0x2, - AuthCookie = 0x4 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(AuthMethods) +#include namespace Tor { @@ -52,13 +43,25 @@ class TorControl; class ProtocolInfoCommand : public TorControlCommand { + Q_OBJECT + Q_DISABLE_COPY(ProtocolInfoCommand) + public: + enum AuthMethod + { + AuthUnknown = 0, + AuthNull = 0x1, + AuthHashedPassword = 0x2, + AuthCookie = 0x4 + }; + Q_DECLARE_FLAGS(AuthMethods, AuthMethod) + ProtocolInfoCommand(TorControl *manager); QByteArray build(); AuthMethods authMethods() const { return m_authMethods; } - std::string torVersion() const { return m_torVersion; } - std::string cookieFile() const { return m_cookieFile; } + QString torVersion() const { return m_torVersion; } + QString cookieFile() const { return m_cookieFile; } protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -66,8 +69,8 @@ protected: private: TorControl *manager; AuthMethods m_authMethods; - std::string m_torVersion; - std::string m_cookieFile; + QString m_torVersion; + QString m_cookieFile; }; } diff --git a/libretroshare/src/tor/SecureRNG.cpp b/libretroshare/src/tor/SecureRNG.cpp index e07ef8e72..60cf3c048 100644 --- a/libretroshare/src/tor/SecureRNG.cpp +++ b/libretroshare/src/tor/SecureRNG.cpp @@ -31,12 +31,10 @@ */ #include "SecureRNG.h" - +#include #include #include #include -#include -#include #ifdef Q_OS_WIN #include @@ -84,7 +82,7 @@ bool SecureRNG::seed() #else if (!RAND_poll()) { - std::cerr << "OpenSSL RNG seed failed:" << ERR_get_error(); + qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); return false; } #endif @@ -96,16 +94,11 @@ bool SecureRNG::seed() return true; } -void SecureRNG::random(unsigned char *buf, int size) +void SecureRNG::random(char *buf, int size) { - int r = RAND_bytes(buf, size); - + int r = RAND_bytes(reinterpret_cast(buf), size); if (r <= 0) - { - std::ostringstream s; - s << "RNG failed: " << ERR_get_error() ; - throw std::runtime_error(s.str()); - } + qFatal("RNG failed: %lu", ERR_get_error()); } QByteArray SecureRNG::random(int size) @@ -118,7 +111,7 @@ QByteArray SecureRNG::random(int size) QByteArray SecureRNG::randomPrintable(int length) { QByteArray re(length, 0); - for (uint32_t i = 0; i < re.size(); i++) + for (int i = 0; i < re.size(); i++) re[i] = randomInt(95) + 32; return re; } @@ -130,24 +123,24 @@ unsigned SecureRNG::randomInt(unsigned max) for (;;) { - random(reinterpret_cast(&value), sizeof(value)); + random(reinterpret_cast(&value), sizeof(value)); if (value < cutoff) return value % max; } } #ifndef UINT64_MAX -#define UINT64_MAX ((uint64_t)-1) +#define UINT64_MAX ((quint64)-1) #endif -uint64_t SecureRNG::randomInt64(uint64_t max) +quint64 SecureRNG::randomInt64(quint64 max) { - uint64_t cutoff = UINT64_MAX - (UINT64_MAX % max); - uint64_t value = 0; + quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); + quint64 value = 0; for (;;) { - random(reinterpret_cast(value), sizeof(value)); + random(reinterpret_cast(value), sizeof(value)); if (value < cutoff) return value % max; } diff --git a/libretroshare/src/tor/SecureRNG.h b/libretroshare/src/tor/SecureRNG.h index cce43cec5..f3b2a4b64 100644 --- a/libretroshare/src/tor/SecureRNG.h +++ b/libretroshare/src/tor/SecureRNG.h @@ -33,19 +33,19 @@ #ifndef SECURERNG_H #define SECURERNG_H -#include "TorTypes.h" +#include class SecureRNG { public: static bool seed(); - static void random(unsigned char *buf, int size); - static Tor::TorByteArray random(int size); + static void random(char *buf, int size); + static QByteArray random(int size); - static Tor::TorByteArray randomPrintable(int length); + static QByteArray randomPrintable(int length); static unsigned randomInt(unsigned max); - static uint64_t randomInt64(uint64_t max); + static quint64 randomInt64(quint64 max); }; #endif // SECURERNG_H diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index b78b50ae5..81de151b0 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -32,14 +32,14 @@ #include "StrUtil.h" -QByteArray quotedString(const QByteArray& string) +QByteArray quotedString(const QByteArray &string) { QByteArray out; out.reserve(string.size() * 2); - out += '"'; + out.append('"'); - for (uint32_t i = 0; i < string.size(); ++i) + for (int i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -67,7 +67,7 @@ QByteArray unquotedString(const QByteArray &string) QByteArray out; out.reserve(string.size() - 2); - for (uint32_t i = 1; i < string.size(); ++i) + for (int i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -85,9 +85,9 @@ QByteArray unquotedString(const QByteArray &string) return out; } -std::list splitQuotedStrings(const QByteArray &input, char separator) +QList splitQuotedStrings(const QByteArray &input, char separator) { - std::list out; + QList out; bool inquote = false; int start = 0; diff --git a/libretroshare/src/tor/StrUtil.h b/libretroshare/src/tor/StrUtil.h index ba9b5ac3a..c86d2c6ec 100644 --- a/libretroshare/src/tor/StrUtil.h +++ b/libretroshare/src/tor/StrUtil.h @@ -33,14 +33,14 @@ #ifndef STRINGUTIL_H #define STRINGUTIL_H -#include "TorTypes.h" -#include +#include +#include QByteArray quotedString(const QByteArray &string); /* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ QByteArray unquotedString(const QByteArray &string); -std::list splitQuotedStrings(const QByteArray &input, char separator); +QList splitQuotedStrings(const QByteArray &input, char separator); #endif // STRINGUTIL_H diff --git a/libretroshare/src/tor/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h index 6c8693682..894381054 100644 --- a/libretroshare/src/tor/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -33,31 +33,32 @@ #ifndef TORCONTROLCOMMAND_H #define TORCONTROLCOMMAND_H -#include -#include "tor/TorTypes.h" +#include +#include namespace Tor { -class TorControlCommand : public NonCopiable + +class TorControlCommand : public QObject { + Q_OBJECT + Q_DISABLE_COPY(TorControlCommand) + friend class TorControlSocket; public: TorControlCommand(); - virtual ~TorControlCommand() {} int statusCode() const { return m_finalStatus; } -#ifdef NO_TOR_CONTROL_SIGNALS signals: - void replyLine(int statusCode, const TorByteArray& data); + void replyLine(int statusCode, const QByteArray &data); void finished(); -#endif protected: - virtual void onReply(int statusCode, const TorByteArray& data); + virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); - virtual void onDataLine(const TorByteArray& data); + virtual void onDataLine(const QByteArray &data); virtual void onDataFinished(); private: diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 9f31777e6..a9daa8986 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -118,11 +118,6 @@ TorProcess *TorManager::process() return d->process; } -bool TorManager::isTorAvailable() -{ - return !instance()->d->torExecutablePath().isNull(); -} - QString TorManager::torDataDirectory() const { return d->dataDir; @@ -524,3 +519,47 @@ void TorManagerPrivate::setError(const QString &message) #include "TorManager.moc" +bool RsTor::isTorAvailable() +{ + return !instance()->d->torExecutablePath().isNull(); +} + +bool RsTor::getHiddenServiceInfo(std::string& service_id, + std::string& service_onion_address, + uint16_t& service_port, + std::string& service_target_address, + uint16_t& target_port) +{ + QString sid; + QString soa; + QHostAddress sta; + + if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port)) + return false; + + service_id = sid.toStdString(); + service_onion_address = soa.toStdString(); + service_target_address = sta.toString().toStdString(); + + return true; +} + +std::list RsTor::logMessages() +{ + QStringList qs = instance()->logMessages(); + + std::list s; + for(auto& ss:qs) + s.push_back(ss.toStdString()); + + return s; +} + +std::string RsTor::socksAddress() +{ + return instance()->control()->socksAddress().toString().toStdString(); +} +uint16_t RsTor::socksPort() +{ + return instance()->control()->socksPort(); +} diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e9acc1208..9d3dd388d 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -35,6 +35,8 @@ #ifndef TORMANAGER_H #define TORMANAGER_H +#include "retroshare/rstor.h" + #include #include #include @@ -48,7 +50,8 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject + +class TorManager : public QObject, public RsTor { Q_OBJECT @@ -61,7 +64,6 @@ class TorManager : public QObject Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) public: - static bool isTorAvailable() ; static TorManager *instance(); TorProcess *process(); @@ -103,6 +105,7 @@ signals: private: explicit TorManager(QObject *parent = 0); TorManagerPrivate *d; + friend class RsTor; }; } diff --git a/libretroshare/src/tor/TorTypes.h b/libretroshare/src/tor/TorTypes.h index a3ebb523a..393e6a849 100644 --- a/libretroshare/src/tor/TorTypes.h +++ b/libretroshare/src/tor/TorTypes.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include namespace Tor { @@ -18,7 +20,13 @@ private: class TorByteArray: public std::vector { public: - TorByteArray(const std::string& s = std::string()) + TorByteArray(const unsigned char *data,uint32_t len) + { + clear(); + for(uint32_t i=0;i size()) + if(s.size() > size()) return false; - for(uint32_t i=0;i size()) - return false; - - for(uint32_t i=0;i size()) return false; + + for(uint32_t i=0;i size()) + throw std::runtime_error("Length out of range in TorByteArray::mid()"); + + TorByteArray b; + for(uint32_t i=0;i<(uint32_t)length;++i) + b.push_back(data()[i+start]); + + return b; + } + + static TorByteArray number(uint64_t n) + { + std::ostringstream o; + o << n ; + return TorByteArray(o.str()); + } }; typedef std::string TorHostAddress; } -typedef Tor::TorByteArray QByteArray; // to be removed diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e106146fb..7c89d9834 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -33,15 +33,15 @@ #include #include "gui/settings/rsharesettings.h" -#include "TorControl/TorManager.h" #include "util/misc.h" #include "gui/common/FilesDefs.h" -#include -#include -#include -#include -#include +#include "retroshare/rstor.h" +#include "retroshare/rsidentity.h" +#include "retroshare/rsinit.h" +#include "retroshare/rsnotify.h" +#include "rsserver/rsaccounts.h" +#include "util/rsrandom.h" #include #include diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index cfb9932ca..404fa6466 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -66,7 +66,7 @@ CrashStackTrace gCrashStackTrace; # include "gui/settings/JsonApiPage.h" #endif // RS_JSONAPI -#include "TorControl/TorManager.h" +#include "retroshare/rstor.h" #include "TorControl/TorControlWindow.h" #include "retroshare/rsidentity.h" From 43e8ed3d98c88d9cf65a26b56671814dd4573428 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 17:12:17 +0200 Subject: [PATCH 112/697] fixed compilation --- libretroshare/src/tor/TorManager.cpp | 107 ++++++++++++++++++ retroshare-gui/src/gui/GenCertDialog.cpp | 2 +- .../src/gui/statusbar/torstatus.cpp | 27 +++-- retroshare-gui/src/main.cpp | 44 ++++--- 4 files changed, 142 insertions(+), 38 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index a9daa8986..8ba1eb456 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -563,3 +563,110 @@ uint16_t RsTor::socksPort() { return instance()->control()->socksPort(); } + +RsTorStatus RsTor::torStatus() +{ + TorControl::TorStatus ts = instance()->control()->torStatus(); + + switch(ts) + { + case TorControl::TorOffline: return RsTorStatus::OFFLINE; + case TorControl::TorReady: return RsTorStatus::READY; + + default: + case TorControl::TorUnknown: return RsTorStatus::UNKNOWN; + } +} + +RsTorControlStatus RsTor::torControlStatus() +{ + TorControl::Status ts = instance()->control()->status(); + + switch(ts) + { + default: + case Tor::TorControl::Error : return RsTorControlStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorControlStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorControlStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorControlStatus::CONNECTING; + case Tor::TorControl::Connected : return RsTorControlStatus::CONNECTED; + } +} + +bool RsTor::setupHiddenService() +{ + return instance()->setupHiddenService(); +} + +RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) +{ + service_id.clear(); + auto list = instance()->control()->hiddenServices(); + + if(list.empty()) + return RsTorHiddenServiceStatus::NOT_CREATRED; + + service_id = (*list.begin())->serviceId().toStdString(); + + switch((*list.begin())->status()) + { + default: + case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATRED; + case Tor::HiddenService::Offline : return RsTorHiddenServiceStatus::OFFLINE; + case Tor::HiddenService::Online : return RsTorHiddenServiceStatus::ONLINE; + } +} + +std::map RsTor::bootstrapStatus() +{ + QVariantMap m = instance()->control()->bootstrapStatus(); + std::map res; + + for(auto it(m.begin());it!=m.end();++it) + res.insert(std::make_pair(it.key().toStdString(),it.value().toString().toStdString())); + + return res; +} + +bool RsTor::hasError() +{ + return instance()->hasError(); +} +std::string RsTor::errorMessage() +{ + return instance()->errorMessage().toStdString(); +} + +void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port) +{ + QHostAddress qserver_address; + instance()->getProxyServerInfo(qserver_address,server_port); + + server_address = qserver_address.toString().toStdString(); +} + +bool RsTor::start() +{ + return instance()->start(); +} + +void RsTor::setTorDataDirectory(const std::string& dir) +{ + instance()->setTorDataDirectory(QString::fromStdString(dir)); +} +void RsTor::setHiddenServiceDirectory(const std::string& dir) +{ + instance()->setHiddenServiceDirectory(QString::fromStdString(dir)); +} + +TorManager *RsTor::instance() +{ + assert(getpid() == gettid()); // make sure we're not in a thread + + static TorManager *rsTor = nullptr; + + if(rsTor == nullptr) + rsTor = new TorManager; + + return rsTor; +} diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index 7c89d9834..f9511a46c 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -528,7 +528,7 @@ void GenCertDialog::genPerson() bool isHiddenLoc = (ui.nodeType_CB->currentIndex()>0); bool isAutoTor = (ui.nodeType_CB->currentIndex()==1); - if(isAutoTor && !Tor::TorManager::isTorAvailable()) + if(isAutoTor && !RsTor::isTorAvailable()) { QMessageBox::critical(this,tr("Tor is not available"),tr("No Tor executable has been found on your system. You need to install Tor before creating a hidden identity.")) ; return ; diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index f046f09cc..cac12f3d8 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -28,11 +28,10 @@ #include "retroshare/rsconfig.h" #include "retroshare/rsinit.h" #include "retroshare/rspeers.h" +#include "retroshare/rstor.h" #include #include "util/misc.h" -#include "TorControl/TorManager.h" -#include "TorControl/TorControl.h" #include "gui/common/FilesDefs.h" #include @@ -92,8 +91,8 @@ void TorStatus::getTorStatus() if(RsAccounts::isTorAuto()) { // get Tor status - int tor_control_status = Tor::TorManager::instance()->control()->status(); - int torstatus = Tor::TorManager::instance()->control()->torStatus(); + RsTorControlStatus tor_control_status = RsTor::torControlStatus(); + RsTorStatus torstatus = RsTor::torStatus(); QString tor_control_status_str,torstatus_str ; bool tor_control_ok ; @@ -101,30 +100,30 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case Tor::TorControl::Error : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case Tor::TorControl::NotConnected: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case Tor::TorControl::Connecting: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case Tor::TorControl::Authenticating: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case Tor::TorControl::Connected: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorControlStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorControlStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorControlStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorControlStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorControlStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; } switch(torstatus) { default: - case Tor::TorControl::TorUnknown: torstatus_str = "Unknown" ; break ; - case Tor::TorControl::TorOffline: torstatus_str = "Tor offline" ; break ; - case Tor::TorControl::TorReady: torstatus_str = "Tor ready" ; break ; + case RsTorStatus::UNKNOWN: torstatus_str = "Unknown" ; break ; + case RsTorStatus::OFFLINE: torstatus_str = "Tor offline" ; break ; + case RsTorStatus::READY: torstatus_str = "Tor ready" ; break ; } #define MIN_RS_NET_SIZE 10 - if(torstatus == Tor::TorControl::TorOffline || !online || !tor_control_ok) + if(torstatus == RsTorStatus::OFFLINE || !online || !tor_control_ok) { // RED - some issue. torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-stopping.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is currently offline")); } - else if(torstatus == Tor::TorControl::TorReady && online && tor_control_ok) + else if(torstatus == RsTorStatus::READY && online && tor_control_ok) { torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-on.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is OK")); diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 404fa6466..104f525a8 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -399,24 +399,23 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); { // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service - QString tor_hidden_service_dir = QString::fromStdString(RsAccounts::AccountDirectory()) + QString("/hidden_service/") ; + std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->setTorDataDirectory(Rshare::dataDirectory() + QString("/tor/")); - torManager->setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run + RsTor::setTorDataDirectory(Rshare::dataDirectory().toStdString() + "/tor/"); + RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run - RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir.toUtf8())) ; + RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; - torManager->setupHiddenService(); + RsTor::setupHiddenService(); - if(! torManager->start() || torManager->hasError()) + if(! RsTor::start() || RsTor::hasError()) { - QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+torManager->errorMessage()) ; + QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+QString::fromStdString(RsTor::errorMessage())) ; return 1 ; } { - TorControlDialog tcd(torManager) ; + TorControlDialog tcd; QString error_msg ; tcd.show(); @@ -460,30 +459,29 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); { // Tor works with viable hidden service. Let's use it! - QString service_id ; - QString onion_address ; + std::string service_id ; + std::string onion_address ; uint16_t service_port ; uint16_t service_target_port ; uint16_t proxy_server_port ; - QHostAddress service_target_address ; - QHostAddress proxy_server_address ; + std::string service_target_address ; + std::string proxy_server_address ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); - torManager->getProxyServerInfo(proxy_server_address,proxy_server_port) ; + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; std::cerr << "Got hidden service info: " << std::endl; - std::cerr << " onion address : " << onion_address.toStdString() << std::endl; - std::cerr << " service_id : " << service_id.toStdString() << std::endl; + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; std::cerr << " service port : " << service_port << std::endl; std::cerr << " target port : " << service_target_port << std::endl; - std::cerr << " target address : " << service_target_address.toString().toStdString() << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; - std::cerr << "Setting proxy server to " << service_target_address.toString().toStdString() << ":" << service_target_port << std::endl; + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; - rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address.toString().toStdString(), service_target_port); - rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address.toStdString(), service_port); - rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address.toString().toStdString(),proxy_server_port) ; + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; } Rshare::initPlugins(); From 607c1896e56d02182c565e7012d5bb5b8f4a3895 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 18:52:48 +0200 Subject: [PATCH 113/697] progress in event handling in RsTor --- libretroshare/src/tor/TorControl.cpp | 43 ++++++++++++++++++- libretroshare/src/tor/TorManager.cpp | 12 +++--- .../src/gui/statusbar/torstatus.cpp | 12 +++--- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 29979e2b3..35cc96664 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -32,6 +32,7 @@ #include +#include "retroshare/rstor.h" #include "TorControl.h" #include "TorControlSocket.h" #include "HiddenService.h" @@ -139,6 +140,29 @@ QNetworkProxy TorControl::connectionProxy() return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); } +static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) +{ + switch(t) + { + default: + case TorControl::Error: return RsTorConnectivityStatus::ERROR; + case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; + case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case TorControl::Connected: return RsTorConnectivityStatus::CONNECTED; + } +} +static RsTorStatus torStatus(Tor::TorControl::TorStatus t) +{ + switch(t) + { + default: + case TorControl::TorUnknown: return RsTorStatus::UNKNOWN; + case TorControl::TorOffline: return RsTorStatus::OFFLINE; + case TorControl::TorReady: return RsTorStatus::READY; + } +} + void TorControlPrivate::setStatus(TorControl::Status n) { if (n == status) @@ -150,12 +174,23 @@ void TorControlPrivate::setStatus(TorControl::Status n) if (old == TorControl::Error) errorMessage.clear(); + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONTROL_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(status); + + rsEvents->postEvent(ev); + } +#ifdef TO_REMOVE emit q->statusChanged(status, old); if (status == TorControl::Connected && old < TorControl::Connected) emit q->connected(); else if (status < TorControl::Connected && old >= TorControl::Connected) emit q->disconnected(); +#endif } void TorControlPrivate::setTorStatus(TorControl::TorStatus n) @@ -617,7 +652,13 @@ void TorControlPrivate::updateBootstrap(const QList &data) //torCtrlDebug() << bootstrapStatus << std::endl; - emit q->bootstrapStatusChanged(); + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; + rsEvents->postEvent(ev); + } } QObject *TorControl::getConfiguration(const QString &options) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 8ba1eb456..d167c9cba 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -578,18 +578,18 @@ RsTorStatus RsTor::torStatus() } } -RsTorControlStatus RsTor::torControlStatus() +RsTorConnectivityStatus RsTor::torConnectivityStatus() { TorControl::Status ts = instance()->control()->status(); switch(ts) { default: - case Tor::TorControl::Error : return RsTorControlStatus::ERROR; - case Tor::TorControl::NotConnected : return RsTorControlStatus::NOT_CONNECTED; - case Tor::TorControl::Authenticating: return RsTorControlStatus::AUTHENTICATING; - case Tor::TorControl::Connecting: return RsTorControlStatus::CONNECTING; - case Tor::TorControl::Connected : return RsTorControlStatus::CONNECTED; + case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case Tor::TorControl::Connected : return RsTorConnectivityStatus::CONNECTED; } } diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index cac12f3d8..319d8da3d 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -91,7 +91,7 @@ void TorStatus::getTorStatus() if(RsAccounts::isTorAuto()) { // get Tor status - RsTorControlStatus tor_control_status = RsTor::torControlStatus(); + RsTorConnectivityStatus tor_control_status = RsTor::torConnectivityStatus(); RsTorStatus torstatus = RsTor::torStatus(); QString tor_control_status_str,torstatus_str ; @@ -100,11 +100,11 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case RsTorControlStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case RsTorControlStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case RsTorControlStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case RsTorControlStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorControlStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorConnectivityStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; } switch(torstatus) From a23ad41b112665fcb5f5a0e5ef5e157afb37edba Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 23:13:17 +0200 Subject: [PATCH 114/697] fixed event handling in Tor bootstrap process --- libretroshare/src/tor/TorControl.cpp | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 35cc96664..2b0040252 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -178,10 +178,10 @@ void TorControlPrivate::setStatus(TorControl::Status n) { auto ev = std::make_shared(); - ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONTROL_STATUS_CHANGED; + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; ev->mTorConnectivityStatus = torConnectivityStatus(status); - rsEvents->postEvent(ev); + rsEvents->sendEvent(ev); } #ifdef TO_REMOVE emit q->statusChanged(status, old); @@ -200,9 +200,19 @@ void TorControlPrivate::setTorStatus(TorControl::TorStatus n) TorControl::TorStatus old = torStatus; torStatus = n; +#ifdef TO_REMOVE emit q->torStatusChanged(torStatus, old); emit q->connectivityChanged(); +#endif + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorStatus = ::torStatus(torStatus); + rsEvents->sendEvent(ev); + } if (torStatus == TorControl::TorReady && socksAddress.isNull()) { // Request info again to read the SOCKS port getTorInfo(); @@ -460,7 +470,14 @@ void TorControlPrivate::getTorInfo() torCtrlDebug() << "torctrl: Using manually specified SOCKS connection settings"; socksAddress = forceAddress; socksPort = port; - emit q->connectivityChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + rsEvents->sendEvent(ev); + } } else keys << QByteArray("net/listeners/socks"); @@ -496,7 +513,14 @@ void TorControlPrivate::getTorInfoReply() * is reached. */ if (!socksAddress.isNull()) { torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress.toString().toStdString() << ":" << socksPort << std::endl; - emit q->connectivityChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + rsEvents->sendEvent(ev); + } } if (command->get(QByteArray("status/circuit-established")).toInt() == 1) { @@ -657,7 +681,7 @@ void TorControlPrivate::updateBootstrap(const QList &data) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; - rsEvents->postEvent(ev); + rsEvents->sendEvent(ev); } } From 139b22b41a561e9c6e50bede56d3aa367b6f340b Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 27 Jun 2021 18:14:22 +0200 Subject: [PATCH 115/697] added rstor.h file --- libretroshare/src/retroshare/rstor.h | 168 +++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 libretroshare/src/retroshare/rstor.h diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h new file mode 100644 index 000000000..7538671b1 --- /dev/null +++ b/libretroshare/src/retroshare/rstor.h @@ -0,0 +1,168 @@ +#pragma once + +// This code stands as an interface for the automatic configuration +// of Tor hidden services to be used by retroshare. +// +// The correct way to use it is to: +// +// 1 - properly set data and hidden service directories. This allowd the TorManager +// to save its keys for the hidden service, or to load one that has previously been created +// +// 2 - call setupHiddenService(). This creates/loads the hidden service. +// +// 3 - call RsTor::start() +// +// 4 - loop/wait until RsTor::getHiddenServiceStatus(service_id) +// returns RsTorHiddenServiceStatus::ONLINE +// +// 5 - call RsTor::getHiddenserviceInfo to properly setup RS internal ports and addresses: +// +// RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); +// RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; +// +// rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); +// rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); +// rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; + +#include "retroshare/rsevents.h" + +namespace Tor { + class TorManager; +} + +enum class RsTorManagerEventCode: uint8_t +{ + UNKNOWN = 0x00, + TOR_STATUS_CHANGED = 0x01, + BOOTSTRAP_STATUS_CHANGED = 0x02, + TOR_CONNECTIVITY_CHANGED = 0x03, +}; + +// Status of the Tor hidden service setup/loaded by RS + +enum class RsTorHiddenServiceStatus: uint8_t { + ERROR = 0x00, + NOT_CREATED = 0x01, + OFFLINE = 0x02, + ONLINE = 0x03 +}; + +// Status of the connection/authentication between RS and the Tor service + +enum class RsTorConnectivityStatus: uint8_t { + ERROR = 0x00, + NOT_CONNECTED = 0x01, + CONNECTING = 0x02, + AUTHENTICATING = 0x03, + CONNECTED = 0x04 +}; + +// Status of the Tor service with which RS is talking. + +enum class RsTorStatus: uint8_t { + UNKNOWN = 0x00, + OFFLINE = 0x01, + READY = 0x02 +}; + +struct RsTorManagerEvent: public RsEvent +{ + RsTorManagerEvent(): RsEvent(RsEventType::TOR_MANAGER), + mTorManagerEventType(RsTorManagerEventCode::UNKNOWN) + {} + + RsTorManagerEventCode mTorManagerEventType; + + RsTorConnectivityStatus mTorConnectivityStatus; + RsTorStatus mTorStatus; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mTorManagerEventType); + RS_SERIAL_PROCESS(mTorConnectivityStatus); + RS_SERIAL_PROCESS(mTorStatus); + } + + ~RsTorManagerEvent() = default; +}; + +class RsTor +{ +public: + /*! + * \brief isTorAvailable + * \return true if a Tor executble has been found. False otherwise. + */ + static bool isTorAvailable() ; + + /*! + * \brief torStatus + * \return Status of the Tor service used by RS + */ + static RsTorStatus torStatus() ; + + /*! + * \brief torConnectivityStatus + * \return Status of the connectivity/authentication between RS and Tor + */ + static RsTorConnectivityStatus torConnectivityStatus() ; + + static void setTorDataDirectory(const std::string& dir); + static void setHiddenServiceDirectory(const std::string& dir); + + static bool setupHiddenService(); + + /*! + * \brief getProxyServerInfo + * \param server_address Address of the proxy used by RS to send data in the Tor network. Usually 127.0.0.1 + * \param server_port Port of the proxy used by RS to send data in the Tor network. Usually 9050. + */ + static void getProxyServerInfo(std::string& server_address, uint16_t& server_port); + + /*! + * \brief getHiddenServiceStatus + * \param service_id onion address of the hidden service (if the service is OFFLINE or ONLINE) + * \return Status of the created/loaded hidden service. + */ + static RsTorHiddenServiceStatus getHiddenServiceStatus(std::string& service_id); + + /*! + * \brief start + * Launches the Tor management threads. + */ + static bool start(); + + /*! + * \brief getHiddenServiceInfo + * Gets information about the hidden service setup by RS to run. + * \param service_id + * \param service_onion_address + * \param service_port + * \param service_target_address + * \param target_port + * \return + */ + static bool getHiddenServiceInfo(std::string& service_id, + std::string& service_onion_address, + uint16_t& service_port, + std::string& service_target_address, + uint16_t& target_port); + + /*! + * \brief bootstrapStatus + * \return Log messages of the Tor bootstrapping status. + */ + static std::map bootstrapStatus(); + static std::list logMessages(); + + static std::string socksAddress(); + static uint16_t socksPort(); + + static bool hasError(); + static std::string errorMessage(); + +private: + static Tor::TorManager *instance(); +}; From da86da29ff12cee1e8ec2dd4105d46468d55b70e Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 29 Jun 2021 00:23:32 +0200 Subject: [PATCH 116/697] attempt at fixing tor bootstrap. Not working yet --- libretroshare/src/retroshare/rsinit.h | 2 + libretroshare/src/rsserver/rsinit.cc | 51 +++++++++++++++++++ libretroshare/src/tor/TorManager.cpp | 4 +- retroshare-service/src/retroshare-service.cc | 37 +++++++++++++- retroshare-service/src/retroshare-service.pro | 4 +- 5 files changed, 94 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/retroshare/rsinit.h b/libretroshare/src/retroshare/rsinit.h index 73fea2684..11eb54466 100644 --- a/libretroshare/src/retroshare/rsinit.h +++ b/libretroshare/src/retroshare/rsinit.h @@ -159,6 +159,7 @@ public: ERR_ALREADY_RUNNING, /// Another istance is running already ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running? ERR_NO_AVAILABLE_ACCOUNT, /// Used in retroshare-service -U list when no account is available + ERR_CANNOT_CONFIGURE_TOR, /// cannot start/configure Tor for an auto-tor node ERR_UNKNOWN /// Unkown error, maybe password is wrong? }; @@ -184,6 +185,7 @@ public: static bool isPortable(); static bool isWindowsXP(); static bool collectEntropy(uint32_t bytes) ; + static bool startAutoTor(); /*! * \brief lockFilePath diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..ff411ac2e 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -42,6 +42,7 @@ #include "util/folderiterator.h" #include "util/rsstring.h" #include "retroshare/rsinit.h" +#include "retroshare/rstor.h" #include "retroshare/rsnotify.h" #include "retroshare/rsiface.h" #include "plugins/pluginmanager.h" @@ -1923,6 +1924,46 @@ int RsServer::StartupRetroShare() return 1; } +bool RsInit::startAutoTor() +{ + std::cerr << "(II) node is an automated Tor node => launching Tor auto-configuration." << std::endl; + // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service + + std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; + + RsTor::setTorDataDirectory(RsAccounts::ConfigDirectory() + "/tor/"); + RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run + + RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; + + if(! RsTor::start() || RsTor::hasError()) + { + std::cerr << "(EE) Tor cannot be started on your system: "+RsTor::errorMessage() << std::endl ; + return false ; + } + std::cerr << "(II) Tor has been started." << std::endl; + + // now start/create the hidden service as needed. + + std::string service_id; + RsTor::setupHiddenService(); + + while(RsTor::torStatus() != RsTorStatus::READY && RsTor::getHiddenServiceStatus(service_id) != RsTorHiddenServiceStatus::ONLINE) // runs until some status is reached: either tor works, or it fails. + { + rstime::rs_usleep(0.5*1000*1000) ; + + std::cerr << "(II) Hidden service ID: " << service_id << ", status: " << (int)RsTor::getHiddenServiceStatus(service_id) << std::endl; + if(RsTor::hasError()) + { + std::string error_msg = RsTor::errorMessage(); + + std::cerr << "(EE) Tor hidden service cannot be started: " << error_msg << std::endl; + return false; + } + } + return true; +} + RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(const RsPeerId& account, const std::string& password) { if(isLoggedIn()) return RsInit::ERR_ALREADY_RUNNING; @@ -1942,6 +1983,16 @@ RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(const RsPeerId& accoun rsNotify->setDisableAskPassword(false) ; rsNotify->clearPgpPassphrase() ; + bool is_hidden_node = false; + bool is_auto_tor = false ; + bool is_first_time = false ; + + RsAccounts::getCurrentAccountOptions(is_hidden_node,is_auto_tor,is_first_time); + + if(is_auto_tor) + if(!RsInit::startAutoTor()) + return RsInit::ERR_CANNOT_CONFIGURE_TOR; + if(ret == RsInit::OK && RsControl::instance()->StartupRetroShare() == 1) return RsInit::OK; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index d167c9cba..f21c12709 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -604,14 +604,14 @@ RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) auto list = instance()->control()->hiddenServices(); if(list.empty()) - return RsTorHiddenServiceStatus::NOT_CREATRED; + return RsTorHiddenServiceStatus::NOT_CREATED; service_id = (*list.begin())->serviceId().toStdString(); switch((*list.begin())->status()) { default: - case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATRED; + case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATED; case Tor::HiddenService::Offline : return RsTorHiddenServiceStatus::OFFLINE; case Tor::HiddenService::Online : return RsTorHiddenServiceStatus::ONLINE; } diff --git a/retroshare-service/src/retroshare-service.cc b/retroshare-service/src/retroshare-service.cc index e80d468e1..898d71067 100644 --- a/retroshare-service/src/retroshare-service.cc +++ b/retroshare-service/src/retroshare-service.cc @@ -22,7 +22,10 @@ #include "util/stacktrace.h" #include "util/argstream.h" #include "util/rskbdinput.h" +#include "util/rsdir.h" #include "retroshare/rsinit.h" +#include "retroshare/rstor.h" +#include "retroshare/rspeers.h" #ifdef RS_JSONAPI #include "retroshare/rsjsonapi.h" @@ -47,6 +50,7 @@ static CrashStackTrace gCrashStackTrace; # include "util/androiddebug.h" #endif // def __ANDROID__ +#include #include "retroshare/rsinit.h" #include "retroshare/rsiface.h" @@ -95,7 +99,9 @@ int main(int argc, char* argv[]) #ifdef __ANDROID__ AndroidStdIOCatcher dbg; (void) dbg; QAndroidService app(argc, argv); -#endif // def __ANDROID__ +#else // def __ANDROID__ + QCoreApplication app(argc,argv); // needed for TorManaer (that uses QDir). To be removed when TorManager doesn't use Qt anymore. +#endif signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); @@ -311,6 +317,35 @@ int main(int argc, char* argv[]) << std::endl; return -result; } + + if(RsAccounts::isTorAuto()) + { + + std::cerr << "(II) Hidden service is ready:" << std::endl; + + std::string service_id ; + std::string onion_address ; + uint16_t service_port ; + uint16_t service_target_port ; + uint16_t proxy_server_port ; + std::string service_target_address ; + std::string proxy_server_address ; + + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; + + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; + std::cerr << " service port : " << service_port << std::endl; + std::cerr << " target port : " << service_target_port << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; + + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; + + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; + } } #endif // def RS_SERVICE_TERMINAL_LOGIN diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro index cbd1b9d13..8c5259a7b 100644 --- a/retroshare-service/src/retroshare-service.pro +++ b/retroshare-service/src/retroshare-service.pro @@ -22,7 +22,9 @@ TARGET = retroshare-service -QT += core +CONFIG += qt + +QT += core network QT -= gui !include("../../libretroshare/src/use_libretroshare.pri"):error("Including") From ae79261cbce5156f2ffc95b8e495a0c814a2ef48 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 2 Jul 2021 00:11:10 +0200 Subject: [PATCH 117/697] fixed bootstrapping of Tor in retroshare-service --- libretroshare/src/rsserver/rsinit.cc | 5 +++++ libretroshare/src/tor/TorManager.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ff411ac2e..6373e0d3c 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -35,6 +35,8 @@ # include // for QString::fromStdString(...) #endif +#include + #include "util/argstream.h" #include "util/rsdebug.h" #include "util/rsdir.h" @@ -1960,6 +1962,9 @@ bool RsInit::startAutoTor() std::cerr << "(EE) Tor hidden service cannot be started: " << error_msg << std::endl; return false; } + // process Qt event loop to deal with messages of online/offline info + + QCoreApplication::processEvents(); } return true; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index f21c12709..fc81d943e 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -357,6 +357,11 @@ bool TorManager::start() emit configurationNeededChanged(); } + std::cerr << "Starting Tor process:" << std::endl; + std::cerr << " Tor executable path: " << executable.toStdString() << std::endl; + std::cerr << " Tor data directory : " << d->dataDir.toStdString() << std::endl; + std::cerr << " Tor default torrc : " << defaultTorrc.toStdString() << std::endl; + d->process->setExecutable(executable); d->process->setDataDir(d->dataDir); d->process->setDefaultTorrc(defaultTorrc); From a43a158750210c259108661ca686e3aad3dbcc5b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 00:13:01 +0200 Subject: [PATCH 118/697] added back missing files --- .../src/TorControl/TorControlWindow.cpp | 252 ++++++++++++++++++ .../src/TorControl/TorControlWindow.h | 50 ++++ .../src/TorControl/TorControlWindow.ui | 134 ++++++++++ 3 files changed, 436 insertions(+) create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.cpp create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.h create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.ui diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp new file mode 100644 index 000000000..897bdd35d --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -0,0 +1,252 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include "util/rstime.h" + +#include "retroshare/rstor.h" +#include "retroshare/rsevents.h" + +#include "TorControlWindow.h" +#include "util/qtthreadsutils.h" + +TorControlDialog::TorControlDialog(QWidget *) +{ + setupUi(this) ; + + mEventHandlerId = 0; // very important! + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId, RsEventType::TOR_MANAGER ); + + // QObject::connect(tm->control(),SIGNAL(statusChanged(int,int)),this,SLOT(statusChanged())) ; + // QObject::connect(tm->control(),SIGNAL(connected()),this,SLOT(statusChanged())); + // QObject::connect(tm->control(),SIGNAL(disconnected()),this,SLOT(statusChanged())); + // QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged())); + // QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged())); + // QObject::connect(tm ,SIGNAL(errorChanged()),this,SLOT(statusChanged())); + + //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; + + mIncomingServer = new QTcpServer(this) ; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_UNKNOWN; + + connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); + + QTimer *timer = new QTimer ; + + QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; + timer->start(500) ; + + // Hide some debug output for the released version + + setWindowFlags( Qt::Dialog | Qt::FramelessWindowHint ); + + adjustSize(); +} + +void TorControlDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::TOR_MANAGER) return; + + const RsTorManagerEvent *fe = dynamic_cast(event.get()); + if(!fe) + return; + + switch (fe->mTorManagerEventType) + { + case RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED: + case RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED: + case RsTorManagerEventCode::TOR_STATUS_CHANGED: statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); + break; + default: + break; + } +} + +void TorControlDialog::onIncomingConnection() +{ + std::cerr << "Incoming connection !!" << std::endl; +} + +void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivityStatus tor_control_status) +{ + QString tor_control_status_str,torstatus_str ; + + if(RsTor::hasError()) + mErrorMsg = QString::fromStdString(RsTor::errorMessage()) ; + + switch(tor_control_status) + { + default: + case RsTorConnectivityStatus::ERROR : tor_control_status_str = tr("Error") ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; + case RsTorConnectivityStatus::CONNECTED: tor_control_status_str = tr("Connected") ; break ; + } + + switch(torstatus) + { + default: + case RsTorStatus::UNKNOWN: torstatus_str = tr("Unknown") ; break ; + case RsTorStatus::OFFLINE: torstatus_str = tr("Tor offline") ; break ; + case RsTorStatus::READY: torstatus_str = tr("Tor ready") ; break ; + } + + torStatus_LB->setText(torstatus_str) ; + + if(torstatus == RsTorStatus::UNKNOWN) + torStatus_LB->setToolTip(tr("Check that Tor is accessible in your executable path")) ; + else + torStatus_LB->setToolTip("") ; + + std::map qvm = RsTor::bootstrapStatus(); + QString bootstrapstatus_str ; + + std::cerr << "Tor control status: " << tor_control_status_str.toStdString() << std::endl; + std::cerr << "Tor status: " << torstatus_str.toStdString() << std::endl; + + std::cerr << "Bootstrap status map: " << std::endl; + + for(auto it(qvm.begin());it!=qvm.end();++it) + std::cerr << " " << it->first << " : " << it->second << std::endl; + + if(!qvm["progress"].empty()) + torBootstrapStatus_LB->setText(QString::fromStdString(qvm["progress"]) + " % (" + QString::fromStdString(qvm["summary"]) + ")") ; + else + torBootstrapStatus_LB->setText(tr("[Waiting for Tor...]")) ; + + std::string service_id ; + std::string onion_address ; + std::string service_target_address ; + uint16_t service_port ; + uint16_t target_port ; + + if(RsTor::getHiddenServiceInfo(service_id,onion_address,service_port, service_target_address,target_port)) + { + hiddenServiceAddress_LB->setText(QString::number(service_port) + ":" + QString::fromStdString(service_target_address) + ":" + QString::number(target_port)); + onionAddress_LB->setText(QString::fromStdString(onion_address)); + } + else + { + hiddenServiceAddress_LB->setText(QString("[Not ready]")) ; + onionAddress_LB->setText(QString("[Not ready]")) ; + } + + showLog(); + adjustSize(); + + QCoreApplication::processEvents(); // forces update +} + +void TorControlDialog::showLog() +{ + static std::set already_seen ; + + std::string s ; + std::list logmsgs = RsTor::logMessages() ; + bool can_print = false ; + + for(auto it(logmsgs.begin());it!=logmsgs.end();++it) + { + s += *it + "\n" ; + + if(already_seen.find(*it) == already_seen.end()) + { + can_print = true ; + already_seen.insert(*it); + } + + if(can_print) + std::cerr << "[TOR DEBUG LOG] " << *it << std::endl; + } + +// torLog_TB->setText(s) ;: + + std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; +} + +TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) +{ + if(!mErrorMsg.isNull()) + { + error_msg = mErrorMsg ; + return TorControlDialog::TOR_STATUS_FAIL ; + } + + switch(RsTor::torStatus()) + { + case RsTorStatus::READY: rstime::rs_usleep(1*1000*1000);return TOR_STATUS_OK ; + default: + return TOR_STATUS_UNKNOWN ; + } +} + +TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() +{ + std::cerr << "Checking for hidden services:" ; + + switch(mHiddenServiceStatus) + { + default: + case HIDDEN_SERVICE_STATUS_UNKNOWN: { + + std::cerr << " trying to setup. " ; + + if(!RsTor::setupHiddenService()) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ; + std::cerr << "Failed." << std::endl; + return mHiddenServiceStatus ; + } + std::cerr << "Done." << std::endl; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ; + return mHiddenServiceStatus ; + } + + case HIDDEN_SERVICE_STATUS_REQUESTED: { + + std::string service_id; + + RsTorHiddenServiceStatus service_status = RsTor::getHiddenServiceStatus(service_id); + + if(service_id.empty()) + { + std::cerr << "Not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + else + { + if(mHiddenService.empty()) + mHiddenService = service_id ; + + std::cerr << "New service acquired. Status is " << (int)service_status ; + + if(service_status == RsTorHiddenServiceStatus::ONLINE) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_OK ; + std::cerr << ": published and running!" << std::endl; + + return mHiddenServiceStatus ; + } + else + { + std::cerr << ": not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + } + } + case HIDDEN_SERVICE_STATUS_OK : + std::cerr << "New service acquired." << std::endl; + return mHiddenServiceStatus ; + } +} + diff --git a/retroshare-gui/src/TorControl/TorControlWindow.h b/retroshare-gui/src/TorControl/TorControlWindow.h new file mode 100644 index 000000000..5fc23e8e9 --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.h @@ -0,0 +1,50 @@ +#include "retroshare/rsevents.h" +#include "retroshare/rstor.h" +#include "ui_TorControlWindow.h" + +class QTcpServer ; + +namespace Tor { + class HiddenService ; + class TorManager ; +} + +class TorControlDialog: public QWidget, public Ui::TorControlDialog +{ + Q_OBJECT + +public: + TorControlDialog(QWidget *parent =NULL); + + enum TorStatus { + TOR_STATUS_UNKNOWN = 0x00, + TOR_STATUS_OK = 0x01, + TOR_STATUS_FAIL = 0x02 + }; + + enum HiddenServiceStatus { + HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00, // no information known. + HIDDEN_SERVICE_STATUS_FAIL = 0x01, // some error occurred + HIDDEN_SERVICE_STATUS_REQUESTED = 0x02, // one service at least has been requested. Still being tested. + HIDDEN_SERVICE_STATUS_OK = 0x03 // one service responds and has been tested + }; + + // Should be called multiple times in a loop until it returns something else than *_UNKNOWN + + TorStatus checkForTor(QString& error_msg) ; + HiddenServiceStatus checkForHiddenService() ; + +protected slots: + void showLog(); + void statusChanged(RsTorStatus torstatus,RsTorConnectivityStatus tor_control_status); + void onIncomingConnection(); + + void handleEvent_main_thread(std::shared_ptr event); +private: + QString mErrorMsg ; + HiddenServiceStatus mHiddenServiceStatus ; + std::string mHiddenService; + + QTcpServer *mIncomingServer ; + RsEventsHandlerId_t mEventHandlerId; +}; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.ui b/retroshare-gui/src/TorControl/TorControlWindow.ui new file mode 100644 index 000000000..602146641 --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.ui @@ -0,0 +1,134 @@ + + + TorControlDialog + + + + 0 + 0 + 600 + 228 + + + + + 0 + 0 + + + + Dialog + + + + + + + 75 + true + + + + Setting up Tor... + + + Qt::AlignCenter + + + + + + + + + + + + :/icons/tor-logo.png + + + false + + + + + + + + + Tor status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Unknown + + + + + + + Not started + + + + + + + Hidden service address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Tor bootstrap status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + Onion address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + + + + + + + + From d6ccd75a7f92871bc99926e0342135b770867cd9 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 00:31:09 +0200 Subject: [PATCH 119/697] started documenting rsHistory.h to bring history to JSON api --- libretroshare/src/retroshare/rshistory.h | 43 +++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/retroshare/rshistory.h b/libretroshare/src/retroshare/rshistory.h index f8eb7ecaa..2032c3d59 100644 --- a/libretroshare/src/retroshare/rshistory.h +++ b/libretroshare/src/retroshare/rshistory.h @@ -41,7 +41,7 @@ static const uint32_t RS_HISTORY_TYPE_PRIVATE = 1 ; static const uint32_t RS_HISTORY_TYPE_LOBBY = 2 ; static const uint32_t RS_HISTORY_TYPE_DISTANT = 3 ; -class HistoryMsg +class HistoryMsg: RsSerializable { public: HistoryMsg() @@ -52,7 +52,18 @@ public: recvTime = 0; } -public: + virtual void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override + { + RS_SERIAL_PROCESS(msgId); + RS_SERIAL_PROCESS(chatPeerId); + RS_SERIAL_PROCESS(incoming); + RS_SERIAL_PROCESS(peerId); + RS_SERIAL_PROCESS(peerName); + RS_SERIAL_PROCESS(sendTime); + RS_SERIAL_PROCESS(recvTime); + RS_SERIAL_PROCESS(message); + } + uint32_t msgId; RsPeerId chatPeerId; bool incoming; @@ -71,10 +82,34 @@ class RsHistory { public: virtual bool chatIdToVirtualPeerId(const ChatId &chat_id, RsPeerId &peer_id) = 0; - virtual bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount) = 0; + + /*! + * @brief Retrieves the history of messages for a given chatId + * @jsonapi{development} + * @param[in] chatPeerId Chat Id for which the history needs to be retrieved + * @param[out] msgs retrieved messages + * @param[in] loadCount maximum number of messages to get + * @return true if messages can be retrieved, false otherwise. + */ + virtual bool getMessages(const ChatId& chatPeerId, std::list &msgs, uint32_t loadCount) = 0; + + /*! + * @brief Retrieves a specific message from the history + * @jsonapi{development} + * @param[in] msgId Id of the message to get + * @param[out] msg retrieved message + * @return true if message can be retrieved, false otherwise. + */ virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0; + virtual void removeMessages(const std::list &msgIds) = 0; - virtual void clear(const ChatId &chatPeerId) = 0; + + /*! + * @brief clears the message history for a given chat peer + * @jsonapi{development} + * @param[in] chatPeerID Id of the chat/peer for which the history needs to be wiped + */ + virtual void clear(const ChatId &chatPeerId) = 0; virtual bool getEnable(uint32_t chat_type) = 0; virtual void setEnable(uint32_t chat_type, bool enable) = 0; From 4833a8fdc42d59be0cc90e73ef4a54d7e442e370 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 20:48:47 +0200 Subject: [PATCH 120/697] added json api description for the rest of RsHistory --- libretroshare/src/retroshare/rshistory.h | 50 ++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/retroshare/rshistory.h b/libretroshare/src/retroshare/rshistory.h index 2032c3d59..faa649f2d 100644 --- a/libretroshare/src/retroshare/rshistory.h +++ b/libretroshare/src/retroshare/rshistory.h @@ -102,7 +102,12 @@ public: */ virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0; - virtual void removeMessages(const std::list &msgIds) = 0; + /*! + * @brief Remove messages from the history + * @jsonapi{development} + * @param[in] msgIds list of messages to remove + */ + virtual void removeMessages(const std::list& msgIds) = 0; /*! * @brief clears the message history for a given chat peer @@ -111,15 +116,46 @@ public: */ virtual void clear(const ChatId &chatPeerId) = 0; - virtual bool getEnable(uint32_t chat_type) = 0; - virtual void setEnable(uint32_t chat_type, bool enable) = 0; + /*! + * @brief Get whether chat history is enabled or not + * @jsonapi{development} + * @param[in] chat_type Type of chat (see list of constants above) + * @return true when the information is available + */ + virtual bool getEnable(uint32_t chat_type) = 0; + /*! + * @brief Set whether chat history is enabled or not + * @jsonapi{development} + * @param[in] chat_type Type of chat (see list of constants above) + * @param[in] enabled Desired state of the variable + */ + virtual void setEnable(uint32_t chat_type, bool enable) = 0; + + /*! + * @brief Retrieves the maximum storage time period for messages in history + * @return max storage duration of chat. + */ virtual uint32_t getMaxStorageDuration() = 0; - virtual void setMaxStorageDuration(uint32_t seconds) = 0; + /*! + * @brief Sets the maximum storage time period for messages in history + * @param[in] seconds max storage duration time in seconds + */ + virtual void setMaxStorageDuration(uint32_t seconds) = 0; - // 0 = no limit, >0 count of saved messages - virtual uint32_t getSaveCount(uint32_t chat_type) = 0; - virtual void setSaveCount(uint32_t chat_type, uint32_t count) = 0; + /*! + * @brief Gets the maximum number of messages to save + * @param[in] chat_type Type of chat for that number limit + * @return maximum number of messages to save + */ + virtual uint32_t getSaveCount(uint32_t chat_type) = 0; + + /*! + * @brief Sets the maximum number of messages to save + * @param[in] chat_type Type of chat for that number limit + * @param[in] count Max umber of messages, 0 meaning indefinitly + */ + virtual void setSaveCount(uint32_t chat_type, uint32_t count) = 0; }; #endif From 850554429432964ed0bcab275be2c590b7b07bcb Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 21:54:44 +0200 Subject: [PATCH 121/697] removed signals in HiddenService class --- libretroshare/src/tor/HiddenService.cpp | 27 +++++++++++++++---------- libretroshare/src/tor/HiddenService.h | 26 +++++++++++++++--------- libretroshare/src/tor/TorManager.cpp | 19 +++++++++++------ libretroshare/src/tor/TorManager.h | 14 +++++++------ 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index b2b58626a..22b7200fe 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -42,13 +42,13 @@ using namespace Tor; -HiddenService::HiddenService(QObject *parent) - : QObject(parent), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client) + : m_status(NotCreated), m_client(client) { } -HiddenService::HiddenService(const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client,const QString &path) + : m_dataPath(path), m_status(NotCreated), m_client(client) { /* Set the initial status and, if possible, load the hostname */ if (QDir(m_dataPath).exists(QLatin1String("private_key"))) { @@ -58,8 +58,8 @@ HiddenService::HiddenService(const QString &path, QObject *parent) } } -HiddenService::HiddenService(const CryptoKey &privateKey, const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &path) + : m_dataPath(path), m_status(NotCreated), m_client(client) { setPrivateKey(privateKey); m_status = Offline; @@ -73,10 +73,12 @@ void HiddenService::setStatus(Status newStatus) Status old = m_status; m_status = newStatus; - emit statusChanged(m_status, old); + if(m_client) + m_client->hiddenServiceStatusChanged(m_status,old); //emit statusChanged(m_status, old); if (m_status == Online) - emit serviceOnline(); + if(m_client) + m_client->hiddenServiceOnline(); //emit serviceOnline(); } void HiddenService::addTarget(const Target &target) @@ -95,7 +97,8 @@ void HiddenService::setServiceId(const QByteArray& sid) m_service_id = sid; m_hostname = sid + ".onion"; - emit hostnameChanged(); + if(m_client) + m_client->hiddenServiceHostnameChanged(); // emit hostnameChanged(); } void HiddenService::setPrivateKey(const CryptoKey &key) { @@ -113,7 +116,8 @@ void HiddenService::setPrivateKey(const CryptoKey &key) m_privateKey = key; - emit privateKeyChanged(); + if(m_client) + m_client->hiddenServicePrivateKeyChanged(); //emit privateKeyChanged(); } void HiddenService::loadPrivateKey() @@ -128,7 +132,8 @@ void HiddenService::loadPrivateKey() return; } - emit privateKeyChanged(); + if(m_client) + m_client->hiddenServicePrivateKeyChanged(); // emit privateKeyChanged(); } void HiddenService::servicePublished() diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 20fa1d851..4efa55582 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -43,6 +43,18 @@ namespace Tor class TorSocket; +// This class is used to receive synchroneous notifications from the hidden service. +// Each client should implement its own notification handling. + +class HiddenServiceClient +{ +public: + virtual void hiddenServiceStatusChanged(int /* newStatus */, int /* oldStatus */) =0; + virtual void hiddenServiceOnline() =0; + virtual void hiddenServicePrivateKeyChanged() =0; + virtual void hiddenServiceHostnameChanged() =0; +}; + class HiddenService : public QObject { Q_OBJECT @@ -64,9 +76,9 @@ public: Online /* Published */ }; - HiddenService(QObject *parent = 0); - HiddenService(const QString &dataPath, QObject *parent = 0); - HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); + HiddenService(HiddenServiceClient *client); + HiddenService(HiddenServiceClient *client,const QString &dataPath); + HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &dataPath = QString()); Status status() const { return m_status; } @@ -82,12 +94,6 @@ public: void addTarget(const Target &target); void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); -signals: - void statusChanged(int newStatus, int oldStatus); - void serviceOnline(); - void privateKeyChanged(); - void hostnameChanged(); - private slots: void servicePublished(); @@ -101,6 +107,8 @@ private: void loadPrivateKey(); void setStatus(Status newStatus); + + HiddenServiceClient *m_client; }; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index fc81d943e..7fa645beb 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -175,23 +175,24 @@ bool TorManager::setupHiddenService() return false; } - d->hiddenService = new Tor::HiddenService(key, legacyDir, this); + d->hiddenService = new Tor::HiddenService(this,key, legacyDir); std::cerr << "Got key from legacy dir: " << std::endl; std::cerr << key.bytes().toStdString() << std::endl; } else { - d->hiddenService = new Tor::HiddenService(legacyDir, this); + d->hiddenService = new Tor::HiddenService(this,legacyDir); std::cerr << "Creating new hidden service." << std::endl; - connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; - connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; + // connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; + // connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; } - Q_ASSERT(d->hiddenService); - connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); + assert(d->hiddenService); + + // connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); // Generally, these are not used, and we bind to localhost and port 0 // for an automatic (and portable) selection. @@ -225,6 +226,9 @@ void TorManager::hiddenServiceStatusChanged(int old_status,int new_status) void TorManager::hiddenServicePrivateKeyChanged() { + if(!d->hiddenService) + return ; + QString key = QString::fromLatin1(d->hiddenService->privateKey().bytes()); QFile outfile(d->hiddenServiceDir + QLatin1String("/private_key")) ; @@ -249,6 +253,9 @@ void TorManager::hiddenServicePrivateKeyChanged() void TorManager::hiddenServiceHostnameChanged() { + if(!d->hiddenService) + return ; + QFile outfile2(d->hiddenServiceDir + QLatin1String("/hostname")) ; outfile2.open( QIODevice::WriteOnly | QIODevice::Text ); QTextStream t(&outfile2); diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 9d3dd388d..3c9733519 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -36,6 +36,7 @@ #define TORMANAGER_H #include "retroshare/rstor.h" +#include "HiddenService.h" #include #include @@ -51,7 +52,7 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject, public RsTor +class TorManager : public QObject, public HiddenServiceClient, public RsTor { Q_OBJECT @@ -90,13 +91,14 @@ public: bool getHiddenServiceInfo(QString& service_id,QString& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port); bool getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port); -public slots: +//public slots: bool start(); -private slots: - void hiddenServicePrivateKeyChanged(); - void hiddenServiceHostnameChanged(); - void hiddenServiceStatusChanged(int old_status,int new_status); +//private slots: + virtual void hiddenServiceOnline() override {} // do nothing here. + virtual void hiddenServicePrivateKeyChanged() override; + virtual void hiddenServiceHostnameChanged() override; + virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; signals: void configurationNeededChanged(); From 4e4427f0bd00d3ae579680612ccf5bb7f1f5c21a Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 22:01:07 +0200 Subject: [PATCH 122/697] fixed errors in libretroshare.pro --- libretroshare/src/libretroshare.pro | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..da5f25ba4 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -137,7 +137,6 @@ PUBLIC_HEADERS = retroshare/rsdisc.h \ retroshare/rsmsgs.h \ retroshare/rsnotify.h \ retroshare/rspeers.h \ - retroshare/rsrank.h \ retroshare/rsstatus.h \ retroshare/rsturtle.h \ retroshare/rsbanlist.h \ @@ -348,13 +347,13 @@ HEADERS += ft/ftchunkmap.h \ ft/ftturtlefiletransferitem.h HEADERS += crypto/chacha20.h \ - crypto/rsaes.h \ - crypto/hashstream.h \ - crypto/rscrypto.h + crypto/rsaes.h \ + crypto/hashstream.h \ + crypto/rscrypto.h -HEADERS += directory_updater.h \ - directory_list.h \ - p3filelists.h +HEADERS += file_sharing/directory_updater.h \ + file_sharing/directory_list.h \ + file_sharing/p3filelists.h HEADERS += chat/distantchat.h \ chat/p3chatservice.h \ @@ -416,7 +415,7 @@ HEADERS += grouter/groutercache.h \ retroshare/rsgrouter.h \ grouter/grouteritems.h \ grouter/p3grouter.h \ - grouter/rsgroutermatrix.h \ + grouter/groutermatrix.h \ grouter/groutertypes.h \ grouter/grouterclientservice.h @@ -429,7 +428,6 @@ HEADERS += rsitems/rsitem.h \ rsitems/rsmsgitems.h \ serialiser/rsserial.h \ rsitems/rsserviceids.h \ - serialiser/rsserviceitems.h \ rsitems/rsstatusitems.h \ serialiser/rstlvaddrs.h \ serialiser/rstlvbase.h \ From b6156bff00f17cac02f79d0a5d7e3d45a8e3c78f Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 4 Jul 2021 14:06:37 +0200 Subject: [PATCH 123/697] fixed compilation for appveyor --- libretroshare/src/tor/TorManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 7fa645beb..18cb963cd 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -30,6 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include "TorManager.h" @@ -673,7 +674,7 @@ void RsTor::setHiddenServiceDirectory(const std::string& dir) TorManager *RsTor::instance() { - assert(getpid() == gettid()); // make sure we're not in a thread + assert(getpid() == syscall(SYS_gettid));// make sure we're not in a thread static TorManager *rsTor = nullptr; From abf481b0a181b51df03bca46715d80d3ed1bcda1 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 4 Jul 2021 18:27:12 +0200 Subject: [PATCH 124/697] removal of slignal/slots --- libretroshare/src/libretroshare.pro | 2 +- libretroshare/src/retroshare/rstor.h | 4 ++ libretroshare/src/tor/TorManager.cpp | 61 ++++++++++++++++++++-------- libretroshare/src/tor/TorManager.h | 27 ++++++------ libretroshare/src/tor/TorProcess.cpp | 56 +++++++++++++++++-------- libretroshare/src/tor/TorProcess.h | 33 ++++++++++----- 6 files changed, 122 insertions(+), 61 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0d3889708..21161433a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -448,7 +448,7 @@ HEADERS += rsitems/rsitem.h \ serialiser/rstlvkeyvalue.h \ serialiser/rstlvgenericparam.h \ serialiser/rstlvgenericmap.h \ - serialiser/rstlvgenericmap.inl \ + serialiser/rstlvgenericmap.inl \ serialiser/rstlvlist.h \ serialiser/rstlvmaps.h \ serialiser/rstlvbanlist.h \ diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 7538671b1..dd4739304 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -36,6 +36,8 @@ enum class RsTorManagerEventCode: uint8_t TOR_STATUS_CHANGED = 0x01, BOOTSTRAP_STATUS_CHANGED = 0x02, TOR_CONNECTIVITY_CHANGED = 0x03, + TOR_MANAGER_ERROR = 0x04, + CONFIGURATION_NEEDED = 0x05, }; // Status of the Tor hidden service setup/loaded by RS @@ -75,6 +77,7 @@ struct RsTorManagerEvent: public RsEvent RsTorConnectivityStatus mTorConnectivityStatus; RsTorStatus mTorStatus; + std::string mErrorMessage; ///* @see RsEvent @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override @@ -83,6 +86,7 @@ struct RsTorManagerEvent: public RsEvent RS_SERIAL_PROCESS(mTorManagerEventType); RS_SERIAL_PROCESS(mTorConnectivityStatus); RS_SERIAL_PROCESS(mTorStatus); + RS_SERIAL_PROCESS(mErrorMessage); } ~RsTorManagerEvent() = default; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 18cb963cd..9983d8c1f 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -33,6 +33,8 @@ #include #include +#include + #include "TorManager.h" #include "TorProcess.h" #include "TorControl.h" @@ -51,7 +53,7 @@ using namespace Tor; namespace Tor { -class TorManagerPrivate : public QObject +class TorManagerPrivate : public QObject, public TorProcessClient { Q_OBJECT @@ -75,23 +77,24 @@ public: void setError(const QString &errorMessage); + virtual void processStateChanged(int state) override; + virtual void processErrorChanged(const QString &errorMessage) override; + virtual void processLogMessage(const QString &message) override; + public slots: - void processStateChanged(int state); - void processErrorChanged(const QString &errorMessage); - void processLogMessage(const QString &message); void controlStatusChanged(int status); void getConfFinished(); }; } -TorManager::TorManager(QObject *parent) - : QObject(parent), d(new TorManagerPrivate(this)) +TorManager::TorManager() + : d(new TorManagerPrivate(this)) { } TorManagerPrivate::TorManagerPrivate(TorManager *parent) - : QObject(parent) + : QObject(nullptr) , q(parent) , process(0) , control(new TorControl(this)) @@ -105,7 +108,7 @@ TorManager *TorManager::instance() { static TorManager *p = 0; if (!p) - p = new TorManager(qApp); + p = new TorManager(); return p; } @@ -293,7 +296,8 @@ bool TorManager::start() { if (!d->errorMessage.isEmpty()) { d->errorMessage.clear(); - emit errorChanged(); + + //emit errorChanged(); // not needed because there's no error to handle } SettingsObject settings(QStringLiteral("tor")); @@ -341,11 +345,11 @@ bool TorManager::start() } if (!d->process) { - d->process = new TorProcess(this); - connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); - connect(d->process, SIGNAL(errorMessageChanged(QString)), d, - SLOT(processErrorChanged(QString))); - connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); + d->process = new TorProcess(d); + + // QObject::connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); + // QObject::connect(d->process, SIGNAL(errorMessageChanged(QString)), d, SLOT(processErrorChanged(QString))); + // QObject::connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); } if (!QFile::exists(d->dataDir) && !d->createDataDir(d->dataDir)) { @@ -362,7 +366,14 @@ bool TorManager::start() QFile torrc(d->dataDir + QStringLiteral("torrc")); if (!torrc.exists() || torrc.size() == 0) { d->configNeeded = true; - emit configurationNeededChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + rsEvents->sendEvent(ev); + } + //emit configurationNeededChanged(); } std::cerr << "Starting Tor process:" << std::endl; @@ -460,7 +471,14 @@ void TorManagerPrivate::getConfFinished() if (command->get("DisableNetwork").toInt() == 1 && !configNeeded) { configNeeded = true; - emit q->configurationNeededChanged(); + //emit q->configurationNeededChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + rsEvents->sendEvent(ev); + } } } @@ -527,7 +545,16 @@ bool TorManagerPrivate::createDefaultTorrc(const QString &path) void TorManagerPrivate::setError(const QString &message) { errorMessage = message; - emit q->errorChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_MANAGER_ERROR; + ev->mErrorMessage = message.toStdString(); + rsEvents->sendEvent(ev); + } + //emit q->errorChanged(); } #include "TorManager.moc" diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 3c9733519..e0a24ae15 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -38,7 +38,6 @@ #include "retroshare/rstor.h" #include "HiddenService.h" -#include #include #include @@ -52,17 +51,17 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject, public HiddenServiceClient, public RsTor +class TorManager : public HiddenServiceClient, public RsTor { - Q_OBJECT + // Q_OBJECT - Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) - Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) - Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) - Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) - Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) - Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) + // Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) + // Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) + // Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) + // Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) + // Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) + // Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) + // Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) public: static TorManager *instance(); @@ -100,12 +99,12 @@ public: virtual void hiddenServiceHostnameChanged() override; virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; -signals: - void configurationNeededChanged(); - void errorChanged(); +//signals: +// void configurationNeededChanged(); +// void errorChanged(); private: - explicit TorManager(QObject *parent = 0); + explicit TorManager(); TorManagerPrivate *d; friend class RsTor; }; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index ca1aecfe5..1ad48db2d 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -39,8 +39,8 @@ using namespace Tor; -TorProcess::TorProcess(QObject *parent) - : QObject(parent), d(new TorProcessPrivate(this)) +TorProcess::TorProcess(TorProcessClient *client,QObject *parent) + : d(new TorProcessPrivate(this)),m_client(client) { } @@ -51,7 +51,7 @@ TorProcess::~TorProcess() } TorProcessPrivate::TorProcessPrivate(TorProcess *q) - : QObject(q), q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) + : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) { connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, @@ -124,15 +124,16 @@ void TorProcess::start() if (d->executable.isEmpty() || d->dataDir.isEmpty()) { d->errorMessage = QStringLiteral("Tor executable and data directory not specified"); d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + + if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage); // emit errorMessageChanged(d->errorMessage); return; } if (!d->ensureFilesExist()) { d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); return; } @@ -141,8 +142,8 @@ void TorProcess::start() if (password.isEmpty() || hashedPassword.isEmpty()) { d->errorMessage = QStringLiteral("Random password generation failed"); d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); } QStringList args; @@ -157,7 +158,8 @@ void TorProcess::start() args << d->extraSettings; d->state = Starting; - emit stateChanged(d->state); + + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); if (QFile::exists(d->controlPortFilePath())) QFile::remove(d->controlPortFilePath()); @@ -194,7 +196,23 @@ void TorProcess::stop() } #endif - emit stateChanged(d->state); + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); +} + +void TorProcess::stateChanged(int newState) +{ + if(m_client) + m_client->processStateChanged(newState); +} +void TorProcess::errorMessageChanged(const QString &errorMessage) +{ + if(m_client) + m_client->processErrorChanged(errorMessage); +} +void TorProcess::logMessage(const QString &message) +{ + if(m_client) + m_client->processLogMessage(message); } QByteArray TorProcess::controlPassword() @@ -246,7 +264,9 @@ QString TorProcessPrivate::controlPortFilePath() const void TorProcessPrivate::processStarted() { state = TorProcess::Connecting; - emit q->stateChanged(state); + + /*emit*/ q->stateChanged(state); + /*emit*/ q->stateChanged(state); controlPortAttempts = 0; controlPortTimer.start(); @@ -262,8 +282,8 @@ void TorProcessPrivate::processFinished() if (errorMessage.isEmpty()) errorMessage = QStringLiteral("Process exited unexpectedly (code %1)").arg(process.exitCode()); state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); + /*emit*/ q->errorMessageChanged(errorMessage); + /*emit*/ q->stateChanged(state); } void TorProcessPrivate::processError(QProcess::ProcessError error) @@ -277,7 +297,7 @@ void TorProcessPrivate::processReadable() while (process.bytesAvailable() > 0) { QByteArray line = process.readLine(2048).trimmed(); if (!line.isEmpty()) - emit q->logMessage(QString::fromLatin1(line)); + /*emit*/ q->logMessage(QString::fromLatin1(line)); } } @@ -295,7 +315,7 @@ void TorProcessPrivate::tryReadControlPort() if (!controlHost.isNull() && controlPort > 0) { controlPortTimer.stop(); state = TorProcess::Ready; - emit q->stateChanged(state); + /*emit*/ q->stateChanged(state); return; } } @@ -304,8 +324,8 @@ void TorProcessPrivate::tryReadControlPort() if (++controlPortAttempts * controlPortTimer.interval() > 10000) { errorMessage = QStringLiteral("No control port available after launching process"); state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); + /*emit*/ q->errorMessageChanged(errorMessage); + /*emit*/ q->stateChanged(state); } } diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index ad489dc43..9a2511f09 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -41,15 +41,25 @@ namespace Tor class TorProcessPrivate; +// This class is used to inherit calls from the TorProcess + +class TorProcessClient +{ +public: + virtual void processStateChanged(int) = 0; + virtual void processErrorChanged(const QString&) = 0; + virtual void processLogMessage(const QString&) = 0; +}; + /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess : public QObject +class TorProcess { - Q_OBJECT - Q_ENUMS(State) + //Q_OBJECT + //Q_ENUMS(State) - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + //Q_PROPERTY(State state READ state NOTIFY stateChanged) + //Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) public: enum State { @@ -60,7 +70,7 @@ public: Ready }; - explicit TorProcess(QObject *parent = 0); + explicit TorProcess(TorProcessClient *client,QObject *parent = 0); virtual ~TorProcess(); QString executable() const; @@ -81,17 +91,18 @@ public: quint16 controlPort(); QByteArray controlPassword(); -public slots: - void start(); - void stop(); - -signals: +//signals: void stateChanged(int newState); void errorMessageChanged(const QString &errorMessage); void logMessage(const QString &message); +//public slots: + void start(); + void stop(); + private: TorProcessPrivate *d; + TorProcessClient *m_client; }; } From fc198d4e6d4905cb7cfdf98901154aeb284454d7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 7 Jul 2021 13:05:42 +0200 Subject: [PATCH 125/697] libretroshare: add share single files (no dir, no extra) Add capability to libretroshare to share single files without sharing the whole folder containing it, this is expecially useful in Android where files are organized in a peculiar way that render classic way of sharing folder almost unusable. Using extra files which was already implemented doesn't solve this use case as extra files are limited in time and dosn't support search and sharing permissions. RetroShare GUI works fine if a single file is added as shared dir via JSON API, but probably would need tweaking some flags in file picker to give the ability to the user. --- .../src/file_sharing/directory_storage.cc | 95 +++-- .../src/file_sharing/directory_updater.cc | 353 ++++++++++-------- libretroshare/src/util/rsdir.cc | 33 +- libretroshare/src/util/rsdir.h | 21 +- 4 files changed, 316 insertions(+), 186 deletions(-) diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index c4a46f4fb..2d78240c8 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -30,6 +30,7 @@ #include "directory_storage.h" #include "dir_hierarchy.h" #include "filelist_io.h" +#include "util/cxx17retrocompat.h" #ifdef RS_DEEP_FILES_INDEX # include "deep_search/filesindex.hpp" @@ -617,48 +618,78 @@ bool LocalDirectoryStorage::getFileSharingPermissions(const EntryIndex& indx,Fil return locked_getFileSharingPermissions(indx,flags,parent_groups) ; } -bool LocalDirectoryStorage::locked_getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags& flags, std::list &parent_groups) +bool LocalDirectoryStorage::locked_getFileSharingPermissions( + const EntryIndex& indx, FileStorageFlags& flags, + std::list& parent_groups ) { - flags.clear() ; - parent_groups.clear(); + flags.clear(); + parent_groups.clear(); - std::string base_dir; + /* We got a request for root directory no need to do anything more after + * clearing outputs */ + if(!indx) return true; - const InternalFileHierarchyStorage::FileStorageNode *n = mFileHierarchy->getNode(indx) ; + using FileStorageNode = InternalFileHierarchyStorage::FileStorageNode; + using EntryIndex = DirectoryStorage::EntryIndex; - if(n == NULL) - return false ; + rs_view_ptr n = mFileHierarchy->getNode(indx); + if(!n) + { + RS_ERR("Node for index: ", indx, "not found"); + print_stacktrace(); + return false; + } - for(DirectoryStorage::EntryIndex i=((n->type()==InternalFileHierarchyStorage::FileStorageNode::TYPE_FILE)?((intptr_t)n->parent_index):indx);;) - { - const InternalFileHierarchyStorage::DirEntry *e = mFileHierarchy->getDirEntry(i) ; + // Climb down node tree up to root + 1 + EntryIndex curIndex = indx; + while (n->parent_index) + { + curIndex = n->parent_index; + n = mFileHierarchy->getNode(curIndex); + } - if(e == NULL) - break ; + // Retrieve base name + std::string tBaseName; + switch (n->type()) + { + // Handle single file shared case + case InternalFileHierarchyStorage::FileStorageNode::TYPE_FILE: + tBaseName = mFileHierarchy->getFileEntry(curIndex)->file_name; + break; + // Handle shared directory case + case InternalFileHierarchyStorage::FileStorageNode::TYPE_DIR: + tBaseName = mFileHierarchy->getDirEntry(curIndex)->dir_name; + break; + default: + RS_ERR("Got unhandled node type: ", n->type()); + print_stacktrace(); + return false; + } - if(e->parent_index == 0) - { - base_dir = e->dir_name ; - break ; - } - i = e->parent_index ; - } + // Use base name to retrieve sharing permissions + if(!tBaseName.empty()) + { + auto it = std::as_const(mLocalDirs).find(tBaseName); - if(!base_dir.empty()) - { - std::map::const_iterator it = mLocalDirs.find(base_dir) ; + if(it == mLocalDirs.end()) + { + RS_ERR( "base name \"", tBaseName, + "\" for index: ", indx, " not found in shared dir list." ); + print_stacktrace(); + return false; + } - if(it == mLocalDirs.end()) - { - std::cerr << "(II) base directory \"" << base_dir << "\" not found in shared dir list." << std::endl; - return false ; - } + flags = it->second.shareflags; + parent_groups = it->second.parent_groups; + } + else + { + RS_ERR("base name for indx: ", indx, " is empty"); + print_stacktrace(); + return false; + } - flags = it->second.shareflags; - parent_groups = it->second.parent_groups; - } - - return true; + return true; } std::string LocalDirectoryStorage::locked_getVirtualDirName(EntryIndex indx) const diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc index 828d1ee2c..16f09149c 100644 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ b/libretroshare/src/file_sharing/directory_updater.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2016 by Mr.Alice * + * Copyright (C) 2016 by Mr.Alice * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,13 +21,15 @@ * along with this program. If not, see . * * * ******************************************************************************/ + +#include "util/cxx17retrocompat.h" #include "util/folderiterator.h" #include "util/rstime.h" #include "rsserver/p3face.h" - #include "directory_storage.h" #include "directory_updater.h" #include "file_sharing_defaults.h" +#include "util/rsdebuglevel3.h" //#define DEBUG_LOCAL_DIR_UPDATER 1 @@ -121,185 +125,238 @@ void LocalDirectoryUpdater::forceUpdate(bool add_safe_delay) bool LocalDirectoryUpdater::sweepSharedDirectories(bool& some_files_not_ready) { - if(mHashSalt.isNull()) - { - std::cerr << "(EE) no salt value in LocalDirectoryUpdater. Is that a bug?" << std::endl; - return false; - } + if(mHashSalt.isNull()) + { + RS_ERR("no salt value in LocalDirectoryUpdater"); + print_stacktrace(); + return false; + } - mIsChecking = true ; + mIsChecking = true; - RsServer::notify()->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] LocalDirectoryUpdater::sweep()" << std::endl; -#endif + RsServer::notify()->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - // recursive update algorithm works that way: - // - the external loop starts on the shared directory list and goes through sub-directories - // - at the same time, it updates the local list of shared directories. A single sweep is performed over the whole directory structure. - // - the information that is costly to compute (the hash) is store externally into a separate structure. - // - doing so, changing directory names or moving files between directories does not cause a re-hash of the content. - // - std::list shared_directory_list ; - mSharedDirectories->getSharedDirectoryList(shared_directory_list); + /* recursive update algorithm works that way: + * - the external loop starts on the shared directory list and goes through + * sub-directories + * - at the same time, it updates the local list of shared directories. + * A single sweep is performed over the whole directory structure. + * - the information that is costly to compute (the hash) is stored + * externally into a separate structure. + * - doing so, changing directory names or moving files between directories + * does not cause a re-hash of the content. */ + std::list shared_directory_list; + mSharedDirectories->getSharedDirectoryList(shared_directory_list); + std::set sub_dir_list; - std::set sub_dir_list ; + /* Support also single files sharing as it make much more sense on some + * platforms like Android */ + std::map singleFilesMap; - // We re-check that each dir actually exists. It might have been removed from the disk. + /* We re-check that each dir actually exists. It might have been removed + * from the disk. Accept also single files not just directories. */ + for(auto& realDir: std::as_const(shared_directory_list)) + { + const auto& fPath = realDir.filename; + if(RsDirUtil::checkDirectory(fPath)) + sub_dir_list.insert(fPath); + else if (RsDirUtil::fileExists(fPath)) + { + rstime_t lastWrite= RsDirUtil::lastWriteTime(fPath); + if(time(nullptr) >= lastWrite + MIN_TIME_AFTER_LAST_MODIFICATION) + { + uint64_t fSize = 0; + RsDirUtil::checkFile(fPath,fSize); - for(std::list::const_iterator real_dir_it(shared_directory_list.begin());real_dir_it!=shared_directory_list.end();++real_dir_it) - if(RsDirUtil::checkDirectory( (*real_dir_it).filename ) ) - sub_dir_list.insert( (*real_dir_it).filename ) ; + singleFilesMap[fPath].modtime = lastWrite; + singleFilesMap[fPath].size = fSize; + } + else + { + some_files_not_ready = true; + RS_INFO( "file: \"", fPath, "\" is " + "probably being written to. Keep it for later"); + } + } + else RS_WARN( "Got non existent file \"", fPath, + "\" in shared directories list. Ignored." ); + } - // make sure that entries in stored_dir_it are the same than paths in real_dir_it, and in the same order. + { + const auto tRoot = mSharedDirectories->root(); + std::map needsUpdate; + mSharedDirectories->updateSubFilesList( + tRoot, singleFilesMap, needsUpdate); - mSharedDirectories->updateSubDirectoryList(mSharedDirectories->root(),sub_dir_list,mHashSalt) ; + for( DirectoryStorage::FileIterator storedSingleFilesIt( + mSharedDirectories, mSharedDirectories->root() ); + storedSingleFilesIt; ++storedSingleFilesIt ) + { + const auto& it = storedSingleFilesIt; + RsFileHash hash; + if( mHashCache->requestHash( + it.name(), it.size(), it.modtime(), hash, + this, *it ) ) + mSharedDirectories->updateHash(*it, hash, it.hash() != hash); + } + } - // now for each of them, go recursively and match both files and dirs + /* make sure that entries in stored_dir_it are the same than paths in + * real_dir_it, and in the same order. */ + mSharedDirectories->updateSubDirectoryList( + mSharedDirectories->root(), sub_dir_list, mHashSalt ); - std::set existing_dirs ; + // now for each of them, go recursively and match both files and dirs + std::set existing_dirs; + for( DirectoryStorage::DirIterator stored_dir_it( + mSharedDirectories, mSharedDirectories->root() ); + stored_dir_it; ++stored_dir_it ) + { + RS_DBG4("recursing into \"", stored_dir_it.name()); - for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,mSharedDirectories->root()) ; stored_dir_it;++stored_dir_it) - { -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] recursing into " << stored_dir_it.name() << std::endl; -#endif existing_dirs.insert(RsDirUtil::removeSymLinks(stored_dir_it.name())); + recursUpdateSharedDir( + stored_dir_it.name(), *stored_dir_it, + existing_dirs, 1, some_files_not_ready ); + /* here we need to use the list that was stored, instead of the shared + * dir list, because the two are not necessarily in the same order. */ + } - recursUpdateSharedDir(stored_dir_it.name(), *stored_dir_it,existing_dirs,1,some_files_not_ready) ; // here we need to use the list that was stored, instead of the shared dir list, because the two - // are not necessarily in the same order. - } + RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); + mIsChecking = false; - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - mIsChecking = false ; - - return true ; + return true; } -void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx,std::set& existing_directories,uint32_t current_depth,bool& some_files_not_ready) +void LocalDirectoryUpdater::recursUpdateSharedDir( + const std::string& cumulated_path, DirectoryStorage::EntryIndex indx, + std::set& existing_directories, uint32_t current_depth, + bool& some_files_not_ready ) { -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] parsing directory " << cumulated_path << ", index=" << indx << std::endl; -#endif + RS_DBG4("parsing directory \"", cumulated_path, "\" index: ", indx); - // make sure list of subdirs is the same - // make sure list of subfiles is the same - // request all hashes to the hashcache + /* make sure list of subdirs is the same + * make sure list of subfiles is the same + * request all hashes to the hashcache */ - librs::util::FolderIterator dirIt(cumulated_path,mFollowSymLinks,false); // disallow symbolic links and files from the future. + // disallow symbolic links and files from the future. + librs::util::FolderIterator dirIt(cumulated_path, mFollowSymLinks, false); - rstime_t dir_local_mod_time ; - if(!mSharedDirectories->getDirectoryLocalModTime(indx,dir_local_mod_time)) - { - std::cerr << "(EE) Cannot get local mod time for dir index " << indx << std::endl; - return; - } + rstime_t dir_local_mod_time; + if(!mSharedDirectories->getDirectoryLocalModTime(indx,dir_local_mod_time)) + { + RS_ERR("Cannot get local mod time for dir index: ", indx); + print_stacktrace(); + return; + } - rstime_t now = time(NULL) ; + rstime_t now = time(nullptr); + /* the > is because we may have changed the virtual name, and therefore the + * TS wont match. We only want to detect when the directory has changed on + * the disk */ + if(mNeedsFullRecheck || dirIt.dir_modtime() > dir_local_mod_time) + { + // collect subdirs and subfiles + std::map subfiles; + std::set subdirs; - if(mNeedsFullRecheck || dirIt.dir_modtime() > dir_local_mod_time) // the > is because we may have changed the virtual name, and therefore the TS wont match. - // we only want to detect when the directory has changed on the disk - { - // collect subdirs and subfiles + for( ; dirIt.isValid(); dirIt.next() ) + if(filterFile(dirIt.file_name())) + { + const auto fType = dirIt.file_type(); + switch(fType) + { + case librs::util::FolderIterator::TYPE_FILE: + if(now >= dirIt.file_modtime() + MIN_TIME_AFTER_LAST_MODIFICATION) + { + subfiles[dirIt.file_name()].modtime = dirIt.file_modtime(); + subfiles[dirIt.file_name()].size = dirIt.file_size(); + RS_DBG4("adding sub-file \"", dirIt.file_name(), "\""); + } + else + { + some_files_not_ready = true; + RS_INFO( "file: \"", dirIt.file_fullpath(), "\" is " + "probably being written to. Keep it for later"); + } + break; + case librs::util::FolderIterator::TYPE_DIR: + { + bool dir_is_accepted = true; + /* 64 is here as a safe limit, to make infinite loops + * impossible. + * TODO: Make it a visible constexpr in the header */ + if( (mMaxShareDepth > 0u && current_depth > mMaxShareDepth) + || (mMaxShareDepth == 0 && current_depth >= 64) ) + dir_is_accepted = false; - std::map subfiles ; - std::set subdirs ; + if(dir_is_accepted && mFollowSymLinks && mIgnoreDuplicates) + { + std::string real_path = RsDirUtil::removeSymLinks( + cumulated_path + "/" + dirIt.file_name() ); - for(;dirIt.isValid();dirIt.next()) - if(filterFile(dirIt.file_name())) - { - switch(dirIt.file_type()) - { - case librs::util::FolderIterator::TYPE_FILE: + if( existing_directories.end() != + existing_directories.find(real_path) ) + { + RS_WARN( "Directory: \"", cumulated_path, + "\" has real path: \"", real_path, + "\" which already belongs to another " + "shared directory. Ignoring" ); + dir_is_accepted = false; + } + else existing_directories.insert(real_path); + } - if(dirIt.file_modtime() + MIN_TIME_AFTER_LAST_MODIFICATION < now) - { - subfiles[dirIt.file_name()].modtime = dirIt.file_modtime() ; - subfiles[dirIt.file_name()].size = dirIt.file_size(); -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " adding sub-file \"" << dirIt.file_name() << "\"" << std::endl; -#endif - } - else - { - some_files_not_ready = true ; + if(dir_is_accepted) subdirs.insert(dirIt.file_name()); - std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being written to. Keeping it for later." << std::endl; - } + RS_DBG4("adding sub-dir \"", dirIt.file_name(), "\""); - break; + break; + } + default: + RS_ERR( "Got Dir entry of unknown type:", fType, + "with path \"", cumulated_path, "/", + dirIt.file_name(), "\"" ); + print_stacktrace(); + break; + } + } - case librs::util::FolderIterator::TYPE_DIR: - { - bool dir_is_accepted = true ; + /* update folder modificatoin time, which is the only way to detect + * e.g. removed or renamed files. */ + mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()); - if( (mMaxShareDepth > 0u && current_depth > mMaxShareDepth) || (mMaxShareDepth==0 && current_depth >= 64)) // 64 is here as a safe limit, to make loops impossible. - dir_is_accepted = false ; + // update file and dir lists for current directory. + mSharedDirectories->updateSubDirectoryList(indx,subdirs,mHashSalt); - if(dir_is_accepted && mFollowSymLinks && mIgnoreDuplicates) - { - std::string real_path = RsDirUtil::removeSymLinks(cumulated_path + "/" + dirIt.file_name()) ; + std::map new_files; + mSharedDirectories->updateSubFilesList(indx, subfiles, new_files); - if(existing_directories.end() != existing_directories.find(real_path)) - { - std::cerr << "(WW) Directory " << cumulated_path << " has real path " << real_path << " which already belongs to another shared directory. Ignoring" << std::endl; - dir_is_accepted = false ; - } - else - existing_directories.insert(real_path) ; - } - - if(dir_is_accepted) - subdirs.insert(dirIt.file_name()); - -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " adding sub-dir \"" << dirIt.file_name() << "\"" << std::endl; -#endif - } - break; - default: - std::cerr << "(EE) Dir entry of unknown type with path \"" << cumulated_path << "/" << dirIt.file_name() << "\"" << std::endl; - } - } - // update folder modificatoin time, which is the only way to detect e.g. removed or renamed files. - - mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()) ; - - // update file and dir lists for current directory. - - mSharedDirectories->updateSubDirectoryList(indx,subdirs,mHashSalt) ; - - std::map new_files ; - mSharedDirectories->updateSubFilesList(indx,subfiles,new_files) ; - - // now go through list of subfiles and request the hash to hashcache - - for(DirectoryStorage::FileIterator dit(mSharedDirectories,indx);dit;++dit) - { - // ask about the hash. If not present, ask HashCache. If not present, or different, the callback will update it. - - RsFileHash hash ; - - // mSharedDirectories does two things: store H(F), and compute H(H(F)), which is used in FT. The later is always needed. - - if(mHashCache->requestHash(cumulated_path + "/" + dit.name(),dit.size(),dit.modtime(),hash,this,*dit)) - mSharedDirectories->updateHash(*dit,hash,hash != dit.hash()); - } - } -#ifdef DEBUG_LOCAL_DIR_UPDATER - else - std::cerr << " directory is unchanged. Keeping existing files and subdirs list." << std::endl; -#endif - - // go through the list of sub-dirs and recursively update - - for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,indx) ; stored_dir_it; ++stored_dir_it) + // now go through list of subfiles and request the hash to hashcache + for( DirectoryStorage::FileIterator dit(mSharedDirectories,indx); + dit; ++dit ) { -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " recursing into " << stored_dir_it.name() << std::endl; -#endif - recursUpdateSharedDir(cumulated_path + "/" + stored_dir_it.name(), *stored_dir_it,existing_directories,current_depth+1,some_files_not_ready) ; + /* ask about the hash. If not present, ask HashCache. + * If not present, or different, the callback will update it. */ + RsFileHash hash; + + /* mSharedDirectories does two things: store H(F), and + * compute H(H(F)), which is used in FT. + * The later is always needed. */ + + if( mHashCache->requestHash( + cumulated_path + "/" + dit.name(), + dit.size(), dit.modtime(), hash, this, *dit ) ) + mSharedDirectories->updateHash(*dit, hash, hash != dit.hash()); } + } + + // go through the list of sub-dirs and recursively update + for( DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories, indx); + stored_dir_it; ++stored_dir_it ) + recursUpdateSharedDir( cumulated_path + "/" + stored_dir_it.name(), + *stored_dir_it, existing_directories, + current_depth+1, some_files_not_ready ); } bool LocalDirectoryUpdater::filterFile(const std::string& fname) const diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 8556b8198..07906b75f 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * + * Copyright (C) 2020-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -438,6 +438,35 @@ bool RsDirUtil::checkFile(const std::string& filename,uint64_t& file_size,bool d return true; } +rstime_t RsDirUtil::lastWriteTime( + const std::string& path, + std::error_condition& errc ) +{ + if(!fileExists(path)) + { + errc = std::errc::no_such_file_or_directory; + return 0; + } + +#ifdef WINDOWS_SYS + struct _stati64 buf; + std::wstring wPath; + librs::util::ConvertUtf8ToUtf16(path, wPath); + if ( 0 == _wstati64(wPath.c_str(), &buf)) +#else + struct stat64 buf; + if ( 0 == stat64(path.c_str(), &buf)) +#endif + { + /* errc is meaningful only if retval is 0 + * so it is not necessary but we clean it just in case */ + errc = std::error_condition(); + return buf.st_mtime; + } + + errc = std::errc::io_error; + return 0; +} bool RsDirUtil::checkDirectory(const std::string& dir) { diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 50e636541..862e981db 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * + * Copyright (C) 2020-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -27,11 +27,13 @@ #include #include #include -#include +#include +#include class RsThread; -#include +#include "retroshare/rstypes.h" +#include "util/rsmemory.h" #ifndef WINDOWS_SYS typedef int rs_lock_handle_t; @@ -92,6 +94,17 @@ bool moveFile(const std::string& source, const std::string& dest); bool removeFile(const std::string& file); bool fileExists(const std::string& file); bool checkFile(const std::string& filename,uint64_t& file_size,bool disallow_empty_file = false); + +/** + * @brief Retrieve file last modification time + * @param path path of the file + * @param errc optional storage for error details + * @return 0 on error, file modification time represented as unix epoch otherwise. + */ +rstime_t lastWriteTime( + const std::string& path, + std::error_condition& errc = RS_DEFAULT_STORAGE_PARAM(std::error_condition) ); + bool checkDirectory(const std::string& dir); bool checkCreateDirectory(const std::string& dir); From e1580868dc6ee36c926dcb457c35fff0cfa9a914 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sun, 18 Jul 2021 20:02:21 +0200 Subject: [PATCH 126/697] Avoid leaking non browsable shared single files to friends --- .../src/file_sharing/directory_storage.cc | 252 ++++++++++++------ 1 file changed, 167 insertions(+), 85 deletions(-) diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 2d78240c8..0accb336e 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2016 by Mr.Alice * + * Copyright (C) 2016 Mr.Alice * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -736,134 +738,214 @@ std::string LocalDirectoryStorage::locked_getVirtualPath(EntryIndex indx) const return it->second.virtualname + "/" + res; } -bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinaryData& bindata,const RsPeerId& client_id) +bool LocalDirectoryStorage::serialiseDirEntry( + const EntryIndex& indx, RsTlvBinaryData& bindata, + const RsPeerId& client_id ) { - RS_STACK_MUTEX(mDirStorageMtx) ; + RS_STACK_MUTEX(mDirStorageMtx); - const InternalFileHierarchyStorage::DirEntry *dir = mFileHierarchy->getDirEntry(indx); + const InternalFileHierarchyStorage::DirEntry* dir = + mFileHierarchy->getDirEntry(indx); #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE std::cerr << "Serialising Dir entry " << std::hex << indx << " for client id " << client_id << std::endl; #endif - if(dir == NULL) - { - std::cerr << "(EE) serialiseDirEntry: ERROR. Cannot find entry " << (void*)(intptr_t)indx << std::endl; - return false; - } - // compute list of allowed subdirs - std::vector allowed_subdirs ; - FileStorageFlags node_flags ; - std::list node_groups ; + if(!dir) + { + RS_ERR("Cannot find entry ", indx); + return false; + } - // for each subdir, compute the node flags and groups, then ask rsPeers to compute the mask that result from these flags for the particular peer supplied in parameter + // compute list of allowed subdirs + std::vector allowed_subdirs; + FileStorageFlags node_flags; + std::list node_groups; + + /* for each subdir, compute the node flags and groups, then ask rsPeers to + * compute the mask that result from these flags for the particular peer + * supplied in parameter */ + + for(uint32_t i=0;isubdirs.size();++i) + if(indx != 0 || ( + locked_getFileSharingPermissions( + dir->subdirs[i], node_flags, node_groups ) && + ( rsPeers->computePeerPermissionFlags( + client_id, node_flags, node_groups ) & + RS_FILE_HINTS_BROWSABLE ) )) + { + RsFileHash hash; + if(!mFileHierarchy->getDirHashFromIndex(dir->subdirs[i],hash)) + { + RS_ERR( "Cannot get hash from subdir index: ", + dir->subdirs[i], ". Weird bug." ); + print_stacktrace(); + return false; + } + allowed_subdirs.push_back(hash); - for(uint32_t i=0;isubdirs.size();++i) - if(indx != 0 || (locked_getFileSharingPermissions(dir->subdirs[i],node_flags,node_groups) && (rsPeers->computePeerPermissionFlags(client_id,node_flags,node_groups) & RS_FILE_HINTS_BROWSABLE))) - { - RsFileHash hash ; - if(!mFileHierarchy->getDirHashFromIndex(dir->subdirs[i],hash)) - { - std::cerr << "(EE) Cannot get hash from subdir index " << dir->subdirs[i] << ". Weird bug." << std::endl ; - return false; - } - allowed_subdirs.push_back(hash) ; #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE std::cerr << " pushing subdir " << hash << ", array position=" << i << " indx=" << dir->subdirs[i] << std::endl; #endif - } + } #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE else std::cerr << " not pushing subdir " << hash << ", array position=" << i << " indx=" << dir->subdirs[i] << ": permission denied for this peer." << std::endl; #endif - // now count the files that do not have a null hash (meaning the hash has indeed been computed) + /* now count the files that do not have a null hash (meaning the hash has + * indeed been computed), also in case files are shared singularly (without + * a shared directory) so they are child of root check browsability + * permission */ + uint32_t allowed_subfiles = 0; + for(uint32_t i=0; isubfiles.size(); ++i) + { + const InternalFileHierarchyStorage::FileEntry* file = + mFileHierarchy->getFileEntry(dir->subfiles[i]); + if(file != nullptr && !file->file_hash.isNull() + && ( indx !=0 || ( + locked_getFileSharingPermissions( + dir->subfiles[i], node_flags, node_groups ) && + rsPeers->computePeerPermissionFlags( + client_id, node_flags, node_groups ) & + RS_FILE_HINTS_BROWSABLE ) )) + allowed_subfiles++; + } - uint32_t allowed_subfiles = 0 ; + unsigned char* section_data = (unsigned char *) + rs_malloc(FL_BASE_TMP_SECTION_SIZE); + if(!section_data) return false; - for(uint32_t i=0;isubfiles.size();++i) - { - const InternalFileHierarchyStorage::FileEntry *file = mFileHierarchy->getFileEntry(dir->subfiles[i]) ; - if(file != NULL && !file->file_hash.isNull()) - allowed_subfiles++ ; - } + uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; + uint32_t section_offset = 0; - unsigned char *section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; + /* we need to send: + * - the name of the directory, its TS + * - the index entry for each subdir (the updte TS are exchanged at a + * higher level) + * - the file info for each subfile */ - if(!section_data) - return false ; + std::string virtual_dir_name = locked_getVirtualDirName(indx); - uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; - uint32_t section_offset = 0; + /* Manual serialization AGAIN! This is terrible and should be ported to the + * new serialization system ASAP! */ + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_DIR_NAME, virtual_dir_name )) + { free(section_data); return false; } + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_RECURS_MODIF_TS, + (uint32_t)dir->dir_most_recent_time )) + { free(section_data); return false; } + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_MODIF_TS, (uint32_t)dir->dir_modtime )) + { free(section_data); return false;} - // we need to send: - // - the name of the directory, its TS - // - the index entry for each subdir (the updte TS are exchanged at a higher level) - // - the file info for each subfile - // - std::string virtual_dir_name = locked_getVirtualDirName(indx) ; + // serialise number of subdirs and number of subfiles + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_RAW_NUMBER, (uint32_t)allowed_subdirs.size() )) + { free(section_data); return false; } + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_RAW_NUMBER, (uint32_t)allowed_subfiles )) + { free(section_data); return false; } - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,virtual_dir_name )) { free(section_data); return false ;} - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)dir->dir_most_recent_time)) { free(section_data); return false ;} - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)dir->dir_modtime )) { free(section_data); return false ;} + // serialise subdirs entry indexes + for(uint32_t i=0; isubfiles.size(); ++i) + { + uint32_t file_section_offset = 0; - // serialise directory subfiles, with info for each of them + const InternalFileHierarchyStorage::FileEntry* file = + mFileHierarchy->getFileEntry(dir->subfiles[i]); - unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; + if(file == nullptr || file->file_hash.isNull()) + { + RS_INFO( "skipping unhashed or Null file entry ", + dir->subfiles[i], " to get/send file info." ); + continue; + } - if(!file_section_data) - { - free(section_data); - return false ; - } + if(indx == 0) + { + if(!locked_getFileSharingPermissions( + dir->subfiles[i], node_flags, node_groups )) + { + RS_ERR( "Failure getting sharing permission for single file: ", + dir->subfiles[i] ); + print_stacktrace(); + continue; + } - uint32_t file_section_size = FL_BASE_TMP_SECTION_SIZE ; + if(!( rsPeers->computePeerPermissionFlags( + client_id, node_flags, node_groups ) & + RS_FILE_HINTS_BROWSABLE )) + { + RS_INFO( "Skipping single file shared without browse " + "permission" ); + continue; + } + } - for(uint32_t i=0;isubfiles.size();++i) - { - uint32_t file_section_offset = 0 ; + if(!FileListIO::writeField( + file_section_data, file_section_size, file_section_offset, + FILE_LIST_IO_TAG_FILE_NAME, file->file_name )) + { free(section_data); free(file_section_data); return false; } + if(!FileListIO::writeField( + file_section_data, file_section_size, file_section_offset, + FILE_LIST_IO_TAG_FILE_SIZE, file->file_size )) + { free(section_data); free(file_section_data); return false; } + if(!FileListIO::writeField( + file_section_data, file_section_size, file_section_offset, + FILE_LIST_IO_TAG_FILE_SHA1_HASH, file->file_hash )) + { free(section_data); free(file_section_data); return false; } + if(!FileListIO::writeField( + file_section_data, file_section_size, file_section_offset, + FILE_LIST_IO_TAG_MODIF_TS, (uint32_t)file->file_modtime )) + { free(section_data); free(file_section_data); return false; } - const InternalFileHierarchyStorage::FileEntry *file = mFileHierarchy->getFileEntry(dir->subfiles[i]) ; - - if(file == NULL || file->file_hash.isNull()) - { - std::cerr << "(II) skipping unhashed or Null file entry " << dir->subfiles[i] << " to get/send file info." << std::endl; - continue ; - } - - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)file->file_modtime)) { free(section_data);free(file_section_data);return false ;} - - // now write the whole string into a single section in the file - - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_offset)) { free(section_data); free(file_section_data);return false ;} + // now write the whole string into a single section in the file + if(!FileListIO::writeField( + section_data, section_size, section_offset, + FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY, + file_section_data, file_section_offset )) + { free(section_data); free(file_section_data); return false; } #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE std::cerr << " pushing subfile " << file->hash << ", array position=" << i << " indx=" << dir->subfiles[i] << std::endl; #endif - } - free(file_section_data) ; + } + free(file_section_data); #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl; #endif - bindata.bin_data = realloc(section_data,section_offset) ; // This discards the possibly unused trailing bytes in the end of section_data - bindata.bin_len = section_offset ; + // Discards the possibly unused trailing bytes in the end of section_data + bindata.bin_data = realloc(section_data,section_offset); + bindata.bin_len = section_offset; - return true ; + return true; } From 9970f9d22ffe8f30fc4b7786b71d9dfb06c8689e Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sun, 18 Jul 2021 20:14:26 +0200 Subject: [PATCH 127/697] Avoid leaking single shared file path in search results Single shared files are a bit special and contain the full path in the name because they are not shared as part of a directory, epurate the path component from matching process and from search result --- .../src/file_sharing/dir_hierarchy.cc | 57 ++++++++++------ libretroshare/src/file_sharing/p3filelists.cc | 66 ++++++++++++------- 2 files changed, 80 insertions(+), 43 deletions(-) diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index d93df1d1b..351212b12 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2016 by Mr.Alice * + * Copyright (C) 2016 Mr.Alice * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -29,6 +31,7 @@ #include "dir_hierarchy.h" #include "filelist_io.h" #include "file_sharing_defaults.h" +#include "util/cxx17retrocompat.h" #ifdef RS_DEEP_FILES_INDEX # include "deep_search/filesindex.hpp" @@ -784,27 +787,43 @@ int InternalFileHierarchyStorage::searchTerms( const std::list& terms, std::list& results ) const { - // most entries are likely to be files, so we could do a linear search over the entries tab. - // instead we go through the table of hashes. + /* most entries are likely to be files, so we could do a linear search over + * the entries tab. Instead we go through the table of hashes.*/ - for(std::map::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) - if(mNodes[it->second] != NULL) - { - const std::string &str1 = static_cast(mNodes[it->second])->file_name; + for(auto& it : std::as_const(mFileHashes)) + { + // node may be null for some hash waiting to be deleted + if(mNodes[it.second]) + { + rs_view_ptr tFileEntry = + static_cast(mNodes[it.second]); - for(std::list::const_iterator iter(terms.begin()); iter != terms.end(); ++iter) - { - /* always ignore case */ - const std::string &str2 = (*iter); + /* Most file will just have file name stored, but single file shared + * without a shared dir will contain full path instead of just the + * name, so purify it to perform the search */ + std::string tFilename = tFileEntry->file_name; + if(tFileEntry->file_name.find("/") != std::string::npos) + { + std::string _tParentDir; + RsDirUtil::splitDirFromFile( + tFileEntry->file_name, _tParentDir, tFilename ); + } - if(str1.end() != std::search( str1.begin(), str1.end(), str2.begin(), str2.end(), RsRegularExpression::CompareCharIC() )) - { - results.push_back(it->second); - break; - } - } - } - return 0 ; + for(auto& termIt : std::as_const(terms)) + { + /* always ignore case */ + if(tFilename.end() != std::search( + tFilename.begin(), tFilename.end(), + termIt.begin(), termIt.end(), + RsRegularExpression::CompareCharIC() )) + { + results.push_back(it.second); + break; + } + } + } + } + return 0; } bool InternalFileHierarchyStorage::check(std::string& error_string) // checks consistency of storage. diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 6eb3899e2..83523d0bf 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -30,7 +30,7 @@ #include "retroshare/rsids.h" #include "retroshare/rspeers.h" #include "retroshare/rsinit.h" - +#include "util/cxx17retrocompat.h" #include "rsserver/p3face.h" #define P3FILELISTS_DEBUG() std::cerr << time(NULL) << " : FILE_LISTS : " << __FUNCTION__ << " : " @@ -1476,7 +1476,9 @@ bool p3FileDatabase::search( return false; } -int p3FileDatabase::filterResults(const std::list& firesults,std::list& results,FileSearchFlags flags,const RsPeerId& peer_id) const +int p3FileDatabase::filterResults( + const std::list& firesults, std::list& results, + FileSearchFlags flags, const RsPeerId& peer_id ) const { results.clear(); @@ -1484,29 +1486,33 @@ int p3FileDatabase::filterResults(const std::list& firesults,std::list::const_iterator rit(firesults.begin()); rit != firesults.end(); ++rit) - { - DirDetails cdetails ; + for(void* rit: std::as_const(firesults)) + { + DirDetails cdetails; - if(!RequestDirDetails (*rit,cdetails,RS_FILE_HINTS_LOCAL)) - { - P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << *rit << std::endl; - continue ; - } + if(!RequestDirDetails(rit, cdetails, RS_FILE_HINTS_LOCAL)) + { + RS_ERR("Cannot retrieve dir details for entry: ", rit); + print_stacktrace(); + continue ; + } + + RS_DBG( "Filtering candidate: ", rit, + ", name: ", cdetails.name, ", path: ", cdetails.path, + ", flags: ", cdetails.flags, ", peer: ", peer_id ); + + if(!peer_id.isNull()) + { + FileSearchFlags permission_flags = + rsPeers->computePeerPermissionFlags( + peer_id, cdetails.flags, cdetails.parent_groups ); + + if (cdetails.type == DIR_TYPE_FILE && ( permission_flags & flags )) + { + cdetails.id.clear(); + results.push_back(cdetails); #ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Filtering candidate " << *rit << ", flags=" << cdetails.flags << ", peer=" << peer_id ; -#endif - - if(!peer_id.isNull()) - { - FileSearchFlags permission_flags = rsPeers->computePeerPermissionFlags(peer_id,cdetails.flags,cdetails.parent_groups) ; - - if (cdetails.type == DIR_TYPE_FILE && ( permission_flags & flags )) - { - cdetails.id.clear() ; - results.push_back(cdetails); -#ifdef DEBUG_P3FILELISTS - std::cerr << ": kept" << std::endl ; + std::cerr << ": kept" << std::endl ; #endif } #ifdef DEBUG_P3FILELISTS @@ -1518,7 +1524,19 @@ int p3FileDatabase::filterResults(const std::list& firesults,std::list Date: Sun, 18 Jul 2021 21:42:43 +0200 Subject: [PATCH 128/697] Improve RsDirUtil::lastWriteTime error reporting --- libretroshare/src/util/rsdir.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 07906b75f..a9311acff 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -458,13 +458,14 @@ rstime_t RsDirUtil::lastWriteTime( if ( 0 == stat64(path.c_str(), &buf)) #endif { - /* errc is meaningful only if retval is 0 - * so it is not necessary but we clean it just in case */ + /* errc output param is guaranted to be meaningful only if an error + * happens so is not strictly necessary but we clean it anyway just + * in case */ errc = std::error_condition(); return buf.st_mtime; } - errc = std::errc::io_error; + errc = std::error_condition(errno, std::generic_category()); return 0; } From e850e00a823ca9d7a9d7b351e5d7a3195ed95b3f Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 19 Jul 2021 16:40:13 +0200 Subject: [PATCH 129/697] Optimization, cleanup, compiler warning fix Chores I have made while working on single file share --- .../src/file_sharing/dir_hierarchy.cc | 157 ++++++---- .../src/file_sharing/directory_storage.cc | 20 +- .../src/file_sharing/directory_updater.cc | 5 +- libretroshare/src/file_sharing/p3filelists.cc | 278 ++++++++++-------- libretroshare/src/ft/ftserver.cc | 10 +- libretroshare/src/turtle/p3turtle.cc | 37 +-- libretroshare/src/util/folderiterator.cc | 7 +- libretroshare/src/util/folderiterator.h | 6 +- libretroshare/src/util/rsdir.h | 9 +- libretroshare/src/util/rstime.h | 3 +- 10 files changed, 309 insertions(+), 223 deletions(-) diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index 351212b12..6504da96f 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -73,7 +73,8 @@ InternalFileHierarchyStorage::InternalFileHierarchyStorage() : mRoot(0) mTotalFiles = 0 ; } -bool InternalFileHierarchyStorage::getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const +bool InternalFileHierarchyStorage::getDirHashFromIndex( + const DirectoryStorage::EntryIndex& index, RsFileHash& hash ) const { if(!checkIndex(index,FileStorageNode::TYPE_DIR)) return false ; @@ -82,6 +83,7 @@ bool InternalFileHierarchyStorage::getDirHashFromIndex(const DirectoryStorage::E return true; } + bool InternalFileHierarchyStorage::getIndexFromDirHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) { std::map::iterator it = mDirHashes.find(hash) ; @@ -91,35 +93,39 @@ bool InternalFileHierarchyStorage::getIndexFromDirHash(const RsFileHash& hash,Di index = it->second; - // make sure the hash actually points to some existing file. If not, remove it. This is a lazy update of dir hashes: when we need them, we check them. - if(!checkIndex(index, FileStorageNode::TYPE_DIR) || static_cast(mNodes[index])->dir_hash != hash) - { - std::cerr << "(II) removing non existing hash from dir hash list: " << hash << std::endl; - - mDirHashes.erase(it) ; - return false ; - } + /* make sure the hash actually points to some existing directory. If not, + * remove it. This is an opportunistic update of dir hashes: when we need + * them, we check them. */ + if( !checkIndex(index, FileStorageNode::TYPE_DIR) || + static_cast(mNodes[index])->dir_hash != hash ) + { + RS_INFO("removing non existing dir hash: ", hash, " from dir hash list"); + mDirHashes.erase(it); + return false; + } return true; } -bool InternalFileHierarchyStorage::getIndexFromFileHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) + +bool InternalFileHierarchyStorage::getIndexFromFileHash( + const RsFileHash& hash, DirectoryStorage::EntryIndex& index ) { - std::map::iterator it = mFileHashes.find(hash) ; + auto it = std::as_const(mFileHashes).find(hash); + if(it == mFileHashes.end()) return false; - if(it == mFileHashes.end()) - return false; + index = it->second; - index = it->second; + /* make sure the hash actually points to some existing file. If not, remove + * it. This is an opportunistic update of file hashes: when we need them, + * we check them. */ + if( !checkIndex(it->second, FileStorageNode::TYPE_FILE) || + static_cast(mNodes[index])->file_hash != hash ) + { + RS_INFO("removing non existing file hash: ", hash, " from file hash list"); + mFileHashes.erase(it); + return false; + } - // make sure the hash actually points to some existing file. If not, remove it. This is a lazy update of file hashes: when we need them, we check them. - if(!checkIndex(it->second, FileStorageNode::TYPE_FILE) || static_cast(mNodes[index])->file_hash != hash) - { - std::cerr << "(II) removing non existing hash from file hash list: " << hash << std::endl; - - mFileHashes.erase(it) ; - return false ; - } - - return true; + return true; } bool InternalFileHierarchyStorage::getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const @@ -158,10 +164,13 @@ bool InternalFileHierarchyStorage::isIndexValid(DirectoryStorage::EntryIndex e) return e < mNodes.size() && mNodes[e] != NULL ; } -bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::set& subdirs, const RsFileHash& random_hash_seed) +bool InternalFileHierarchyStorage::updateSubDirectoryList( + const DirectoryStorage::EntryIndex& indx, + const std::set& subdirs, + const RsFileHash& random_hash_seed ) { - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return false; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + return false; DirEntry& d(*static_cast(mNodes[indx])) ; @@ -287,10 +296,17 @@ bool InternalFileHierarchyStorage::checkIndex(DirectoryStorage::EntryIndex indx, return true; } -bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map& subfiles,std::map& new_files) +bool InternalFileHierarchyStorage::updateSubFilesList( + const DirectoryStorage::EntryIndex& indx, + const std::map& subfiles, + std::map& new_files ) { - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return false; + if(!checkIndex(indx, FileStorageNode::TYPE_DIR)) + { + RS_ERR("indx: ", indx, std::errc::not_a_directory); + print_stacktrace(); + return false; + } DirEntry& d(*static_cast(mNodes[indx])) ; new_files = subfiles ; @@ -315,9 +331,11 @@ bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::En continue; } - if(it->second.modtime != f.file_modtime || it->second.size != f.file_size) // file is newer and/or has different size + // file is newer and/or has different size + if(it->second.modtime != f.file_modtime || it->second.size != f.file_size) { - f.file_hash.clear(); // hash needs recomputing + // hash needs recomputing + f.file_hash.clear(); f.file_modtime = it->second.modtime; f.file_size = it->second.size; @@ -345,13 +363,16 @@ bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::En } return true; } -bool InternalFileHierarchyStorage::updateHash(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash) +bool InternalFileHierarchyStorage::updateHash( + const DirectoryStorage::EntryIndex& file_index, const RsFileHash& hash ) { - if(!checkIndex(file_index,FileStorageNode::TYPE_FILE)) - { - std::cerr << "[directory storage] (EE) cannot update file at index " << file_index << ". Not a valid index, or not a file." << std::endl; - return false; - } + if(!checkIndex(file_index, FileStorageNode::TYPE_FILE)) + { + RS_ERR( "Cannot update file at index ", file_index, + ". Not a valid index, or not a file." ); + print_stacktrace(); + return false; + } #ifdef DEBUG_DIRECTORY_STORAGE std::cerr << "[directory storage] updating hash at index " << file_index << ", hash=" << hash << std::endl; #endif @@ -439,14 +460,20 @@ DirectoryStorage::EntryIndex InternalFileHierarchyStorage::allocateNewIndex() return mNodes.size()-1 ; } -bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryIndex& indx,const std::string& dir_name,rstime_t most_recent_time,rstime_t dir_modtime,const std::vector& subdirs_hash,const std::vector& subfiles_array) +bool InternalFileHierarchyStorage::updateDirEntry( + const DirectoryStorage::EntryIndex& indx, const std::string& dir_name, + rstime_t most_recent_time, rstime_t dir_modtime, + const std::vector& subdirs_hash, + const std::vector& subfiles_array ) { - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - { - std::cerr << "[directory storage] (EE) cannot update dir at index " << indx << ". Not a valid index, or not an existing dir." << std::endl; - return false; - } - DirEntry& d(*static_cast(mNodes[indx])) ; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + { + RS_ERR( "cannot update dir at index ", indx, ". Not a valid index, or " + "not an existing dir." ); + return false; + } + + DirEntry& d(*static_cast(mNodes[indx])); #ifdef DEBUG_DIRECTORY_STORAGE std::cerr << "Updating dir entry: name=\"" << dir_name << "\", most_recent_time=" << most_recent_time << ", modtime=" << dir_modtime << std::endl; @@ -706,14 +733,14 @@ const InternalFileHierarchyStorage::FileStorageNode *InternalFileHierarchyStorag return NULL ; } -const InternalFileHierarchyStorage::DirEntry *InternalFileHierarchyStorage::getDirEntry(DirectoryStorage::EntryIndex indx) const +const InternalFileHierarchyStorage::DirEntry* +InternalFileHierarchyStorage::getDirEntry(DirectoryStorage::EntryIndex indx) const { - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return NULL ; - - return static_cast(mNodes[indx]) ; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) return nullptr; + return static_cast(mNodes[indx]); } -const InternalFileHierarchyStorage::FileEntry *InternalFileHierarchyStorage::getFileEntry(DirectoryStorage::EntryIndex indx) const +const InternalFileHierarchyStorage::FileEntry* +InternalFileHierarchyStorage::getFileEntry(DirectoryStorage::EntryIndex indx) const { if(!checkIndex(indx,FileStorageNode::TYPE_FILE)) return NULL ; @@ -757,7 +784,10 @@ bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,DirectorySt class DirectoryStorageExprFileEntry: public RsRegularExpression::ExpFileEntry { public: - DirectoryStorageExprFileEntry(const InternalFileHierarchyStorage::FileEntry& fe,const InternalFileHierarchyStorage::DirEntry& parent) : mFe(fe),mDe(parent) {} + DirectoryStorageExprFileEntry( + const InternalFileHierarchyStorage::FileEntry& fe, + const InternalFileHierarchyStorage::DirEntry& parent ) : + mFe(fe), mDe(parent) {} inline virtual const std::string& file_name() const { return mFe.file_name ; } inline virtual uint64_t file_size() const { return mFe.file_size ; } @@ -771,14 +801,18 @@ private: const InternalFileHierarchyStorage::DirEntry& mDe ; }; -int InternalFileHierarchyStorage::searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const +int InternalFileHierarchyStorage::searchBoolExp( + RsRegularExpression::Expression* exp, + std::list& results ) const { - for(std::map::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) - if(mNodes[it->second] != NULL && exp->eval( - DirectoryStorageExprFileEntry(*static_cast(mNodes[it->second]), - *static_cast(mNodes[mNodes[it->second]->parent_index]) - ))) - results.push_back(it->second); + for(auto& it: std::as_const(mFileHashes)) + if(mNodes[it.second]) + if(exp->eval( + DirectoryStorageExprFileEntry( + *static_cast(mNodes[it.second]), + *static_cast(mNodes[mNodes[it.second]->parent_index]) + ) )) + results.push_back(it.second); return 0; } @@ -977,8 +1011,9 @@ void InternalFileHierarchyStorage::recursPrint(int depth,DirectoryStorage::Entry bool InternalFileHierarchyStorage::nodeAccessError(const std::string& s) { - std::cerr << "(EE) InternalDirectoryStructure: ERROR: " << s << std::endl; - return false ; + RS_ERR(s); + print_stacktrace(); + return false; } // Removes the given subdirectory from the parent node and all its pendign subdirs and files. diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 0accb336e..402cae533 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -70,8 +70,11 @@ DirectoryStorage::FileIterator& DirectoryStorage::FileIterator::operator++() return *this; } -DirectoryStorage::EntryIndex DirectoryStorage::FileIterator::operator*() const { return mStorage->getSubFileIndex(mParentIndex,mFileTabIndex) ; } -DirectoryStorage::EntryIndex DirectoryStorage::DirIterator ::operator*() const { return mStorage->getSubDirIndex(mParentIndex,mDirTabIndex) ; } +DirectoryStorage::EntryIndex DirectoryStorage::FileIterator::operator*() const +{ return mStorage->getSubFileIndex(mParentIndex, mFileTabIndex); } + +DirectoryStorage::EntryIndex DirectoryStorage::DirIterator::operator*() const +{ return mStorage->getSubDirIndex(mParentIndex, mDirTabIndex); } DirectoryStorage::FileIterator::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } DirectoryStorage::DirIterator ::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } @@ -142,7 +145,9 @@ bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx, const std: mChanged = true ; return res ; } -bool DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::map& subfiles,std::map& new_files) +bool DirectoryStorage::updateSubFilesList( + const EntryIndex& indx, const std::map& subfiles, + std::map& new_files ) { RS_STACK_MUTEX(mDirStorageMtx) ; bool res = mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ; @@ -351,7 +356,8 @@ int LocalDirectoryStorage::searchHash(const RsFileHash& hash, RsFileHash& real_h return false ; } -void LocalDirectoryStorage::setSharedDirectoryList(const std::list& lst) +void LocalDirectoryStorage::setSharedDirectoryList( + const std::list& lst ) { std::set dirs_with_new_virtualname ; bool dirs_with_changed_flags = false ; @@ -382,7 +388,9 @@ void LocalDirectoryStorage::setSharedDirectoryList(const std::list new_dirs ; @@ -532,7 +540,7 @@ bool LocalDirectoryStorage::updateHash( #endif ret = (!update_internal_hierarchy) || - mFileHierarchy->updateHash(index,hash); + mFileHierarchy->updateHash(index, hash); } // RS_STACK_MUTEX(mDirStorageMtx); #ifdef RS_DEEP_FILES_INDEX diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc index 16f09149c..7d6828712 100644 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ b/libretroshare/src/file_sharing/directory_updater.cc @@ -3,7 +3,7 @@ * * * libretroshare: retroshare core library * * * - * Copyright (C) 2016 by Mr.Alice * + * Copyright (C) 2016 Mr.Alice * * Copyright (C) 2021 Gioacchino Mazzurco * * Copyright (C) 2021 Asociación Civil Altermundi * * * @@ -404,7 +404,8 @@ void LocalDirectoryUpdater::hash_callback(uint32_t client_param, const std::stri bool LocalDirectoryUpdater::hash_confirm(uint32_t client_param) { - return mSharedDirectories->getEntryType(DirectoryStorage::EntryIndex(client_param)) == DIR_TYPE_FILE ; + return mSharedDirectories->getEntryType( + DirectoryStorage::EntryIndex(client_param) ) == DIR_TYPE_FILE; } void LocalDirectoryUpdater::setFileWatchPeriod(int seconds) diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 83523d0bf..419196275 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2018 by Mr.Alice * + * Copyright (C) 2018 Mr.Alice * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -1044,31 +1046,36 @@ void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIn } // This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files. -int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const +int p3FileDatabase::RequestDirDetails( + void* ref, DirDetails& d, FileSearchFlags flags ) const { - RS_STACK_MUTEX(mFLSMtx) ; + RS_STACK_MUTEX(mFLSMtx); - d.children.clear(); + d.children.clear(); - // Case where the pointer is NULL, which means we're at the top of the list of shared directories for all friends (including us) - // or at the top of our own list of shared directories, depending on the flags. + /* Case where the pointer is NULL, which means we're at the top of the list + * of shared directories for all friends (including us) or at the top of our + * own list of shared directories, depending on the flags. + * + * Friend index is used as follows: + * 0 : own id + * 1...n : other friends + * + * entry_index: starts at 0. + * + * The point is: we cannot use (0,0) because it encodes to NULL. No existing + * combination should encode to NULL. + * So we need to properly convert the friend index into 0 or into a friend + * tab index in mRemoteDirectories. + * + * We should also check the consistency between flags and the content of ref. + */ - // Friend index is used as follows: - // 0 : own id - // 1...n : other friends - // - // entry_index: starts at 0. - // - // The point is: we cannot use (0,0) because it encodes to NULL. No existing combination should encode to NULL. - // So we need to properly convert the friend index into 0 or into a friend tab index in mRemoteDirectories. - // - // We should also check the consistency between flags and the content of ref. - - if (ref == NULL) - { - d.ref = NULL ; - d.type = DIR_TYPE_ROOT; - d.parent = NULL; + if (ref == nullptr) + { + d.ref = nullptr; + d.type = DIR_TYPE_ROOT; + d.parent = nullptr; d.prow = -1; d.name = "root"; d.hash.clear() ; @@ -1078,12 +1085,13 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags d.max_mtime = 0 ; if(flags & RS_FILE_HINTS_LOCAL) - { - void *p; + { + void *p = nullptr; - { - convertEntryIndexToPointer(0,0,p); // root of own directories - DirStub stub; + { + // root of own directories + convertEntryIndexToPointer(0, 0, p); + DirStub stub; stub.type = DIR_TYPE_PERSON; stub.name = mServCtrl->getOwnId().toStdString(); stub.ref = p; @@ -1092,9 +1100,11 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags if(mExtraFiles->size() > 0) { - convertEntryIndexToPointer(0,1,p); // local shared files from extra list - DirStub stub; - stub.type = DIR_TYPE_PERSON; // not totally exact, but used as a trick. + // local shared files from extra list + convertEntryIndexToPointer(0, 1, p); + DirStub stub; + // not totally exact, but used as a trick. + stub.type = DIR_TYPE_PERSON; stub.name = "[Extra List]"; stub.ref = p; @@ -1127,18 +1137,19 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags } uint32_t fi; - DirectoryStorage::EntryIndex e ; + DirectoryStorage::EntryIndex e; convertPointerToEntryIndex(ref,e,fi); - // check consistency - if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 1 && (flags & RS_FILE_HINTS_LOCAL))) - { - P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; - return false ; - } + // check consistency + if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || + (fi > 1 && (flags & RS_FILE_HINTS_LOCAL))) + { + RS_ERR("Remote request on local index or local request on remote index"); + return false; + } - if((flags & RS_FILE_HINTS_LOCAL) && fi == 1) // extra list + if((flags & RS_FILE_HINTS_LOCAL) && fi == 1) // extra list { getExtraFilesDirDetails(ref,e,d); @@ -1150,25 +1161,28 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags } - DirectoryStorage *storage = (flags & RS_FILE_HINTS_LOCAL)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]); + DirectoryStorage* storage = + (flags & RS_FILE_HINTS_LOCAL) ? + ((DirectoryStorage*) mLocalSharedDirs) : + ((DirectoryStorage*) mRemoteDirectories[fi-1]); - // Case where the index is the top of a single person. Can be us, or a friend. + /* Case where the index is the top of a single person. + * Can be us, or a friend. */ + if(!storage || !storage->extractData(e,d)) + { + RS_WARN( "request on index; ", e, ", for directory ID:", + ( (!storage)? ("[NULL]") : (storage->peerId().toStdString()) ), + " failed" ); + return false; + } - if(storage==NULL || !storage->extractData(e,d)) - { -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "(WW) request on index " << e << ", for directory ID=" << ((storage==NULL)?("[NULL]"):(storage->peerId().toStdString())) << " failed. This should not happen." << std::endl; -#endif - return false ; - } + /* update indexes. This is a bit hacky, but does the job. The cast to + * intptr_t is the proper way to convert a pointer into an int. */ + convertEntryIndexToPointer((intptr_t)d.ref,fi,d.ref); - // update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert - // a pointer into an int. - - convertEntryIndexToPointer((intptr_t)d.ref,fi,d.ref) ; - - for(uint32_t i=0;i((intptr_t)d.children[i].ref,fi,d.children[i].ref); + for(uint32_t i=0; i( + (intptr_t) d.children[i].ref, fi, d.children[i].ref ); if(e == 0) // root { @@ -1178,9 +1192,9 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags else { if(d.parent == 0) // child of root node - d.prow = (flags & RS_FILE_HINTS_LOCAL)?0:(fi-1); + d.prow = (flags & RS_FILE_HINTS_LOCAL) ? 0 : (fi-1); else - d.prow = storage->parentRow(e) ; + d.prow = storage->parentRow(e); convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ; } @@ -1307,7 +1321,9 @@ uint32_t p3FileDatabase::watchPeriod() return mLocalDirWatcher->fileWatchPeriod(); } -int p3FileDatabase::SearchKeywords(const std::list& keywords, std::list& results,FileSearchFlags flags,const RsPeerId& client_peer_id) +int p3FileDatabase::SearchKeywords( + const std::list& keywords, std::list& results, + FileSearchFlags flags, const RsPeerId& client_peer_id ) { if(flags & RS_FILE_HINTS_LOCAL) { @@ -1319,15 +1335,15 @@ int p3FileDatabase::SearchKeywords(const std::list& keywords, std:: mLocalSharedDirs->searchTerms(keywords,firesults) ; - for(std::list::iterator it(firesults.begin());it!=firesults.end();++it) - { - void *p=NULL; - convertEntryIndexToPointer(*it,0,p); - pointers.push_back(p) ; - } + for(auto& it: std::as_const(firesults)) + { + void *p = nullptr; + convertEntryIndexToPointer(it, 0, p); + pointers.push_back(p); + } } - filterResults(pointers,results,flags,client_peer_id) ; + filterResults(pointers, results, flags, client_peer_id); } if(flags & RS_FILE_HINTS_REMOTE) @@ -1610,78 +1626,90 @@ void p3FileDatabase::tickSend() void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item) { - RsFileListsSyncResponseItem *ritem = new RsFileListsSyncResponseItem; + RsFileListsSyncResponseItem* ritem = new RsFileListsSyncResponseItem; - // look at item TS. If local is newer, send the full directory content. - { - RS_STACK_MUTEX(mFLSMtx) ; + // look at item TS. If local is newer, send the full directory content. + { + RS_STACK_MUTEX(mFLSMtx); -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Received directory sync request from peer " << item->PeerId() << ". hash=" << item->entry_hash << ", flags=" << (void*)(intptr_t)item->flags << ", request id: " << std::hex << item->request_id << std::dec << ", last known TS: " << item->last_known_recurs_modf_TS << std::endl; -#endif + RS_DBG( "Received directory sync request from peer ", item->PeerId(), + ". hash=", item->entry_hash, ", flags=", item->flags, + ", request id: ", item->request_id, ", last known TS: ", + item->last_known_recurs_modf_TS ); - EntryIndex entry_index = DirectoryStorage::NO_INDEX; + EntryIndex entry_index = DirectoryStorage::NO_INDEX; + if(!mLocalSharedDirs->getIndexFromDirHash(item->entry_hash,entry_index)) + { + RS_DBG("Cannot find entry index for hash ", item->entry_hash, + " cannot respond to sync request." ); + return; + } - if(!mLocalSharedDirs->getIndexFromDirHash(item->entry_hash,entry_index)) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl; -#endif - return; - } + uint32_t entry_type = mLocalSharedDirs->getEntryType(entry_index); + ritem->PeerId(item->PeerId()); + ritem->request_id = item->request_id; + ritem->entry_hash = item->entry_hash; - uint32_t entry_type = mLocalSharedDirs->getEntryType(entry_index) ; - ritem->PeerId(item->PeerId()) ; - ritem->request_id = item->request_id; - ritem->entry_hash = item->entry_hash ; + std::list node_groups; + FileStorageFlags node_flags; - std::list node_groups; - FileStorageFlags node_flags; + if(entry_type != DIR_TYPE_DIR) + { + RS_DBG( "Directory does not exist anymore, or is not a directory, " + "or permission denied. Answering with proper flags." ); + ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | + RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED; + } + else if( entry_index != 0 && + (!mLocalSharedDirs->getFileSharingPermissions( + entry_index, node_flags,node_groups ) || + !(rsPeers->computePeerPermissionFlags( + item->PeerId(), node_flags, node_groups ) & + RS_FILE_HINTS_BROWSABLE)) ) + { + RS_ERR("cannot get file permissions for entry index: ", entry_index, + ", or permission denied." ); + ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | + RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED; + } + else + { + rstime_t local_recurs_max_time; + mLocalSharedDirs->getDirectoryRecursModTime( + entry_index, local_recurs_max_time ); - if(entry_type != DIR_TYPE_DIR) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory does not exist anymore, or is not a directory, or permission denied. Answering with proper flags." << std::endl; -#endif - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED ; - } - else if(entry_index != 0 && (!mLocalSharedDirs->getFileSharingPermissions(entry_index,node_flags,node_groups) || !(rsPeers->computePeerPermissionFlags(item->PeerId(),node_flags,node_groups) & RS_FILE_HINTS_BROWSABLE))) - { - P3FILELISTS_ERROR() << "(EE) cannot get file permissions for entry index " << (void*)(intptr_t)entry_index << ", or permission denied." << std::endl; - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED ; - } - else - { - rstime_t local_recurs_max_time ; - mLocalSharedDirs->getDirectoryRecursModTime(entry_index,local_recurs_max_time) ; + /* normally, should be "<", but since we provided the TS it should + * be equal, so != is more robust. */ + if(item->last_known_recurs_modf_TS != local_recurs_max_time) + { + RS_DBG( "Directory is more recent than what the friend knows. " + "Sending full dir content as response."); - if(item->last_known_recurs_modf_TS != local_recurs_max_time) // normally, should be "<", but since we provided the TS it should be equal, so != is more robust. - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory is more recent than what the friend knows. Sending full dir content as response." << std::endl; -#endif + ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | + RsFileListsItem::FLAGS_SYNC_DIR_CONTENT; + ritem->last_known_recurs_modf_TS = local_recurs_max_time; - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_SYNC_DIR_CONTENT; - ritem->last_known_recurs_modf_TS = local_recurs_max_time; + /* We supply the peer id, in order to possibly remove some + * subdirs, if entries are not allowed to be seen by this peer. + */ + mLocalSharedDirs->serialiseDirEntry( + entry_index, ritem->directory_content_data, + item->PeerId() ); + } + else + { + RS_DBG3( "Directory is up to date w.r.t. what the friend knows." + " Sending ACK." ); - // We supply the peer id, in order to possibly remove some subdirs, if entries are not allowed to be seen by this peer. - mLocalSharedDirs->serialiseDirEntry(entry_index,ritem->directory_content_data,item->PeerId()) ; - } - else - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory is up to date w.r.t. what the friend knows. Sending ACK." << std::endl; -#endif + ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | + RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE; + ritem->last_known_recurs_modf_TS = local_recurs_max_time; + } + } + } - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE ; - ritem->last_known_recurs_modf_TS = local_recurs_max_time ; - } - } - } - - // sends the response. - - splitAndSendItem(ritem) ; + // sends the response. + splitAndSendItem(ritem); } void p3FileDatabase::splitAndSendItem(RsFileListsSyncResponseItem *ritem) diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 07a400acf..2da3c7398 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2008 by Robert Fernie * + * Copyright (C) 2008 Robert Fernie * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -873,9 +875,11 @@ int ftServer::SearchKeywords(std::list keywords, std::listSearchKeywords(keywords, results,flags,RsPeerId()); } -int ftServer::SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) +int ftServer::SearchKeywords( + std::list keywords, std::list &results, + FileSearchFlags flags, const RsPeerId& peer_id ) { - return mFileDatabase->SearchKeywords(keywords, results,flags,peer_id); + return mFileDatabase->SearchKeywords(keywords, results, flags, peer_id); } int ftServer::SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags) diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 10069056a..65f14048e 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2009-2018 by Cyril Soler * + * Copyright (C) 2009-2018 Cyril Soler * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -26,6 +28,10 @@ #include #include #include +#include +#include +#include +#include #include "rsserver/p3face.h" #include "crypto/rscrypto.h" @@ -39,13 +45,7 @@ #include "ft/ftcontroller.h" #include "p3turtle.h" - -#include -#include -#include - -#include - +#include "util/cxx17retrocompat.h" #include "util/rsdebug.h" #include "util/rsprint.h" #include "util/rsrandom.h" @@ -1975,7 +1975,8 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) // -void RsTurtleStringSearchRequestItem::search(std::list& result) const +void RsTurtleStringSearchRequestItem::search( + std::list& result ) const { /* call to core */ std::list initialResults; @@ -1988,17 +1989,19 @@ void RsTurtleStringSearchRequestItem::search(std::list& result) std::cerr << "Performing rsFiles->search()" << std::endl ; #endif // now, search! - rsFiles->SearchKeywords(words, initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId()); + rsFiles->SearchKeywords( + words, initialResults, + RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE, PeerId() ); #ifdef P3TURTLE_DEBUG std::cerr << initialResults.size() << " matches found." << std::endl ; #endif result.clear() ; - for(std::list::const_iterator it(initialResults.begin());it!=initialResults.end();++it) + for(auto& it: std::as_const(initialResults)) { // retain only file type - if (it->type == DIR_TYPE_DIR) + if (it.type == DIR_TYPE_DIR) { #ifdef P3TURTLE_DEBUG std::cerr << " Skipping directory " << it->name << std::endl ; @@ -2006,12 +2009,12 @@ void RsTurtleStringSearchRequestItem::search(std::list& result) continue; } - TurtleFileInfo i ; - i.hash = it->hash ; - i.size = it->size ; - i.name = it->name ; + TurtleFileInfo i; + i.hash = it.hash; + i.size = it.size; + i.name = it.name; - result.push_back(i) ; + result.push_back(i); } } void RsTurtleRegExpSearchRequestItem::search(std::list& result) const diff --git a/libretroshare/src/util/folderiterator.cc b/libretroshare/src/util/folderiterator.cc index c67204fc6..df3203ba2 100644 --- a/libretroshare/src/util/folderiterator.cc +++ b/libretroshare/src/util/folderiterator.cc @@ -38,8 +38,11 @@ namespace librs { namespace util { -FolderIterator::FolderIterator(const std::string& folderName, bool allow_symlinks, bool allow_files_from_the_future) - : mFolderName(folderName),mAllowSymLinks(allow_symlinks),mAllowFilesFromTheFuture(allow_files_from_the_future) +FolderIterator::FolderIterator( + const std::string& folderName, bool allow_symlinks, + bool allow_files_from_the_future ): + mFolderName(folderName), mAllowSymLinks(allow_symlinks), + mAllowFilesFromTheFuture(allow_files_from_the_future) { is_open = false ; validity = false ; diff --git a/libretroshare/src/util/folderiterator.h b/libretroshare/src/util/folderiterator.h index 19cbb8e9c..5a853eae3 100644 --- a/libretroshare/src/util/folderiterator.h +++ b/libretroshare/src/util/folderiterator.h @@ -44,8 +44,10 @@ namespace librs { namespace util { class FolderIterator { public: - FolderIterator(const std::string& folderName,bool allow_symlinks,bool allow_files_from_the_future = true); - ~FolderIterator(); + FolderIterator( + const std::string& folderName, bool allow_symlinks, + bool allow_files_from_the_future = true ); + ~FolderIterator(); enum { TYPE_UNKNOWN = 0x00, TYPE_FILE = 0x01, diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 862e981db..9f4b2e6b5 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -81,10 +81,11 @@ const char *scanf_string_for_uint(int bytes) ; int breakupDirList(const std::string& path, std::list &subdirs); -// Splits the path into parent directory and file. File can be empty if full_path is a dir ending with '/' -// if full_path does not contain a directory, then dir will be "." and file will be full_path. - -bool splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file); +/** Splits the path into parent directory and file. File can be empty if + * full_path is a dir ending with '/' if full_path does not contain a directory, + * then dir will be "." and file will be full_path */ +bool splitDirFromFile( const std::string& full_path, + std::string& dir, std::string& file ); bool copyFile(const std::string& source,const std::string& dest); diff --git a/libretroshare/src/util/rstime.h b/libretroshare/src/util/rstime.h index 6cc01e486..c17f2a5c7 100644 --- a/libretroshare/src/util/rstime.h +++ b/libretroshare/src/util/rstime.h @@ -3,7 +3,8 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2013-2013 by Cyril Soler * + * Copyright 2013 Cyril Soler * + * Copyright 2018 Gioacchino Mazzurco * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * From 6cf60f1addb50cf509d5a30d943af1b817c41248 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 19 Jul 2021 21:07:52 +0200 Subject: [PATCH 130/697] Removed not needed libraries in VOIP.pro for Windows build --- plugins/VOIP/VOIP.pro | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index 3f675c1a1..1ec4defa4 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -63,12 +63,6 @@ win32 { DEPENDPATH += . $$INC_DIR INCLUDEPATH += . $$INC_DIR - - USE_PRECOMPILED_LIBS = - - # Should we keep these after removing opencv?? - LIBS += -lole32 -loleaut32 -luuid -lvfw32 - LIBS += -llibjpeg-turbo -lzlib } #################################### MacOSX ##################################### From 282f4f18a3a7a5aa40187ab8263a22979458b636 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 19 Jul 2021 21:08:41 +0200 Subject: [PATCH 131/697] Removed library opencv from Windows build environment --- build_scripts/Windows/build-libs/Makefile | 29 +---------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/build_scripts/Windows/build-libs/Makefile b/build_scripts/Windows/build-libs/Makefile index e6927150f..8bab46b92 100644 --- a/build_scripts/Windows/build-libs/Makefile +++ b/build_scripts/Windows/build-libs/Makefile @@ -4,7 +4,6 @@ MINIUPNPC_VERSION=2.0 OPENSSL_VERSION=1.1.1h SPEEX_VERSION=1.2.0 SPEEXDSP_VERSION=1.2rc3 -OPENCV_VERSION=4.5.0 LIBXML2_VERSION=2.9.7 LIBXSLT_VERSION=1.1.32 CURL_VERSION=7.58.0 @@ -19,7 +18,7 @@ DOWNLOAD_PATH?=download BUILD_PATH=build LIBS_PATH?=libs -all: dirs zlib bzip2 miniupnpc openssl speex speexdsp opencv libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs +all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs download: \ $(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz \ @@ -28,7 +27,6 @@ download: \ $(DOWNLOAD_PATH)/openssl-$(OPENSSL_VERSION).tar.gz \ $(DOWNLOAD_PATH)/speex-$(SPEEX_VERSION).tar.gz \ $(DOWNLOAD_PATH)/speexdsp-$(SPEEXDSP_VERSION).tar.gz \ - $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz \ $(DOWNLOAD_PATH)/libxml2-$(LIBXML2_VERSION).tar.gz \ $(DOWNLOAD_PATH)/libxslt-$(LIBXSLT_VERSION).tar.gz \ $(DOWNLOAD_PATH)/curl-$(CURL_VERSION).tar.gz \ @@ -187,31 +185,6 @@ $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION): $(DOWNLOAD_PATH)/speexdsp-$(SPEEXDSP rm -r -f speexdsp-$(SPEEXDSP_VERSION) mv $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION).tmp $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION) -opencv: $(BUILD_PATH)/opencv-$(OPENCV_VERSION) - -$(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz: - wget --no-check-certificate https://github.com/opencv/opencv/archive/$(OPENCV_VERSION).tar.gz -O $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - -$(BUILD_PATH)/opencv-$(OPENCV_VERSION): $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - # prepare - rm -r -f $(BUILD_PATH)/opencv-* - tar xvf $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - # Remove version numbers from libraries. Is there a switch? - sed -i -e's/\(ocv_update(OPENCV_DLLVERSION \).*$$/\1"")/' opencv-$(OPENCV_VERSION)/CMakeLists.txt - # build - mkdir -p opencv-$(OPENCV_VERSION)/build - #cd opencv-$(OPENCV_VERSION)/build && cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="`pwd`/../../build" - cd opencv-$(OPENCV_VERSION)/build && cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DENABLE_CXX11=ON -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -DSTRSAFE_NO_DEPRECATE" -DCMAKE_INSTALL_PREFIX="`pwd`/install" - cd opencv-$(OPENCV_VERSION)/build && make install - # copy files - mkdir -p $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/include - cp -r opencv-$(OPENCV_VERSION)/build/install/include/* $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/include/ - mkdir -p $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/lib/opencv - cp -r opencv-$(OPENCV_VERSION)/build/install/x64/mingw/staticlib/* $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/lib/opencv/ - # cleanup - rm -r -f opencv-$(OPENCV_VERSION) - mv $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp $(BUILD_PATH)/opencv-$(OPENCV_VERSION) - libxml2: $(BUILD_PATH)/libxml2-$(LIBXML2_VERSION) $(DOWNLOAD_PATH)/libxml2-$(LIBXML2_VERSION).tar.gz: From 3cfab3ace0450cd91784e10f4b44df964412afd2 Mon Sep 17 00:00:00 2001 From: howdy-partner <3364866+howdy-partner@users.noreply.github.com> Date: Thu, 10 Jun 2021 00:41:42 +0300 Subject: [PATCH 132/697] fix smiley bug --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index e330f49d3..491d2ca21 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -1583,7 +1583,12 @@ void ChatWidget::addSmiley() smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) QString plainText = ui->chatTextEdit->toPlainText(); - QChar start = plainText[ui->chatTextEdit->textCursor().position() - 1]; + + int startPosition = ui->chatTextEdit->textCursor().position(); + if (startPosition > 0) + startPosition -= 1; + + QChar start = plainText[startPosition]; if(!ui->chatTextEdit->textCursor().atStart() && start != QChar(' ')) smiley = QString(" ") + smiley; From 8bed99cc9f3763269b6b1aada45a43c9993d7b80 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 6 Aug 2021 12:15:34 +0200 Subject: [PATCH 133/697] Fix compilation with C++17 --- libretroshare/src/util/rsdir.cc | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 8556b8198..1a6375297 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * + * Copyright (C) 2020-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -64,6 +64,26 @@ * #define RSDIR_DEBUG 1 ****/ +#if __cplusplus < 201703L +bool std::filesystem::create_directories(const std::string& path) +{ + for( std::string::size_type lastIndex = 0; lastIndex < std::string::npos; + lastIndex = path.find('/', lastIndex) ) + { + std::string&& curDir = path.substr(0, ++lastIndex); + if(!RsDirUtil::checkCreateDirectory(curDir)) + { + RsErr() << __PRETTY_FUNCTION__ << " failure creating: " << curDir + << " of: " << path << std::endl; + return false; + } + } + return true; +} +#else +# include +#endif // __cplusplus < 201703L + std::string RsDirUtil::getTopDir(const std::string& dir) { std::string top; @@ -528,24 +548,6 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir) return true; } -#if __cplusplus < 201703L -bool std::filesystem::create_directories(const std::string& path) -{ - for( std::string::size_type lastIndex = 0; lastIndex < std::string::npos; - lastIndex = path.find('/', lastIndex) ) - { - std::string&& curDir = path.substr(0, ++lastIndex); - if(!RsDirUtil::checkCreateDirectory(curDir)) - { - RsErr() << __PRETTY_FUNCTION__ << " failure creating: " << curDir - << " of: " << path << std::endl; - return false; - } - } - return true; -} -#endif // __cplusplus < 201703L - std::string RsDirUtil::removeSymLinks(const std::string& path) { #if defined(WINDOWS_SYS) || defined(__APPLE__) || defined(__ANDROID__) From 4db6ac92e77a977c330ad3263db940d79217d90a Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 11 Aug 2021 16:01:45 +0200 Subject: [PATCH 134/697] initial split of PHPHandler into two classes --- libretroshare/src/libretroshare.pro | 2 + libretroshare/src/pgp/pgphandler.cc | 1742 --------------------------- libretroshare/src/pgp/pgphandler.h | 183 ++- libretroshare/src/pqi/authgpg.cc | 2 +- libretroshare/src/pqi/authgpg.h | 6 +- 5 files changed, 84 insertions(+), 1851 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..89d9e5d9a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -364,6 +364,7 @@ HEADERS += chat/distantchat.h \ HEADERS += pqi/authssl.h \ pqi/authgpg.h \ pgp/pgphandler.h \ + pgp/openpgpsdkhandler.h \ pgp/pgpkeyutil.h \ pgp/rscertificate.h \ pgp/pgpauxutils.h \ @@ -538,6 +539,7 @@ SOURCES += chat/distantchat.cc \ SOURCES += pqi/authgpg.cc \ pqi/authssl.cc \ pgp/pgphandler.cc \ + pgp/openpgpsdkhandler.cc \ pgp/pgpkeyutil.cc \ pgp/rscertificate.cc \ pgp/pgpauxutils.cc \ diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index b1e96b00b..3a5eaf837 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -33,15 +33,6 @@ #include "util/rswin.h" #endif -extern "C" { -#include -#include -#include -#include -#include -#include -#include -} #include "pgphandler.h" #include "retroshare/rsiface.h" // For rsicontrol. #include "retroshare/rspeers.h" // For rsicontrol. @@ -59,56 +50,6 @@ static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; PassphraseCallback PGPHandler::_passphrase_callback = NULL ; -ops_keyring_t *PGPHandler::allocateOPSKeyring() -{ - ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; - - if(kr == NULL) - return NULL ; - - kr->nkeys = 0 ; - kr->nkeys_allocated = 0 ; - kr->keys = 0 ; - - return kr ; -} - -ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) -{ - const ops_parser_content_union_t *content=&content_->content; - bool prev_was_bad = false ; - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; - /* fallthrough */ - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - { - std::string passwd; - std::string uid_hint ; - - if(cbinfo->cryptinfo.keydata->nuids > 0) - uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; - - bool cancelled = false ; - passwd = PGPHandler::passphraseCallback()(NULL,"",uid_hint.c_str(),NULL,prev_was_bad,&cancelled) ; - - if(cancelled) - *(unsigned char *)cbinfo->arg = 1; - - *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; - memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; - return OPS_KEEP_MEMORY; - } - break; - - default: - break; - } - - return OPS_RELEASE_MEMORY; -} void PGPHandler::setPassphraseCallback(PassphraseCallback cb) { _passphrase_callback = cb ; @@ -117,195 +58,10 @@ void PGPHandler::setPassphraseCallback(PassphraseCallback cb) PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) : pgphandlerMtx(std::string("PGPHandler")), _pubring_path(pubring),_secring_path(secring),_trustdb_path(trustdb),_pgp_lock_filename(pgp_lock_filename) { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - _pubring_changed = false ; - _trustdb_changed = false ; - - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - if(_passphrase_callback == NULL) - std::cerr << "WARNING: before created a PGPHandler, you need to init the passphrase callback using PGPHandler::setPassphraseCallback()" << std::endl; - - // Allocate public and secret keyrings. - // - _pubring = allocateOPSKeyring() ; - _secring = allocateOPSKeyring() ; - - // Check that the file exists. If not, create a void keyring. - - FILE *ftest ; - ftest = RsDirUtil::rs_fopen(pubring.c_str(),"rb") ; - bool pubring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - ftest = RsDirUtil::rs_fopen(secring.c_str(),"rb") ; - bool secring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - - // Read public and secret keyrings from supplied files. - // - if(pubring_exist) - { - if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring. File corrupted.") ; - } - else - std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; - - const ops_keydata_t *keydata ; - int i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - - // Init all certificates. - - initCertificateInfo(cert,keydata,i) ; - - // Validate signatures. - - validateAndUpdateSignatures(cert,keydata) ; - - ++i ; - } - _pubring_last_update_time = time(NULL) ; - std::cerr << "Pubring read successfully." << std::endl; - - if(secring_exist) - { - if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring. File corrupted.") ; - } - else - std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; - - i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) - { - initCertificateInfo(_secret_keyring_map[ RsPgpId(keydata->key_id) ],keydata,i) ; - ++i ; - } - _secring_last_update_time = time(NULL) ; - - std::cerr << "Secring read successfully." << std::endl; - - locked_readPrivateTrustDatabase() ; - _trustdb_last_update_time = time(NULL) ; -} - -void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) -{ - // Parse certificate name - // - - if(keydata->uids != NULL) - { - std::string namestring( (char *)keydata->uids[0].user_id ) ; - - cert._name = "" ; - uint32_t i=0; - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} - - // trim right spaces - std::string::size_type found = cert._name.find_last_not_of(' '); - if (found != std::string::npos) - cert._name.erase(found + 1); - else - cert._name.clear(); // all whitespace - - std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} - - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} - - if(i< namestring.length()) - { - std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next2 = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} - } - } - - cert._trustLvl = 1 ; // to be setup accordingly - cert._validLvl = 1 ; // to be setup accordingly - cert._key_index = index ; - cert._flags = 0 ; - cert._time_stamp = 0 ;// "never" by default. Will be updated by trust database, and effective key usage. - - switch(keydata->key.pkey.algorithm) - { - case OPS_PKA_RSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA ; - break ; - case OPS_PKA_DSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - default: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_UNKNOWN ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - } - - ops_fingerprint_t f ; - ops_fingerprint(&f,&keydata->key.pkey) ; - - cert._fpr = PGPFingerprintType(f.fingerprint) ; -} - -bool PGPHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) -{ - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; - - if(res == ops_false) - { - static ops_boolean_t already = 0 ; - if(!already) - { - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - already = 1 ; - } - } - - bool ret = false ; - - // Parse signers. - // - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - { - RsPgpId signer_id(result->valid_sigs[i].signer_id); - - if(cert.signers.find(signer_id) == cert.signers.end()) - { - cert.signers.insert(signer_id) ; - ret = true ; - } - } - - ops_validate_result_free(result) ; - - return ret ; } PGPHandler::~PGPHandler() { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Freeing PGPHandler. Deleting keyrings." << std::endl; -#endif - - // no need to free the the _map_ elements. They will be freed by the following calls: - // - ops_keyring_free(_pubring) ; - ops_keyring_free(_secring) ; - - free(_pubring) ; - free(_secring) ; } bool PGPHandler::printKeys() const @@ -340,19 +96,9 @@ bool PGPHandler::printKeys() const std::cerr << std::endl ; } } - std::cerr << "Public keyring list from OPS:" << std::endl; - ops_keyring_list(_pubring) ; - return true ; } -bool PGPHandler::haveSecretKey(const RsPgpId& id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - return locked_getSecretKey(id) != NULL ; -} - const PGPCertificateInfo *PGPHandler::getCertificateInfo(const RsPgpId& id) const { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -365,1186 +111,6 @@ const PGPCertificateInfo *PGPHandler::getCertificateInfo(const RsPgpId& id) cons return NULL ; } -bool PGPHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // go through secret keyring, and check that we have the pubkey as well. - // - - const ops_keydata_t *keydata = NULL ; - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(_secring,i++)) != NULL ) - if(ops_keyring_find_key_by_id(_pubring,keydata->key_id) != NULL) // check that the key is in the pubring as well - { -#ifdef PGPHANDLER_DSA_SUPPORT - if(keydata->key.pkey.algorithm == OPS_PKA_RSA || keydata->key.pkey.algorithm == OPS_PKA_DSA) -#else - if(keydata->key.pkey.algorithm == OPS_PKA_RSA) -#endif - ids.push_back(RsPgpId(keydata->key_id)) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; -#endif - } - - return true ; -} - -bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) -{ - // Some basic checks - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - errString = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - if(name.length() > PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE) - { - errString = std::string("(EE) name in certificate exceeds the maximum allowed name size") ; - return false ; - } - if(email.length() > PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE) - { - errString = std::string("(EE) email in certificate exceeds the maximum allowed email size") ; - return false ; - } - if(passphrase.length() > PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE) - { - errString = std::string("(EE) passphrase in certificate exceeds the maximum allowed passphrase size") ; - return false ; - } - if(keynumbits % 1024 != 0) - { - errString = std::string("(EE) RSA key length is not a multiple of 1024") ; - return false ; - } - - // Now the real thing - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - // 1 - generate keypair - RSA-2048 - // - ops_user_id_t uid ; - char *s = strdup((name + " (Generated by RetroShare) <" + email + ">" ).c_str()) ; - uid.user_id = (unsigned char *)s ; - unsigned long int e = 65537 ; // some prime number - - ops_keydata_t *key = ops_rsa_create_selfsigned_keypair(keynumbits, e, &uid) ; - - free(s) ; - - if(!key) - return false ; - - // 2 - save the private key encrypted to a temporary memory buffer, so as to read an encrypted key to memory - - ops_create_info_t *cinfo = NULL ; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString = std::string("(EE) Cannot encode secret key to memory!!") ; - return false ; - } - - // 3 - read the memory chunk into an encrypted keyring - - ops_keyring_t *tmp_secring = allocateOPSKeyring() ; - - if(! ops_keyring_read_from_mem(tmp_secring, ops_false, buf)) - { - errString = std::string("(EE) Cannot re-read key from memory!!") ; - return false ; - } - ops_teardown_memory_write(cinfo,buf); // cleanup memory - - // 4 - copy the encrypted private key to the private keyring - - pgpId = RsPgpId(tmp_secring->keys[0].key_id) ; - addNewKeyToOPSKeyring(_secring,tmp_secring->keys[0]) ; - initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; -#endif - ops_keyring_free(tmp_secring) ; - free(tmp_secring) ; - - // 5 - add key to secret keyring on disk. - - cinfo = NULL ; - std::string secring_path_tmp = _secring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - errString= std::string("Cannot copy secret keyring !! Disk full? Out of disk quota?") ; - return false ; - } - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - errString= std::string("Cannot rename tmp secret key file ") + secring_path_tmp + " into " + _secring_path +". Disk error?" ; - return false ; - } - - // 6 - copy the public key to the public keyring on disk - - cinfo = NULL ; - std::string pubring_path_tmp = _pubring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_pubring_path) && !RsDirUtil::copyFile(_pubring_path,pubring_path_tmp)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - fd=ops_setup_file_append(&cinfo, pubring_path_tmp.c_str()); - - if(!ops_write_transferable_public_key(key, ops_false, cinfo)) - { - errString=std::string("Cannot encode secret key to memory!!") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(pubring_path_tmp,_pubring_path)) - { - errString= std::string("Cannot rename tmp public key file ") + pubring_path_tmp + " into " + _pubring_path +". Disk error?" ; - return false ; - } - // 7 - clean - ops_keydata_free(key) ; - - // 8 - re-read the key from the public keyring, and add it to memory. - - _pubring_last_update_time = 0 ; // force update pubring from disk. - locked_syncPublicKeyring() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; -#endif - - // 9 - Update some flags. - - privateTrustCertificate(pgpId,PGPCertificateInfo::PGP_CERTIFICATE_TRUST_ULTIMATE) ; - - return true ; -} - -std::string PGPHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) -{ - ops_create_info_t* cinfo; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - ops_boolean_t armoured = ops_true ; - - if(key->type == OPS_PTAG_CT_PUBLIC_KEY) - { - if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else if(key->type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - { - if(ops_write_transferable_secret_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else - { - ops_create_info_delete(cinfo); - std::cerr << "Unhandled key type " << key->type << std::endl; - return "ERROR: Cannot write key. Unhandled key type. " ; - } - - ops_writer_close(cinfo) ; - - std::string res((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ; - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - std::string tmp ; - if(PGPKeyManagement::createMinimalKey(res,tmp) ) - res = tmp ; - } - - return res ; -} - -const ops_keydata_t *PGPHandler::locked_getSecretKey(const RsPgpId& id) const -{ - std::map::const_iterator res = _secret_keyring_map.find(id) ; - - if(res == _secret_keyring_map.end()) - return NULL ; - else - return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; -} -const ops_keydata_t *PGPHandler::locked_getPublicKey(const RsPgpId& id,bool stamp_the_key) const -{ - std::map::const_iterator res = _public_keyring_map.find(id) ; - - if(res == _public_keyring_map.end()) - return NULL ; - else - { - if(stamp_the_key) // Should we stamp the key as used? - { - static rstime_t last_update_db_because_of_stamp = 0 ; - rstime_t now = time(NULL) ; - - res->second._time_stamp = now ; - - if(now > last_update_db_because_of_stamp + 3600) // only update database once every hour. No need to do it more often. - { - _trustdb_changed = true ; - last_update_db_because_of_stamp = now ; - } - } - return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; - } -} - -std::string PGPHandler::SaveCertificateToString(const RsPgpId& id,bool include_signatures) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(key == NULL) - { - std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; - return "" ; - } - - return makeRadixEncodedPGPKey(key,include_signatures) ; -} - -bool PGPHandler::exportPublicKey( - const RsPgpId& id, - unsigned char*& mem_block, size_t& mem_size, - bool armoured, bool include_signatures ) const -{ - mem_block = nullptr; mem_size = 0; // clear just in case - - if(armoured) - { - RsErr() << __PRETTY_FUNCTION__ << " should not be used with " - << "armoured=true, because there's a bug in the armoured export" - << " of OPS" << std::endl; - print_stacktrace(); - return false; - } - - RS_STACK_MUTEX(pgphandlerMtx); - const ops_keydata_t* key = locked_getPublicKey(id,false); - - if(!key) - { - RsErr() << __PRETTY_FUNCTION__ << " key id: " << id - << " not found in keyring." << std::endl; - return false; - } - - ops_create_info_t* cinfo; - ops_memory_t *buf = nullptr; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(ops_write_transferable_public_key_from_packet_data( - key, armoured, cinfo ) != ops_true) - { - RsErr() << __PRETTY_FUNCTION__ << " This key id " << id - << " cannot be processed by RetroShare because DSA certificates" - << " support is not implemented yet." << std::endl; - return false; - } - - ops_writer_close(cinfo); - - mem_size = ops_memory_get_length(buf); - mem_block = reinterpret_cast(malloc(mem_size)); - memcpy(mem_block,ops_memory_get_data(buf),mem_size); - - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - size_t new_size; - PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size); - mem_size = new_size; - } - - return true; -} - -bool PGPHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *pubkey = locked_getPublicKey(exported_key_id,false) ; - - if(pubkey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; - return false ; - } - const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; - - if(seckey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; - return false ; - } - - FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; - if(f == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; - return false ; - } - - fprintf(f,"%s\n", makeRadixEncodedPGPKey(pubkey,true).c_str()) ; - fprintf(f,"%s\n", makeRadixEncodedPGPKey(seckey,true).c_str()) ; - - fclose(f) ; - return true ; -} - -bool PGPHandler::exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *pubkey = locked_getPublicKey(exportedKeyId,false); - - if(!pubkey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in public keyring."; - return false; - } - const ops_keydata_t *seckey = locked_getSecretKey(exportedKeyId); - - if(!seckey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in secret keyring."; - return false; - } - - data = makeRadixEncodedPGPKey(pubkey, includeSignatures); - data += "\n"; - data += makeRadixEncodedPGPKey(seckey, includeSignatures); - data += "\n"; - return true; -} - -bool PGPHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const -{ - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,mem_block,mem_size); - - if(!ops_keyring_read_from_mem(tmp_keyring,ops_false,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - //error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - //error_string.clear() ; - - if(tmp_keyring->nkeys != 1) - { - std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; - return false ; - } - if(tmp_keyring->keys[0].uids == NULL) - { - std::cerr << "No uid in supplied key." << std::endl; - return false ; - } - - key_id = RsPgpId(tmp_keyring->keys[0].key_id) ; - name = std::string((char *)tmp_keyring->keys[0].uids[0].user_id) ; - - // now parse signatures. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res ; - - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],_pubring,cb_get_passphrase) ; - } - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // also add self-signature if any (there should be!). - // - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // Parse signers. - // - - std::set signers_set ; // Use a set to remove duplicates. - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - signers_set.insert(RsPgpId(result->valid_sigs[i].signer_id)) ; - - ops_validate_result_free(result) ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - // write to the output variable - - signers.clear() ; - - for(std::set::const_iterator it(signers_set.begin());it!=signers_set.end();++it) - signers.push_back(*it) ; - - return true ; -} - -bool PGPHandler::importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) -{ - import_error = "" ; - - // 1 - Test for file existance - // - FILE *ftest = RsDirUtil::rs_fopen(filename.c_str(),"r") ; - - if(ftest == NULL) - { - import_error = "Cannot open file " + filename + " for read. Please check access permissions." ; - return false ; - } - - fclose(ftest) ; - - // 2 - Read keyring from supplied file. - // - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_file(tmp_keyring, ops_true, filename.c_str())) - { - import_error = "PGPHandler::readKeyRing(): cannot read key file. File corrupted?" ; - free(tmp_keyring); - return false ; - } - - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) -{ - import_error = "" ; - - ops_memory_t* mem = ops_memory_new(); - ops_memory_add(mem, (unsigned char*)data.data(), data.length()); - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_mem(tmp_keyring, ops_true, mem)) - { - import_error = "PGPHandler::importGPGKeyPairFromString(): cannot parse key data" ; - free(tmp_keyring); - return false ; - } - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &imported_key_id, std::string &import_error) -{ - if(tmp_keyring == 0) - { - import_error = "PGPHandler::checkAndImportKey(): keyring is null" ; - return false; - } - - if(tmp_keyring->nkeys != 2) - { - import_error = "PGPHandler::importKeyPair(): file does not contain a valid keypair." ; - if(tmp_keyring->nkeys > 2) - import_error += "\nMake sure that your key is a RSA key (DSA is not yet supported) and does not contain subkeys (not supported yet)."; - return false ; - } - - // 3 - Test that keyring contains a valid keypair. - // - const ops_keydata_t *pubkey = NULL ; - const ops_keydata_t *seckey = NULL ; - - if(tmp_keyring->keys[0].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[0] ; - else if(tmp_keyring->keys[0].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[0] ; - else - { - import_error = "Unrecognised key type in key file for key #0. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; - return false ; - } - if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[1] ; - else if(tmp_keyring->keys[1].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[1] ; - else - { - import_error = "Unrecognised key type in key file for key #1. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; - return false ; - } - - if(pubkey == nullptr || seckey == nullptr || pubkey == seckey) - { - import_error = "File does not contain a public and a private key. Sorry." ; - return false ; - } - if(memcmp( pubkey->fingerprint.fingerprint, - seckey->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES ) != 0) - { - import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; - return false ; - } - if(pubkey->key.pkey.version != 4) - { - import_error = "Public key is not version 4. Rejected!" ; - return false ; - } - - // 4 - now check self-signature for this keypair. For this we build a dummy keyring containing only the key. - // - ops_validate_result_t *result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_keyring_t dummy_keyring ; - dummy_keyring.nkeys=1 ; - dummy_keyring.nkeys_allocated=1 ; - dummy_keyring.keys=const_cast(pubkey) ; - - ops_validate_key_signatures(result, const_cast(pubkey), &dummy_keyring, cb_get_passphrase) ; - - // Check that signatures contain at least one certification from the user id. - // - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - pubkey->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - import_error = "Cannot validate self signature for the imported key. Sorry." ; - return false ; - } - ops_validate_result_free(result); - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - import_error = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - // 5 - All test passed. Adding key to keyring. - // - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - imported_key_id = RsPgpId(pubkey->key_id) ; - - if(locked_getSecretKey(imported_key_id) == NULL) - { - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - ops_create_info_t *cinfo = NULL ; - - // Make a copy of the secret keyring - // - std::string secring_path_tmp = _secring_path + ".tmp" ; - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - import_error = "(EE) Cannot write secret key to disk!! Disk full? Out of disk quota. Keyring will be left untouched." ; - return false ; - } - - // Append the new key - - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key_from_packet_data(seckey,ops_false,cinfo)) - { - import_error = "(EE) Cannot encode secret key to disk!! Disk full? Out of disk quota?" ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - // Rename the new keyring to overwrite the old one. - // - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - import_error = " (EE) Cannot move temp file " + secring_path_tmp + ". Bad write permissions?" ; - return false ; - } - - addNewKeyToOPSKeyring(_secring,*seckey) ; - initCertificateInfo(_secret_keyring_map[ imported_key_id ],seckey,_secring->nkeys-1) ; - } - else - import_error = "Private key already exists! Not importing it again." ; - - if(locked_addOrMergeKey(_pubring,_public_keyring_map,pubkey)) - _pubring_changed = true ; - } - - // 6 - clean - // - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring); - - // write public key to disk - syncDatabase(); - - return true ; -} - -void PGPHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& key) -{ - if(kr->nkeys >= kr->nkeys_allocated) - { - kr->keys = (ops_keydata_t *)realloc(kr->keys,(kr->nkeys+1)*sizeof(ops_keydata_t)) ; - kr->nkeys_allocated = kr->nkeys+1; - } - memset(&kr->keys[kr->nkeys],0,sizeof(ops_keydata_t)) ; - ops_keydata_copy(&kr->keys[kr->nkeys],&key) ; - kr->nkeys++ ; -} - -bool PGPHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate(data,data_len,ops_false,id,error_string); -} - -bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string); -} - -bool PGPHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Reading new key from string: " << std::endl; -#endif - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,data,data_len) ; - - if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - error_string.clear() ; - - // Check that there is exactly one key in this data packet. - // - if(tmp_keyring->nkeys != 1) - { - std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; - error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; - return false ; - } - - const ops_keydata_t *keydata = ops_keyring_get_key_by_index(tmp_keyring,0); - - // Check that the key is a version 4 key - // - if(keydata->key.pkey.version != 4) - { - error_string = "Public key is not version 4. Rejected!" ; - std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; - return false ; - } - - // Check that the key is correctly self-signed. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_validate_key_signatures(result,keydata,tmp_keyring,cb_get_passphrase) ; - - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - keydata->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - error_string = "This key is not self-signed. This is required by Retroshare." ; - std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; - ops_validate_result_free(result); - return false ; - } - ops_validate_result_free(result); - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key read correctly: " << std::endl; - ops_keyring_list(tmp_keyring) ; -#endif - - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(tmp_keyring,i++)) != NULL ) - if(locked_addOrMergeKey(_pubring,_public_keyring_map,keydata)) - { - _pubring_changed = true ; -#ifdef DEBUG_PGPHANDLER - std::cerr << " Added the key in the main public keyring." << std::endl; -#endif - } - else - std::cerr << "Key already in public keyring." << std::endl; - - if(tmp_keyring->nkeys > 0) - id = RsPgpId(tmp_keyring->keys[0].key_id) ; - else - return false ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - _pubring_changed = true ; - - return true ; -} - -bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) -{ - bool ret = false ; - RsPgpId id(keydata->key_id) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "AddOrMergeKey():" << std::endl; - std::cerr << " id: " << id.toStdString() << std::endl; -#endif - - // See if the key is already in the keyring - const ops_keydata_t *existing_key = NULL; - std::map::const_iterator res = kmap.find(id) ; - - // Checks that - // - the key is referenced by keyid - // - the map is initialized - // - the fingerprint matches! - // - if(res == kmap.end() || (existing_key = ops_keyring_get_key_by_index(keyring,res->second._key_index)) == NULL) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key is new. Adding it to keyring" << std::endl; -#endif - addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. - initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; - existing_key = &(keyring->keys[keyring->nkeys-1]) ; - ret = true ; - } - else - { - if(memcmp( existing_key->fingerprint.fingerprint, - keydata->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES )) - { - std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key exists. Merging signatures." << std::endl; -#endif - ret = mergeKeySignatures(const_cast(existing_key),keydata) ; - - if(ret) - initCertificateInfo(kmap[id],existing_key,res->second._key_index) ; - } - - if(ret) - { - validateAndUpdateSignatures(kmap[id],existing_key) ; - kmap[id]._time_stamp = time(NULL) ; - } - - return ret ; -} - -bool PGPHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - - std::string outfile_tmp = outfile + ".tmp" ; - - ops_create_info_t *info; - int fd = ops_setup_file_write(&info, outfile_tmp.c_str(), ops_true); - - if (fd < 0) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; - return false ; - } - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; - return false ; - } - - ops_write(text.c_str(), text.length(), info); - ops_teardown_file_write(info, fd); - - if(!RsDirUtil::renameFile(outfile_tmp,outfile)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; - return false ; - } - - return true ; -} - -bool PGPHandler::encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - if(public_key->key.pkey.algorithm != OPS_PKA_RSA) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; - return false ; - } - ops_create_info_t *info; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&info, &buf, 0); - bool res = true; - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) - { - std::cerr << "Encryption failed." << std::endl; - res = false ; - } - - ops_write(data,len,info); - ops_writer_close(info); - ops_create_info_delete(info); - - int tlen = ops_memory_get_length(buf) ; - - if( (int)*encrypted_data_len >= tlen) - { - if(res) - { - memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ; - *encrypted_data_len = tlen ; - res = true ; - } - } - else - { - std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; - res = false ; - } - - ops_memory_release(buf) ; - free(buf) ; - - return res ; -} - -bool PGPHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) -{ - int out_length ; - unsigned char *out ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ; - - if(*data_len < (unsigned int)out_length) - { - std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; - return false ; - } - - *data_len = (unsigned int)out_length ; - memcpy(data,out,out_length) ; - free(out) ; - - return (bool)res ; -} - -bool PGPHandler::decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - unsigned char *out_buf = NULL ; - std::string buf ; - - FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"rb") ; - - if (f == NULL) - { - std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; - return false; - } - - int c ; - while( (c = fgetc(f))!= EOF) - buf += (unsigned char)c; - - fclose(f) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; - std::cerr << "buf=\"" << buf << "\"" << std::endl; -#endif - - int out_length ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)buf.c_str(),buf.length(),&out_buf,&out_length,_secring,ops_true,cb_get_passphrase) ; - - text = std::string((char *)out_buf,out_length) ; - free (out_buf); - return (bool)res ; -} - -bool PGPHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // need to find the key and to decrypt it. - - const ops_keydata_t *key = locked_getSecretKey(id) ; - - if(!key) - { - std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; - return false ; - } - - std::string uid_hint ; - if(key->nuids > 0) - uid_hint = std::string((const char *)key->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(key->key_id).toStdString()+")" ; - -#ifdef DEBUG_PGPHANDLER - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - PGPFingerprintType fp(f.fingerprint) ; -#endif - - bool last_passwd_was_wrong = false ; -ops_secret_key_t *secret_key = NULL ; - - for(int i=0;i<3;++i) - { - bool cancelled =false; - std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason - - secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key entering cancelled" << std::endl; - return false ; - } - if(secret_key) - break ; - - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - last_passwd_was_wrong = true ; - } - if(!secret_key) - { - std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; - return false ; - } - - // then do the signature. - - ops_boolean_t not_raw = !use_raw_signature ; -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#else - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#endif - - if(!memres) - return false ; - - bool res ; - uint32_t slen = (uint32_t)ops_memory_get_length(memres); - - if(*signlen >= slen) - { - *signlen = slen ; - - memcpy(sign,ops_memory_get_data(memres),*signlen) ; - res = true ; - } - else - { - std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; - res = false ; - } - - ops_memory_release(memres) ; - free(memres) ; - ops_secret_key_free(secret_key) ; - free(secret_key) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)data, len) ; - std::cerr << std::endl; - std::cerr << "Data: " << std::endl; - hexdump( (unsigned char *)sign,*signlen) ; - std::cerr << std::endl; -#endif - return res ; -} - -bool PGPHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - ops_keydata_t *key_to_sign = const_cast(locked_getPublicKey(id_of_key_to_sign,true)) ; - - if(key_to_sign == NULL) - { - std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; - return false ; - } - - // 1 - get decrypted secret key - // - const ops_keydata_t *skey = locked_getSecretKey(ownId) ; - - if(!skey) - { - std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; - return false ; - } - const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; - - if(!pkey) - { - std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; - return false ; - } - - bool cancelled = false; - std::string passphrase = _passphrase_callback(NULL,"",RsPgpId(skey->key_id).toStdString().c_str(),"Please enter passwd for encrypting your key : ",false,&cancelled) ; - - ops_secret_key_t *secret_key = ops_decrypt_secret_key_from_data(skey,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key cancelled by used." << std::endl; - return false ; - } - if(!secret_key) - { - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 2 - then do the signature. - - if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) - { - std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 3 - free memory - // - ops_secret_key_free(secret_key) ; - free(secret_key) ; - - _pubring_changed = true ; - - // 4 - update signatures. - // - PGPCertificateInfo& cert(_public_keyring_map[ id_of_key_to_sign ]) ; - validateAndUpdateSignatures(cert,key_to_sign) ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; - - return true ; -} - void PGPHandler::updateOwnSignatureFlag(const RsPgpId& own_id) { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -1599,59 +165,6 @@ void PGPHandler::locked_updateOwnSignatureFlag(PGPCertificateInfo& cert,const Rs RsPgpFingerprint::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES ); } -bool PGPHandler::getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(!key) return false; - - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - fp = RsPgpFingerprint::fromBufferUnsafe(f.fingerprint); - - return true ; -} - -bool PGPHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - RsPgpId id = RsPgpId(key_fingerprint.toByteArray() + PGPFingerprintType::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES) ; - const ops_keydata_t *key = locked_getPublicKey(id,true) ; - - if(key == NULL) - { - std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - - // Check that fingerprint is the same. - const ops_public_key_t *pkey = &key->key.pkey ; - ops_fingerprint_t fp ; - ops_fingerprint(&fp,pkey) ; - - if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) - { - std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)sign,sign_len) ; - std::cerr << std::endl; - std::cerr << "Signed data: " << std::endl; - hexdump( (unsigned char *)literal_data, literal_data_length) ; - std::cerr << std::endl; -#endif - - return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; -} - void PGPHandler::setAcceptConnexion(const RsPgpId& id,bool b) { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -1699,65 +212,6 @@ bool PGPHandler::isGPGAccepted(const RsPgpId &id) return (res != _public_keyring_map.end()) && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) ; } -// Lexicographic order on signature packets -// -bool operator<(const ops_packet_t& p1,const ops_packet_t& p2) -{ - if(p1.length < p2.length) - return true ; - if(p1.length > p2.length) - return false ; - - for(uint32_t i=0;i p2.raw[i]) - return false ; - } - return false ; -} - -bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) -{ - // First sort all signatures into lists to see which is new, which is not new - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; -#endif - std::set dst_packets ; - - for(uint32_t i=0;inpackets;++i) dst_packets.insert(dst->packets[i]) ; - - std::set to_add ; - - for(uint32_t i=0;inpackets;++i) - if(dst_packets.find(src->packets[i]) == dst_packets.end()) - { - uint8_t tag ; - uint32_t length ; - unsigned char *tmp_data = src->packets[i].raw ; // put it in a tmp variable because read_packetHeader() will modify it!! - - PGPKeyParser::read_packetHeader(tmp_data,tag,length) ; - - if(tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) - to_add.insert(src->packets[i]) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; -#endif - } - - for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; -#endif - ops_add_packet_to_keydata(dst,&*it) ; - } - return to_add.size() > 0 ; -} - bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) { PGPSignatureInfo info ; @@ -1895,71 +349,6 @@ bool PGPHandler::locked_writePrivateTrustDatabase() return true ; } -bool PGPHandler::syncDatabase() -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Sync-ing keyrings." << std::endl; -#endif - locked_syncPublicKeyring() ; - //locked_syncSecretKeyring() ; - - // Now sync the trust database as well. - // - locked_syncTrustDatabase() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Done. " << std::endl; -#endif - return true ; -} - -bool PGPHandler::locked_syncPublicKeyring() -{ - struct stat64 buf ; -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(_pubring_path, wfullname); - if(-1 == _wstati64(wfullname.c_str(), &buf)) -#else - if(-1 == stat64(_pubring_path.c_str(), &buf)) -#endif - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; - - if(_pubring_last_update_time < buf.st_mtime) - { - std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; - - locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; - _pubring_last_update_time = buf.st_mtime ; - } - - // Now check if the pubring was locally modified, which needs saving it again - if(_pubring_changed && RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - std::string tmp_keyring_file = _pubring_path + ".tmp" ; - - std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; - if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) - { - std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; - return false ; - } - if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) - { - std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; - return false ; - } - - std::cerr << "Done." << std::endl; - _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? - _pubring_changed = false ; - } - return true ; -} - bool PGPHandler::locked_syncTrustDatabase() { struct stat64 buf ; @@ -1997,137 +386,6 @@ bool PGPHandler::locked_syncTrustDatabase() } return true ; } -void PGPHandler::locked_mergeKeyringFromDisk( ops_keyring_t *keyring, - std::map& kmap, - const std::string& keyring_file) -{ -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; -#endif - // 1 - load keyring into a temporary keyring list. - ops_keyring_t *tmp_keyring = PGPHandler::allocateOPSKeyring() ; - if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) - { - std::cerr << "PGPHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; - ops_keyring_free(tmp_keyring) ; - return ; - } - // 2 - load new keys and merge existing key signatures - - for(int i=0;inkeys;++i) - locked_addOrMergeKey(keyring,kmap,&tmp_keyring->keys[i]) ;// we dont' account for the return value. This is disk merging, not local changes. - - // 4 - clean - ops_keyring_free(tmp_keyring) ; -} - -bool PGPHandler::removeKeysFromPGPKeyring(const std::set& keys_to_remove,std::string& backup_file,uint32_t& error_code) -{ - // 1 - lock everything. - // - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - error_code = PGP_KEYRING_REMOVAL_ERROR_NO_ERROR ; - - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; - return false ; - } - - // 2 - sync everything. - // - locked_syncPublicKeyring() ; - - // 3 - make a backup of the public keyring - // - char template_name[_pubring_path.length()+8] ; - sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ; - -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - int fd_keyring_backup(mkstemp(template_name)); - if (fd_keyring_backup == -1) -#else - if(mktemp(template_name) == NULL) -#endif - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; - return false ; - } -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - close(fd_keyring_backup); // TODO: keep the file open and use the fd -#endif - - if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; - return false ; - } - backup_file = std::string(template_name,_pubring_path.length()+7) ; - - std::cerr << "Keyring was backed up to file " << backup_file << std::endl; - - // Remove keys from the keyring, and update the keyring map. - // - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - { - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; - continue ; - } - - std::map::iterator res = _public_keyring_map.find(*it) ; - - if(res == _public_keyring_map.end()) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; - continue ; - } - - if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; - return false ; - } - - // Move the last key to the freed place. This deletes the key in place. - // - ops_keyring_remove_key(_pubring,res->second._key_index) ; - - // Erase the info from the keyring map. - // - _public_keyring_map.erase(res) ; - - // now update all indices back. This internal look is very costly, but it avoids deleting the wrong keys, since the keyring structure is - // changed by ops_keyring_remove_key and therefore indices don't point to the correct location anymore. - - int i=0 ; - const ops_keydata_t *keydata ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - cert._key_index = i ; - ++i ; - } - } - - // Everything went well, sync back the keyring on disk - - _pubring_changed = true ; - _trustdb_changed = true ; - - locked_syncPublicKeyring() ; - locked_syncTrustDatabase() ; - - return true ; -} diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 5d7eb82f8..07b02325c 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -29,12 +29,6 @@ #include #include -extern "C" { -#include -#include -#include -} - typedef std::string (*PassphraseCallback)(void *data, const char *uid_title, const char *uid_hint, const char *passphrase_info, int prev_was_bad,bool *cancelled) ; class PGPCertificateInfo @@ -56,9 +50,11 @@ class PGPCertificateInfo mutable rstime_t _time_stamp ; // last time the key was used (received, used for signature verification, etc) PGPFingerprintType _fpr; /* fingerprint */ - // RsPgpId _key_id ; - uint32_t _key_index ; // index to array of keys in the public keyring + // Index to array of keys in the public keyring. Dependign on the specific implementation + // of how the keyring is stored, this may be used differently. + + uint32_t _key_index ; static const uint32_t PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION = 0x0001 ; static const uint32_t PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE = 0x0002 ; @@ -80,53 +76,87 @@ class PGPCertificateInfo class PGPHandler { public: - PGPHandler( const std::string& path_to_public_keyring, + PGPHandler( const std::string& path_to_public_keyring, const std::string& path_to_secret_keyring, const std::string& path_to_trust_database, const std::string& pgp_lock_file) ; virtual ~PGPHandler() ; - /** + //=======================================================================================// + // Methods that needs to be derived depending on how PGP is implemented // + //=======================================================================================// + + // Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated + // and given pack for proper display. + // + virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) =0; + virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; + + virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids)=0; + virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) =0; + + virtual std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const=0; + + /** The caller is in charge of freeing `mem` once finished */ + virtual bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const =0; + + virtual bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const=0; + virtual bool exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const =0; + + // Gets info about the key. Who are the signers, what's the owner's name, etc. + // + virtual bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const =0; + + virtual bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) =0; + /** * @param ids list of gpg certificate ids (note, not the actual certificates) */ + + virtual bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) =0; + + virtual bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string)=0; + virtual bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string)=0; + + virtual bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) =0; + virtual bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) =0; + + // The client should supply a memory chunk to store the data. The length will be updated to the real length of the data. + // + virtual bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len , unsigned char *encrypted_data, unsigned int *encrypted_data_len) =0; + virtual bool decryptDataBin(const RsPgpId& key_id,const void *encrypted_data, const uint32_t encrypted_len , unsigned char *data, unsigned int *data_len) =0; + + virtual bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") =0; + virtual bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) =0; + virtual bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) =0; + /** + * @brief Get PGP fingerprint for the given key + * @param id PGP 64bit key id + * @param fp storage for the retrived key fingerpring, the contained value + * is meaningfull only if true is returned + * @return true if the key was found, false if not + */ + virtual bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const=0; + + virtual bool haveSecretKey(const RsPgpId& id) const =0; + + // Syncs the keyrings and trust database between memory and disk. The algorithm is: + // 1 - lock the keyrings + // 2 - compare file modification dates with last writing date + // - if file is modified, load it, and merge with memory + // 3 - look into memory modification flags + // - if flag says keyring has changed, write to disk + // + virtual bool syncDatabase() =0; + + + //=======================================================================================// + // Common methods to PGPHandler // + //=======================================================================================// + bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) const ; - bool haveSecretKey(const RsPgpId& id) const ; - bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) ; - bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ; - bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_id) const ; - bool exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const; - - bool availableGPGCertificatesWithPrivateKeys(std::list& ids); - bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ; - - bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string); - bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string); - - std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ; - - /** The caller is in charge of freeing `mem` once finished */ - bool exportPublicKey( const RsPgpId& id, - unsigned char*& mem, size_t& mem_size, - bool armoured, bool include_signatures) const; - - bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ; - bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") ; - bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ; - bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) ; - - // The client should supply a memory chunk to store the data. The length will be updated to the real length of the data. - // - bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len - , unsigned char *encrypted_data, unsigned int *encrypted_data_len) ; - bool decryptDataBin(const RsPgpId& key_id,const void *encrypted_data, const uint32_t encrypted_len - , unsigned char *data, unsigned int *data_len) ; - - bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) ; - bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) ; + bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ; void setAcceptConnexion(const RsPgpId&,bool) ; @@ -135,11 +165,6 @@ public: void locked_updateOwnSignatureFlag(PGPCertificateInfo&, const RsPgpId&, PGPCertificateInfo&, const RsPgpId&) ; - // Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated - // and given pack for proper display. - // - bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) ; - //bool isKeySupported(const RsPgpId& id) const ; bool privateTrustCertificate(const RsPgpId& id,int valid_level) ; @@ -174,66 +199,18 @@ public: */ static RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& f); - /** - * @brief Get PGP fingerprint for the given key - * @param id PGP 64bit key id - * @param fp storage for the retrived key fingerpring, the contained value - * is meaningfull only if true is returned - * @return true if the key was found, false if not - */ - bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const; - - // Gets info about the key. Who are the signers, what's the owner's name, etc. - // - bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const ; - // Debug stuff. virtual bool printKeys() const ; - // Syncs the keyrings and trust database between memory and disk. The algorithm is: - // 1 - lock the keyrings - // 2 - compare file modification dates with last writing date - // - if file is modified, load it, and merge with memory - // 3 - look into memory modification flags - // - if flag says keyring has changed, write to disk - // - bool syncDatabase() ; - - private: - bool LoadCertificate(const unsigned char *bin_data,uint32_t bin_data_len, bool armoured, RsPgpId& gpg_id, std::string& error_string); - void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; - - // Returns true if the signatures have been updated - // - bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; - - /** Check public/private key and import them into the keyring - * @param keyring keyring with the new public/private key pair. Will be freed by the function. - * @param imported_key_id PGP id of the imported key - * @param import_error human readbale error message - * @returns true on success - * */ - bool checkAndImportKeyPair(ops_keyring_t *keyring, RsPgpId& imported_key_id,std::string& import_error); - - const ops_keydata_t *locked_getPublicKey(const RsPgpId&,bool stamp_the_key) const; - const ops_keydata_t *locked_getSecretKey(const RsPgpId&) const ; - + protected: void locked_readPrivateTrustDatabase() ; bool locked_writePrivateTrustDatabase() ; - - bool locked_syncPublicKeyring() ; - bool locked_syncTrustDatabase() ; - - void locked_mergeKeyringFromDisk(ops_keyring_t *keyring, std::map& kmap, const std::string& keyring_file) ; - bool locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) ; + bool locked_syncTrustDatabase() ; // Members. // mutable RsMutex pgphandlerMtx ; - ops_keyring_t *_pubring ; - ops_keyring_t *_secring ; - std::map _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring. std::map _secret_keyring_map ; @@ -249,11 +226,5 @@ public: rstime_t _secring_last_update_time ; rstime_t _trustdb_last_update_time ; - // Helper functions. - // - static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) ; - static ops_keyring_t *allocateOPSKeyring() ; - static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; static PassphraseCallback _passphrase_callback ; - static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different }; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index b41084cf0..2d29fbb65 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -126,7 +126,7 @@ void AuthGPG::exit() AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), - PGPHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), + OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), gpgMtxData("AuthGPG-data"), diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 4fe76194c..a6023f436 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -34,7 +34,7 @@ #include "util/rsthreads.h" #include "pqi/p3cfgmgr.h" -#include "pgp/pgphandler.h" +#include "pgp/openpgpsdkhandler.h" #define MAX_GPG_SIGNATURE_SIZE 4096 @@ -89,7 +89,9 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler +// Note: replace OpenPGPSDKHandler with your own PGP handler class when needed. + +class AuthGPG: public p3Config, public RsTickingThread, public OpenPGPSDKHandler { public: static void init(const std::string& path_to_pubring, From b8f4e6439374b3e96e3993d571c872caf5f6e6ac Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 11 Aug 2021 16:02:02 +0200 Subject: [PATCH 135/697] initial split of PHPHandler into two classes --- libretroshare/src/pgp/openpgpsdkhandler.cc | 1801 ++++++++++++++++++++ libretroshare/src/pgp/openpgpsdkhandler.h | 116 ++ 2 files changed, 1917 insertions(+) create mode 100644 libretroshare/src/pgp/openpgpsdkhandler.cc create mode 100644 libretroshare/src/pgp/openpgpsdkhandler.h diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc new file mode 100644 index 000000000..87f3c3343 --- /dev/null +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -0,0 +1,1801 @@ +/******************************************************************************* + * libretroshare/src/pgp: pgphandler.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2018 Cyril Soler * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#ifdef WINDOWS_SYS +#include +#include "util/rsstring.h" +#include "util/rswin.h" +#endif + +extern "C" { +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +} +#include "openpgpsdkhandler.h" + +#include "util/rsdir.h" +#include "util/rsdiscspace.h" +#include "util/rsmemory.h" +#include "pgp/pgpkeyutil.h" +#include "retroshare/rspeers.h" + +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE = 64 ; +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE = 64 ; +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; + +//#define DEBUG_PGPHANDLER 1 +//#define PGPHANDLER_DSA_SUPPORT + +PassphraseCallback PGPHandler::_passphrase_callback = NULL ; + +ops_keyring_t *OpenPGPSDKHandler::allocateOPSKeyring() +{ + ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; + + if(kr == NULL) + return NULL ; + + kr->nkeys = 0 ; + kr->nkeys_allocated = 0 ; + kr->keys = 0 ; + + return kr ; +} + +ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) +{ + const ops_parser_content_union_t *content=&content_->content; + bool prev_was_bad = false ; + + switch(content_->tag) + { + case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; + /* fallthrough */ + case OPS_PARSER_CMD_GET_SK_PASSPHRASE: + { + std::string passwd; + std::string uid_hint ; + + if(cbinfo->cryptinfo.keydata->nuids > 0) + uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; + uid_hint += "(" + RsPgpId(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; + + bool cancelled = false ; + passwd = PGPHandler::passphraseCallback()(NULL,"",uid_hint.c_str(),NULL,prev_was_bad,&cancelled) ; + + if(cancelled) + *(unsigned char *)cbinfo->arg = 1; + + *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; + memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; + return OPS_KEEP_MEMORY; + } + break; + + default: + break; + } + + return OPS_RELEASE_MEMORY; +} + +OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) + : PGPHandler(pubring,secring,trustdb,pgp_lock_filename) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + // Allocate public and secret keyrings. + // + _pubring = allocateOPSKeyring() ; + _secring = allocateOPSKeyring() ; + + // Check that the file exists. If not, create a void keyring. + + FILE *ftest ; + ftest = RsDirUtil::rs_fopen(pubring.c_str(),"rb") ; + bool pubring_exist = (ftest != NULL) ; + if(ftest != NULL) + fclose(ftest) ; + ftest = RsDirUtil::rs_fopen(secring.c_str(),"rb") ; + bool secring_exist = (ftest != NULL) ; + if(ftest != NULL) + fclose(ftest) ; + + // Read public and secret keyrings from supplied files. + // + if(pubring_exist) + { + if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) + throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read pubring. File corrupted.") ; + } + else + std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; + + const ops_keydata_t *keydata ; + int i=0 ; + while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) + { + PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; + + // Init all certificates. + + initCertificateInfo(cert,keydata,i) ; + + // Validate signatures. + + validateAndUpdateSignatures(cert,keydata) ; + + ++i ; + } + _pubring_last_update_time = time(NULL) ; + std::cerr << "Pubring read successfully." << std::endl; + + if(secring_exist) + { + if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) + throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read secring. File corrupted.") ; + } + else + std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; + + i=0 ; + while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) + { + initCertificateInfo(_secret_keyring_map[ RsPgpId(keydata->key_id) ],keydata,i) ; + ++i ; + } + _secring_last_update_time = time(NULL) ; + + std::cerr << "Secring read successfully." << std::endl; + + locked_readPrivateTrustDatabase() ; + _trustdb_last_update_time = time(NULL) ; +} + +void OpenPGPSDKHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) +{ + // Parse certificate name + // + + if(keydata->uids != NULL) + { + std::string namestring( (char *)keydata->uids[0].user_id ) ; + + cert._name = "" ; + uint32_t i=0; + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} + + // trim right spaces + std::string::size_type found = cert._name.find_last_not_of(' '); + if (found != std::string::npos) + cert._name.erase(found + 1); + else + cert._name.clear(); // all whitespace + + std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; + ++i ; + next = "" ; + while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} + + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} + + if(i< namestring.length()) + { + std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; + ++i ; + next2 = "" ; + while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} + } + } + + cert._trustLvl = 1 ; // to be setup accordingly + cert._validLvl = 1 ; // to be setup accordingly + cert._key_index = index ; + cert._flags = 0 ; + cert._time_stamp = 0 ;// "never" by default. Will be updated by trust database, and effective key usage. + + switch(keydata->key.pkey.algorithm) + { + case OPS_PKA_RSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA ; + break ; + case OPS_PKA_DSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; + break ; + default: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_UNKNOWN ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; + break ; + } + + ops_fingerprint_t f ; + ops_fingerprint(&f,&keydata->key.pkey) ; + + cert._fpr = PGPFingerprintType(f.fingerprint) ; +} + +bool OpenPGPSDKHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) +{ + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; + + if(res == ops_false) + { + static ops_boolean_t already = 0 ; + if(!already) + { + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + already = 1 ; + } + } + + bool ret = false ; + + // Parse signers. + // + + if(result != NULL) + for(size_t i=0;ivalid_count;++i) + { + RsPgpId signer_id(result->valid_sigs[i].signer_id); + + if(cert.signers.find(signer_id) == cert.signers.end()) + { + cert.signers.insert(signer_id) ; + ret = true ; + } + } + + ops_validate_result_free(result) ; + + return ret ; +} + +OpenPGPSDKHandler::~OpenPGPSDKHandler() +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. +#ifdef DEBUG_PGPHANDLER + std::cerr << "Freeing OpenPGPSDKHandler. Deleting keyrings." << std::endl; +#endif + + // no need to free the the _map_ elements. They will be freed by the following calls: + // + ops_keyring_free(_pubring) ; + ops_keyring_free(_secring) ; + + free(_pubring) ; + free(_secring) ; +} + +void OpenPGPSDKHandler::printOPSKeys() const +{ + std::cerr << "Public keyring list from OPS:" << std::endl; + ops_keyring_list(_pubring) ; +} + +bool OpenPGPSDKHandler::haveSecretKey(const RsPgpId& id) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + return locked_getSecretKey(id) != NULL ; +} + +bool OpenPGPSDKHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + // go through secret keyring, and check that we have the pubkey as well. + // + + const ops_keydata_t *keydata = NULL ; + int i=0 ; + + while( (keydata = ops_keyring_get_key_by_index(_secring,i++)) != NULL ) + if(ops_keyring_find_key_by_id(_pubring,keydata->key_id) != NULL) // check that the key is in the pubring as well + { +#ifdef PGPHANDLER_DSA_SUPPORT + if(keydata->key.pkey.algorithm == OPS_PKA_RSA || keydata->key.pkey.algorithm == OPS_PKA_DSA) +#else + if(keydata->key.pkey.algorithm == OPS_PKA_RSA) +#endif + ids.push_back(RsPgpId(keydata->key_id)) ; +#ifdef DEBUG_PGPHANDLER + else + std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; +#endif + } + + return true ; +} + +bool OpenPGPSDKHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) +{ + // Some basic checks + + if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + errString = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; + return false ; + } + if(name.length() > PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE) + { + errString = std::string("(EE) name in certificate exceeds the maximum allowed name size") ; + return false ; + } + if(email.length() > PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE) + { + errString = std::string("(EE) email in certificate exceeds the maximum allowed email size") ; + return false ; + } + if(passphrase.length() > PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE) + { + errString = std::string("(EE) passphrase in certificate exceeds the maximum allowed passphrase size") ; + return false ; + } + if(keynumbits % 1024 != 0) + { + errString = std::string("(EE) RSA key length is not a multiple of 1024") ; + return false ; + } + + // Now the real thing + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + // 1 - generate keypair - RSA-2048 + // + ops_user_id_t uid ; + char *s = strdup((name + " (Generated by RetroShare) <" + email + ">" ).c_str()) ; + uid.user_id = (unsigned char *)s ; + unsigned long int e = 65537 ; // some prime number + + ops_keydata_t *key = ops_rsa_create_selfsigned_keypair(keynumbits, e, &uid) ; + + free(s) ; + + if(!key) + return false ; + + // 2 - save the private key encrypted to a temporary memory buffer, so as to read an encrypted key to memory + + ops_create_info_t *cinfo = NULL ; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&cinfo, &buf, 0); + + if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) + { + errString = std::string("(EE) Cannot encode secret key to memory!!") ; + return false ; + } + + // 3 - read the memory chunk into an encrypted keyring + + ops_keyring_t *tmp_secring = allocateOPSKeyring() ; + + if(! ops_keyring_read_from_mem(tmp_secring, ops_false, buf)) + { + errString = std::string("(EE) Cannot re-read key from memory!!") ; + return false ; + } + ops_teardown_memory_write(cinfo,buf); // cleanup memory + + // 4 - copy the encrypted private key to the private keyring + + pgpId = RsPgpId(tmp_secring->keys[0].key_id) ; + addNewKeyToOPSKeyring(_secring,tmp_secring->keys[0]) ; + initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; +#endif + ops_keyring_free(tmp_secring) ; + free(tmp_secring) ; + + // 5 - add key to secret keyring on disk. + + cinfo = NULL ; + std::string secring_path_tmp = _secring_path + ".tmp" ; + + if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) + { + errString= std::string("Cannot copy secret keyring !! Disk full? Out of disk quota?") ; + return false ; + } + int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); + + if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) + { + errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) + { + errString= std::string("Cannot rename tmp secret key file ") + secring_path_tmp + " into " + _secring_path +". Disk error?" ; + return false ; + } + + // 6 - copy the public key to the public keyring on disk + + cinfo = NULL ; + std::string pubring_path_tmp = _pubring_path + ".tmp" ; + + if(RsDirUtil::fileExists(_pubring_path) && !RsDirUtil::copyFile(_pubring_path,pubring_path_tmp)) + { + errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; + return false ; + } + fd=ops_setup_file_append(&cinfo, pubring_path_tmp.c_str()); + + if(!ops_write_transferable_public_key(key, ops_false, cinfo)) + { + errString=std::string("Cannot encode secret key to memory!!") ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + if(!RsDirUtil::renameFile(pubring_path_tmp,_pubring_path)) + { + errString= std::string("Cannot rename tmp public key file ") + pubring_path_tmp + " into " + _pubring_path +". Disk error?" ; + return false ; + } + // 7 - clean + ops_keydata_free(key) ; + + // 8 - re-read the key from the public keyring, and add it to memory. + + _pubring_last_update_time = 0 ; // force update pubring from disk. + locked_syncPublicKeyring() ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; +#endif + + // 9 - Update some flags. + + privateTrustCertificate(pgpId,PGPCertificateInfo::PGP_CERTIFICATE_TRUST_ULTIMATE) ; + + return true ; +} + +std::string OpenPGPSDKHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) +{ + ops_create_info_t* cinfo; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&cinfo, &buf, 0); + ops_boolean_t armoured = ops_true ; + + if(key->type == OPS_PTAG_CT_PUBLIC_KEY) + { + if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true) + return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; + } + else if(key->type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + { + if(ops_write_transferable_secret_key_from_packet_data(key,armoured,cinfo) != ops_true) + return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; + } + else + { + ops_create_info_delete(cinfo); + std::cerr << "Unhandled key type " << key->type << std::endl; + return "ERROR: Cannot write key. Unhandled key type. " ; + } + + ops_writer_close(cinfo) ; + + std::string res((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ; + ops_teardown_memory_write(cinfo,buf); + + if(!include_signatures) + { + std::string tmp ; + if(PGPKeyManagement::createMinimalKey(res,tmp) ) + res = tmp ; + } + + return res ; +} + +const ops_keydata_t *OpenPGPSDKHandler::locked_getSecretKey(const RsPgpId& id) const +{ + std::map::const_iterator res = _secret_keyring_map.find(id) ; + + if(res == _secret_keyring_map.end()) + return NULL ; + else + return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; +} +const ops_keydata_t *OpenPGPSDKHandler::locked_getPublicKey(const RsPgpId& id,bool stamp_the_key) const +{ + std::map::const_iterator res = _public_keyring_map.find(id) ; + + if(res == _public_keyring_map.end()) + return NULL ; + else + { + if(stamp_the_key) // Should we stamp the key as used? + { + static rstime_t last_update_db_because_of_stamp = 0 ; + rstime_t now = time(NULL) ; + + res->second._time_stamp = now ; + + if(now > last_update_db_because_of_stamp + 3600) // only update database once every hour. No need to do it more often. + { + _trustdb_changed = true ; + last_update_db_because_of_stamp = now ; + } + } + return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; + } +} + +std::string OpenPGPSDKHandler::SaveCertificateToString(const RsPgpId& id,bool include_signatures) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + const ops_keydata_t *key = locked_getPublicKey(id,false) ; + + if(key == NULL) + { + std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; + return "" ; + } + + return makeRadixEncodedPGPKey(key,include_signatures) ; +} + +bool OpenPGPSDKHandler::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const +{ + mem_block = nullptr; mem_size = 0; // clear just in case + + if(armoured) + { + RsErr() << __PRETTY_FUNCTION__ << " should not be used with " + << "armoured=true, because there's a bug in the armoured export" + << " of OPS" << std::endl; + print_stacktrace(); + return false; + } + + RS_STACK_MUTEX(pgphandlerMtx); + const ops_keydata_t* key = locked_getPublicKey(id,false); + + if(!key) + { + RsErr() << __PRETTY_FUNCTION__ << " key id: " << id + << " not found in keyring." << std::endl; + return false; + } + + ops_create_info_t* cinfo; + ops_memory_t *buf = nullptr; + ops_setup_memory_write(&cinfo, &buf, 0); + + if(ops_write_transferable_public_key_from_packet_data( + key, armoured, cinfo ) != ops_true) + { + RsErr() << __PRETTY_FUNCTION__ << " This key id " << id + << " cannot be processed by RetroShare because DSA certificates" + << " support is not implemented yet." << std::endl; + return false; + } + + ops_writer_close(cinfo); + + mem_size = ops_memory_get_length(buf); + mem_block = reinterpret_cast(malloc(mem_size)); + memcpy(mem_block,ops_memory_get_data(buf),mem_size); + + ops_teardown_memory_write(cinfo,buf); + + if(!include_signatures) + { + size_t new_size; + PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size); + mem_size = new_size; + } + + return true; +} + +bool OpenPGPSDKHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *pubkey = locked_getPublicKey(exported_key_id,false) ; + + if(pubkey == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; + return false ; + } + const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; + + if(seckey == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; + return false ; + } + + FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; + if(f == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; + return false ; + } + + fprintf(f,"%s\n", makeRadixEncodedPGPKey(pubkey,true).c_str()) ; + fprintf(f,"%s\n", makeRadixEncodedPGPKey(seckey,true).c_str()) ; + + fclose(f) ; + return true ; +} + +bool OpenPGPSDKHandler::exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const +{ + RS_STACK_MUTEX(pgphandlerMtx); + + const ops_keydata_t *pubkey = locked_getPublicKey(exportedKeyId,false); + + if(!pubkey) + { + errorMsg = "Cannot output key " + exportedKeyId.toStdString() + + ": not found in public keyring."; + return false; + } + const ops_keydata_t *seckey = locked_getSecretKey(exportedKeyId); + + if(!seckey) + { + errorMsg = "Cannot output key " + exportedKeyId.toStdString() + + ": not found in secret keyring."; + return false; + } + + data = makeRadixEncodedPGPKey(pubkey, includeSignatures); + data += "\n"; + data += makeRadixEncodedPGPKey(seckey, includeSignatures); + data += "\n"; + return true; +} + +bool OpenPGPSDKHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const +{ + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + ops_memory_t *mem = ops_memory_new() ; + ops_memory_add(mem,mem_block,mem_size); + + if(!ops_keyring_read_from_mem(tmp_keyring,ops_false,mem)) + { + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + ops_memory_release(mem) ; + free(mem) ; + + std::cerr << "Could not read key. Format error?" << std::endl; + //error_string = std::string("Could not read key. Format error?") ; + return false ; + } + ops_memory_release(mem) ; + free(mem) ; + //error_string.clear() ; + + if(tmp_keyring->nkeys != 1) + { + std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; + return false ; + } + if(tmp_keyring->keys[0].uids == NULL) + { + std::cerr << "No uid in supplied key." << std::endl; + return false ; + } + + key_id = RsPgpId(tmp_keyring->keys[0].key_id) ; + name = std::string((char *)tmp_keyring->keys[0].uids[0].user_id) ; + + // now parse signatures. + // + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + ops_boolean_t res ; + + { + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],_pubring,cb_get_passphrase) ; + } + + if(res == ops_false) + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + + // also add self-signature if any (there should be!). + // + res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; + + if(res == ops_false) + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + + // Parse signers. + // + + std::set signers_set ; // Use a set to remove duplicates. + + if(result != NULL) + for(size_t i=0;ivalid_count;++i) + signers_set.insert(RsPgpId(result->valid_sigs[i].signer_id)) ; + + ops_validate_result_free(result) ; + + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + + // write to the output variable + + signers.clear() ; + + for(std::set::const_iterator it(signers_set.begin());it!=signers_set.end();++it) + signers.push_back(*it) ; + + return true ; +} + +bool OpenPGPSDKHandler::importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) +{ + import_error = "" ; + + // 1 - Test for file existance + // + FILE *ftest = RsDirUtil::rs_fopen(filename.c_str(),"r") ; + + if(ftest == NULL) + { + import_error = "Cannot open file " + filename + " for read. Please check access permissions." ; + return false ; + } + + fclose(ftest) ; + + // 2 - Read keyring from supplied file. + // + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + + if(ops_false == ops_keyring_read_from_file(tmp_keyring, ops_true, filename.c_str())) + { + import_error = "OpenPGPSDKHandler::readKeyRing(): cannot read key file. File corrupted?" ; + free(tmp_keyring); + return false ; + } + + return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); +} + +bool OpenPGPSDKHandler::importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) +{ + import_error = "" ; + + ops_memory_t* mem = ops_memory_new(); + ops_memory_add(mem, (unsigned char*)data.data(), data.length()); + + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + + if(ops_false == ops_keyring_read_from_mem(tmp_keyring, ops_true, mem)) + { + import_error = "OpenPGPSDKHandler::importGPGKeyPairFromString(): cannot parse key data" ; + free(tmp_keyring); + return false ; + } + return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); +} + +bool OpenPGPSDKHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &imported_key_id, std::string &import_error) +{ + if(tmp_keyring == 0) + { + import_error = "OpenPGPSDKHandler::checkAndImportKey(): keyring is null" ; + return false; + } + + if(tmp_keyring->nkeys != 2) + { + import_error = "OpenPGPSDKHandler::importKeyPair(): file does not contain a valid keypair." ; + if(tmp_keyring->nkeys > 2) + import_error += "\nMake sure that your key is a RSA key (DSA is not yet supported) and does not contain subkeys (not supported yet)."; + return false ; + } + + // 3 - Test that keyring contains a valid keypair. + // + const ops_keydata_t *pubkey = NULL ; + const ops_keydata_t *seckey = NULL ; + + if(tmp_keyring->keys[0].type == OPS_PTAG_CT_PUBLIC_KEY) + pubkey = &tmp_keyring->keys[0] ; + else if(tmp_keyring->keys[0].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + seckey = &tmp_keyring->keys[0] ; + else + { + import_error = "Unrecognised key type in key file for key #0. Giving up." ; + std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; + return false ; + } + if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) + pubkey = &tmp_keyring->keys[1] ; + else if(tmp_keyring->keys[1].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + seckey = &tmp_keyring->keys[1] ; + else + { + import_error = "Unrecognised key type in key file for key #1. Giving up." ; + std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; + return false ; + } + + if(pubkey == nullptr || seckey == nullptr || pubkey == seckey) + { + import_error = "File does not contain a public and a private key. Sorry." ; + return false ; + } + if(memcmp( pubkey->fingerprint.fingerprint, + seckey->fingerprint.fingerprint, + RsPgpFingerprint::SIZE_IN_BYTES ) != 0) + { + import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; + return false ; + } + if(pubkey->key.pkey.version != 4) + { + import_error = "Public key is not version 4. Rejected!" ; + return false ; + } + + // 4 - now check self-signature for this keypair. For this we build a dummy keyring containing only the key. + // + ops_validate_result_t *result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + + ops_keyring_t dummy_keyring ; + dummy_keyring.nkeys=1 ; + dummy_keyring.nkeys_allocated=1 ; + dummy_keyring.keys=const_cast(pubkey) ; + + ops_validate_key_signatures(result, const_cast(pubkey), &dummy_keyring, cb_get_passphrase) ; + + // Check that signatures contain at least one certification from the user id. + // + bool found = false ; + + for(uint32_t i=0;ivalid_count;++i) + if(!memcmp( + static_cast(result->valid_sigs[i].signer_id), + pubkey->key_id, + RsPgpId::SIZE_IN_BYTES )) + { + found = true ; + break ; + } + + if(!found) + { + import_error = "Cannot validate self signature for the imported key. Sorry." ; + return false ; + } + ops_validate_result_free(result); + + if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + import_error = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; + return false ; + } + // 5 - All test passed. Adding key to keyring. + // + { + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + imported_key_id = RsPgpId(pubkey->key_id) ; + + if(locked_getSecretKey(imported_key_id) == NULL) + { + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + ops_create_info_t *cinfo = NULL ; + + // Make a copy of the secret keyring + // + std::string secring_path_tmp = _secring_path + ".tmp" ; + if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) + { + import_error = "(EE) Cannot write secret key to disk!! Disk full? Out of disk quota. Keyring will be left untouched." ; + return false ; + } + + // Append the new key + + int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); + + if(!ops_write_transferable_secret_key_from_packet_data(seckey,ops_false,cinfo)) + { + import_error = "(EE) Cannot encode secret key to disk!! Disk full? Out of disk quota?" ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + // Rename the new keyring to overwrite the old one. + // + if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) + { + import_error = " (EE) Cannot move temp file " + secring_path_tmp + ". Bad write permissions?" ; + return false ; + } + + addNewKeyToOPSKeyring(_secring,*seckey) ; + initCertificateInfo(_secret_keyring_map[ imported_key_id ],seckey,_secring->nkeys-1) ; + } + else + import_error = "Private key already exists! Not importing it again." ; + + if(locked_addOrMergeKey(_pubring,_public_keyring_map,pubkey)) + _pubring_changed = true ; + } + + // 6 - clean + // + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring); + + // write public key to disk + syncDatabase(); + + return true ; +} + +void OpenPGPSDKHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& key) +{ + if(kr->nkeys >= kr->nkeys_allocated) + { + kr->keys = (ops_keydata_t *)realloc(kr->keys,(kr->nkeys+1)*sizeof(ops_keydata_t)) ; + kr->nkeys_allocated = kr->nkeys+1; + } + memset(&kr->keys[kr->nkeys],0,sizeof(ops_keydata_t)) ; + ops_keydata_copy(&kr->keys[kr->nkeys],&key) ; + kr->nkeys++ ; +} + +bool OpenPGPSDKHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) +{ + return LoadCertificate(data,data_len,ops_false,id,error_string); +} + +bool OpenPGPSDKHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) +{ + return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string); +} + +bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. +#ifdef DEBUG_PGPHANDLER + std::cerr << "Reading new key from string: " << std::endl; +#endif + + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + ops_memory_t *mem = ops_memory_new() ; + ops_memory_add(mem,data,data_len) ; + + if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem)) + { + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + ops_memory_release(mem) ; + free(mem) ; + + std::cerr << "Could not read key. Format error?" << std::endl; + error_string = std::string("Could not read key. Format error?") ; + return false ; + } + ops_memory_release(mem) ; + free(mem) ; + error_string.clear() ; + + // Check that there is exactly one key in this data packet. + // + if(tmp_keyring->nkeys != 1) + { + std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; + error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; + return false ; + } + + const ops_keydata_t *keydata = ops_keyring_get_key_by_index(tmp_keyring,0); + + // Check that the key is a version 4 key + // + if(keydata->key.pkey.version != 4) + { + error_string = "Public key is not version 4. Rejected!" ; + std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; + return false ; + } + + // Check that the key is correctly self-signed. + // + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + + ops_validate_key_signatures(result,keydata,tmp_keyring,cb_get_passphrase) ; + + bool found = false ; + + for(uint32_t i=0;ivalid_count;++i) + if(!memcmp( + static_cast(result->valid_sigs[i].signer_id), + keydata->key_id, + RsPgpId::SIZE_IN_BYTES )) + { + found = true ; + break ; + } + + if(!found) + { + error_string = "This key is not self-signed. This is required by Retroshare." ; + std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; + ops_validate_result_free(result); + return false ; + } + ops_validate_result_free(result); + +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key read correctly: " << std::endl; + ops_keyring_list(tmp_keyring) ; +#endif + + int i=0 ; + + while( (keydata = ops_keyring_get_key_by_index(tmp_keyring,i++)) != NULL ) + if(locked_addOrMergeKey(_pubring,_public_keyring_map,keydata)) + { + _pubring_changed = true ; +#ifdef DEBUG_PGPHANDLER + std::cerr << " Added the key in the main public keyring." << std::endl; +#endif + } + else + std::cerr << "Key already in public keyring." << std::endl; + + if(tmp_keyring->nkeys > 0) + id = RsPgpId(tmp_keyring->keys[0].key_id) ; + else + return false ; + + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + + _pubring_changed = true ; + + return true ; +} + +bool OpenPGPSDKHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) +{ + bool ret = false ; + RsPgpId id(keydata->key_id) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "AddOrMergeKey():" << std::endl; + std::cerr << " id: " << id.toStdString() << std::endl; +#endif + + // See if the key is already in the keyring + const ops_keydata_t *existing_key = NULL; + std::map::const_iterator res = kmap.find(id) ; + + // Checks that + // - the key is referenced by keyid + // - the map is initialized + // - the fingerprint matches! + // + if(res == kmap.end() || (existing_key = ops_keyring_get_key_by_index(keyring,res->second._key_index)) == NULL) + { +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key is new. Adding it to keyring" << std::endl; +#endif + addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. + initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; + existing_key = &(keyring->keys[keyring->nkeys-1]) ; + ret = true ; + } + else + { + if(memcmp( existing_key->fingerprint.fingerprint, + keydata->fingerprint.fingerprint, + RsPgpFingerprint::SIZE_IN_BYTES )) + { + std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; + return false ; + } + +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key exists. Merging signatures." << std::endl; +#endif + ret = mergeKeySignatures(const_cast(existing_key),keydata) ; + + if(ret) + initCertificateInfo(kmap[id],existing_key,res->second._key_index) ; + } + + if(ret) + { + validateAndUpdateSignatures(kmap[id],existing_key) ; + kmap[id]._time_stamp = time(NULL) ; + } + + return ret ; +} + +bool OpenPGPSDKHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; + + if(public_key == NULL) + { + std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + return false ; + } + + if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + return false ; + } + + std::string outfile_tmp = outfile + ".tmp" ; + + ops_create_info_t *info; + int fd = ops_setup_file_write(&info, outfile_tmp.c_str(), ops_true); + + if (fd < 0) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; + return false ; + } + + if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; + return false ; + } + + ops_write(text.c_str(), text.length(), info); + ops_teardown_file_write(info, fd); + + if(!RsDirUtil::renameFile(outfile_tmp,outfile)) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; + return false ; + } + + return true ; +} + +bool OpenPGPSDKHandler::encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; + + if(public_key == NULL) + { + std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + return false ; + } + + if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + return false ; + } + if(public_key->key.pkey.algorithm != OPS_PKA_RSA) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; + return false ; + } + ops_create_info_t *info; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&info, &buf, 0); + bool res = true; + + if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) + { + std::cerr << "Encryption failed." << std::endl; + res = false ; + } + + ops_write(data,len,info); + ops_writer_close(info); + ops_create_info_delete(info); + + int tlen = ops_memory_get_length(buf) ; + + if( (int)*encrypted_data_len >= tlen) + { + if(res) + { + memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ; + *encrypted_data_len = tlen ; + res = true ; + } + } + else + { + std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; + res = false ; + } + + ops_memory_release(buf) ; + free(buf) ; + + return res ; +} + +bool OpenPGPSDKHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) +{ + int out_length ; + unsigned char *out ; + ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ; + + if(*data_len < (unsigned int)out_length) + { + std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; + return false ; + } + + *data_len = (unsigned int)out_length ; + memcpy(data,out,out_length) ; + free(out) ; + + return (bool)res ; +} + +bool OpenPGPSDKHandler::decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + unsigned char *out_buf = NULL ; + std::string buf ; + + FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"rb") ; + + if (f == NULL) + { + std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; + return false; + } + + int c ; + while( (c = fgetc(f))!= EOF) + buf += (unsigned char)c; + + fclose(f) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "OpenPGPSDKHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; + std::cerr << "buf=\"" << buf << "\"" << std::endl; +#endif + + int out_length ; + ops_boolean_t res = ops_decrypt_memory((const unsigned char *)buf.c_str(),buf.length(),&out_buf,&out_length,_secring,ops_true,cb_get_passphrase) ; + + text = std::string((char *)out_buf,out_length) ; + free (out_buf); + return (bool)res ; +} + +bool OpenPGPSDKHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + // need to find the key and to decrypt it. + + const ops_keydata_t *key = locked_getSecretKey(id) ; + + if(!key) + { + std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; + return false ; + } + + std::string uid_hint ; + if(key->nuids > 0) + uid_hint = std::string((const char *)key->uids[0].user_id) ; + uid_hint += "(" + RsPgpId(key->key_id).toStdString()+")" ; + +#ifdef DEBUG_PGPHANDLER + ops_fingerprint_t f ; + ops_fingerprint(&f,&key->key.pkey) ; + + PGPFingerprintType fp(f.fingerprint) ; +#endif + + bool last_passwd_was_wrong = false ; +ops_secret_key_t *secret_key = NULL ; + + for(int i=0;i<3;++i) + { + bool cancelled =false; + std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason + + secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; + + if(cancelled) + { + std::cerr << "Key entering cancelled" << std::endl; + return false ; + } + if(secret_key) + break ; + + std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + last_passwd_was_wrong = true ; + } + if(!secret_key) + { + std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; + return false ; + } + + // then do the signature. + + ops_boolean_t not_raw = !use_raw_signature ; +#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 + ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; +#else + ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ; +#endif + + if(!memres) + return false ; + + bool res ; + uint32_t slen = (uint32_t)ops_memory_get_length(memres); + + if(*signlen >= slen) + { + *signlen = slen ; + + memcpy(sign,ops_memory_get_data(memres),*signlen) ; + res = true ; + } + else + { + std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; + res = false ; + } + + ops_memory_release(memres) ; + free(memres) ; + ops_secret_key_free(secret_key) ; + free(secret_key) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; + std::cerr << "Signature body: " << std::endl; + hexdump( (unsigned char *)data, len) ; + std::cerr << std::endl; + std::cerr << "Data: " << std::endl; + hexdump( (unsigned char *)sign,*signlen) ; + std::cerr << std::endl; +#endif + return res ; +} + +bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + ops_keydata_t *key_to_sign = const_cast(locked_getPublicKey(id_of_key_to_sign,true)) ; + + if(key_to_sign == NULL) + { + std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; + return false ; + } + + // 1 - get decrypted secret key + // + const ops_keydata_t *skey = locked_getSecretKey(ownId) ; + + if(!skey) + { + std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; + return false ; + } + const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; + + if(!pkey) + { + std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; + return false ; + } + + bool cancelled = false; + std::string passphrase = _passphrase_callback(NULL,"",RsPgpId(skey->key_id).toStdString().c_str(),"Please enter passwd for encrypting your key : ",false,&cancelled) ; + + ops_secret_key_t *secret_key = ops_decrypt_secret_key_from_data(skey,passphrase.c_str()) ; + + if(cancelled) + { + std::cerr << "Key cancelled by used." << std::endl; + return false ; + } + if(!secret_key) + { + std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + return false ; + } + + // 2 - then do the signature. + + if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) + { + std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; + return false ; + } + + // 3 - free memory + // + ops_secret_key_free(secret_key) ; + free(secret_key) ; + + _pubring_changed = true ; + + // 4 - update signatures. + // + PGPCertificateInfo& cert(_public_keyring_map[ id_of_key_to_sign ]) ; + validateAndUpdateSignatures(cert,key_to_sign) ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; + + return true ; +} + +bool OpenPGPSDKHandler::getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const +{ + RS_STACK_MUTEX(pgphandlerMtx); + + const ops_keydata_t *key = locked_getPublicKey(id,false) ; + + if(!key) return false; + + ops_fingerprint_t f ; + ops_fingerprint(&f,&key->key.pkey) ; + + fp = RsPgpFingerprint::fromBufferUnsafe(f.fingerprint); + + return true ; +} + +bool OpenPGPSDKHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + RsPgpId id = RsPgpId(key_fingerprint.toByteArray() + PGPFingerprintType::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES) ; + const ops_keydata_t *key = locked_getPublicKey(id,true) ; + + if(key == NULL) + { + std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; + return false ; + } + + // Check that fingerprint is the same. + const ops_public_key_t *pkey = &key->key.pkey ; + ops_fingerprint_t fp ; + ops_fingerprint(&fp,pkey) ; + + if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) + { + std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; + return false ; + } + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; + std::cerr << "Signature body: " << std::endl; + hexdump( (unsigned char *)sign,sign_len) ; + std::cerr << std::endl; + std::cerr << "Signed data: " << std::endl; + hexdump( (unsigned char *)literal_data, literal_data_length) ; + std::cerr << std::endl; +#endif + + return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; +} + +// Lexicographic order on signature packets +// +bool operator<(const ops_packet_t& p1,const ops_packet_t& p2) +{ + if(p1.length < p2.length) + return true ; + if(p1.length > p2.length) + return false ; + + for(uint32_t i=0;i p2.raw[i]) + return false ; + } + return false ; +} + +bool OpenPGPSDKHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) +{ + // First sort all signatures into lists to see which is new, which is not new + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; +#endif + std::set dst_packets ; + + for(uint32_t i=0;inpackets;++i) dst_packets.insert(dst->packets[i]) ; + + std::set to_add ; + + for(uint32_t i=0;inpackets;++i) + if(dst_packets.find(src->packets[i]) == dst_packets.end()) + { + uint8_t tag ; + uint32_t length ; + unsigned char *tmp_data = src->packets[i].raw ; // put it in a tmp variable because read_packetHeader() will modify it!! + + PGPKeyParser::read_packetHeader(tmp_data,tag,length) ; + + if(tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) + to_add.insert(src->packets[i]) ; +#ifdef DEBUG_PGPHANDLER + else + std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; +#endif + } + + for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) + { +#ifdef DEBUG_PGPHANDLER + std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; +#endif + ops_add_packet_to_keydata(dst,&*it) ; + } + return to_add.size() > 0 ; +} + +bool OpenPGPSDKHandler::syncDatabase() +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Sync-ing keyrings." << std::endl; +#endif + locked_syncPublicKeyring() ; + //locked_syncSecretKeyring() ; + + // Now sync the trust database as well. + // + locked_syncTrustDatabase() ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Done. " << std::endl; +#endif + return true ; +} + +bool OpenPGPSDKHandler::locked_syncPublicKeyring() +{ + struct stat64 buf ; +#ifdef WINDOWS_SYS + std::wstring wfullname; + librs::util::ConvertUtf8ToUtf16(_pubring_path, wfullname); + if(-1 == _wstati64(wfullname.c_str(), &buf)) +#else + if(-1 == stat64(_pubring_path.c_str(), &buf)) +#endif + std::cerr << "OpenPGPSDKHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; + + if(_pubring_last_update_time < buf.st_mtime) + { + std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; + + locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; + _pubring_last_update_time = buf.st_mtime ; + } + + // Now check if the pubring was locally modified, which needs saving it again + if(_pubring_changed && RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + std::string tmp_keyring_file = _pubring_path + ".tmp" ; + + std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; + if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) + { + std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; + return false ; + } + if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) + { + std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; + return false ; + } + + std::cerr << "Done." << std::endl; + _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? + _pubring_changed = false ; + } + return true ; +} + +void OpenPGPSDKHandler::locked_mergeKeyringFromDisk(ops_keyring_t *keyring, + std::map& kmap, + const std::string& keyring_file) +{ +#ifdef DEBUG_PGPHANDLER + std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; +#endif + + // 1 - load keyring into a temporary keyring list. + ops_keyring_t *tmp_keyring = OpenPGPSDKHandler::allocateOPSKeyring() ; + + if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) + { + std::cerr << "OpenPGPSDKHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; + ops_keyring_free(tmp_keyring) ; + return ; + } + + // 2 - load new keys and merge existing key signatures + + for(int i=0;inkeys;++i) + locked_addOrMergeKey(keyring,kmap,&tmp_keyring->keys[i]) ;// we dont' account for the return value. This is disk merging, not local changes. + + // 4 - clean + ops_keyring_free(tmp_keyring) ; +} + +bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_to_remove,std::string& backup_file,uint32_t& error_code) +{ + // 1 - lock everything. + // + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + error_code = PGP_KEYRING_REMOVAL_ERROR_NO_ERROR ; + + for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) + if(locked_getSecretKey(*it) != NULL) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; + return false ; + } + + // 2 - sync everything. + // + locked_syncPublicKeyring() ; + + // 3 - make a backup of the public keyring + // + char template_name[_pubring_path.length()+8] ; + sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ; + +#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 + int fd_keyring_backup(mkstemp(template_name)); + if (fd_keyring_backup == -1) +#else + if(mktemp(template_name) == NULL) +#endif + { + std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; + return false ; + } +#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 + close(fd_keyring_backup); // TODO: keep the file open and use the fd +#endif + + if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) + { + std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; + return false ; + } + backup_file = std::string(template_name,_pubring_path.length()+7) ; + + std::cerr << "Keyring was backed up to file " << backup_file << std::endl; + + // Remove keys from the keyring, and update the keyring map. + // + for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) + { + if(locked_getSecretKey(*it) != NULL) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; + continue ; + } + + std::map::iterator res = _public_keyring_map.find(*it) ; + + if(res == _public_keyring_map.end()) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; + continue ; + } + + if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; + return false ; + } + + // Move the last key to the freed place. This deletes the key in place. + // + ops_keyring_remove_key(_pubring,res->second._key_index) ; + + // Erase the info from the keyring map. + // + _public_keyring_map.erase(res) ; + + // now update all indices back. This internal look is very costly, but it avoids deleting the wrong keys, since the keyring structure is + // changed by ops_keyring_remove_key and therefore indices don't point to the correct location anymore. + + int i=0 ; + const ops_keydata_t *keydata ; + while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) + { + PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; + cert._key_index = i ; + ++i ; + } + } + + // Everything went well, sync back the keyring on disk + + _pubring_changed = true ; + _trustdb_changed = true ; + + locked_syncPublicKeyring() ; + locked_syncTrustDatabase() ; + + return true ; +} diff --git a/libretroshare/src/pgp/openpgpsdkhandler.h b/libretroshare/src/pgp/openpgpsdkhandler.h new file mode 100644 index 000000000..e6c06ba84 --- /dev/null +++ b/libretroshare/src/pgp/openpgpsdkhandler.h @@ -0,0 +1,116 @@ +/******************************************************************************* + * libretroshare/src/pgp: pgphandler.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2018 Cyril Soler * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include + +#include "util/rsthreads.h" +#include "pgp/pgphandler.h" +#include "retroshare/rstypes.h" + +extern "C" { + // we should make sure later on to get rid of these structures in the .h + #include "openpgpsdk/keyring.h" +} + +/// This class offer an abstract pgp handler to be used in RetroShare. +class OpenPGPSDKHandler: public PGPHandler +{ +public: + OpenPGPSDKHandler( const std::string& path_to_public_keyring, + const std::string& path_to_secret_keyring, + const std::string& path_to_trust_database, + const std::string& pgp_lock_file) ; + + virtual ~OpenPGPSDKHandler() ; + + //================================================================================================// + // Implemented API from PGPHandler // + //================================================================================================// + + virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; + virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) override; + virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids) override; + virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) override; + + virtual std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const override; + virtual bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const override; + + virtual bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const override; + virtual bool exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const override; + virtual bool getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const override; + virtual bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) override; + virtual bool importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) override; + virtual bool LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) override; + virtual bool LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) override; + virtual bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) override; + virtual bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) override; + virtual bool decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) override; + virtual bool decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) override; + virtual bool SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) override; + virtual bool privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) override; + virtual bool VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) override; + virtual bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const override; + virtual bool haveSecretKey(const RsPgpId& id) const override; + virtual bool syncDatabase() override; + private: + bool locked_syncPublicKeyring() ; + + void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; + bool LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) ; + + // Returns true if the signatures have been updated + // + bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; + + /** Check public/private key and import them into the keyring + * @param keyring keyring with the new public/private key pair. Will be freed by the function. + * @param imported_key_id PGP id of the imported key + * @param import_error human readbale error message + * @returns true on success + * */ + bool checkAndImportKeyPair(ops_keyring_t *keyring, RsPgpId& imported_key_id,std::string& import_error); + + const ops_keydata_t *locked_getPublicKey(const RsPgpId&,bool stamp_the_key) const; + const ops_keydata_t *locked_getSecretKey(const RsPgpId&) const ; + + void locked_mergeKeyringFromDisk(ops_keyring_t *keyring, std::map& kmap, const std::string& keyring_file) ; + bool locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) ; + + // Members. + // + ops_keyring_t *_pubring ; + ops_keyring_t *_secring ; + + void printOPSKeys() const; + + // Helper functions. + // + static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) ; + static ops_keyring_t *allocateOPSKeyring() ; + static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; + static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different +}; From b084b20280665fcfe1d16beed2c2704f4c194019 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 14 Aug 2021 14:56:28 +0200 Subject: [PATCH 136/697] removed getAuthGPG and replaced AuthGPG with a class with static members --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 20 +- libretroshare/src/pgp/pgpauxutils.cc | 10 +- libretroshare/src/pqi/authgpg.cc | 186 +++++++++++------- libretroshare/src/pqi/authgpg.h | 115 ++++++----- libretroshare/src/pqi/authssl.cc | 15 +- libretroshare/src/pqi/p3peermgr.cc | 20 +- libretroshare/src/pqi/pqissl.cc | 3 +- libretroshare/src/pqi/pqissllistener.cc | 3 +- libretroshare/src/rsserver/p3peers.cc | 61 +++--- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 29 +-- libretroshare/src/rsserver/rsinit.cc | 11 +- libretroshare/src/rsserver/rsloginhandler.cc | 5 +- libretroshare/src/services/p3idservice.cc | 4 +- 14 files changed, 266 insertions(+), 218 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 732967f44..179a845d7 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthGPG::getAuthGPG()->getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthGPG::getGPGOwnId()] = DiscPgpInfo(); } @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthGPG::getAuthGPG()->isGPGAccepted(pgpId))) + if (!(AuthGPG::isGPGAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); - AuthGPG::getAuthGPG()->getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); + AuthGPG::getGPGAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -723,7 +723,7 @@ void p3discovery2::processPGPList(const RsPeerId &fromId, const RsDiscPgpListIte std::set::const_iterator fit; for(fit = item->pgpIdSet.ids.begin(); fit != item->pgpIdSet.ids.end(); ++fit) { - if (!AuthGPG::getAuthGPG()->isGPGId(*fit)) + if (!AuthGPG::isPGPId(*fit)) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit; @@ -1058,11 +1058,11 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); + RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::getAuthGPG()->isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::isGPGAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; @@ -1078,7 +1078,7 @@ void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &to unsigned char *bin_data; size_t bin_len; - if(!AuthGPG::getAuthGPG()->exportPublicKey(aboutId,bin_data,bin_len,false,true)) + if(!AuthGPG::exportPublicKey(aboutId,bin_data,bin_len,false,true)) { std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl; return ; @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthGPG::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; @@ -1147,7 +1147,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* // otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key. if(det.skip_pgp_signature_validation) - AuthGPG::getAuthGPG()->AllowConnection(det.gpg_id,true); + AuthGPG::AllowConnection(det.gpg_id,true); } /************* from pqiServiceMonitor *******************/ diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index d7229e848..a9c3b36f6 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -44,7 +44,7 @@ RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) bool PgpAuxUtilsImpl::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const { - return AuthGPG::getAuthGPG()->getKeyFingerprint(id, fp); + return AuthGPG::getKeyFingerprint(id, fp); } bool PgpAuxUtilsImpl::VerifySignBin(const void *data, @@ -54,17 +54,17 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, const PGPFingerprintType& withfingerprint) { - return AuthGPG::getAuthGPG()->VerifySignBin(data, len, sign, signlen, withfingerprint); + return AuthGPG::VerifySignBin(data, len, sign, signlen, withfingerprint); } bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthGPG::getAuthGPG()->getGPGAllList(ids); + return AuthGPG::getGPGAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const { - return AuthGPG::getAuthGPG()->parseSignature(sign,signlen,issuer); + return AuthGPG::parseSignature(sign,signlen,issuer); } diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 2d29fbb65..b870b5d1e 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -54,9 +54,21 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ +int AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +{ + return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); +} +bool AuthGPG::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +{ + return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); +} +void AuthGPG::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) +{ + CfgMgr->addConfiguration(fname, instance()); +} bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) { - return PGPHandler::decryptTextFromFile(mOwnGpgId,text,inputfile) ; + return instance()->mPgpHandler->decryptTextFromFile(instance()->mOwnGpgId,text,inputfile) ; } bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) @@ -66,22 +78,22 @@ bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::str // for(std::list::const_iterator it(pgp_ids.begin());it!=pgp_ids.end();++it) // pids.push_back(RsPgpId(*it)) ; - return PGPHandler::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return instance()->mPgpHandler->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } // bool AuthGPG::decryptTextFromString(std::string& encrypted_text,std::string& output) // { -// return PGPHandler::decryptTextFromString(mOwnGpgId,encrypted_text,output) ; +// return instance()->mPgpHandler->decryptTextFromString(mOwnGpgId,encrypted_text,output) ; // } bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) { - return PGPHandler::encryptTextToFile(mOwnGpgId,text,outfile) ; + return instance()->mPgpHandler->encryptTextToFile(instance()->mOwnGpgId,text,outfile) ; } // bool AuthGPG::encryptTextToString(const std::string& pgp_id,const std::string& text,std::string& outstr) // { -// return PGPHandler::encryptTextToString(RsPgpId(pgp_id),text,outstr) ; +// return instance()->mPgpHandler->encryptTextToString(RsPgpId(pgp_id),text,outstr) ; // } std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad,bool *cancelled) @@ -107,8 +119,8 @@ void AuthGPG::init( std::cerr << "AuthGPG::init() called twice!" << std::endl ; } -// if(cb) PGPHandler::setPassphraseCallback(cb);else - PGPHandler::setPassphraseCallback(pgp_pwd_callback); +// if(cb) instance()->mPgpHandler->setPassphraseCallback(cb);else + instance()->mPgpHandler->setPassphraseCallback(pgp_pwd_callback); _instance = new AuthGPG( path_to_public_keyring, path_to_secret_keyring, path_to_trustdb, pgp_lock_file ); @@ -126,7 +138,6 @@ void AuthGPG::exit() AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), - OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), gpgMtxData("AuthGPG-data"), @@ -135,7 +146,9 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa _force_sync_database(false), mCount(0) { - start("AuthGPG"); + mPgpHandler = new OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file); + + start("AuthGPG"); } /* This function is called when retroshare is first started @@ -149,7 +162,7 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa //{ // std::list pids ; // -// PGPHandler::availableGPGCertificatesWithPrivateKeys(pids) ; +// mPgpHandler->availableGPGCertificatesWithPrivateKeys(pids) ; // // for(std::list::const_iterator it(pids.begin());it!=pids.end();++it) // ids.push_back( (*it).toStdString() ) ; @@ -171,11 +184,11 @@ int AuthGPG::GPGInit(const RsPgpId &ownId) std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; #endif - mOwnGpgId = RsPgpId(ownId); + instance()->mOwnGpgId = ownId; //force the validity of the private key. When set to unknown, it caused signature and text encryptions bugs - privateTrustCertificate(ownId, 5); - updateOwnSignatureFlag(mOwnGpgId) ; + instance()->privateTrustCertificate(ownId, 5); + instance()->mPgpHandler->updateOwnSignatureFlag(ownId) ; #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit finished." << std::endl; @@ -204,7 +217,7 @@ void AuthGPG::threadTick() /// - checks whether the keyring has changed on disk. /// - merges/updates according to status. /// - PGPHandler::syncDatabase() ; + mPgpHandler->syncDatabase() ; mCount = 0; _force_sync_database = false ; }//if (++count >= 100 || _force_sync_database) @@ -251,7 +264,7 @@ void AuthGPG::processServices() /* don't bother loading - if we already have the certificate */ - if (isGPGId(loadOrSave->m_certGpgId)) + if (mPgpHandler->isGPGId(loadOrSave->m_certGpgId)) { #ifdef GPG_DEBUG std::cerr << "AuthGPGimpl::processServices() Skipping load - already have it" << std::endl; @@ -307,64 +320,64 @@ void AuthGPG::processServices() bool AuthGPG::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) { - return PGPHandler::SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; + return instance()->mPgpHandler->SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; } /* import to GnuPG and other Certificates */ bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) { - return PGPHandler::VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; + return instance()->mPgpHandler->VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; } bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) { - return PGPHandler::parseSignature((unsigned char*)sig,siglen,issuer_id) ; + return instance()->mPgpHandler->parseSignature((unsigned char*)sig,siglen,issuer_id) ; } bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id) { - return PGPHandler::exportGPGKeyPair(fname,exported_id) ; + return instance()->mPgpHandler->exportGPGKeyPair(fname,exported_id) ; } bool AuthGPG::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { - return PGPHandler::exportGPGKeyPairToString( + return instance()->mPgpHandler->exportGPGKeyPairToString( data, pgpId, includeSignatures, errorMsg); } bool AuthGPG::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) { - return PGPHandler::importGPGKeyPair(fname,imported_id,import_error) ; + return instance()->mPgpHandler->importGPGKeyPair(fname,imported_id,import_error) ; } bool AuthGPG::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) { - return PGPHandler::importGPGKeyPairFromString(data, gpg_id, import_error); + return instance()->mPgpHandler->importGPGKeyPairFromString(data, gpg_id, import_error); } bool AuthGPG::active() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - return gpgKeySelected; + return instance()->gpgKeySelected; } bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - return PGPHandler::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString) ; + return instance()->mPgpHandler->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString) ; } /**** These Two are common */ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *info = getCertificateInfo(id) ; + const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; if(info != NULL) { @@ -378,11 +391,29 @@ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) } } +AuthGPG *AuthGPG::instance() +{ + if(!_instance) + { + RsFatal() << "AuthGPG::instance() called before AuthGPG::init()! This should not happen." << std::endl; + return nullptr; + } + + return _instance; +} +bool AuthGPG::isPGPId(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGId(id); +} +bool AuthGPG::isPGPAccepted(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGAccepted(id); +} /**** These Two are common */ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *info = getCertificateInfo(id) ; + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ + const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; if(info != NULL) { @@ -400,20 +431,20 @@ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) const RsPgpId& AuthGPG::getGPGOwnId() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - return mOwnGpgId ; + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ + return instance()->mOwnGpgId ; } std::string AuthGPG::getGPGOwnName() { - return getGPGName(mOwnGpgId) ; + return getGPGName(instance()->mOwnGpgId) ; } bool AuthGPG::getGPGAllList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - PGPHandler::getGPGFilteredList(ids) ; + instance()->mPgpHandler->getGPGFilteredList(ids) ; return true; } @@ -421,7 +452,7 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p { try { - return PGPHandler::getCertificateInfo(RsPgpId(pgp_id)) ; + return instance()->mPgpHandler->getCertificateInfo(RsPgpId(pgp_id)) ; } catch(std::exception& e) { @@ -429,13 +460,13 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p return NULL ; } } -bool AuthGPG::haveSecretKey(const RsPgpId& id) const +bool AuthGPG::haveSecretKey(const RsPgpId& id) { - return PGPHandler::haveSecretKey(id) ; + return instance()->mPgpHandler->haveSecretKey(id) ; } -bool AuthGPG::isKeySupported(const RsPgpId& id) const +bool AuthGPG::isKeySupported(const RsPgpId& id) { - const PGPCertificateInfo *pc = getCertificateInfo(id) ; + const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(id) ; if(pc == NULL) return false ; @@ -445,9 +476,9 @@ bool AuthGPG::isKeySupported(const RsPgpId& id) const bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *pc = PGPHandler::getCertificateInfo(pgp_id) ; + const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(pgp_id) ; if(pc == NULL) return false ; @@ -476,9 +507,7 @@ bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - return PGPHandler::getGPGFilteredList(list,filter) ; + return instance()->mPgpHandler->getGPGFilteredList(list,filter) ; } static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; } //{ return info._validLvl >= PGPCertificateInfo::GPGME_VALIDITY_MARGINAL ; } @@ -504,9 +533,9 @@ bool AuthGPG::getGPGSignedList(std::list &ids) // { // RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ // #ifdef LIMIT_CERTIFICATE_SIZE -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),false) ; +// certificate = instance()->mPgpHandler->SaveCertificateToString(RsPgpId(id),false) ; // #else -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),true) ; +// certificate = instance()->mPgpHandler->SaveCertificateToString(RsPgpId(id),true) ; // #endif // // // #ifdef LIMIT_CERTIFICATE_SIZE @@ -530,18 +559,18 @@ bool AuthGPG::getGPGSignedList(std::list &ids) /* SKTAN : do not know how to use std::string id */ std::string AuthGPG::SaveCertificateToString(const RsPgpId &id,bool include_signatures) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - return PGPHandler::SaveCertificateToString(id,include_signatures) ; + return instance()->mPgpHandler->SaveCertificateToString(id,include_signatures) ; } /* import to GnuPG and other Certificates */ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - if(PGPHandler::LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string)) + if(instance()->mPgpHandler->LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string)) { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; + instance()->mPgpHandler->updateOwnSignatureFlag(gpg_id,instance()->mOwnGpgId) ; return true ; } @@ -551,11 +580,11 @@ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_l /* import to GnuPG and other Certificates */ bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - if(PGPHandler::LoadCertificateFromString(str,gpg_id,error_string)) + if(instance()->mPgpHandler->LoadCertificateFromString(str,gpg_id,error_string)) { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; + instance()->mPgpHandler->updateOwnSignatureFlag(gpg_id,instance()->mOwnGpgId) ; return true ; } @@ -584,11 +613,11 @@ bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) /* Was a "Reload Certificates" here -> be shouldn't be needed -> and very expensive, try without. */ { - RsStackMutex stack(gpgMtxData); - PGPHandler::setAcceptConnexion(gpg_id,accept) ; + RsStackMutex stack(instance()->gpgMtxData); + instance()->mPgpHandler->setAcceptConnexion(gpg_id,accept) ; } - IndicateConfigChanged(); + instance()->IndicateConfigChanged(); RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, accept ? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); @@ -602,7 +631,7 @@ bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl; #endif - return privateSignCertificate(id) ; + return instance()->privateSignCertificate(id) ; } bool AuthGPG::RevokeCertificate(const RsPgpId &id) @@ -622,26 +651,39 @@ bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) #ifdef GPG_DEBUG std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl; #endif - return privateTrustCertificate(id, trustlvl) ; + return instance()->privateTrustCertificate(id, trustlvl) ; } bool AuthGPG::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { - return PGPHandler::encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; + return instance()->mPgpHandler->encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; } bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { - return PGPHandler::decryptDataBin(mOwnGpgId,data,datalen,sign,signlen) ; + return instance()->mPgpHandler->decryptDataBin(instance()->mOwnGpgId,data,datalen,sign,signlen) ; } bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) { - return DoOwnSignature(data, datalen, sign, signlen, reason); + return instance()->DoOwnSignature(data, datalen, sign, signlen, reason); } +bool AuthGPG::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) +{ + return instance()->mPgpHandler->exportPublicKey(id,mem_block,mem_size,armoured,include_signatures); +} + +bool AuthGPG::isPgpPubKeyAvailable(const RsPgpId& pgp_id) +{ + return instance()->mPgpHandler->isPgpPubKeyAvailable(pgp_id); +} +bool AuthGPG::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) +{ + return instance()->mPgpHandler->getKeyFingerprint(id,fp); +} bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) { - return VerifySignature(data, datalen, sign, signlen, withfingerprint); + return instance()->VerifySignature(data, datalen, sign, signlen, withfingerprint); } /* Sign/Trust stuff */ @@ -650,7 +692,7 @@ int AuthGPG::privateSignCertificate(const RsPgpId &id) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - int ret = PGPHandler::privateSignCertificate(mOwnGpgId,id) ; + int ret = mPgpHandler->privateSignCertificate(mOwnGpgId,id) ; _force_sync_database = true ; return ret ; } @@ -675,7 +717,7 @@ int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) if(!isGPGAccepted(id)) return 0; - int res = PGPHandler::privateTrustCertificate(id,trustlvl) ; + int res = instance()->mPgpHandler->privateTrustCertificate(id,trustlvl) ; _force_sync_database = true ; return res ; } @@ -690,6 +732,10 @@ RsSerialiser *AuthGPG::setupSerialiser() rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } +bool AuthGPG::isGPGAccepted(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGAccepted(id); +} bool AuthGPG::saveList(bool& cleanup, std::list& lst) { @@ -745,7 +791,7 @@ bool AuthGPG::loadList(std::list& load) std::list::iterator kit; for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) if (kit->key != mOwnGpgId.toStdString()) - PGPHandler::setAcceptConnexion(RsPgpId(kit->key), (kit->value == "TRUE")); + instance()->mPgpHandler->setAcceptConnexion(RsPgpId(kit->key), (kit->value == "TRUE")); } delete (*it); } @@ -755,14 +801,14 @@ bool AuthGPG::loadList(std::list& load) bool AuthGPG::addService(AuthGPGService *service) { - RsStackMutex stack(gpgMtxService); /********* LOCKED *********/ + RsStackMutex stack(instance()->gpgMtxService); /********* LOCKED *********/ - if (std::find(services.begin(), services.end(), service) != services.end()) { + if (std::find(instance()->services.begin(), instance()->services.end(), service) != instance()->services.end()) { /* it exists already! */ return false; } - services.push_back(service); + instance()->services.push_back(service); return true; } diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index a6023f436..177f71663 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -89,18 +89,19 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -// Note: replace OpenPGPSDKHandler with your own PGP handler class when needed. - -class AuthGPG: public p3Config, public RsTickingThread, public OpenPGPSDKHandler +class AuthGPG: public p3Config, public RsTickingThread { public: - static void init(const std::string& path_to_pubring, - const std::string& path_to_secring, - const std::string& path_to_trustdb, - const std::string& pgp_lock_file); + static void init(const std::string& path_to_pubring, + const std::string& path_to_secring, + const std::string& path_to_trustdb, + const std::string& pgp_lock_file); - static void exit(); - static AuthGPG *getAuthGPG() { return _instance ; } + static void registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr); + static void exit(); + + static bool isPGPId(const RsPgpId& id) ; + static bool isPGPAccepted(const RsPgpId& id) ; /** * @param ids list of gpg certificate ids (note, not the actual certificates) @@ -120,7 +121,7 @@ public: * (see storage at the end of the class) * ****/ - virtual bool active(); + static bool active(); // /* Initialize */ // virtual bool InitAuth (); @@ -128,10 +129,13 @@ public: /* Init by generating new Own PGP Cert, or selecting existing PGP Cert */ - virtual int GPGInit(const RsPgpId &ownId); - virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); + static int GPGInit(const RsPgpId &ownId); + static bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - /*********************************************************************************/ + static bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; + static int availableGPGCertificatesWithPrivateKeys(std::list& pgpIds); + + /*********************************************************************************/ /************************* STAGE 3 ***********************************************/ /*********************************************************************************/ /***** @@ -142,29 +146,35 @@ public: * provide access to details in cache list. * ****/ - virtual std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); - virtual std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); - /* PGP web of trust management */ - virtual const RsPgpId& getGPGOwnId(); - virtual std::string getGPGOwnName(); + static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); - //virtual std::string getGPGOwnEmail(); - virtual bool isKeySupported(const RsPgpId &id) const ; - virtual bool haveSecretKey(const RsPgpId &id) const ; - virtual bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); - virtual bool getGPGAllList(std::list &ids); - virtual bool getGPGValidList(std::list &ids); - virtual bool getGPGAcceptedList(std::list &ids); - virtual bool getGPGSignedList(std::list &ids); - virtual bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; - virtual bool exportIdentityToString( + /* PGP web of trust management */ + static const RsPgpId& getGPGOwnId(); + static std::string getGPGOwnName(); + + static bool isGPGAccepted(const RsPgpId& id); + + //virtual std::string getGPGOwnEmail(); + static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; + static bool isKeySupported(const RsPgpId &id) ; + static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); + static bool haveSecretKey(const RsPgpId &id) ; + static bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getGPGAllList(std::list &ids); + static bool getGPGValidList(std::list &ids); + static bool getGPGAcceptedList(std::list &ids); + static bool getGPGSignedList(std::list &ids); + static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; + static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; + static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; + static bool exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ); - virtual bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) ; + static bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) ; /*********************************************************************************/ /************************* STAGE 4 ***********************************************/ @@ -173,9 +183,9 @@ public: * STAGE 4: Loading and Saving Certificates. (Strings and Files) * ****/ - virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string); - virtual bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string); - virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ; + static bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string); + static bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string); + static std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ; // Cached certificates. //bool getCachedGPGCertificate(const RsPgpId &id, std::string &certificate); @@ -190,12 +200,12 @@ public: * done in gpgroot already. * ****/ - virtual bool AllowConnection(const RsPgpId &gpg_id, bool accept); + static bool AllowConnection(const RsPgpId &gpg_id, bool accept); - virtual bool SignCertificateLevel0(const RsPgpId &id); - virtual bool RevokeCertificate(const RsPgpId &id); /* Particularly hard - leave for later */ + static bool SignCertificateLevel0(const RsPgpId &id); + static bool RevokeCertificate(const RsPgpId &id); /* Particularly hard - leave for later */ - virtual bool TrustCertificate(const RsPgpId& id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust + static bool TrustCertificate(const RsPgpId& id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust /*********************************************************************************/ /************************* STAGE 7 ***********************************************/ @@ -206,25 +216,25 @@ public: * There should also be Encryption Functions... (do later). * ****/ - virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = ""); - virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint); - virtual bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id); + static bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = ""); + static bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint); + static bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id); - virtual bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen); - virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen); + static bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen); + static bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen); - virtual bool decryptTextFromFile( std::string& text,const std::string& filename); - virtual bool encryptTextToFile (const std::string& text,const std::string& filename); + static bool decryptTextFromFile( std::string& text,const std::string& filename); + static bool encryptTextToFile (const std::string& text,const std::string& filename); // virtual bool decryptTextFromString( std::string& encrypted_text,std::string& clear_string); // virtual bool encryptTextToString (const std::string& pgp_id,const std::string& clear_text,std::string& encrypted_string); - bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; + static bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; //END of PGP public functions /* GPG service */ - virtual bool addService(AuthGPGService *service) ; + static bool addService(AuthGPGService *service) ; // This is for debug purpose only. Don't use it !! static void setAuthGPG_debug(AuthGPG *auth_gpg) { _instance = auth_gpg ; } @@ -236,9 +246,9 @@ public: /*****************************************************************/ /*********************** p3config ******************************/ /* Key Functions to be overloaded for Full Configuration */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual bool loadList(std::list& load); + virtual RsSerialiser *setupSerialiser() override; + virtual bool saveList(bool &cleanup, std::list&) override; + virtual bool loadList(std::list& load) override; /*****************************************************************/ private: @@ -276,8 +286,7 @@ private: void threadTick() override; /// @see RsTickingThread private: - - static AuthGPG *instance_gpg; // pointeur vers le singleton + static AuthGPG *instance(); RsMutex gpgMtxService; RsMutex gpgMtxEngine; @@ -292,6 +301,8 @@ private: rstime_t mStoreKeyTime; + PGPHandler *mPgpHandler; + RsPgpId mOwnGpgId; bool gpgKeySelected; bool _force_sync_database ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index eb89a1ed5..6d14d0043 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,8 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, - (unsigned char *) AuthGPG::getAuthGPG()->getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthGPG::getGPGOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -770,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getAuthGPG()->getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getGPGOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -945,7 +944,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) std::cerr << "Buffers Allocated" << std::endl; /* NOW Sign via GPG Functions */ - if (!AuthGPG::getAuthGPG()->SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) + if (!AuthGPG::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) { sigoutl = 0; goto err; @@ -1040,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) + if (!AuthGPG::getGPGDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1185,9 +1184,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) // passed, verify the signature itself - if (!AuthGPG::getAuthGPG()->VerifySignBin( - signed_data, signed_data_length, signature->data, - static_cast(signature->length), pd.fpr )) + if (!AuthGPG::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) { diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE; goto err; @@ -1383,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <getGPGOwnId() && !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if ( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { std::string errMsg = "Connection attempt signed by PGP key id: " + pgpId.toStdString() + " not accepted because it is not" diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index 83c4d9366..15eaa08f8 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -812,11 +812,11 @@ int p3PeerMgrIMPL::getFriendCount(bool ssl, bool online) // count all gpg id's std::list gpgIds; - AuthGPG::getAuthGPG()->getGPGAcceptedList(gpgIds); + AuthGPG::getGPGAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthGPG::getAuthGPG()->getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthGPG::getGPGOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -962,7 +962,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg // check that the PGP key is known - if(!AuthGPG::getAuthGPG()->isGPGId(gpg_id)) + if(!AuthGPG::isPGPId(gpg_id)) { RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl; return false; @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthGPG::getAuthGPG()->isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getAuthGPG()->getGPGOwnId()) + if (!AuthGPG::isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getGPGOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id); + pstate.name = AuthGPG::getGPGName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -1126,8 +1126,8 @@ bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_ * superficially set to true the PGP signature verification would have been * skipped and the attacker connection would be accepted. * If the PGP key is available add it as full friend. */ - if(AuthGPG::getAuthGPG()->isPgpPubKeyAvailable(pgp_id)) - AuthGPG::getAuthGPG()->AllowConnection(pgp_id, true); + if(AuthGPG::isPgpPubKeyAvailable(pgp_id)) + AuthGPG::AllowConnection(pgp_id, true); else pstate.skip_pgp_signature_validation = true; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); + mOwnState.gpg_id = AuthGPG::getGPGOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId()) + if(AuthGPG::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthGPG::getAuthGPG()->isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getAuthGPG()->getGPGOwnId()) + if(AuthGPG::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 76d447cc8..b6f655692 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,8 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index fa25bfe0b..a9e392a56 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,8 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index c44877fc5..25caac374 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -254,7 +254,7 @@ bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint bool p3Peers::haveSecretKey(const RsPgpId& id) { - return AuthGPG::getAuthGPG()->haveSecretKey(id); + return AuthGPG::haveSecretKey(id); } /* There are too many dependancies of this function @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); + ps.gpg_id = AuthGPG::getGPGOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -559,17 +559,17 @@ bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) bool p3Peers::isKeySupported(const RsPgpId& id) { - return AuthGPG::getAuthGPG()->isKeySupported(id); + return AuthGPG::isKeySupported(id); } std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthGPG::getAuthGPG()->getGPGName(gpg_id); + return AuthGPG::getGPGName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthGPG::getAuthGPG()->isGPGAccepted(pgpId); } +{ return AuthGPG::isGPGAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthGPG::getAuthGPG()->getGPGOwnName(); + return AuthGPG::getGPGOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGAllList(ids); + AuthGPG::getGPGAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGValidList(ids); + AuthGPG::getGPGValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGSignedList(ids); + AuthGPG::getGPGSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthGPG::getAuthGPG()->getGPGAcceptedList(ids)) + if(AuthGPG::getGPGAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthGPG::getAuthGPG()->getGPGAcceptedList(ids); + AuthGPG::getGPGAcceptedList(ids); return true; } @@ -676,7 +676,7 @@ bool p3Peers::getAssociatedSSLIds(const RsPgpId &gpg_id, std::list &id bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason /* = "" */) { - return AuthGPG::getAuthGPG()->SignDataBin(data,len,sign,signlen, reason); + return AuthGPG::SignDataBin(data,len,sign,signlen, reason); } RsPgpId p3Peers::pgpIdFromFingerprint(const RsPgpFingerprint& fpr) @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthGPG::getAuthGPG()->getGPGDetails(pgp_id, d); + bool res = AuthGPG::getGPGDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -739,12 +739,12 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() with : id : " << id << "; gpg_id : " << gpg_id << std::endl; #endif - if(AuthGPG::getAuthGPG()->isGPGId(gpg_id)) + if(AuthGPG::isPGPId(gpg_id)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorising GPG Id: " << gpg_id << std::endl; #endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpg_id, true)) + if (AuthGPG::AllowConnection(gpg_id, true)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorization OK." << std::endl; @@ -797,7 +797,7 @@ bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,con bool p3Peers::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { - return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return AuthGPG::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } bool p3Peers::removeFriendLocation(const RsPeerId &sslId) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthGPG::getAuthGPG()->getGPGOwnId()) { + if (gpgId == AuthGPG::getGPGOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } @@ -825,7 +825,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() Removing GPG Id: " << gpgId << std::endl; #endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpgId, false)) + if (AuthGPG::AllowConnection(gpgId, false)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() OK." << std::endl; @@ -1107,9 +1107,7 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if( !AuthGPG::getAuthGPG()->exportPublicKey( - RsPgpId(pgp_id), mem_block, mem_block_size, - false, include_signatures ) ) + if( !AuthGPG::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) { RsErr() << __PRETTY_FUNCTION__ << " Failure retriving certificate for id " << pgp_id @@ -1140,8 +1138,7 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::getAuthGPG()->exportPublicKey( - gpg_id,mem_block,mem_block_size,false,false )) + if(!AuthGPG::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) return false; RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false); @@ -1601,7 +1598,7 @@ std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInvit unsigned char *mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::getAuthGPG()->exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) + if(!AuthGPG::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) { std::cerr << "Cannot output certificate for id \"" << detail.gpg_id << "\". Sorry." << std::endl; @@ -1637,7 +1634,7 @@ bool p3Peers::loadCertificateFromString( } RsPgpId gpgid; - bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); + bool res = AuthGPG::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); gpg_id = gpgid; ssl_id = crt->sslid(); @@ -1654,7 +1651,7 @@ bool p3Peers::loadCertificateFromString( } bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) { - bool res = AuthGPG::getAuthGPG()->LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); + bool res = AuthGPG::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); if(res) mPeerMgr->notifyPgpKeyReceived(gpg_id); @@ -1673,9 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( - cert.pgp_key(), cert.pgp_key_size(), - pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthGPG::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " @@ -1753,7 +1748,7 @@ bool p3Peers::signGPGCertificate(const RsPgpId &id, const std::string &gpg_pass rsNotify->cachePgpPassphrase(gpg_passphrase); rsNotify->setDisableAskPassword(true); - bool res = AuthGPG::getAuthGPG()->SignCertificateLevel0(id); + bool res = AuthGPG::SignCertificateLevel0(id); rsNotify->clearPgpPassphrase(); rsNotify->setDisableAskPassword(false); @@ -1767,7 +1762,7 @@ bool p3Peers::trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) std::cerr << "p3Peers::TrustCertificate() " << id; std::cerr << std::endl; #endif - return AuthGPG::getAuthGPG()->TrustCertificate(id, trustlvl); + return AuthGPG::TrustCertificate(id, trustlvl); } /* Group Stuff */ diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 6d3343dc7..7abb1e6da 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthGPG::getAuthGPG()->getGPGOwnName(); + status.ownName = AuthGPG::getGPGOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 8be56073c..2bf306449 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -701,10 +701,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, if(! RsAccounts::GetPGPLoginDetails(account.mPgpId, account.mPgpName, account.mPgpEmail)) return false ; - if(!AuthGPG::getAuthGPG()->haveSecretKey(account.mPgpId)) + if(!AuthGPG::haveSecretKey(account.mPgpId)) return false ; - if(!AuthGPG::getAuthGPG()->isKeySupported(account.mPgpId)) + if(!AuthGPG::isKeySupported(account.mPgpId)) { std::string keystring = account.mPgpId.toStdString() + " " + account.mPgpName + "<" + account.mPgpEmail ; unsupported_keys[keystring].push_back("Location: " + account.mLocation + "  (" + account.mSslId.toStdString() + ")") ; @@ -851,9 +851,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ -int RsAccountsDetail::GetPGPLogins(std::list &pgpIds) { - AuthGPG::getAuthGPG()->availableGPGCertificatesWithPrivateKeys(pgpIds); - return 1; +int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) +{ + AuthGPG::availableGPGCertificatesWithPrivateKeys(pgpIds); + return 1; } int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email) @@ -863,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthGPG::getAuthGPG()->getGPGName(id,&ok); + name = AuthGPG::getGPGName(id,&ok); if(!ok) return 0 ; - email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok); + email = AuthGPG::getGPGEmail(id,&ok); if(!ok) return 0 ; @@ -886,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthGPG::getAuthGPG() -> GPGInit(pgpId)) + if (0 < AuthGPG::GPGInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -906,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthGPG::getAuthGPG()->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthGPG::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. @@ -918,24 +919,24 @@ void RsAccountsDetail::getUnsupportedKeys(std::mapexportProfile(fname,id); + return AuthGPG::exportProfile(fname,id); } bool RsAccountsDetail::importIdentity(const std::string& fname,RsPgpId& id,std::string& import_error) { - return AuthGPG::getAuthGPG()->importProfile(fname,id,import_error); + return AuthGPG::importProfile(fname,id,import_error); } bool RsAccountsDetail::importIdentityFromString(const std::string &data, RsPgpId &imported_pgp_id, std::string &import_error) { - return AuthGPG::getAuthGPG()->importProfileFromString(data, imported_pgp_id, import_error); + return AuthGPG::importProfileFromString(data, imported_pgp_id, import_error); } bool RsAccountsDetail::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { - return AuthGPG::getAuthGPG()->exportIdentityToString( + return AuthGPG::exportIdentityToString( data, pgpId, includeSignatures, errorMsg ); } @@ -1020,7 +1021,7 @@ bool RsAccountsDetail::GenerateSSLCertificate(const RsPgpId& pgp_id, const s int nbits = 4096; - //std::string pgp_name = AuthGPG::getAuthGPG()->getGPGName(pgp_id); + //std::string pgp_name = AuthGPG::getGPGName(pgp_id); // Create the filename ..... // Temporary Directory for creating files.... diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..6b12152fc 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -510,7 +510,7 @@ RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates( if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location)) throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - if(0 == AuthGPG::getAuthGPG() -> GPGInit(pgpId)) + if(0 == AuthGPG::GPGInit(pgpId)) throw RsInit::ERR_UNKNOWN; // PGP Error. LoadCertificateStatus retVal = @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthGPG::getAuthGPG()->getGPGOwnId(), - AuthGPG::getAuthGPG()->getGPGOwnName(), + AuthGPG::getGPGOwnId(), + AuthGPG::getGPGOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); @@ -1604,7 +1604,8 @@ int RsServer::StartupRetroShare() //mConfigMgr->addConfiguration("ftserver.cfg", ftserver); // - mConfigMgr->addConfiguration("gpg_prefs.cfg" , AuthGPG::getAuthGPG()); + AuthGPG::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); + mConfigMgr->addConfiguration("gxsnettunnel.cfg", mGxsNetTunnel); mConfigMgr->addConfiguration("peers.cfg" , mPeerMgr); mConfigMgr->addConfiguration("general.cfg" , mGeneralConfig); @@ -1792,7 +1793,7 @@ int RsServer::StartupRetroShare() /* Add AuthGPG services */ /**************************************************************************/ - //AuthGPG::getAuthGPG()->addService(mDisc); + //AuthGPG::addService(mDisc); /**************************************************************************/ /* Force Any Last Configuration Options */ diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc index dbe023235..67b863931 100644 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ b/libretroshare/src/rsserver/rsloginhandler.cc @@ -60,8 +60,7 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile( return true ; } - bool ok = AuthGPG::getAuthGPG()->encryptTextToFile( - ssl_passwd, getSSLPasswdFileName(ssl_id)); + bool ok = AuthGPG::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); if (!ok) std::cerr << "Encrypting went wrong !" << std::endl; @@ -90,7 +89,7 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& #endif std::string plain; - if ( AuthGPG::getAuthGPG()->decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) + if ( AuthGPG::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) { sslPassword = plain; #ifdef DEBUG_RSLOGINHANDLER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d35d3afe0..bc6a83333 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1066,7 +1066,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); + ssdata.pgp.pgpId = AuthGPG::getGPGOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } @@ -3618,7 +3618,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup( unsigned int sign_size = MAX_SIGN_SIZE; memset(signarray,0,MAX_SIGN_SIZE) ; // just in case. - int result = AuthGPG::getAuthGPG()->SignDataBin( + int result = AuthGPG::SignDataBin( static_cast(hash.toByteArray()), hash.SIZE_IN_BYTES, signarray, &sign_size, __PRETTY_FUNCTION__ ) From 020ef61297f50c2f93a419713e3972e8ae5d2a9e Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Aug 2021 09:41:30 +0200 Subject: [PATCH 137/697] fixed compilation --- libretroshare/src/pgp/openpgpsdkhandler.cc | 2 -- libretroshare/src/pgp/openpgpsdkhandler.h | 2 +- libretroshare/src/pgp/pgphandler.h | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc index 87f3c3343..316b428af 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.cc +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -61,8 +61,6 @@ static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; //#define DEBUG_PGPHANDLER 1 //#define PGPHANDLER_DSA_SUPPORT -PassphraseCallback PGPHandler::_passphrase_callback = NULL ; - ops_keyring_t *OpenPGPSDKHandler::allocateOPSKeyring() { ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; diff --git a/libretroshare/src/pgp/openpgpsdkhandler.h b/libretroshare/src/pgp/openpgpsdkhandler.h index e6c06ba84..8aff1459b 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.h +++ b/libretroshare/src/pgp/openpgpsdkhandler.h @@ -51,7 +51,7 @@ public: // Implemented API from PGPHandler // //================================================================================================// - virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; + //virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) override; virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids) override; virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) override; diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 07b02325c..19323b142 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -91,7 +91,7 @@ public: // and given pack for proper display. // virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) =0; - virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; + //virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids)=0; virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) =0; From 5c560837ba20a20efac821d65bc3a7310c8833da Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Aug 2021 15:38:16 +0200 Subject: [PATCH 138/697] fixed unwanted display of DHT information in connect disalog for Tor nodes and Tor friends --- .../src/gui/connect/ConnectProgressDialog.cpp | 156 +++++++++++------- 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp b/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp index ce1c843c8..e405430e5 100755 --- a/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp +++ b/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp @@ -235,38 +235,42 @@ void ConnectProgressDialog::initDialog() void ConnectProgressDialog::updateStatus() { - if (time(NULL) > mInitTS + CONNECT_TIMEOUT_PERIOD) - { - sayConnectTimeout(); - mState = CONNECT_STATE_FAILED; - } + if (time(NULL) > mInitTS + CONNECT_TIMEOUT_PERIOD) + { + sayConnectTimeout(); + mState = CONNECT_STATE_FAILED; + } - switch(mState) - { - case CONNECT_STATE_PROGRESS: + switch(mState) + { + case CONNECT_STATE_PROGRESS: - updateNetworkStatus(); - updateContactStatus(); + updateNetworkStatus(); + updateContactStatus(); + + if(!mIsPeerHiddenNode && !mAmIHiddenNode) + { #ifdef RS_USE_BITDHT - updateDhtStatus(); + updateDhtStatus(); #endif - updateLookupStatus(); - updateUdpStatus(); + updateLookupStatus(); + updateUdpStatus(); + } - return; - break; + return; + break; - default: - case CONNECT_STATE_CLOSED: - case CONNECT_STATE_FAILED: - case CONNECT_STATE_DENIED: - case CONNECT_STATE_CONNECTED: - break; - } + default: + case CONNECT_STATE_CLOSED: + case CONNECT_STATE_FAILED: + case CONNECT_STATE_DENIED: + case CONNECT_STATE_CONNECTED: + break; + } - /* shutdown actions */ - ui->progressFrame->setEnabled(false); - mTimer->stop(); + /* shutdown actions */ + ui->progressFrame->setEnabled(false); + mTimer->stop(); } @@ -282,42 +286,70 @@ void ConnectProgressDialog::stopAndClose() void ConnectProgressDialog::updateNetworkStatus() { - RsNetState netState = rsConfig->getNetState(); + QLabel *label = ui->NetResult; - QLabel *label = ui->NetResult; - switch(netState) - { - case RsNetState::BAD_UNKNOWN: - label->setText(tr("Unknown State")); - break; - case RsNetState::BAD_OFFLINE: - label->setText(tr("Offline")); - break; - case RsNetState::BAD_NATSYM: - label->setText(tr("Behind Symmetric NAT")); - break; - case RsNetState::BAD_NODHT_NAT: - label->setText(tr("Behind NAT & No DHT")); - break; - case RsNetState::WARNING_RESTART: - label->setText(tr("NET Restart")); - break; - case RsNetState::WARNING_NATTED: - label->setText(tr("Behind NAT")); - break; - case RsNetState::WARNING_NODHT: - label->setText(tr("No DHT")); - break; - case RsNetState::GOOD: - label->setText(tr("NET STATE GOOD!")); - break; - case RsNetState::ADV_FORWARD: - label->setText(tr("UNVERIFIABLE FORWARD!")); - break; - case RsNetState::ADV_DARK_FORWARD: - label->setText(tr("UNVERIFIABLE FORWARD & NO DHT")); - break; - } + if(mAmIHiddenNode || mIsPeerHiddenNode) + switch(rsConfig->getNetState()) + { + case RsNetState::BAD_UNKNOWN: + label->setText(tr("Unknown State")); + break; + case RsNetState::BAD_OFFLINE: + label->setText(tr("Offline")); + break; + case RsNetState::BAD_NATSYM: + label->setText(tr("Behind Symmetric NAT")); + break; + case RsNetState::WARNING_RESTART: + label->setText(tr("NET Restart")); + break; + case RsNetState::BAD_NODHT_NAT: + case RsNetState::WARNING_NATTED: + label->setText(tr("Behind NAT")); + break; + case RsNetState::WARNING_NODHT: + case RsNetState::GOOD: + label->setText(tr("NET STATE GOOD!")); + break; + case RsNetState::ADV_DARK_FORWARD: + case RsNetState::ADV_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD!")); + break; + } + else + switch(rsConfig->getNetState()) + { + case RsNetState::BAD_UNKNOWN: + label->setText(tr("Unknown State")); + break; + case RsNetState::BAD_OFFLINE: + label->setText(tr("Offline")); + break; + case RsNetState::BAD_NATSYM: + label->setText(tr("Behind Symmetric NAT")); + break; + case RsNetState::BAD_NODHT_NAT: + label->setText(tr("Behind NAT & No DHT")); + break; + case RsNetState::WARNING_RESTART: + label->setText(tr("NET Restart")); + break; + case RsNetState::WARNING_NATTED: + label->setText(tr("Behind NAT")); + break; + case RsNetState::WARNING_NODHT: + label->setText(tr("No DHT")); + break; + case RsNetState::GOOD: + label->setText(tr("NET STATE GOOD!")); + break; + case RsNetState::ADV_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD!")); + break; + case RsNetState::ADV_DARK_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD & NO DHT")); + break; + } } void ConnectProgressDialog::updateContactStatus() @@ -454,13 +486,9 @@ void ConnectProgressDialog::updateLookupStatus() mState = CONNECT_STATE_FAILED; if (mLookupStatus == CONNECT_LOOKUP_NODHTCONFIG) - { sayPeerNoDhtConfig(); - } else - { sayPeerOffline(); - } } case CONNECT_LOOKUP_FAIL: From de3ad227bda8c6953773249310434da6665d1265 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Mon, 23 Aug 2021 01:16:36 +0200 Subject: [PATCH 139/697] Filter html img tags that points to local files --- retroshare-gui/src/util/HandleRichText.cpp | 24 ++++++++++++++++++++++ retroshare-gui/src/util/HandleRichText.h | 1 + 2 files changed, 25 insertions(+) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 409d37aa6..bba7c03af 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -334,6 +334,29 @@ void RsHtml::replaceAnchorWithImg(QDomDocument &doc, QDomElement &element, QText element.appendChild(img); } +void RsHtml::filterEmbeddedImages(QDomDocument &doc, QDomElement ¤tElement) +{ + QDomNodeList children = currentElement.childNodes(); + for(uint index = 0; index < (uint)children.length(); index++) { + QDomNode node = children.item(index); + if(node.isElement()) { + QDomElement element = node.toElement(); + if(element.tagName().toLower() == "img") { + if(element.hasAttribute("src")) { + QString src = element.attribute("src"); + // Do not allow things in the image source, except these: + // :/ internal resource needed for emotes + // data:image base64 embedded image needed for stickers + if(!src.startsWith(":/") && !src.startsWith("data:image", Qt::CaseInsensitive)) { + element.setAttribute("src", ":/images/imageblocked_24.png"); + } + } + } + filterEmbeddedImages(doc, element); + } + } +} + int RsHtml::indexInWithValidation(QRegExp &rx, const QString &text, EmbedInHtml &embedInfos, int pos) { int index = rx.indexIn(text, pos); @@ -636,6 +659,7 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo } QDomElement body = doc.documentElement(); + filterEmbeddedImages(doc, body); // This should be first, becuse it should not overwrite embedded custom smileys if (flag & RSHTML_FORMATTEXT_EMBED_SMILEYS) { embedHtml(textDocument, doc, body, defEmbedImg, flag); } diff --git a/retroshare-gui/src/util/HandleRichText.h b/retroshare-gui/src/util/HandleRichText.h index 8189e4ce1..9462ba865 100644 --- a/retroshare-gui/src/util/HandleRichText.h +++ b/retroshare-gui/src/util/HandleRichText.h @@ -82,6 +82,7 @@ public: protected: void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement ¤tElement, EmbedInHtml& embedInfos, ulong flag); void replaceAnchorWithImg(QDomDocument& doc, QDomElement &element, QTextDocument *textDocument, const RetroShareLink &link); + void filterEmbeddedImages(QDomDocument &doc, QDomElement ¤tElement); virtual bool canReplaceAnchor(QDomDocument &doc, QDomElement &element, const RetroShareLink &link); virtual void anchorTextForImg(QDomDocument &doc, QDomElement &element, const RetroShareLink &link, QString &text); From f5f608dbec8086ea553d4bd4135212c595e84a1b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 28 Aug 2021 21:39:12 +0200 Subject: [PATCH 140/697] trying to fix compilation on windows --- libretroshare/src/tor/TorManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 9983d8c1f..a4bb04e4f 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -30,9 +30,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include +#if defined(_WIN32) || defined(__MINGW32__) +#include +#else +#include +#endif + #include #include "TorManager.h" From 5e851b4efdbf6036c9b86fe3dd9631b876a8a522 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 28 Aug 2021 21:46:02 +0200 Subject: [PATCH 141/697] trying to fix compilation on windows --- libretroshare/src/tor/TorManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index a4bb04e4f..f825bbfc7 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -32,9 +32,10 @@ #include -#if defined(_WIN32) || defined(__MINGW32__) -#include -#else +// This works on linux only. I have no clue how to do that on windows. Anyway, this +// is only needed for an assert that should normaly never be triggered. + +#if !defined(_WIN32) && !defined(__MINGW32__) #include #endif @@ -706,7 +707,9 @@ void RsTor::setHiddenServiceDirectory(const std::string& dir) TorManager *RsTor::instance() { +#if !defined(_WIN32) && !defined(__MINGW32__) assert(getpid() == syscall(SYS_gettid));// make sure we're not in a thread +#endif static TorManager *rsTor = nullptr; From e22c5c9702668842a86f3b2be0a8dc74adf4740e Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 29 Aug 2021 21:15:52 +0200 Subject: [PATCH 142/697] added bool return value to denyLobbyInvite() and marked overriding methods in p3msgs accordingly --- libretroshare/src/chat/distributedchat.cc | 6 +- libretroshare/src/chat/distributedchat.h | 2 +- libretroshare/src/retroshare/rsmsgs.h | 5 +- libretroshare/src/rsserver/p3msgs.cc | 4 +- libretroshare/src/rsserver/p3msgs.h | 110 +++++++++++----------- 5 files changed, 65 insertions(+), 62 deletions(-) diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 4112afd31..cacd68e08 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -1513,7 +1513,7 @@ ChatLobbyVirtualPeerId DistributedChatService::makeVirtualPeerId(ChatLobbyId lob } -void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id) +bool DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id) { RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ @@ -1525,10 +1525,12 @@ void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id) if(it == _lobby_invites_queue.end()) { std::cerr << " (EE) lobby invite not in cache!!" << std::endl; - return ; + return false; } _lobby_invites_queue.erase(it) ; + + return true; } bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id) diff --git a/libretroshare/src/chat/distributedchat.h b/libretroshare/src/chat/distributedchat.h index 96369511d..e7b9ee33a 100644 --- a/libretroshare/src/chat/distributedchat.h +++ b/libretroshare/src/chat/distributedchat.h @@ -61,7 +61,7 @@ class DistributedChatService void getChatLobbyList(std::list& clids) ; bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& clinfo) ; bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) ; - void denyLobbyInvite(const ChatLobbyId& id) ; + bool denyLobbyInvite(const ChatLobbyId& id) ; void getPendingChatLobbyInvites(std::list& invites) ; void invitePeerToLobby(const ChatLobbyId&, const RsPeerId& peer_id,bool connexion_challenge = false) ; void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 614a99707..6264af47a 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -906,8 +906,9 @@ virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ; * @brief denyLobbyInvite deny a chat lobby invite * @jsonapi{development} * @param[in] id chat lobby id you were invited into - */ - virtual void denyLobbyInvite(const ChatLobbyId &id) = 0 ; + * @return true on success + */ + virtual bool denyLobbyInvite(const ChatLobbyId &id) = 0 ; /** * @brief getPendingChatLobbyInvites get a list of all pending chat lobby invites diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index b877c0282..a89e1ae04 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -530,9 +530,9 @@ bool p3Msgs::acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& gxs_id) { return mChatSrv->acceptLobbyInvite(id,gxs_id) ; } -void p3Msgs::denyLobbyInvite(const ChatLobbyId& id) +bool p3Msgs::denyLobbyInvite(const ChatLobbyId& id) { - mChatSrv->denyLobbyInvite(id) ; + return mChatSrv->denyLobbyInvite(id) ; } void p3Msgs::getPendingChatLobbyInvites(std::list& invites) { diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h index 91d044ee5..f30ebe5aa 100644 --- a/libretroshare/src/rsserver/p3msgs.h +++ b/libretroshare/src/rsserver/p3msgs.h @@ -64,66 +64,66 @@ public: /*! * @param msgList ref to list summarising client's msgs */ - virtual bool getMessageSummaries(std::list &msgList); - virtual bool getMessage(const std::string &mId, Rs::Msgs::MessageInfo &msg); - virtual void getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox); + virtual bool getMessageSummaries(std::list &msgList)override ; + virtual bool getMessage(const std::string &mId, Rs::Msgs::MessageInfo &msg)override ; + virtual void getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox)override ; RS_DEPRECATED_FOR(sendMail) - virtual bool MessageSend(Rs::Msgs::MessageInfo &info); - virtual bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag); - virtual bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId); - virtual bool MessageToTrash(const std::string &mid, bool bTrash); - virtual bool MessageDelete(const std::string &mid); - virtual bool MessageRead(const std::string &mid, bool unreadByUser); - virtual bool MessageReplied(const std::string &mid, bool replied); - virtual bool MessageForwarded(const std::string &mid, bool forwarded); - virtual bool MessageStar(const std::string &mid, bool star); - virtual bool MessageJunk(const std::string &mid, bool junk); - virtual bool MessageLoadEmbeddedImages(const std::string &mid, bool load); - virtual bool getMsgParentId(const std::string &msgId, std::string &msgParentId); + virtual bool MessageSend(Rs::Msgs::MessageInfo &info)override ; + virtual bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag)override ; + virtual bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId)override ; + virtual bool MessageToTrash(const std::string &mid, bool bTrash)override ; + virtual bool MessageDelete(const std::string &mid)override ; + virtual bool MessageRead(const std::string &mid, bool unreadByUser)override ; + virtual bool MessageReplied(const std::string &mid, bool replied)override ; + virtual bool MessageForwarded(const std::string &mid, bool forwarded)override ; + virtual bool MessageStar(const std::string &mid, bool star)override ; + virtual bool MessageJunk(const std::string &mid, bool junk)override ; + virtual bool MessageLoadEmbeddedImages(const std::string &mid, bool load)override ; + virtual bool getMsgParentId(const std::string &msgId, std::string &msgParentId)override ; - virtual bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags); - virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); - virtual bool removeMessageTagType(uint32_t tagId); + virtual bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags)override ; + virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color)override ; + virtual bool removeMessageTagType(uint32_t tagId)override ; - virtual bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); + virtual bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info)override ; /* set == false && tagId == 0 --> remove all */ - virtual bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); + virtual bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set)override ; - virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags); + virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags)override ; - virtual uint32_t getDistantMessagingPermissionFlags() ; - virtual void setDistantMessagingPermissionFlags(uint32_t flags) ; + virtual uint32_t getDistantMessagingPermissionFlags() override ; + virtual void setDistantMessagingPermissionFlags(uint32_t flags) override ; /*! * gets avatar from peer, image data in jpeg format */ - virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size); + virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size)override ; /*! * sets clients avatar, image data should be in jpeg format */ - virtual void setOwnAvatarData(const unsigned char *data,int size); + virtual void setOwnAvatarData(const unsigned char *data,int size)override ; /*! * retrieve clients avatar, image data in jpeg format */ - virtual void getOwnAvatarData(unsigned char *& data,int& size); + virtual void getOwnAvatarData(unsigned char *& data,int& size)override ; /*! * sets clients custom status (e.g. "i'm tired") */ - virtual void setCustomStateString(const std::string& status_string) ; + virtual void setCustomStateString(const std::string& status_string) override ; /*! * retrieves client's custom status */ - virtual std::string getCustomStateString() ; + virtual std::string getCustomStateString() override ; /*! * retrieves peer's custom status */ - virtual std::string getCustomStateString(const RsPeerId& peer_id) ; + virtual std::string getCustomStateString(const RsPeerId& peer_id) override ; /*! @@ -132,56 +132,56 @@ public: * @param msg the message * @see ChatId */ - virtual bool sendChat(ChatId destination, std::string msg) ; + virtual bool sendChat(ChatId destination, std::string msg) override ; /*! * Return the max message size for security forwarding */ - virtual uint32_t getMaxMessageSecuritySize(int type); + virtual uint32_t getMaxMessageSecuritySize(int type)override ; /*! * sends immediate status string to a specific peer, e.g. in a private chat * @param chat_id chat id to send status string to * @param status_string immediate status to send */ - virtual void sendStatusString(const ChatId& id, const std::string& status_string) ; + virtual void sendStatusString(const ChatId& id, const std::string& status_string) override ; /** * @brief clearChatLobby: Signal chat was cleared by GUI. * @param id: Chat id cleared. */ - virtual void clearChatLobby(const ChatId &id); + virtual void clearChatLobby(const ChatId &id)override ; /****************************************/ - virtual bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &own_id) ; - virtual void getListOfNearbyChatLobbies(std::vector& public_lobbies) ; - virtual void getChatLobbyList(std::list& cl_list) ; - virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) ; - virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ; - virtual bool acceptLobbyInvite(const ChatLobbyId& id, const RsGxsId &gxs_id) ; - virtual void denyLobbyInvite(const ChatLobbyId& id) ; - virtual void getPendingChatLobbyInvites(std::list& invites) ; - virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; - virtual void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id); - virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&) ; - virtual bool getIdentityForChatLobby(const ChatLobbyId&,RsGxsId& nick) ; - virtual bool setDefaultIdentityForChatLobby(const RsGxsId&) ; - virtual void getDefaultIdentityForChatLobby(RsGxsId& nick) ; - virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe); - virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id); - virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set& invited_friends,ChatLobbyFlags privacy_type) ; + virtual bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &own_id) override ; + virtual void getListOfNearbyChatLobbies(std::vector& public_lobbies) override ; + virtual void getChatLobbyList(std::list& cl_list) override ; + virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) override ; + virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) override ; + virtual bool acceptLobbyInvite(const ChatLobbyId& id, const RsGxsId &gxs_id) override ; + virtual bool denyLobbyInvite(const ChatLobbyId& id) override ; + virtual void getPendingChatLobbyInvites(std::list& invites) override ; + virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) override ; + virtual void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id)override ; + virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&) override ; + virtual bool getIdentityForChatLobby(const ChatLobbyId&,RsGxsId& nick) override ; + virtual bool setDefaultIdentityForChatLobby(const RsGxsId&) override ; + virtual void getDefaultIdentityForChatLobby(RsGxsId& nick) override ; + virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe)override ; + virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id)override ; + virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set& invited_friends,ChatLobbyFlags privacy_type) override ; virtual bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId &pid, uint32_t& error_code, - bool notify = true ); + bool notify = true )override ; - virtual bool getDistantChatStatus(const DistantChatPeerId& gxs_id,DistantChatPeerInfo& info); - virtual bool closeDistantChatConnexion(const DistantChatPeerId &pid) ; + virtual bool getDistantChatStatus(const DistantChatPeerId& gxs_id,DistantChatPeerInfo& info)override ; + virtual bool closeDistantChatConnexion(const DistantChatPeerId &pid) override ; - virtual uint32_t getDistantChatPermissionFlags() ; - virtual bool setDistantChatPermissionFlags(uint32_t flags) ; + virtual uint32_t getDistantChatPermissionFlags() override ; + virtual bool setDistantChatPermissionFlags(uint32_t flags) override ; private: From e384613809113b228e543c26cfb960f5c74e91df Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sat, 28 Aug 2021 21:39:57 +0200 Subject: [PATCH 143/697] Android: provide Dockerfile and use it for GitalbCI Add support for installing Android SDK NDK directly into prepare-toolchain-clang.sh Modernize prepare-toolchain-clang.sh Add support to install Qt based on installer 4.X to prepare-toolchain-clang.sh Setub GtlabCI to build android APK based on the produced Docker image --- .gitlab-ci.yml | 56 ++ README.asciidoc | 2 +- build_scripts/Android/Dockerfile | 118 +++ .../Android/prepare-toolchain-clang.sh | 785 +++++++++++++----- build_scripts/GitlabCI/Android.Dockerfile | 43 + 5 files changed, 775 insertions(+), 229 deletions(-) create mode 100644 build_scripts/Android/Dockerfile create mode 100644 build_scripts/GitlabCI/Android.Dockerfile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d620b3719..58dc03d1b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,3 +51,59 @@ build-and-test: docker exec retroshare curl --verbose http://127.0.0.1:9092/rsMsgs/getChatLobbyList | jq - docker container stop retroshare + +build-android-arm-apk: + script: + - > + if [ -n "$CI_MERGE_REQUEST_ID" ]; then + REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; + REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; + else + REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; + REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; + fi ; + export REPO_ARGS ; + echo REPO_ARGS=$REPO_ARGS ; + - mkdir Dockercontext + - > + docker build -t retroshare:android_arm_latest $REPO_ARGS + --build-arg ANDROID_PLATFORM_VER=16 + --build-arg ANDROID_NDK_ARCH=arm + --file $CI_PROJECT_DIR/build_scripts/GitlabCI/Android.Dockerfile + Dockercontext +# see https://stackoverflow.com/a/59055906 + - > + docker cp + $(docker create --rm retroshare:android_arm_latest):/retroshare-service-android-build/android-build/build/outputs/apk/debug/android-build-debug.apk + $CI_PROJECT_DIR/RetroShare_Android_Service-arm.apk + artifacts: + paths: + - RetroShare_Android_Service-arm.apk + +# Use separate runner to avoid no space left on device +build-android-arm64-apk: + script: + - > + if [ -n "$CI_MERGE_REQUEST_ID" ]; then + REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; + REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; + else + REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; + REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; + fi ; + export REPO_ARGS ; + echo REPO_ARGS=$REPO_ARGS ; + - mkdir Dockercontext + - > + docker build -t retroshare:android_arm64_latest $REPO_ARGS + --build-arg ANDROID_PLATFORM_VER=21 + --build-arg ANDROID_NDK_ARCH=arm64 + --file $CI_PROJECT_DIR/build_scripts/GitlabCI/Android.Dockerfile + Dockercontext + - > + docker cp + $(docker create --rm retroshare:android_arm64_latest):/retroshare-service-android-build/android-build/build/outputs/apk/debug/android-build-debug.apk + $CI_PROJECT_DIR/RetroShare_Android_Service-arm64.apk + artifacts: + paths: + - RetroShare_Android_Service-arm64.apk diff --git a/README.asciidoc b/README.asciidoc index 734c3d083..182b46e7f 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -9,7 +9,7 @@ RetroShare provides file sharing, chat, messages, forums, channels and more. .Build Status |=============================================================================== -|GNU/Linux (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"] +|GNU/Linux, Android (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"] |GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.org/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.org/RetroShare/RetroShare"] |Windows (via AppVeyor) | image:https://ci.appveyor.com/api/projects/status/github/RetroShare/RetroShare?svg=true[link="https://ci.appveyor.com/project/RetroShare58622/retroshare"] |=============================================================================== diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile new file mode 100644 index 000000000..a8972d24a --- /dev/null +++ b/build_scripts/Android/Dockerfile @@ -0,0 +1,118 @@ +## To prepare an image suitable as base for Gitlab CI use +## image name must match gitlab repository name, you can play just with the tag +## the part after : +# export CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_arm_base" +# docker build --squash -t "${CI_REGISTRY_IMAGE}" \ +# --build-arg QT_INSTALLER_JWT_TOKEN="your qt JWT token goes here" . +# +# To build Android ARMv8 (64 bit) package pass also +# export CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_arm64_base" +# --build-arg ANDROID_NDK_ARCH=arm64 --build-arg ANDROID_PLATFORM_VER=21 + +## --squash is very important in case of GitlabCI shared runners as they are +## limited to 25GB disk size + +## To push it to gitlab CI registry you need first to login and the to push +# docker login registry.gitlab.com +# docker push ${CI_IMAGE_NAME} + + +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get clean +RUN apt-get install -y -qq \ + bash build-essential bzip2 cmake curl chrpath doxygen \ + git p7zip python qt5-default qttools5-dev tclsh unzip wget zip + +# Dependencies to create Android pkg +RUN apt-get install -y -qq \ + openjdk-8-jre openjdk-8-jdk openjdk-8-jdk-headless gradle + +ARG FRESHCLONE=0 +ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git +ARG REPO_BRANCH=master +ARG REPO_DEPTH="--depth 2000" + +RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \ + git fetch --tags + +ENV PREPARE_TOOLCHAIN="/RetroShare/build_scripts/Android/prepare-toolchain-clang.sh" +ENV NATIVE_LIBS_TOOLCHAIN_PATH="/android-toolchain/" + +ARG ANDROID_PLATFORM_VER=16 +ARG ANDROID_NDK_ARCH=arm + +ENV ANDROID_SDK_PATH="/opt/android-sdk" +ENV ANDROID_HOME="$ANDROID_SDK_PATH" +ENV ANDROID_SDK_ROOT="$ANDROID_SDK_PATH" + +ENV ANDROID_NDK_PATH="/opt/android-ndk" +ENV ANDROID_NDK_ROOT="$ANDROID_NDK_PATH" + +ENV PATH="$PATH:$ANDROID_HOME/tools" +ENV PATH="$PATH:$ANDROID_HOME/platform-tools" +ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/" + +RUN mkdir /bCache +WORKDIR /bCache + +## Quick HACK to ease development +#COPY prepare-toolchain-clang.sh $PREPARE_TOOLCHAIN + +RUN $PREPARE_TOOLCHAIN install_android_sdk +RUN $PREPARE_TOOLCHAIN install_android_ndk +RUN $PREPARE_TOOLCHAIN bootstrap_toolchain +RUN $PREPARE_TOOLCHAIN build_bzlib +RUN $PREPARE_TOOLCHAIN build_openssl +RUN $PREPARE_TOOLCHAIN build_sqlite +RUN $PREPARE_TOOLCHAIN build_sqlcipher +RUN $PREPARE_TOOLCHAIN build_rapidjson +RUN $PREPARE_TOOLCHAIN build_restbed +RUN $PREPARE_TOOLCHAIN build_udp-discovery-cpp +RUN $PREPARE_TOOLCHAIN build_xapian +RUN $PREPARE_TOOLCHAIN build_miniupnpc +RUN $PREPARE_TOOLCHAIN deduplicate_includes + +ARG QT_INSTALLER_JWT_TOKEN +RUN $PREPARE_TOOLCHAIN install_qt_android +# Avoid Qt account details leak into the image +RUN rm -f /root/.local/share/Qt/qtaccount.ini +# Shrink image by removing unneded Qt components +RUN rm -r \ + $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Docs/ \ + $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Examples/ \ + $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Tools/ + +RUN mkdir /jsonapi-generator-build +WORKDIR /jsonapi-generator-build/ +RUN qmake ../RetroShare/jsonapi-generator/src/ \ + CONFIG+=no_retroshare_plugins \ + CONFIG+=no_retroshare_service CONFIG+=no_retroshare_gui \ + CONFIG+=rs_jsonapi && \ + make -j$(nproc) + +#CONFIG+=no_keywords +RUN mkdir /retroshare-service-android-build +WORKDIR /retroshare-service-android-build +RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \ + -spec android-clang \ + CONFIG+=retroshare_service CONFIG+=rs_jsonapi \ + RS_UPNP_LIB=miniupnpc \ + JSONAPI_GENERATOR_EXE=/jsonapi-generator-build/jsonapi-generator \ + NATIVE_LIBS_TOOLCHAIN_PATH=$NATIVE_LIBS_TOOLCHAIN_PATH \ + CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password \ + CONFIG+=no_rs_service_terminal_login +RUN make -j$(nproc) +RUN make install INSTALL_ROOT=/retroshare-service-android-build/android-build/ +RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/androiddeployqt \ + --input retroshare-service/src/android-libretroshare-service.so-deployment-settings.json \ + --output android-build --android-platform android-$ANDROID_PLATFORM_VER \ + --jdk $JAVA_HOME --gradle + + +RUN rm -rf /bCache + +# Clean apt cache +RUN apt-get clean && rm -rf /var/lib/apt/lists/* diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 83c30721b..daa556b79 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -2,7 +2,8 @@ # Script to prepare RetroShare Android package building toolchain # -# Copyright (C) 2016-2020 Gioacchino Mazzurco +# Copyright (C) 2016-2021 Gioacchino Mazzurco +# Copyright (C) 2020-2021 Asociación Civil Altermundi # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the @@ -38,6 +39,15 @@ define_default_value ANDROID_PLATFORM_VER "16" define_default_value NATIVE_LIBS_TOOLCHAIN_PATH "${HOME}/Builds/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}/" define_default_value HOST_NUM_CPU $(nproc) +define_default_value ANDROID_SDK_INSTALL "false" +define_default_value ANDROID_SDK_TOOLS_VERSION "3859397" +define_default_value ANDROID_SDK_TOOLS_SHA256 444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0 +define_default_value ANDROID_SDK_VERSION "29.0.3" + +define_default_value ANDROID_NDK_INSTALL "false" +define_default_value ANDROID_NDK_VERSION "r21" +define_default_value ANDROID_NDK_SHA256 b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b + define_default_value BZIP2_SOURCE_VERSION "1.0.6" define_default_value BZIP2_SOURCE_SHA256 a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd @@ -48,16 +58,22 @@ define_default_value SQLITE_SOURCE_YEAR "2018" define_default_value SQLITE_SOURCE_VERSION "3250200" define_default_value SQLITE_SOURCE_SHA256 da9a1484423d524d3ac793af518cdf870c8255d209e369bd6a193e9f9d0e3181 -define_default_value SQLCIPHER_SOURCE_VERSION "4.2.0" -define_default_value SQLCIPHER_SOURCE_SHA256 105c1b813f848da038c03647a8bfc9d42fb46865e6aaf4edfd46ff3b18cdccfc +define_default_value SQLCIPHER_SOURCE_VERSION "4.4.3" +define_default_value SQLCIPHER_SOURCE_SHA256 b8df69b998c042ce7f8a99f07cf11f45dfebe51110ef92de95f1728358853133 define_default_value LIBUPNP_SOURCE_VERSION "1.8.4" define_default_value LIBUPNP_SOURCE_SHA256 976c3e4555604cdd8391ed2f359c08c9dead3b6bf131c24ce78e64d6669af2ed -define_default_value INSTALL_QT_ANDROID "false" -define_default_value QT_VERSION "5.12.0" +define_default_value QT_ANDROID_VIA_INSTALLER "false" +define_default_value QT_VERSION "5.12.11" +define_default_value QT_INSTALLER_VERSION "4.1.1" +define_default_value QT_INSTALLER_SHA256 1266ffd0d1b0e466244e3bc8422975c1aa9d96745b6bb28d422f7f92df11f34c +define_default_value QT_INSTALLER_JWT_TOKEN "Need a QT account JWT token to use the insaller see https://wiki.qt.io/Online_Installer_4.x" +define_default_value QT_INSTALL_PATH "${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt/" + define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763 +define_default_value RESTBED_SOURCE_REPO "https://github.com/Corvusoft/restbed.git" define_default_value RESTBED_SOURCE_VERSION f74f9329dac82e662c1d570b7cd72c192b729eb4 define_default_value UDP_DISCOVERY_CPP_SOURCE "https://github.com/truvorskameikin/udp-discovery-cpp.git" @@ -72,6 +88,64 @@ define_default_value RAPIDJSON_SOURCE_SHA256 bf7ced29704a1e696fbccf2a2b4ea068e77 define_default_value MINIUPNPC_SOURCE_VERSION "2.1.20190625" define_default_value MINIUPNPC_SOURCE_SHA256 8723f5d7fd7970de23635547700878cd29a5c2bb708b5e5475b2d1d2510317fb +# zlib and libpng versions walks toghether +define_default_value ZLIB_SOURCE_VERSION "1.2.11" +define_default_value ZLIB_SOURCE_SHA256 4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066 + +define_default_value LIBPNG_SOURCE_VERSION "1.6.37" +define_default_value LIBPNG_SOURCE_SHA256 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca + +define_default_value LIBJPEG_SOURCE_VERSION "9d" +define_default_value LIBJPEG_SOURCE_SHA256 6c434a3be59f8f62425b2e3c077e785c9ce30ee5874ea1c270e843f273ba71ee + +define_default_value TIFF_SOURCE_VERSION "4.2.0" +define_default_value TIFF_SOURCE_SHA256 eb0484e568ead8fa23b513e9b0041df7e327f4ee2d22db5a533929dfc19633cb + +define_default_value CIMG_SOURCE_VERSION "2.9.7" +define_default_value CIMG_SOURCE_SHA256 595dda9718431a123b418fa0db88e248c44590d47d9b1646970fa0503e27fa5c + +define_default_value PHASH_SOURCE_REPO "https://gitlab.com/g10h4ck/pHash.git" +define_default_value PHASH_SOURCE_VERSION origin/android-ndk + +define_default_value MVPTREE_SOURCE_REPO "https://github.com/starkdg/mvptree.git" +define_default_value MVPTREE_SOURCE_VERSION origin/master + +define_default_value REPORT_DIR "$(pwd)/$(basename ${NATIVE_LIBS_TOOLCHAIN_PATH})_build_report/" + +cArch="" +eABI="" +cmakeABI="" + +case "${ANDROID_NDK_ARCH}" in +"arm") + cArch="${ANDROID_NDK_ARCH}" + eABI="eabi" + ;; +"arm64") + cArch="aarch64" + eABI="" + ;; +"x86") + cArch="i686" + eABI="" + ;; +"x86_64") + echo "ANDROID_NDK_ARCH=${ANDROID_NDK_ARCH} not supported yet" + exit -1 + cArch="??" + eABI="" +esac + +export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/" +export PREFIX="${SYSROOT}/usr/" +export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang" +export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++" +export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar" +export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib" + +# Used to instruct cmake to explicitely ignore host libraries +export HOST_IGNORE_PREFIX="/usr/" + ## $1 filename, $2 sha256 hash function check_sha256() @@ -104,159 +178,262 @@ function verified_download() } } -cArch="" -eABI="" +# This function is the result of reading and testing many many stuff be very +# careful editing it +function andro_cmake() +{ +# Using android.toolchain.cmake as documented here +# https://developer.android.com/ndk/guides/cmake seens to break more things then +# it fixes :-\ -case "${ANDROID_NDK_ARCH}" in -"arm") - cArch="${ANDROID_NDK_ARCH}" - eABI="eabi" + cmakeProc="" + case "${ANDROID_NDK_ARCH}" in + "arm") + cmakeProc="armv7-a" ;; -"arm64") - cArch="aarch64" - eABI="" + "arm64") + cmakeProc="aarch64" ;; -"x86") - cArch="i686" - eABI="" + "x86") + cmakeProc="i686" ;; -esac + "x86_64") + cmakeProc="x86_64" + ;; + *) + echo "Unhandled NDK architecture ${ANDROID_NDK_ARCH}" + exit -1 + ;; + esac -export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/" -export PREFIX="${SYSROOT}/usr/" -export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang" -export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++" -export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar" -export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib" + _hi="$HOST_IGNORE_PREFIX" + cmake \ + -DCMAKE_SYSTEM_PROCESSOR=$cmakeProc \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_PREFIX_PATH="${PREFIX}" \ + -DCMAKE_SYSTEM_PREFIX_PATH="${PREFIX}" \ + -DCMAKE_INCLUDE_PATH="${PREFIX}/include" \ + -DCMAKE_SYSTEM_INCLUDE_PATH="${PREFIX}/include" \ + -DCMAKE_LIBRARY_PATH="${PREFIX}/lib" \ + -DCMAKE_SYSTEM_LIBRARY_PATH="${PREFIX}/lib" \ + -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ + -DCMAKE_IGNORE_PATH="$_hi/include;$_hi/lib;$_hi/lib64" \ + $@ + + # It is probably ok to do not touch CMAKE_PROGRAM_PATH and + # CMAKE_SYSTEM_PROGRAM_PATH +} + +function git_source_get() +{ + sourceDir="$1" ; shift #$1 + sourceRepo="$1" ; shift #$2 + sourceVersion="$1" ; shift #$3 + # extra paramethers are treated as submodules + + [ -d "$sourceDir" ] && + { + pushd "$sourceDir" + actUrl="$(git remote get-url origin)" + [ "$actUrl" != "$sourceRepo" ] && rm -rf "${sourceDir}" + popd + } || true + + [ -d $sourceDir ] || git clone "$sourceRepo" "$sourceDir" + pushd $sourceDir + + git fetch --all + git reset --hard ${sourceVersion} + + while [ "$1" != "" ] ; do + git submodule update --init "$1" + pushd "$1" + git reset --hard + shift + popd + done + + popd +} + +declare -A TASK_REGISTER + +function task_register() +{ + TASK_REGISTER[$1]=true +} + +function task_unregister() +{ + # we may simply wipe them but we could benefit from keeping track of + # unregistered tasks too + TASK_REGISTER[$1]=false +} + +function task_logfile() +{ + echo "$REPORT_DIR/$1.log" +} + +function task_run() +{ + mTask="$1" ; shift + + [ "${TASK_REGISTER[$mTask]}" != "true" ] && + { + echo "Attempt to run not registered task $mTask $@" + return -1 + } + + logFile="$(task_logfile $mTask)" + if [ -f "$logFile" ] ; then + echo "Task $mTask already run more details at $logFile" + else + date | tee > "$logFile" + $mTask $@ |& tee --append "$logFile" + mRetval="${PIPESTATUS[0]}" + echo "Task $mTask return ${mRetval} more details at $logFile" + date | tee --append "$logFile" + return ${mRetval} + fi +} + +function task_zap() +{ + rm -f "$(task_logfile $1)" +} + +DUPLICATED_INCLUDES_LIST_FILE="${REPORT_DIR}/duplicated_includes_list" +DUPLICATED_INCLUDES_DIR="${REPORT_DIR}/duplicated_includes/" + +task_register install_android_sdk +install_android_sdk() +{ + tFile="sdk-tools-linux-${ANDROID_SDK_TOOLS_VERSION}.zip" + + verified_download "${tFile}" "${ANDROID_SDK_TOOLS_SHA256}" \ + "https://dl.google.com/android/repository/${tFile}" + + unzip "${tFile}" + mkdir -p "$ANDROID_SDK_PATH" + rm -rf "$ANDROID_SDK_PATH/tools/" + mv --verbose tools/ "$ANDROID_SDK_PATH/tools/" + + # Install Android SDK + yes | $ANDROID_SDK_PATH/tools/bin/sdkmanager --licenses && \ + $ANDROID_SDK_PATH/tools/bin/sdkmanager --update + $ANDROID_SDK_PATH/tools/bin/sdkmanager "platforms;android-$ANDROID_PLATFORM_VER" + $ANDROID_SDK_PATH/tools/bin/sdkmanager "build-tools;$ANDROID_SDK_VERSION" +} + +task_register install_android_ndk +install_android_ndk() +{ + tFile="android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip" + + verified_download "${tFile}" "${ANDROID_NDK_SHA256}" \ + "https://dl.google.com/android/repository/${tFile}" + + unzip "${tFile}" + mkdir -p "$ANDROID_NDK_PATH" + rm -rf "$ANDROID_NDK_PATH" + mv --verbose "android-ndk-${ANDROID_NDK_VERSION}/" "$ANDROID_NDK_PATH/" +} ## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html -build_toolchain() +task_register bootstrap_toolchain +bootstrap_toolchain() { - echo "build_toolchain() -################################################################################ -################################################################################ -################################################################################ -" - - rm -rf ${NATIVE_LIBS_TOOLCHAIN_PATH} + rm -rf "${NATIVE_LIBS_TOOLCHAIN_PATH}" ${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \ --arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \ --api ${ANDROID_PLATFORM_VER} - find "${PREFIX}/include/" -not -type d > "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" + + # Avoid problems with arm64 some libraries installing on lib64 + ln -s "${PREFIX}/lib/" "${PREFIX}/lib64" + + pushd "${PREFIX}/include/" + find . -not -type d > "${DUPLICATED_INCLUDES_LIST_FILE}" + popd } ## This avoid include errors due to -isystem and -I ordering issue -delete_copied_includes() +task_register deduplicate_includes +deduplicate_includes() { - echo "delete_copied_includes() -################################################################################ -################################################################################ -################################################################################ -" - cat "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" | while read delFile ; do - rm "$delFile" - done + while read delFile ; do + mNewPath="${DUPLICATED_INCLUDES_DIR}/$delFile" + mkdir --verbose --parents "$(dirname "$mNewPath")" + mv --verbose "${PREFIX}/include/$delFile" "$mNewPath" + done < "${DUPLICATED_INCLUDES_LIST_FILE}" } -## More information available at https://gitlab.com/relan/provisioners/merge_requests/1 and http://stackoverflow.com/a/34032216 +task_register reduplicate_includes +reduplicate_includes() +{ + pushd "${DUPLICATED_INCLUDES_DIR}" + find . -not -type d | while read delFile ; do + mv --verbose "${delFile}" "${PREFIX}/include/$delFile" + done + popd +} + +# $1 optional prefix prepended only if return value is not empty +# $2 optional suffix appended only if return value is not empty +task_register get_qt_arch +get_qt_arch() +{ + local QT_VERSION_COMP="$(echo $QT_VERSION | awk -F. '{print $1*1000000+$2*1000+$3}')" + local QT_ARCH="" + + # Qt >= 5.15.0 ships all Android architectures toghether + [ "$QT_VERSION_COMP" -lt "5015000" ] && + { + case "${ANDROID_NDK_ARCH}" in + "arm") + QT_ARCH="armv7" + ;; + "arm64") + QT_ARCH="arm64_v8a" + ;; + "x86") + QT_ARCH="x86" + ;; + esac + + echo "$1$QT_ARCH$2" + } +} + +task_register get_qt_dir +get_qt_dir() +{ + echo "${QT_INSTALL_PATH}/${QT_VERSION}/android$(get_qt_arch _)/" +} + +## More information available at https://wiki.qt.io/Online_Installer_4.x +task_register install_qt_android install_qt_android() { - echo "install_qt_android() -################################################################################ -################################################################################ -################################################################################ -" - - QT_VERSION_CODE=$(echo $QT_VERSION | tr -d .) - QT_INSTALL_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt - QT_INSTALLER="qt-unified-linux-x64-3.0.2-online.run" - - verified_download $QT_INSTALLER $QT_ANDROID_INSTALLER_SHA256 \ - http://master.qt.io/archive/online_installers/3.0/${QT_INSTALLER} + QT_VERSION_CODE="$(echo $QT_VERSION | tr -d .)" + QT_INSTALLER="qt-unified-linux-x86_64-${QT_INSTALLER_VERSION}-online.run" + tMajDotMinVer="$(echo $QT_INSTALLER_VERSION | awk -F. '{print $1"."$2}')" + verified_download $QT_INSTALLER $QT_INSTALLER_SHA256 \ + "https://master.qt.io/archive/online_installers/${tMajDotMinVer}/${QT_INSTALLER}" chmod a+x ${QT_INSTALLER} - - QT_INSTALLER_SCRIPT="qt_installer_script.js" - cat << EOF > "${QT_INSTALLER_SCRIPT}" -function Controller() { - installer.autoRejectMessageBoxes(); - installer.installationFinished.connect(function() { - gui.clickButton(buttons.NextButton); - }); - - var welcomePage = gui.pageWidgetByObjectName("WelcomePage"); - welcomePage.completeChanged.connect(function() { - if (gui.currentPageWidget().objectName == welcomePage.objectName) - gui.clickButton(buttons.NextButton); - }); -} - -Controller.prototype.WelcomePageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.CredentialsPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.IntroductionPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.TargetDirectoryPageCallback = function() { - gui.currentPageWidget().TargetDirectoryLineEdit.setText("$QT_INSTALL_PATH"); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ComponentSelectionPageCallback = function() { - var widget = gui.currentPageWidget(); - - // You can get these component names by running the installer with the - // --verbose flag. It will then print out a resource tree. - - widget.deselectComponent("qt.tools.qtcreator"); - widget.deselectComponent("qt.tools.doc"); - widget.deselectComponent("qt.tools.examples"); - - widget.selectComponent("qt.$QT_VERSION_CODE.android_armv7"); - - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.LicenseAgreementPageCallback = function() { - gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.StartMenuDirectoryPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ReadyForInstallationPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.FinishedPageCallback = function() { - var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; - if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) - checkBoxForm.launchQtCreatorCheckBox.checked = false; - gui.clickButton(buttons.FinishButton); -} -EOF - -QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} --script ${QT_INSTALLER_SCRIPT} + QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} \ + install qt.qt5.${QT_VERSION_CODE}.android$(get_qt_arch _) \ + --accept-licenses --accept-obligations --confirm-command \ + --default-answer --no-default-installations \ + --root "${QT_INSTALL_PATH}" } ## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136 +task_register build_bzlib build_bzlib() { - echo "build_bzlib() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="bzip2-${BZIP2_SOURCE_VERSION}" rm -rf $B_dir @@ -279,14 +456,9 @@ build_bzlib() } ## More information available at http://doc.qt.io/qt-5/opensslsupport.html +task_register build_openssl build_openssl() { - echo "build_openssl() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="openssl-${OPENSSL_SOURCE_VERSION}" rm -rf $B_dir @@ -308,6 +480,10 @@ build_openssl() --openssldir="${SYSROOT}/etc/ssl" # sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile # sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile + + # Avoid documentation build which is unneded and time consuming + echo "exit 0; " > util/process_docs.pl + make -j${HOST_NUM_CPU} make install rm -f ${PREFIX}/lib/libssl.so* @@ -315,14 +491,9 @@ build_openssl() cd .. } +task_register build_sqlite build_sqlite() { - echo "build_sqlite() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="sqlite-autoconf-${SQLITE_SOURCE_VERSION}" rm -rf $B_dir @@ -335,18 +506,13 @@ build_sqlite() make -j${HOST_NUM_CPU} make install rm -f ${PREFIX}/lib/libsqlite3.so* -# ${CC} -shared -o libsqlite3.so -fPIC sqlite3.o -ldl -# cp libsqlite3.so "${SYSROOT}/usr/lib" cd .. } +task_register build_sqlcipher build_sqlcipher() { - echo "build_sqlcipher() -################################################################################ -################################################################################ -################################################################################ -" + task_run build_sqlite B_dir="sqlcipher-${SQLCIPHER_SOURCE_VERSION}" rm -rf $B_dir @@ -358,14 +524,14 @@ build_sqlcipher() tar -xf $T_file cd $B_dir - case "${ANDROID_NDK_ARCH}" in - "arm64") - # SQLCipher config.sub is outdated and doesn't recognize newer architectures - rm config.sub - autoreconf --verbose --install --force - automake --add-missing --copy --force-missing - ;; - esac +# case "${ANDROID_NDK_ARCH}" in +# "arm64") +# # SQLCipher config.sub is outdated and doesn't recognize newer architectures +# rm config.sub +# autoreconf --verbose --install --force +# automake --add-missing --copy --force-missing +# ;; +# esac ./configure --with-pic --build=$(sh ./config.guess) \ --host=${cArch}-linux \ --prefix="${PREFIX}" --with-sysroot="${SYSROOT}" \ @@ -377,14 +543,9 @@ build_sqlcipher() cd .. } +task_register build_libupnp build_libupnp() { - echo "build_libupnp() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="pupnp-release-${LIBUPNP_SOURCE_VERSION}" B_ext=".tar.gz" B_file="${B_dir}${B_ext}" @@ -408,14 +569,9 @@ build_libupnp() cd .. } +task_register build_rapidjson build_rapidjson() { - echo "build_rapidjson() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="rapidjson-${RAPIDJSON_SOURCE_VERSION}" D_file="${B_dir}.tar.gz" verified_download $D_file $RAPIDJSON_SOURCE_SHA256 \ @@ -424,42 +580,25 @@ build_rapidjson() cp -r "${B_dir}/include/rapidjson/" "${PREFIX}/include/rapidjson" } +task_register build_restbed build_restbed() { - echo "build_restbed() -################################################################################ -################################################################################ -################################################################################ -" + S_dir="restbed" + B_dir="${S_dir}-build" + git_source_get "$S_dir" "$RESTBED_SOURCE_REPO" "${RESTBED_SOURCE_VERSION}" \ + "dependency/asio" "dependency/catch" - [ -d restbed ] || git clone --depth=2000 https://github.com/Corvusoft/restbed.git - cd restbed -# git fetch --tags -# git checkout tags/${RESTBED_SOURCE_VERSION} - git checkout ${RESTBED_SOURCE_VERSION} - git submodule update --init dependency/asio - git submodule update --init dependency/catch - git submodule update --init dependency/kashmir - cd .. - - rm -rf restbed-build; mkdir restbed-build ; cd restbed-build - cmake \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON BUILD_TESTS=OFF \ - -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../restbed + rm -rf "$B_dir"; mkdir "$B_dir" + pushd "$B_dir" + andro_cmake -DBUILD_TESTS=OFF -DBUILD_SSL=OFF -B. -H../${S_dir} make -j${HOST_NUM_CPU} make install - cp "${PREFIX}/library/librestbed.a" "${PREFIX}/lib/" - cd .. + popd } +task_register build_udp-discovery-cpp build_udp-discovery-cpp() { - echo "build_udp-discovery-cpp() -################################################################################ -################################################################################ -################################################################################ -" - S_dir="udp-discovery-cpp" [ -d $S_dir ] || git clone $UDP_DISCOVERY_CPP_SOURCE $S_dir cd $S_dir @@ -468,23 +607,16 @@ build_udp-discovery-cpp() B_dir="udp-discovery-cpp-build" rm -rf ${B_dir}; mkdir ${B_dir}; cd ${B_dir} - cmake \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../udp-discovery-cpp + andro_cmake -B. -H../$S_dir make -j${HOST_NUM_CPU} cp libudp-discovery.a "${PREFIX}/lib/" cp ../$S_dir/*.hpp "${PREFIX}/include/" cd .. } +task_register build_xapian build_xapian() { - echo "build_xapian() -################################################################################ -################################################################################ -################################################################################ -" - B_dir="xapian-core-${XAPIAN_SOURCE_VERSION}" D_file="$B_dir.tar.xz" verified_download $D_file $XAPIAN_SOURCE_SHA256 \ @@ -503,15 +635,12 @@ build_xapian() --prefix="${PREFIX}" --with-sysroot="${SYSROOT}" make -j${HOST_NUM_CPU} make install + cd .. } +task_register build_miniupnpc build_miniupnpc() { - echo "build_miniupnpc() -################################################################################ -################################################################################ -################################################################################ -" S_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}" B_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}-build" D_file="$S_dir.tar.gz" @@ -521,29 +650,229 @@ build_miniupnpc() tar -xf $D_file mkdir $B_dir cd $B_dir - cmake \ + andro_cmake \ -DUPNPC_BUILD_STATIC=TRUE \ -DUPNPC_BUILD_SHARED=FALSE \ -DUPNPC_BUILD_TESTS=FALSE \ -DUPNPC_BUILD_SAMPLE=FALSE \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -S../$S_dir + -B. -S../$S_dir make -j${HOST_NUM_CPU} make install + cd .. } -build_toolchain -[ "${INSTALL_QT_ANDROID}X" != "trueX" ] || install_qt_android -build_bzlib -build_openssl -build_sqlite -build_sqlcipher -build_libupnp -build_rapidjson -build_restbed -build_udp-discovery-cpp -build_xapian -build_miniupnpc -delete_copied_includes +task_register build_zlib +build_zlib() +{ + S_dir="zlib-${ZLIB_SOURCE_VERSION}" + B_dir="zlib-${ZLIB_SOURCE_VERSION}-build" + D_file="$S_dir.tar.xz" + verified_download $D_file $ZLIB_SOURCE_SHA256 \ + http://www.zlib.net/${D_file} + rm -rf $S_dir $B_dir + tar -xf $D_file + mkdir $B_dir + cd $B_dir + andro_cmake -B. -S../$S_dir + make -j${HOST_NUM_CPU} + make install + rm -f ${PREFIX}/lib/libz.so* + cd .. +} -echo NATIVE_LIBS_TOOLCHAIN_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH} +task_register build_libpng +build_libpng() +{ + task_run build_zlib + + S_dir="libpng-${LIBPNG_SOURCE_VERSION}" + B_dir="libpng-${LIBPNG_SOURCE_VERSION}-build" + D_file="$S_dir.tar.xz" + verified_download $D_file $LIBPNG_SOURCE_SHA256 \ + https://download.sourceforge.net/libpng/${D_file} + rm -rf $S_dir $B_dir + tar -xf $D_file + + # libm is part of bionic An android + sed -i -e 's/find_library(M_LIBRARY m)/set(M_LIBRARY "")/' $S_dir/CMakeLists.txt + + # Disable hardware acceleration as they are problematic for Android + # compilation and are not supported by all phones, it is necessary to fiddle + # with CMakeLists.txt as libpng 1.6.37 passing it as cmake options seems not + # working properly + # https://github.com/imagemin/optipng-bin/issues/97 + # https://github.com/opencv/opencv/issues/7600 + echo "add_definitions(-DPNG_ARM_NEON_OPT=0)" >> $S_dir/CMakeLists.txt + + mkdir $B_dir + pushd $B_dir + + HW_OPT="OFF" +# [ "$ANDROID_PLATFORM_VER" -ge "22" ] && HW_OPT="ON" + + andro_cmake \ + -DPNG_SHARED=OFF \ + -DPNG_STATIC=ON \ + -DPNG_TESTS=OFF \ + -DPNG_HARDWARE_OPTIMIZATIONS=$HW_OPT \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -B. -S../$S_dir + make -j${HOST_NUM_CPU} + make install + popd +} + +task_register build_libjpeg +build_libjpeg() +{ + S_dir="jpeg-${LIBJPEG_SOURCE_VERSION}" + D_file="jpegsrc.v${LIBJPEG_SOURCE_VERSION}.tar.gz" + verified_download $D_file $LIBJPEG_SOURCE_SHA256 \ + https://www.ijg.org/files/$D_file + rm -rf $S_dir + tar -xf $D_file + cd $S_dir + ./configure --with-pic --prefix="${PREFIX}" --host=${cArch}-linux + make -j${HOST_NUM_CPU} + make install + rm -f ${PREFIX}/lib/libjpeg.so* + cd .. +} + +task_register build_tiff +build_tiff() +{ + S_dir="tiff-${TIFF_SOURCE_VERSION}" + B_dir="${S_dir}-build" + D_file="tiff-${TIFF_SOURCE_VERSION}.tar.gz" + + verified_download $D_file $TIFF_SOURCE_SHA256 \ + https://download.osgeo.org/libtiff/${D_file} + + rm -rf $S_dir $B_dir + tar -xf $D_file + mkdir $B_dir + + # Disable tools building, not needed for retroshare, and depending on some + # OpenGL headers not available on Android + echo "" > $S_dir/tools/CMakeLists.txt + + # Disable tests building, not needed for retroshare, and causing linker + # errors + echo "" > $S_dir/test/CMakeLists.txt + + # Disable extra tools building, not needed for retroshare, and causing + # linker errors + echo "" > $S_dir/contrib/CMakeLists.txt + + # Disable more unneded stuff + echo "" > $S_dir/build/CMakeLists.txt + echo "" > $S_dir/html/CMakeLists.txt + echo "" > $S_dir/man/CMakeLists.txt + echo "" > $S_dir/port/CMakeLists.txt + + # Change to static library build + sed -i 's\add_library(tiff\add_library(tiff STATIC\' \ + $S_dir/libtiff/CMakeLists.txt + + cd $B_dir + #TODO: build dependecies to support more formats + andro_cmake \ + -Dlibdeflate=OFF -Djbig=OFF -Dlzma=OFF -Dzstd=OFF -Dwebp=OFF \ + -Djpeg12=OFF \ + -Dcxx=OFF \ + -B. -S../$S_dir + make -j${HOST_NUM_CPU} + make install + cd .. +} + +task_register build_cimg +build_cimg() +{ + task_run build_libpng + task_run build_libjpeg + task_run build_tiff + + S_dir="CImg-${CIMG_SOURCE_VERSION}" + D_file="CImg_${CIMG_SOURCE_VERSION}.zip" + + verified_download $D_file $CIMG_SOURCE_SHA256 \ + https://cimg.eu/files/${D_file} + + unzip -o $D_file + + cp --archive --verbose "$S_dir/CImg.h" "$PREFIX/include/" +} + +task_register build_phash +build_phash() +{ + task_run build_cimg + + S_dir="pHash" + B_dir="${S_dir}-build" + + git_source_get "$S_dir" "$PHASH_SOURCE_REPO" "${PHASH_SOURCE_VERSION}" + + rm -rf $B_dir; mkdir $B_dir ; pushd $B_dir + andro_cmake -DPHASH_DYNAMIC=OFF -DPHASH_STATIC=ON -B. -H../pHash + make -j${HOST_NUM_CPU} + make install + popd +} + +task_register build_mvptree +build_mvptree() +{ + S_dir="mvptree" + B_dir="${S_dir}-build" + + git_source_get "$S_dir" "$MVPTREE_SOURCE_REPO" "${MVPTREE_SOURCE_VERSION}" + rm -rf $B_dir; mkdir $B_dir ; pushd $B_dir + andro_cmake -B. -H../${S_dir} + make -j${HOST_NUM_CPU} + make install + popd +} + +task_register get_native_libs_toolchain_path +get_native_libs_toolchain_path() +{ + echo ${NATIVE_LIBS_TOOLCHAIN_PATH} +} + +task_register build_default_toolchain +build_default_toolchain() +{ + task_run bootstrap_toolchain || return $? + task_run build_bzlib || return $? + task_run build_openssl || return $? + task_run build_sqlcipher || return $? + task_run build_rapidjson || return $? + task_run build_restbed || return $? + task_run build_udp-discovery-cpp || return $? + task_run build_xapian || return $? + task_run build_miniupnpc || return $? + task_run build_phash || return $? + task_run build_mvptree || return $? + task_run deduplicate_includes || return $? + task_run get_native_libs_toolchain_path || return $? +} + +if [ "$1" == "" ]; then + rm -rf "$REPORT_DIR" + mkdir -p "$REPORT_DIR" + cat "$0" > "$REPORT_DIR/build_script" + env > "$REPORT_DIR/build_env" + build_default_toolchain +else + # do not delete report directory in this case so we can reuse material + # produced by previous run, like deduplicated includes + mkdir -p "$REPORT_DIR" + while [ "$1" != "" ] ; do + task_zap $1 + task_run $1 || exit $? + shift + done +fi diff --git a/build_scripts/GitlabCI/Android.Dockerfile b/build_scripts/GitlabCI/Android.Dockerfile new file mode 100644 index 000000000..80795de19 --- /dev/null +++ b/build_scripts/GitlabCI/Android.Dockerfile @@ -0,0 +1,43 @@ +ARG ANDROID_NDK_ARCH=arm +FROM registry.gitlab.com/retroshare/retroshare:android_${ANDROID_NDK_ARCH}_base + +RUN apt-get update -y && apt-get upgrade -y + +ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git +ARG REPO_BRANCH=master + +WORKDIR /RetroShare +RUN git remote add testing $REPO_URL && \ + git fetch --tags testing $REPO_BRANCH && \ + git reset --hard testing/$REPO_BRANCH && \ + git --no-pager log --max-count 1 + +RUN rm -rf /jsonapi-generator-build ; mkdir /jsonapi-generator-build +WORKDIR /jsonapi-generator-build/ +RUN qmake ../RetroShare/jsonapi-generator/src/ \ + CONFIG+=no_retroshare_plugins \ + CONFIG+=no_retroshare_service CONFIG+=no_retroshare_gui \ + CONFIG+=rs_jsonapi && \ + make -j$(nproc) + +RUN rm -rf /retroshare-service-android-build ; mkdir /retroshare-service-android-build +WORKDIR /retroshare-service-android-build + +# ARG declared before FROM get wiped after it, so we need declaring it again +ARG ANDROID_NDK_ARCH=arm +RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \ + -spec android-clang \ + CONFIG+=retroshare_service CONFIG+=rs_jsonapi \ + RS_UPNP_LIB=miniupnpc \ + JSONAPI_GENERATOR_EXE=/jsonapi-generator-build/jsonapi-generator \ + NATIVE_LIBS_TOOLCHAIN_PATH=$NATIVE_LIBS_TOOLCHAIN_PATH \ + CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password \ + CONFIG+=no_rs_service_terminal_login +RUN make -j$(nproc) +RUN make install INSTALL_ROOT=/retroshare-service-android-build/android-build/ + +ARG ANDROID_PLATFORM_VER=16 +RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/androiddeployqt \ + --input retroshare-service/src/android-libretroshare-service.so-deployment-settings.json \ + --output android-build --android-platform android-$ANDROID_PLATFORM_VER \ + --jdk $JAVA_HOME --gradle From af035478b919122c2921c9061f10488c9cc589a8 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 2 Sep 2021 09:08:01 +0200 Subject: [PATCH 144/697] Attempt to avoid timeout in Travis CI macOS --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9b0be7fa6..fc617d1b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,11 +68,11 @@ before_script: fi script: - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j4; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then travis_wait 30 make -j$(nproc); fi after_success: - if [ $TRAVIS_OS_NAME == osx ]; then build_scripts/OSX/travis_makeOSXPackage.sh ; fi - - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi +# - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi # branches: From f5f0ddc1adb913ee40dd69c414f88be3d6578d1a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 2 Sep 2021 11:13:41 +0200 Subject: [PATCH 145/697] Updated Travis CI URL --- README.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.asciidoc b/README.asciidoc index 182b46e7f..8f8f6d089 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -10,7 +10,7 @@ RetroShare provides file sharing, chat, messages, forums, channels and more. .Build Status |=============================================================================== |GNU/Linux, Android (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"] -|GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.org/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.org/RetroShare/RetroShare"] +|GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.com/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.com/RetroShare/RetroShare"] |Windows (via AppVeyor) | image:https://ci.appveyor.com/api/projects/status/github/RetroShare/RetroShare?svg=true[link="https://ci.appveyor.com/project/RetroShare58622/retroshare"] |=============================================================================== From d51d96116f28ec6a59bd7229dea3bfb1d9a273b7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 2 Sep 2021 12:07:04 +0200 Subject: [PATCH 146/697] Disable Travis CI Linux to save scarce credits Fix Travis CI badge URL --- .travis.yml | 8 ++++---- README.asciidoc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc617d1b8..ef38661ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,10 +8,10 @@ language: cpp matrix: include: - - os: linux - dist: bionic - sudo: required - compiler: gcc +# - os: linux +# dist: bionic +# sudo: required +# compiler: gcc - os: osx osx_image: xcode10.2 compiler: clang diff --git a/README.asciidoc b/README.asciidoc index 8f8f6d089..9bacc3345 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -10,8 +10,8 @@ RetroShare provides file sharing, chat, messages, forums, channels and more. .Build Status |=============================================================================== |GNU/Linux, Android (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"] -|GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.com/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.com/RetroShare/RetroShare"] |Windows (via AppVeyor) | image:https://ci.appveyor.com/api/projects/status/github/RetroShare/RetroShare?svg=true[link="https://ci.appveyor.com/project/RetroShare58622/retroshare"] +|macOS, (via Travis CI) | image:https://app.travis-ci.com/RetroShare/RetroShare.svg?branch=master[link="https://app.travis-ci.com/github/RetroShare/RetroShare"] |=============================================================================== From 900ea5508d0f19d5a72f72fff294983fa605cca0 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 2 Sep 2021 17:44:57 +0200 Subject: [PATCH 147/697] Updated OBS submodule --- build_scripts/OBS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/OBS b/build_scripts/OBS index 6d6ee4aab..984ed34b7 160000 --- a/build_scripts/OBS +++ b/build_scripts/OBS @@ -1 +1 @@ -Subproject commit 6d6ee4aab171c23c603f7e813ba66d22192393ad +Subproject commit 984ed34b7f751bd407877603551ead49959f1901 From 8452e30afc203d3aa950fd5ee43cee3150fd976b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 3 Sep 2021 12:48:44 +0200 Subject: [PATCH 148/697] CI and Android toolchain improvements --- build_scripts/Android/Dockerfile | 12 +------ .../Android/prepare-toolchain-clang.sh | 10 ++++-- build_scripts/GitlabCI/base.Dockerfile | 34 +++++++++---------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index a8972d24a..dc1320d9c 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -63,17 +63,7 @@ WORKDIR /bCache RUN $PREPARE_TOOLCHAIN install_android_sdk RUN $PREPARE_TOOLCHAIN install_android_ndk -RUN $PREPARE_TOOLCHAIN bootstrap_toolchain -RUN $PREPARE_TOOLCHAIN build_bzlib -RUN $PREPARE_TOOLCHAIN build_openssl -RUN $PREPARE_TOOLCHAIN build_sqlite -RUN $PREPARE_TOOLCHAIN build_sqlcipher -RUN $PREPARE_TOOLCHAIN build_rapidjson -RUN $PREPARE_TOOLCHAIN build_restbed -RUN $PREPARE_TOOLCHAIN build_udp-discovery-cpp -RUN $PREPARE_TOOLCHAIN build_xapian -RUN $PREPARE_TOOLCHAIN build_miniupnpc -RUN $PREPARE_TOOLCHAIN deduplicate_includes +RUN $PREPARE_TOOLCHAIN ARG QT_INSTALLER_JWT_TOKEN RUN $PREPARE_TOOLCHAIN install_qt_android diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index daa556b79..25fefccba 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -68,7 +68,7 @@ define_default_value QT_ANDROID_VIA_INSTALLER "false" define_default_value QT_VERSION "5.12.11" define_default_value QT_INSTALLER_VERSION "4.1.1" define_default_value QT_INSTALLER_SHA256 1266ffd0d1b0e466244e3bc8422975c1aa9d96745b6bb28d422f7f92df11f34c -define_default_value QT_INSTALLER_JWT_TOKEN "Need a QT account JWT token to use the insaller see https://wiki.qt.io/Online_Installer_4.x" +define_default_value QT_INSTALLER_JWT_TOKEN "" define_default_value QT_INSTALL_PATH "${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt/" define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763 @@ -416,6 +416,13 @@ get_qt_dir() task_register install_qt_android install_qt_android() { + [ "$QT_INSTALLER_JWT_TOKEN" == "" ] && + { + echo "To run Qt installer QT_INSTALLER_JWT_TOKEN environement variable \ +need to be set to a valid JWT token see https://wiki.qt.io/Online_Installer_4.x" + return -1 + } + QT_VERSION_CODE="$(echo $QT_VERSION | tr -d .)" QT_INSTALLER="qt-unified-linux-x86_64-${QT_INSTALLER_VERSION}-online.run" tMajDotMinVer="$(echo $QT_INSTALLER_VERSION | awk -F. '{print $1"."$2}')" @@ -855,7 +862,6 @@ build_default_toolchain() task_run build_xapian || return $? task_run build_miniupnpc || return $? task_run build_phash || return $? - task_run build_mvptree || return $? task_run deduplicate_includes || return $? task_run get_native_libs_toolchain_path || return $? } diff --git a/build_scripts/GitlabCI/base.Dockerfile b/build_scripts/GitlabCI/base.Dockerfile index f4cf610db..f1ad9c5a2 100644 --- a/build_scripts/GitlabCI/base.Dockerfile +++ b/build_scripts/GitlabCI/base.Dockerfile @@ -2,42 +2,42 @@ ## force cloning a new ## To prepare an image suitable as base for Gitlab CI use -# docker build -t "${CI_REGISTRY_IMAGE}:base" --build-arg KEEP_SOURCE=true --build-arg REPO_DEPTH="" -f base.Dockerfile . - -## Now you need to tag it so you can later push it -# docker tag ${ID_OF_THE_CREATED_IMAGE} registry.gitlab.com/retroshare/${CI_REGISTRY_IMAGE}:base +# export CI_REGISTRY_IMAGE="registry.gitlab.com/retroshare/retroshare:base" +# docker build -t "${CI_REGISTRY_IMAGE}" -f base.Dockerfile . ## To push it to gitlab CI registry you need first to login and the to push # docker login registry.gitlab.com -# docker push registry.gitlab.com/retroshare/${CI_REGISTRY_IMAGE}:base - +# docker push "${CI_REGISTRY_IMAGE}" ## To run the container -# docker run -it -p 127.0.0.1:9092:9092 "${CI_REGISTRY_IMAGE}:base" retroshare-service --jsonApiPort 9092 --jsonApiBindAddress 0.0.0.0 +# docker run -it -p 127.0.0.1:9092:9092 "${CI_REGISTRY_IMAGE}" retroshare-service --jsonApiPort 9092 --jsonApiBindAddress 0.0.0.0 FROM ubuntu -ARG CACHEBUST=0 -RUN \ - apt-get update -y && apt-get upgrade -y && \ - apt-get install -y build-essential libssl-dev libbz2-dev libsqlite3-dev \ +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update -y && apt-get upgrade -y -qq && \ + apt-get install -y -qq build-essential cimg-dev libssl-dev libbz2-dev \ + libsqlite3-dev \ libsqlcipher-dev libupnp-dev pkg-config libz-dev \ qt5-default libxapian-dev qttools5-dev doxygen rapidjson-dev \ git cmake curl +RUN git clone --depth 1 https://github.com/aetilius/pHash.git && \ + rm -rf pHash-build && mkdir pHash-build && cd pHash-build && \ + cmake -B. -H../pHash && make -j$(nproc) && make install && cd .. && \ + rm -rf pHash-build pHash + ARG FRESHCLONE=0 ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git ARG REPO_BRANCH=master ARG REPO_DEPTH="--depth 2000" -ARG KEEP_SOURCE=false -RUN apt-get update -y && apt-get upgrade -y RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \ git fetch --tags && cd .. -RUN \ - mkdir RetroShare-build && cd RetroShare-build && \ +RUN mkdir RetroShare-build && cd RetroShare-build && \ qmake ../RetroShare \ - CONFIG+=no_retroshare_plugins CONFIG+=ipv6 \ + CONFIG+=no_retroshare_plugins \ CONFIG+=retroshare_service CONFIG+=no_retroshare_gui \ CONFIG+=rs_jsonapi CONFIG+=rs_deep_search && \ (make -j$(nproc) || make -j$(nproc) || make) && make install && \ - cd .. && rm -rf RetroShare-build && ($KEEP_SOURCE || rm -rf RetroShare) + cd .. && rm -rf RetroShare-build From a18d6aaa1eb55006074366e8536b9d295eb66379 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 3 Sep 2021 14:55:03 +0200 Subject: [PATCH 149/697] Add JSON API to get/set storage and sync GXS time --- .../src/retroshare/rsgxsifacehelper.h | 83 ++++++++++++------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 4339f95f0..e48d0cb23 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2011 Christopher Evi-Parker * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -208,6 +209,58 @@ public: return mGxs.getGroupStatistic(token, stats); } + /*! + * @brief Get default maximum storage time for GXS messages + * @jsonapi{development} + * @return storage time in seconds + */ + uint32_t getDefaultStoragePeriod() + { return mGxs.getDefaultStoragePeriod(); } + + /*! + * @brief Get maximum storage time of GXS messages for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @return storage time in seconds + */ + uint32_t getStoragePeriod(const RsGxsGroupId& groupId) + { return mGxs.getStoragePeriod(groupId); } + + /*! + * @brief Set GXS messages maximum storage time for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @param[in] storageSecs storage time in seconds + */ + void setStoragePeriod(const RsGxsGroupId& groupId, uint32_t storageSecs) + { mGxs.setStoragePeriod(groupId, storageSecs); } + + /*! + * @brief Get default maximum syncronization age for GXS messages + * @jsonapi{development} + * @return age in seconds + */ + uint32_t getDefaultSyncPeriod() + { return mGxs.getDefaultSyncPeriod(); } + + /*! + * @brief Get maximum syncronization age of GXS messages for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @return age in seconds + */ + uint32_t getSyncPeriod(const RsGxsGroupId& groupId) + { return mGxs.getSyncPeriod(groupId); } + + /*! + * @brief Set GXS messages maximum syncronization age for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @param[in] syncAge age in seconds + */ + void setSyncPeriod(const RsGxsGroupId& groupId, uint32_t syncAge) + { mGxs.setSyncPeriod(groupId, syncAge); } + /*! * This determines the reputation threshold messages need to surpass in order * for it to be accepted by local user from remote source @@ -221,34 +274,6 @@ public: return mGxs.setGroupReputationCutOff(token, grpId, CutOff); } - /*! - * @return storage/sync time of messages in secs - */ - uint32_t getDefaultStoragePeriod() - { - return mGxs.getDefaultStoragePeriod(); - } - uint32_t getStoragePeriod(const RsGxsGroupId& grpId) - { - return mGxs.getStoragePeriod(grpId); - } - void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) - { - mGxs.setStoragePeriod(grpId,age_in_secs); - } - uint32_t getDefaultSyncPeriod() - { - return mGxs.getDefaultSyncPeriod(); - } - uint32_t getSyncPeriod(const RsGxsGroupId& grpId) - { - return mGxs.getSyncPeriod(grpId); - } - void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) - { - mGxs.setSyncPeriod(grpId,age_in_secs); - } - RsReputationLevel minReputationForForwardingMessages( uint32_t group_sign_flags, uint32_t identity_flags ) { From 19915a8eb4ce921367cbc8ded3d6e79d2e15dbc7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 3 Sep 2021 14:56:45 +0200 Subject: [PATCH 150/697] Fix broken line endings --- .../src/retroshare/rsgxsifacehelper.h | 1122 ++++++++--------- 1 file changed, 561 insertions(+), 561 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index e48d0cb23..a6680afc6 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -1,561 +1,561 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsifacehelper.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2011 Christopher Evi-Parker * - * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2019-2021 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "retroshare/rsgxsiface.h" -#include "retroshare/rsservicecontrol.h" -#include "retroshare/rsreputations.h" -#include "rsgxsflags.h" -#include "util/rsdeprecate.h" -#include "util/rsdebug.h" - -/*! - * This class only make method of internal members visible tu upper level to - * offer a more friendly API. - * This is just a workaround to awkward GXS API design, do not take it as an - * example for your coding. - * To properly fix the API design many changes with the implied chain reactions - * are necessary, so at this point this workaround seems acceptable. - */ - -//================================== -// #define DEBUG_GXSIFACEHELPER 1 -//================================== - -enum class TokenRequestType: uint8_t -{ - __NONE = 0x00, /// Used to detect uninitialized - GROUP_DATA = 0x01, - GROUP_META = 0x02, - GROUP_IDS = 0x03, - POSTS = 0x04, - ALL_POSTS = 0x05, - MSG_RELATED_INFO = 0x06, - GROUP_STATISTICS = 0x07, - SERVICE_STATISTICS = 0x08, - NO_KILL_TYPE = 0x09, - __MAX /// Used to detect out of range -}; - -class RsGxsIfaceHelper -{ -public: - /*! - * @param gxs handle to RsGenExchange instance of service (Usually the - * service class itself) - */ - explicit RsGxsIfaceHelper(RsGxsIface& gxs) : - mGxs(gxs), mTokenService(*gxs.getTokenService()), mMtx("GxsIfaceHelper") - {} - - ~RsGxsIfaceHelper() = default; - -#ifdef TO_REMOVE - /*! - * Gxs services should call this for automatic handling of - * changes, send - * @param changes - */ - void receiveChanges(std::vector &changes) - { - mGxs.receiveChanges(changes); - } -#endif - - /* Generic Lists */ - - /*! - * Retrieve list of group ids associated to a request token - * @param token token to be redeemed for this request - * @param groupIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getGroupList(const uint32_t &token, std::list &groupIds) - { - return mGxs.getGroupList(token, groupIds); - } - - /*! - * Retrieves list of msg ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgList(const uint32_t &token, - GxsMsgIdResult& msgIds) - { - return mGxs.getMsgList(token, msgIds); - } - - /*! - * Retrieves list of msg related ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) - { - return mGxs.getMsgRelatedList(token, msgIds); - } - - /*! - * @param token token to be redeemed for group summary request - * @param groupInfo the ids returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getGroupSummary(const uint32_t &token, std::list &groupInfo) - { - return mGxs.getGroupMeta(token, groupInfo); - } - - /*! - * @param token token to be redeemed for message summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) - { - return mGxs.getMsgMeta(token, msgInfo); - } - - /*! - * @param token token to be redeemed for message related summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgRelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo) - { - return mGxs.getMsgRelatedMeta(token, msgInfo); - } - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) - { - return mGxs.subscribeToGroup(token, grpId, subscribe); - } - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) - { - return mGxs.acknowledgeTokenMsg(token, msgId); - } - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) - { - return mGxs.acknowledgeTokenGrp(token, grpId); - } - - /*! - * Gets service statistic for a given services - * @param token value to to retrieve requested stats - * @param stats the status - * @return true if token exists false otherwise - */ - bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) - { - return mGxs.getServiceStatistic(token, stats); - } - - /*! - * - * @param token to be redeemed - * @param stats the stats associated to token request - * @return true if token is false otherwise - */ - bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) - { - return mGxs.getGroupStatistic(token, stats); - } - - /*! - * @brief Get default maximum storage time for GXS messages - * @jsonapi{development} - * @return storage time in seconds - */ - uint32_t getDefaultStoragePeriod() - { return mGxs.getDefaultStoragePeriod(); } - - /*! - * @brief Get maximum storage time of GXS messages for the given group - * @jsonapi{development} - * @param[in] groupId Id of the group - * @return storage time in seconds - */ - uint32_t getStoragePeriod(const RsGxsGroupId& groupId) - { return mGxs.getStoragePeriod(groupId); } - - /*! - * @brief Set GXS messages maximum storage time for the given group - * @jsonapi{development} - * @param[in] groupId Id of the group - * @param[in] storageSecs storage time in seconds - */ - void setStoragePeriod(const RsGxsGroupId& groupId, uint32_t storageSecs) - { mGxs.setStoragePeriod(groupId, storageSecs); } - - /*! - * @brief Get default maximum syncronization age for GXS messages - * @jsonapi{development} - * @return age in seconds - */ - uint32_t getDefaultSyncPeriod() - { return mGxs.getDefaultSyncPeriod(); } - - /*! - * @brief Get maximum syncronization age of GXS messages for the given group - * @jsonapi{development} - * @param[in] groupId Id of the group - * @return age in seconds - */ - uint32_t getSyncPeriod(const RsGxsGroupId& groupId) - { return mGxs.getSyncPeriod(groupId); } - - /*! - * @brief Set GXS messages maximum syncronization age for the given group - * @jsonapi{development} - * @param[in] groupId Id of the group - * @param[in] syncAge age in seconds - */ - void setSyncPeriod(const RsGxsGroupId& groupId, uint32_t syncAge) - { mGxs.setSyncPeriod(groupId, syncAge); } - - /*! - * This determines the reputation threshold messages need to surpass in order - * for it to be accepted by local user from remote source - * NOTE: threshold only enforced if service require author signature - * @param token value set to be redeemed with acknowledgement - * @param grpId group id for cutoff value to be set - * @param CutOff The cut off value to set - */ - void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) - { - return mGxs.setGroupReputationCutOff(token, grpId, CutOff); - } - - RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_flags ) - { - return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags); - } - - /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds, bool high_priority_request = false ) - { - TokenRequestType token_request_type; - - switch(opts.mReqType) - { - case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; - case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; - case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; - default: - RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; - return false; - } - - cancelActiveRequestTokens(token_request_type); - - if( mTokenService.requestGroupInfo(token, 0, opts, groupIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts, bool high_priority_request = false) - { - TokenRequestType token_request_type; - - switch(opts.mReqType) - { - case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; - case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; - case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; - default: - RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; - return false; - } - - cancelActiveRequestTokens(token_request_type); - - - if( mTokenService.requestGroupInfo(token, 0, opts)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgInfo - bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const GxsMsgReq& msgIds ) - { - if(mTokenService.requestMsgInfo(token, 0, opts, msgIds)) - { - RS_STACK_MUTEX(mMtx); - - mActiveTokens[token]= (msgIds.size()==1 && msgIds.begin()->second.size()==0) ?(TokenRequestType::ALL_POSTS):(TokenRequestType::POSTS); -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgInfo - bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list& grpIds ) - { - if(mTokenService.requestMsgInfo(token, 0, opts, grpIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::ALL_POSTS; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgRelatedInfo - bool requestMsgRelatedInfo( - uint32_t& token, const RsTokReqOptions& opts, - const std::vector& msgIds ) - { - if( mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::MSG_RELATED_INFO; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /** - * @jsonapi{development} - * @param[in] token - */ - RsTokenService::GxsRequestStatus requestStatus(uint32_t token) - { return mTokenService.requestStatus(token); } - - /// @see RsTokenService::requestServiceStatistic - bool requestServiceStatistic(uint32_t& token) - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_SERVICE_STATS; - - mTokenService.requestServiceStatistic(token,opts); - - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS; - -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - - /// @see RsTokenService::requestGroupStatistic - bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_STATS; - - mTokenService.requestGroupStatistic(token, grpId,opts); - - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - - bool cancelActiveRequestTokens(TokenRequestType type) - { - RS_STACK_MUTEX(mMtx); - for(auto it = mActiveTokens.begin();it!=mActiveTokens.end();) - if(it->second == type) - { - mTokenService.cancelRequest(it->first); - it = mActiveTokens.erase(it); - } - else - ++it; - - return true; - } - - /// @see RsTokenService::cancelRequest - bool cancelRequest(uint32_t token) - { - { - RS_STACK_MUTEX(mMtx); - mActiveTokens.erase(token); - } - return mTokenService.cancelRequest(token); - } - - /** - * @deprecated - * Token service methods are already exposed by this helper, so you should - * not need to get token service pointer directly anymore. - */ - RS_DEPRECATED RsTokenService* getTokenService() { return &mTokenService; } - -protected: - /** - * Block caller while request is being processed. - * Useful for blocking API implementation. - * @param[in] token token associated to the request caller is waiting for - * @param[in] maxWait maximum waiting time in milliseconds - * @param[in] checkEvery time in millisecond between status checks - * @param[in] auto_delete_if_unsuccessful delete the request when it fails. This avoid leaving useless pending requests in the queue that would slow down additional calls. - */ - RsTokenService::GxsRequestStatus waitToken( - uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), - bool auto_delete_if_unsuccessful=true) - { -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - auto wkStartime = std::chrono::steady_clock::now(); - int maxWorkAroundCnt = 10; -LLwaitTokenBeginLabel: -#endif - auto timeout = std::chrono::steady_clock::now() + maxWait; - auto st = requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) - && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) - cancelRequest(token); - -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - /* Work around for very slow/old android devices, we don't expect this - * to be necessary on newer devices. If it take unreasonably long - * something worser is already happening elsewere and we return anyway. - */ - if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE - && maxWorkAroundCnt-- > 0 ) - { - maxWait *= 10; - checkEvery *= 3; - Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " - << " workaround st: " << st - << " maxWorkAroundCnt: " << maxWorkAroundCnt - << " maxWait: " << maxWait.count() - << " checkEvery: " << checkEvery.count() << std::endl; - goto LLwaitTokenBeginLabel; - } - Dbg3() << __PRETTY_FUNCTION__ << " lasted: " - << std::chrono::duration_cast( - std::chrono::steady_clock::now() - wkStartime ).count() - << "ms" << std::endl; - -#endif - - { - RS_STACK_MUTEX(mMtx); - mActiveTokens.erase(token); - } - - return st; - } - -private: - RsGxsIface& mGxs; - RsTokenService& mTokenService; - RsMutex mMtx; - - std::map mActiveTokens; - -#ifdef DEBUG_GXSIFACEHELPER - void locked_dumpTokens() - { - const uint16_t service_id = mGxs.serviceType(); - const auto countSize = static_cast(TokenRequestType::__MAX); - uint32_t count[countSize] = {0}; - - RsDbg rsdbg; - rsdbg << __PRETTY_FUNCTION__ << " Service 0x" << std::hex << service_id - << " (" << rsServiceControl->getServiceName( - RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id) ) - << ") this=0x" << static_cast(this) - << ") Active tokens (per type): "; - - // let's count how many token of each type we've got. - for(auto& it: mActiveTokens) ++count[static_cast(it.second)]; - - for(uint32_t i=0; i < countSize; ++i) - rsdbg /* << i << ":" */ << count[i] << " "; - } -#endif // def DEBUG_GXSIFACEHELPER - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; +/******************************************************************************* + * libretroshare/src/retroshare: rsgxsifacehelper.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2011 Christopher Evi-Parker * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ +#pragma once + +#include +#include + +#include "retroshare/rsgxsiface.h" +#include "retroshare/rsservicecontrol.h" +#include "retroshare/rsreputations.h" +#include "rsgxsflags.h" +#include "util/rsdeprecate.h" +#include "util/rsdebug.h" + +/*! + * This class only make method of internal members visible tu upper level to + * offer a more friendly API. + * This is just a workaround to awkward GXS API design, do not take it as an + * example for your coding. + * To properly fix the API design many changes with the implied chain reactions + * are necessary, so at this point this workaround seems acceptable. + */ + +//================================== +// #define DEBUG_GXSIFACEHELPER 1 +//================================== + +enum class TokenRequestType: uint8_t +{ + __NONE = 0x00, /// Used to detect uninitialized + GROUP_DATA = 0x01, + GROUP_META = 0x02, + GROUP_IDS = 0x03, + POSTS = 0x04, + ALL_POSTS = 0x05, + MSG_RELATED_INFO = 0x06, + GROUP_STATISTICS = 0x07, + SERVICE_STATISTICS = 0x08, + NO_KILL_TYPE = 0x09, + __MAX /// Used to detect out of range +}; + +class RsGxsIfaceHelper +{ +public: + /*! + * @param gxs handle to RsGenExchange instance of service (Usually the + * service class itself) + */ + explicit RsGxsIfaceHelper(RsGxsIface& gxs) : + mGxs(gxs), mTokenService(*gxs.getTokenService()), mMtx("GxsIfaceHelper") + {} + + ~RsGxsIfaceHelper() = default; + +#ifdef TO_REMOVE + /*! + * Gxs services should call this for automatic handling of + * changes, send + * @param changes + */ + void receiveChanges(std::vector &changes) + { + mGxs.receiveChanges(changes); + } +#endif + + /* Generic Lists */ + + /*! + * Retrieve list of group ids associated to a request token + * @param token token to be redeemed for this request + * @param groupIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getGroupList(const uint32_t &token, std::list &groupIds) + { + return mGxs.getGroupList(token, groupIds); + } + + /*! + * Retrieves list of msg ids associated to a request token + * @param token token to be redeemed for this request + * @param msgIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgList(const uint32_t &token, + GxsMsgIdResult& msgIds) + { + return mGxs.getMsgList(token, msgIds); + } + + /*! + * Retrieves list of msg related ids associated to a request token + * @param token token to be redeemed for this request + * @param msgIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) + { + return mGxs.getMsgRelatedList(token, msgIds); + } + + /*! + * @param token token to be redeemed for group summary request + * @param groupInfo the ids returned for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getGroupSummary(const uint32_t &token, std::list &groupInfo) + { + return mGxs.getGroupMeta(token, groupInfo); + } + + /*! + * @param token token to be redeemed for message summary request + * @param msgInfo the message metadata returned for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) + { + return mGxs.getMsgMeta(token, msgInfo); + } + + /*! + * @param token token to be redeemed for message related summary request + * @param msgInfo the message metadata returned for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgRelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo) + { + return mGxs.getMsgRelatedMeta(token, msgInfo); + } + + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) + { + return mGxs.subscribeToGroup(token, grpId, subscribe); + } + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) + { + return mGxs.acknowledgeTokenMsg(token, msgId); + } + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) + { + return mGxs.acknowledgeTokenGrp(token, grpId); + } + + /*! + * Gets service statistic for a given services + * @param token value to to retrieve requested stats + * @param stats the status + * @return true if token exists false otherwise + */ + bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) + { + return mGxs.getServiceStatistic(token, stats); + } + + /*! + * + * @param token to be redeemed + * @param stats the stats associated to token request + * @return true if token is false otherwise + */ + bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) + { + return mGxs.getGroupStatistic(token, stats); + } + + /*! + * @brief Get default maximum storage time for GXS messages + * @jsonapi{development} + * @return storage time in seconds + */ + uint32_t getDefaultStoragePeriod() + { return mGxs.getDefaultStoragePeriod(); } + + /*! + * @brief Get maximum storage time of GXS messages for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @return storage time in seconds + */ + uint32_t getStoragePeriod(const RsGxsGroupId& groupId) + { return mGxs.getStoragePeriod(groupId); } + + /*! + * @brief Set GXS messages maximum storage time for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @param[in] storageSecs storage time in seconds + */ + void setStoragePeriod(const RsGxsGroupId& groupId, uint32_t storageSecs) + { mGxs.setStoragePeriod(groupId, storageSecs); } + + /*! + * @brief Get default maximum syncronization age for GXS messages + * @jsonapi{development} + * @return age in seconds + */ + uint32_t getDefaultSyncPeriod() + { return mGxs.getDefaultSyncPeriod(); } + + /*! + * @brief Get maximum syncronization age of GXS messages for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @return age in seconds + */ + uint32_t getSyncPeriod(const RsGxsGroupId& groupId) + { return mGxs.getSyncPeriod(groupId); } + + /*! + * @brief Set GXS messages maximum syncronization age for the given group + * @jsonapi{development} + * @param[in] groupId Id of the group + * @param[in] syncAge age in seconds + */ + void setSyncPeriod(const RsGxsGroupId& groupId, uint32_t syncAge) + { mGxs.setSyncPeriod(groupId, syncAge); } + + /*! + * This determines the reputation threshold messages need to surpass in order + * for it to be accepted by local user from remote source + * NOTE: threshold only enforced if service require author signature + * @param token value set to be redeemed with acknowledgement + * @param grpId group id for cutoff value to be set + * @param CutOff The cut off value to set + */ + void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) + { + return mGxs.setGroupReputationCutOff(token, grpId, CutOff); + } + + RsReputationLevel minReputationForForwardingMessages( + uint32_t group_sign_flags, uint32_t identity_flags ) + { + return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags); + } + + /// @see RsTokenService::requestGroupInfo + bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds, bool high_priority_request = false ) + { + TokenRequestType token_request_type; + + switch(opts.mReqType) + { + case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; + case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; + case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; + default: + RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; + return false; + } + + cancelActiveRequestTokens(token_request_type); + + if( mTokenService.requestGroupInfo(token, 0, opts, groupIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + else + return false; + } + + /// @see RsTokenService::requestGroupInfo + bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts, bool high_priority_request = false) + { + TokenRequestType token_request_type; + + switch(opts.mReqType) + { + case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; + case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; + case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; + default: + RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; + return false; + } + + cancelActiveRequestTokens(token_request_type); + + + if( mTokenService.requestGroupInfo(token, 0, opts)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + else + return false; + } + + /// @see RsTokenService::requestMsgInfo + bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const GxsMsgReq& msgIds ) + { + if(mTokenService.requestMsgInfo(token, 0, opts, msgIds)) + { + RS_STACK_MUTEX(mMtx); + + mActiveTokens[token]= (msgIds.size()==1 && msgIds.begin()->second.size()==0) ?(TokenRequestType::ALL_POSTS):(TokenRequestType::POSTS); +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + else + return false; + } + + /// @see RsTokenService::requestMsgInfo + bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list& grpIds ) + { + if(mTokenService.requestMsgInfo(token, 0, opts, grpIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::ALL_POSTS; +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + else + return false; + } + + /// @see RsTokenService::requestMsgRelatedInfo + bool requestMsgRelatedInfo( + uint32_t& token, const RsTokReqOptions& opts, + const std::vector& msgIds ) + { + if( mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::MSG_RELATED_INFO; +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + else + return false; + } + + /** + * @jsonapi{development} + * @param[in] token + */ + RsTokenService::GxsRequestStatus requestStatus(uint32_t token) + { return mTokenService.requestStatus(token); } + + /// @see RsTokenService::requestServiceStatistic + bool requestServiceStatistic(uint32_t& token) + { + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_SERVICE_STATS; + + mTokenService.requestServiceStatistic(token,opts); + + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS; + +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + + /// @see RsTokenService::requestGroupStatistic + bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) + { + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_STATS; + + mTokenService.requestGroupStatistic(token, grpId,opts); + + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS; +#ifdef DEBUG_GXSIFACEHELPER + locked_dumpTokens(); +#endif + return true; + } + + bool cancelActiveRequestTokens(TokenRequestType type) + { + RS_STACK_MUTEX(mMtx); + for(auto it = mActiveTokens.begin();it!=mActiveTokens.end();) + if(it->second == type) + { + mTokenService.cancelRequest(it->first); + it = mActiveTokens.erase(it); + } + else + ++it; + + return true; + } + + /// @see RsTokenService::cancelRequest + bool cancelRequest(uint32_t token) + { + { + RS_STACK_MUTEX(mMtx); + mActiveTokens.erase(token); + } + return mTokenService.cancelRequest(token); + } + + /** + * @deprecated + * Token service methods are already exposed by this helper, so you should + * not need to get token service pointer directly anymore. + */ + RS_DEPRECATED RsTokenService* getTokenService() { return &mTokenService; } + +protected: + /** + * Block caller while request is being processed. + * Useful for blocking API implementation. + * @param[in] token token associated to the request caller is waiting for + * @param[in] maxWait maximum waiting time in milliseconds + * @param[in] checkEvery time in millisecond between status checks + * @param[in] auto_delete_if_unsuccessful delete the request when it fails. This avoid leaving useless pending requests in the queue that would slow down additional calls. + */ + RsTokenService::GxsRequestStatus waitToken( + uint32_t token, + std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000), + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), + bool auto_delete_if_unsuccessful=true) + { +#if defined(__ANDROID__) && (__ANDROID_API__ < 24) + auto wkStartime = std::chrono::steady_clock::now(); + int maxWorkAroundCnt = 10; +LLwaitTokenBeginLabel: +#endif + auto timeout = std::chrono::steady_clock::now() + maxWait; + auto st = requestStatus(token); + + while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) + && std::chrono::steady_clock::now() < timeout ) + { + std::this_thread::sleep_for(checkEvery); + st = requestStatus(token); + } + if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) + cancelRequest(token); + +#if defined(__ANDROID__) && (__ANDROID_API__ < 24) + /* Work around for very slow/old android devices, we don't expect this + * to be necessary on newer devices. If it take unreasonably long + * something worser is already happening elsewere and we return anyway. + */ + if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE + && maxWorkAroundCnt-- > 0 ) + { + maxWait *= 10; + checkEvery *= 3; + Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " + << " workaround st: " << st + << " maxWorkAroundCnt: " << maxWorkAroundCnt + << " maxWait: " << maxWait.count() + << " checkEvery: " << checkEvery.count() << std::endl; + goto LLwaitTokenBeginLabel; + } + Dbg3() << __PRETTY_FUNCTION__ << " lasted: " + << std::chrono::duration_cast( + std::chrono::steady_clock::now() - wkStartime ).count() + << "ms" << std::endl; + +#endif + + { + RS_STACK_MUTEX(mMtx); + mActiveTokens.erase(token); + } + + return st; + } + +private: + RsGxsIface& mGxs; + RsTokenService& mTokenService; + RsMutex mMtx; + + std::map mActiveTokens; + +#ifdef DEBUG_GXSIFACEHELPER + void locked_dumpTokens() + { + const uint16_t service_id = mGxs.serviceType(); + const auto countSize = static_cast(TokenRequestType::__MAX); + uint32_t count[countSize] = {0}; + + RsDbg rsdbg; + rsdbg << __PRETTY_FUNCTION__ << " Service 0x" << std::hex << service_id + << " (" << rsServiceControl->getServiceName( + RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id) ) + << ") this=0x" << static_cast(this) + << ") Active tokens (per type): "; + + // let's count how many token of each type we've got. + for(auto& it: mActiveTokens) ++count[static_cast(it.second)]; + + for(uint32_t i=0; i < countSize; ++i) + rsdbg /* << i << ":" */ << count[i] << " "; + } +#endif // def DEBUG_GXSIFACEHELPER + + RS_SET_CONTEXT_DEBUG_LEVEL(1) +}; From 2ed150072484048721b8f4bf19bea84ee9f68270 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 3 Sep 2021 15:25:21 +0200 Subject: [PATCH 151/697] Improve debuggability of failed CI Separate ubuntu build and testing stages --- .gitlab-ci.yml | 75 ++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 58dc03d1b..a3be771bd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,32 +1,49 @@ image: docker:stable services: - - docker:stable-dind + - docker:stable-dind + +stages: + - build + - test workflow: rules: - if: $CI_MERGE_REQUEST_ID - if: $CI_COMMIT_BRANCH -build-and-test: +variables: + REPO_ARGS_CMD: '[ -n "$CI_MERGE_REQUEST_ID" ] && echo --build-arg REPO_URL=\"$CI_MERGE_REQUEST_SOURCE_PROJECT_URL\" --build-arg REPO_BRANCH=\"$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME\" || echo --build-arg REPO_URL=\"$CI_REPOSITORY_URL\" --build-arg REPO_BRANCH=\"$CI_COMMIT_BRANCH\"' + UBUNTU_TESTING_IMAGE_TAG: "$CI_REGISTRY_IMAGE/gitlabci_outputs/ubuntu_testing:$CI_COMMIT_SHA" + +build-ubuntu-test-image: + stage: build script: - - > - if [ -n "$CI_MERGE_REQUEST_ID" ]; then - REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; - else - REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; - fi ; - export REPO_ARGS ; - echo REPO_ARGS=$REPO_ARGS ; + - > + docker login "$CI_REGISTRY" + --username "$CI_REGISTRY_USER" + --password "$CI_REGISTRY_PASSWORD" - mkdir Dockercontext - > - docker build -t retroshare:testing $REPO_ARGS + docker build + -t $UBUNTU_TESTING_IMAGE_TAG + $($REPO_ARGS_CMD) --file $CI_PROJECT_DIR/build_scripts/GitlabCI/gitlabCI.Dockerfile Dockercontext + - docker push $UBUNTU_TESTING_IMAGE_TAG + - echo UBUNTU_TESTING_IMAGE_TAG=$UBUNTU_TESTING_IMAGE_TAG + +test-ubuntu: + stage: test + script: + - > + docker login "$CI_REGISTRY" + --username "$CI_REGISTRY_USER" + --password "$CI_REGISTRY_PASSWORD" + - echo UBUNTU_TESTING_IMAGE_TAG=$UBUNTU_TESTING_IMAGE_TAG + - docker pull $UBUNTU_TESTING_IMAGE_TAG - > - docker run --name retroshare --detach --tty retroshare:testing + docker run --name retroshare --detach --tty $UBUNTU_TESTING_IMAGE_TAG retroshare-service --jsonApiPort 9092 - apk add jq - > @@ -51,24 +68,13 @@ build-and-test: docker exec retroshare curl --verbose http://127.0.0.1:9092/rsMsgs/getChatLobbyList | jq - docker container stop retroshare - + build-android-arm-apk: + stage: build script: - - > - if [ -n "$CI_MERGE_REQUEST_ID" ]; then - REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; - else - REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; - fi ; - export REPO_ARGS ; - echo REPO_ARGS=$REPO_ARGS ; - mkdir Dockercontext - > - docker build -t retroshare:android_arm_latest $REPO_ARGS - --build-arg ANDROID_PLATFORM_VER=16 - --build-arg ANDROID_NDK_ARCH=arm + docker build -t retroshare:android_arm_latest $($REPO_ARGS_CMD) --file $CI_PROJECT_DIR/build_scripts/GitlabCI/Android.Dockerfile Dockercontext # see https://stackoverflow.com/a/59055906 @@ -82,20 +88,11 @@ build-android-arm-apk: # Use separate runner to avoid no space left on device build-android-arm64-apk: + stage: build script: - - > - if [ -n "$CI_MERGE_REQUEST_ID" ]; then - REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; - else - REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; - fi ; - export REPO_ARGS ; - echo REPO_ARGS=$REPO_ARGS ; - mkdir Dockercontext - > - docker build -t retroshare:android_arm64_latest $REPO_ARGS + docker build -t retroshare:android_arm64_latest $($REPO_ARGS_CMD) --build-arg ANDROID_PLATFORM_VER=21 --build-arg ANDROID_NDK_ARCH=arm64 --file $CI_PROJECT_DIR/build_scripts/GitlabCI/Android.Dockerfile From e6d3ee978b33e05403a44d11e670e7ca595c5fd6 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 5 Sep 2021 18:11:58 +0200 Subject: [PATCH 152/697] Fixes crash after: (EE) asked to create an invalidated profile that already exists createInvalidatedProfile returned with iterator.end() in some cases. updateInternalData dereferenced the result without checking it first. It overindexed an array, read some memory trash, then wrote it into an another array. --- retroshare-gui/src/gui/common/FriendListModel.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index 9d2bfa50b..1b83485bc 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -1052,7 +1052,12 @@ std::map::const_iterator RsFriendListModel::createInvalidatedP if(rsPeers->getGPGDetails(pgp_id,hprof.profile_info)) { - std::cerr << "(EE) asked to create an invalidated profile that already exists!" << std::endl; + std::cerr << "(EE) asked to create an invalidated profile that already exists: " << pgp_id << std::endl; + + pgp_indices[pgp_id] = mProfiles.size(); + mProfiles.push_back(hprof); + it2 = pgp_indices.find(pgp_id); + return it2; } From 154148d77fa3b9de65c76b605703b674582fb02c Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 5 Sep 2021 19:43:07 +0200 Subject: [PATCH 153/697] Fix to not allow empty profile names on profile creation --- retroshare-gui/src/gui/GenCertDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e106146fb..e77095526 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -407,7 +407,7 @@ void GenCertDialog::updateCheckLabels() ui.node_name_check_LB ->setPixmap(bad) ; } - if(!generate_new || ui.name_input->text().length() >= 3) + if(!generate_new || ui.name_input->text().trimmed().length() >= 3) ui.profile_name_check_LB ->setPixmap(good) ; else { From 099113805eb49b8f1389e5ff2f17da96864e5650 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 8 Sep 2021 09:03:46 +0200 Subject: [PATCH 154/697] added missing internal change of webUI directory --- retroshare-gui/src/gui/settings/WebuiPage.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/retroshare-gui/src/gui/settings/WebuiPage.cpp b/retroshare-gui/src/gui/settings/WebuiPage.cpp index 8bdc11146..f0006fec3 100644 --- a/retroshare-gui/src/gui/settings/WebuiPage.cpp +++ b/retroshare-gui/src/gui/settings/WebuiPage.cpp @@ -65,6 +65,9 @@ void WebuiPage::selectWebInterfaceDirectory() return; whileBlocking(ui.webInterfaceFiles_LE)->setText(dirname); + + QString S; + updateParams(S); } bool WebuiPage::updateParams(QString &errmsg) @@ -82,6 +85,8 @@ bool WebuiPage::updateParams(QString &errmsg) // store config Settings->setWebinterfaceEnabled(ui.enableWebUI_CB->isChecked()); Settings->setWebinterfaceFilesDirectory(ui.webInterfaceFiles_LE->text()); + + rsWebUi->setHtmlFilesDirectory(ui.webInterfaceFiles_LE->text().toStdString()); } return ok; } @@ -196,6 +201,9 @@ void WebuiPage::onApplyClicked() { rsWebUi->setUserPassword(ui.password_LE->text().toStdString()); + QString errmsg; + updateParams(errmsg); + if(!restart()) { QMessageBox::warning(0, tr("failed to start Webinterface"), "Failed to start the webinterface."); From 2bd3fbf977bec600b78cc69cb48736d2561c4d67 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Sep 2021 20:05:19 +0200 Subject: [PATCH 155/697] made Options tab in Profiles Details window be disabled when the profile is not a friend --- retroshare-gui/src/gui/connect/PGPKeyDialog.cpp | 4 ++++ retroshare-gui/src/gui/connect/PGPKeyDialog.ui | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp b/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp index b167ca1ed..cc86593c4 100644 --- a/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp +++ b/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp @@ -45,6 +45,8 @@ #include "util/DateTime.h" #include "util/misc.h" +#define FRIEND_OPTIONS_TAB_INDEX 2 + QMap PGPKeyDialog::instances_pgp; PGPKeyDialog *PGPKeyDialog::instance(const RsPgpId& pgp_id) @@ -199,11 +201,13 @@ void PGPKeyDialog::load() { ui.make_friend_button->hide(); ui.denyFriendButton->show(); + ui.stabWidget->setTabEnabled(FRIEND_OPTIONS_TAB_INDEX,true); } else { ui.make_friend_button->show(); ui.denyFriendButton->hide(); + ui.stabWidget->setTabEnabled(FRIEND_OPTIONS_TAB_INDEX,false); } //web of trust diff --git a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui index 04b891fdf..d65df4758 100644 --- a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui +++ b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui @@ -393,7 +393,7 @@ p, li { white-space: pre-wrap; } - Options + Friend options From 9a440e077e8bd442fb92fa56cc68483ef5a4809d Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 21 Sep 2021 20:47:25 +0200 Subject: [PATCH 156/697] automatically close ongoing uploads when we stop sharing an extra file --- libretroshare/src/ft/ftcontroller.cc | 5 +++++ libretroshare/src/ft/ftcontroller.h | 1 + libretroshare/src/ft/ftdatamultiplex.cc | 17 +++++++++++++++++ libretroshare/src/ft/ftdatamultiplex.h | 6 +++--- libretroshare/src/ft/ftserver.cc | 5 ++++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 1dc0b1dad..b43139911 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -1541,6 +1541,11 @@ std::string ftController::getPartialsDirectory() return mPartialsPath; } +bool ftController::FileServerCancel(const RsFileHash& hash) +{ + RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ + return mDataplex->deleteServer(hash); +} bool ftController::setDestinationDirectory(const RsFileHash& hash,const std::string& dest_dir) { RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ diff --git a/libretroshare/src/ft/ftcontroller.h b/libretroshare/src/ft/ftcontroller.h index e890a83d6..854a3e3a1 100644 --- a/libretroshare/src/ft/ftcontroller.h +++ b/libretroshare/src/ft/ftcontroller.h @@ -157,6 +157,7 @@ public: bool getFileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info); bool setDestinationName(const RsFileHash& hash,const std::string& dest_name) ; bool setDestinationDirectory(const RsFileHash& hash,const std::string& dest_name) ; + bool FileServerCancel(const RsFileHash& hash); // Download speed bool getPriority(const RsFileHash& hash,DwlSpeed& p); diff --git a/libretroshare/src/ft/ftdatamultiplex.cc b/libretroshare/src/ft/ftdatamultiplex.cc index de8f1261c..f4b63be8b 100644 --- a/libretroshare/src/ft/ftdatamultiplex.cc +++ b/libretroshare/src/ft/ftdatamultiplex.cc @@ -1039,6 +1039,23 @@ void ftDataMultiplex::handlePendingCrcRequests() } } +bool ftDataMultiplex::deleteServer(const RsFileHash& hash) +{ + RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ + + auto sit = mServers.find(hash); + + if(sit == mServers.end()) + return false; + + // We don't delete servers that are clients at the same time ! + if(dynamic_cast(sit->second) == NULL) + delete sit->second; + + mServers.erase(sit); + return true; +} + void ftDataMultiplex::deleteUnusedServers() { RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ diff --git a/libretroshare/src/ft/ftdatamultiplex.h b/libretroshare/src/ft/ftdatamultiplex.h index 019940b63..6b15e7617 100644 --- a/libretroshare/src/ft/ftdatamultiplex.h +++ b/libretroshare/src/ft/ftdatamultiplex.h @@ -112,9 +112,9 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread bool FileDownloads(std::list &hashs); bool FileDetails(const RsFileHash &hash, FileSearchFlags hintsflag, FileInfo &info); - void deleteUnusedServers() ; - void handlePendingCrcRequests() ; - + void deleteUnusedServers() ; + bool deleteServer(const RsFileHash& hash); // deletes FtServers for the given hash. Used when removing an extra file from shares. + void handlePendingCrcRequests() ; /*************** SEND INTERFACE (calls ftDataSend) *******************/ diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 07a400acf..e8c7b504d 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -817,7 +817,10 @@ bool ftServer::ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t } bool ftServer::ExtraFileRemove(const RsFileHash& hash) -{ return mFileDatabase->removeExtraFile(hash); } +{ + mFtController->FileServerCancel(hash); + return mFileDatabase->removeExtraFile(hash); +} bool ftServer::ExtraFileHash( std::string localpath, rstime_t period, TransferRequestFlags flags ) { From 75aaf134d2f656272f2d22edd2b47185a489d95b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 30 Sep 2021 13:11:48 +0200 Subject: [PATCH 157/697] CI: fix phash install prefix in base dockerfile --- build_scripts/GitlabCI/base.Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_scripts/GitlabCI/base.Dockerfile b/build_scripts/GitlabCI/base.Dockerfile index f1ad9c5a2..b65ed1776 100644 --- a/build_scripts/GitlabCI/base.Dockerfile +++ b/build_scripts/GitlabCI/base.Dockerfile @@ -25,7 +25,8 @@ RUN apt-get update -y && apt-get upgrade -y -qq && \ RUN git clone --depth 1 https://github.com/aetilius/pHash.git && \ rm -rf pHash-build && mkdir pHash-build && cd pHash-build && \ - cmake -B. -H../pHash && make -j$(nproc) && make install && cd .. && \ + cmake -B. -H../pHash -DCMAKE_INSTALL_PREFIX=/usr && \ + make -j$(nproc) && make install && cd .. && \ rm -rf pHash-build pHash ARG FRESHCLONE=0 From a432b94351cf055554ac123516a3a7f81c9f436d Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 3 Oct 2021 21:41:04 +0200 Subject: [PATCH 158/697] Fix remove friend from group Fix missing update after creating a new group --- retroshare-gui/src/gui/common/NewFriendList.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index ba794fafe..1b0a684a3 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -697,7 +697,7 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() mModel->getGroupData(parent,info); QAction *removeFromGroup = groupsMenu->addAction(tr("Remove from group ")+QString::fromUtf8(info.name.c_str())); - removeFromGroup->setData(parent.sibling(parent.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole)); + removeFromGroup->setData(QString::fromStdString(info.id.toStdString())); connect(removeFromGroup, SIGNAL(triggered()), this, SLOT(removeFromGroup())); } @@ -767,6 +767,7 @@ void NewFriendList::createNewGroup() { CreateGroup createGrpDialog (RsNodeGroupId(), this); createGrpDialog.exec(); + checkInternalData(true); } #ifdef NOT_USED From d97ad8099cc719f88bed9cd594ddf13d9bb69cf5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 9 Oct 2021 01:08:23 +0200 Subject: [PATCH 159/697] added base network layer for friend server. Not working yet. --- RetroShare.pro | 6 ++ libretroshare/src/rsitems/rsserviceids.h | 5 +- retroshare-friendserver/src/friendserver.cc | 32 +++++++ retroshare-friendserver/src/friendserver.h | 42 +++++++++ retroshare-friendserver/src/fsitem.h | 25 ++++++ retroshare-friendserver/src/network.cc | 89 +++++++++++++++++++ retroshare-friendserver/src/network.h | 62 +++++++++++++ .../src/retroshare-friendserver.cc | 61 +++++++++++++ .../src/retroshare-friendserver.pro | 43 +++++++++ retroshare.pri | 5 ++ 10 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 retroshare-friendserver/src/friendserver.cc create mode 100644 retroshare-friendserver/src/friendserver.h create mode 100644 retroshare-friendserver/src/fsitem.h create mode 100644 retroshare-friendserver/src/network.cc create mode 100644 retroshare-friendserver/src/network.h create mode 100644 retroshare-friendserver/src/retroshare-friendserver.cc create mode 100644 retroshare-friendserver/src/retroshare-friendserver.pro diff --git a/RetroShare.pro b/RetroShare.pro index dc590dd17..58ae659ab 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -55,6 +55,12 @@ retroshare_service { retroshare_service.target = retroshare_service } +retroshare_friendserver { + SUBDIRS += retroshare_friendserver + retroshare_friendserver.file = retroshare-friendserver/src/retroshare-friendserver.pro + retroshare_friendserver.depends = libretroshare + retroshare_friendserver.target = retroshare_friendserver +} retroshare_plugins { SUBDIRS += plugins plugins.file = plugins/plugins.pro diff --git a/libretroshare/src/rsitems/rsserviceids.h b/libretroshare/src/rsitems/rsserviceids.h index ead349e32..693a1b149 100644 --- a/libretroshare/src/rsitems/rsserviceids.h +++ b/libretroshare/src/rsitems/rsserviceids.h @@ -49,7 +49,8 @@ enum class RsServiceType : uint16_t GXS_TUNNEL = 0x0028, BANLIST = 0x0101, STATUS = 0x0102, - NXS = 0x0200, + FRIEND_SERVER = 0x0103, + NXS = 0x0200, GXSID = 0x0211, PHOTO = 0x0212, WIKI = 0x0213, @@ -109,6 +110,8 @@ RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102; +RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_FRIEND_SERVER = 0x0103; + /// Rs Network Exchange Service RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_NXS = 0x0200; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_GXSID = 0x0211; diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc new file mode 100644 index 000000000..10584d401 --- /dev/null +++ b/retroshare-friendserver/src/friendserver.cc @@ -0,0 +1,32 @@ +#include "util/rsdebug.h" + +#include "friendserver.h" +#include "fsitem.h" + +void FriendServer::threadTick() +{ + // Listen to the network interface, capture incoming data etc. + + std::this_thread::sleep_for(std::chrono::seconds(1)); +} + +FriendServer::FriendServer(const std::string& base_dir) +{ + RsDbg() << "Creating friend server." << std::endl; + mBaseDirectory = base_dir; +} + +void FriendServer::run() +{ + // 1 - create network interface. + + mni = new FsNetworkInterface; + + RsSerialiser *rss = new RsSerialiser ; + rss->addSerialType(new FsSerializer) ; + + pqi = new pqistreamer(rss, RsPeerId(), mni,BIN_FLAGS_READABLE); + + while(!shouldStop()) { threadTick() ; } +} + diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h new file mode 100644 index 000000000..0be516508 --- /dev/null +++ b/retroshare-friendserver/src/friendserver.h @@ -0,0 +1,42 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#pragma once + +#include "util/rsthreads.h" +#include "pqi/pqistreamer.h" + +#include "network.h" + +class FriendServer : public RsTickingThread +{ + public: + FriendServer(const std::string& base_directory); + + private: + virtual void threadTick() override; + virtual void run() override; + + FsNetworkInterface *mni; + pqistreamer *pqi; + + std::string mBaseDirectory; +}; diff --git a/retroshare-friendserver/src/fsitem.h b/retroshare-friendserver/src/fsitem.h new file mode 100644 index 000000000..ff03be4f9 --- /dev/null +++ b/retroshare-friendserver/src/fsitem.h @@ -0,0 +1,25 @@ +#include "serialiser/rsserial.h" +#include "serialiser/rsserializer.h" + +#include "rsitems/rsitem.h" +#include "rsitems/rsserviceids.h" +#include "rsitems/itempriorities.h" + +class FsItem: public RsItem +{ +public: + FsItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_FRIEND_SERVER,item_subtype) + { + setPriorityLevel(QOS_PRIORITY_DEFAULT) ; + } + + virtual ~FsItem() {} + virtual void clear() {} +}; + +struct FsSerializer : RsServiceSerializer +{ + FsSerializer(RsSerializationFlags flags = RsSerializationFlags::NONE): RsServiceSerializer(RS_SERVICE_TYPE_FRIEND_SERVER, flags) {} + + virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const {}; +}; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc new file mode 100644 index 000000000..5aab08cae --- /dev/null +++ b/retroshare-friendserver/src/network.cc @@ -0,0 +1,89 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util/rsnet.h" +#include "util/rsprint.h" +#include "util/rsdebug.h" + +#include "network.h" + +FsNetworkInterface::FsNetworkInterface() +{ + mClintListn = 0; + start(); +} +void FsNetworkInterface::start() +{ + struct sockaddr_in ipOfServer; + + mClintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket + + memset(&ipOfServer, '0', sizeof(ipOfServer)); + + ipOfServer.sin_family = AF_INET; + ipOfServer.sin_addr.s_addr = htonl(INADDR_ANY); + ipOfServer.sin_port = htons(2017); // this is the port number of running server + + bind(mClintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)); + listen(mClintListn , 20); + + RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) << std::endl; +} + +int FsNetworkInterface::close() +{ + RsDbg() << "Stopping network interface" << std::endl; + return 1; +} + +int FsNetworkInterface::tick() +{ + int clintConnt = accept(mClintListn, (struct sockaddr*)NULL, NULL); + + char inBuffer[1025]; + int readbytes = read(clintConnt, inBuffer, strlen(inBuffer)); + + ::close(clintConnt); + + // display some debug info + + if(readbytes > 0) + { + RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; + RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + } + else + std::this_thread::sleep_for(std::chrono::seconds(1)); + + return true; +} + diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h new file mode 100644 index 000000000..8417927e8 --- /dev/null +++ b/retroshare-friendserver/src/network.h @@ -0,0 +1,62 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#pragma once + +#include "util/rsthreads.h" +#include "pqi/pqi_base.h" + +class FsNetworkInterface: public BinInterface +{ +public: + FsNetworkInterface() ; + + void start() ; + + // Implements BinInterface methods + + virtual int tick() override; + + virtual int senddata(void *data, int len) override; + virtual int readdata(void *data, int len) override; + + virtual int netstatus() override; + virtual int isactive() override; + virtual bool moretoread(uint32_t usec) override; + virtual bool cansend(uint32_t usec) override; + + virtual int close() override; + + /** + * If hashing data + **/ + virtual RsFileHash gethash() override { return RsFileHash() ; } + virtual uint64_t bytecount() override { return mTotalBytes; } + + virtual bool bandwidthLimited() override { return false; } +private: + + void initListening(); + void stopListening(); + + int mClintListn ; + uint64_t mTotalBytes; +}; diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc new file mode 100644 index 000000000..1be8e1f4e --- /dev/null +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -0,0 +1,61 @@ +/* + * RetroShare Service + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "util/stacktrace.h" +#include "util/argstream.h" +#include "util/rstime.h" +#include "util/rsdebug.h" + +#include "friendserver.h" + +int main(int argc, char* argv[]) +{ + RsInfo() << "\n" << + "+================================================================+\n" + "| o---o o |\n" + "| \\ / - Retroshare Friend Server - / \\ |\n" + "| o o---o |\n" + "+================================================================+" + << std::endl << std::endl; + + //RsInit::InitRsConfig(); + //RsControl::earlyInitNotificationSystem(); + + std::string base_directory; + + argstream as(argc,argv); + + as >> parameter( 'c',"base-dir", base_directory, "directory", "Set base directory.", false ) + >> help( 'h', "help", "Display this Help" ); + + as.defaultErrorHandling(true, true); + + // Now start the real thing. + + FriendServer fs(base_directory); + fs.start(); + + while(fs.isRunning()) + std::this_thread::sleep_for(std::chrono::seconds(1)); + + return 0; +} + diff --git a/retroshare-friendserver/src/retroshare-friendserver.pro b/retroshare-friendserver/src/retroshare-friendserver.pro new file mode 100644 index 000000000..79986b461 --- /dev/null +++ b/retroshare-friendserver/src/retroshare-friendserver.pro @@ -0,0 +1,43 @@ +# RetroShare service qmake build script +# +# Copyright (C) 2021-2021, retroshare team +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see . +# +# SPDX-FileCopyrightText: Retroshare Team +# SPDX-License-Identifier: AGPL-3.0-or-later + +!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") + +TARGET = retroshare-friendserver + +!include("../../libretroshare/src/use_libretroshare.pri"):error("Including") + +SOURCES += retroshare-friendserver.cc \ + friendserver.cc \ + network.cc + +HEADERS += friendserver.h \ + network.h \ + fsitem.h + +################################# Linux ########################################## + +unix { + target.path = "$${RS_BIN_DIR}" + INSTALLS += target +} + +################################### COMMON stuff ################################## + diff --git a/retroshare.pri b/retroshare.pri index 8e59df32d..3fcad4a78 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -50,6 +50,11 @@ retroshare_plugins:CONFIG -= no_retroshare_plugins CONFIG *= retroshare_service no_retroshare_service:CONFIG -= retroshare_service +# To disable RetroShare FriendServer append the following assignation to +# qmake command line "CONFIG+=no_rs_friendserver" +CONFIG *= retroshare_friendserver +no_rs_friendserver:CONFIG -= retroshare_friendserver + # To disable SQLCipher support append the following assignation to qmake # command line "CONFIG+=no_sqlcipher" CONFIG *= sqlcipher From 85bb831f473b47ce6745ac5668dcfaeaea756e26 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 9 Oct 2021 15:06:06 +0200 Subject: [PATCH 160/697] using pqistreamer to deserialize data from FsNetwork --- retroshare-friendserver/src/friendserver.cc | 7 +- retroshare-friendserver/src/network.cc | 123 ++++++++++++++++++-- retroshare-friendserver/src/network.h | 34 +++--- 3 files changed, 138 insertions(+), 26 deletions(-) diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 10584d401..2913aa4a9 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -7,12 +7,14 @@ void FriendServer::threadTick() { // Listen to the network interface, capture incoming data etc. - std::this_thread::sleep_for(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + pqi->tick(); } FriendServer::FriendServer(const std::string& base_dir) { - RsDbg() << "Creating friend server." << std::endl; + RsDbg() << "Creating friend server." ; mBaseDirectory = base_dir; } @@ -21,6 +23,7 @@ void FriendServer::run() // 1 - create network interface. mni = new FsNetworkInterface; + mni->start(); RsSerialiser *rss = new RsSerialiser ; rss->addSerialType(new FsSerializer) ; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index 5aab08cae..a8207d732 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -37,12 +37,14 @@ #include "network.h" FsNetworkInterface::FsNetworkInterface() + : mFsNiMtx(std::string("FsNetworkInterface")) { + RS_STACK_MUTEX(mFsNiMtx); + mClintListn = 0; - start(); -} -void FsNetworkInterface::start() -{ + mTotalReadBytes = 0; + mTotalBufferBytes = 0; + struct sockaddr_in ipOfServer; mClintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket @@ -54,9 +56,9 @@ void FsNetworkInterface::start() ipOfServer.sin_port = htons(2017); // this is the port number of running server bind(mClintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)); - listen(mClintListn , 20); + listen(mClintListn , 40); - RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) << std::endl; + RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) ; } int FsNetworkInterface::close() @@ -65,12 +67,26 @@ int FsNetworkInterface::close() return 1; } +void FsNetworkInterface::threadTick() +{ + tick(); +} + int FsNetworkInterface::tick() { - int clintConnt = accept(mClintListn, (struct sockaddr*)NULL, NULL); + std::cerr << "ticking FsNetworkInterface" << std::endl; + + int clintConnt = accept(mClintListn, (struct sockaddr*)NULL, NULL); // accept is a blocking call! char inBuffer[1025]; - int readbytes = read(clintConnt, inBuffer, strlen(inBuffer)); + memset(inBuffer,0,1025); + + int readbytes = read(clintConnt, inBuffer, sizeof(inBuffer)); + + if(readbytes < 0) + RsErr() << "read() failed. Errno=" << errno ; + + std::cerr << "clintConnt: " << clintConnt << ", readbytes: " << readbytes << std::endl; ::close(clintConnt); @@ -80,10 +96,97 @@ int FsNetworkInterface::tick() { RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + + void *ptr = malloc(readbytes); + + if(!ptr) + throw std::runtime_error("Cannot allocate memory! Go buy some RAM!"); + + memcpy(ptr,inBuffer,readbytes); + + RS_STACK_MUTEX(mFsNiMtx); + in_buffer.push_back(std::make_pair(ptr,readbytes)); + + mTotalBufferBytes += readbytes; + mTotalReadBytes += readbytes; + + RsDbg() << "InBuffer: " << in_buffer.size() << " elements. Total size: " << mTotalBufferBytes << ". Total read: " << mTotalReadBytes ; } - else - std::this_thread::sleep_for(std::chrono::seconds(1)); return true; } +int FsNetworkInterface::senddata(void *, int len) +{ + RsErr() << "Trying to send data through FsNetworkInterface although it's not implemented yet!"<< std::endl; + return false; +} +int FsNetworkInterface::readdata(void *data, int len) +{ + RS_STACK_MUTEX(mFsNiMtx); + + // read incoming bytes in the buffer + + int total_len = 0; + + while(total_len < len) + { + if(in_buffer.empty()) + { + mTotalBufferBytes -= total_len; + return total_len; + } + + // If the remaining buffer is too large, chop of the beginning of it. + + if(total_len + in_buffer.front().second > len) + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,len - total_len); + + void *ptr = malloc(in_buffer.front().second - (len - total_len)); + memcpy(ptr,&(static_cast(in_buffer.front().first)[len - total_len]),in_buffer.front().second - (len - total_len)); + + free(in_buffer.front().first); + in_buffer.front().first = ptr; + in_buffer.front().second -= len-total_len; + + mTotalBufferBytes -= len; + return len; + } + else // copy everything + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,in_buffer.front().second); + + total_len += in_buffer.front().second; + + free(in_buffer.front().first); + in_buffer.pop_front(); + } + } + mTotalBufferBytes -= len; + return len; +} + +int FsNetworkInterface::netstatus() +{ + return 1; // dummy response. +} +int FsNetworkInterface::isactive() +{ + RS_STACK_MUTEX(mFsNiMtx); + return mClintListn > 0; +} +bool FsNetworkInterface::moretoread(uint32_t /* usec */) +{ + RS_STACK_MUTEX(mFsNiMtx); + return mTotalBufferBytes > 0; +} +bool FsNetworkInterface::cansend(uint32_t) +{ + return false; +} + + + + + diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index 8417927e8..e276a8d63 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -24,39 +24,45 @@ #include "util/rsthreads.h" #include "pqi/pqi_base.h" -class FsNetworkInterface: public BinInterface +class FsNetworkInterface: public BinInterface, public RsTickingThread { public: FsNetworkInterface() ; - void start() ; + // Implements RsTickingThread + + void threadTick() override; // Implements BinInterface methods - virtual int tick() override; + int tick() override; - virtual int senddata(void *data, int len) override; - virtual int readdata(void *data, int len) override; + int senddata(void *data, int len) override; + int readdata(void *data, int len) override; - virtual int netstatus() override; - virtual int isactive() override; - virtual bool moretoread(uint32_t usec) override; - virtual bool cansend(uint32_t usec) override; + int netstatus() override; + int isactive() override; + bool moretoread(uint32_t usec) override; + bool cansend(uint32_t usec) override; - virtual int close() override; + int close() override; /** * If hashing data **/ - virtual RsFileHash gethash() override { return RsFileHash() ; } - virtual uint64_t bytecount() override { return mTotalBytes; } + RsFileHash gethash() override { return RsFileHash() ; } + uint64_t bytecount() override { return mTotalReadBytes; } - virtual bool bandwidthLimited() override { return false; } + bool bandwidthLimited() override { return false; } private: + RsMutex mFsNiMtx; void initListening(); void stopListening(); int mClintListn ; - uint64_t mTotalBytes; + uint64_t mTotalReadBytes; + uint64_t mTotalBufferBytes; + + std::list > in_buffer; }; From 5bfa77a0fe7597984ab08699af6174efeffdba3e Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 11 Oct 2021 23:40:22 +0200 Subject: [PATCH 161/697] implemented item serialisation and high level handlign in FS --- retroshare-friendserver/src/friendserver.cc | 32 ++++++ retroshare-friendserver/src/friendserver.h | 22 +++-- retroshare-friendserver/src/fsitem.h | 104 +++++++++++++++++++- 3 files changed, 145 insertions(+), 13 deletions(-) diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 2913aa4a9..644e34fce 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -10,8 +10,40 @@ void FriendServer::threadTick() std::this_thread::sleep_for(std::chrono::milliseconds(200)); pqi->tick(); + + RsItem *item; + + while(nullptr != (item = pqi->GetItem())) + { + RsFriendServerItem *fsitem = dynamic_cast(item); + + if(!fsitem) + { + RsErr() << "Received an item of the wrong type!" ; + + continue; + } + + switch(fsitem->PacketSubType()) + { + case RS_PKT_SUBTYPE_FS_CLIENT_REMOVE: handleClientRemove(dynamic_cast(fsitem)); + break; + case RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH: handleClientPublish(dynamic_cast(fsitem)); + break; + default: ; + } + delete item; + } } +void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *item) +{ + RsDbg() << "Received a client publish item:" << *item ; +} +void FriendServer::handleClientRemove(const RsFriendServerClientRemoveItem *item) +{ + RsDbg() << "Received a client remove item:" << *item ; +} FriendServer::FriendServer(const std::string& base_dir) { RsDbg() << "Creating friend server." ; diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 0be516508..8b7c7f4bc 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -26,17 +26,23 @@ #include "network.h" +class RsFriendServerClientRemoveItem; +class RsFriendServerClientPublishItem; + class FriendServer : public RsTickingThread { - public: - FriendServer(const std::string& base_directory); +public: + FriendServer(const std::string& base_directory); - private: - virtual void threadTick() override; - virtual void run() override; +private: + virtual void threadTick() override; + virtual void run() override; - FsNetworkInterface *mni; - pqistreamer *pqi; + void handleClientRemove(const RsFriendServerClientRemoveItem *item); + void handleClientPublish(const RsFriendServerClientPublishItem *item); - std::string mBaseDirectory; + FsNetworkInterface *mni; + pqistreamer *pqi; + + std::string mBaseDirectory; }; diff --git a/retroshare-friendserver/src/fsitem.h b/retroshare-friendserver/src/fsitem.h index ff03be4f9..d05df9873 100644 --- a/retroshare-friendserver/src/fsitem.h +++ b/retroshare-friendserver/src/fsitem.h @@ -5,21 +5,115 @@ #include "rsitems/rsserviceids.h" #include "rsitems/itempriorities.h" -class FsItem: public RsItem +const uint8_t RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH = 0x01 ; +const uint8_t RS_PKT_SUBTYPE_FS_CLIENT_REMOVE = 0x02 ; +const uint8_t RS_PKT_SUBTYPE_FS_SERVER_RESPONSE = 0x03 ; +const uint8_t RS_PKT_SUBTYPE_FS_SERVER_ENCRYPTED_RESPONSE = 0x04 ; + +class RsFriendServerItem: public RsItem { public: - FsItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_FRIEND_SERVER,item_subtype) + RsFriendServerItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_FRIEND_SERVER,item_subtype) { setPriorityLevel(QOS_PRIORITY_DEFAULT) ; } + virtual void clear() override; - virtual ~FsItem() {} - virtual void clear() {} + virtual ~RsFriendServerItem() {} +}; + +class RsFriendServerClientPublishItem: public RsFriendServerItem +{ +public: + RsFriendServerClientPublishItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH) {} + + void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RS_SERIAL_PROCESS(n_requested_friends); + RS_SERIAL_PROCESS(long_invite); + } + virtual void clear() override + { + long_invite = std::string(); + n_requested_friends=0; + } + + // specific members for that item + + uint32_t n_requested_friends; + std::string long_invite; +}; + +class RsFriendServerClientRemoveItem: public RsFriendServerItem +{ +public: + RsFriendServerClientRemoveItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_CLIENT_REMOVE) {} + + void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) + { + } +}; +class RsFriendServerEncryptedServerResponseItem: public RsFriendServerItem +{ +public: + RsFriendServerEncryptedServerResponseItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_SERVER_ENCRYPTED_RESPONSE) {} + + void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RsTypeSerializer::RawMemoryWrapper prox(bin_data, bin_len); + RsTypeSerializer::serial_process(j, ctx, prox, "data"); + } + + virtual void clear() override + { + free(bin_data); + bin_len = 0; + bin_data = nullptr; + } + // + + void *bin_data; + uint32_t bin_len; +}; + +class RsFriendServerServerResponseItem: public RsFriendServerItem +{ +public: + RsFriendServerServerResponseItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_SERVER_RESPONSE) {} + + void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RS_SERIAL_PROCESS(friend_invites); + } + + virtual void clear() override + { + friend_invites.clear(); + } + // specific members for that item + + std::map friend_invites; }; struct FsSerializer : RsServiceSerializer { FsSerializer(RsSerializationFlags flags = RsSerializationFlags::NONE): RsServiceSerializer(RS_SERVICE_TYPE_FRIEND_SERVER, flags) {} - virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const {}; + virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const + { + if(service_id != static_cast(RsServiceType::FRIEND_SERVER)) + return nullptr; + + switch(item_sub_id) + { + case RS_PKT_SUBTYPE_FS_CLIENT_REMOVE: return new RsFriendServerClientRemoveItem(); + case RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH: return new RsFriendServerClientPublishItem(); + case RS_PKT_SUBTYPE_FS_SERVER_RESPONSE: return new RsFriendServerServerResponseItem(); + case RS_PKT_SUBTYPE_FS_SERVER_ENCRYPTED_RESPONSE: return new RsFriendServerEncryptedServerResponseItem(); + default: + RsErr() << "Unknown subitem type " << item_sub_id << " in FsSerialiser" ; + return nullptr; + } + + } }; From 3f6503dfc344444a137c9d668231704e7ab050f6 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 12 Oct 2021 22:29:36 +0200 Subject: [PATCH 162/697] added friend server control UI --- .../src/gui/FriendServerControl.cpp | 41 +++++++ retroshare-gui/src/gui/FriendServerControl.h | 34 ++++++ retroshare-gui/src/gui/FriendServerControl.ui | 103 ++++++++++++++++++ retroshare-gui/src/gui/FriendsDialog.cpp | 2 + retroshare-gui/src/gui/FriendsDialog.h | 4 +- retroshare-gui/src/retroshare-gui.pro | 3 + 6 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 retroshare-gui/src/gui/FriendServerControl.cpp create mode 100644 retroshare-gui/src/gui/FriendServerControl.h create mode 100644 retroshare-gui/src/gui/FriendServerControl.ui diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp new file mode 100644 index 000000000..d4ab1dc5c --- /dev/null +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * gui/FriendServer.cpp * + * * + * Copyright (c) 2021 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "FriendServerControl.h" +//#include + +#include + +/** Constructor */ +FriendServerControl::FriendServerControl(QWidget *parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + +// /* Hide Settings frame */ +// connect( ui.maxFriendLevelSB, SIGNAL(valueChanged(int)), this, SLOT(setMaxFriendLevel(int))); +// connect( ui.edgeLengthSB, SIGNAL(valueChanged(int)), this, SLOT(setEdgeLength(int))); +// connect( ui.freezeCheckBox, SIGNAL(toggled(bool)), this, SLOT(setFreezeState(bool))); +// connect( ui.nameBox, SIGNAL(textChanged(QString)), this, SLOT(setNameSearch(QString))); +} + +FriendServerControl::~FriendServerControl() +{ +} diff --git a/retroshare-gui/src/gui/FriendServerControl.h b/retroshare-gui/src/gui/FriendServerControl.h new file mode 100644 index 000000000..ecdbce756 --- /dev/null +++ b/retroshare-gui/src/gui/FriendServerControl.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * gui/NetworkView.h * + * * + * Copyright (c) 2008 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#pragma once + +#include + +#include "ui_FriendServerControl.h" + +class FriendServerControl : public QWidget, public Ui::FriendServerControl +{ + Q_OBJECT + + public: + FriendServerControl(QWidget *parent = 0); + virtual ~FriendServerControl(); +}; diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui new file mode 100644 index 000000000..aa699560c --- /dev/null +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -0,0 +1,103 @@ + + + FriendServerControl + + + + 0 + 0 + 620 + 499 + + + + + + + On/Off + + + + + + + + + Friends to request: + + + + + + + 1 + + + 15 + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Server onion address: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 380 + + + + + + + + + diff --git a/retroshare-gui/src/gui/FriendsDialog.cpp b/retroshare-gui/src/gui/FriendsDialog.cpp index 660f13fa7..79338c9f8 100644 --- a/retroshare-gui/src/gui/FriendsDialog.cpp +++ b/retroshare-gui/src/gui/FriendsDialog.cpp @@ -44,6 +44,7 @@ #include "NetworkView.h" #include "NetworkDialog.h" #include "gui/common/NewFriendList.h" +#include "gui/FriendServerControl.h" #include "gui/Identity/IdDialog.h" /* Images for Newsfeed icons */ //#define IMAGE_NEWSFEED "" @@ -90,6 +91,7 @@ FriendsDialog::FriendsDialog(QWidget *parent) : MainPage(parent) ui.tabWidget->setTabPosition(QTabWidget::North); ui.tabWidget->addTab(networkView = new NetworkView(),QIcon(IMAGE_NETWORK2), tr("Network graph")); ui.tabWidget->addTab(networkDialog = new NetworkDialog(),QIcon(IMAGE_PEERS), tr("Keyring")); + ui.tabWidget->addTab(friendServerControl = new FriendServerControl(),QIcon(IMAGE_PEERS), tr("Friend Server")); ui.tabWidget->hideCloseButton(0); ui.tabWidget->hideCloseButton(1); diff --git a/retroshare-gui/src/gui/FriendsDialog.h b/retroshare-gui/src/gui/FriendsDialog.h index bd8979224..7e86669b8 100644 --- a/retroshare-gui/src/gui/FriendsDialog.h +++ b/retroshare-gui/src/gui/FriendsDialog.h @@ -30,6 +30,7 @@ class NetworkDialog; class NetworkView; class IdDialog; class CirclesDialog; +class FriendServerControl; class FriendsDialog : public MainPage { @@ -64,7 +65,8 @@ public: NetworkDialog *networkDialog ; NetworkView *networkView ; - + FriendServerControl *friendServerControl ; + IdDialog *idDialog; private slots: diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 654efd170..46d13d20d 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -424,6 +424,7 @@ HEADERS += rshare.h \ gui/AboutDialog.h \ gui/AboutWidget.h \ gui/NetworkView.h \ + gui/FriendServerControl.h \ gui/FriendsDialog.h \ gui/ServicePermissionDialog.h \ gui/RemoteDirModel.h \ @@ -689,6 +690,7 @@ FORMS += gui/StartDialog.ui \ gui/FileTransfer/BannedFilesDialog.ui \ gui/MainWindow.ui \ gui/NetworkView.ui \ + gui/FriendServerControl.ui \ gui/FriendsDialog.ui \ gui/ShareManager.ui \ # gui/ShareDialog.ui \ @@ -809,6 +811,7 @@ SOURCES += main.cpp \ gui/mainpagestack.cpp \ gui/MainWindow.cpp \ gui/NetworkView.cpp \ + gui/FriendServerControl.cpp \ gui/FriendsDialog.cpp \ gui/ServicePermissionDialog.cpp \ gui/RemoteDirModel.cpp \ From 21ea281df46411ebf787f2043fbf442486918b9c Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 13 Oct 2021 22:50:09 +0200 Subject: [PATCH 163/697] added empty rsFriendServer struct and basic UI functionality --- libretroshare/src/libretroshare.pro | 1 + libretroshare/src/retroshare/rsfriendserver.h | 20 +++++ retroshare-friendserver/src/fsitem.h | 3 +- .../src/gui/FriendServerControl.cpp | 89 +++++++++++++++++-- retroshare-gui/src/gui/FriendServerControl.h | 20 ++++- retroshare-gui/src/gui/FriendServerControl.ui | 44 +++++++++ retroshare-gui/src/gui/FriendsDialog.cpp | 2 +- retroshare-gui/src/gui/settings/ServerPage.ui | 4 +- 8 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 libretroshare/src/retroshare/rsfriendserver.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index da5f25ba4..caaabd0b7 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -145,6 +145,7 @@ PUBLIC_HEADERS = retroshare/rsdisc.h \ retroshare/rsrtt.h \ retroshare/rsconfig.h \ retroshare/rsversion.h \ + retroshare/rsfriendserver.h \ retroshare/rsservicecontrol.h \ retroshare/rsgxsdistsync.h diff --git a/libretroshare/src/retroshare/rsfriendserver.h b/libretroshare/src/retroshare/rsfriendserver.h new file mode 100644 index 000000000..cb516c1df --- /dev/null +++ b/libretroshare/src/retroshare/rsfriendserver.h @@ -0,0 +1,20 @@ +#include +#include +#include "util/rstime.h" + +class RsFriendServer +{ +public: + void start() {} + void stop() {} + + void checkServerAddress_async(const std::string&,uint16_t, const std::function& callback) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + callback(true); + } + void setServerAddress(const std::string&,uint16_t) {} + void setFriendsToRequest(uint32_t) {} +}; + +extern RsFriendServer *rsFriendServer; diff --git a/retroshare-friendserver/src/fsitem.h b/retroshare-friendserver/src/fsitem.h index d05df9873..4714178af 100644 --- a/retroshare-friendserver/src/fsitem.h +++ b/retroshare-friendserver/src/fsitem.h @@ -17,9 +17,8 @@ public: { setPriorityLevel(QOS_PRIORITY_DEFAULT) ; } - virtual void clear() override; - virtual ~RsFriendServerItem() {} + virtual void clear() override {} }; class RsFriendServerClientPublishItem: public RsFriendServerItem diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp index d4ab1dc5c..53091c934 100644 --- a/retroshare-gui/src/gui/FriendServerControl.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -18,24 +18,97 @@ * * *******************************************************************************/ +#include +#include +#include + +#include "retroshare/rsfriendserver.h" + +#include "util/qtthreadsutils.h" +#include "gui/common/FilesDefs.h" + #include "FriendServerControl.h" -//#include #include +RsFriendServer *rsFriendServer = new RsFriendServer; + +#define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" +#define ICON_STATUS_OK ":/images/ledon1.png" + /** Constructor */ FriendServerControl::FriendServerControl(QWidget *parent) { - /* Invoke the Qt Designer generated object setup routine */ - setupUi(this); + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); -// /* Hide Settings frame */ -// connect( ui.maxFriendLevelSB, SIGNAL(valueChanged(int)), this, SLOT(setMaxFriendLevel(int))); -// connect( ui.edgeLengthSB, SIGNAL(valueChanged(int)), this, SLOT(setEdgeLength(int))); -// connect( ui.freezeCheckBox, SIGNAL(toggled(bool)), this, SLOT(setFreezeState(bool))); -// connect( ui.nameBox, SIGNAL(textChanged(QString)), this, SLOT(setNameSearch(QString))); + mConnectionCheckTimer = new QTimer; + + QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress())); + QObject::connect(torServerAddress_LE,SIGNAL(textChanged(const QString&)),this,SLOT(onOnionAddressEdit(const QString&))); + + mCheckingServerMovie = new QMovie(":/images/loader/circleball-16.gif"); + + updateFriendServerStatusIcon(false); } FriendServerControl::~FriendServerControl() { + delete mCheckingServerMovie; + delete mConnectionCheckTimer; } + +void FriendServerControl::onOnOffClick(bool b) +{ + if(b) + rsFriendServer->start(); + else + rsFriendServer->stop(); +} + +void FriendServerControl::onOnionAddressEdit(const QString&) +{ + // Setup timer to auto-check the friend server address + + mConnectionCheckTimer->stop(); + mConnectionCheckTimer->setSingleShot(true); + mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time. + + mConnectionCheckTimer->start(); + + serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); + mCheckingServerMovie->start(); +} + +void FriendServerControl::checkServerAddress() +{ + rsFriendServer->checkServerAddress_async(torServerAddress_LE->text().toStdString(),torServerPort_SB->value(), + [this](bool test_result) + { + RsQThreadUtils::postToObject( [=]() { updateFriendServerStatusIcon(test_result); },this); + } + ); +} + +void FriendServerControl::onNbFriendsToRequestsChanged(int n) +{ + rsFriendServer->setFriendsToRequest(n); +} + +void FriendServerControl::updateFriendServerStatusIcon(bool ok) +{ + if(ok) + { + torServerStatus_LB->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; + torServerStatus_LB->setToolTip(tr("Friend server is currently reachable.")) ; + } + else + { + torServerStatus_LB->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + torServerStatus_LB->setToolTip(tr("The proxy is not enabled or broken.\nAre all services up and running fine??\nAlso check your ports!")) ; + } + mCheckingServerMovie->stop(); +} + + + diff --git a/retroshare-gui/src/gui/FriendServerControl.h b/retroshare-gui/src/gui/FriendServerControl.h index ecdbce756..76cbb5b28 100644 --- a/retroshare-gui/src/gui/FriendServerControl.h +++ b/retroshare-gui/src/gui/FriendServerControl.h @@ -26,9 +26,21 @@ class FriendServerControl : public QWidget, public Ui::FriendServerControl { - Q_OBJECT + Q_OBJECT - public: - FriendServerControl(QWidget *parent = 0); - virtual ~FriendServerControl(); +public: + FriendServerControl(QWidget *parent = 0); + virtual ~FriendServerControl(); + +protected slots: + void onOnOffClick(bool b); + void onOnionAddressEdit(const QString&); + void onNbFriendsToRequestsChanged(int n); + void checkServerAddress(); + +private: + void updateFriendServerStatusIcon(bool ok); + + QTimer *mConnectionCheckTimer; + QMovie *mCheckingServerMovie; }; diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui index aa699560c..681399c15 100644 --- a/retroshare-gui/src/gui/FriendServerControl.ui +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -74,6 +74,13 @@ + + + + + + + @@ -83,6 +90,43 @@
+ + + + + + Server port: + + + + + + + 1025 + + + 65536 + + + 1729 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/retroshare-gui/src/gui/FriendsDialog.cpp b/retroshare-gui/src/gui/FriendsDialog.cpp index 79338c9f8..5e896af02 100644 --- a/retroshare-gui/src/gui/FriendsDialog.cpp +++ b/retroshare-gui/src/gui/FriendsDialog.cpp @@ -89,9 +89,9 @@ FriendsDialog::FriendsDialog(QWidget *parent) : MainPage(parent) ui.avatar->setFrameType(AvatarWidget::STATUS_FRAME); ui.tabWidget->setTabPosition(QTabWidget::North); + ui.tabWidget->addTab(friendServerControl = new FriendServerControl(),QIcon(IMAGE_PEERS), tr("Friend Server")); ui.tabWidget->addTab(networkView = new NetworkView(),QIcon(IMAGE_NETWORK2), tr("Network graph")); ui.tabWidget->addTab(networkDialog = new NetworkDialog(),QIcon(IMAGE_PEERS), tr("Keyring")); - ui.tabWidget->addTab(friendServerControl = new FriendServerControl(),QIcon(IMAGE_PEERS), tr("Friend Server")); ui.tabWidget->hideCloseButton(0); ui.tabWidget->hideCloseButton(1); diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 5ef7308b1..4cc8cf568 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -6,8 +6,8 @@ 0 0 - 712 - 502 + 738 + 540 From 34593d1b6f7efe7bfb05e32b18a97ce43d6e169b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 14 Jul 2021 20:36:34 +0200 Subject: [PATCH 164/697] Emit an event when a shared file hashing complete Properly notify when a shared file has been hashed Deprecate event with arbitrary data packed in std::string --- libretroshare/src/file_sharing/hash_cache.cc | 25 ++++++++++------- libretroshare/src/retroshare/rsevents.h | 11 +++++--- libretroshare/src/retroshare/rsfiles.h | 28 +++++++++++++++++++- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/file_sharing/hash_cache.cc b/libretroshare/src/file_sharing/hash_cache.cc index 331f1a481..62924d70a 100644 --- a/libretroshare/src/file_sharing/hash_cache.cc +++ b/libretroshare/src/file_sharing/hash_cache.cc @@ -187,9 +187,10 @@ void HashStorage::threadTick() else rs_sprintf(tmpout, "%lu/%lu (%s - %d%%) : %s", (unsigned long int)mHashCounter+1, (unsigned long int)mTotalFilesToHash, friendlyUnit(mTotalHashedSize).c_str(), int(mTotalHashedSize/double(mTotalSizeToHash)*100.0), job.full_path.c_str()) ; - //RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_HASH_FILE, tmpout) ; - if(rsEvents) { + /* Emit deprecated event only for retrocompatibility + * TODO: create a proper event with structured data instead of a + * formatted string */ auto ev = std::make_shared(); ev->mEventCode = RsSharedDirectoriesEventCode::HASHING_FILE; ev->mMessage = tmpout; @@ -198,7 +199,7 @@ void HashStorage::threadTick() double seconds_origin = rstime::RsScopeTimer::currentTime() ; - if(RsDirUtil::getFileHash(job.full_path, hash,size, this)) + if(RsDirUtil::getFileHash(job.full_path, hash, size, this)) { // store the result @@ -218,8 +219,7 @@ void HashStorage::threadTick() mChanged = true ; mTotalHashedSize += size ; } - else - std::cerr << "ERROR: cannot hash file " << job.full_path << std::endl; + else RS_ERR("Failure hashing file: ", job.full_path); mHashingTime += rstime::RsScopeTimer::currentTime() - seconds_origin ; mHashedBytes += size ; @@ -233,11 +233,18 @@ void HashStorage::threadTick() ++mHashCounter ; } - } - // call the client + } - if(!hash.isNull()) - job.client->hash_callback(job.client_param, job.full_path, hash, size); + // call the client + if(!hash.isNull()) + job.client->hash_callback(job.client_param, job.full_path, hash, size); + + /* Notify we completed hashing a file */ + auto ev = std::make_shared(); + ev->mFilePath = job.full_path; + ev->mHashingSpeed = mCurrentHashingSpeed; + ev->mFileHash = hash; + rsEvents->postEvent(ev); } bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_t mod_time,RsFileHash& known_hash,HashStorageClient *c,uint32_t client_param) diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index ec2e7b97f..9b9fbf106 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -91,8 +91,8 @@ enum class RsEventType : uint32_t /// @see RsGxsPostedEvent GXS_IDENTITY = 12, - /// @see RsFiles - SHARED_DIRECTORIES = 13, + /// @see RsFiles @deprecated + SHARED_DIRECTORIES = 13, /// @see RsFiles FILE_TRANSFER = 14, @@ -100,8 +100,11 @@ enum class RsEventType : uint32_t /// @see RsMsgs CHAT_MESSAGE = 15, - /// @see rspeers.h - NETWORK = 16, + /// @see rspeers.h + NETWORK = 16, + + /** Emitted to update library clients about file hashing being completed */ + FILE_HASHING_COMPLETED = 20, __MAX /// Used internally, keep last }; diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index f25d90957..17b68aede 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -194,7 +194,8 @@ enum class RsFileTransferEventCode: uint8_t { COMPLETED_FILES_REMOVED = 0x02, // }; -struct RsSharedDirectoriesEvent: RsEvent +struct RS_DEPRECATED_FOR("Packing arbitrary data into an std::string is bad idea") +RsSharedDirectoriesEvent: RsEvent { RsSharedDirectoriesEvent() : RsEvent(RsEventType::SHARED_DIRECTORIES), mEventCode(RsSharedDirectoriesEventCode::UNKNOWN) {} ~RsSharedDirectoriesEvent() override = default; @@ -212,6 +213,31 @@ struct RsSharedDirectoriesEvent: RsEvent std::string mMessage; }; +struct RsFileHashingCompletedEvent: RsEvent +{ + RsFileHashingCompletedEvent(): + RsEvent(RsEventType::FILE_HASHING_COMPLETED), mHashingSpeed(0) {} + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mFilePath); + RS_SERIAL_PROCESS(mFileHash); + RS_SERIAL_PROCESS(mHashingSpeed); + } + + /// Complete path of the file being hashed + std::string mFilePath; + + /// File hash, null if error occurred + RsFileHash mFileHash; + + /// Hashing speed in MB/s + double mHashingSpeed; +}; + struct RsFileTransferEvent: RsEvent { RsFileTransferEvent() : RsEvent(RsEventType::FILE_TRANSFER), mFileTransferEventCode(RsFileTransferEventCode::UNKNOWN) {} From 8e4a9e6a38280366323813b72b7760d65a8bfed8 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 19 Oct 2021 23:24:50 +0200 Subject: [PATCH 165/697] implemented multiple clients in Friend Server --- libretroshare/src/retroshare/rsfriendserver.h | 4 +- retroshare-friendserver/src/friendserver.cc | 10 +- retroshare-friendserver/src/friendserver.h | 1 - retroshare-friendserver/src/network.cc | 200 +++++++++++++++--- retroshare-friendserver/src/network.h | 72 +++++-- .../src/gui/FriendServerControl.cpp | 22 +- 6 files changed, 246 insertions(+), 63 deletions(-) diff --git a/libretroshare/src/retroshare/rsfriendserver.h b/libretroshare/src/retroshare/rsfriendserver.h index cb516c1df..6b343eb0e 100644 --- a/libretroshare/src/retroshare/rsfriendserver.h +++ b/libretroshare/src/retroshare/rsfriendserver.h @@ -8,10 +8,10 @@ public: void start() {} void stop() {} - void checkServerAddress_async(const std::string&,uint16_t, const std::function& callback) + void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) { std::this_thread::sleep_for(std::chrono::seconds(1)); - callback(true); + callback(addr,true); } void setServerAddress(const std::string&,uint16_t) {} void setFriendsToRequest(uint32_t) {} diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 644e34fce..a33f34bf7 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -9,11 +9,9 @@ void FriendServer::threadTick() std::this_thread::sleep_for(std::chrono::milliseconds(200)); - pqi->tick(); - RsItem *item; - while(nullptr != (item = pqi->GetItem())) + while(nullptr != (item = mni->GetItem())) { RsFriendServerItem *fsitem = dynamic_cast(item); @@ -23,6 +21,7 @@ void FriendServer::threadTick() continue; } + std::cerr << "Received item: " << std::endl << *fsitem << std::endl; switch(fsitem->PacketSubType()) { @@ -57,11 +56,6 @@ void FriendServer::run() mni = new FsNetworkInterface; mni->start(); - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new FsSerializer) ; - - pqi = new pqistreamer(rss, RsPeerId(), mni,BIN_FLAGS_READABLE); - while(!shouldStop()) { threadTick() ; } } diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 8b7c7f4bc..83e7eaaa7 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -42,7 +42,6 @@ private: void handleClientPublish(const RsFriendServerClientPublishItem *item); FsNetworkInterface *mni; - pqistreamer *pqi; std::string mBaseDirectory; }; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index a8207d732..c346b9a16 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -34,7 +34,10 @@ #include "util/rsprint.h" #include "util/rsdebug.h" +#include "pqi/pqithreadstreamer.h" + #include "network.h" +#include "fsitem.h" FsNetworkInterface::FsNetworkInterface() : mFsNiMtx(std::string("FsNetworkInterface")) @@ -42,8 +45,6 @@ FsNetworkInterface::FsNetworkInterface() RS_STACK_MUTEX(mFsNiMtx); mClintListn = 0; - mTotalReadBytes = 0; - mTotalBufferBytes = 0; struct sockaddr_in ipOfServer; @@ -61,34 +62,117 @@ FsNetworkInterface::FsNetworkInterface() RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) ; } -int FsNetworkInterface::close() -{ - RsDbg() << "Stopping network interface" << std::endl; - return 1; -} - void FsNetworkInterface::threadTick() { - tick(); + // 1 - check for new connections + + checkForNewConnections(); + + // 2 - tick all streamers + + for(auto& it:mConnections) + it.second.pqi->tick(); } -int FsNetworkInterface::tick() +static RsPeerId makePeerId(int t) +{ + unsigned char s[RsPeerId::SIZE_IN_BYTES]; + *reinterpret_cast(&s) = t; + return RsPeerId::fromBufferUnsafe(s); +} +bool FsNetworkInterface::checkForNewConnections() +{ + // look for incoming data + +// fd_set ReadFDs, WriteFDs, ExceptFDs; +// FD_ZERO(&ReadFDs); +// FD_ZERO(&WriteFDs); +// FD_ZERO(&ExceptFDs); +// +// FD_SET(mClintListn, &ReadFDs); +// FD_SET(mClintListn, &ExceptFDs); +// +// struct timeval timeout; +// timeout.tv_sec = 0; +// timeout.tv_usec = 500000; // 200 ms timeout +// int status = select(mClintListn+1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout); +// +// if(status <= 0) // if no incoming data, return. Each tick waits for 200 ms anyway. +// return false; + + struct sockaddr addr; + + //socklen_t addr_len = sizeof(sockaddr); + //int clintConnt = accept(mClintListn, &addr, &addr_len); // accept is a blocking call! + int clintConnt = accept(mClintListn, nullptr, nullptr); // accept is a blocking call! + + if(clintConnt < 0) + { + RsErr()<< "Incoming connection with nothing to read!" << std::endl; + return false; + } + RsDbg() << "Got incoming connection from " << sockaddr_storage_tostring( *(sockaddr_storage*)&addr); + + ConnectionData c; + c.socket = clintConnt; + c.client_address = addr; + + RsPeerId pid = makePeerId(clintConnt); + + RsSerialiser *rss = new RsSerialiser ; + rss->addSerialType(new FsSerializer) ; + + FsBioInterface *bio = new FsBioInterface(clintConnt); + + auto p = new pqistreamer(rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); + auto pqi = new pqithreadstreamer(p,rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); + c.pqi = pqi; + + pqi->start(); + + RS_STACK_MUTEX(mFsNiMtx); + mConnections[makePeerId(clintConnt)] = c; + + return true; +} + +RsItem *FsNetworkInterface::GetItem() +{ + RS_STACK_MUTEX(mFsNiMtx); + + for(auto& it:mConnections) + { + RsItem *item = it.second.pqi->GetItem(); + if(item) + return item; + } + return nullptr; +} + +FsBioInterface::FsBioInterface(int socket) + : mCLintConnt(socket) +{ + mTotalReadBytes=0; + mTotalBufferBytes=0; +} + +int FsBioInterface::tick() { std::cerr << "ticking FsNetworkInterface" << std::endl; - int clintConnt = accept(mClintListn, (struct sockaddr*)NULL, NULL); // accept is a blocking call! + // 2 - read incoming data pending on existing connections char inBuffer[1025]; memset(inBuffer,0,1025); - int readbytes = read(clintConnt, inBuffer, sizeof(inBuffer)); + int readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); if(readbytes < 0) RsErr() << "read() failed. Errno=" << errno ; - std::cerr << "clintConnt: " << clintConnt << ", readbytes: " << readbytes << std::endl; + std::cerr << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes << std::endl; - ::close(clintConnt); + //::close(clintConnt); // display some debug info @@ -104,27 +188,22 @@ int FsNetworkInterface::tick() memcpy(ptr,inBuffer,readbytes); - RS_STACK_MUTEX(mFsNiMtx); in_buffer.push_back(std::make_pair(ptr,readbytes)); - mTotalBufferBytes += readbytes; + mTotalReadBytes += readbytes; - RsDbg() << "InBuffer: " << in_buffer.size() << " elements. Total size: " << mTotalBufferBytes << ". Total read: " << mTotalReadBytes ; + std::cerr << "Total bytes:" << mTotalReadBytes << std::endl; + std::cerr << "Connections:" << std::endl; + + RsDbg() << "socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; } return true; } -int FsNetworkInterface::senddata(void *, int len) +int FsBioInterface::readdata(void *data, int len) { - RsErr() << "Trying to send data through FsNetworkInterface although it's not implemented yet!"<< std::endl; - return false; -} -int FsNetworkInterface::readdata(void *data, int len) -{ - RS_STACK_MUTEX(mFsNiMtx); - // read incoming bytes in the buffer int total_len = 0; @@ -167,26 +246,81 @@ int FsNetworkInterface::readdata(void *data, int len) return len; } -int FsNetworkInterface::netstatus() +int FsBioInterface::senddata(void *data, int len) +{ + return isactive(); +} +int FsBioInterface::netstatus() { return 1; // dummy response. } -int FsNetworkInterface::isactive() +int FsBioInterface::isactive() { - RS_STACK_MUTEX(mFsNiMtx); - return mClintListn > 0; + return mCLintConnt > 0; } -bool FsNetworkInterface::moretoread(uint32_t /* usec */) +bool FsBioInterface::moretoread(uint32_t /* usec */) { - RS_STACK_MUTEX(mFsNiMtx); return mTotalBufferBytes > 0; } -bool FsNetworkInterface::cansend(uint32_t) +bool FsBioInterface::cansend(uint32_t) { - return false; + return isactive(); +} + +int FsBioInterface::close() +{ + RsDbg() << "Stopping network interface" << std::endl; + return 1; } +FsClient::FsClient(const std::string& address) + : mServerAddress(address) +{ +} +bool FsClient::sendItem(RsItem *item) +{ + // request a connection + int CreateSocket = 0,n = 0; + char dataReceived[1024]; + struct sockaddr_in ipOfServer; + memset(dataReceived, '0' ,sizeof(dataReceived)); + if((CreateSocket = socket(AF_INET, SOCK_STREAM, 0))< 0) + { + printf("Socket not created \n"); + return 1; + } + + ipOfServer.sin_family = AF_INET; + ipOfServer.sin_port = htons(2017); + ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) + { + printf("Connection failed due to port and ip problems\n"); + return 1; + } + + while((n = read(CreateSocket, dataReceived, sizeof(dataReceived)-1)) > 0) + { + dataReceived[n] = 0; + if(fputs(dataReceived, stdout) == EOF) + { + printf("\nStandard output error"); + } + + printf("\n"); + } + + if( n < 0) + { + printf("Standard input error \n"); + } + + return 0; + + // if ok, stream the item through it +} diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index e276a8d63..402f7a982 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -24,16 +24,21 @@ #include "util/rsthreads.h" #include "pqi/pqi_base.h" -class FsNetworkInterface: public BinInterface, public RsTickingThread +class pqistreamer; + +struct ConnectionData +{ + sockaddr client_address; + int socket; + pqistreamer *pqi; +}; + +class FsBioInterface: public BinInterface { public: - FsNetworkInterface() ; + FsBioInterface(int socket); - // Implements RsTickingThread - - void threadTick() override; - - // Implements BinInterface methods + // Implements BinInterface methods int tick() override; @@ -54,15 +59,58 @@ public: uint64_t bytecount() override { return mTotalReadBytes; } bool bandwidthLimited() override { return false; } + +private: + int mCLintConnt; + uint32_t mTotalReadBytes; + uint32_t mTotalBufferBytes; + + std::list > in_buffer; +}; + +// This class handles multiple connections to the server and supplies RsItem elements + +class FsNetworkInterface: public RsTickingThread +{ +public: + FsNetworkInterface() ; + + // basic functionality + + RsItem *GetItem(); + + // Implements RsTickingThread + + void threadTick() override; + +protected: + bool checkForNewConnections(); + private: RsMutex mFsNiMtx; void initListening(); void stopListening(); - int mClintListn ; - uint64_t mTotalReadBytes; - uint64_t mTotalBufferBytes; - - std::list > in_buffer; + int mClintListn ; // listening socket + std::map mConnections; }; + +// This class runs a client connection to the friend server. It opens a socket at each connection. + +class FsClient +{ +public: + FsClient(const std::string& address); + + bool sendItem(RsItem *item); + +private: + std::string mServerAddress; +}; + + + + + + diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp index 53091c934..82a7df829 100644 --- a/retroshare-gui/src/gui/FriendServerControl.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -48,6 +48,7 @@ FriendServerControl::FriendServerControl(QWidget *parent) QObject::connect(torServerAddress_LE,SIGNAL(textChanged(const QString&)),this,SLOT(onOnionAddressEdit(const QString&))); mCheckingServerMovie = new QMovie(":/images/loader/circleball-16.gif"); + serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); updateFriendServerStatusIcon(false); } @@ -70,21 +71,26 @@ void FriendServerControl::onOnionAddressEdit(const QString&) { // Setup timer to auto-check the friend server address - mConnectionCheckTimer->stop(); mConnectionCheckTimer->setSingleShot(true); mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time. mConnectionCheckTimer->start(); - serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); - mCheckingServerMovie->start(); + if(mCheckingServerMovie->fileName() != QString(":/images/loader/circleball-16.gif" )) + { + mCheckingServerMovie->setFileName(":/images/loader/circleball-16.gif"); + mCheckingServerMovie->start(); + } } void FriendServerControl::checkServerAddress() { rsFriendServer->checkServerAddress_async(torServerAddress_LE->text().toStdString(),torServerPort_SB->value(), - [this](bool test_result) + [this](const std::string& address,bool test_result) { + if(test_result) + rsFriendServer->setServerAddress(address,1729); + RsQThreadUtils::postToObject( [=]() { updateFriendServerStatusIcon(test_result); },this); } ); @@ -97,17 +103,19 @@ void FriendServerControl::onNbFriendsToRequestsChanged(int n) void FriendServerControl::updateFriendServerStatusIcon(bool ok) { + mCheckingServerMovie->stop(); + if(ok) { - torServerStatus_LB->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; torServerStatus_LB->setToolTip(tr("Friend server is currently reachable.")) ; + mCheckingServerMovie->setFileName(ICON_STATUS_OK); } else { - torServerStatus_LB->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; torServerStatus_LB->setToolTip(tr("The proxy is not enabled or broken.\nAre all services up and running fine??\nAlso check your ports!")) ; + mCheckingServerMovie->setFileName(ICON_STATUS_UNKNOWN); } - mCheckingServerMovie->stop(); + mCheckingServerMovie->start(); } From c77b9d1e1f73d5b3744b25c112bb8296711cab94 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 20 Oct 2021 21:14:08 +0200 Subject: [PATCH 166/697] added embedded test for FS --- retroshare-friendserver/src/network.cc | 54 ++++++++++++++----- .../src/retroshare-friendserver.cc | 17 +++++- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index c346b9a16..bad0aa583 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -248,7 +248,8 @@ int FsBioInterface::readdata(void *data, int len) int FsBioInterface::senddata(void *data, int len) { - return isactive(); + int written = write(mCLintConnt, data, len); + return written; } int FsBioInterface::netstatus() { @@ -281,7 +282,8 @@ FsClient::FsClient(const std::string& address) bool FsClient::sendItem(RsItem *item) { - // request a connection + // open a connection + int CreateSocket = 0,n = 0; char dataReceived[1024]; struct sockaddr_in ipOfServer; @@ -300,24 +302,48 @@ bool FsClient::sendItem(RsItem *item) if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) { - printf("Connection failed due to port and ip problems\n"); - return 1; + printf("Connection failed due to port and ip problems, or server is not available\n"); + return false; } - while((n = read(CreateSocket, dataReceived, sizeof(dataReceived)-1)) > 0) + // Serialise the item and send it. + + uint32_t size = RsSerialiser::MAX_SERIAL_SIZE; + RsTemporaryMemory data(size); + + if(!data) { - dataReceived[n] = 0; - if(fputs(dataReceived, stdout) == EOF) + RsErr() << "Cannot allocate memory to send item!" << std::endl; + return false; + } + + FsSerializer *fss = new FsSerializer; + RsSerialiser rss; + rss.addSerialType(fss); + + FsSerializer().serialise(item,data,&size); + + write(CreateSocket,data,size); + + // Now attempt to read and deserialize anything that comes back from that connexion + + FsBioInterface bio(CreateSocket); + pqistreamer pqi(&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); + pqithreadstreamer p(&pqi,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); + p.start(); + + while(true) + { + RsItem *item = p.GetItem(); + + if(!item) { - printf("\nStandard output error"); + rstime::rs_usleep(1000*200); + continue; } - printf("\n"); - } - - if( n < 0) - { - printf("Standard input error \n"); + std::cerr << "Got a response item: " << std::endl; + std::cerr << *item << std::endl; } return 0; diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc index 1be8e1f4e..93ce3f409 100644 --- a/retroshare-friendserver/src/retroshare-friendserver.cc +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -26,6 +26,9 @@ #include "friendserver.h" +// debug +#include "fsitem.h" + int main(int argc, char* argv[]) { RsInfo() << "\n" << @@ -54,8 +57,20 @@ int main(int argc, char* argv[]) fs.start(); while(fs.isRunning()) - std::this_thread::sleep_for(std::chrono::seconds(1)); + { + std::this_thread::sleep_for(std::chrono::seconds(2)); + // send one request for testing to see what happens + + RsFriendServerClientPublishItem *item = new RsFriendServerClientPublishItem(); + item->long_invite = std::string("[Long Invite]"); + item->n_requested_friends = 10; + + std::cerr << "Sending fake request item for testing..." << std::endl; + FsClient(std::string("127.0.0.1")).sendItem(item); + + std::this_thread::sleep_for(std::chrono::seconds(4)); + } return 0; } From 8939896abf2cc3e761f640a31adc083dfcda8620 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 20 Oct 2021 23:06:25 +0200 Subject: [PATCH 167/697] added missing comment in pqi_base --- libretroshare/src/pqi/pqi_base.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqi_base.h b/libretroshare/src/pqi/pqi_base.h index 51980b501..72d5d540b 100644 --- a/libretroshare/src/pqi/pqi_base.h +++ b/libretroshare/src/pqi/pqi_base.h @@ -280,7 +280,8 @@ public: * Sends data to a prescribed location (implementation dependent) *@param data what will be sent *@param len the size of data pointed to in memory - */ + *@returns total number of bytes actually sent + */ virtual int senddata(void *data, int len) = 0; /** From c58956139612aeb615364ceaf64e59ae9693b239 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 20 Oct 2021 23:06:38 +0200 Subject: [PATCH 168/697] made sockets non blocking --- retroshare-friendserver/src/network.cc | 95 +++++++++++++++++--------- retroshare-friendserver/src/network.h | 1 + 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index bad0aa583..d309f8a13 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -46,22 +46,44 @@ FsNetworkInterface::FsNetworkInterface() mClintListn = 0; - struct sockaddr_in ipOfServer; - mClintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket + int flags = fcntl(mClintListn, F_GETFL); + fcntl(mClintListn, F_SETFL, flags | O_NONBLOCK); + + struct sockaddr_in ipOfServer; memset(&ipOfServer, '0', sizeof(ipOfServer)); ipOfServer.sin_family = AF_INET; - ipOfServer.sin_addr.s_addr = htonl(INADDR_ANY); ipOfServer.sin_port = htons(2017); // this is the port number of running server + ipOfServer.sin_addr.s_addr = htonl(INADDR_ANY); - bind(mClintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)); - listen(mClintListn , 40); + if(bind(mClintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)) < 0) + { + RsErr() << "Error while binding: errno=" << errno ; + return; + } + + if(listen(mClintListn , 40) < 0) + { + RsErr() << "Error while calling listen: errno=" << errno ; + return; + } RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) ; } +FsNetworkInterface::~FsNetworkInterface() +{ + for(auto& it:mConnections) + { + delete it.second.pqi; + std::cerr << "Releasing socket " << it.second.socket << std::endl; + close(it.second.socket); + } + std::cerr << "Releasing listening socket " << mClintListn << std::endl; + close(mClintListn); +} void FsNetworkInterface::threadTick() { // 1 - check for new connections @@ -72,6 +94,8 @@ void FsNetworkInterface::threadTick() for(auto& it:mConnections) it.second.pqi->tick(); + + rstime::rs_usleep(1000*200); } static RsPeerId makePeerId(int t) @@ -84,41 +108,37 @@ bool FsNetworkInterface::checkForNewConnections() { // look for incoming data -// fd_set ReadFDs, WriteFDs, ExceptFDs; -// FD_ZERO(&ReadFDs); -// FD_ZERO(&WriteFDs); -// FD_ZERO(&ExceptFDs); -// -// FD_SET(mClintListn, &ReadFDs); -// FD_SET(mClintListn, &ExceptFDs); -// -// struct timeval timeout; -// timeout.tv_sec = 0; -// timeout.tv_usec = 500000; // 200 ms timeout -// int status = select(mClintListn+1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout); -// -// if(status <= 0) // if no incoming data, return. Each tick waits for 200 ms anyway. -// return false; - struct sockaddr addr; + socklen_t addr_len = sizeof(sockaddr); - //socklen_t addr_len = sizeof(sockaddr); - //int clintConnt = accept(mClintListn, &addr, &addr_len); // accept is a blocking call! - int clintConnt = accept(mClintListn, nullptr, nullptr); // accept is a blocking call! + int clintConnt = accept(mClintListn, &addr, &addr_len); // accept is a blocking call! if(clintConnt < 0) { - RsErr()<< "Incoming connection with nothing to read!" << std::endl; + if(errno == EWOULDBLOCK) + ;//RsErr()<< "Incoming connection with nothing to read!" << std::endl; + else + RsErr()<< "Error when accepting connection." << std::endl; + return false; } RsDbg() << "Got incoming connection from " << sockaddr_storage_tostring( *(sockaddr_storage*)&addr); + // Make the socket non blocking so that we can read from it and return if nothing comes + + int flags = fcntl(clintConnt, F_GETFL); + fcntl(clintConnt, F_SETFL, flags | O_NONBLOCK); + + // Create connection info + ConnectionData c; c.socket = clintConnt; c.client_address = addr; RsPeerId pid = makePeerId(clintConnt); + // Setup a pqistreamer to deserialize whatever comes from this connection + RsSerialiser *rss = new RsSerialiser ; rss->addSerialType(new FsSerializer) ; @@ -167,8 +187,18 @@ int FsBioInterface::tick() int readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); + if(readbytes == 0) + { + std::cerr << "Reached END of the stream!" << std::endl; + return 0; + } if(readbytes < 0) - RsErr() << "read() failed. Errno=" << errno ; + { + if(errno != EWOULDBLOCK && errno != EAGAIN) + RsErr() << "read() failed. Errno=" << errno ; + + return false; + } std::cerr << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes << std::endl; @@ -179,7 +209,7 @@ int FsBioInterface::tick() if(readbytes > 0) { RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; - RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; void *ptr = malloc(readbytes); @@ -190,13 +220,9 @@ int FsBioInterface::tick() in_buffer.push_back(std::make_pair(ptr,readbytes)); mTotalBufferBytes += readbytes; - mTotalReadBytes += readbytes; - std::cerr << "Total bytes:" << mTotalReadBytes << std::endl; - std::cerr << "Connections:" << std::endl; - - RsDbg() << "socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; + std::cerr << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; } return true; @@ -248,8 +274,9 @@ int FsBioInterface::readdata(void *data, int len) int FsBioInterface::senddata(void *data, int len) { - int written = write(mCLintConnt, data, len); - return written; +// int written = write(mCLintConnt, data, len); +// return written; + return len; } int FsBioInterface::netstatus() { diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index 402f7a982..37ced7624 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -74,6 +74,7 @@ class FsNetworkInterface: public RsTickingThread { public: FsNetworkInterface() ; + virtual ~FsNetworkInterface() ; // basic functionality From b731cf34eea045ee60ec522422ad3e8c54d3ad98 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 24 Oct 2021 17:41:23 +0200 Subject: [PATCH 169/697] moved part of the code to libretroshare/src/friend_server --- libretroshare/src/friend_server/fsbio.cc | 133 +++++++++++ libretroshare/src/friend_server/fsbio.h | 35 +++ libretroshare/src/friend_server/fsclient.cc | 77 +++++++ libretroshare/src/friend_server/fsclient.h | 13 ++ .../src/friend_server}/fsitem.h | 0 libretroshare/src/friend_server/fsmanager.cc | 0 libretroshare/src/friend_server/fsmanager.h | 0 libretroshare/src/libretroshare.pro | 8 + retroshare-friendserver/src/network.cc | 209 +----------------- retroshare-friendserver/src/network.h | 48 ---- 10 files changed, 267 insertions(+), 256 deletions(-) create mode 100644 libretroshare/src/friend_server/fsbio.cc create mode 100644 libretroshare/src/friend_server/fsbio.h create mode 100644 libretroshare/src/friend_server/fsclient.cc create mode 100644 libretroshare/src/friend_server/fsclient.h rename {retroshare-friendserver/src => libretroshare/src/friend_server}/fsitem.h (100%) create mode 100644 libretroshare/src/friend_server/fsmanager.cc create mode 100644 libretroshare/src/friend_server/fsmanager.h diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc new file mode 100644 index 000000000..4104c3c0d --- /dev/null +++ b/libretroshare/src/friend_server/fsbio.cc @@ -0,0 +1,133 @@ +FsBioInterface::FsBioInterface(int socket) + : mCLintConnt(socket) +{ + mTotalReadBytes=0; + mTotalBufferBytes=0; +} + +int FsBioInterface::tick() +{ + std::cerr << "ticking FsNetworkInterface" << std::endl; + + // 2 - read incoming data pending on existing connections + + char inBuffer[1025]; + memset(inBuffer,0,1025); + + int readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); + + if(readbytes == 0) + { + std::cerr << "Reached END of the stream!" << std::endl; + return 0; + } + if(readbytes < 0) + { + if(errno != EWOULDBLOCK && errno != EAGAIN) + RsErr() << "read() failed. Errno=" << errno ; + + return false; + } + + std::cerr << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes << std::endl; + + //::close(clintConnt); + + // display some debug info + + if(readbytes > 0) + { + RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; + //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + + void *ptr = malloc(readbytes); + + if(!ptr) + throw std::runtime_error("Cannot allocate memory! Go buy some RAM!"); + + memcpy(ptr,inBuffer,readbytes); + + in_buffer.push_back(std::make_pair(ptr,readbytes)); + mTotalBufferBytes += readbytes; + mTotalReadBytes += readbytes; + + std::cerr << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; + } + + return true; +} + +int FsBioInterface::readdata(void *data, int len) +{ + // read incoming bytes in the buffer + + int total_len = 0; + + while(total_len < len) + { + if(in_buffer.empty()) + { + mTotalBufferBytes -= total_len; + return total_len; + } + + // If the remaining buffer is too large, chop of the beginning of it. + + if(total_len + in_buffer.front().second > len) + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,len - total_len); + + void *ptr = malloc(in_buffer.front().second - (len - total_len)); + memcpy(ptr,&(static_cast(in_buffer.front().first)[len - total_len]),in_buffer.front().second - (len - total_len)); + + free(in_buffer.front().first); + in_buffer.front().first = ptr; + in_buffer.front().second -= len-total_len; + + mTotalBufferBytes -= len; + return len; + } + else // copy everything + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,in_buffer.front().second); + + total_len += in_buffer.front().second; + + free(in_buffer.front().first); + in_buffer.pop_front(); + } + } + mTotalBufferBytes -= len; + return len; +} + +int FsBioInterface::senddata(void *data, int len) +{ +// int written = write(mCLintConnt, data, len); +// return written; + return len; +} +int FsBioInterface::netstatus() +{ + return 1; // dummy response. +} +int FsBioInterface::isactive() +{ + return mCLintConnt > 0; +} +bool FsBioInterface::moretoread(uint32_t /* usec */) +{ + return mTotalBufferBytes > 0; +} +bool FsBioInterface::cansend(uint32_t) +{ + return isactive(); +} + +int FsBioInterface::close() +{ + RsDbg() << "Stopping network interface" << std::endl; + return 1; +} + + diff --git a/libretroshare/src/friend_server/fsbio.h b/libretroshare/src/friend_server/fsbio.h new file mode 100644 index 000000000..2e872d48d --- /dev/null +++ b/libretroshare/src/friend_server/fsbio.h @@ -0,0 +1,35 @@ +class FsBioInterface: public BinInterface +{ +public: + FsBioInterface(int socket); + + // Implements BinInterface methods + + int tick() override; + + int senddata(void *data, int len) override; + int readdata(void *data, int len) override; + + int netstatus() override; + int isactive() override; + bool moretoread(uint32_t usec) override; + bool cansend(uint32_t usec) override; + + int close() override; + + /** + * If hashing data + **/ + RsFileHash gethash() override { return RsFileHash() ; } + uint64_t bytecount() override { return mTotalReadBytes; } + + bool bandwidthLimited() override { return false; } + +private: + int mCLintConnt; + uint32_t mTotalReadBytes; + uint32_t mTotalBufferBytes; + + std::list > in_buffer; +}; + diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc new file mode 100644 index 000000000..6ee8518af --- /dev/null +++ b/libretroshare/src/friend_server/fsclient.cc @@ -0,0 +1,77 @@ +FsClient::FsClient(const std::string& address) + : mServerAddress(address) +{ +} + +bool FsClient::sendItem(RsItem *item) +{ + // open a connection + + int CreateSocket = 0,n = 0; + char dataReceived[1024]; + struct sockaddr_in ipOfServer; + + memset(dataReceived, '0' ,sizeof(dataReceived)); + + if((CreateSocket = socket(AF_INET, SOCK_STREAM, 0))< 0) + { + printf("Socket not created \n"); + return 1; + } + + ipOfServer.sin_family = AF_INET; + ipOfServer.sin_port = htons(2017); + ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) + { + printf("Connection failed due to port and ip problems, or server is not available\n"); + return false; + } + + // Serialise the item and send it. + + uint32_t size = RsSerialiser::MAX_SERIAL_SIZE; + RsTemporaryMemory data(size); + + if(!data) + { + RsErr() << "Cannot allocate memory to send item!" << std::endl; + return false; + } + + FsSerializer *fss = new FsSerializer; + RsSerialiser rss; + rss.addSerialType(fss); + + FsSerializer().serialise(item,data,&size); + + // TODO: we should write in multiple chunks just in case the socket is not fully ready + write(CreateSocket,data,size); + + // Now attempt to read and deserialize anything that comes back from that connexion + + FsBioInterface bio(CreateSocket); + pqistreamer pqi(&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); + pqithreadstreamer p(&pqi,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); + p.start(); + + while(true) + { + RsItem *item = p.GetItem(); + + if(!item) + { + rstime::rs_usleep(1000*200); + continue; + } + + std::cerr << "Got a response item: " << std::endl; + std::cerr << *item << std::endl; + } + + return 0; + + // if ok, stream the item through it +} + diff --git a/libretroshare/src/friend_server/fsclient.h b/libretroshare/src/friend_server/fsclient.h new file mode 100644 index 000000000..6e79ed1b3 --- /dev/null +++ b/libretroshare/src/friend_server/fsclient.h @@ -0,0 +1,13 @@ +// This class runs a client connection to the friend server. It opens a socket at each connection. + +class FsClient +{ +public: + FsClient(const std::string& address); + + bool sendItem(RsItem *item); + +private: + std::string mServerAddress; +}; + diff --git a/retroshare-friendserver/src/fsitem.h b/libretroshare/src/friend_server/fsitem.h similarity index 100% rename from retroshare-friendserver/src/fsitem.h rename to libretroshare/src/friend_server/fsitem.h diff --git a/libretroshare/src/friend_server/fsmanager.cc b/libretroshare/src/friend_server/fsmanager.cc new file mode 100644 index 000000000..e69de29bb diff --git a/libretroshare/src/friend_server/fsmanager.h b/libretroshare/src/friend_server/fsmanager.h new file mode 100644 index 000000000..e69de29bb diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index caaabd0b7..d6f0397df 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -404,6 +404,10 @@ HEADERS += pqi/authssl.h \ pqi/pqinetstatebox.h \ pqi/p3servicecontrol.h +SOURCES += friend_server/fsclient.h \ + friend_server/fsbio.h \ + friend_server/fsmanager.h + HEADERS += rsserver/p3face.h \ rsserver/p3history.h \ rsserver/p3msgs.h \ @@ -569,6 +573,10 @@ SOURCES += pqi/authgpg.cc \ pqi/pqinetstatebox.cc \ pqi/p3servicecontrol.cc +SOURCES += friend_server/fsclient.cc \ + friend_server/fsbio.cc \ + friend_server/fsmanager.cc + SOURCES += rsserver/p3face-config.cc \ rsserver/p3face-server.cc \ rsserver/p3face-info.cc \ diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index d309f8a13..c5451e9b1 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -35,6 +35,7 @@ #include "util/rsdebug.h" #include "pqi/pqithreadstreamer.h" +#include "friend_server/fsbio.h" #include "network.h" #include "fsitem.h" @@ -169,211 +170,3 @@ RsItem *FsNetworkInterface::GetItem() return nullptr; } -FsBioInterface::FsBioInterface(int socket) - : mCLintConnt(socket) -{ - mTotalReadBytes=0; - mTotalBufferBytes=0; -} - -int FsBioInterface::tick() -{ - std::cerr << "ticking FsNetworkInterface" << std::endl; - - // 2 - read incoming data pending on existing connections - - char inBuffer[1025]; - memset(inBuffer,0,1025); - - int readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); - - if(readbytes == 0) - { - std::cerr << "Reached END of the stream!" << std::endl; - return 0; - } - if(readbytes < 0) - { - if(errno != EWOULDBLOCK && errno != EAGAIN) - RsErr() << "read() failed. Errno=" << errno ; - - return false; - } - - std::cerr << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes << std::endl; - - //::close(clintConnt); - - // display some debug info - - if(readbytes > 0) - { - RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; - //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; - - void *ptr = malloc(readbytes); - - if(!ptr) - throw std::runtime_error("Cannot allocate memory! Go buy some RAM!"); - - memcpy(ptr,inBuffer,readbytes); - - in_buffer.push_back(std::make_pair(ptr,readbytes)); - mTotalBufferBytes += readbytes; - mTotalReadBytes += readbytes; - - std::cerr << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; - } - - return true; -} - -int FsBioInterface::readdata(void *data, int len) -{ - // read incoming bytes in the buffer - - int total_len = 0; - - while(total_len < len) - { - if(in_buffer.empty()) - { - mTotalBufferBytes -= total_len; - return total_len; - } - - // If the remaining buffer is too large, chop of the beginning of it. - - if(total_len + in_buffer.front().second > len) - { - memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,len - total_len); - - void *ptr = malloc(in_buffer.front().second - (len - total_len)); - memcpy(ptr,&(static_cast(in_buffer.front().first)[len - total_len]),in_buffer.front().second - (len - total_len)); - - free(in_buffer.front().first); - in_buffer.front().first = ptr; - in_buffer.front().second -= len-total_len; - - mTotalBufferBytes -= len; - return len; - } - else // copy everything - { - memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,in_buffer.front().second); - - total_len += in_buffer.front().second; - - free(in_buffer.front().first); - in_buffer.pop_front(); - } - } - mTotalBufferBytes -= len; - return len; -} - -int FsBioInterface::senddata(void *data, int len) -{ -// int written = write(mCLintConnt, data, len); -// return written; - return len; -} -int FsBioInterface::netstatus() -{ - return 1; // dummy response. -} -int FsBioInterface::isactive() -{ - return mCLintConnt > 0; -} -bool FsBioInterface::moretoread(uint32_t /* usec */) -{ - return mTotalBufferBytes > 0; -} -bool FsBioInterface::cansend(uint32_t) -{ - return isactive(); -} - -int FsBioInterface::close() -{ - RsDbg() << "Stopping network interface" << std::endl; - return 1; -} - - -FsClient::FsClient(const std::string& address) - : mServerAddress(address) -{ -} - -bool FsClient::sendItem(RsItem *item) -{ - // open a connection - - int CreateSocket = 0,n = 0; - char dataReceived[1024]; - struct sockaddr_in ipOfServer; - - memset(dataReceived, '0' ,sizeof(dataReceived)); - - if((CreateSocket = socket(AF_INET, SOCK_STREAM, 0))< 0) - { - printf("Socket not created \n"); - return 1; - } - - ipOfServer.sin_family = AF_INET; - ipOfServer.sin_port = htons(2017); - ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1"); - - if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) - { - printf("Connection failed due to port and ip problems, or server is not available\n"); - return false; - } - - // Serialise the item and send it. - - uint32_t size = RsSerialiser::MAX_SERIAL_SIZE; - RsTemporaryMemory data(size); - - if(!data) - { - RsErr() << "Cannot allocate memory to send item!" << std::endl; - return false; - } - - FsSerializer *fss = new FsSerializer; - RsSerialiser rss; - rss.addSerialType(fss); - - FsSerializer().serialise(item,data,&size); - - write(CreateSocket,data,size); - - // Now attempt to read and deserialize anything that comes back from that connexion - - FsBioInterface bio(CreateSocket); - pqistreamer pqi(&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); - pqithreadstreamer p(&pqi,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); - p.start(); - - while(true) - { - RsItem *item = p.GetItem(); - - if(!item) - { - rstime::rs_usleep(1000*200); - continue; - } - - std::cerr << "Got a response item: " << std::endl; - std::cerr << *item << std::endl; - } - - return 0; - - // if ok, stream the item through it -} diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index 37ced7624..e5ff4bc3c 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -33,41 +33,6 @@ struct ConnectionData pqistreamer *pqi; }; -class FsBioInterface: public BinInterface -{ -public: - FsBioInterface(int socket); - - // Implements BinInterface methods - - int tick() override; - - int senddata(void *data, int len) override; - int readdata(void *data, int len) override; - - int netstatus() override; - int isactive() override; - bool moretoread(uint32_t usec) override; - bool cansend(uint32_t usec) override; - - int close() override; - - /** - * If hashing data - **/ - RsFileHash gethash() override { return RsFileHash() ; } - uint64_t bytecount() override { return mTotalReadBytes; } - - bool bandwidthLimited() override { return false; } - -private: - int mCLintConnt; - uint32_t mTotalReadBytes; - uint32_t mTotalBufferBytes; - - std::list > in_buffer; -}; - // This class handles multiple connections to the server and supplies RsItem elements class FsNetworkInterface: public RsTickingThread @@ -97,19 +62,6 @@ private: std::map mConnections; }; -// This class runs a client connection to the friend server. It opens a socket at each connection. - -class FsClient -{ -public: - FsClient(const std::string& address); - - bool sendItem(RsItem *item); - -private: - std::string mServerAddress; -}; - From 19e42663a0141a75e03d2fed41b3265d7cf73df0 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 24 Oct 2021 20:01:19 +0200 Subject: [PATCH 170/697] fixed compilation --- libretroshare/src/friend_server/fsbio.cc | 27 ++++++++++++++++ libretroshare/src/friend_server/fsbio.h | 24 ++++++++++++++ libretroshare/src/friend_server/fsclient.cc | 27 ++++++++++++++++ libretroshare/src/friend_server/fsclient.h | 25 +++++++++++++++ libretroshare/src/friend_server/fsitem.h | 24 ++++++++++++++ libretroshare/src/libretroshare.pro | 1 + libretroshare/src/retroshare/rsfriendserver.h | 32 +++++++++++++------ retroshare-friendserver/src/friendserver.cc | 2 +- retroshare-friendserver/src/network.cc | 2 +- retroshare-friendserver/src/network.h | 2 +- .../src/retroshare-friendserver.cc | 3 +- 11 files changed, 156 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc index 4104c3c0d..517738225 100644 --- a/libretroshare/src/friend_server/fsbio.cc +++ b/libretroshare/src/friend_server/fsbio.cc @@ -1,3 +1,28 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsbio.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include "util/rsprint.h" +#include "fsbio.h" + FsBioInterface::FsBioInterface(int socket) : mCLintConnt(socket) { @@ -111,10 +136,12 @@ int FsBioInterface::netstatus() { return 1; // dummy response. } + int FsBioInterface::isactive() { return mCLintConnt > 0; } + bool FsBioInterface::moretoread(uint32_t /* usec */) { return mTotalBufferBytes > 0; diff --git a/libretroshare/src/friend_server/fsbio.h b/libretroshare/src/friend_server/fsbio.h index 2e872d48d..446ad29f8 100644 --- a/libretroshare/src/friend_server/fsbio.h +++ b/libretroshare/src/friend_server/fsbio.h @@ -1,3 +1,27 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsbio.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include "pqi/pqi_base.h" + class FsBioInterface: public BinInterface { public: diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index 6ee8518af..c332aee24 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -1,3 +1,30 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsclient.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include "pqi/pqithreadstreamer.h" + +#include "fsclient.h" +#include "fsbio.h" + FsClient::FsClient(const std::string& address) : mServerAddress(address) { diff --git a/libretroshare/src/friend_server/fsclient.h b/libretroshare/src/friend_server/fsclient.h index 6e79ed1b3..c29a10671 100644 --- a/libretroshare/src/friend_server/fsclient.h +++ b/libretroshare/src/friend_server/fsclient.h @@ -1,3 +1,28 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsclient.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include +#include "fsitem.h" + // This class runs a client connection to the friend server. It opens a socket at each connection. class FsClient diff --git a/libretroshare/src/friend_server/fsitem.h b/libretroshare/src/friend_server/fsitem.h index 4714178af..3ca7e50d5 100644 --- a/libretroshare/src/friend_server/fsitem.h +++ b/libretroshare/src/friend_server/fsitem.h @@ -1,3 +1,27 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsitem.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#pragma once + #include "serialiser/rsserial.h" #include "serialiser/rsserializer.h" diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d6f0397df..f8d01a613 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -406,6 +406,7 @@ HEADERS += pqi/authssl.h \ SOURCES += friend_server/fsclient.h \ friend_server/fsbio.h \ + friend_server/fsitem.h \ friend_server/fsmanager.h HEADERS += rsserver/p3face.h \ diff --git a/libretroshare/src/retroshare/rsfriendserver.h b/libretroshare/src/retroshare/rsfriendserver.h index 6b343eb0e..9ce4b25ef 100644 --- a/libretroshare/src/retroshare/rsfriendserver.h +++ b/libretroshare/src/retroshare/rsfriendserver.h @@ -2,19 +2,33 @@ #include #include "util/rstime.h" +// The Friend Server component of Retroshare automatically adds/removes some friends so that the +// +// The current strategy is: +// +// - if total nb of friends < S +// request new friends to the FS +// - if total nb of friends >= S +// do not request anymore (and unpublish the key), but keep the friends already here +// +// Possible states: +// - not started +// - maintain friend list +// - actively request friends +// +// The friend server internally keeps track of which friends have been added using the friend server. +// It's important to keep the ones that are already connected because they may count on us. +// Friends supplied by the FS who never connected for a few days should be removed automatically. + class RsFriendServer { public: - void start() {} - void stop() {} + virtual void start() =0; + virtual void stop() =0; - void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) - { - std::this_thread::sleep_for(std::chrono::seconds(1)); - callback(addr,true); - } - void setServerAddress(const std::string&,uint16_t) {} - void setFriendsToRequest(uint32_t) {} + virtual void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) =0; + virtual void setServerAddress(const std::string&,uint16_t) =0; + virtual void setFriendsToRequest(uint32_t) =0; }; extern RsFriendServer *rsFriendServer; diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index a33f34bf7..fa4591955 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -1,7 +1,7 @@ #include "util/rsdebug.h" #include "friendserver.h" -#include "fsitem.h" +#include "friend_server/fsitem.h" void FriendServer::threadTick() { diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index c5451e9b1..5f697e9b0 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -38,7 +38,7 @@ #include "friend_server/fsbio.h" #include "network.h" -#include "fsitem.h" +#include "friend_server/fsitem.h" FsNetworkInterface::FsNetworkInterface() : mFsNiMtx(std::string("FsNetworkInterface")) diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index e5ff4bc3c..e842ec77c 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -22,7 +22,7 @@ #pragma once #include "util/rsthreads.h" -#include "pqi/pqi_base.h" +#include "retroshare/rspeers.h" class pqistreamer; diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc index 93ce3f409..c93c59609 100644 --- a/retroshare-friendserver/src/retroshare-friendserver.cc +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -27,7 +27,8 @@ #include "friendserver.h" // debug -#include "fsitem.h" +#include "friend_server/fsitem.h" +#include "friend_server/fsclient.h" int main(int argc, char* argv[]) { From dbb6a7471eaa0e30d9dce52c8afc23635f93a942 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 24 Oct 2021 22:26:10 +0200 Subject: [PATCH 171/697] fixed compilation (fix by sehraf) --- libretroshare/src/libretroshare.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 30aee9671..c654b2e61 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1030,8 +1030,8 @@ rs_sam3_libsam3 { cd $${RS_SRC_PATH} && ( \ git submodule update --init supportlibs/libsam3 || \ true ) && \ - mkdir -p $${UDP_DISCOVERY_BUILD_PATH} && \ - cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} && \ + mkdir -p $${LIBSAM3_BUILD_PATH} && \ + (cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} || true) && \ cd $${LIBSAM3_BUILD_PATH} && \ $(MAKE) build QMAKE_EXTRA_COMPILERS += libsam3 From b8e27d6bc07e9b9acaf245baa31c1fa6c6141070 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 25 Oct 2021 13:32:24 +0200 Subject: [PATCH 172/697] Document sam3 build options, fix Android CI --- build_scripts/Android/Dockerfile | 6 +++--- build_scripts/Android/README.asciidoc | 1 + build_scripts/GitlabCI/Android.Dockerfile | 5 +++-- retroshare.pri | 25 +++++++++++++++-------- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index dc1320d9c..6ff2ba2f5 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -80,10 +80,9 @@ WORKDIR /jsonapi-generator-build/ RUN qmake ../RetroShare/jsonapi-generator/src/ \ CONFIG+=no_retroshare_plugins \ CONFIG+=no_retroshare_service CONFIG+=no_retroshare_gui \ - CONFIG+=rs_jsonapi && \ + CONFIG+=rs_jsonapi CONFIG+=no_rs_sam3_libsam3 && \ make -j$(nproc) -#CONFIG+=no_keywords RUN mkdir /retroshare-service-android-build WORKDIR /retroshare-service-android-build RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \ @@ -93,7 +92,8 @@ RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \ JSONAPI_GENERATOR_EXE=/jsonapi-generator-build/jsonapi-generator \ NATIVE_LIBS_TOOLCHAIN_PATH=$NATIVE_LIBS_TOOLCHAIN_PATH \ CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password \ - CONFIG+=no_rs_service_terminal_login + CONFIG+=no_rs_service_terminal_login \ + CONFIG+=no_rs_sam3 CONFIG+=no_rs_sam3_libsam3 RUN make -j$(nproc) RUN make install INSTALL_ROOT=/retroshare-service-android-build/android-build/ RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/androiddeployqt \ diff --git a/build_scripts/Android/README.asciidoc b/build_scripts/Android/README.asciidoc index d5670e10c..c47974161 100644 --- a/build_scripts/Android/README.asciidoc +++ b/build_scripts/Android/README.asciidoc @@ -81,6 +81,7 @@ JSONAPI_GENERATOR_EXE=Your_Path/jsonapi-generator/src/jsonapi-generator NATIVE_LIBS_TOOLCHAIN_PATH=Your_Path/retroshare-android-16-arm/ CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password CONFIG+=no_rs_service_terminal_login +CONFIG+=no_rs_sam3 CONFIG+=no_rs_sam3_libsam3 ------------------------------------------------------------------------------- TIP: Some versions of QtCreator try to find the Android SDK in diff --git a/build_scripts/GitlabCI/Android.Dockerfile b/build_scripts/GitlabCI/Android.Dockerfile index 80795de19..30942e95a 100644 --- a/build_scripts/GitlabCI/Android.Dockerfile +++ b/build_scripts/GitlabCI/Android.Dockerfile @@ -17,7 +17,7 @@ WORKDIR /jsonapi-generator-build/ RUN qmake ../RetroShare/jsonapi-generator/src/ \ CONFIG+=no_retroshare_plugins \ CONFIG+=no_retroshare_service CONFIG+=no_retroshare_gui \ - CONFIG+=rs_jsonapi && \ + CONFIG+=rs_jsonapi CONFIG+=no_rs_sam3_libsam3 && \ make -j$(nproc) RUN rm -rf /retroshare-service-android-build ; mkdir /retroshare-service-android-build @@ -32,7 +32,8 @@ RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \ JSONAPI_GENERATOR_EXE=/jsonapi-generator-build/jsonapi-generator \ NATIVE_LIBS_TOOLCHAIN_PATH=$NATIVE_LIBS_TOOLCHAIN_PATH \ CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password \ - CONFIG+=no_rs_service_terminal_login + CONFIG+=no_rs_service_terminal_login \ + CONFIG+=no_rs_sam3 CONFIG+=no_rs_sam3_libsam3 RUN make -j$(nproc) RUN make install INSTALL_ROOT=/retroshare-service-android-build/android-build/ diff --git a/retroshare.pri b/retroshare.pri index 7661f2bf8..8c55efd8f 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -1,7 +1,8 @@ # RetroShare common qmake build script # -# Copyright (C) 2004-2019, Retroshare Team -# Copyright (C) 2016-2019, Gioacchino Mazzurco +# Copyright (C) 2004-2021 Retroshare Team +# Copyright (C) 2016-2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Lesser General Public License as published by the @@ -199,13 +200,16 @@ no_rs_service_terminal_login:CONFIG -= rs_service_terminal_login CONFIG+=rs_dh_init_check no_rs_dh_init_check:CONFIG -= rs_dh_init_check -# To export all symbols for the plugins on Windows build we need to build libretroshare as -# shared library. Fix linking error (ld.exe: Error: export ordinal too large) due to too -# many exported symbols. -retroshare_plugins:win32:CONFIG *= libretroshare_shared +# To disable I2P sam3 support append the following assignation to qmake command +# line "CONFIG+=no_rs_sam3" +CONFIG *= rs_sam3 +no_rs_sam3:CONFIG -= rs_sam3 + +# To disable I2P sam3 library submodule build append the following assignation +# to qmake command line "CONFIG+=no_rs_sam3_libsam3" +CONFIG *= rs_sam3_libsam3 +no_rs_sam3_libsam3:CONFIG -= rs_sam3_libsam3 -CONFIG+=rs_sam3 -CONFIG+=rs_sam3_libsam3 # Specify host precompiled jsonapi-generator path, appending the following # assignation to qmake command line @@ -649,6 +653,11 @@ android-* { RS_THREAD_LIB = } +# To export all symbols for the plugins on Windows build we need to build +# libretroshare as shared library. Fix linking error (ld.exe: Error: export +# ordinal too large) due to too many exported symbols. +retroshare_plugins:win32:CONFIG *= libretroshare_shared + win32-g++|win32-clang-g++ { !isEmpty(EXTERNAL_LIB_DIR) { message(Use pre-compiled libraries in $${EXTERNAL_LIB_DIR}.) From b6596437481fa7fff30fc22d9122904359c0566a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 25 Oct 2021 15:50:19 +0200 Subject: [PATCH 173/697] Attempt to fix non sam3 builds --- libretroshare/src/pqi/pqisslpersongrp.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/pqi/pqisslpersongrp.cc b/libretroshare/src/pqi/pqisslpersongrp.cc index 16112c744..328d64cae 100644 --- a/libretroshare/src/pqi/pqisslpersongrp.cc +++ b/libretroshare/src/pqi/pqisslpersongrp.cc @@ -82,7 +82,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener rss->addSerialType(new RsRawSerialiser()); pqicSOCKSProxy = new pqiconnect(pqip, rss, pqis); } - +#ifdef RS_USE_I2P_SAM3 if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PSAM3)) { pqissli2psam3 *pqis = new pqissli2psam3((pqissllistener *) listener, pqip, mLinkMgr); @@ -90,9 +90,11 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener rss->addSerialType(new RsRawSerialiser()); pqicI2P = new pqiconnect(pqip, rss, pqis); - } else { - pqicI2P = pqicSOCKSProxy; } + else +#endif // def RS_USE_I2P_SAM3 + pqicI2P = pqicSOCKSProxy; + /* first select type based on peer */ uint32_t typePeer = mPeerMgr->getHiddenType(id); From 8089542e74b000afa38422e72da48be6761b626d Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 27 Oct 2021 11:47:53 +0200 Subject: [PATCH 174/697] Updated OBS submodule --- build_scripts/OBS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/OBS b/build_scripts/OBS index 984ed34b7..b260e5834 160000 --- a/build_scripts/OBS +++ b/build_scripts/OBS @@ -1 +1 @@ -Subproject commit 984ed34b7f751bd407877603551ead49959f1901 +Subproject commit b260e58346b1eec782bdf88a7e8f3c9d36fd3ecb From 045069c3e6144a63426494f6d6bfdaf7530c995b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sun, 10 Jan 2021 22:25:14 +0100 Subject: [PATCH 175/697] Implement proper GXS message deletion notification GxsForums propagate message deletion notification as RsEvent --- libretroshare/src/gxs/rsgenexchange.cc | 2 +- libretroshare/src/gxs/rsgxsnotify.h | 10 + libretroshare/src/retroshare/rsgxsforums.h | 12 +- libretroshare/src/services/p3gxsforums.cc | 381 ++++++++++----------- retroshare-gui/src/gui/NewsFeed.cpp | 5 +- 5 files changed, 202 insertions(+), 208 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 5ddb0be26..9610fc1a6 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -4,7 +4,7 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Christopher Evi-Parker * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * diff --git a/libretroshare/src/gxs/rsgxsnotify.h b/libretroshare/src/gxs/rsgxsnotify.h index 990acfe84..6f186e1fe 100644 --- a/libretroshare/src/gxs/rsgxsnotify.h +++ b/libretroshare/src/gxs/rsgxsnotify.h @@ -97,3 +97,13 @@ private: bool mMetaChange; }; +struct RsGxsBulkMsgDeletedChange : RsGxsNotify +{ + RsGxsBulkMsgDeletedChange( + const RsGxsGroupId& gid, const std::set& msgsId): + RsGxsNotify(gid), messagesId(msgsId) {} + + NotifyType getType() override { return TYPE_MESSAGE_DELETED; } + + const std::set messagesId; +}; diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 83a961fc3..182a8177d 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -115,9 +115,10 @@ enum class RsForumEventCode: uint8_t READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed. - SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed - PINNED_POSTS_CHANGED = 0x0b, /// some posts where pinned or un-pinned - DELETED_FORUM = 0x0c, /// forum was deleted by cleaning + SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed + PINNED_POSTS_CHANGED = 0x0b, /// some posts where pinned or un-pinned + DELETED_FORUM = 0x0c, /// forum was deleted by cleaning + DELETED_POSTS = 13 /// Posts deleted by cleaning }; struct RsGxsForumEvent: RsEvent @@ -128,7 +129,7 @@ struct RsGxsForumEvent: RsEvent RsForumEventCode mForumEventCode; RsGxsGroupId mForumGroupId; - RsGxsMessageId mForumMsgId; + std::set mForumMsgsId; std::list mModeratorsAdded; std::list mModeratorsRemoved; @@ -140,8 +141,7 @@ struct RsGxsForumEvent: RsEvent RsEvent::serial_process(j, ctx); RS_SERIAL_PROCESS(mForumEventCode); RS_SERIAL_PROCESS(mForumGroupId); - RS_SERIAL_PROCESS(mForumMsgId); - RS_SERIAL_PROCESS(mForumMsgId); + RS_SERIAL_PROCESS(mForumMsgsId); RS_SERIAL_PROCESS(mModeratorsAdded); RS_SERIAL_PROCESS(mModeratorsRemoved); } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index a301997e6..b8d2194c5 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -192,221 +192,202 @@ RsSerialiser* p3GxsForums::setupSerialiser() void p3GxsForums::notifyChanges(std::vector &changes) { -#ifdef GXSFORUMS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() : " << changes.size() << "changes to notify" << std::endl; -#endif + RS_DBG2(changes.size(), " changes to notify"); std::vector::iterator it; for(it = changes.begin(); it != changes.end(); ++it) { - RsGxsMsgChange *msgChange = dynamic_cast(*it); - - if (msgChange) + rs_view_ptr gxsChange = *it; + switch(gxsChange->getType()) { - if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */ - if (rsEvents) + case RsGxsNotify::TYPE_RECEIVED_NEW: // [[fallthrough]] + case RsGxsNotify::TYPE_PUBLISHED: + { + rs_view_ptr msgChange = + dynamic_cast(*it); + rs_view_ptr groupChange = + dynamic_cast(*it); + + if(msgChange) /* Message received*/ + { + auto ev = std::make_shared(); + ev->mForumMsgsId.insert(msgChange->mMsgId); + ev->mForumGroupId = msgChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; + rsEvents->postEvent(ev); + } + else if(groupChange) /* Group received */ + { + bool unknown; + { + RS_STACK_MUTEX(mKnownForumsMutex); + unknown = ( mKnownForums.find(gxsChange->mGroupId) + == mKnownForums.end() ); + mKnownForums[gxsChange->mGroupId] = time(nullptr); + IndicateConfigChanged(); + } + + if(unknown) { auto ev = std::make_shared(); - ev->mForumMsgId = msgChange->mMsgId; - ev->mForumGroupId = msgChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; + ev->mForumGroupId = gxsChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::NEW_FORUM; rsEvents->postEvent(ev); } - -#ifdef NOT_USED_YET - if (!msgChange->metaChange()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() Found Message Change Notification"; - std::cerr << std::endl; -#endif - - std::map > &msgChangeMap = msgChange->msgChangeMap; - for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() Msgs for Group: " << mit->first; - std::cerr << std::endl; -#endif - bool enabled = false; - if (autoDownloadEnabled(mit->first, enabled) && enabled) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first; - std::cerr << std::endl; -#endif - - /* problem is most of these will be comments and votes, - * should make it occasional - every 5mins / 10minutes TODO */ - unprocessedGroups.push_back(mit->first); - } - } + else + RS_DBG1( " Not notifying already known forum ", + gxsChange->mGroupId ); } -#endif + break; } - else + case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed { - if (rsEvents) + auto ev = std::make_shared(); + ev->mForumGroupId = gxsChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); + break; + } + case RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED: + { + auto ev = std::make_shared(); + ev->mForumGroupId = gxsChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::SYNC_PARAMETERS_UPDATED; + rsEvents->postEvent(ev); + break; + } + case RsGxsNotify::TYPE_MESSAGE_DELETED: + { + rs_view_ptr delChange = + dynamic_cast(gxsChange); + + if(!delChange) { - RsGxsGroupChange *grpChange = dynamic_cast(*it); - if (grpChange) - { - switch (grpChange->getType()) - { - case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::SYNC_PARAMETERS_UPDATED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_PUBLISHED: - case RsGxsNotify::TYPE_RECEIVED_NEW: - { - /* group received */ - - bool unknown; - { - RS_STACK_MUTEX(mKnownForumsMutex); - unknown = (mKnownForums.find(grpChange->mGroupId)==mKnownForums.end()); - mKnownForums[grpChange->mGroupId] = time(nullptr); - IndicateConfigChanged(); - } - - if(unknown) - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::NEW_FORUM; - rsEvents->postEvent(ev); - } - else - RsInfo() << __PRETTY_FUNCTION__ - << " Not notifying already known forum " - << grpChange->mGroupId << std::endl; - } - break; - - case RsGxsNotify::TYPE_GROUP_DELETED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::DELETED_FORUM; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - - RS_STACK_MUTEX(mKnownForumsMutex); - mKnownForums[grpChange->mGroupId] = time(nullptr); - IndicateConfigChanged(); - } - break; - - case RsGxsNotify::TYPE_UPDATED: - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast(grpChange->mOldGroupItem); - RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast(grpChange->mNewGroupItem); - - if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem or NULL. This is inconsistent!" << std::endl; - delete grpChange; - continue; - } - - // First of all, we check if there is a difference between the old and new list of moderators - - std::list added_mods, removed_mods; - - for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids) - if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end()) - added_mods.push_back(gxs_id); - - for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids) - if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end()) - removed_mods.push_back(gxs_id); - - if(!added_mods.empty() || !removed_mods.empty()) - { - auto ev = std::make_shared(); - - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mModeratorsAdded = added_mods; - ev->mModeratorsRemoved = removed_mods; - ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED; - - rsEvents->postEvent(ev); - } - - // check the list of pinned posts - - std::list added_pins, removed_pins; - - for(auto& msg_id: new_forum_grp_item->mGroup.mPinnedPosts.ids) - if(old_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) == old_forum_grp_item->mGroup.mPinnedPosts.ids.end()) - added_pins.push_back(msg_id); - - for(auto& msg_id: old_forum_grp_item->mGroup.mPinnedPosts.ids) - if(new_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) == new_forum_grp_item->mGroup.mPinnedPosts.ids.end()) - removed_pins.push_back(msg_id); - - if(!added_pins.empty() || !removed_pins.empty()) - { - auto ev = std::make_shared(); - - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mForumEventCode = RsForumEventCode::PINNED_POSTS_CHANGED; - - rsEvents->postEvent(ev); - } - - if( old_forum_grp_item->mGroup.mDescription != new_forum_grp_item->mGroup.mDescription - || old_forum_grp_item->meta.mGroupName != new_forum_grp_item->meta.mGroupName - || old_forum_grp_item->meta.mGroupFlags != new_forum_grp_item->meta.mGroupFlags - || old_forum_grp_item->meta.mAuthorId != new_forum_grp_item->meta.mAuthorId - || old_forum_grp_item->meta.mCircleId != new_forum_grp_item->meta.mCircleId - ) - { - auto ev = std::make_shared(); - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mForumEventCode = RsForumEventCode::UPDATED_FORUM; - rsEvents->postEvent(ev); - } - } - break; - - - default: - RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl; - break; - } - } + RS_ERR( "Got mismatching notification type: ", + gxsChange->getType() ); + print_stacktrace(); + goto cleanup; } + + auto ev = std::make_shared(); + ev->mForumEventCode = RsForumEventCode::DELETED_POSTS; + ev->mForumGroupId = delChange->mGroupId; + ev->mForumMsgsId = delChange->messagesId; + break; + } + case RsGxsNotify::TYPE_GROUP_DELETED: + { + auto ev = std::make_shared(); + ev->mForumGroupId = gxsChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::DELETED_FORUM; + rsEvents->postEvent(ev); + break; + } + case RsGxsNotify::TYPE_STATISTICS_CHANGED: + { + auto ev = std::make_shared(); + ev->mForumGroupId = gxsChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED; + rsEvents->postEvent(ev); + + RS_STACK_MUTEX(mKnownForumsMutex); + mKnownForums[gxsChange->mGroupId] = time(nullptr); + IndicateConfigChanged(); + break; + } + case RsGxsNotify::TYPE_UPDATED: + { + /* Happens when the group data has changed. In this case we need to + * analyse the old and new group in order to detect possible + * notifications for clients */ + + rs_view_ptr grpChange = + dynamic_cast(*it); + + RsGxsForumGroupItem* old_forum_grp_item = + dynamic_cast(grpChange->mOldGroupItem); + RsGxsForumGroupItem* new_forum_grp_item = + dynamic_cast(grpChange->mNewGroupItem); + + if( old_forum_grp_item == nullptr || new_forum_grp_item == nullptr) + { + RS_ERR( "received GxsGroupUpdate item with mOldGroup and " + "mNewGroup not of type RsGxsForumGroupItem or NULL. " + "This is inconsistent!"); + print_stacktrace(); + goto cleanup; + } + + /* First of all, we check if there is a difference between the old + * and new list of moderators */ + + std::list added_mods, removed_mods; + for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids) + if( old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) + == old_forum_grp_item->mGroup.mAdminList.ids.end() ) + added_mods.push_back(gxs_id); + + for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids) + if( new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) + == new_forum_grp_item->mGroup.mAdminList.ids.end() ) + removed_mods.push_back(gxs_id); + + if(!added_mods.empty() || !removed_mods.empty()) + { + auto ev = std::make_shared(); + + ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; + ev->mModeratorsAdded = added_mods; + ev->mModeratorsRemoved = removed_mods; + ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED; + + rsEvents->postEvent(ev); + } + + // check the list of pinned posts + std::list added_pins, removed_pins; + + for(auto& msg_id: new_forum_grp_item->mGroup.mPinnedPosts.ids) + if( old_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) + == old_forum_grp_item->mGroup.mPinnedPosts.ids.end() ) + added_pins.push_back(msg_id); + + for(auto& msg_id: old_forum_grp_item->mGroup.mPinnedPosts.ids) + if( new_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) + == new_forum_grp_item->mGroup.mPinnedPosts.ids.end() ) + removed_pins.push_back(msg_id); + + if(!added_pins.empty() || !removed_pins.empty()) + { + auto ev = std::make_shared(); + ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; + ev->mForumEventCode = RsForumEventCode::PINNED_POSTS_CHANGED; + rsEvents->postEvent(ev); + } + + if( old_forum_grp_item->mGroup.mDescription != new_forum_grp_item->mGroup.mDescription + || old_forum_grp_item->meta.mGroupName != new_forum_grp_item->meta.mGroupName + || old_forum_grp_item->meta.mGroupFlags != new_forum_grp_item->meta.mGroupFlags + || old_forum_grp_item->meta.mAuthorId != new_forum_grp_item->meta.mAuthorId + || old_forum_grp_item->meta.mCircleId != new_forum_grp_item->meta.mCircleId ) + { + auto ev = std::make_shared(); + ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; + ev->mForumEventCode = RsForumEventCode::UPDATED_FORUM; + rsEvents->postEvent(ev); + } + + break; } - /* shouldn't need to worry about groups - as they need to be subscribed to */ + default: + RS_ERR( "Got a GXS event of type ", gxsChange->getType(), + " Currently not handled." ); + break; + } - delete *it; +cleanup: + delete *it; } } @@ -1072,7 +1053,7 @@ void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& { auto ev = std::make_shared(); - ev->mForumMsgId = msgId.second; + ev->mForumMsgsId.insert(msgId.second); ev->mForumGroupId = msgId.first; ev->mForumEventCode = RsForumEventCode::READ_STATUS_CHANGED; rsEvents->postEvent(ev); @@ -1103,7 +1084,7 @@ std::error_condition p3GxsForums::setPostKeepForever( { auto ev = std::make_shared(); ev->mForumGroupId = forumId; - ev->mForumMsgId = postId; + ev->mForumMsgsId.insert(postId); ev->mForumEventCode = RsForumEventCode::UPDATED_MESSAGE; rsEvents->postEvent(ev); return std::error_condition(); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index afef19b16..3c86de318 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -270,7 +270,10 @@ void NewsFeed::handleForumEvent(std::shared_ptr event) case RsForumEventCode::UPDATED_MESSAGE: case RsForumEventCode::NEW_MESSAGE: - addFeedItem(new GxsForumMsgItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, pe->mForumMsgId, false, true)); + for(const auto& postId: pe->mForumMsgsId) + addFeedItem(new GxsForumMsgItem( + this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, postId, + false, true )); break; default: break; From cef43fe04830cf7e3ba83d4fabe09c8b51221839 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 13 Jan 2021 17:24:03 +0100 Subject: [PATCH 176/697] Notify one deletion per event as Cyril suggested --- libretroshare/src/gxs/rsgenexchange.cc | 13 +++++++++---- libretroshare/src/gxs/rsgxsnotify.h | 10 +++++----- libretroshare/src/retroshare/rsgxsforums.h | 10 +++++----- libretroshare/src/services/p3gxsforums.cc | 12 ++++++------ retroshare-gui/src/gui/NewsFeed.cpp | 4 ++-- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 9610fc1a6..99725cd70 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -2717,10 +2717,15 @@ void RsGenExchange::processMessageDelete() msgDeleted.push_back(note.msgIds); } - for(const auto& msgreq:msgDeleted) - for(const auto& msgit:msgreq) - for(const auto& msg:msgit.second) - mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_MESSAGE_DELETED,msgit.first,msg, false)); + /* Three nested for looks like a performance bomb, but as Cyril says here + * https://github.com/RetroShare/RetroShare/pull/2218#pullrequestreview-565194022 + * this should actually not explode at all because it is just one message at + * time that get notified */ + for(const auto& msd : mMsgDeletePublish) + for(auto& msgMap : msd.mMsgs) + for(auto& msgId : msgMap.second) + mNotifications.push_back( + new RsGxsMsgDeletedChange(msgMap.first, msgId) ); mMsgDeletePublish.clear(); } diff --git a/libretroshare/src/gxs/rsgxsnotify.h b/libretroshare/src/gxs/rsgxsnotify.h index 6f186e1fe..030d9f26f 100644 --- a/libretroshare/src/gxs/rsgxsnotify.h +++ b/libretroshare/src/gxs/rsgxsnotify.h @@ -97,13 +97,13 @@ private: bool mMetaChange; }; -struct RsGxsBulkMsgDeletedChange : RsGxsNotify +struct RsGxsMsgDeletedChange : RsGxsNotify { - RsGxsBulkMsgDeletedChange( - const RsGxsGroupId& gid, const std::set& msgsId): - RsGxsNotify(gid), messagesId(msgsId) {} + RsGxsMsgDeletedChange( + const RsGxsGroupId& gid, const RsGxsMessageId& msgId): + RsGxsNotify(gid), messageId(msgId) {} NotifyType getType() override { return TYPE_MESSAGE_DELETED; } - const std::set messagesId; + const RsGxsMessageId messageId; }; diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 182a8177d..1b35f2db9 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -118,7 +118,7 @@ enum class RsForumEventCode: uint8_t SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed PINNED_POSTS_CHANGED = 0x0b, /// some posts where pinned or un-pinned DELETED_FORUM = 0x0c, /// forum was deleted by cleaning - DELETED_POSTS = 13 /// Posts deleted by cleaning + DELETED_POSTS = 0x0d /// Posts deleted by cleaning }; struct RsGxsForumEvent: RsEvent @@ -129,9 +129,9 @@ struct RsGxsForumEvent: RsEvent RsForumEventCode mForumEventCode; RsGxsGroupId mForumGroupId; - std::set mForumMsgsId; - std::list mModeratorsAdded; - std::list mModeratorsRemoved; + RsGxsMessageId mForumMsgId; + std::list mModeratorsAdded; + std::list mModeratorsRemoved; ///* @see RsEvent @see RsSerializable void serial_process( @@ -141,7 +141,7 @@ struct RsGxsForumEvent: RsEvent RsEvent::serial_process(j, ctx); RS_SERIAL_PROCESS(mForumEventCode); RS_SERIAL_PROCESS(mForumGroupId); - RS_SERIAL_PROCESS(mForumMsgsId); + RS_SERIAL_PROCESS(mForumMsgId); RS_SERIAL_PROCESS(mModeratorsAdded); RS_SERIAL_PROCESS(mModeratorsRemoved); } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index b8d2194c5..a57d4e68f 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -211,7 +211,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) if(msgChange) /* Message received*/ { auto ev = std::make_shared(); - ev->mForumMsgsId.insert(msgChange->mMsgId); + ev->mForumMsgId = msgChange->mMsgId; ev->mForumGroupId = msgChange->mGroupId; ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; rsEvents->postEvent(ev); @@ -258,8 +258,8 @@ void p3GxsForums::notifyChanges(std::vector &changes) } case RsGxsNotify::TYPE_MESSAGE_DELETED: { - rs_view_ptr delChange = - dynamic_cast(gxsChange); + rs_view_ptr delChange = + dynamic_cast(gxsChange); if(!delChange) { @@ -272,7 +272,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) auto ev = std::make_shared(); ev->mForumEventCode = RsForumEventCode::DELETED_POSTS; ev->mForumGroupId = delChange->mGroupId; - ev->mForumMsgsId = delChange->messagesId; + ev->mForumMsgId = delChange->messageId; break; } case RsGxsNotify::TYPE_GROUP_DELETED: @@ -1053,7 +1053,7 @@ void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& { auto ev = std::make_shared(); - ev->mForumMsgsId.insert(msgId.second); + ev->mForumMsgId = msgId.second; ev->mForumGroupId = msgId.first; ev->mForumEventCode = RsForumEventCode::READ_STATUS_CHANGED; rsEvents->postEvent(ev); @@ -1084,7 +1084,7 @@ std::error_condition p3GxsForums::setPostKeepForever( { auto ev = std::make_shared(); ev->mForumGroupId = forumId; - ev->mForumMsgsId.insert(postId); + ev->mForumMsgId = postId; ev->mForumEventCode = RsForumEventCode::UPDATED_MESSAGE; rsEvents->postEvent(ev); return std::error_condition(); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 3c86de318..4e59685b3 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -270,9 +270,9 @@ void NewsFeed::handleForumEvent(std::shared_ptr event) case RsForumEventCode::UPDATED_MESSAGE: case RsForumEventCode::NEW_MESSAGE: - for(const auto& postId: pe->mForumMsgsId) addFeedItem(new GxsForumMsgItem( - this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, postId, + this, NEWSFEED_NEW_FORUM, + pe->mForumGroupId, pe->mForumMsgId, false, true )); break; From ab349a8157711c61ad4030c4f1557e6af37fef52 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 15 Jan 2021 16:42:29 +0100 Subject: [PATCH 177/697] Use unannotated pointer as per Cyril taste --- libretroshare/src/services/p3gxsforums.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index a57d4e68f..cd7cbb5fe 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -197,16 +197,14 @@ void p3GxsForums::notifyChanges(std::vector &changes) std::vector::iterator it; for(it = changes.begin(); it != changes.end(); ++it) { - rs_view_ptr gxsChange = *it; + RsGxsNotify* gxsChange = *it; switch(gxsChange->getType()) { case RsGxsNotify::TYPE_RECEIVED_NEW: // [[fallthrough]] case RsGxsNotify::TYPE_PUBLISHED: { - rs_view_ptr msgChange = - dynamic_cast(*it); - rs_view_ptr groupChange = - dynamic_cast(*it); + RsGxsMsgChange* msgChange = dynamic_cast(*it); + RsGxsGroupChange* groupChange = dynamic_cast(*it); if(msgChange) /* Message received*/ { @@ -258,7 +256,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) } case RsGxsNotify::TYPE_MESSAGE_DELETED: { - rs_view_ptr delChange = + RsGxsMsgDeletedChange* delChange = dynamic_cast(gxsChange); if(!delChange) @@ -301,8 +299,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) * analyse the old and new group in order to detect possible * notifications for clients */ - rs_view_ptr grpChange = - dynamic_cast(*it); + RsGxsGroupChange* grpChange = dynamic_cast(*it); RsGxsForumGroupItem* old_forum_grp_item = dynamic_cast(grpChange->mOldGroupItem); From 1b551d809f419db94e0a2ae88be803ac8115cee4 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 8 Feb 2021 17:04:04 +0100 Subject: [PATCH 178/697] First working prototype of GXS service search Channels are now able to take advantage of the new deep search goodies Rebase on top of master 2021/10/19 --- .../src/deep_search/channelsindex.cpp | 169 +++-- .../src/deep_search/channelsindex.hpp | 39 +- libretroshare/src/deep_search/commonutils.cpp | 154 ++++- libretroshare/src/deep_search/commonutils.hpp | 34 +- libretroshare/src/deep_search/filesindex.cpp | 83 ++- libretroshare/src/deep_search/filesindex.hpp | 23 +- .../src/file_sharing/directory_storage.cc | 6 +- libretroshare/src/ft/ftserver.cc | 4 +- libretroshare/src/gxs/rsgenexchange.cc | 42 +- libretroshare/src/gxs/rsgxsnetservice.cc | 134 ++-- libretroshare/src/gxs/rsgxsnetservice.h | 62 +- libretroshare/src/gxs/rsgxsnettunnel.cc | 607 +++++++++++++----- libretroshare/src/gxs/rsgxsnettunnel.h | 62 +- libretroshare/src/gxs/rsgxsutil.cc | 145 +---- libretroshare/src/gxs/rsgxsutil.h | 36 +- libretroshare/src/gxs/rsnxs.h | 62 +- .../rsmemory.cc => gxs/rsnxsobserver.cpp} | 89 ++- libretroshare/src/gxs/rsnxsobserver.h | 104 ++- libretroshare/src/libretroshare.pro | 12 +- libretroshare/src/retroshare/rsgxschannels.h | 147 +++-- libretroshare/src/retroshare/rsgxsiface.h | 62 +- .../src/retroshare/rsgxsifacetypes.h | 2 +- libretroshare/src/rsitems/rsgxschannelitems.h | 65 +- libretroshare/src/rsitems/rsitem.h | 5 +- libretroshare/src/rsitems/rsserviceids.h | 14 +- libretroshare/src/services/p3gxschannels.h | 74 +-- libretroshare/src/util/rsdebug.cc | 9 +- libretroshare/src/util/rsdebug.h | 10 +- libretroshare/src/util/rsmemory.h | 70 +- .../src/gui/gxschannels/GxsChannelDialog.cpp | 4 +- 30 files changed, 1455 insertions(+), 874 deletions(-) rename libretroshare/src/{util/rsmemory.cc => gxs/rsnxsobserver.cpp} (55%) diff --git a/libretroshare/src/deep_search/channelsindex.cpp b/libretroshare/src/deep_search/channelsindex.cpp index cd1c374fc..86a1e341a 100644 --- a/libretroshare/src/deep_search/channelsindex.cpp +++ b/libretroshare/src/deep_search/channelsindex.cpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -20,16 +20,23 @@ #include "deep_search/channelsindex.hpp" #include "deep_search/commonutils.hpp" +#include "retroshare/rsinit.h" +#include "util/rsdebuglevel3.h" -uint32_t DeepChannelsIndex::search( +/*static*/ std::string DeepChannelsIndex::dbDefaultPath() +{ return RsAccounts::AccountDirectory() + "/deep_channels_xapian_db"; } + +std::error_condition DeepChannelsIndex::search( const std::string& queryStr, std::vector& results, uint32_t maxResults ) { + RS_DBG3(queryStr); + results.clear(); std::unique_ptr dbPtr( - DeepSearch::openReadOnlyDatabase(dbPath()) ); - if(!dbPtr) return 0; + DeepSearch::openReadOnlyDatabase(mDbPath) ); + if(!dbPtr) return std::errc::bad_file_descriptor; Xapian::Database& db(*dbPtr); @@ -63,17 +70,13 @@ uint32_t DeepChannelsIndex::search( results.push_back(s); } - return static_cast(results.size()); + return std::error_condition(); } -void DeepChannelsIndex::indexChannelGroup(const RsGxsChannelGroup& chan) +std::error_condition DeepChannelsIndex::indexChannelGroup( + const RsGxsChannelGroup& chan ) { - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); + RS_DBG4(chan); // Set up a TermGenerator that we'll use in indexing. Xapian::TermGenerator termgenerator; @@ -94,21 +97,8 @@ void DeepChannelsIndex::indexChannelGroup(const RsGxsChannelGroup& chan) termgenerator.increase_termpos(); termgenerator.index_text(chan.mDescription); - RsUrl chanUrl; chanUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", chan.mMeta.mGroupId.toStdString()); - const std::string idTerm("Q" + chanUrl.toString()); - - chanUrl.setQueryKV("publishTs", std::to_string(chan.mMeta.mPublishTs)); - chanUrl.setQueryKV("name", chan.mMeta.mGroupName); - if(!chan.mMeta.mAuthorId.isNull()) - chanUrl.setQueryKV("authorId", chan.mMeta.mAuthorId.toStdString()); - if(chan.mMeta.mSignFlags) - chanUrl.setQueryKV( "signFlags", - std::to_string(chan.mMeta.mSignFlags) ); - std::string rsLink(chanUrl.toString()); - // store the RS link so we are able to retrive it on matching search + const std::string rsLink(channelIndexId(chan.mMeta.mGroupId)); doc.add_value(URL_VALUENO, rsLink); // Store some fields for display purposes. @@ -117,35 +107,32 @@ void DeepChannelsIndex::indexChannelGroup(const RsGxsChannelGroup& chan) // We use the identifier to ensure each object ends up in the // database only once no matter how many times we run the // indexer. "Q" prefix is a Xapian convention for unique id term. + const std::string idTerm("Q" + rsLink); doc.add_boolean_term(idTerm); - db.replace_document(idTerm, doc); + + mWriteQueue.push( [idTerm, doc](Xapian::WritableDatabase& db) + { db.replace_document(idTerm, doc); } ); + + return std::error_condition(); } -void DeepChannelsIndex::removeChannelFromIndex(RsGxsGroupId grpId) +std::error_condition DeepChannelsIndex::removeChannelFromIndex( + const RsGxsGroupId& grpId ) { + RS_DBG3(grpId); + // "Q" prefix is a Xapian convention for unique id term. - RsUrl chanUrl; chanUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", grpId.toStdString()); - std::string idTerm("Q" + chanUrl.toString()); + const std::string idTerm("Q" + channelIndexId(grpId)); + mWriteQueue.push( [idTerm](Xapian::WritableDatabase& db) + { db.delete_document(idTerm); } ); - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - db.delete_document(idTerm); + return std::error_condition(); } -void DeepChannelsIndex::indexChannelPost(const RsGxsChannelPost& post) +std::error_condition DeepChannelsIndex::indexChannelPost( + const RsGxsChannelPost& post ) { - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); + RS_DBG4(post); // Set up a TermGenerator that we'll use in indexing. Xapian::TermGenerator termgenerator; @@ -160,21 +147,16 @@ void DeepChannelsIndex::indexChannelPost(const RsGxsChannelPost& post) termgenerator.index_text( DeepSearch::timetToXapianDate(post.mMeta.mPublishTs), 1, "D" ); - // TODO: we should strip out HTML tags instead of skipping indexing - // Avoid indexing HTML - bool isPlainMsg = - post.mMsg[0] != '<' || post.mMsg[post.mMsg.size() - 1] != '>'; - - if(isPlainMsg) - termgenerator.index_text(post.mMsg, 1, "XD"); + // Avoid indexing RetroShare-gui HTML tags + const std::string cleanMsg = DeepSearch::simpleTextHtmlExtract(post.mMsg); + termgenerator.index_text( + DeepSearch::simpleTextHtmlExtract(post.mMsg), 1, "XD" ); // Index fields without prefixes for general search. termgenerator.index_text(post.mMeta.mMsgName); - if(isPlainMsg) - { - termgenerator.increase_termpos(); - termgenerator.index_text(post.mMsg); - } + + termgenerator.increase_termpos(); + termgenerator.index_text(cleanMsg); for(const RsGxsFile& attachment : post.mFiles) { @@ -184,47 +166,50 @@ void DeepChannelsIndex::indexChannelPost(const RsGxsChannelPost& post) termgenerator.index_text(attachment.mName); } - // We use the identifier to ensure each object ends up in the - // database only once no matter how many times we run the - // indexer. - RsUrl postUrl; postUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", post.mMeta.mGroupId.toStdString()) - .setQueryKV("msgid", post.mMeta.mMsgId.toStdString()); - std::string idTerm("Q" + postUrl.toString()); - - postUrl.setQueryKV("publishTs", std::to_string(post.mMeta.mPublishTs)); - postUrl.setQueryKV("name", post.mMeta.mMsgName); - postUrl.setQueryKV("authorId", post.mMeta.mAuthorId.toStdString()); - std::string rsLink(postUrl.toString()); - // store the RS link so we are able to retrive it on matching search + const std::string rsLink(postIndexId(post.mMeta.mGroupId, post.mMeta.mMsgId)); doc.add_value(URL_VALUENO, rsLink); // Store some fields for display purposes. - if(isPlainMsg) - doc.set_data(post.mMeta.mMsgName + "\n" + post.mMsg); - else doc.set_data(post.mMeta.mMsgName); + doc.set_data(post.mMeta.mMsgName + "\n" + cleanMsg); + // We use the identifier to ensure each object ends up in the + // database only once no matter how many times we run the + // indexer. + const std::string idTerm("Q" + rsLink); doc.add_boolean_term(idTerm); - db.replace_document(idTerm, doc); + + mWriteQueue.push( [idTerm, doc](Xapian::WritableDatabase& db) + { db.replace_document(idTerm, doc); } ); + + return std::error_condition(); } -void DeepChannelsIndex::removeChannelPostFromIndex( +std::error_condition DeepChannelsIndex::removeChannelPostFromIndex( + const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ) +{ + RS_DBG3(grpId, msgId); + + std::string idTerm("Q" + postIndexId(grpId, msgId)); + mWriteQueue.push( [idTerm](Xapian::WritableDatabase& db) + { db.delete_document(idTerm); } ); + + return std::error_condition(); +} + +/*static*/ std::string DeepChannelsIndex::channelIndexId(RsGxsGroupId grpId) +{ + RsUrl channelIndexId(RsGxsChannels::DEFAULT_CHANNEL_BASE_URL); + channelIndexId.setQueryKV( + RsGxsChannels::CHANNEL_URL_ID_FIELD, grpId.toStdString() ); + return channelIndexId.toString(); +} + +/*static*/ std::string DeepChannelsIndex::postIndexId( RsGxsGroupId grpId, RsGxsMessageId msgId ) { - RsUrl postUrl; postUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", grpId.toStdString()) - .setQueryKV("msgid", msgId.toStdString()); - // "Q" prefix is a Xapian convention for unique id term. - std::string idTerm("Q" + postUrl.toString()); - - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - db.delete_document(idTerm); + RsUrl postIndexId(RsGxsChannels::DEFAULT_CHANNEL_BASE_URL); + postIndexId.setQueryKV(RsGxsChannels::CHANNEL_URL_ID_FIELD, grpId.toStdString()); + postIndexId.setQueryKV(RsGxsChannels::CHANNEL_URL_MSG_ID_FIELD, msgId.toStdString()); + return postIndexId.toString(); } diff --git a/libretroshare/src/deep_search/channelsindex.hpp b/libretroshare/src/deep_search/channelsindex.hpp index 0a49629d9..b767ce2b4 100644 --- a/libretroshare/src/deep_search/channelsindex.hpp +++ b/libretroshare/src/deep_search/channelsindex.hpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -24,8 +24,8 @@ #include "util/rstime.h" #include "retroshare/rsgxschannels.h" -#include "retroshare/rsinit.h" #include "util/rsurl.h" +#include "deep_search/commonutils.hpp" struct DeepChannelsSearchResult { @@ -36,28 +36,34 @@ struct DeepChannelsSearchResult struct DeepChannelsIndex { + explicit DeepChannelsIndex(const std::string& dbPath) : + mDbPath(dbPath), mWriteQueue(dbPath) {} + /** * @brief Search indexed GXS groups and messages * @param[in] maxResults maximum number of acceptable search results, 0 for * no limits * @return search results count */ - static uint32_t search( const std::string& queryStr, - std::vector& results, - uint32_t maxResults = 100 ); + std::error_condition search( + const std::string& queryStr, + std::vector& results, + uint32_t maxResults = 100 ); - static void indexChannelGroup(const RsGxsChannelGroup& chan); + std::error_condition indexChannelGroup(const RsGxsChannelGroup& chan); - static void removeChannelFromIndex(RsGxsGroupId grpId); + std::error_condition removeChannelFromIndex(const RsGxsGroupId& grpId); - static void indexChannelPost(const RsGxsChannelPost& post); + std::error_condition indexChannelPost(const RsGxsChannelPost& post); - static void removeChannelPostFromIndex( - RsGxsGroupId grpId, RsGxsMessageId msgId ); + std::error_condition removeChannelPostFromIndex( + const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ); - static uint32_t indexFile(const std::string& path); + static std::string dbDefaultPath(); private: + static std::string channelIndexId(RsGxsGroupId grpId); + static std::string postIndexId(RsGxsGroupId grpId, RsGxsMessageId msgId); enum : Xapian::valueno { @@ -68,10 +74,7 @@ private: BAD_VALUENO = Xapian::BAD_VALUENO }; - static const std::string& dbPath() - { - static const std::string dbDir = - RsAccounts::AccountDirectory() + "/deep_channels_xapian_db"; - return dbDir; - } + const std::string mDbPath; + + DeepSearch::StubbornWriteOpQueue mWriteQueue; }; diff --git a/libretroshare/src/deep_search/commonutils.cpp b/libretroshare/src/deep_search/commonutils.cpp index eecbd4ec6..cbe4ee27b 100644 --- a/libretroshare/src/deep_search/commonutils.cpp +++ b/libretroshare/src/deep_search/commonutils.cpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -18,39 +18,17 @@ * * *******************************************************************************/ +#include +#include + #include "deep_search/commonutils.hpp" #include "util/stacktrace.h" -#include "util/rsdebug.h" +#include "util/rsthreads.h" +#include "util/rsdebuglevel0.h" + namespace DeepSearch { - -std::unique_ptr openWritableDatabase( - const std::string& path, int flags, int blockSize ) -{ - try - { - std::unique_ptr dbPtr( - new Xapian::WritableDatabase(path, flags, blockSize) ); - return dbPtr; - } - catch(Xapian::DatabaseLockError) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed aquiring Xapian DB lock " - << path << std::endl; - print_stacktrace(); - } - catch(...) - { - RsErr() << __PRETTY_FUNCTION__ << " Xapian DB is apparently corrupted " - << "deleting it might help without causing any harm: " - << path << std::endl; - print_stacktrace(); - } - - return nullptr; -} - std::unique_ptr openReadOnlyDatabase( const std::string& path, int flags ) { @@ -60,12 +38,12 @@ std::unique_ptr openReadOnlyDatabase( new Xapian::Database(path, flags) ); return dbPtr; } - catch(Xapian::DatabaseOpeningError e) + catch(Xapian::DatabaseOpeningError& e) { RsWarn() << __PRETTY_FUNCTION__ << " " << e.get_msg() << ", probably nothing has been indexed yet." << std::endl; } - catch(Xapian::DatabaseLockError) + catch(Xapian::DatabaseLockError&) { RsErr() << __PRETTY_FUNCTION__ << " Failed aquiring Xapian DB lock " << path << std::endl; @@ -90,4 +68,116 @@ std::string timetToXapianDate(const rstime_t& time) return date; } +StubbornWriteOpQueue::~StubbornWriteOpQueue() +{ + auto fErr = flush(0); + if(fErr) + { + RS_FATAL( "Flush failed on destruction ", mOpStore.size(), + " operations irreparably lost ", fErr ); + print_stacktrace(); + } +} + +void StubbornWriteOpQueue::push(write_op op) +{ + RS_DBG4(""); + + { + std::unique_lock lock(mQueueMutex); + mOpStore.push(op); + } + + flush(); +} + +std::error_condition StubbornWriteOpQueue::flush( + rstime_t acceptDelay, rstime_t callTS ) +{ + RS_DBG4(""); + + { + // Return without attempt to open the database if the queue is empty + std::unique_lock lock(mQueueMutex); + if(mOpStore.empty()) return std::error_condition(); + } + + std::unique_ptr dbPtr; + try + { + dbPtr = std::make_unique( + mDbPath, Xapian::DB_CREATE_OR_OPEN ); + } + catch(Xapian::DatabaseLockError) + { + if(acceptDelay) + { + rstime_t tNow = time(nullptr); + rstime_t maxRemaining = tNow - (callTS + acceptDelay); + if(maxRemaining > 0) + { + std::chrono::milliseconds interval( + std::max(50l, maxRemaining*1000/5) ); + RS_DBG3( "Cannot acquire database write lock, retrying in:", + interval.count(), "ms" ); + RsThread::async([this, acceptDelay, callTS, interval]() + { + std::this_thread::sleep_for(interval); + flush(acceptDelay, callTS); + }); + return std::error_condition(); + } + else + { + RS_ERR(std::errc::timed_out, acceptDelay, callTS, tNow); + return std::errc::timed_out; + } + } + else return std::errc::resource_unavailable_try_again; + } + catch(...) + { + RS_ERR("Xapian DB ", mDbPath, " is apparently corrupted"); + print_stacktrace(); + return std::errc::io_error; + } + + std::unique_lock lock(mQueueMutex); + while(!mOpStore.empty()) + { + auto op = mOpStore.front(); mOpStore.pop(); + op(*dbPtr); + } + return std::error_condition(); +} + +std::string simpleTextHtmlExtract(const std::string& rsHtmlDoc) +{ + if(rsHtmlDoc.empty()) return rsHtmlDoc; + + const bool isPlainMsg = + rsHtmlDoc[0] != '<' || rsHtmlDoc[rsHtmlDoc.size() - 1] != '>'; + if(isPlainMsg) return rsHtmlDoc; + + auto oSize = rsHtmlDoc.size(); + auto bodyTagBegin(rsHtmlDoc.find("= oSize) return rsHtmlDoc; + + auto bodyTagEnd(rsHtmlDoc.find(">", bodyTagBegin)); + if(bodyTagEnd >= oSize) return rsHtmlDoc; + + std::string retVal(rsHtmlDoc.substr(bodyTagEnd+1)); + + std::string::size_type oPos; + std::string::size_type cPos; + while((oPos = retVal.find("<")) < retVal.size()) + { + if((cPos = retVal.find(">")) <= retVal.size()) + retVal.erase(oPos, 1+cPos-oPos); + else break; + } + + return retVal; +} + } diff --git a/libretroshare/src/deep_search/commonutils.hpp b/libretroshare/src/deep_search/commonutils.hpp index 28961bc09..5f47c39bd 100644 --- a/libretroshare/src/deep_search/commonutils.hpp +++ b/libretroshare/src/deep_search/commonutils.hpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -21,6 +21,9 @@ #include #include +#include +#include +#include #include "util/rstime.h" @@ -33,13 +36,34 @@ namespace DeepSearch { - -std::unique_ptr openWritableDatabase( - const std::string& path, int flags = 0, int blockSize = 0 ); +typedef std::function write_op; std::unique_ptr openReadOnlyDatabase( const std::string& path, int flags = 0 ); std::string timetToXapianDate(const rstime_t& time); +std::string simpleTextHtmlExtract(const std::string& rsHtmlDoc); + +struct StubbornWriteOpQueue +{ + explicit StubbornWriteOpQueue(const std::string& dbPath): + mDbPath(dbPath) {} + + ~StubbornWriteOpQueue(); + + void push(write_op op); + + std::error_condition flush( + rstime_t acceptDelay = 20, rstime_t callTS = time(nullptr) ); + +private: + std::queue mOpStore; + rstime_t mLastFlush; + + std::mutex mQueueMutex; + + const std::string mDbPath; +}; + } diff --git a/libretroshare/src/deep_search/filesindex.cpp b/libretroshare/src/deep_search/filesindex.cpp index 3edcf9a97..9d5b09a72 100644 --- a/libretroshare/src/deep_search/filesindex.cpp +++ b/libretroshare/src/deep_search/filesindex.cpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -18,47 +18,47 @@ * * *******************************************************************************/ -#include "deep_search/filesindex.hpp" -#include "deep_search/commonutils.hpp" -#include "util/rsdebug.h" -#include "retroshare/rsinit.h" -#include "retroshare/rsversion.h" #include +#include "deep_search/filesindex.hpp" +#include "deep_search/commonutils.hpp" +#include "util/rsdebuglevel1.h" +#include "retroshare/rsinit.h" +#include "retroshare/rsversion.h" + /*static*/ std::multimap DeepFilesIndex::indexersRegister = {}; -bool DeepFilesIndex::indexFile( +std::error_condition DeepFilesIndex::indexFile( const std::string& path, const std::string& name, const RsFileHash& hash ) { - auto dbPtr = DeepSearch::openWritableDatabase( - mDbPath, Xapian::DB_CREATE_OR_OPEN ); - if(!dbPtr) return false; - Xapian::WritableDatabase& db(*dbPtr); - const std::string hashString = hash.toStdString(); const std::string idTerm("Q" + hashString); - Xapian::Document oldDoc; - Xapian::PostingIterator pIt = db.postlist_begin(idTerm); - if( pIt != db.postlist_end(idTerm) ) + auto db = DeepSearch::openReadOnlyDatabase(mDbPath); + if(db) { - oldDoc = db.get_document(*pIt); - if( oldDoc.get_value(INDEXER_VERSION_VALUENO) == - RS_HUMAN_READABLE_VERSION && - std::stoull(oldDoc.get_value(INDEXERS_COUNT_VALUENO)) == - indexersRegister.size() ) + Xapian::Document oldDoc; + Xapian::PostingIterator pIt = db->postlist_begin(idTerm); + if( pIt != db->postlist_end(idTerm) ) { - /* Looks like this file has already been indexed by this RetroShare - * exact version, so we can skip it. If the version was different it - * made sense to reindex it as better indexers might be available - * since last time it was indexed */ - Dbg3() << __PRETTY_FUNCTION__ << " skipping laready indexed file: " - << hash << " " << name << std::endl; - return true; + oldDoc = db->get_document(*pIt); + if( oldDoc.get_value(INDEXER_VERSION_VALUENO) == + RS_HUMAN_READABLE_VERSION && + std::stoull(oldDoc.get_value(INDEXERS_COUNT_VALUENO)) == + indexersRegister.size() ) + { + /* Looks like this file has already been indexed by this + * RetroShare exact version, so we can skip it. If the version + * was different it made sense to reindex it as better indexers + * might be available since last time it was indexed */ + RS_DBG3("skipping laready indexed file: ", hash, " ", name); + return std::error_condition(); + } } + db.reset(); // Release DB read lock ASAP } Xapian::Document doc; @@ -80,22 +80,21 @@ bool DeepFilesIndex::indexFile( doc.add_value( INDEXERS_COUNT_VALUENO, std::to_string(indexersRegister.size()) ); - db.replace_document(idTerm, doc); - return true; + mWriteQueue.push([idTerm, doc](Xapian::WritableDatabase& db) + { db.replace_document(idTerm, doc); }); + + return std::error_condition(); } -bool DeepFilesIndex::removeFileFromIndex(const RsFileHash& hash) +std::error_condition DeepFilesIndex::removeFileFromIndex(const RsFileHash& hash) { - Dbg3() << __PRETTY_FUNCTION__ << " removing file from index: " - << hash << std::endl; + RS_DBG3(hash); - std::unique_ptr db = - DeepSearch::openWritableDatabase(mDbPath, Xapian::DB_CREATE_OR_OPEN); - if(!db) return false; + mWriteQueue.push([hash](Xapian::WritableDatabase& db) + { db.delete_document("Q" + hash.toStdString()); }); - db->delete_document("Q" + hash.toStdString()); - return true; + return std::error_condition(); } /*static*/ std::string DeepFilesIndex::dbDefaultPath() @@ -104,20 +103,20 @@ bool DeepFilesIndex::removeFileFromIndex(const RsFileHash& hash) /*static*/ bool DeepFilesIndex::registerIndexer( int order, const DeepFilesIndex::IndexerFunType& indexerFun ) { - Dbg1() << __PRETTY_FUNCTION__ << " " << order << std::endl; + RS_DBG1(order); indexersRegister.insert(std::make_pair(order, indexerFun)); return true; } -uint32_t DeepFilesIndex::search( +std::error_condition DeepFilesIndex::search( const std::string& queryStr, std::vector& results, uint32_t maxResults ) { results.clear(); auto dbPtr = DeepSearch::openReadOnlyDatabase(mDbPath); - if(!dbPtr) return 0; + if(!dbPtr) return std::errc::bad_file_descriptor; Xapian::Database& db(*dbPtr); // Set up a QueryParser with a stemmer and suitable prefixes. @@ -151,7 +150,7 @@ uint32_t DeepFilesIndex::search( results.push_back(s); } - return static_cast(results.size()); + return std::error_condition(); } diff --git a/libretroshare/src/deep_search/filesindex.hpp b/libretroshare/src/deep_search/filesindex.hpp index f811e5e9c..b337bd072 100644 --- a/libretroshare/src/deep_search/filesindex.hpp +++ b/libretroshare/src/deep_search/filesindex.hpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -19,9 +19,6 @@ *******************************************************************************/ #pragma once -#include "retroshare/rstypes.h" -#include "util/rsdebug.h" - #include #include #include @@ -29,6 +26,9 @@ #include #include +#include "retroshare/rstypes.h" +#include "deep_search/commonutils.hpp" + struct DeepFilesSearchResult { DeepFilesSearchResult() : mWeight(0) {} @@ -41,7 +41,8 @@ struct DeepFilesSearchResult class DeepFilesIndex { public: - DeepFilesIndex(const std::string& dbPath) : mDbPath(dbPath) {} + explicit DeepFilesIndex(const std::string& dbPath): + mDbPath(dbPath), mWriteQueue(dbPath) {} /** * @brief Search indexed files @@ -49,7 +50,7 @@ public: * no limits * @return search results count */ - uint32_t search( const std::string& queryStr, + std::error_condition search( const std::string& queryStr, std::vector& results, uint32_t maxResults = 100 ); @@ -57,7 +58,7 @@ public: * @return false if file could not be indexed because of error or * unsupported type, true otherwise. */ - bool indexFile( + std::error_condition indexFile( const std::string& path, const std::string& name, const RsFileHash& hash ); @@ -65,7 +66,7 @@ public: * @brief Remove file entry from database * @return false on error, true otherwise. */ - bool removeFileFromIndex(const RsFileHash& hash); + std::error_condition removeFileFromIndex(const RsFileHash& hash); static std::string dbDefaultPath(); @@ -96,8 +97,8 @@ private: const std::string mDbPath; + DeepSearch::StubbornWriteOpQueue mWriteQueue; + /** Storage for indexers function by order */ static std::multimap indexersRegister; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) }; diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 402cae533..583ac5882 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2016 Mr.Alice * - * Copyright (C) 2021 Gioacchino Mazzurco * - * Copyright (C) 2021 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -549,7 +549,7 @@ bool LocalDirectoryStorage::updateHash( fInfo.storage_permission_flags & DIR_FLAGS_ANONYMOUS_SEARCH ) { DeepFilesIndex dfi(DeepFilesIndex::dbDefaultPath()); - ret &= dfi.indexFile(fInfo.path, fInfo.fname, hash); + ret &= !dfi.indexFile(fInfo.path, fInfo.fname, hash); } #endif // def RS_DEEP_FILES_INDEX diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 7d5dadb12..bf745e9e8 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -5,7 +5,7 @@ * * * Copyright (C) 2008 Robert Fernie * * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2020-2021 Asociación Civil Altermundi * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -2037,7 +2037,7 @@ bool ftServer::receiveSearchRequest( std::vector dRes; DeepFilesIndex dfi(DeepFilesIndex::dbDefaultPath()); - if(dfi.search(searchReq.queryString, dRes, maxAllowsHits) > 0) + if(!dfi.search(searchReq.queryString, dRes, maxAllowsHits)) { RsFileSearchResultItem resIt; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 99725cd70..0a9db1e58 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -5,6 +5,7 @@ * * * Copyright (C) 2012 Christopher Evi-Parker * * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -193,47 +194,6 @@ RsGenExchange::RsGenExchange( VALIDATE_MAX_WAITING_TIME(60) { mDataAccess = new RsGxsDataAccess(gds); - - // Perform an early checking/cleaning of the db. Will eliminate groups and messages that do not match their hash - -#ifdef RS_DEEP_CHANNEL_INDEX - // This code is only called because it of deep indexing in channels. But loading - // the entire set of messages in order to provide indexing is pretty bad (very costly and slowly - // eats memory, as many tests have shown. Not because of leaks, but because new threads are - // apparently attributed large stacks and pages of memory are not regained by the system maybe because it thinks - // that RS will use them again. - // - // * the deep check should be implemented differently, in an incremental way. For instance in notifyChanges() of each - // service (e.g. channels here) should update the index when a new message is received. The question to how old messages - // are processed is open. I believe that they shouldn't. New users will progressively process them. - // - // * integrity check (re-hashing of message data) is not needed. Message signature already ensures that all messages received are - // unalterated. The only problem (possibly very rare) is that a message is locally corrupted and not deleted (because of no check). - // It will therefore never be replaced by the correct one from friends. The cost of re-hashing the whole db data regularly - // doesn't counterbalance such a low risk. - // - if(mServType == RS_SERVICE_GXS_TYPE_CHANNELS) - { - std::vector grpsToDel; - GxsMsgReq msgsToDel; - - RsGxsSinglePassIntegrityCheck::check(mServType,mGixs,mDataStore, - this, *mSerialiser, - grpsToDel,msgsToDel); - - for(auto& grpId: grpsToDel) - { - uint32_t token2=0; - deleteGroup(token2,grpId); - } - - if(!msgsToDel.empty()) - { - uint32_t token1=0; - deleteMsgs(token1,msgsToDel); - } - } -#endif } void RsGenExchange::setNetworkExchangeService(RsNetworkExchangeService *ns) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e1b70a670..8038b63f4 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Christopher Evi-Parker * + * Copyright (C) 2012 Christopher Evi-Parker * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -5204,13 +5206,14 @@ TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_st return mGxsNetTunnel->turtleSearchRequest(match_string,this) ; } -#ifndef RS_DEEP_CHANNEL_INDEX static bool termSearch(const std::string& src, const std::string& substring) { - /* always ignore case */ - return src.end() != std::search( src.begin(), src.end(), substring.begin(), substring.end(), RsRegularExpression::CompareCharIC() ); + /* always ignore case */ + return src.end() != std::search( + src.begin(), src.end(), substring.begin(), substring.end(), + RsRegularExpression::CompareCharIC() ); } -#endif // ndef RS_DEEP_CHANNEL_INDEX + bool RsGxsNetService::retrieveDistantSearchResults(TurtleRequestId req,std::map& group_infos) { @@ -5246,7 +5249,8 @@ bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id) return true ; } -void RsGxsNetService::receiveTurtleSearchResults( TurtleRequestId req, const std::list& group_infos ) +void RsGxsNetService::receiveTurtleSearchResults( + TurtleRequestId req, const std::list& group_infos ) { std::set groupsToNotifyResults; @@ -5276,26 +5280,20 @@ void RsGxsNetService::receiveTurtleSearchResults( TurtleRequestId req, const std for (const RsGxsGroupSummary& gps : group_infos) { -#ifndef RS_DEEP_CHANNEL_INDEX +#ifdef TO_REMOVE + /* Because of deep search is enabled search results may bring more + * info then we already have also about post that are indexed by + * xapian, so we don't apply this filter anymore. */ + /* Only keep groups that are not locally known, and groups that are * not already in the mDistantSearchResults structure. - * mDataStore may in some situations allocate an empty group meta data, so it's important - * to test that the group meta is both non null and actually corresponds to the group id we seek. */ + * mDataStore may in some situations allocate an empty group meta + * data, so it's important to test that the group meta is both non + * null and actually corresponds to the group id we seek. */ + auto& meta(grpMeta[gps.mGroupId]); + if(meta != nullptr && meta->mGroupId == gps.mGroupId) continue; +#endif // def TO_REMOVE - auto& meta(grpMeta[gps.mGroupId]); - - if(meta != nullptr && meta->mGroupId == gps.mGroupId) - continue; - -#ifdef NXS_NET_DEBUG_9 - std::cerr << " group " << gps.mGroupId << " is not known. Adding it to search results..." << std::endl; -#endif - -#else // ndef RS_DEEP_CHANNEL_INDEX - /* When deep search is enabled search results may bring more info - * then we already have also about post that are indexed by xapian, - * so we don't apply this filter in this case. */ -#endif const RsGxsGroupId& grpId(gps.mGroupId); groupsToNotifyResults.insert(grpId); @@ -5332,18 +5330,19 @@ void RsGxsNetService::receiveTurtleSearchResults( TurtleRequestId req, const std mObserver->receiveDistantSearchResults(req, grpId); } -void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len) +void RsGxsNetService::receiveTurtleSearchResults( + TurtleRequestId req, + const uint8_t* encrypted_group_data, uint32_t encrypted_group_data_len ) { #ifdef NXS_NET_DEBUG_8 GXSNETDEBUG___ << " received encrypted group data for turtle search request " << std::hex << req << std::dec << ": " << RsUtil::BinToHex(encrypted_group_data,encrypted_group_data_len,50) << std::endl; #endif - auto it = mSearchRequests.find(req); - - if(mSearchRequests.end() == it) - { - std::cerr << "(EE) received search results for unknown request " << std::hex << req << std::dec ; - return; - } + auto it = mSearchRequests.find(req); + if(mSearchRequests.end() == it) + { + RS_WARN("Received search results for unknown request: ", req); + return; + } RsGxsGroupId grpId = it->second; uint8_t encryption_master_key[32]; @@ -5417,56 +5416,36 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig mObserver->receiveDistantSearchResults(req, grpId); } +std::error_condition RsGxsNetService::distantSearchRequest( + rs_owner_ptr searchData, uint32_t dataSize, + RsServiceType serviceType, TurtleRequestId& requestId ) +{ + return mGxsNetTunnel->turtleSearchRequest( + searchData, dataSize, serviceType, requestId ); +} + +std::error_condition RsGxsNetService::handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) +{ + RS_DBG(""); + return mObserver->handleDistantSearchRequest( + requestData, requestSize, resultData, resultSize ); +} + +std::error_condition RsGxsNetService::receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) +{ + return mObserver->receiveDistantSearchResult( + requestId, resultData, resultSize ); +} + bool RsGxsNetService::search( const std::string& substring, std::list& group_infos ) { group_infos.clear(); -#ifdef RS_DEEP_CHANNEL_INDEX - -#warning TODO: filter deep index search result to non circle-restricted groups. -// /!\ -// /!\ These results should be filtered to only return results coming from a non restricted group! -// /!\ - - std::vector results; - DeepChannelsIndex::search(substring, results); - - for(auto dsr : results) - { - RsUrl rUrl(dsr.mUrl); - const auto& uQ(rUrl.query()); - auto rit = uQ.find("id"); - if(rit != rUrl.query().end()) - { - RsGroupNetworkStats stats; - RsGxsGroupId grpId(rit->second); - if( !grpId.isNull() && getGroupNetworkStats(grpId, stats) ) - { - RsGxsGroupSummary s; - - s.mGroupId = grpId; - - if((rit = uQ.find("name")) != uQ.end()) - s.mGroupName = rit->second; - if((rit = uQ.find("signFlags")) != uQ.end()) - s.mSignFlags = static_cast(std::stoul(rit->second)); - if((rit = uQ.find("publishTs")) != uQ.end()) - s.mPublishTs = static_cast(std::stoll(rit->second)); - if((rit = uQ.find("authorId")) != uQ.end()) - s.mAuthorId = RsGxsId(rit->second); - - s.mSearchContext = dsr.mSnippet; - - s.mNumberOfMessages = stats.mMaxVisibleCount; - s.mLastMessageTs = stats.mLastGroupModificationTS; - s.mPopularity = stats.mSuppliers; - - group_infos.push_back(s); - } - } - } -#else // RS_DEEP_CHANNEL_INDEX RsGxsGrpMetaTemporaryMap grpMetaMap; { RS_STACK_MUTEX(mNxsMutex) ; @@ -5492,12 +5471,11 @@ bool RsGxsNetService::search( const std::string& substring, group_infos.push_back(s); } -#endif // RS_DEEP_CHANNEL_INDEX #ifdef NXS_NET_DEBUG_8 GXSNETDEBUG___ << " performing local substring search in response to distant request. Found " << group_infos.size() << " responses." << std::endl; #endif - return !group_infos.empty(); + return !group_infos.empty(); } bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len) diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 295b8232a..a4b448003 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Christopher Evi-Parker * + * Copyright (C) 2012 Christopher Evi-Parker * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,8 +21,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RSGXSNETSERVICE_H -#define RSGXSNETSERVICE_H +#pragma once #include #include @@ -130,18 +131,53 @@ public: virtual bool msgAutoSync() const override { return mAllowMsgSync; } virtual bool grpAutoSync() const override { return mGrpAutoSync; } - /*! - * \brief Search methods. - * These four methods are used to request distant search and receive the results. - * \param group_id - */ - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id)override ; - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string)override ; - virtual bool search(const std::string& substring,std::list& group_infos) override ; + /// @see RsNetworkExchangeService + std::error_condition distantSearchRequest( + rs_owner_ptr searchData, uint32_t dataSize, + RsServiceType serviceType, TurtleRequestId& requestId ) override; + + /// @see RsNetworkExchangeService + std::error_condition handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; + + /// @see RsNetworkExchangeService + std::error_condition receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; + + /** Request group data via turtle search + * @param group_id */ + TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id) override; + + /** + * @brief Search for matching groups names over turtle search. + * @deprecated this method is kept mostly for retrocompatibility with older + * peers, newly implemented search functions should instead be based on the + * service generic search. + * @see RsNetworkExchangeService + */ + RS_DEPRECATED_FOR(distantSearchRequest) + TurtleRequestId turtleSearchRequest(const std::string& match_string) override; + + /** @see RsNetworkExchangeService + * @deprecated kept for retrocompatibility with older peers, new code should + * instead be based on the service generic search */ + RS_DEPRECATED_FOR(receiveDistantSearchResult) + void receiveTurtleSearchResults( + TurtleRequestId req, + const uint8_t* encrypted_group_data, + uint32_t encrypted_group_data_len ) override; + + /** + * @deprecated kept for retrocompatibility with older peers, new code should + * instead be based on the service generic search */ + RS_DEPRECATED_FOR(handleRemoteSearchRequest) + virtual bool search( const std::string& substring, + std::list& group_infos) override; virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)override ; virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos)override ; - virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)override ; virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &group_infos)override ; virtual bool clearDistantSearchResults(const TurtleRequestId& id)override ; @@ -629,5 +665,3 @@ private: bool mUseMetaCache; }; - -#endif // RSGXSNETSERVICE_H diff --git a/libretroshare/src/gxs/rsgxsnettunnel.cc b/libretroshare/src/gxs/rsgxsnettunnel.cc index 9b7a3089a..7f70ffa42 100644 --- a/libretroshare/src/gxs/rsgxsnettunnel.cc +++ b/libretroshare/src/gxs/rsgxsnettunnel.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2018 by Cyril Soler * + * Copyright (C) 2018 Cyril Soler * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -27,6 +29,8 @@ #include "gxs/rsnxs.h" #include "rsgxsnettunnel.h" +/*extern*/ RsGxsDistSync* rsGxsDistSync = nullptr; + //#define DEBUG_RSGXSNETTUNNEL 1 #define GXS_NET_TUNNEL_NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; } @@ -36,42 +40,93 @@ static const uint32_t RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_DATA = 1; static const uint32_t RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH = 100; -RsGxsDistSync *rsGxsDistSync = NULL; RsGxsNetTunnelService::RsGxsNetTunnelService(): mGxsNetTunnelMtx("GxsNetTunnel") { mRandomBias.clear(); - mLastKeepAlive = time(NULL) + (RSRandom::random_u32()%20); // adds some variance in order to avoid doing all this tasks at once across services - mLastAutoWash = time(NULL) + (RSRandom::random_u32()%20); - mLastDump = time(NULL) + (RSRandom::random_u32()%20); + /* adds some variance in order to avoid doing all this tasks at once across + * services */ + auto now = time(nullptr); + mLastKeepAlive = now + (RsRandom::random_u32()%20); + mLastAutoWash = now + (RsRandom::random_u32()%20); + mLastDump = now + (RsRandom::random_u32()%20); } -//===========================================================================================================================================// -// Transport Items // -//===========================================================================================================================================// +//============================================================================// +// Transport Items // +//============================================================================// -const uint16_t RS_SERVICE_TYPE_GXS_NET_TUNNEL = 0x2233 ; +enum class RsGxsNetTunnelItemSubtypes : uint8_t +{ + VIRTUAL_PEER = 0x01, + KEEP_ALIVE = 0x02, + + RANDOM_BIAS = 0x03, + + /// @deprecated kept only for retrocompatibility @see SERVICE_SEARCH_REQUEST + SEARCH_SUBSTRING = 0x04, + + SEARCH_GROUP_REQUEST = 0x05, + + // SEARCH_GROUP_SUMMARY = 0x06, removed + + SEARCH_GROUP_DATA = 0x07, + + /// @deprecated kept only for retrocompatibility @see SERVICE_SEARCH_REPLY + SEARCH_GROUP_SUMMARY = 0x08, + + /** Generic search request generated and handled by specific service + * (channels, forums...) */ + SERVICE_SEARCH_REQUEST = 0x09, + + /** Generic search reply generated and handled by specific service + * (channels, forums...) */ + SERVICE_SEARCH_REPLY = 0x0a +}; + +RS_DEPRECATED_FOR(RsServiceType::GXS_DISTANT) +constexpr uint16_t RS_SERVICE_TYPE_GXS_NET_TUNNEL = + static_cast(RsServiceType::GXS_DISTANT); + +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER = 0x01 ; +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE = 0x02 ; +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_RANDOM_BIAS = 0x03 ; +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING = 0x04 ; +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST = 0x05 ; -// const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY = 0x06; // DEPRECATED +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA = 0x07 ; +RS_DEPRECATED_FOR(RsGxsNetTunnelItemSubtypes) const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY = 0x08; +// Do not add new subitems types as const, use RsGxsNetTunnelItemSubtypes instead -class RsGxsNetTunnelItem: public RsItem +struct RsGxsNetTunnelItem: RsItem { public: - explicit RsGxsNetTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_NET_TUNNEL,item_subtype) + explicit RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes subtype): + RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_NET_TUNNEL, + static_cast(subtype) ) + { + /* no priority. All items are encapsulated into generic Turtle items + * anyway. */ + } + + virtual ~RsGxsNetTunnelItem() = default; + virtual void clear() {} + + RS_DEPRECATED_FOR("RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes subtype)") + explicit RsGxsNetTunnelItem(uint8_t item_subtype): + RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_NET_TUNNEL, + item_subtype ) { // no priority. All items are encapsulated into generic Turtle items anyway. } - - virtual ~RsGxsNetTunnelItem() {} - virtual void clear() {} }; class RsGxsNetTunnelVirtualPeerItem: public RsGxsNetTunnelItem @@ -113,7 +168,86 @@ public: Bias20Bytes mRandomBias; // Cannot be a simple char[] because of serialization. }; -class RsGxsNetTunnelTurtleSearchSubstringItem: public RsGxsNetTunnelItem +struct RsGxsServiceTurtleSearchReqItem: RsGxsNetTunnelItem +{ + RsGxsServiceTurtleSearchReqItem(): + RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REQUEST), + mServiceType(RsServiceType::NONE), mSearchData(nullptr), + mSearchDataSize(0) {} + + explicit RsGxsServiceTurtleSearchReqItem(RsServiceType service): + RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REQUEST), + mServiceType(service), mSearchData(nullptr), mSearchDataSize(0) {} + + /// Type of the service which originated the search request + RsServiceType mServiceType; + + uint8_t* mSearchData; /// Service search request data + uint32_t mSearchDataSize; /// Search data size + + /// @see RsSerializable + void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mServiceType); + + RsTypeSerializer::RawMemoryWrapper prox(mSearchData, mSearchDataSize); + RsTypeSerializer::serial_process(j, ctx, prox, "mSearchData"); + } + + /// @see RsItem + void clear() override + { + free(mSearchData); + mSearchData = nullptr; + mSearchDataSize = 0; + } + + ~RsGxsServiceTurtleSearchReqItem() override { clear(); } +}; + +struct RsGxsServiceTurtleSearchReplyItem: RsGxsNetTunnelItem +{ + RsGxsServiceTurtleSearchReplyItem(): + RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REPLY), + mServiceType(RsServiceType::NONE), mReplyData(nullptr), + mReplyDataSize(0) {} + + explicit RsGxsServiceTurtleSearchReplyItem(RsServiceType service): + RsGxsNetTunnelItem(RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REPLY), + mServiceType(service), mReplyData(nullptr), mReplyDataSize(0) {} + + /// Type of the service which originated the search request + RsServiceType mServiceType; + + uint8_t* mReplyData; /// Service search reply data + uint32_t mReplyDataSize; /// Search reply data size + + /// @see RsSerializable + void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mServiceType); + + RsTypeSerializer::RawMemoryWrapper prox(mReplyData, mReplyDataSize); + RsTypeSerializer::serial_process(j, ctx, prox, "mSearchData"); + } + + /// @see RsItem + void clear() override + { + free(mReplyData); + mReplyData = nullptr; + mReplyDataSize = 0; + } + + ~RsGxsServiceTurtleSearchReplyItem() override { clear(); } +}; + +class RS_DEPRECATED_FOR(RsGxsServiceTurtleSearchItem) +RsGxsNetTunnelTurtleSearchSubstringItem: public RsGxsNetTunnelItem { public: explicit RsGxsNetTunnelTurtleSearchSubstringItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING) {} @@ -164,6 +298,7 @@ public: RsTypeSerializer::serial_process(j,ctx,group_infos,"group_infos") ; } }; + class RsGxsNetTunnelTurtleSearchGroupDataItem: public RsGxsNetTunnelItem { public: @@ -193,28 +328,41 @@ public: class RsGxsNetTunnelSerializer: public RsServiceSerializer { public: - RsGxsNetTunnelSerializer() :RsServiceSerializer(RS_SERVICE_TYPE_GXS_NET_TUNNEL) {} + RsGxsNetTunnelSerializer(): + RsServiceSerializer(RS_SERVICE_TYPE_GXS_NET_TUNNEL) {} virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const { if(service != RS_SERVICE_TYPE_GXS_NET_TUNNEL) { - GXS_NET_TUNNEL_ERROR() << "received item with wrong service ID " << std::hex << service << std::dec << std::endl; - return NULL ; + RS_ERR( "received item with wrong service ID ", service); + print_stacktrace(); + return nullptr; } - switch(item_subtype) + switch(static_cast(item_subtype)) { - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER : return new RsGxsNetTunnelVirtualPeerItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE : return new RsGxsNetTunnelKeepAliveItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_RANDOM_BIAS : return new RsGxsNetTunnelRandomBiasItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING : return new RsGxsNetTunnelTurtleSearchSubstringItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST : return new RsGxsNetTunnelTurtleSearchGroupRequestItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY : return new RsGxsNetTunnelTurtleSearchGroupSummaryItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem; + case RsGxsNetTunnelItemSubtypes::VIRTUAL_PEER: + return new RsGxsNetTunnelVirtualPeerItem; + case RsGxsNetTunnelItemSubtypes::KEEP_ALIVE: + return new RsGxsNetTunnelKeepAliveItem; + case RsGxsNetTunnelItemSubtypes::RANDOM_BIAS: + return new RsGxsNetTunnelRandomBiasItem; + case RsGxsNetTunnelItemSubtypes::SEARCH_SUBSTRING: + return new RsGxsNetTunnelTurtleSearchSubstringItem; + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_REQUEST: + return new RsGxsNetTunnelTurtleSearchGroupRequestItem; + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_SUMMARY: + return new RsGxsNetTunnelTurtleSearchGroupSummaryItem; + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_DATA: + return new RsGxsNetTunnelTurtleSearchGroupDataItem; + case RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REQUEST: + return new RsGxsServiceTurtleSearchReqItem; + case RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REPLY: + return new RsGxsServiceTurtleSearchReplyItem; default: - GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << (int)item_subtype << std::dec << " is not handled!" << std::endl; - return NULL ; + RS_ERR("Unkonown item type: ", static_cast(item_subtype)); + return nullptr; } } }; @@ -993,7 +1141,9 @@ TurtleRequestId RsGxsNetTunnelService::turtleGroupRequest(const RsGxsGroupId& gr return mTurtle->turtleSearch(mem,size,this) ; } -TurtleRequestId RsGxsNetTunnelService::turtleSearchRequest(const std::string& match_string,RsNetworkExchangeService *client_service) +TurtleRequestId RsGxsNetTunnelService::turtleSearchRequest( + const std::string& match_string, + RsNetworkExchangeService* client_service ) { GXS_NET_TUNNEL_DEBUG() << ": starting a turtle search request for string \"" << match_string << "\"" << std::endl; @@ -1002,7 +1152,7 @@ TurtleRequestId RsGxsNetTunnelService::turtleSearchRequest(const std::string& ma search_item.service = client_service->serviceType() ; uint32_t size = RsGxsNetTunnelSerializer().size(&search_item) ; - unsigned char *mem = (unsigned char*)rs_malloc(size) ; + uint8_t* mem = rs_malloc(size); if(mem == NULL) return 0 ; @@ -1013,151 +1163,304 @@ TurtleRequestId RsGxsNetTunnelService::turtleSearchRequest(const std::string& ma return mTurtle->turtleSearch(mem,size,this) ; } -bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_data,uint32_t search_request_data_len,unsigned char *& search_result_data,uint32_t& search_result_data_size,uint32_t& max_allowed_hits) +std::error_condition RsGxsNetTunnelService::turtleSearchRequest( + rs_owner_ptr searchData, uint32_t dataSize, + RsServiceType serviceType, TurtleRequestId& requestId ) { - GXS_NET_TUNNEL_DEBUG() << ": received a request." << std::endl; + if(!searchData || !dataSize || serviceType == RsServiceType::NONE) + return std::errc::invalid_argument; - RsItem *item = RsGxsNetTunnelSerializer().deserialise(search_request_data,&search_request_data_len) ; + RsGxsServiceTurtleSearchReqItem searchItem(serviceType); + searchItem.mSearchDataSize = dataSize; + searchItem.mSearchData = searchData; - RsGxsNetTunnelTurtleSearchSubstringItem *substring_sr = dynamic_cast(item) ; + RsGxsNetTunnelSerializer tSerializer; - if(substring_sr != NULL) - { - GXS_NET_TUNNEL_DEBUG() << " : type is substring for service " << std::hex << (int)substring_sr->service << std::dec << std::endl; + uint32_t size = tSerializer.size(&searchItem); + uint8_t* buf = rs_malloc(size); - max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH ; + tSerializer.serialise(&searchItem, buf, &size); - std::list results ; - RsNetworkExchangeService *service = nullptr; + requestId = mTurtle->turtleSearch(buf, size, this); + if(!requestId) return std::errc::result_out_of_range; - { - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - auto it = mSearchableServices.find(substring_sr->service) ; - - if(it != mSearchableServices.end()) - service = it->second; - } - - if(service != nullptr && service->search(substring_sr->substring_match,results)) - { - RsGxsNetTunnelTurtleSearchGroupSummaryItem search_result_item ; - - GXS_NET_TUNNEL_DEBUG() << " : " << results.size() << " result found. Sending back." << std::endl; - - search_result_item.service = substring_sr->service ; - search_result_item.group_infos = results ; - - search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ; - search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ; - - delete item; - - if(search_result_data == NULL) - return false ; - - RsGxsNetTunnelSerializer().serialise(&search_result_item,search_result_data,&search_result_data_size); - - return true ; - } - } - - RsGxsNetTunnelTurtleSearchGroupRequestItem *substring_gr = dynamic_cast(item) ; - - if(substring_gr != NULL) - { - RS_STACK_MUTEX(mGxsNetTunnelMtx); - auto it = mSearchableServices.find(substring_gr->service) ; - - max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_DATA ; - - unsigned char *encrypted_group_data = NULL ; - uint32_t encrypted_group_data_len = 0 ; - - if(it != mSearchableServices.end() && it->second->search(substring_gr->hashed_group_id,encrypted_group_data,encrypted_group_data_len)) - { - RsGxsNetTunnelTurtleSearchGroupDataItem search_result_item ; - - search_result_item.service = substring_gr->service ; - search_result_item.encrypted_group_data = encrypted_group_data ; - search_result_item.encrypted_group_data_len = encrypted_group_data_len; - - search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ; - search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ; - - if(search_result_data == NULL) - return false ; - - RsGxsNetTunnelSerializer().serialise(&search_result_item,search_result_data,&search_result_data_size); - - delete item; - return true ; - } - } - - delete item; - return false ; + return std::error_condition(); } -void RsGxsNetTunnelService::receiveSearchResult(TurtleSearchRequestId request_id,unsigned char *search_result_data,uint32_t search_result_data_len) +rs_view_ptr +RsGxsNetTunnelService::retrievieSearchableServiceLocking(uint16_t serviceType) { - RsItem *item = RsGxsNetTunnelSerializer().deserialise(search_result_data,&search_result_data_len); + RS_STACK_MUTEX(mGxsNetTunnelMtx); + auto it = mSearchableServices.find(serviceType); + if( it != mSearchableServices.end()) return it->second; + return nullptr; +} - GXS_NET_TUNNEL_DEBUG() << " : received search result for search request " << std::hex << request_id << "" << std::endl; +bool RsGxsNetTunnelService::receiveSearchRequest( + uint8_t* search_request_data, uint32_t search_request_data_len, + uint8_t*& search_result_data, uint32_t& search_result_data_size, + uint32_t& max_allowed_hits ) +{ + /* Must return true only if there are matching results available, false in + * all other cases. @see RsTurleClientService */ - RsGxsNetTunnelTurtleSearchGroupSummaryItem *result_gs = dynamic_cast(item) ; + RS_DBG3(""); - if(result_gs != NULL) + RsGxsNetTunnelSerializer tSerializer; + + std::unique_ptr item; + item.reset(tSerializer.deserialise( + search_request_data, &search_request_data_len )); + + if(!item) { - GXS_NET_TUNNEL_DEBUG() << " : result is of type group summary result for service " << result_gs->service << std::dec << ": " << std::endl; - -#ifdef DEBUG_RSGXSNETTUNNEL - for(auto it(result_gs->group_infos.begin());it!=result_gs->group_infos.end();++it) - std::cerr << " group " << (*it).mGroupId << ": " << (*it).mGroupName << ", " << (*it).mNumberOfMessages << " messages, last is " << time(NULL)-(*it).mLastMessageTs << " secs ago." << std::endl; -#endif - - auto it = mSearchableServices.find(result_gs->service) ; - - if(it == mSearchableServices.end()) - { - GXS_NET_TUNNEL_ERROR() << ": deserialized item is for service " << std::hex << result_gs->service << std::dec << " that is not in the searchable services list." << std::endl; - delete item; - return ; - } - - it->second->receiveTurtleSearchResults(request_id,result_gs->group_infos) ; - - delete item; - return ; + RS_ERR( "Deserialization failed: ", + search_request_data, search_request_data_len, item.get() ); + print_stacktrace(); + return false; } - RsGxsNetTunnelTurtleSearchGroupDataItem *result_gd = dynamic_cast(item) ; - - if(result_gd != NULL) - { - GXS_NET_TUNNEL_DEBUG() << " : result is of type group data for service " << result_gd->service << std::dec << ": " << std::endl; - - auto it = mSearchableServices.find(result_gd->service) ; - - if(it == mSearchableServices.end()) + switch(static_cast(item->PacketSubType())) + { + case RsGxsNetTunnelItemSubtypes::SEARCH_SUBSTRING: + { + if(!search_result_data) { - GXS_NET_TUNNEL_ERROR() << ": deserialized item is for service " << std::hex << result_gd->service << std::dec << " that is not in the searchable services list." << std::endl; - delete item; - return ; + RS_ERR( "Got item with TURTLE_SEARCH_SUBSTRING without space for " + "results!" ); + print_stacktrace(); + break; } - it->second->receiveTurtleSearchResults(request_id,result_gd->encrypted_group_data,result_gd->encrypted_group_data_len) ; + auto substring_sr = + dynamic_cast(item.get()); + if(!substring_sr) + { + RS_WARN( "Got item with TURTLE_SEARCH_SUBSTRING subtype: ", + item->PacketSubType(), " but casting failed!"); + break; + } - result_gd->encrypted_group_data = NULL ; // prevents deletion - delete item; + max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH; + std::list results; + auto tService = retrievieSearchableServiceLocking(substring_sr->service); + if(tService && tService->search(substring_sr->substring_match, results)) + { + RsGxsNetTunnelTurtleSearchGroupSummaryItem search_result_item; + search_result_item.service = substring_sr->service; + search_result_item.group_infos = results; + search_result_data_size = tSerializer.size(&search_result_item); + search_result_data = rs_malloc(search_result_data_size); - return ; - } + tSerializer.serialise( + &search_result_item, search_result_data, + &search_result_data_size ); - GXS_NET_TUNNEL_ERROR() << ": deserialized item is of unknown type. Dropping!" << std::endl; + return true; + } + + break; + } + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_REQUEST: + { + auto *substring_gr = + dynamic_cast(item.get()); + + if(!substring_gr) + { + RS_WARN( "Got item with TURTLE_SEARCH_GROUP_REQUEST subtype: ", + item->PacketSubType(), " but casting failed!" ); + break; + } + + max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_DATA; + uint8_t* encrypted_group_data = nullptr; + uint32_t encrypted_group_data_len = 0; + + auto tService = retrievieSearchableServiceLocking(substring_gr->service); + if(tService && tService->search( + substring_gr->hashed_group_id, + encrypted_group_data, encrypted_group_data_len )) + { + RsGxsNetTunnelTurtleSearchGroupDataItem search_result_item; + search_result_item.service = substring_gr->service; + search_result_item.encrypted_group_data = encrypted_group_data; + search_result_item.encrypted_group_data_len = encrypted_group_data_len; + search_result_data_size = tSerializer.size(&search_result_item); + search_result_data = rs_malloc(search_result_data_size); + + tSerializer.serialise( + &search_result_item, + search_result_data, &search_result_data_size ); + return true; + } + break; + } + case RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REQUEST: + { + RS_DBG3("SERVICE_SEARCH_REQUEST"); + + auto searchItem = + static_cast(item.get()); + + max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH; + + uint16_t sType = static_cast(searchItem->mServiceType); + auto sService = retrievieSearchableServiceLocking(sType); + if(!sService) + { + RS_WARN("Got search request for non searchable service: ", sType); + break; + } + + RsGxsServiceTurtleSearchReplyItem replyItem(searchItem->mServiceType); + + auto errc = sService->handleDistantSearchRequest( + searchItem->mSearchData, searchItem->mSearchDataSize, + replyItem.mReplyData, replyItem.mReplyDataSize ); + if(errc) + { + // Some error has been reported by the searchable service + RS_WARN("searchable service: ", sType , " reported: ", errc); + break; + } + + if( (!replyItem.mReplyData && replyItem.mReplyDataSize) || + (replyItem.mReplyData && !replyItem.mReplyDataSize) ) + { + // Inconsistent behaviour from searcheable service + RS_ERR( "searchable service: ", sType , " silently failed handling " + "inconsistent result mReplyData: ", replyItem.mReplyData, + " mReplyDataSize: ", replyItem.mReplyDataSize ); + break; + } + + /* Our node have 0 matching results */ + if(!replyItem.mReplyData && !replyItem.mReplyDataSize) + break; + + search_result_data_size = tSerializer.size(&replyItem); + search_result_data = rs_malloc(search_result_data_size); + + tSerializer.serialise( + &replyItem, search_result_data, &search_result_data_size ); + + return true; + } + default: + RS_WARN("Got unknown item type: ", item->PacketSubType()); + break; + } + + return false; } -void RsGxsNetTunnelService::getStatistics(std::map& groups, std::map& virtual_peers, std::map &turtle_vpid_to_net_tunnel_vpid, Bias20Bytes& bias ) const +void RsGxsNetTunnelService::receiveSearchResult( + TurtleSearchRequestId request_id, + uint8_t* search_result_data, uint32_t search_result_data_len ) +{ + RS_DBG3(request_id); + + std::unique_ptr item; + item.reset(RsGxsNetTunnelSerializer().deserialise( + search_result_data,&search_result_data_len )); + + auto castFailedWarn = [](const uint8_t subtype) + { + RS_WARN( "Got item with subtype: ", subtype, + " but cast failed!" ); + }; + + auto searchableServiceGet = [this](const auto pservice) + { + auto service = static_cast(pservice); + auto it = mSearchableServices.find(service); + if(it == mSearchableServices.end()) + { + RS_WARN( "got item for service ", service, + " which is not in the searchable services list." ); + return static_cast(nullptr); + } + + return it->second; + }; + + const auto tSubtype = item->PacketSubType(); + switch (static_cast(tSubtype)) + { + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_SUMMARY: + { + auto result_gs = + dynamic_cast( + item.get() ); + + if(!result_gs) + { + castFailedWarn(tSubtype); + break; + } + + RS_DBG2( " got result is of type group summary result for service ", + result_gs->service ); + + auto service = searchableServiceGet(result_gs->service); + if(service) + service->receiveTurtleSearchResults( + request_id, result_gs->group_infos ); + return; + } + case RsGxsNetTunnelItemSubtypes::SEARCH_GROUP_DATA: + { + auto result_gd = + dynamic_cast(item.get()); + + if(!result_gd) + { + castFailedWarn(tSubtype); + break; + } + + RS_DBG2("got group data result for service: ", result_gd->service); + + auto service = searchableServiceGet(result_gd->service); + if(service) + service->receiveTurtleSearchResults( + request_id, + result_gd->encrypted_group_data, + result_gd->encrypted_group_data_len ); + + /* Ensure ownershipt is passed down preventing deletion */ + result_gd->encrypted_group_data = nullptr; + break; + } + case RsGxsNetTunnelItemSubtypes::SERVICE_SEARCH_REPLY: + { + auto searchReply = + static_cast(item.get()); + + auto service = searchableServiceGet(searchReply->mServiceType); + if(service) + service->receiveDistantSearchResult( + request_id, + searchReply->mReplyData, + searchReply->mReplyDataSize ); + + /* Ensure memory ownership is passed down preventing deletion */ + searchReply->mReplyData = nullptr; + break; + } + default: + RS_WARN("got item of unknown type: ", item->PacketSubType()); + break; + } +} + +void RsGxsNetTunnelService::getStatistics( + std::map& groups, + std::map& virtual_peers, + std::map& + turtle_vpid_to_net_tunnel_vpid, Bias20Bytes& bias ) const { groups = mGroups ; virtual_peers = mVirtualPeers ; diff --git a/libretroshare/src/gxs/rsgxsnettunnel.h b/libretroshare/src/gxs/rsgxsnettunnel.h index 7c18ab54c..c7f9ac1f3 100644 --- a/libretroshare/src/gxs/rsgxsnettunnel.h +++ b/libretroshare/src/gxs/rsgxsnettunnel.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2018 by Cyril Soler * + * Copyright (C) 2018 Cyril Soler * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -23,6 +25,7 @@ #pragma once #include +#include #include "turtle/p3turtle.h" #include "retroshare/rsgxsdistsync.h" @@ -100,7 +103,7 @@ // and there is no way to prevent it. We therefore rely on GXS data integrity system to prevent this to happen. // -class RsGxsNetTunnelItem ; +struct RsGxsNetTunnelItem; class RsNetworkExchangeService ; class RsGxsNetTunnelService: @@ -108,8 +111,8 @@ class RsGxsNetTunnelService: public RsGxsDistSync { public: - RsGxsNetTunnelService() ; - virtual ~RsGxsNetTunnelService() ; + RsGxsNetTunnelService(); + ~RsGxsNetTunnelService() override; /*! * \brief registerSearchableService @@ -181,24 +184,38 @@ public: */ void dump() const; - /*! - * \brief connectToTurtleRouter - * Should be called after allocating a RsGxsNetTunnelService - * \param tr turtle router object - */ - virtual void connectToTurtleRouter(p3turtle *tr) ; + /*! + * Should be called after allocating a RsGxsNetTunnelService + * \param tr turtle router object + */ + void connectToTurtleRouter(p3turtle *tr) override; - TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id, RsNetworkExchangeService *client_service) ; - TurtleRequestId turtleSearchRequest(const std::string& match_string,RsNetworkExchangeService *client_service) ; + /** Gxs services (channels, forums...) are supposed to use this to request + * searches on distant peers */ + std::error_condition turtleSearchRequest( + rs_owner_ptr searchData, uint32_t dataSize, + RsServiceType serviceType, TurtleRequestId& requestId ); - /*! - * \brief receiveSearchRequest - * See RsTurtleClientService::@ - */ - virtual bool receiveSearchRequest(unsigned char *search_request_data, uint32_t search_request_data_len, unsigned char *& search_result_data, uint32_t& search_result_data_len, uint32_t &max_allowed_hits); - virtual void receiveSearchResult(TurtleSearchRequestId request_id,unsigned char *search_result_data,uint32_t search_result_data_len); + ///@see RsTurtleClientService + bool receiveSearchRequest( + unsigned char* search_request_data, + uint32_t search_request_data_len, + unsigned char*& search_result_data, + uint32_t& search_result_data_len, + uint32_t& max_allowed_hits ) override; - void threadTick() override; /// @see RsTickingThread + ///@see RsTurtleClientService + virtual void receiveSearchResult( + TurtleSearchRequestId request_id, + unsigned char* search_result_data, + uint32_t search_result_data_len ) override; + + TurtleRequestId turtleGroupRequest( + const RsGxsGroupId& group_id, + RsNetworkExchangeService* client_service ); + + /// @see RsTickingThread + void threadTick() override; // Overloads p3Config @@ -213,6 +230,11 @@ public: std::map& turtle_vpid_to_net_tunnel_vpid, Bias20Bytes& bias) const; + RS_DEPRECATED + TurtleRequestId turtleSearchRequest( + const std::string& match_string, + RsNetworkExchangeService* client_service ); + protected: // interaction with turtle router @@ -233,6 +255,8 @@ private: void sendKeepAlivePackets() ; void handleIncoming(RsGxsNetTunnelItem *item) ; void flush_pending_items(); + rs_view_ptr retrievieSearchableServiceLocking( + uint16_t serviceType ); std::map mGroups ; // groups on the client and server side diff --git a/libretroshare/src/gxs/rsgxsutil.cc b/libretroshare/src/gxs/rsgxsutil.cc index f64fd236f..4a0f3e372 100644 --- a/libretroshare/src/gxs/rsgxsutil.cc +++ b/libretroshare/src/gxs/rsgxsutil.cc @@ -3,8 +3,8 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2013-2013 by Christopher Evi-Parker * - * Copyright (C) 2018 Gioacchino Mazzurco * + * Copyright (C) 2013 Christopher Evi-Parker * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -29,12 +29,6 @@ #include "pqi/pqihash.h" #include "gxs/rsgixs.h" -#ifdef RS_DEEP_CHANNEL_INDEX -# include "deep_search/channelsindex.hpp" -# include "services/p3gxschannels.h" -# include "rsitems/rsgxschannelitems.h" -#endif - // The goals of this set of methods is to check GXS messages and groups for consistency, mostly // re-ferifying signatures and hashes, to make sure that the data hasn't been tempered. This shouldn't // happen anyway, but we still conduct these test as an extra safety measure. @@ -197,9 +191,8 @@ bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector& grpsToDel, GxsMsgReq& msgsToDel) +bool RsGxsSinglePassIntegrityCheck::check( + uint16_t service_type, RsGixs* mgixs, RsGeneralDataService* mds, + std::vector& grpsToDel, GxsMsgReq& msgsToDel ) { #ifdef DEBUG_GXSUTIL GXSUTIL_DEBUG() << "Parsing all groups and messages data in service " << std::hex << mds->serviceType() << " for integrity check. Could take a while..." << std::endl; #endif -#ifdef RS_DEEP_CHANNEL_INDEX - bool isGxsChannels = mGenExchangeClient->serviceType() == RS_SERVICE_GXS_TYPE_CHANNELS; - std::set indexedGroups; -#endif // first take out all the groups std::map grp; @@ -393,55 +380,14 @@ bool RsGxsSinglePassIntegrityCheck::check(uint16_t service_type, RsGixs *mgixs, } else msgIds.erase(msgIds.find(grp->grpId)); // could not get them, so group is removed from list. - -#ifdef RS_DEEP_CHANNEL_INDEX - // This should be moved to p3gxschannels. It is really not the place for this here! - - if( isGxsChannels - && grp->metaData->mCircleType == GXS_CIRCLE_TYPE_PUBLIC - && grp->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) - { - RsGxsGrpMetaData meta; - meta.deserialise(grp->meta.bin_data, grp->meta.bin_len); - - uint32_t blz = grp->grp.bin_len; - RsItem* rIt = mSerializer.deserialise(grp->grp.bin_data, - &blz); - - if( RsGxsChannelGroupItem* cgIt = - dynamic_cast(rIt) ) - { - RsGxsChannelGroup cg; - cgIt->toChannelGroup(cg, false); - cg.mMeta = meta; - - indexedGroups.insert(grp->grpId); - DeepChannelsIndex::indexChannelGroup(cg); - } - else - { - std::cerr << __PRETTY_FUNCTION__ << " Group: " - << meta.mGroupId.toStdString() << " " - << meta.mGroupName - << " doesn't seems a channel, please " - << "report to developers" - << std::endl; - print_stacktrace(); - } - - delete rIt; - } -#endif // def RS_DEEP_CHANNEL_INDEX - } - else - { - std::cerr << __PRETTY_FUNCTION__ <<" (EE) deleting group " << grp->grpId << " with wrong hash or null/corrupted meta data. meta=" << grp->metaData << std::endl; - grpsToDel.push_back(grp->grpId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelFromIndex(grp->grpId); -#endif // def RS_DEEP_CHANNEL_INDEX } + else + { + RS_WARN( "deleting group ", grp->grpId, + " with wrong hash or null/corrupted meta data. meta=", + grp->metaData ); + grpsToDel.push_back(grp->grpId); + } delete grp; } @@ -469,15 +415,9 @@ bool RsGxsSinglePassIntegrityCheck::check(uint16_t service_type, RsGixs *mgixs, if(nxsMsg) nxsMsgS.insert(nxsMsg->msgId); - for (auto& msgId:msgIdV) - if(nxsMsgS.find(msgId) == nxsMsgS.end()) - { - msgsToDel[grpId].insert(msgId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelPostFromIndex(grpId, msgId); -#endif // def RS_DEEP_CHANNEL_INDEX - } + for (auto& msgId:msgIdV) + if(nxsMsgS.find(msgId) == nxsMsgS.end()) + msgsToDel[grpId].insert(msgId); } for(auto mit = msgs.begin(); mit != msgs.end(); ++mit) @@ -495,54 +435,11 @@ bool RsGxsSinglePassIntegrityCheck::check(uint16_t service_type, RsGixs *mgixs, if(msg->metaData == NULL || currHash != msg->metaData->mHash) { - std::cerr << __PRETTY_FUNCTION__ <<" (EE) deleting message " << msg->msgId << " in group " << msg->grpId << " with wrong hash or null/corrupted meta data. meta=" << (void*)msg->metaData << std::endl; + RS_WARN( "deleting message ", msg->msgId, " in group ", + msg->grpId, + " with wrong hash or null/corrupted meta data. meta=", + static_cast(msg->metaData) ); msgsToDel[msg->grpId].insert(msg->msgId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelPostFromIndex( - msg->grpId, msg->msgId ); -#endif // def RS_DEEP_CHANNEL_INDEX - } - else if (subscribed_groups.count(msg->metaData->mGroupId)) - { -#ifdef RS_DEEP_CHANNEL_INDEX - // This should be moved to p3gxschannels. It is really not the place for this here! - - if( isGxsChannels && indexedGroups.count(msg->metaData->mGroupId) ) - { - RsGxsMsgMetaData meta; - meta.deserialise(msg->meta.bin_data, &msg->meta.bin_len); - - uint32_t blz = msg->msg.bin_len; - RsItem* rIt = mSerializer.deserialise(msg->msg.bin_data, - &blz); - - if( RsGxsChannelPostItem* cgIt = - dynamic_cast(rIt) ) - { - RsGxsChannelPost cg; - cgIt->toChannelPost(cg, false); - cg.mMeta = meta; - - DeepChannelsIndex::indexChannelPost(cg); - } - else if(dynamic_cast(rIt)) {} - else if(dynamic_cast(rIt)) {} - else - { - std::cerr << __PRETTY_FUNCTION__ << " Message: " - << meta.mMsgId.toStdString() - << " in group: " - << meta.mGroupId.toStdString() << " " - << " doesn't seems a channel post, please " - << "report to developers" - << std::endl; - print_stacktrace(); - } - - delete rIt; - } -#endif // def RS_DEEP_CHANNEL_INDEX } delete msg; diff --git a/libretroshare/src/gxs/rsgxsutil.h b/libretroshare/src/gxs/rsgxsutil.h index 34f1b2baa..21fd6bb06 100644 --- a/libretroshare/src/gxs/rsgxsutil.h +++ b/libretroshare/src/gxs/rsgxsutil.h @@ -3,8 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2013-2013 by Christopher Evi-Parker * - * Copyright (C) 2018 Gioacchino Mazzurco * + * Copyright (C) 2013 Christopher Evi-Parker * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -162,18 +163,9 @@ class RsGxsIntegrityCheck : public RsThread enum CheckState { CheckStart, CheckChecking }; public: - - - /*! - * - * @param dataService - * @param mGroupTS - * @param chunkSize - * @param sleepPeriod - */ - RsGxsIntegrityCheck(RsGeneralDataService* const dataService, - RsGenExchange *genex, RsSerialType&, - RsGixs *gixs); + RsGxsIntegrityCheck( RsGeneralDataService* const dataService, + RsGenExchange* genex, RsSerialType&, + RsGixs* gixs ); static bool check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds); bool isDone(); @@ -201,19 +193,9 @@ private: class RsGxsSinglePassIntegrityCheck { public: - - /*! - * - * @param dataService - * @param mGroupTS - * @param chunkSize - * @param sleepPeriod - */ - static bool check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds -#ifdef RS_DEEP_CHANNEL_INDEX - , RsGenExchange* mGenExchangeClient, RsSerialType& mSerializer -#endif - , std::vector& grpsToDel, GxsMsgReq& msgsToDel); + static bool check( + uint16_t service_type, RsGixs* mgixs, RsGeneralDataService* mds, + std::vector& grpsToDel, GxsMsgReq& msgsToDel ); }; class GroupUpdate diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index fb6238f92..2f9bb25a6 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -3,8 +3,10 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2011-2011 by Robert Fernie * - * Copyright 2011-2011 by Christopher Evi-Parker * + * Copyright (C) 2011 Robert Fernie * + * Copyright (C) 2011 Christopher Evi-Parker * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -20,17 +22,15 @@ * along with this program. If not, see . * * * *******************************************************************************/ - -#ifndef RSGNP_H -#define RSGNP_H +#pragma once #include #include -#include "util/rstime.h" #include #include #include +#include "util/rstime.h" #include "services/p3service.h" #include "retroshare/rsreputations.h" #include "retroshare/rsidentity.h" @@ -61,9 +61,8 @@ class RsNetworkExchangeService { public: - - RsNetworkExchangeService(){ return;} - virtual ~RsNetworkExchangeService() {} + RsNetworkExchangeService() = default; + virtual ~RsNetworkExchangeService() = default; virtual uint16_t serviceType() const =0; /*! @@ -85,9 +84,24 @@ public: virtual bool msgAutoSync() const =0; virtual bool grpAutoSync() const =0; - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// DISTANT SEARCH FUNCTIONS /// - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + /// DISTANT SEARCH FUNCTIONS /// + //////////////////////////////////////////////////////////////////////////// + + /// Trigger remote generic GXS service search + virtual std::error_condition distantSearchRequest( + rs_owner_ptr searchData, uint32_t dataSize, + RsServiceType serviceType, TurtleRequestId& requestId ) = 0; + + /// Handle remote generic GXS services search requests to specific service + virtual std::error_condition handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) = 0; + + /// Receive remote generic GXS services search result + virtual std::error_condition receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) = 0; /*! * \brief turtleGroupRequest @@ -115,13 +129,17 @@ public: */ virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos)=0; - /*! - * \brief receiveTurtleSearchResults - * Called by turtle (through RsGxsNetTunnel) when new data is received - * \param req Turtle search request ID associated with this result - * \param encrypted_group_data Group data - */ - virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)=0; + /*! + * \brief receiveTurtleSearchResults + * Called by turtle (through RsGxsNetTunnel) when new data is received + * \param req Turtle search request ID associated with this result + * \param encrypted_group_data Group data + */ + RS_DEPRECATED_FOR("receiveDistantSearchResult") + virtual void receiveTurtleSearchResults( + TurtleRequestId req, + rs_owner_ptr encrypted_group_data, + uint32_t encrypted_group_data_len ) = 0; /*! * \brief retrieveTurtleSearchResults @@ -141,7 +159,9 @@ public: virtual bool clearDistantSearchResults(const TurtleRequestId& id)=0; virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSearchResults&)=0; - virtual bool search(const std::string& substring,std::list& group_infos) =0; + RS_DEPRECATED_FOR("handleDistantSearchRequest and distantSearchRequest") + virtual bool search(const std::string& substring,std::list& group_infos) =0; + virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)=0; /*! @@ -306,5 +326,3 @@ public: } } }; - -#endif // RSGNP_H diff --git a/libretroshare/src/util/rsmemory.cc b/libretroshare/src/gxs/rsnxsobserver.cpp similarity index 55% rename from libretroshare/src/util/rsmemory.cc rename to libretroshare/src/gxs/rsnxsobserver.cpp index 2b162c77d..2b5ab0d8a 100644 --- a/libretroshare/src/util/rsmemory.cc +++ b/libretroshare/src/gxs/rsnxsobserver.cpp @@ -1,53 +1,36 @@ -/******************************************************************************* - * libretroshare/src/util: rsmemory.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsmemory.h" - -void *rs_malloc(size_t size) -{ - static const size_t SAFE_MEMALLOC_THRESHOLD = 1024*1024*1024 ; // 1Gb should be enough for everything! - - if(size == 0) - { - std::cerr << "(EE) Memory allocation error. A chunk of size 0 was requested. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - if(size > SAFE_MEMALLOC_THRESHOLD) - { - std::cerr << "(EE) Memory allocation error. A chunk of size larger than " << SAFE_MEMALLOC_THRESHOLD << " was requested. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - void *mem = malloc(size) ; - - if(mem == NULL) - { - std::cerr << "(EE) Memory allocation error for a chunk of " << size << " bytes. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - return mem ; -} - +/******************************************************************************* + * RetroShare General eXchange System * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "gxs/rsnxsobserver.h" + +const RsNxsObserverErrorCategory RsNxsObserverErrorCategory::instance; + +std::error_condition RsNxsObserverErrorCategory::default_error_condition(int ev) +const noexcept +{ + switch(static_cast(ev)) + { + case RsNxsObserverErrorNum::NOT_OVERRIDDEN_BY_OBSERVER: + return std::errc::operation_not_supported; + default: + return std::error_condition(ev, *this); + } +} diff --git a/libretroshare/src/gxs/rsnxsobserver.h b/libretroshare/src/gxs/rsnxsobserver.h index 2da5067a4..5725df0f0 100644 --- a/libretroshare/src/gxs/rsnxsobserver.h +++ b/libretroshare/src/gxs/rsnxsobserver.h @@ -3,7 +3,10 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2011-2012 by Robert Fernie, Evi-Parker Christopher * + * Copyright (C) 2011-2012 Robert Fernie * + * Copyright (C) 2011-2012 Christopher Evi-Parker * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,21 +22,61 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RSNXSOBSERVER_H -#define RSNXSOBSERVER_H +#pragma once -#include +#include +#include + +#include "retroshare/rsgxsiface.h" #include "rsitems/rsnxsitems.h" +#include "util/rsdebug.h" -typedef uint32_t TurtleRequestId ; +typedef uint32_t TurtleRequestId; + +enum class RsNxsObserverErrorNum : int32_t +{ + NOT_OVERRIDDEN_BY_OBSERVER = 2004, +}; + +struct RsNxsObserverErrorCategory: std::error_category +{ + const char* name() const noexcept override + { return "RetroShare NXS Observer"; } + + std::string message(int ev) const override + { + switch (static_cast(ev)) + { + case RsNxsObserverErrorNum::NOT_OVERRIDDEN_BY_OBSERVER: + return "Method not overridden by observer"; + default: + return rsErrorNotInCategory(ev, name()); + } + } + + std::error_condition default_error_condition(int ev) const noexcept override; + + const static RsNxsObserverErrorCategory instance; +}; + + +namespace std +{ +/** Register RsNxsObserverErrorNum as an error condition enum, must be in std + * namespace */ +template<> struct is_error_condition_enum : true_type {}; +} + +/** Provide RsJsonApiErrorNum conversion to std::error_condition, must be in + * same namespace of RsJsonApiErrorNum */ +inline std::error_condition make_error_condition(RsNxsObserverErrorNum e) noexcept +{ + return std::error_condition( + static_cast(e), RsNxsObserverErrorCategory::instance ); +}; class RsNxsObserver { -public: - - RsNxsObserver() {} - - public: /*! @@ -56,6 +99,42 @@ public: std::cerr << __PRETTY_FUNCTION__ << ": not overloaded but still called. Nothing will happen." << std::endl; } + /** If advanced search functionalities like deep indexing are supported at + * observer/service level, this method should be overridden to handle search + * requests there. + * @param[in] requestData search query + * @param[in] requestSize search query size + * @param[out] resultData results data + * @param[out] resultSize results data size + * @return Error details or success, NOT_OVERRIDDEN_BY_OBSERVER is + * returned to inform the caller that this method was not overridden by the + * observer so do not use it for other meanings. */ + virtual std::error_condition handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) + { + (void) requestData; (void) requestSize; + (void) resultData; (void) resultSize; + return RsNxsObserverErrorNum::NOT_OVERRIDDEN_BY_OBSERVER; + } + + /** If advanced search functionalities like deep indexing are supported at + * observer/service level, this method should be overridden to handle search + * results there. + * @param[in] requestId search query id + * @param[out] resultData results data + * @param[out] resultSize results data size + * @return Error details or success, NOT_OVERRIDDEN_BY_OBSERVER is + * returned to inform the caller that this method was not overridden by the + * observer so do not use it for other meanings. */ + virtual std::error_condition receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) + { + (void) requestId; (void) resultData; (void) resultSize; + return RsNxsObserverErrorNum::NOT_OVERRIDDEN_BY_OBSERVER; + } + /*! * @param grpId group id */ @@ -70,6 +149,7 @@ public: * @param grpId group id */ virtual void notifyChangedGroupStats(const RsGxsGroupId &grpId) = 0; -}; -#endif // RSNXSOBSERVER_H + RsNxsObserver() = default; + virtual ~RsNxsObserver() = default; +}; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index c654b2e61..d410e8a52 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -633,7 +633,6 @@ SOURCES += util/folderiterator.cc \ util/rsexpr.cc \ util/smallobject.cc \ util/rsdir.cc \ - util/rsmemory.cc \ util/rsdiscspace.cc \ util/rsnet.cc \ util/rsnet_ss.cc \ @@ -712,7 +711,8 @@ SOURCES += rsitems/rsnxsitems.cc \ gxs/gxstokenqueue.cc \ gxs/rsgxsnetutils.cc \ gxs/rsgxsutil.cc \ - gxs/rsgxsrequesttypes.cc + gxs/rsgxsrequesttypes.cc \ + gxs/rsnxsobserver.cpp # gxs tunnels HEADERS += gxstunnel/p3gxstunnel.h \ @@ -936,6 +936,14 @@ rs_jsonapi { SOURCES += jsonapi/jsonapi.cpp } +rs_deep_forums_index { + HEADERS *= deep_search/commonutils.hpp + SOURCES *= deep_search/commonutils.cpp + + HEADERS += deep_search/forumsindex.hpp + SOURCES += deep_search/forumsindex.cpp +} + rs_deep_channels_index { HEADERS *= deep_search/commonutils.hpp SOURCES *= deep_search/commonutils.cpp diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index 421417bdc..bd09950f4 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -46,6 +46,11 @@ class RsGxsChannels; extern RsGxsChannels* rsGxsChannels; +/* TODO: At this abstraction level that turtle is used for distant searches + * should be an hidden implementation detail. As of today a bit of those + * implementation details leaks around because we use TurtleRequestId in this + * interface */ + struct RsGxsChannelGroup : RsSerializable, RsGxsGenericGroupData { RsGxsChannelGroup() : mAutoDownload(false) {} @@ -108,29 +113,38 @@ struct RsGxsChannelPost : RsSerializable, RsGxsGenericMsgData enum class RsChannelEventCode: uint8_t { UNKNOWN = 0x00, - NEW_CHANNEL = 0x01, // emitted when new channel is received - UPDATED_CHANNEL = 0x02, // emitted when existing channel is updated - NEW_MESSAGE = 0x03, // new message reeived in a particular channel (group and msg id) - UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular channel - RECEIVED_PUBLISH_KEY = 0x05, // publish key for this channel has been received - SUBSCRIBE_STATUS_CHANGED = 0x06, // subscription for channel mChannelGroupId changed. - READ_STATUS_CHANGED = 0x07, // existing message has been read or set to unread - RECEIVED_DISTANT_SEARCH_RESULT = 0x08, // result for the given group id available for the given turtle request id - STATISTICS_CHANGED = 0x09, // stats (nb of supplier friends, how many msgs they have etc) has changed - SYNC_PARAMETERS_UPDATED = 0x0a, // sync and storage times have changed - NEW_COMMENT = 0x0b, // new comment arrived/published. mChannelThreadId gives the ID of the commented message - NEW_VOTE = 0x0c, // new vote arrived/published. mChannelThreadId gives the ID of the votes message comment - DELETED_CHANNEL = 0x0d, // channel was deleted by auto-cleaning system + NEW_CHANNEL = 0x01, /// emitted when new channel is received + UPDATED_CHANNEL = 0x02, /// emitted when existing channel is updated + NEW_MESSAGE = 0x03, /// new message reeived in a particular channel (group and msg id) + UPDATED_MESSAGE = 0x04, /// existing message has been updated in a particular channel + RECEIVED_PUBLISH_KEY = 0x05, /// publish key for this channel has been received + SUBSCRIBE_STATUS_CHANGED = 0x06, /// subscription for channel mChannelGroupId changed. + READ_STATUS_CHANGED = 0x07, /// existing message has been read or set to unread + + /** Result for the given group id available for the given turtle request id + * @deprecated kept for retrocompatibility with old search system new code + * should use @see DISTANT_SEARCH_RESULT instead */ + RECEIVED_TURTLE_SEARCH_RESULT = 0x08, + + STATISTICS_CHANGED = 0x09, /// stats (nb of supplier friends, how many msgs they have etc) has changed + SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed + NEW_COMMENT = 0x0b, /// new comment arrived/published. mChannelThreadId gives the ID of the commented message + NEW_VOTE = 0x0c, /// new vote arrived/published. mChannelThreadId gives the ID of the votes message comment + DELETED_CHANNEL = 0x0d, /// channel was deleted by auto-cleaning system + DELETED_POST = 0x0e, /// Post deleted (usually by cleaning) + DISTANT_SEARCH_RESULT = 0x0f /// Distant search result received }; struct RsGxsChannelEvent: RsEvent { - RsGxsChannelEvent(): RsEvent(RsEventType::GXS_CHANNELS), mChannelEventCode(RsChannelEventCode::UNKNOWN) {} + RsGxsChannelEvent(): + RsEvent(RsEventType::GXS_CHANNELS), + mChannelEventCode(RsChannelEventCode::UNKNOWN) {} RsChannelEventCode mChannelEventCode; RsGxsGroupId mChannelGroupId; RsGxsMessageId mChannelMsgId; - RsGxsMessageId mChannelThreadId; + RsGxsMessageId mChannelThreadId; ///* @see RsEvent @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override @@ -143,13 +157,14 @@ struct RsGxsChannelEvent: RsEvent } }; -// This event is used to factor multiple search results notifications in a single event. - -struct RsGxsChannelSearchResultEvent: RsEvent +/** This event is used to factor multiple search results notifications in a + * single event.*/ +struct RS_DEPRECATED_FOR(RsGxsChannelDistantSearchResultEvent) +RsGxsChannelSearchResultEvent: RsEvent { RsGxsChannelSearchResultEvent(): RsEvent(RsEventType::GXS_CHANNELS), - mChannelEventCode(RsChannelEventCode::RECEIVED_DISTANT_SEARCH_RESULT) {} + mChannelEventCode(RsChannelEventCode::RECEIVED_TURTLE_SEARCH_RESULT) {} RsChannelEventCode mChannelEventCode; std::map > mSearchResultsMap; @@ -164,6 +179,29 @@ struct RsGxsChannelSearchResultEvent: RsEvent } }; +/** This event is fired once distant search results are received */ +struct RsGxsChannelDistantSearchResultEvent: RsEvent +{ + RsGxsChannelDistantSearchResultEvent(): + RsEvent(RsEventType::GXS_CHANNELS), + mChannelEventCode(RsChannelEventCode::DISTANT_SEARCH_RESULT) {} + + RsChannelEventCode mChannelEventCode; + TurtleRequestId mSearchId; + std::vector mSearchResults; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + + RS_SERIAL_PROCESS(mChannelEventCode); + RS_SERIAL_PROCESS(mSearchId); + RS_SERIAL_PROCESS(mSearchResults); + } +}; + class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService { public: @@ -386,11 +424,15 @@ public: * @brief Get channel content summaries * @jsonapi{development} * @param[in] channelId id of the channel of which the content is requested + * @param[in] contentIds ids of requested contents, if empty summaries of + * all messages are reqeusted * @param[out] summaries storage for summaries * @return false if something failed, true otherwhise */ - virtual bool getContentSummaries( const RsGxsGroupId& channelId, - std::vector& summaries ) = 0; + virtual std::error_condition getContentSummaries( + const RsGxsGroupId& channelId, + const std::set& contentIds, + std::vector& summaries ) = 0; /** * @brief Toggle post read status. Blocking API. @@ -422,22 +464,23 @@ public: virtual bool subscribeToChannel( const RsGxsGroupId& channelId, bool subscribe ) = 0; - /** - * \brief Retrieve statistics about the channel service + /** + * @brief Retrieve statistics about the channel service * @jsonapi{development} - * \param[out] stat Statistics structure - * \return - */ - virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0; + * @param[out] stat storage for statistics + * @return true on success false otherwise + */ + virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0; - /** - * \brief Retrieve statistics about the given channel + /** + * @brief Retrieve statistics about the given channel * @jsonapi{development} - * \param[in] channelId Id of the channel group - * \param[out] stat Statistics structure - * \return - */ - virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0; + * @param[in] channelId Id of the channel group + * @param[out] stat storage for statistics + * @return true on success false otherwise + */ + virtual bool getChannelStatistics( + const RsGxsGroupId& channelId, GxsGroupStatistic& stat ) =0; /// default base URL used for channels links @see exportChannelLink static const std::string DEFAULT_CHANNEL_BASE_URL; @@ -496,14 +539,18 @@ public: std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; /** - * @brief Search the turtle reachable network for matching channels + * @brief Search the whole reachable network for matching channels and + * contents * @jsonapi{development} - * An @see RsGxsChannelSearchResultEvent is emitted when matching channels - * arrives from the network + * An @see RsGxsChannelSearchResultEvent is emitted when matching results + * arrives from the network * @param[in] matchString string to search into the channels - * @return search id + * @param[out] searchId storage for search id, useful to track search events + * and retrieve search results + * @return success or error details */ - virtual TurtleRequestId turtleSearchRequest(const std::string& matchString)=0; + virtual std::error_condition distantSearchRequest( + const std::string& matchString, TurtleRequestId& searchId ) = 0; /** * @brief Retrieve available search results @@ -533,16 +580,18 @@ public: * @param[out] distantGroup storage for group data * @return false on error, true otherwise */ - virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; + virtual bool getDistantSearchResultGroupData( + const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; - /** - * @brief getDistantSearchStatus - * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, - * data request ongoing and data available - */ - virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) =0; + /** + * @brief Get the status of ongoing search + * @return unknown (probably not even searched), known as a search result, + * data request ongoing and data available + */ + virtual DistantSearchGroupStatus getDistantSearchStatus( + const RsGxsGroupId& group_id ) =0; - /** + /** * @brief Clear accumulated search results * @jsonapi{development} * @param[in] reqId search id diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h index ce64bf4ed..eca8b009e 100644 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ b/libretroshare/src/retroshare/rsgxsiface.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Christopher Evi-Parker * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -31,13 +32,63 @@ #include "rsitems/rsserviceids.h" #include "retroshare/rsevents.h" +/*! + * This structure is used to transport GXS search results. + * It contains the group information as well as a context string to tell where + * the information was found. + * Keep it small as to make search responses as light as possible. + * It differs from RsGxsGroupSearchResults because it supports also results from + * message matches not just groups. + */ +struct RsGxsSearchResult : RsSerializable +{ + RsGxsSearchResult(): mPublishTs(0) {} + + /** Id of the group which match*/ + RsGxsGroupId mGroupId; + + /** Title of the group which match */ + std::string mGroupName; + + /** Optional message id if the search match is against a message */ + RsGxsMessageId mMsgId; + + /** Optional message title if the search match is against a message */ + std::string mMsgName; + + /** Author id of the element which matched (group or message) */ + RsGxsId mAuthorId; + + /** Publish timestamp of the element which matched (group or message) */ + rstime_t mPublishTs; + + /** A snippet of content around the exact match */ + std::string mSearchContext; + + /// @see RsSerializable::serial_process + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) + { + RS_SERIAL_PROCESS(mGroupId); + RS_SERIAL_PROCESS(mGroupName); + RS_SERIAL_PROCESS(mMsgId); + RS_SERIAL_PROCESS(mMsgName); + RS_SERIAL_PROCESS(mAuthorId); + RS_SERIAL_PROCESS(mPublishTs); + RS_SERIAL_PROCESS(mSearchContext); + } + + virtual ~RsGxsSearchResult() = default; +}; + /*! * This structure is used to transport group summary information when a GXS * service is searched. It contains the group information as well as a context * string to tell where the information was found. It is more compact than a * GroupMeta object, so as to make search responses as light as possible. */ -struct RsGxsGroupSummary : RsSerializable +struct RS_DEPRECATED_FOR(RsGxsSearchResult) +RsGxsGroupSummary : RsSerializable { RsGxsGroupSummary() : mPublishTs(0), mNumberOfMessages(0),mLastMessageTs(0), @@ -78,8 +129,12 @@ struct RsGxsGroupSummary : RsSerializable * strings to tell where the information was found. It is more compact than a * GroupMeta object, so as to make search responses as light as possible. */ -struct RsGxsGroupSearchResults : RsSerializable +struct RS_DEPRECATED_FOR(RsGxsSearchResult) +RsGxsGroupSearchResults : RsSerializable { + /* TODO: This seems exactly the same as RsGxsGroupSummary + mSearchContexts + * do we really need both? */ + RsGxsGroupSearchResults() : mPublishTs(0), mNumberOfMessages(0),mLastMessageTs(0), mSignFlags(0),mPopularity(0) {} @@ -113,6 +168,7 @@ struct RsGxsGroupSearchResults : RsSerializable virtual ~RsGxsGroupSearchResults() = default; }; + /*! * Stores ids of changed gxs groups and messages. * It is used to notify about GXS changes. diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index 0f78b3738..d6232a0d6 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -63,7 +63,7 @@ struct RsGroupMetaData : RsSerializable mCircleType(0x0001), mAuthenFlags(0), mSubscribeFlags(0), mPop(0), mVisibleMsgCount(0), mLastPost(0), mGroupStatus(0) {} - virtual ~RsGroupMetaData() {} + virtual ~RsGroupMetaData() = default; void operator =(const RsGxsGrpMetaData& rGxsMeta); RsGroupMetaData(const RsGxsGrpMetaData& rGxsMeta) { operator=(rGxsMeta); } diff --git a/libretroshare/src/rsitems/rsgxschannelitems.h b/libretroshare/src/rsitems/rsgxschannelitems.h index fa52c8cfc..598400966 100644 --- a/libretroshare/src/rsitems/rsgxschannelitems.h +++ b/libretroshare/src/rsitems/rsgxschannelitems.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright (C) 2012 Robert Fernie * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,8 +21,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RS_GXS_CHANNEL_ITEMS_H -#define RS_GXS_CHANNEL_ITEMS_H +#pragma once #include @@ -30,14 +31,23 @@ #include "serialiser/rstlvfileitem.h" #include "serialiser/rstlvimage.h" - +#include "serialiser/rsserializable.h" #include "retroshare/rsgxschannels.h" - #include "serialiser/rsserializer.h" - #include "util/rsdir.h" +enum class RsGxsChannelItems : uint8_t +{ + GROUP_ITEM = 0x02, + POST_ITEM = 0x03, + SEARCH_REQUEST = 0x04, + SEARCH_REPLY = 0x05, +}; + +RS_DEPRECATED_FOR(RsGxsChannelItems) const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM = 0x02; + +RS_DEPRECATED_FOR(RsGxsChannelItems) const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; class RsGxsChannelGroupItem : public RsGxsGrpItem @@ -79,6 +89,47 @@ public: RsTlvImage mThumbnail; }; +struct RsGxsChannelsSearchRequest : RsSerializable +{ + RsGxsChannelsSearchRequest() : mType(RsGxsChannelItems::SEARCH_REQUEST) {} + + /// Just for easier back and forward compatibility + RsGxsChannelItems mType; + + /// Store search match string + std::string mQuery; + + /// @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mType); + RS_SERIAL_PROCESS(mQuery); + } + + ~RsGxsChannelsSearchRequest() override = default; +}; + +struct RsGxsChannelsSearchReply : RsSerializable +{ + RsGxsChannelsSearchReply() : mType(RsGxsChannelItems::SEARCH_REPLY) {} + + /// Just for easier back and forward compatibility + RsGxsChannelItems mType; + + /// Results storage + std::vector mResults; + + /// @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mType); + RS_SERIAL_PROCESS(mResults); + } + + ~RsGxsChannelsSearchReply() override = default; +}; class RsGxsChannelSerialiser : public RsGxsCommentSerialiser { @@ -89,5 +140,3 @@ public: virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; }; - -#endif /* RS_GXS_CHANNEL_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsitem.h b/libretroshare/src/rsitems/rsitem.h index 1c8ea9789..3ef44f859 100644 --- a/libretroshare/src/rsitems/rsitem.h +++ b/libretroshare/src/rsitems/rsitem.h @@ -86,9 +86,8 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&)// = 0; { - std::cerr << "(EE) RsItem::serial_process(...) called by an item using" - << "new serialization classes, but not derived! Class is " - << typeid(*this).name() << std::endl; + RS_ERR( "called by an item using new serialization system without " + "overriding Class is: ", typeid(*this).name() ); print_stacktrace(); } diff --git a/libretroshare/src/rsitems/rsserviceids.h b/libretroshare/src/rsitems/rsserviceids.h index ead349e32..eb08db07c 100644 --- a/libretroshare/src/rsitems/rsserviceids.h +++ b/libretroshare/src/rsitems/rsserviceids.h @@ -28,7 +28,9 @@ enum class RsServiceType : uint16_t { - NONE = 0, /// To detect non-initialized reads + /// To detect non-initialized items + NONE = 0, + GOSSIP_DISCOVERY = 0x0011, CHAT = 0x0012, MSG = 0x0013, @@ -46,7 +48,10 @@ enum class RsServiceType : uint16_t GWEMAIL_MAIL = 0x0025, SERVICE_CONTROL = 0x0026, DISTANT_CHAT = 0x0027, + + /// For GXS identity authenticated tunnels, do not confuse with @GXS_DISTANT GXS_TUNNEL = 0x0028, + BANLIST = 0x0101, STATUS = 0x0102, NXS = 0x0200, @@ -58,6 +63,7 @@ enum class RsServiceType : uint16_t POSTED = 0x0216, CHANNELS = 0x0217, GXSCIRCLE = 0x0218, + /// not gxs, but used with identities. REPUTATION = 0x0219, GXS_RECOGN = 0x0220, @@ -68,13 +74,13 @@ enum class RsServiceType : uint16_t CHANNELS_CONFIG = 0x0317, RTT = 0x1011, /// Round Trip Time - - /***************** IDS ALLOCATED FOR PLUGINS ******************/ - // 2000+ PLUGIN_ARADO_ID = 0x2001, PLUGIN_QCHESS_ID = 0x2002, PLUGIN_FEEDREADER = 0x2003, + /// GXS distant sync and search do not confuse with @see GXS_TUNNEL + GXS_DISTANT = 0x2233, + /// Reserved for packet slicing probes. PACKET_SLICING_PROBE = 0xAABB, diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index b5fe1426f..58af0b22d 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -22,6 +23,8 @@ *******************************************************************************/ #pragma once +#include +#include #include "retroshare/rsgxschannels.h" #include "services/p3gxscommon.h" @@ -30,9 +33,7 @@ #include "util/rsmemory.h" #include "util/rsdebug.h" #include "util/rstickevent.h" - -#include -#include +#include "deep_search/channelsindex.hpp" // This class is only a helper to parse the channel group service string. @@ -56,6 +57,11 @@ class p3GxsChannels: public RsGenExchange, public RsGxsChannels, public: p3GxsChannels( RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs ); + + /// @see RsGxsChannels + std::error_condition distantSearchRequest( + const std::string& matchString, TurtleRequestId& searchId ) override; + virtual RsServiceInfo getServiceInfo() override; virtual void service_tick() override; @@ -69,7 +75,7 @@ protected: virtual bool loadList(std::list& loadList) override; // @see p3Config::loadList(std::list&) virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id) override; - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string) override; + virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &results) override; virtual bool clearDistantSearchResults(TurtleRequestId req) override; virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group) override; @@ -112,24 +118,6 @@ virtual bool getChannelAutoDownload(const RsGxsGroupId &groupid, bool& enabled) virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory) override; virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory) override; -#ifdef TO_REMOVE - /// @see RsGxsChannels::turtleSearchRequest - virtual bool turtleSearchRequest(const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait = 300 ) override; - - /// @see RsGxsChannels::turtleChannelRequest - virtual bool turtleChannelRequest( - const RsGxsGroupId& channelId, - const std::function& multiCallback, - rstime_t maxWait = 300 ) override; - - /// @see RsGxsChannels::localSearchRequest - virtual bool localSearchRequest(const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait = 30 ) override; -#endif - /** * Receive results from turtle search @see RsGenExchange @see RsNxsObserver * @see RsGxsNetService::receiveTurtleSearchResults @@ -215,9 +203,10 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; const std::set &contentIds, std::vector &comments) override; - /// Implementation of @see RsGxsChannels::getContentSummaries - bool getContentSummaries( + /// @see RsGxsChannels + std::error_condition getContentSummaries( const RsGxsGroupId& channelId, + const std::set& contentIds, std::vector& summaries ) override; /// Implementation of @see RsGxsChannels::getChannelStatistics @@ -297,6 +286,17 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; virtual bool shareChannelKeys( const RsGxsGroupId& channelId, const std::set& peers ) override; +#ifdef RS_DEEP_CHANNEL_INDEX + /// @see RsNxsObserver + std::error_condition handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; + + std::error_condition receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; +#endif + /// Implementation of @see RsGxsChannels::createChannel RS_DEPRECATED_FOR(createChannelV2) bool createChannel(RsGxsChannelGroup& channel) override; @@ -313,7 +313,6 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; RS_DEPRECATED_FOR(createVoteV2) bool createVote(RsGxsVote& vote) override; - protected: // Overloaded from GxsTokenQueue for Request callbacks. virtual void handleResponse(uint32_t token, uint32_t req_type @@ -329,7 +328,6 @@ static uint32_t channelsAuthenPolicy(); void request_SpecificSubscribedGroups(const std::list &groups); void load_SubscribedGroups(const uint32_t &token); - void request_SpecificUnprocessedPosts(std::list > &ids); void request_GroupUnprocessedPosts(const std::list &grouplist); void load_unprocessedPosts(uint32_t token); @@ -390,26 +388,8 @@ bool generateGroup(uint32_t &token, std::string groupName); rstime_t mLastDistantSearchNotificationTS; std::map > mSearchResultsToNotify; -#ifdef TO_REMOVE - /** Store search callbacks with timeout*/ - std::map< - TurtleRequestId, - std::pair< - std::function, - std::chrono::system_clock::time_point > - > mSearchCallbacksMap; - RsMutex mSearchCallbacksMapMutex; - /** Store distant channels requests callbacks with timeout*/ - std::map< - TurtleRequestId, - std::pair< - std::function, - std::chrono::system_clock::time_point > - > mDistantChannelsCallbacksMap; - RsMutex mDistantChannelsCallbacksMapMutex; - - /// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap - void cleanTimedOutCallbacks(); +#ifdef RS_DEEP_CHANNEL_INDEX + DeepChannelsIndex mDeepIndex; #endif }; diff --git a/libretroshare/src/util/rsdebug.cc b/libretroshare/src/util/rsdebug.cc index 0a4777ab0..ac121bca3 100644 --- a/libretroshare/src/util/rsdebug.cc +++ b/libretroshare/src/util/rsdebug.cc @@ -3,9 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright (C) 2004-2008 by Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * + * Copyright (C) 2004-2008 Robert Fernie * + * Copyright (C) 2020-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -36,6 +36,9 @@ std::string rsErrorNotInCategory(int errNum, const std::string& categoryName) " not available in category: " + categoryName; } +std::error_condition rs_errno_to_condition(int errno_code) +{ return std::make_error_condition(static_cast(errno_code)); } + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// diff --git a/libretroshare/src/util/rsdebug.h b/libretroshare/src/util/rsdebug.h index 6409e9492..4eddac240 100644 --- a/libretroshare/src/util/rsdebug.h +++ b/libretroshare/src/util/rsdebug.h @@ -2,8 +2,8 @@ * RetroShare debugging utilities * * * * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2020-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -65,6 +65,12 @@ std::ostream &operator<<(std::ostream& out, const std::error_condition& err); * the message around */ std::string rsErrorNotInCategory(int errNum, const std::string& categoryName); +/** Convert C errno codes to modern C++11 std::error_condition, this is quite + * useful to use toghether with C functions used around the code like `malloc`, + * `socket` etc to let errors bubble up comprensibly to upper layers C++11 code + */ +std::error_condition rs_errno_to_condition(int errno_code); + template struct t_RsLogger : std::ostringstream diff --git a/libretroshare/src/util/rsmemory.h b/libretroshare/src/util/rsmemory.h index eb2889a6f..8afc48cf7 100644 --- a/libretroshare/src/util/rsmemory.h +++ b/libretroshare/src/util/rsmemory.h @@ -3,8 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012 Cyril Soler * - * Copyright 2019-2020 Gioacchino Mazzurco * + * Copyright (C) 2012 Cyril Soler * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -25,8 +26,10 @@ #include #include #include +#include #include "util/stacktrace.h" +#include "util/rsdebug.h" /** * @brief Shorthand macro to declare optional functions output parameters @@ -108,7 +111,66 @@ template using rs_view_ptr = T*; * @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf */ template using rs_owner_ptr = T*; -void *rs_malloc(size_t size) ; + +/// 1Gb should be enough for everything! +static constexpr size_t SAFE_MEMALLOC_THRESHOLD = 1024*1024*1024; + +/** Comfortable templated safer malloc, just use it specifing the type of the + * pointer to be returned without need of ugly casting the returned pointer + * `uint8_t* ptr = rs_malloc(40);` + * @param[in] size number of bytes to allocate + * @param[out] ec optional storage for error details. Value is meaningful only + * whem nullptr is returned. + * @return nullptr on error, pointer to the allocated chuck of memory on success + */ +template rs_owner_ptr rs_malloc( + size_t size, + rs_view_ptr ec = nullptr ) +{ + if(size == 0) + { + if(!ec) + { + RS_ERR("A chunk of size 0 was requested"); + print_stacktrace(); + exit(static_cast(std::errc::invalid_argument)); + } + + *ec = std::errc::invalid_argument; + return nullptr; + } + + if(size > SAFE_MEMALLOC_THRESHOLD) + { + if(!ec) + { + RS_ERR( "A chunk of size larger than ", SAFE_MEMALLOC_THRESHOLD, + " was requested" ); + exit(static_cast(std::errc::argument_out_of_domain)); + } + + *ec = std::errc::argument_out_of_domain; + return nullptr; + } + + void* mem = malloc(size); + if(!mem) + { + if(!ec) + { + RS_ERR( "Allocation failed for a chunk of ", size, + " bytes with: ", errno); + print_stacktrace(); + exit(errno); + } + + *ec = rs_errno_to_condition(errno); + return nullptr; + } + + return static_cast>(mem); +} + /** @deprecated use std::unique_ptr instead // This is a scope guard to release the memory block when going of of the current scope. @@ -128,7 +190,7 @@ void *rs_malloc(size_t size) ; // // } // mem gets freed automatically */ -class RsTemporaryMemory +class RS_DEPRECATED_FOR("std::unique_ptr") RsTemporaryMemory { public: explicit RsTemporaryMemory(size_t s) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index e18a161a3..baf715a96 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -411,7 +411,9 @@ void GxsChannelDialog::clearDistantSearchResults(TurtleRequestId id) TurtleRequestId GxsChannelDialog::distantSearch(const QString& search_string) { - return rsGxsChannels->turtleSearchRequest(search_string.toStdString()) ; + TurtleRequestId searchId; + rsGxsChannels->distantSearchRequest(search_string.toStdString(), searchId); + return searchId; } bool GxsChannelDialog::getDistantSearchResults(TurtleRequestId id, std::map& group_infos) From 9c38eed6482c70a109143c0a7d960ed12ff9f4c1 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 19 Feb 2021 23:23:02 +0100 Subject: [PATCH 179/697] Implement deep indexing and search for forums RsGxsNetTunnelService::receiveSearchRequest handle no results case properly RsNxsObserver::handleDistantSearchRequest improve method behaviour documentation RsTurtleClientService Improve documentation --- libretroshare/src/deep_search/commonutils.cpp | 20 + libretroshare/src/deep_search/forumsindex.cpp | 208 ++++++++++ libretroshare/src/deep_search/forumsindex.hpp | 81 ++++ libretroshare/src/gxs/rsgxsnetservice.cc | 6 + libretroshare/src/gxs/rsnxsobserver.h | 8 +- libretroshare/src/retroshare/rsgxschannels.h | 2 +- libretroshare/src/retroshare/rsgxsforums.h | 76 +++- libretroshare/src/rsitems/rsgxsforumitems.h | 62 ++- libretroshare/src/rsserver/rsinit.cc | 34 +- libretroshare/src/services/p3gxsforums.cc | 363 ++++++++++++++++-- libretroshare/src/services/p3gxsforums.h | 52 ++- .../src/turtle/turtleclientservice.h | 73 ++-- retroshare.pri | 6 + 13 files changed, 902 insertions(+), 89 deletions(-) create mode 100644 libretroshare/src/deep_search/forumsindex.cpp create mode 100644 libretroshare/src/deep_search/forumsindex.hpp diff --git a/libretroshare/src/deep_search/commonutils.cpp b/libretroshare/src/deep_search/commonutils.cpp index cbe4ee27b..c3b9c5342 100644 --- a/libretroshare/src/deep_search/commonutils.cpp +++ b/libretroshare/src/deep_search/commonutils.cpp @@ -168,13 +168,33 @@ std::string simpleTextHtmlExtract(const std::string& rsHtmlDoc) std::string retVal(rsHtmlDoc.substr(bodyTagEnd+1)); + // strip also CSS inside + oSize = retVal.size(); + auto styleTagBegin(retVal.find("", styleTagBegin)); + if(styleEnd < oSize) + retVal.erase(styleTagBegin, 8+styleEnd-styleTagBegin); + } + std::string::size_type oPos; std::string::size_type cPos; + int itCount = 0; while((oPos = retVal.find("<")) < retVal.size()) { if((cPos = retVal.find(">")) <= retVal.size()) retVal.erase(oPos, 1+cPos-oPos); else break; + + // Avoid infinite loop with crafty input + if(itCount > 1000) + { + RS_WARN( "Breaking stripping loop due to max allowed iterations ", + "rsHtmlDoc: ", rsHtmlDoc, " retVal: ", retVal ); + break; + } + ++itCount; } return retVal; diff --git a/libretroshare/src/deep_search/forumsindex.cpp b/libretroshare/src/deep_search/forumsindex.cpp new file mode 100644 index 000000000..acc7aed9a --- /dev/null +++ b/libretroshare/src/deep_search/forumsindex.cpp @@ -0,0 +1,208 @@ +/******************************************************************************* + * RetroShare full text indexing and search implementation based on Xapian * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License version 3 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "deep_search/forumsindex.hpp" +#include "deep_search/commonutils.hpp" +#include "retroshare/rsinit.h" +#include "retroshare/rsgxsforums.h" +#include "util/rsdebuglevel4.h" + +std::error_condition DeepForumsIndex::search( + const std::string& queryStr, + std::vector& results, uint32_t maxResults ) +{ + results.clear(); + + std::unique_ptr dbPtr( + DeepSearch::openReadOnlyDatabase(mDbPath) ); + if(!dbPtr) return std::errc::bad_file_descriptor; + + Xapian::Database& db(*dbPtr); + + // Set up a QueryParser with a stemmer and suitable prefixes. + Xapian::QueryParser queryparser; + //queryparser.set_stemmer(Xapian::Stem("en")); + queryparser.set_stemming_strategy(queryparser.STEM_SOME); + // Start of prefix configuration. + //queryparser.add_prefix("title", "S"); + //queryparser.add_prefix("description", "XD"); + // End of prefix configuration. + + // And parse the query. + Xapian::Query query = queryparser.parse_query(queryStr); + + // Use an Enquire object on the database to run the query. + Xapian::Enquire enquire(db); + enquire.set_query(query); + + Xapian::MSet mset = enquire.get_mset( + 0, maxResults ? maxResults : db.get_doccount() ); + + for( Xapian::MSetIterator m = mset.begin(); m != mset.end(); ++m ) + { + const Xapian::Document& doc = m.get_document(); + DeepForumsSearchResult s; + s.mUrl = doc.get_value(URL_VALUENO); +#if XAPIAN_AT_LEAST(1,3,5) + s.mSnippet = mset.snippet(doc.get_data()); +#endif // XAPIAN_AT_LEAST(1,3,5) + results.push_back(s); + } + + return std::error_condition(); +} + +/*static*/ std::string DeepForumsIndex::forumIndexId(const RsGxsGroupId& grpId) +{ + RsUrl forumIndexId(RsGxsForums::DEFAULT_FORUM_BASE_URL); + forumIndexId.setQueryKV( + RsGxsForums::FORUM_URL_ID_FIELD, grpId.toStdString() ); + return forumIndexId.toString(); +} + +/*static*/ std::string DeepForumsIndex::postIndexId( + const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ) +{ + RsUrl postIndexId(RsGxsForums::DEFAULT_FORUM_BASE_URL); + postIndexId.setQueryKV(RsGxsForums::FORUM_URL_ID_FIELD, grpId.toStdString()); + postIndexId.setQueryKV(RsGxsForums::FORUM_URL_MSG_ID_FIELD, msgId.toStdString()); + return postIndexId.toString(); +} + +std::error_condition DeepForumsIndex::indexForumGroup( + const RsGxsForumGroup& forum ) +{ + // Set up a TermGenerator that we'll use in indexing. + Xapian::TermGenerator termgenerator; + //termgenerator.set_stemmer(Xapian::Stem("en")); + + // We make a document and tell the term generator to use this. + Xapian::Document doc; + termgenerator.set_document(doc); + + // Index each field with a suitable prefix. + termgenerator.index_text(forum.mMeta.mGroupName, 1, "G"); + termgenerator.index_text( + DeepSearch::timetToXapianDate(forum.mMeta.mPublishTs), 1, "D" ); + termgenerator.index_text(forum.mDescription, 1, "XD"); + + // Index fields without prefixes for general search. + termgenerator.index_text(forum.mMeta.mGroupName); + termgenerator.increase_termpos(); + termgenerator.index_text(forum.mDescription); + + // store the RS link so we are able to retrive it on matching search + const std::string rsLink(forumIndexId(forum.mMeta.mGroupId)); + doc.add_value(URL_VALUENO, rsLink); + + /* Store some fields for display purposes. Retrieved later to provide the + * matching snippet on search */ + doc.set_data(forum.mMeta.mGroupName + "\n" + forum.mDescription); + + /* We use the identifier to ensure each object ends up in the database only + * once no matter how many times we run the indexer. + * "Q" prefix is a Xapian convention for unique id term. */ + const std::string idTerm("Q" + rsLink); + doc.add_boolean_term(idTerm); + + mWriteQueue.push([idTerm, doc](Xapian::WritableDatabase& db) + { db.replace_document(idTerm, doc); } ); + + return std::error_condition(); +} + +std::error_condition DeepForumsIndex::removeForumFromIndex( + const RsGxsGroupId& grpId ) +{ + mWriteQueue.push([grpId](Xapian::WritableDatabase& db) + { db.delete_document("Q" + forumIndexId(grpId)); }); + + return std::error_condition(); +} + +std::error_condition DeepForumsIndex::indexForumPost(const RsGxsForumMsg& post) +{ + RS_DBG4(post); + + const auto& groupId = post.mMeta.mGroupId; + const auto& msgId = post.mMeta.mMsgId; + + if(groupId.isNull() || msgId.isNull()) + { + RS_ERR("Got post with invalid id ", post); + print_stacktrace(); + return std::errc::invalid_argument; + } + + // Set up a TermGenerator that we'll use in indexing. + Xapian::TermGenerator termgenerator; + //termgenerator.set_stemmer(Xapian::Stem("en")); + + // We make a document and tell the term generator to use this. + Xapian::Document doc; + termgenerator.set_document(doc); + + // Index each field with a suitable prefix. + termgenerator.index_text(post.mMeta.mMsgName, 1, "S"); + termgenerator.index_text( + DeepSearch::timetToXapianDate(post.mMeta.mPublishTs), 1, "D" ); + + // Avoid indexing RetroShare-gui HTML tags + const std::string cleanMsg = DeepSearch::simpleTextHtmlExtract(post.mMsg); + termgenerator.index_text(cleanMsg, 1, "XD" ); + + // Index fields without prefixes for general search. + termgenerator.index_text(post.mMeta.mMsgName); + + termgenerator.increase_termpos(); + termgenerator.index_text(cleanMsg); + // store the RS link so we are able to retrive it on matching search + const std::string rsLink(postIndexId(groupId, msgId)); + doc.add_value(URL_VALUENO, rsLink); + + // Store some fields for display purposes. + doc.set_data(post.mMeta.mMsgName + "\n" + cleanMsg); + + // We use the identifier to ensure each object ends up in the + // database only once no matter how many times we run the + // indexer. + const std::string idTerm("Q" + rsLink); + doc.add_boolean_term(idTerm); + + mWriteQueue.push( [idTerm, doc](Xapian::WritableDatabase& db) + { db.replace_document(idTerm, doc); } ); + + + return std::error_condition(); +} + +std::error_condition DeepForumsIndex::removeForumPostFromIndex( + RsGxsGroupId grpId, RsGxsMessageId msgId ) +{ + // "Q" prefix is a Xapian convention for unique id term. + std::string idTerm("Q" + postIndexId(grpId, msgId)); + mWriteQueue.push( [idTerm](Xapian::WritableDatabase& db) + { db.delete_document(idTerm); } ); + + return std::error_condition(); +} + +/*static*/ std::string DeepForumsIndex::dbDefaultPath() +{ return RsAccounts::AccountDirectory() + "/deep_forum_index_xapian_db"; } diff --git a/libretroshare/src/deep_search/forumsindex.hpp b/libretroshare/src/deep_search/forumsindex.hpp new file mode 100644 index 000000000..2955ce323 --- /dev/null +++ b/libretroshare/src/deep_search/forumsindex.hpp @@ -0,0 +1,81 @@ +/******************************************************************************* + * RetroShare full text indexing and search implementation based on Xapian * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License version 3 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ +#pragma once + +#include +#include +#include + +#include "util/rstime.h" +#include "retroshare/rsgxsforums.h" +#include "retroshare/rsevents.h" +#include "deep_search/commonutils.hpp" + +struct DeepForumsSearchResult +{ + std::string mUrl; + double mWeight; + std::string mSnippet; +}; + +struct DeepForumsIndex +{ + explicit DeepForumsIndex(const std::string& dbPath) : + mDbPath(dbPath), mWriteQueue(dbPath) {} + + /** + * @brief Search indexed GXS groups and messages + * @param[in] maxResults maximum number of acceptable search results, 0 for + * no limits + * @return search results count + */ + std::error_condition search( const std::string& queryStr, + std::vector& results, + uint32_t maxResults = 100 ); + + std::error_condition indexForumGroup(const RsGxsForumGroup& chan); + + std::error_condition removeForumFromIndex(const RsGxsGroupId& grpId); + + std::error_condition indexForumPost(const RsGxsForumMsg& post); + + std::error_condition removeForumPostFromIndex( + RsGxsGroupId grpId, RsGxsMessageId msgId ); + + static std::string dbDefaultPath(); + +private: + static std::string forumIndexId(const RsGxsGroupId& grpId); + static std::string postIndexId( + const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ); + + enum : Xapian::valueno + { + /// Used to store retroshare url of indexed documents + URL_VALUENO, + + /// @see Xapian::BAD_VALUENO + BAD_VALUENO = Xapian::BAD_VALUENO + }; + + const std::string mDbPath; + + DeepSearch::StubbornWriteOpQueue mWriteQueue; +}; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 8038b63f4..e664b580c 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -5420,6 +5420,12 @@ std::error_condition RsGxsNetService::distantSearchRequest( rs_owner_ptr searchData, uint32_t dataSize, RsServiceType serviceType, TurtleRequestId& requestId ) { + if(!mGxsNetTunnel) + { + free(searchData); + return std::errc::function_not_supported; + } + return mGxsNetTunnel->turtleSearchRequest( searchData, dataSize, serviceType, requestId ); } diff --git a/libretroshare/src/gxs/rsnxsobserver.h b/libretroshare/src/gxs/rsnxsobserver.h index 5725df0f0..9d81e7656 100644 --- a/libretroshare/src/gxs/rsnxsobserver.h +++ b/libretroshare/src/gxs/rsnxsobserver.h @@ -104,8 +104,10 @@ public: * requests there. * @param[in] requestData search query * @param[in] requestSize search query size - * @param[out] resultData results data - * @param[out] resultSize results data size + * @param[out] resultData results data storage for a pointer to search + * result reply data or nullptr if no mathing results where found + * @param[out] resultSize storage for results data size or 0 if no matching + * results where found * @return Error details or success, NOT_OVERRIDDEN_BY_OBSERVER is * returned to inform the caller that this method was not overridden by the * observer so do not use it for other meanings. */ @@ -113,6 +115,8 @@ public: rs_view_ptr requestData, uint32_t requestSize, rs_owner_ptr& resultData, uint32_t& resultSize ) { + /* Avoid unused paramethers warning this way so doxygen can still parse + * paramethers documentation */ (void) requestData; (void) requestSize; (void) resultData; (void) resultSize; return RsNxsObserverErrorNum::NOT_OVERRIDDEN_BY_OBSERVER; diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index bd09950f4..a91e341a7 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -427,7 +427,7 @@ public: * @param[in] contentIds ids of requested contents, if empty summaries of * all messages are reqeusted * @param[out] summaries storage for summaries - * @return false if something failed, true otherwhise + * @return success or error details if something failed */ virtual std::error_condition getContentSummaries( const RsGxsGroupId& channelId, diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 1b35f2db9..561fe646d 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -118,7 +118,10 @@ enum class RsForumEventCode: uint8_t SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed PINNED_POSTS_CHANGED = 0x0b, /// some posts where pinned or un-pinned DELETED_FORUM = 0x0c, /// forum was deleted by cleaning - DELETED_POSTS = 0x0d /// Posts deleted by cleaning + DELETED_POST = 0x0d, /// Post deleted (usually by cleaning) + + /// Distant search result received + DISTANT_SEARCH_RESULT = 0x0e }; struct RsGxsForumEvent: RsEvent @@ -149,6 +152,29 @@ struct RsGxsForumEvent: RsEvent ~RsGxsForumEvent() override; }; +/** This event is fired once distant search results are received */ +struct RsGxsForumsDistantSearchEvent: RsEvent +{ + RsGxsForumsDistantSearchEvent(): + RsEvent(RsEventType::GXS_CHANNELS), + mForumEventCode(RsForumEventCode::DISTANT_SEARCH_RESULT) {} + + RsForumEventCode mForumEventCode; + TurtleRequestId mSearchId; + std::vector mSearchResults; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + + RS_SERIAL_PROCESS(mForumEventCode); + RS_SERIAL_PROCESS(mSearchId); + RS_SERIAL_PROCESS(mSearchResults); + } +}; + class RsGxsForums: public RsGxsIfaceHelper { public: @@ -385,6 +411,50 @@ public: const RsGxsGroupId& forumId, const RsGxsMessageId& postId, bool keepForever ) = 0; + /** + * @brief Get forum content summaries + * @jsonapi{development} + * @param[in] forumId id of the forum of which the content is requested + * @param[in] contentIds ids of requested contents, if empty summaries of + * all messages are reqeusted + * @param[out] summaries storage for summaries + * @return success or error details if something failed + */ + virtual std::error_condition getContentSummaries( + const RsGxsGroupId& forumId, + const std::set& contentIds, + std::vector& summaries ) = 0; + + /** + * @brief Search the whole reachable network for matching forums and + * posts + * @jsonapi{development} + * An @see RsGxsForumsDistantSearchEvent is emitted when matching results + * arrives from the network + * @param[in] matchString string to search into the forum and posts + * @param[out] searchId storage for search id, useful to track search events + * and retrieve search results + * @return success or error details + */ + virtual std::error_condition distantSearchRequest( + const std::string& matchString, TurtleRequestId& searchId ) = 0; + + /** + * @brief Search the local index for matching forums and posts + * @jsonapi{development} + * @param[in] matchString string to search into the index + * @param[out] searchResults storage for searchr esults + * @return success or error details + */ + virtual std::error_condition localSearch( + const std::string& matchString, + std::vector& searchResults ) = 0; + + + //////////////////////////////////////////////////////////////////////////// + /* Following functions are deprecated and should not be considered a stable + * to use API */ + /** * @brief Create forum. Blocking API. * @jsonapi{development} diff --git a/libretroshare/src/rsitems/rsgxsforumitems.h b/libretroshare/src/rsitems/rsgxsforumitems.h index 30c6c4e08..b1f5fb629 100644 --- a/libretroshare/src/rsitems/rsgxsforumitems.h +++ b/libretroshare/src/rsitems/rsgxsforumitems.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright (C) 2012 Robert Fernie * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,8 +21,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RS_GXS_FORUM_ITEMS_H -#define RS_GXS_FORUM_ITEMS_H +#pragma once #include @@ -31,7 +32,18 @@ #include "retroshare/rsgxsforums.h" +enum class RsGxsForumsItems : uint8_t +{ + GROUP_ITEM = 0x02, + MESSAGE_ITEM = 0x03, + SEARCH_REQUEST = 0x04, + SEARCH_REPLY = 0x05, +}; + +RS_DEPRECATED_FOR(RsGxsForumsItems) const uint8_t RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM = 0x02; + +RS_DEPRECATED_FOR(RsGxsForumsItems) const uint8_t RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM = 0x03; class RsGxsForumGroupItem : public RsGxsGrpItem @@ -61,6 +73,48 @@ public: RsGxsForumMsg mMsg; }; +struct RsGxsForumsSearchRequest : RsSerializable +{ + RsGxsForumsSearchRequest() : mType(RsGxsForumsItems::SEARCH_REQUEST) {} + + /// Just for easier back and forward compatibility + RsGxsForumsItems mType; + + /// Store search match string + std::string mQuery; + + /// @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mType); + RS_SERIAL_PROCESS(mQuery); + } + + ~RsGxsForumsSearchRequest() override = default; +}; + +struct RsGxsForumsSearchReply : RsSerializable +{ + RsGxsForumsSearchReply() : mType(RsGxsForumsItems::SEARCH_REPLY) {} + + /// Just for easier back and forward compatibility + RsGxsForumsItems mType; + + /// Results storage + std::vector mResults; + + /// @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RS_SERIAL_PROCESS(mType); + RS_SERIAL_PROCESS(mResults); + } + + ~RsGxsForumsSearchReply() override = default; +}; + class RsGxsForumSerialiser : public RsServiceSerializer { public: @@ -69,5 +123,3 @@ public: virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; }; - -#endif /* RS_GXS_FORUM_ITEMS_H */ diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ad39f46a1..7433ab151 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2,7 +2,8 @@ * libretroshare/src/retroshare: rsinit.cc * * * * Copyright (C) 2004-2014 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * + * Copyright (C) 2016-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -1336,22 +1337,26 @@ int RsServer::StartupRetroShare() mWiki->setNetworkExchangeService(wiki_ns) ; #endif - /**** Forum GXS service ****/ + /************************* Forum GXS service ******************************/ - RsGeneralDataService* gxsforums_ds = new RsDataService(currGxsDir + "/", "gxsforums_db", - RS_SERVICE_GXS_TYPE_FORUMS, NULL, rsInitConfig->gxs_passwd); + RsGeneralDataService* gxsforums_ds = new RsDataService( + currGxsDir + "/", "gxsforums_db", RS_SERVICE_GXS_TYPE_FORUMS, + nullptr, rsInitConfig->gxs_passwd ); + p3GxsForums* mGxsForums = new p3GxsForums( + gxsforums_ds, nullptr, mGxsIdService ); - p3GxsForums *mGxsForums = new p3GxsForums(gxsforums_ds, NULL, mGxsIdService); + RsGxsNetTunnelService* gxsForumsTunnelService = nullptr; +#ifdef RS_DEEP_FORUMS_INDEX + gxsForumsTunnelService = mGxsNetTunnel; +#endif - // create GXS photo service - RsGxsNetService* gxsforums_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_FORUMS, gxsforums_ds, nxsMgr, - mGxsForums, mGxsForums->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils);//,mGxsNetTunnel,true,true,true); + RsGxsNetService* gxsforums_ns = new RsGxsNetService( + RS_SERVICE_GXS_TYPE_FORUMS, gxsforums_ds, nxsMgr, mGxsForums, + mGxsForums->getServiceInfo(), mReputations, mGxsCircles, + mGxsIdService, pgpAuxUtils, gxsForumsTunnelService ); + mGxsForums->setNetworkExchangeService(gxsforums_ns); - mGxsForums->setNetworkExchangeService(gxsforums_ns) ; /**** Channel GXS service ****/ @@ -1598,7 +1603,10 @@ int RsServer::StartupRetroShare() /**************************************************************************/ // Turtle search for GXS services - mGxsNetTunnel->registerSearchableService(gxschannels_ns) ; + mGxsNetTunnel->registerSearchableService(gxschannels_ns); +#ifdef RS_DEEP_FORUMS_INDEX + mGxsNetTunnel->registerSearchableService(gxsforums_ns); +#endif /**************************************************************************/ diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index cd7cbb5fe..2f85afe59 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -59,7 +59,11 @@ p3GxsForums::p3GxsForums( RsGeneralDataService *gds, RsGenExchange( gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()), RsGxsForums(static_cast(*this)), mGenToken(0), - mGenActive(false), mGenCount(0), mKnownForumsMutex("GXS forums known forums timestamp cache") + mGenActive(false), mGenCount(0), + mKnownForumsMutex("GXS forums known forums timestamp cache") +#ifdef RS_DEEP_FORUMS_INDEX + , mDeepIndex(DeepForumsIndex::dbDefaultPath()) +#endif { // Test Data disabled in Repo. //RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); @@ -190,31 +194,61 @@ RsSerialiser* p3GxsForums::setupSerialiser() return rss; } -void p3GxsForums::notifyChanges(std::vector &changes) +void p3GxsForums::notifyChanges(std::vector& changes) { RS_DBG2(changes.size(), " changes to notify"); - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) + for(RsGxsNotify* gxsChange: changes) { - RsGxsNotify* gxsChange = *it; + // Let the compiler delete the change for us + std::unique_ptr gxsChangeDeleter(gxsChange); + switch(gxsChange->getType()) { case RsGxsNotify::TYPE_RECEIVED_NEW: // [[fallthrough]] case RsGxsNotify::TYPE_PUBLISHED: { - RsGxsMsgChange* msgChange = dynamic_cast(*it); - RsGxsGroupChange* groupChange = dynamic_cast(*it); + auto msgChange = dynamic_cast(gxsChange); - if(msgChange) /* Message received*/ + if(msgChange) /* Message received */ { - auto ev = std::make_shared(); - ev->mForumMsgId = msgChange->mMsgId; - ev->mForumGroupId = msgChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; - rsEvents->postEvent(ev); + uint8_t msgSubtype = msgChange->mNewMsgItem->PacketSubType(); + switch(static_cast(msgSubtype)) + { + case RsGxsForumsItems::MESSAGE_ITEM: + { + auto newForumMessageItem = + dynamic_cast( + msgChange->mNewMsgItem ); + + if(!newForumMessageItem) + { + RS_ERR("Received message change with mNewMsgItem type " + "mismatching or null"); + print_stacktrace(); + return; + } + +#ifdef RS_DEEP_FORUMS_INDEX + RsGxsForumMsg tmpPost = newForumMessageItem->mMsg; + tmpPost.mMeta = newForumMessageItem->meta; + mDeepIndex.indexForumPost(tmpPost); +#endif + auto ev = std::make_shared(); + ev->mForumMsgId = msgChange->mMsgId; + ev->mForumGroupId = msgChange->mGroupId; + ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; + rsEvents->postEvent(ev); + break; + } + default: + RS_WARN("Got unknown gxs message subtype: ", msgSubtype); + break; + } } - else if(groupChange) /* Group received */ + + auto groupChange = dynamic_cast(gxsChange); + if(groupChange) /* Group received */ { bool unknown; { @@ -232,9 +266,25 @@ void p3GxsForums::notifyChanges(std::vector &changes) ev->mForumEventCode = RsForumEventCode::NEW_FORUM; rsEvents->postEvent(ev); } - else - RS_DBG1( " Not notifying already known forum ", - gxsChange->mGroupId ); + +#ifdef RS_DEEP_FORUMS_INDEX + uint8_t itemType = groupChange->mNewGroupItem->PacketSubType(); + switch(static_cast(itemType)) + { + case RsGxsForumsItems::GROUP_ITEM: + { + auto newForumGroupItem = + static_cast( + groupChange->mNewGroupItem ); + mDeepIndex.indexForumGroup(newForumGroupItem->mGroup); + break; + } + default: + RS_WARN("Got unknown gxs group subtype: ", itemType); + break; + } +#endif // def RS_DEEP_FORUMS_INDEX + } break; } @@ -256,25 +306,31 @@ void p3GxsForums::notifyChanges(std::vector &changes) } case RsGxsNotify::TYPE_MESSAGE_DELETED: { - RsGxsMsgDeletedChange* delChange = - dynamic_cast(gxsChange); - + auto delChange = dynamic_cast(gxsChange); if(!delChange) { RS_ERR( "Got mismatching notification type: ", gxsChange->getType() ); print_stacktrace(); - goto cleanup; + break; } +#ifdef RS_DEEP_FORUMS_INDEX + mDeepIndex.removeForumPostFromIndex( + delChange->mGroupId, delChange->messageId); +#endif + auto ev = std::make_shared(); - ev->mForumEventCode = RsForumEventCode::DELETED_POSTS; + ev->mForumEventCode = RsForumEventCode::DELETED_POST; ev->mForumGroupId = delChange->mGroupId; ev->mForumMsgId = delChange->messageId; break; } case RsGxsNotify::TYPE_GROUP_DELETED: { +#ifdef RS_DEEP_FORUMS_INDEX + mDeepIndex.removeForumFromIndex(gxsChange->mGroupId); +#endif auto ev = std::make_shared(); ev->mForumGroupId = gxsChange->mGroupId; ev->mForumEventCode = RsForumEventCode::DELETED_FORUM; @@ -299,7 +355,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) * analyse the old and new group in order to detect possible * notifications for clients */ - RsGxsGroupChange* grpChange = dynamic_cast(*it); + auto grpChange = dynamic_cast(gxsChange); RsGxsForumGroupItem* old_forum_grp_item = dynamic_cast(grpChange->mOldGroupItem); @@ -312,9 +368,13 @@ void p3GxsForums::notifyChanges(std::vector &changes) "mNewGroup not of type RsGxsForumGroupItem or NULL. " "This is inconsistent!"); print_stacktrace(); - goto cleanup; + break; } +#ifdef RS_DEEP_FORUMS_INDEX + mDeepIndex.indexForumGroup(new_forum_grp_item->mGroup); +#endif + /* First of all, we check if there is a difference between the old * and new list of moderators */ @@ -382,9 +442,6 @@ void p3GxsForums::notifyChanges(std::vector &changes) " Currently not handled." ); break; } - -cleanup: - delete *it; } } @@ -1348,6 +1405,254 @@ bool RsGxsForumGroup::canEditPosts(const RsGxsId& id) const id == mMeta.mAuthorId; } +std::error_condition p3GxsForums::getContentSummaries( + const RsGxsGroupId& forumId, + const std::set& contentIds, + std::vector& summaries ) +{ + uint32_t token; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_META; + + GxsMsgReq msgReq; + msgReq[forumId] = contentIds; + + + if(!requestMsgInfo(token, opts, msgReq)) + { + RS_ERR("requestMsgInfo failed"); + return std::errc::invalid_argument; + } + + switch(waitToken(token, std::chrono::seconds(5))) + { + case RsTokenService::COMPLETE: + { + GxsMsgMetaMap metaMap; + if(!RsGenExchange::getMsgMeta(token, metaMap)) + return std::errc::result_out_of_range; + summaries = metaMap[forumId]; + return std::error_condition(); + } + case RsTokenService::PARTIAL: // [[fallthrough]]; + case RsTokenService::PENDING: + return std::errc::timed_out; + default: + return std::errc::not_supported; + } +} + +#ifdef RS_DEEP_FORUMS_INDEX +std::error_condition p3GxsForums::handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) +{ + RS_DBG1(""); + + RsGxsForumsSearchRequest request; + { + RsGenericSerializer::SerializeContext ctx(requestData, requestSize); + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::DESERIALIZE; + RS_SERIAL_PROCESS(request); + } + + if(request.mType != RsGxsForumsItems::SEARCH_REQUEST) + { + // If more types are implemented we would put a switch on mType instead + RS_WARN( "Got search request with unkown type: ", + static_cast(request.mType) ); + return std::errc::bad_message; + } + + RsGxsForumsSearchReply reply; + auto mErr = prepareSearchResults(request.mQuery, true, reply.mResults); + if(mErr || reply.mResults.empty()) return mErr; + + { + RsGenericSerializer::SerializeContext ctx; + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::SIZE_ESTIMATE; + RS_SERIAL_PROCESS(reply); + resultSize = ctx.mOffset; + } + + resultData = rs_malloc(resultSize); + RsGenericSerializer::SerializeContext ctx(resultData, resultSize); + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::SERIALIZE; + RS_SERIAL_PROCESS(reply); + + return std::error_condition(); +} + +std::error_condition p3GxsForums::distantSearchRequest( + const std::string& matchString, TurtleRequestId& searchId ) +{ + RsGxsForumsSearchRequest request; + request.mQuery = matchString; + + uint32_t requestSize; + { + RsGenericSerializer::SerializeContext ctx; + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::SIZE_ESTIMATE; + RS_SERIAL_PROCESS(request); + requestSize = ctx.mOffset; + } + + std::error_condition ec; + auto requestData = rs_malloc(requestSize, &ec); + if(!requestData) return ec; + { + RsGenericSerializer::SerializeContext ctx(requestData, requestSize); + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::SERIALIZE; + RS_SERIAL_PROCESS(request); + } + + return netService()->distantSearchRequest( + requestData, requestSize, + static_cast(serviceType()), searchId ); +} + +std::error_condition p3GxsForums::localSearch( + const std::string& matchString, + std::vector& searchResults ) +{ return prepareSearchResults(matchString, false, searchResults); } + +std::error_condition p3GxsForums::prepareSearchResults( + const std::string& matchString, bool publicOnly, + std::vector& searchResults ) +{ + std::vector results; + auto mErr = mDeepIndex.search(matchString, results); + if(mErr) return mErr; + + searchResults.clear(); + for(auto uRes: results) + { + RsUrl resUrl(uRes.mUrl); + const auto forumIdStr = resUrl.getQueryV(RsGxsForums::FORUM_URL_ID_FIELD); + if(!forumIdStr) + { + RS_ERR( "Forum URL retrieved from deep index miss ID. ", + "Should never happen! ", uRes.mUrl ); + print_stacktrace(); + return std::errc::address_not_available; + } + + std::vector forumsInfo; + RsGxsGroupId forumId(*forumIdStr); + if(forumId.isNull()) + { + RS_ERR( "Forum ID retrieved from deep index is invalid. ", + "Should never happen! ", uRes.mUrl ); + print_stacktrace(); + return std::errc::bad_address; + } + + if( !getForumsInfo(std::list{forumId}, forumsInfo) || + forumsInfo.empty() ) + { + RS_ERR( "Forum just parsed from deep index link not found. " + "Should never happen! ", forumId, " ", uRes.mUrl ); + print_stacktrace(); + return std::errc::identifier_removed; + } + + RsGroupMetaData& fMeta(forumsInfo[0].mMeta); + + // Avoid leaking sensitive information to unkown peers + if( publicOnly && + !(fMeta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC) ) continue; + + RsGxsSearchResult res; + res.mGroupId = forumId; + res.mGroupName = fMeta.mGroupName; + res.mAuthorId = fMeta.mAuthorId; + res.mPublishTs = fMeta.mPublishTs; + res.mSearchContext = uRes.mSnippet; + + auto postIdStr = + resUrl.getQueryV(RsGxsForums::FORUM_URL_MSG_ID_FIELD); + if(postIdStr) + { + RsGxsMessageId msgId(*postIdStr); + if(msgId.isNull()) + { + RS_ERR( "Post just parsed from deep index link is invalid. " + "Should never happen! ", postIdStr, " ", uRes.mUrl ); + print_stacktrace(); + return std::errc::bad_address; + } + + std::vector msgSummaries; + auto errc = getContentSummaries( + forumId, std::set{msgId}, msgSummaries); + if(errc) return errc; + + if(msgSummaries.size() != 1) + { + RS_ERR( "getContentSummaries returned: ", msgSummaries.size(), + "should never happen!" ); + return std::errc::result_out_of_range; + } + + RsMsgMetaData& msgMeta(msgSummaries[0]); + res.mMsgId = msgMeta.mMsgId; + res.mMsgName = msgMeta.mMsgName; + res.mAuthorId = msgMeta.mAuthorId; + } + + RS_DBG4(res); + searchResults.push_back(res); + } + + return std::error_condition(); +} + +std::error_condition p3GxsForums::receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) +{ + RsGxsForumsSearchReply reply; + { + RsGenericSerializer::SerializeContext ctx(resultData, resultSize); + RsGenericSerializer::SerializeJob j = + RsGenericSerializer::SerializeJob::DESERIALIZE; + RS_SERIAL_PROCESS(reply); + } + free(resultData); + + if(reply.mType != RsGxsForumsItems::SEARCH_REPLY) + { + // If more types are implemented we would put a switch on mType instead + RS_WARN( "Got search request with unkown type: ", + static_cast(reply.mType) ); + return std::errc::bad_message; + } + + auto event = std::make_shared(); + event->mSearchId = requestId; + event->mSearchResults = reply.mResults; + rsEvents->postEvent(event); + return std::error_condition(); +} + +#else // def RS_DEEP_FORUMS_INDEX + +std::error_condition p3GxsForums::distantSearchRequest( + const std::string&, TurtleRequestId& ) +{ return std::errc::function_not_supported; } + +std::error_condition p3GxsForums::localSearch( + const std::string&, + std::vector& ) +{ return std::errc::function_not_supported; } + +#endif // def RS_DEEP_FORUMS_INDEX + /*static*/ const std::string RsGxsForums::DEFAULT_FORUM_BASE_URL = "retroshare:///forums"; /*static*/ const std::string RsGxsForums::FORUM_URL_NAME_FIELD = diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index 97f04cc7b..b499e7b0d 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -32,6 +32,10 @@ #include "util/rstickevent.h" #include "util/rsdebug.h" +#ifdef RS_DEEP_FORUMS_INDEX +#include "deep_search/forumsindex.hpp" +#endif + class p3GxsForums: public RsGenExchange, public RsGxsForums, public p3Config, public RsTickEvent /* only needed for testing - remove after */ @@ -142,7 +146,34 @@ public: /// @see RsGxsForums std::error_condition setPostKeepForever( const RsGxsGroupId& forumId, const RsGxsMessageId& postId, - bool keepForever ) override; + bool keepForever ) override; + + /// @see RsGxsForums + std::error_condition getContentSummaries( + const RsGxsGroupId& forumId, + const std::set& contentIds, + std::vector& summaries ) override; + + /// @see RsGxsForums + std::error_condition distantSearchRequest( + const std::string& matchString, TurtleRequestId& searchId ) override; + + /// @see RsGxsForums + std::error_condition localSearch( + const std::string& matchString, + std::vector& searchResults ) override; + +#ifdef RS_DEEP_FORUMS_INDEX + /// @see RsNxsObserver + std::error_condition handleDistantSearchRequest( + rs_view_ptr requestData, uint32_t requestSize, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; + + /// @see RsNxsObserver + std::error_condition receiveDistantSearchResult( + const TurtleRequestId requestId, + rs_owner_ptr& resultData, uint32_t& resultSize ) override; +#endif /// implementation of rsGxsGorums /// @@ -155,6 +186,17 @@ public: bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas) ; +protected: +#ifdef RS_DEEP_FORUMS_INDEX + /** Internal usage + * @param[in] publicOnly if true is passed only results pertaining to + * publicly shared forums are returned + */ + std::error_condition prepareSearchResults( + const std::string& matchString, bool publicOnly, + std::vector& searchResults ); +#endif //def RS_DEEP_FORUMS_INDEX + private: static uint32_t forumsAuthenPolicy(); @@ -189,4 +231,8 @@ bool generateGroup(uint32_t &token, std::string groupName); std::map mKnownForums ; RsMutex mKnownForumsMutex; + +#ifdef RS_DEEP_FORUMS_INDEX + DeepForumsIndex mDeepIndex; +#endif }; diff --git a/libretroshare/src/turtle/turtleclientservice.h b/libretroshare/src/turtle/turtleclientservice.h index 9cbe5763f..55525ae3c 100644 --- a/libretroshare/src/turtle/turtleclientservice.h +++ b/libretroshare/src/turtle/turtleclientservice.h @@ -19,23 +19,25 @@ * along with this program. If not, see . * * * *******************************************************************************/ - -// This class is the parent class for any service that will use the turtle router to distribute its packets. -// Typical representative clients include: -// -// p3ChatService: opens tunnels to distant peers for chatting -// ftServer: searches and open tunnels to distant sources for file transfer -// #pragma once #include #include -#include -#include + +#include "serialiser/rsserial.h" +#include "turtle/rsturtleitem.h" +#include "util/rsdebug.h" struct RsItem; class p3turtle ; +/** This class is the parent class for any service that will use the turtle + * router to distribute its packets. + * Typical representative clients include: + * p3ChatService: opens tunnels to distant peers for chatting + * ftServer: searches and open tunnels to distant sources for file + * transfer + */ class RsTurtleClientService { public: @@ -87,30 +89,35 @@ class RsTurtleClientService std::cerr << "!!!!!! Received Data from turtle router, but the client service is not handling it !!!!!!!!!!" << std::endl ; } - /*! - * \brief receiveSearchRequest - * This method is called by the turtle router to notify the client of a search request in the form generic data. The returned - * result contains the serialised generic result returned by the client. - * - * The turtle router keeps the memory ownership over search_request_data - * - * \param search_request_data generic serialized search data - * \param search_request_data_len length of the serialized search data - * \param search_result_data generic serialized search result data - * \param search_result_data_len length of the serialized search result data - * \param max_allowed_hits max number of hits allowed to be sent back and forwarded - * - * \return true if the search is successful. - */ - virtual bool receiveSearchRequest(unsigned char */*search_request_data*/, - uint32_t /*search_request_data_len*/, - unsigned char *& /*search_result_data*/, - uint32_t& /*search_result_data_len*/, - uint32_t& /* max_allows_hits */) - { - std::cerr << "!!!!!! Received search result from turtle router, but the client service who requested it is not handling it !!!!!!!!!!" << std::endl ; - return false; - } + /*! + * This method is called by the turtle router to notify the client of a + * search request in the form generic data. + * The returned result contains the serialised generic result returned by the + * client service. + * The turtle router keeps the memory ownership over search_request_data + * \param search_request_data generic serialized search data + * \param search_request_data_len length of the serialized search data + * \param search_result_data generic serialized search result data + * \param search_result_data_len length of the serialized search result data + * \param max_allowed_hits max number of hits allowed to be sent back and + * forwarded + * \return true if matching results are available, false otherwise. + */ + virtual bool receiveSearchRequest( + unsigned char *search_request_data, uint32_t search_request_data_len, + unsigned char *& search_result_data, uint32_t& search_result_data_len, + uint32_t& max_allows_hits ) + { + /* Suppress unused warning this way and not commenting the param names + * so doxygen match documentation against params */ + (void) search_request_data; (void) search_request_data_len; + (void) search_result_data; (void) search_result_data_len; + (void) max_allows_hits; + + RS_WARN( "Received search request from turtle router, but the client " + "is not handling it!" ); + return false; + } /*! * \brief receiveSearchResult diff --git a/retroshare.pri b/retroshare.pri index 8c55efd8f..d0439e5e2 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -141,6 +141,11 @@ rs_macos10.15:CONFIG -= rs_macos10.11 CONFIG *= no_rs_jsonapi rs_jsonapi:CONFIG -= no_rs_jsonapi +# To enable forums indexing append the following assignation to qmake command +# line "CONFIG+=rs_deep_forums_index" +CONFIG *= no_rs_deep_forums_index +rs_deep_forums_index:CONFIG -= no_rs_deep_forums_index + # To enable channel indexing append the following assignation to qmake command # line "CONFIG+=rs_deep_channels_index" CONFIG *= no_rs_deep_channels_index @@ -561,6 +566,7 @@ rs_webui { DEFINES *= RS_WEBUI } +rs_deep_forums_index:DEFINES *= RS_DEEP_FORUMS_INDEX rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX From dcb2bee8cc0c7afa8d0a52e3d2e76e82b67b444a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 25 Feb 2021 11:18:26 +0100 Subject: [PATCH 180/697] Epurate this branch from channels deep search changes --- .../src/deep_search/channelsindex.cpp | 173 ++++++++++-------- .../src/deep_search/channelsindex.hpp | 39 ++-- libretroshare/src/retroshare/rsgxschannels.h | 149 +++++---------- libretroshare/src/rsitems/rsgxschannelitems.h | 65 +------ libretroshare/src/services/p3gxschannels.h | 74 +++++--- .../src/gui/gxschannels/GxsChannelDialog.cpp | 4 +- 6 files changed, 218 insertions(+), 286 deletions(-) diff --git a/libretroshare/src/deep_search/channelsindex.cpp b/libretroshare/src/deep_search/channelsindex.cpp index 86a1e341a..cd1c374fc 100644 --- a/libretroshare/src/deep_search/channelsindex.cpp +++ b/libretroshare/src/deep_search/channelsindex.cpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2019-2021 Asociación Civil Altermundi * + * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * Copyright (C) 2019 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -20,23 +20,16 @@ #include "deep_search/channelsindex.hpp" #include "deep_search/commonutils.hpp" -#include "retroshare/rsinit.h" -#include "util/rsdebuglevel3.h" -/*static*/ std::string DeepChannelsIndex::dbDefaultPath() -{ return RsAccounts::AccountDirectory() + "/deep_channels_xapian_db"; } - -std::error_condition DeepChannelsIndex::search( +uint32_t DeepChannelsIndex::search( const std::string& queryStr, std::vector& results, uint32_t maxResults ) { - RS_DBG3(queryStr); - results.clear(); std::unique_ptr dbPtr( - DeepSearch::openReadOnlyDatabase(mDbPath) ); - if(!dbPtr) return std::errc::bad_file_descriptor; + DeepSearch::openReadOnlyDatabase(dbPath()) ); + if(!dbPtr) return 0; Xapian::Database& db(*dbPtr); @@ -70,13 +63,17 @@ std::error_condition DeepChannelsIndex::search( results.push_back(s); } - return std::error_condition(); + return static_cast(results.size()); } -std::error_condition DeepChannelsIndex::indexChannelGroup( - const RsGxsChannelGroup& chan ) +void DeepChannelsIndex::indexChannelGroup(const RsGxsChannelGroup& chan) { - RS_DBG4(chan); + std::unique_ptr dbPtr( + DeepSearch::openWritableDatabase( + dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); + if(!dbPtr) return; + + Xapian::WritableDatabase& db(*dbPtr); // Set up a TermGenerator that we'll use in indexing. Xapian::TermGenerator termgenerator; @@ -97,8 +94,21 @@ std::error_condition DeepChannelsIndex::indexChannelGroup( termgenerator.increase_termpos(); termgenerator.index_text(chan.mDescription); + RsUrl chanUrl; chanUrl + .setScheme("retroshare").setPath("/channel") + .setQueryKV("id", chan.mMeta.mGroupId.toStdString()); + const std::string idTerm("Q" + chanUrl.toString()); + + chanUrl.setQueryKV("publishTs", std::to_string(chan.mMeta.mPublishTs)); + chanUrl.setQueryKV("name", chan.mMeta.mGroupName); + if(!chan.mMeta.mAuthorId.isNull()) + chanUrl.setQueryKV("authorId", chan.mMeta.mAuthorId.toStdString()); + if(chan.mMeta.mSignFlags) + chanUrl.setQueryKV( "signFlags", + std::to_string(chan.mMeta.mSignFlags) ); + std::string rsLink(chanUrl.toString()); + // store the RS link so we are able to retrive it on matching search - const std::string rsLink(channelIndexId(chan.mMeta.mGroupId)); doc.add_value(URL_VALUENO, rsLink); // Store some fields for display purposes. @@ -107,32 +117,35 @@ std::error_condition DeepChannelsIndex::indexChannelGroup( // We use the identifier to ensure each object ends up in the // database only once no matter how many times we run the // indexer. "Q" prefix is a Xapian convention for unique id term. - const std::string idTerm("Q" + rsLink); doc.add_boolean_term(idTerm); - - mWriteQueue.push( [idTerm, doc](Xapian::WritableDatabase& db) - { db.replace_document(idTerm, doc); } ); - - return std::error_condition(); + db.replace_document(idTerm, doc); } -std::error_condition DeepChannelsIndex::removeChannelFromIndex( - const RsGxsGroupId& grpId ) +void DeepChannelsIndex::removeChannelFromIndex(RsGxsGroupId grpId) { - RS_DBG3(grpId); - // "Q" prefix is a Xapian convention for unique id term. - const std::string idTerm("Q" + channelIndexId(grpId)); - mWriteQueue.push( [idTerm](Xapian::WritableDatabase& db) - { db.delete_document(idTerm); } ); + RsUrl chanUrl; chanUrl + .setScheme("retroshare").setPath("/channel") + .setQueryKV("id", grpId.toStdString()); + std::string idTerm("Q" + chanUrl.toString()); - return std::error_condition(); + std::unique_ptr dbPtr( + DeepSearch::openWritableDatabase( + dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); + if(!dbPtr) return; + + Xapian::WritableDatabase& db(*dbPtr); + db.delete_document(idTerm); } -std::error_condition DeepChannelsIndex::indexChannelPost( - const RsGxsChannelPost& post ) +void DeepChannelsIndex::indexChannelPost(const RsGxsChannelPost& post) { - RS_DBG4(post); + std::unique_ptr dbPtr( + DeepSearch::openWritableDatabase( + dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); + if(!dbPtr) return; + + Xapian::WritableDatabase& db(*dbPtr); // Set up a TermGenerator that we'll use in indexing. Xapian::TermGenerator termgenerator; @@ -147,16 +160,21 @@ std::error_condition DeepChannelsIndex::indexChannelPost( termgenerator.index_text( DeepSearch::timetToXapianDate(post.mMeta.mPublishTs), 1, "D" ); - // Avoid indexing RetroShare-gui HTML tags - const std::string cleanMsg = DeepSearch::simpleTextHtmlExtract(post.mMsg); - termgenerator.index_text( - DeepSearch::simpleTextHtmlExtract(post.mMsg), 1, "XD" ); + // TODO: we should strip out HTML tags instead of skipping indexing + // Avoid indexing HTML + bool isPlainMsg = + post.mMsg[0] != '<' || post.mMsg[post.mMsg.size() - 1] != '>'; + + if(isPlainMsg) + termgenerator.index_text(post.mMsg, 1, "XD"); // Index fields without prefixes for general search. termgenerator.index_text(post.mMeta.mMsgName); - - termgenerator.increase_termpos(); - termgenerator.index_text(cleanMsg); + if(isPlainMsg) + { + termgenerator.increase_termpos(); + termgenerator.index_text(post.mMsg); + } for(const RsGxsFile& attachment : post.mFiles) { @@ -166,50 +184,47 @@ std::error_condition DeepChannelsIndex::indexChannelPost( termgenerator.index_text(attachment.mName); } - // store the RS link so we are able to retrive it on matching search - const std::string rsLink(postIndexId(post.mMeta.mGroupId, post.mMeta.mMsgId)); - doc.add_value(URL_VALUENO, rsLink); - - // Store some fields for display purposes. - doc.set_data(post.mMeta.mMsgName + "\n" + cleanMsg); - // We use the identifier to ensure each object ends up in the // database only once no matter how many times we run the // indexer. - const std::string idTerm("Q" + rsLink); + RsUrl postUrl; postUrl + .setScheme("retroshare").setPath("/channel") + .setQueryKV("id", post.mMeta.mGroupId.toStdString()) + .setQueryKV("msgid", post.mMeta.mMsgId.toStdString()); + std::string idTerm("Q" + postUrl.toString()); + + postUrl.setQueryKV("publishTs", std::to_string(post.mMeta.mPublishTs)); + postUrl.setQueryKV("name", post.mMeta.mMsgName); + postUrl.setQueryKV("authorId", post.mMeta.mAuthorId.toStdString()); + std::string rsLink(postUrl.toString()); + + // store the RS link so we are able to retrive it on matching search + doc.add_value(URL_VALUENO, rsLink); + + // Store some fields for display purposes. + if(isPlainMsg) + doc.set_data(post.mMeta.mMsgName + "\n" + post.mMsg); + else doc.set_data(post.mMeta.mMsgName); + doc.add_boolean_term(idTerm); - - mWriteQueue.push( [idTerm, doc](Xapian::WritableDatabase& db) - { db.replace_document(idTerm, doc); } ); - - return std::error_condition(); + db.replace_document(idTerm, doc); } -std::error_condition DeepChannelsIndex::removeChannelPostFromIndex( - const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ) -{ - RS_DBG3(grpId, msgId); - - std::string idTerm("Q" + postIndexId(grpId, msgId)); - mWriteQueue.push( [idTerm](Xapian::WritableDatabase& db) - { db.delete_document(idTerm); } ); - - return std::error_condition(); -} - -/*static*/ std::string DeepChannelsIndex::channelIndexId(RsGxsGroupId grpId) -{ - RsUrl channelIndexId(RsGxsChannels::DEFAULT_CHANNEL_BASE_URL); - channelIndexId.setQueryKV( - RsGxsChannels::CHANNEL_URL_ID_FIELD, grpId.toStdString() ); - return channelIndexId.toString(); -} - -/*static*/ std::string DeepChannelsIndex::postIndexId( +void DeepChannelsIndex::removeChannelPostFromIndex( RsGxsGroupId grpId, RsGxsMessageId msgId ) { - RsUrl postIndexId(RsGxsChannels::DEFAULT_CHANNEL_BASE_URL); - postIndexId.setQueryKV(RsGxsChannels::CHANNEL_URL_ID_FIELD, grpId.toStdString()); - postIndexId.setQueryKV(RsGxsChannels::CHANNEL_URL_MSG_ID_FIELD, msgId.toStdString()); - return postIndexId.toString(); + RsUrl postUrl; postUrl + .setScheme("retroshare").setPath("/channel") + .setQueryKV("id", grpId.toStdString()) + .setQueryKV("msgid", msgId.toStdString()); + // "Q" prefix is a Xapian convention for unique id term. + std::string idTerm("Q" + postUrl.toString()); + + std::unique_ptr dbPtr( + DeepSearch::openWritableDatabase( + dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); + if(!dbPtr) return; + + Xapian::WritableDatabase& db(*dbPtr); + db.delete_document(idTerm); } diff --git a/libretroshare/src/deep_search/channelsindex.hpp b/libretroshare/src/deep_search/channelsindex.hpp index b767ce2b4..0a49629d9 100644 --- a/libretroshare/src/deep_search/channelsindex.hpp +++ b/libretroshare/src/deep_search/channelsindex.hpp @@ -1,8 +1,8 @@ /******************************************************************************* * RetroShare full text indexing and search implementation based on Xapian * * * - * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2019-2021 Asociación Civil Altermundi * + * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * Copyright (C) 2019 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License version 3 as * @@ -24,8 +24,8 @@ #include "util/rstime.h" #include "retroshare/rsgxschannels.h" +#include "retroshare/rsinit.h" #include "util/rsurl.h" -#include "deep_search/commonutils.hpp" struct DeepChannelsSearchResult { @@ -36,34 +36,28 @@ struct DeepChannelsSearchResult struct DeepChannelsIndex { - explicit DeepChannelsIndex(const std::string& dbPath) : - mDbPath(dbPath), mWriteQueue(dbPath) {} - /** * @brief Search indexed GXS groups and messages * @param[in] maxResults maximum number of acceptable search results, 0 for * no limits * @return search results count */ - std::error_condition search( - const std::string& queryStr, - std::vector& results, - uint32_t maxResults = 100 ); + static uint32_t search( const std::string& queryStr, + std::vector& results, + uint32_t maxResults = 100 ); - std::error_condition indexChannelGroup(const RsGxsChannelGroup& chan); + static void indexChannelGroup(const RsGxsChannelGroup& chan); - std::error_condition removeChannelFromIndex(const RsGxsGroupId& grpId); + static void removeChannelFromIndex(RsGxsGroupId grpId); - std::error_condition indexChannelPost(const RsGxsChannelPost& post); + static void indexChannelPost(const RsGxsChannelPost& post); - std::error_condition removeChannelPostFromIndex( - const RsGxsGroupId& grpId, const RsGxsMessageId& msgId ); + static void removeChannelPostFromIndex( + RsGxsGroupId grpId, RsGxsMessageId msgId ); - static std::string dbDefaultPath(); + static uint32_t indexFile(const std::string& path); private: - static std::string channelIndexId(RsGxsGroupId grpId); - static std::string postIndexId(RsGxsGroupId grpId, RsGxsMessageId msgId); enum : Xapian::valueno { @@ -74,7 +68,10 @@ private: BAD_VALUENO = Xapian::BAD_VALUENO }; - const std::string mDbPath; - - DeepSearch::StubbornWriteOpQueue mWriteQueue; + static const std::string& dbPath() + { + static const std::string dbDir = + RsAccounts::AccountDirectory() + "/deep_channels_xapian_db"; + return dbDir; + } }; diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index a91e341a7..421417bdc 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2019-2021 Asociación Civil Altermundi * + * Copyright (C) 2018-2020 Gioacchino Mazzurco * + * Copyright (C) 2019-2020 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -46,11 +46,6 @@ class RsGxsChannels; extern RsGxsChannels* rsGxsChannels; -/* TODO: At this abstraction level that turtle is used for distant searches - * should be an hidden implementation detail. As of today a bit of those - * implementation details leaks around because we use TurtleRequestId in this - * interface */ - struct RsGxsChannelGroup : RsSerializable, RsGxsGenericGroupData { RsGxsChannelGroup() : mAutoDownload(false) {} @@ -113,38 +108,29 @@ struct RsGxsChannelPost : RsSerializable, RsGxsGenericMsgData enum class RsChannelEventCode: uint8_t { UNKNOWN = 0x00, - NEW_CHANNEL = 0x01, /// emitted when new channel is received - UPDATED_CHANNEL = 0x02, /// emitted when existing channel is updated - NEW_MESSAGE = 0x03, /// new message reeived in a particular channel (group and msg id) - UPDATED_MESSAGE = 0x04, /// existing message has been updated in a particular channel - RECEIVED_PUBLISH_KEY = 0x05, /// publish key for this channel has been received - SUBSCRIBE_STATUS_CHANGED = 0x06, /// subscription for channel mChannelGroupId changed. - READ_STATUS_CHANGED = 0x07, /// existing message has been read or set to unread - - /** Result for the given group id available for the given turtle request id - * @deprecated kept for retrocompatibility with old search system new code - * should use @see DISTANT_SEARCH_RESULT instead */ - RECEIVED_TURTLE_SEARCH_RESULT = 0x08, - - STATISTICS_CHANGED = 0x09, /// stats (nb of supplier friends, how many msgs they have etc) has changed - SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed - NEW_COMMENT = 0x0b, /// new comment arrived/published. mChannelThreadId gives the ID of the commented message - NEW_VOTE = 0x0c, /// new vote arrived/published. mChannelThreadId gives the ID of the votes message comment - DELETED_CHANNEL = 0x0d, /// channel was deleted by auto-cleaning system - DELETED_POST = 0x0e, /// Post deleted (usually by cleaning) - DISTANT_SEARCH_RESULT = 0x0f /// Distant search result received + NEW_CHANNEL = 0x01, // emitted when new channel is received + UPDATED_CHANNEL = 0x02, // emitted when existing channel is updated + NEW_MESSAGE = 0x03, // new message reeived in a particular channel (group and msg id) + UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular channel + RECEIVED_PUBLISH_KEY = 0x05, // publish key for this channel has been received + SUBSCRIBE_STATUS_CHANGED = 0x06, // subscription for channel mChannelGroupId changed. + READ_STATUS_CHANGED = 0x07, // existing message has been read or set to unread + RECEIVED_DISTANT_SEARCH_RESULT = 0x08, // result for the given group id available for the given turtle request id + STATISTICS_CHANGED = 0x09, // stats (nb of supplier friends, how many msgs they have etc) has changed + SYNC_PARAMETERS_UPDATED = 0x0a, // sync and storage times have changed + NEW_COMMENT = 0x0b, // new comment arrived/published. mChannelThreadId gives the ID of the commented message + NEW_VOTE = 0x0c, // new vote arrived/published. mChannelThreadId gives the ID of the votes message comment + DELETED_CHANNEL = 0x0d, // channel was deleted by auto-cleaning system }; struct RsGxsChannelEvent: RsEvent { - RsGxsChannelEvent(): - RsEvent(RsEventType::GXS_CHANNELS), - mChannelEventCode(RsChannelEventCode::UNKNOWN) {} + RsGxsChannelEvent(): RsEvent(RsEventType::GXS_CHANNELS), mChannelEventCode(RsChannelEventCode::UNKNOWN) {} RsChannelEventCode mChannelEventCode; RsGxsGroupId mChannelGroupId; RsGxsMessageId mChannelMsgId; - RsGxsMessageId mChannelThreadId; + RsGxsMessageId mChannelThreadId; ///* @see RsEvent @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override @@ -157,14 +143,13 @@ struct RsGxsChannelEvent: RsEvent } }; -/** This event is used to factor multiple search results notifications in a - * single event.*/ -struct RS_DEPRECATED_FOR(RsGxsChannelDistantSearchResultEvent) -RsGxsChannelSearchResultEvent: RsEvent +// This event is used to factor multiple search results notifications in a single event. + +struct RsGxsChannelSearchResultEvent: RsEvent { RsGxsChannelSearchResultEvent(): RsEvent(RsEventType::GXS_CHANNELS), - mChannelEventCode(RsChannelEventCode::RECEIVED_TURTLE_SEARCH_RESULT) {} + mChannelEventCode(RsChannelEventCode::RECEIVED_DISTANT_SEARCH_RESULT) {} RsChannelEventCode mChannelEventCode; std::map > mSearchResultsMap; @@ -179,29 +164,6 @@ RsGxsChannelSearchResultEvent: RsEvent } }; -/** This event is fired once distant search results are received */ -struct RsGxsChannelDistantSearchResultEvent: RsEvent -{ - RsGxsChannelDistantSearchResultEvent(): - RsEvent(RsEventType::GXS_CHANNELS), - mChannelEventCode(RsChannelEventCode::DISTANT_SEARCH_RESULT) {} - - RsChannelEventCode mChannelEventCode; - TurtleRequestId mSearchId; - std::vector mSearchResults; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mChannelEventCode); - RS_SERIAL_PROCESS(mSearchId); - RS_SERIAL_PROCESS(mSearchResults); - } -}; - class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService { public: @@ -424,15 +386,11 @@ public: * @brief Get channel content summaries * @jsonapi{development} * @param[in] channelId id of the channel of which the content is requested - * @param[in] contentIds ids of requested contents, if empty summaries of - * all messages are reqeusted * @param[out] summaries storage for summaries - * @return success or error details if something failed + * @return false if something failed, true otherwhise */ - virtual std::error_condition getContentSummaries( - const RsGxsGroupId& channelId, - const std::set& contentIds, - std::vector& summaries ) = 0; + virtual bool getContentSummaries( const RsGxsGroupId& channelId, + std::vector& summaries ) = 0; /** * @brief Toggle post read status. Blocking API. @@ -464,23 +422,22 @@ public: virtual bool subscribeToChannel( const RsGxsGroupId& channelId, bool subscribe ) = 0; - /** - * @brief Retrieve statistics about the channel service + /** + * \brief Retrieve statistics about the channel service * @jsonapi{development} - * @param[out] stat storage for statistics - * @return true on success false otherwise - */ - virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0; + * \param[out] stat Statistics structure + * \return + */ + virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0; - /** - * @brief Retrieve statistics about the given channel + /** + * \brief Retrieve statistics about the given channel * @jsonapi{development} - * @param[in] channelId Id of the channel group - * @param[out] stat storage for statistics - * @return true on success false otherwise - */ - virtual bool getChannelStatistics( - const RsGxsGroupId& channelId, GxsGroupStatistic& stat ) =0; + * \param[in] channelId Id of the channel group + * \param[out] stat Statistics structure + * \return + */ + virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0; /// default base URL used for channels links @see exportChannelLink static const std::string DEFAULT_CHANNEL_BASE_URL; @@ -539,18 +496,14 @@ public: std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; /** - * @brief Search the whole reachable network for matching channels and - * contents + * @brief Search the turtle reachable network for matching channels * @jsonapi{development} - * An @see RsGxsChannelSearchResultEvent is emitted when matching results - * arrives from the network + * An @see RsGxsChannelSearchResultEvent is emitted when matching channels + * arrives from the network * @param[in] matchString string to search into the channels - * @param[out] searchId storage for search id, useful to track search events - * and retrieve search results - * @return success or error details + * @return search id */ - virtual std::error_condition distantSearchRequest( - const std::string& matchString, TurtleRequestId& searchId ) = 0; + virtual TurtleRequestId turtleSearchRequest(const std::string& matchString)=0; /** * @brief Retrieve available search results @@ -580,18 +533,16 @@ public: * @param[out] distantGroup storage for group data * @return false on error, true otherwise */ - virtual bool getDistantSearchResultGroupData( - const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; + virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; - /** - * @brief Get the status of ongoing search - * @return unknown (probably not even searched), known as a search result, - * data request ongoing and data available - */ - virtual DistantSearchGroupStatus getDistantSearchStatus( - const RsGxsGroupId& group_id ) =0; + /** + * @brief getDistantSearchStatus + * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, + * data request ongoing and data available + */ + virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) =0; - /** + /** * @brief Clear accumulated search results * @jsonapi{development} * @param[in] reqId search id diff --git a/libretroshare/src/rsitems/rsgxschannelitems.h b/libretroshare/src/rsitems/rsgxschannelitems.h index 598400966..fa52c8cfc 100644 --- a/libretroshare/src/rsitems/rsgxschannelitems.h +++ b/libretroshare/src/rsitems/rsgxschannelitems.h @@ -3,9 +3,7 @@ * * * libretroshare: retroshare core library * * * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2021 Gioacchino Mazzurco * - * Copyright (C) 2021 Asociación Civil Altermundi * + * Copyright 2012-2012 by Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -21,7 +19,8 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#pragma once +#ifndef RS_GXS_CHANNEL_ITEMS_H +#define RS_GXS_CHANNEL_ITEMS_H #include @@ -31,23 +30,14 @@ #include "serialiser/rstlvfileitem.h" #include "serialiser/rstlvimage.h" -#include "serialiser/rsserializable.h" + #include "retroshare/rsgxschannels.h" + #include "serialiser/rsserializer.h" + #include "util/rsdir.h" -enum class RsGxsChannelItems : uint8_t -{ - GROUP_ITEM = 0x02, - POST_ITEM = 0x03, - SEARCH_REQUEST = 0x04, - SEARCH_REPLY = 0x05, -}; - -RS_DEPRECATED_FOR(RsGxsChannelItems) const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM = 0x02; - -RS_DEPRECATED_FOR(RsGxsChannelItems) const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; class RsGxsChannelGroupItem : public RsGxsGrpItem @@ -89,47 +79,6 @@ public: RsTlvImage mThumbnail; }; -struct RsGxsChannelsSearchRequest : RsSerializable -{ - RsGxsChannelsSearchRequest() : mType(RsGxsChannelItems::SEARCH_REQUEST) {} - - /// Just for easier back and forward compatibility - RsGxsChannelItems mType; - - /// Store search match string - std::string mQuery; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mType); - RS_SERIAL_PROCESS(mQuery); - } - - ~RsGxsChannelsSearchRequest() override = default; -}; - -struct RsGxsChannelsSearchReply : RsSerializable -{ - RsGxsChannelsSearchReply() : mType(RsGxsChannelItems::SEARCH_REPLY) {} - - /// Just for easier back and forward compatibility - RsGxsChannelItems mType; - - /// Results storage - std::vector mResults; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mType); - RS_SERIAL_PROCESS(mResults); - } - - ~RsGxsChannelsSearchReply() override = default; -}; class RsGxsChannelSerialiser : public RsGxsCommentSerialiser { @@ -140,3 +89,5 @@ public: virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; }; + +#endif /* RS_GXS_CHANNEL_ITEMS_H */ diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index 58af0b22d..b5fe1426f 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -4,8 +4,7 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2021 Gioacchino Mazzurco * - * Copyright (C) 2019-2021 Asociación Civil Altermundi * + * Copyright (C) 2018-2019 Gioacchino Mazzurco * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -23,8 +22,6 @@ *******************************************************************************/ #pragma once -#include -#include #include "retroshare/rsgxschannels.h" #include "services/p3gxscommon.h" @@ -33,7 +30,9 @@ #include "util/rsmemory.h" #include "util/rsdebug.h" #include "util/rstickevent.h" -#include "deep_search/channelsindex.hpp" + +#include +#include // This class is only a helper to parse the channel group service string. @@ -57,11 +56,6 @@ class p3GxsChannels: public RsGenExchange, public RsGxsChannels, public: p3GxsChannels( RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs ); - - /// @see RsGxsChannels - std::error_condition distantSearchRequest( - const std::string& matchString, TurtleRequestId& searchId ) override; - virtual RsServiceInfo getServiceInfo() override; virtual void service_tick() override; @@ -75,7 +69,7 @@ protected: virtual bool loadList(std::list& loadList) override; // @see p3Config::loadList(std::list&) virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id) override; - + virtual TurtleRequestId turtleSearchRequest(const std::string& match_string) override; virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &results) override; virtual bool clearDistantSearchResults(TurtleRequestId req) override; virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group) override; @@ -118,6 +112,24 @@ virtual bool getChannelAutoDownload(const RsGxsGroupId &groupid, bool& enabled) virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory) override; virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory) override; +#ifdef TO_REMOVE + /// @see RsGxsChannels::turtleSearchRequest + virtual bool turtleSearchRequest(const std::string& matchString, + const std::function& multiCallback, + rstime_t maxWait = 300 ) override; + + /// @see RsGxsChannels::turtleChannelRequest + virtual bool turtleChannelRequest( + const RsGxsGroupId& channelId, + const std::function& multiCallback, + rstime_t maxWait = 300 ) override; + + /// @see RsGxsChannels::localSearchRequest + virtual bool localSearchRequest(const std::string& matchString, + const std::function& multiCallback, + rstime_t maxWait = 30 ) override; +#endif + /** * Receive results from turtle search @see RsGenExchange @see RsNxsObserver * @see RsGxsNetService::receiveTurtleSearchResults @@ -203,10 +215,9 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; const std::set &contentIds, std::vector &comments) override; - /// @see RsGxsChannels - std::error_condition getContentSummaries( + /// Implementation of @see RsGxsChannels::getContentSummaries + bool getContentSummaries( const RsGxsGroupId& channelId, - const std::set& contentIds, std::vector& summaries ) override; /// Implementation of @see RsGxsChannels::getChannelStatistics @@ -286,17 +297,6 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; virtual bool shareChannelKeys( const RsGxsGroupId& channelId, const std::set& peers ) override; -#ifdef RS_DEEP_CHANNEL_INDEX - /// @see RsNxsObserver - std::error_condition handleDistantSearchRequest( - rs_view_ptr requestData, uint32_t requestSize, - rs_owner_ptr& resultData, uint32_t& resultSize ) override; - - std::error_condition receiveDistantSearchResult( - const TurtleRequestId requestId, - rs_owner_ptr& resultData, uint32_t& resultSize ) override; -#endif - /// Implementation of @see RsGxsChannels::createChannel RS_DEPRECATED_FOR(createChannelV2) bool createChannel(RsGxsChannelGroup& channel) override; @@ -313,6 +313,7 @@ virtual bool ExtraFileRemove(const RsFileHash &hash) override; RS_DEPRECATED_FOR(createVoteV2) bool createVote(RsGxsVote& vote) override; + protected: // Overloaded from GxsTokenQueue for Request callbacks. virtual void handleResponse(uint32_t token, uint32_t req_type @@ -328,6 +329,7 @@ static uint32_t channelsAuthenPolicy(); void request_SpecificSubscribedGroups(const std::list &groups); void load_SubscribedGroups(const uint32_t &token); + void request_SpecificUnprocessedPosts(std::list > &ids); void request_GroupUnprocessedPosts(const std::list &grouplist); void load_unprocessedPosts(uint32_t token); @@ -388,8 +390,26 @@ bool generateGroup(uint32_t &token, std::string groupName); rstime_t mLastDistantSearchNotificationTS; std::map > mSearchResultsToNotify; +#ifdef TO_REMOVE + /** Store search callbacks with timeout*/ + std::map< + TurtleRequestId, + std::pair< + std::function, + std::chrono::system_clock::time_point > + > mSearchCallbacksMap; + RsMutex mSearchCallbacksMapMutex; -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex mDeepIndex; + /** Store distant channels requests callbacks with timeout*/ + std::map< + TurtleRequestId, + std::pair< + std::function, + std::chrono::system_clock::time_point > + > mDistantChannelsCallbacksMap; + RsMutex mDistantChannelsCallbacksMapMutex; + + /// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap + void cleanTimedOutCallbacks(); #endif }; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index baf715a96..e18a161a3 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -411,9 +411,7 @@ void GxsChannelDialog::clearDistantSearchResults(TurtleRequestId id) TurtleRequestId GxsChannelDialog::distantSearch(const QString& search_string) { - TurtleRequestId searchId; - rsGxsChannels->distantSearchRequest(search_string.toStdString(), searchId); - return searchId; + return rsGxsChannels->turtleSearchRequest(search_string.toStdString()) ; } bool GxsChannelDialog::getDistantSearchResults(TurtleRequestId id, std::map& group_infos) From bf8ddf498ec0c85654a5c81f5f5cd6bcb01ba62b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 23 Mar 2021 23:04:10 +0100 Subject: [PATCH 181/697] Fix Android compilation --- libretroshare/src/deep_search/commonutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/deep_search/commonutils.cpp b/libretroshare/src/deep_search/commonutils.cpp index c3b9c5342..693bf9924 100644 --- a/libretroshare/src/deep_search/commonutils.cpp +++ b/libretroshare/src/deep_search/commonutils.cpp @@ -117,7 +117,7 @@ std::error_condition StubbornWriteOpQueue::flush( if(maxRemaining > 0) { std::chrono::milliseconds interval( - std::max(50l, maxRemaining*1000/5) ); + std::max(rstime_t(50), maxRemaining*1000/5) ); RS_DBG3( "Cannot acquire database write lock, retrying in:", interval.count(), "ms" ); RsThread::async([this, acceptDelay, callTS, interval]() From 2196505d19707245bf017c73cc5a149168120d8b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 24 Mar 2021 18:55:41 +0100 Subject: [PATCH 182/697] RsGxsForumsDistantSearchEvent fix event type --- libretroshare/src/retroshare/rsgxsforums.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 561fe646d..4967d46c5 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -156,7 +156,7 @@ struct RsGxsForumEvent: RsEvent struct RsGxsForumsDistantSearchEvent: RsEvent { RsGxsForumsDistantSearchEvent(): - RsEvent(RsEventType::GXS_CHANNELS), + RsEvent(RsEventType::GXS_FORUMS), mForumEventCode(RsForumEventCode::DISTANT_SEARCH_RESULT) {} RsForumEventCode mForumEventCode; From 0b5874017472d616a2ca62cb7f9698647f48545a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 29 Sep 2021 22:25:04 +0200 Subject: [PATCH 183/697] Properly avoid private forum leak in deep search mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC is always true for forums even if they are circle restricted, use circle flags to check if it is really public --- libretroshare/src/retroshare/rsgxscircles.h | 5 +++-- libretroshare/src/services/p3gxsforums.cc | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 32bc8e547..40916f234 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -46,7 +47,7 @@ extern RsGxsCircles* rsGxsCircles; enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat { UNKNOWN = 0, /// Used to detect uninizialized values. - PUBLIC = 1, /// Public distribution, based on GxsIds + PUBLIC = 1, /// Public distribution EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 2f85afe59..6cb3ae5c6 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -653,6 +653,8 @@ bool p3GxsForums::createForumV2( forum.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ | GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; + /* This flag have always this value even for circle restricted forums due to + * how GXS distribute/verify groups */ forum.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; forum.mMeta.mCircleId.clear(); @@ -1565,7 +1567,8 @@ std::error_condition p3GxsForums::prepareSearchResults( // Avoid leaking sensitive information to unkown peers if( publicOnly && - !(fMeta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC) ) continue; + ( static_cast(fMeta.mCircleType) != + RsGxsCircleType::PUBLIC ) ) continue; RsGxsSearchResult res; res.mGroupId = forumId; From 62810d32e13694a64263e8ff86454b05dc00cac7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 26 Oct 2021 15:39:47 +0200 Subject: [PATCH 184/697] deep_search: fix compilation with old Xapian versions --- libretroshare/src/deep_search/commonutils.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libretroshare/src/deep_search/commonutils.cpp b/libretroshare/src/deep_search/commonutils.cpp index 693bf9924..e8e1e4b59 100644 --- a/libretroshare/src/deep_search/commonutils.cpp +++ b/libretroshare/src/deep_search/commonutils.cpp @@ -26,6 +26,14 @@ #include "util/rsthreads.h" #include "util/rsdebuglevel0.h" +#ifndef XAPIAN_AT_LEAST +/// Added in Xapian 1.4.2. +#define XAPIAN_AT_LEAST(A,B,C) \ + (XAPIAN_MAJOR_VERSION > (A) || \ + (XAPIAN_MAJOR_VERSION == (A) && \ + (XAPIAN_MINOR_VERSION > (B) || \ + (XAPIAN_MINOR_VERSION == (B) && XAPIAN_REVISION >= (C))))) +#endif namespace DeepSearch { @@ -34,8 +42,17 @@ std::unique_ptr openReadOnlyDatabase( { try { +#if XAPIAN_AT_LEAST(1,3,2) std::unique_ptr dbPtr( new Xapian::Database(path, flags) ); +#else + std::unique_ptr dbPtr(new Xapian::Database(path)); + if(flags) + { + RS_WARN( "Xapian DB flags: ", flags, " ignored due to old Xapian " + "library version: ", XAPIAN_VERSION, " < 1.3.2" ); + } +#endif return dbPtr; } catch(Xapian::DatabaseOpeningError& e) From b328c3a49317ee3ff383224464e87f21115e1529 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 18:51:40 +0200 Subject: [PATCH 185/697] renamed AuthGPG into AuthPGP --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 20 +-- libretroshare/src/pgp/pgpauxutils.cc | 10 +- libretroshare/src/pqi/authgpg.cc | 124 +++++++++--------- libretroshare/src/pqi/authgpg.h | 12 +- libretroshare/src/pqi/authssl.cc | 12 +- libretroshare/src/pqi/p3peermgr.cc | 20 +-- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3face-config.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 56 ++++---- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 24 ++-- libretroshare/src/rsserver/rsinit.cc | 8 +- libretroshare/src/rsserver/rsloginhandler.cc | 4 +- libretroshare/src/services/p3idservice.cc | 4 +- 15 files changed, 151 insertions(+), 151 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 179a845d7..ad95f7ee3 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthGPG::getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getGPGOwnId()] = DiscPgpInfo(); } @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthGPG::isGPGAccepted(pgpId))) + if (!(AuthPGP::isGPGAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); - AuthGPG::getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); + AuthPGP::getGPGAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -723,7 +723,7 @@ void p3discovery2::processPGPList(const RsPeerId &fromId, const RsDiscPgpListIte std::set::const_iterator fit; for(fit = item->pgpIdSet.ids.begin(); fit != item->pgpIdSet.ids.end(); ++fit) { - if (!AuthGPG::isPGPId(*fit)) + if (!AuthPGP::isPGPId(*fit)) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit; @@ -1058,11 +1058,11 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); + RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isGPGAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; @@ -1078,7 +1078,7 @@ void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &to unsigned char *bin_data; size_t bin_len; - if(!AuthGPG::exportPublicKey(aboutId,bin_data,bin_len,false,true)) + if(!AuthPGP::exportPublicKey(aboutId,bin_data,bin_len,false,true)) { std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl; return ; @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthGPG::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthPGP::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; @@ -1147,7 +1147,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* // otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key. if(det.skip_pgp_signature_validation) - AuthGPG::AllowConnection(det.gpg_id,true); + AuthPGP::AllowConnection(det.gpg_id,true); } /************* from pqiServiceMonitor *******************/ diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index a9c3b36f6..99d3e8880 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -44,7 +44,7 @@ RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) bool PgpAuxUtilsImpl::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const { - return AuthGPG::getKeyFingerprint(id, fp); + return AuthPGP::getKeyFingerprint(id, fp); } bool PgpAuxUtilsImpl::VerifySignBin(const void *data, @@ -54,17 +54,17 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, const PGPFingerprintType& withfingerprint) { - return AuthGPG::VerifySignBin(data, len, sign, signlen, withfingerprint); + return AuthPGP::VerifySignBin(data, len, sign, signlen, withfingerprint); } bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthGPG::getGPGAllList(ids); + return AuthPGP::getGPGAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const { - return AuthGPG::parseSignature(sign,signlen,issuer); + return AuthPGP::parseSignature(sign,signlen,issuer); } diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index b870b5d1e..5e93823a4 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -46,7 +46,7 @@ //const rstime_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour -AuthGPG *AuthGPG::_instance = NULL ; +AuthPGP *AuthPGP::_instance = NULL ; void cleanupZombies(int numkill); // function to cleanup zombies under OSX. @@ -54,24 +54,24 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ -int AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +int AuthPGP::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) { return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); } -bool AuthGPG::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +bool AuthPGP::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) { return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); } -void AuthGPG::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) +void AuthPGP::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) { CfgMgr->addConfiguration(fname, instance()); } -bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) +bool AuthPGP::decryptTextFromFile(std::string& text,const std::string& inputfile) { return instance()->mPgpHandler->decryptTextFromFile(instance()->mOwnGpgId,text,inputfile) ; } -bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) +bool AuthPGP::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { // std::list pids ; // @@ -86,7 +86,7 @@ bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::str // return instance()->mPgpHandler->decryptTextFromString(mOwnGpgId,encrypted_text,output) ; // } -bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) +bool AuthPGP::encryptTextToFile(const std::string& text,const std::string& outfile) { return instance()->mPgpHandler->encryptTextToFile(instance()->mOwnGpgId,text,outfile) ; } @@ -107,7 +107,7 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char return password ; } -void AuthGPG::init( +void AuthPGP::init( const std::string& path_to_public_keyring, const std::string& path_to_secret_keyring, const std::string& path_to_trustdb, @@ -121,12 +121,12 @@ void AuthGPG::init( // if(cb) instance()->mPgpHandler->setPassphraseCallback(cb);else instance()->mPgpHandler->setPassphraseCallback(pgp_pwd_callback); - _instance = new AuthGPG( path_to_public_keyring, + _instance = new AuthPGP( path_to_public_keyring, path_to_secret_keyring, path_to_trustdb, pgp_lock_file ); } -void AuthGPG::exit() +void AuthPGP::exit() { if(_instance) { @@ -136,7 +136,7 @@ void AuthGPG::exit() } } -AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) +AuthPGP::AuthPGP(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), @@ -178,7 +178,7 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa * This function must be called successfully (return == 1) * before anything else can be done. (except above fn). */ -int AuthGPG::GPGInit(const RsPgpId &ownId) +int AuthPGP::GPGInit(const RsPgpId &ownId) { #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; @@ -197,11 +197,11 @@ int AuthGPG::GPGInit(const RsPgpId &ownId) return 1; } - AuthGPG::~AuthGPG() + AuthPGP::~AuthPGP() { } -void AuthGPG::threadTick() +void AuthPGP::threadTick() { rstime::rs_usleep(100 * 1000); //100 msec @@ -223,7 +223,7 @@ void AuthGPG::threadTick() }//if (++count >= 100 || _force_sync_database) } -void AuthGPG::processServices() +void AuthPGP::processServices() { AuthGPGOperation *operation = NULL; AuthGPGService *service = NULL; @@ -318,29 +318,29 @@ void AuthGPG::processServices() delete operation; } -bool AuthGPG::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) +bool AuthPGP::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) { return instance()->mPgpHandler->SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; } /* import to GnuPG and other Certificates */ -bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) +bool AuthPGP::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) { return instance()->mPgpHandler->VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; } -bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) +bool AuthPGP::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) { return instance()->mPgpHandler->parseSignature((unsigned char*)sig,siglen,issuer_id) ; } -bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id) +bool AuthPGP::exportProfile(const std::string& fname,const RsPgpId& exported_id) { return instance()->mPgpHandler->exportGPGKeyPair(fname,exported_id) ; } -bool AuthGPG::exportIdentityToString( +bool AuthPGP::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { @@ -348,24 +348,24 @@ bool AuthGPG::exportIdentityToString( data, pgpId, includeSignatures, errorMsg); } -bool AuthGPG::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) +bool AuthPGP::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) { return instance()->mPgpHandler->importGPGKeyPair(fname,imported_id,import_error) ; } -bool AuthGPG::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) +bool AuthPGP::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) { return instance()->mPgpHandler->importGPGKeyPairFromString(data, gpg_id, import_error); } -bool AuthGPG::active() +bool AuthPGP::active() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->gpgKeySelected; } -bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) +bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -373,7 +373,7 @@ bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::stri } /**** These Two are common */ -std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) +std::string AuthPGP::getGPGName(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -391,7 +391,7 @@ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) } } -AuthGPG *AuthGPG::instance() +AuthPGP *AuthPGP::instance() { if(!_instance) { @@ -401,16 +401,16 @@ AuthGPG *AuthGPG::instance() return _instance; } -bool AuthGPG::isPGPId(const RsPgpId& id) +bool AuthPGP::isPGPId(const RsPgpId& id) { return instance()->mPgpHandler->isGPGId(id); } -bool AuthGPG::isPGPAccepted(const RsPgpId& id) +bool AuthPGP::isPGPAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } /**** These Two are common */ -std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) +std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -429,18 +429,18 @@ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthGPG::getGPGOwnId() +const RsPgpId& AuthPGP::getGPGOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthGPG::getGPGOwnName() +std::string AuthPGP::getGPGOwnName() { return getGPGName(instance()->mOwnGpgId) ; } -bool AuthGPG::getGPGAllList(std::list &ids) +bool AuthPGP::getGPGAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -448,7 +448,7 @@ bool AuthGPG::getGPGAllList(std::list &ids) return true; } -const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& pgp_id) const +const PGPCertificateInfo *AuthPGP::getCertInfoFromStdString(const std::string& pgp_id) const { try { @@ -460,11 +460,11 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p return NULL ; } } -bool AuthGPG::haveSecretKey(const RsPgpId& id) +bool AuthPGP::haveSecretKey(const RsPgpId& id) { return instance()->mPgpHandler->haveSecretKey(id) ; } -bool AuthGPG::isKeySupported(const RsPgpId& id) +bool AuthPGP::isKeySupported(const RsPgpId& id) { const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -474,7 +474,7 @@ bool AuthGPG::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -505,7 +505,7 @@ bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) return true; } -bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) +bool AuthPGP::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) { return instance()->mPgpHandler->getGPGFilteredList(list,filter) ; } @@ -514,17 +514,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthGPG::getGPGValidList(std::list &ids) +bool AuthPGP::getGPGValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthGPG::getGPGAcceptedList(std::list &ids) +bool AuthPGP::getGPGAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthGPG::getGPGSignedList(std::list &ids) +bool AuthPGP::getGPGSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -557,14 +557,14 @@ bool AuthGPG::getGPGSignedList(std::list &ids) /* SKTAN : do not know how to use std::string id */ - std::string AuthGPG::SaveCertificateToString(const RsPgpId &id,bool include_signatures) + std::string AuthPGP::SaveCertificateToString(const RsPgpId &id,bool include_signatures) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ return instance()->mPgpHandler->SaveCertificateToString(id,include_signatures) ; } /* import to GnuPG and other Certificates */ -bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) +bool AuthPGP::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -578,7 +578,7 @@ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_l } /* import to GnuPG and other Certificates */ -bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) +bool AuthPGP::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -605,7 +605,7 @@ bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id, /*************************************/ /* These take PGP Ids */ -bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) +bool AuthPGP::AllowConnection(const RsPgpId& gpg_id, bool accept) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::AllowConnection(" << gpg_id << ")" << std::endl; @@ -625,7 +625,7 @@ bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) } /* These take PGP Ids */ -bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) +bool AuthPGP::SignCertificateLevel0(const RsPgpId &id) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl; @@ -634,7 +634,7 @@ bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) return instance()->privateSignCertificate(id) ; } -bool AuthGPG::RevokeCertificate(const RsPgpId &id) +bool AuthPGP::RevokeCertificate(const RsPgpId &id) { /* remove unused parameter warnings */ (void) id; @@ -646,7 +646,7 @@ bool AuthGPG::RevokeCertificate(const RsPgpId &id) return false; } -bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) +bool AuthPGP::TrustCertificate(const RsPgpId& id, int trustlvl) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl; @@ -654,41 +654,41 @@ bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) return instance()->privateTrustCertificate(id, trustlvl) ; } -bool AuthGPG::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) +bool AuthPGP::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { return instance()->mPgpHandler->encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; } -bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) +bool AuthPGP::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { return instance()->mPgpHandler->decryptDataBin(instance()->mOwnGpgId,data,datalen,sign,signlen) ; } -bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) +bool AuthPGP::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) { return instance()->DoOwnSignature(data, datalen, sign, signlen, reason); } -bool AuthGPG::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) +bool AuthPGP::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) { return instance()->mPgpHandler->exportPublicKey(id,mem_block,mem_size,armoured,include_signatures); } -bool AuthGPG::isPgpPubKeyAvailable(const RsPgpId& pgp_id) +bool AuthPGP::isPgpPubKeyAvailable(const RsPgpId& pgp_id) { return instance()->mPgpHandler->isPgpPubKeyAvailable(pgp_id); } -bool AuthGPG::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) +bool AuthPGP::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) { return instance()->mPgpHandler->getKeyFingerprint(id,fp); } -bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) +bool AuthPGP::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) { return instance()->VerifySignature(data, datalen, sign, signlen, withfingerprint); } /* Sign/Trust stuff */ -int AuthGPG::privateSignCertificate(const RsPgpId &id) +int AuthPGP::privateSignCertificate(const RsPgpId &id) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ @@ -698,7 +698,7 @@ int AuthGPG::privateSignCertificate(const RsPgpId &id) } /* revoke the signature on Certificate */ -int AuthGPG::privateRevokeCertificate(const RsPgpId &/*id*/) +int AuthPGP::privateRevokeCertificate(const RsPgpId &/*id*/) { //RsStackMutex stack(gpgMtx); /******* LOCKED ******/ std::cerr << __PRETTY_FUNCTION__ << ": not implemented!" << std::endl; @@ -706,7 +706,7 @@ int AuthGPG::privateRevokeCertificate(const RsPgpId &/*id*/) return 0; } -int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) +int AuthPGP::privateTrustCertificate(const RsPgpId& id, int trustlvl) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ @@ -726,18 +726,18 @@ int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) // -------------------------------- Config functions ------------------------------ // // -----------------------------------------------------------------------------------// // -RsSerialiser *AuthGPG::setupSerialiser() +RsSerialiser *AuthPGP::setupSerialiser() { RsSerialiser *rss = new RsSerialiser ; rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } -bool AuthGPG::isGPGAccepted(const RsPgpId& id) +bool AuthPGP::isGPGAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } -bool AuthGPG::saveList(bool& cleanup, std::list& lst) +bool AuthPGP::saveList(bool& cleanup, std::list& lst) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::saveList() called" << std::endl ; @@ -768,7 +768,7 @@ bool AuthGPG::saveList(bool& cleanup, std::list& lst) return true; } -bool AuthGPG::loadList(std::list& load) +bool AuthPGP::loadList(std::list& load) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl; @@ -799,7 +799,7 @@ bool AuthGPG::loadList(std::list& load) return true; } -bool AuthGPG::addService(AuthGPGService *service) +bool AuthPGP::addService(AuthGPGService *service) { RsStackMutex stack(instance()->gpgMtxService); /********* LOCKED *********/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 177f71663..d124efdd4 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -89,7 +89,7 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -class AuthGPG: public p3Config, public RsTickingThread +class AuthPGP: public p3Config, public RsTickingThread { public: static void init(const std::string& path_to_pubring, @@ -237,11 +237,11 @@ public: static bool addService(AuthGPGService *service) ; // This is for debug purpose only. Don't use it !! - static void setAuthGPG_debug(AuthGPG *auth_gpg) { _instance = auth_gpg ; } + static void setAuthGPG_debug(AuthPGP *auth_gpg) { _instance = auth_gpg ; } protected: - AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); - virtual ~AuthGPG(); + AuthPGP(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); + virtual ~AuthPGP(); /*****************************************************************/ /*********************** p3config ******************************/ @@ -286,7 +286,7 @@ private: void threadTick() override; /// @see RsTickingThread private: - static AuthGPG *instance(); + static AuthPGP *instance(); RsMutex gpgMtxService; RsMutex gpgMtxEngine; @@ -310,7 +310,7 @@ private: std::list services ; - static AuthGPG *_instance ; + static AuthPGP *_instance ; }; #endif diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 6d14d0043..47eea9e58 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthGPG::getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getGPGOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getGPGOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -944,7 +944,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) std::cerr << "Buffers Allocated" << std::endl; /* NOW Sign via GPG Functions */ - if (!AuthGPG::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) + if (!AuthPGP::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) { sigoutl = 0; goto err; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthGPG::getGPGDetails(issuer, pd)) + if (!AuthPGP::getGPGDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1184,7 +1184,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) // passed, verify the signature itself - if (!AuthGPG::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) + if (!AuthPGP::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) { diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE; goto err; @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthGPG::getGPGAcceptedList(gpgIds); + AuthPGP::getGPGAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthGPG::getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getGPGOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -962,7 +962,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg // check that the PGP key is known - if(!AuthGPG::isPGPId(gpg_id)) + if(!AuthPGP::isPGPId(gpg_id)) { RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl; return false; @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthGPG::isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getGPGOwnId()) + if (!AuthPGP::isGPGAccepted(gpg_id) && gpg_id != AuthPGP::getGPGOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthGPG::getGPGName(gpg_id); + pstate.name = AuthPGP::getGPGName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -1126,8 +1126,8 @@ bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_ * superficially set to true the PGP signature verification would have been * skipped and the attacker connection would be accepted. * If the PGP key is available add it as full friend. */ - if(AuthGPG::isPgpPubKeyAvailable(pgp_id)) - AuthGPG::AllowConnection(pgp_id, true); + if(AuthPGP::isPgpPubKeyAvailable(pgp_id)) + AuthPGP::AllowConnection(pgp_id, true); else pstate.skip_pgp_signature_validation = true; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthGPG::getGPGOwnId(); + mOwnState.gpg_id = AuthPGP::getGPGOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthGPG::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getGPGOwnId()) + if(AuthPGP::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthGPG::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getGPGOwnId()) + if(AuthPGP::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index b6f655692..bf91b72d9 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index a9e392a56..c579280bc 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3face-config.cc b/libretroshare/src/rsserver/p3face-config.cc index 3251f33eb..62c60815b 100644 --- a/libretroshare/src/rsserver/p3face-config.cc +++ b/libretroshare/src/rsserver/p3face-config.cc @@ -118,7 +118,7 @@ void RsServer::rsGlobalShutDown() // if(mWire) mWire->join(); // #endif - AuthGPG::exit(); + AuthPGP::exit(); mShutdownCallback(0); } diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 25caac374..58dae7e44 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -254,7 +254,7 @@ bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint bool p3Peers::haveSecretKey(const RsPgpId& id) { - return AuthGPG::haveSecretKey(id); + return AuthPGP::haveSecretKey(id); } /* There are too many dependancies of this function @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthGPG::getGPGOwnId(); + ps.gpg_id = AuthPGP::getGPGOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -559,17 +559,17 @@ bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) bool p3Peers::isKeySupported(const RsPgpId& id) { - return AuthGPG::isKeySupported(id); + return AuthPGP::isKeySupported(id); } std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthGPG::getGPGName(gpg_id); + return AuthPGP::getGPGName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthGPG::isGPGAccepted(pgpId); } +{ return AuthPGP::isGPGAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthGPG::getGPGOwnName(); + return AuthPGP::getGPGOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGAllList(ids); + AuthPGP::getGPGAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGValidList(ids); + AuthPGP::getGPGValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGSignedList(ids); + AuthPGP::getGPGSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthGPG::getGPGAcceptedList(ids)) + if(AuthPGP::getGPGAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthGPG::getGPGAcceptedList(ids); + AuthPGP::getGPGAcceptedList(ids); return true; } @@ -676,7 +676,7 @@ bool p3Peers::getAssociatedSSLIds(const RsPgpId &gpg_id, std::list &id bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason /* = "" */) { - return AuthGPG::SignDataBin(data,len,sign,signlen, reason); + return AuthPGP::SignDataBin(data,len,sign,signlen, reason); } RsPgpId p3Peers::pgpIdFromFingerprint(const RsPgpFingerprint& fpr) @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthGPG::getGPGDetails(pgp_id, d); + bool res = AuthPGP::getGPGDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -739,12 +739,12 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() with : id : " << id << "; gpg_id : " << gpg_id << std::endl; #endif - if(AuthGPG::isPGPId(gpg_id)) + if(AuthPGP::isPGPId(gpg_id)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorising GPG Id: " << gpg_id << std::endl; #endif - if (AuthGPG::AllowConnection(gpg_id, true)) + if (AuthPGP::AllowConnection(gpg_id, true)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorization OK." << std::endl; @@ -797,7 +797,7 @@ bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,con bool p3Peers::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { - return AuthGPG::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return AuthPGP::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } bool p3Peers::removeFriendLocation(const RsPeerId &sslId) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthGPG::getGPGOwnId()) { + if (gpgId == AuthPGP::getGPGOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } @@ -825,7 +825,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() Removing GPG Id: " << gpgId << std::endl; #endif - if (AuthGPG::AllowConnection(gpgId, false)) + if (AuthPGP::AllowConnection(gpgId, false)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() OK." << std::endl; @@ -1107,7 +1107,7 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if( !AuthGPG::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) + if( !AuthPGP::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) { RsErr() << __PRETTY_FUNCTION__ << " Failure retriving certificate for id " << pgp_id @@ -1138,7 +1138,7 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) + if(!AuthPGP::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) return false; RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false); @@ -1598,7 +1598,7 @@ std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInvit unsigned char *mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) + if(!AuthPGP::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) { std::cerr << "Cannot output certificate for id \"" << detail.gpg_id << "\". Sorry." << std::endl; @@ -1634,7 +1634,7 @@ bool p3Peers::loadCertificateFromString( } RsPgpId gpgid; - bool res = AuthGPG::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); + bool res = AuthPGP::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); gpg_id = gpgid; ssl_id = crt->sslid(); @@ -1651,7 +1651,7 @@ bool p3Peers::loadCertificateFromString( } bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) { - bool res = AuthGPG::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); + bool res = AuthPGP::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); if(res) mPeerMgr->notifyPgpKeyReceived(gpg_id); @@ -1670,7 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthGPG::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthPGP::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " @@ -1748,7 +1748,7 @@ bool p3Peers::signGPGCertificate(const RsPgpId &id, const std::string &gpg_pass rsNotify->cachePgpPassphrase(gpg_passphrase); rsNotify->setDisableAskPassword(true); - bool res = AuthGPG::SignCertificateLevel0(id); + bool res = AuthPGP::SignCertificateLevel0(id); rsNotify->clearPgpPassphrase(); rsNotify->setDisableAskPassword(false); @@ -1762,7 +1762,7 @@ bool p3Peers::trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) std::cerr << "p3Peers::TrustCertificate() " << id; std::cerr << std::endl; #endif - return AuthGPG::TrustCertificate(id, trustlvl); + return AuthPGP::TrustCertificate(id, trustlvl); } /* Group Stuff */ diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 7abb1e6da..2aa859fe1 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthGPG::getGPGOwnName(); + status.ownName = AuthPGP::getGPGOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 2bf306449..83867b943 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -701,10 +701,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, if(! RsAccounts::GetPGPLoginDetails(account.mPgpId, account.mPgpName, account.mPgpEmail)) return false ; - if(!AuthGPG::haveSecretKey(account.mPgpId)) + if(!AuthPGP::haveSecretKey(account.mPgpId)) return false ; - if(!AuthGPG::isKeySupported(account.mPgpId)) + if(!AuthPGP::isKeySupported(account.mPgpId)) { std::string keystring = account.mPgpId.toStdString() + " " + account.mPgpName + "<" + account.mPgpEmail ; unsupported_keys[keystring].push_back("Location: " + account.mLocation + "  (" + account.mSslId.toStdString() + ")") ; @@ -853,7 +853,7 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) { - AuthGPG::availableGPGCertificatesWithPrivateKeys(pgpIds); + AuthPGP::availableGPGCertificatesWithPrivateKeys(pgpIds); return 1; } @@ -864,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthGPG::getGPGName(id,&ok); + name = AuthPGP::getGPGName(id,&ok); if(!ok) return 0 ; - email = AuthGPG::getGPGEmail(id,&ok); + email = AuthPGP::getGPGEmail(id,&ok); if(!ok) return 0 ; @@ -887,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthGPG::GPGInit(pgpId)) + if (0 < AuthPGP::GPGInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -907,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthGPG::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthPGP::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. @@ -919,24 +919,24 @@ void RsAccountsDetail::getUnsupportedKeys(std::mapOwnId(), - AuthGPG::getGPGOwnId(), - AuthGPG::getGPGOwnName(), + AuthPGP::getGPGOwnId(), + AuthPGP::getGPGOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); @@ -1604,7 +1604,7 @@ int RsServer::StartupRetroShare() //mConfigMgr->addConfiguration("ftserver.cfg", ftserver); // - AuthGPG::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); + AuthPGP::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); mConfigMgr->addConfiguration("gxsnettunnel.cfg", mGxsNetTunnel); mConfigMgr->addConfiguration("peers.cfg" , mPeerMgr); diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc index 67b863931..a0834b0af 100644 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ b/libretroshare/src/rsserver/rsloginhandler.cc @@ -60,7 +60,7 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile( return true ; } - bool ok = AuthGPG::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); + bool ok = AuthPGP::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); if (!ok) std::cerr << "Encrypting went wrong !" << std::endl; @@ -89,7 +89,7 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& #endif std::string plain; - if ( AuthGPG::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) + if ( AuthPGP::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) { sslPassword = plain; #ifdef DEBUG_RSLOGINHANDLER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 981c246c4..49bfc36dc 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthGPG::getGPGOwnId(); + ssdata.pgp.pgpId = AuthPGP::getGPGOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } @@ -3619,7 +3619,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup( unsigned int sign_size = MAX_SIGN_SIZE; memset(signarray,0,MAX_SIGN_SIZE) ; // just in case. - int result = AuthGPG::SignDataBin( + int result = AuthPGP::SignDataBin( static_cast(hash.toByteArray()), hash.SIZE_IN_BYTES, signarray, &sign_size, __PRETTY_FUNCTION__ ) From 5e37bd42e4e9a7717f6a0b92bc86c76aaa1fd647 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 18:57:58 +0200 Subject: [PATCH 186/697] renamed isGPGAccepted into isPGPAccepted --- libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 8 ++------ libretroshare/src/pqi/authgpg.h | 2 -- libretroshare/src/pqi/authssl.cc | 2 +- libretroshare/src/pqi/p3peermgr.cc | 6 +++--- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 2 +- 8 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index ad95f7ee3..3f4290dd4 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthPGP::isGPGAccepted(pgpId))) + if (!(AuthPGP::isPGPAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -1062,7 +1062,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isPGPAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 5e93823a4..1d0481112 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -405,10 +405,6 @@ bool AuthPGP::isPGPId(const RsPgpId& id) { return instance()->mPgpHandler->isGPGId(id); } -bool AuthPGP::isPGPAccepted(const RsPgpId& id) -{ - return instance()->mPgpHandler->isGPGAccepted(id); -} /**** These Two are common */ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) { @@ -714,7 +710,7 @@ int AuthPGP::privateTrustCertificate(const RsPgpId& id, int trustlvl) // The trust level is only a user-defined property that has nothing to // do with the fact that we allow connections or not. - if(!isGPGAccepted(id)) + if(!isPGPAccepted(id)) return 0; int res = instance()->mPgpHandler->privateTrustCertificate(id,trustlvl) ; @@ -732,7 +728,7 @@ RsSerialiser *AuthPGP::setupSerialiser() rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } -bool AuthPGP::isGPGAccepted(const RsPgpId& id) +bool AuthPGP::isPGPAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index d124efdd4..6081600b5 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -155,8 +155,6 @@ public: static const RsPgpId& getGPGOwnId(); static std::string getGPGOwnName(); - static bool isGPGAccepted(const RsPgpId& id); - //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 47eea9e58..75dcf2fe3 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index bf91b72d9..f56f73180 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index c579280bc..8986a9a19 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 58dae7e44..48c0b79c2 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -569,7 +569,7 @@ std::string p3Peers::getGPGName(const RsPgpId &gpg_id) } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthPGP::isGPGAccepted(pgpId); } +{ return AuthPGP::isPGPAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { From fdac22f49cc72d443b96214e8c19f8cb17a24eaf Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 19:02:09 +0200 Subject: [PATCH 187/697] renamed remaining *GPG* names into *PGP* --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 8 +++---- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 16 +++++++------- libretroshare/src/pqi/authgpg.h | 14 ++++++------ libretroshare/src/pqi/authssl.cc | 8 +++---- libretroshare/src/pqi/p3peermgr.cc | 12 +++++----- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 22 +++++++++---------- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsinit.cc | 4 ++-- libretroshare/src/services/p3idservice.cc | 2 +- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 3f4290dd4..b14efb550 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthPGP::getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getPGPOwnId()] = DiscPgpInfo(); } @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); - AuthPGP::getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); + AuthPGP::getPGPAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -1058,7 +1058,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); + RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index 99d3e8880..a95424973 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -59,7 +59,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthPGP::getGPGAllList(ids); + return AuthPGP::getPGPAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 1d0481112..371cebe0d 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -425,18 +425,18 @@ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthPGP::getGPGOwnId() +const RsPgpId& AuthPGP::getPGPOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthPGP::getGPGOwnName() +std::string AuthPGP::getPGPOwnName() { return getGPGName(instance()->mOwnGpgId) ; } -bool AuthPGP::getGPGAllList(std::list &ids) +bool AuthPGP::getPGPAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -470,7 +470,7 @@ bool AuthPGP::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthPGP::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getPGPDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -510,17 +510,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthPGP::getGPGValidList(std::list &ids) +bool AuthPGP::getPGPValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthPGP::getGPGAcceptedList(std::list &ids) +bool AuthPGP::getPGPAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthPGP::getGPGSignedList(std::list &ids) +bool AuthPGP::getPGPSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -739,7 +739,7 @@ bool AuthPGP::saveList(bool& cleanup, std::list& lst) std::cerr << "AuthGPG::saveList() called" << std::endl ; #endif std::list ids ; - getGPGAcceptedList(ids) ; // needs to be done before the lock + getPGPAcceptedList(ids) ; // needs to be done before the lock RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 6081600b5..a94d0161f 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -152,19 +152,19 @@ public: static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); /* PGP web of trust management */ - static const RsPgpId& getGPGOwnId(); - static std::string getGPGOwnName(); + static const RsPgpId& getPGPOwnId(); + static std::string getPGPOwnName(); //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); static bool haveSecretKey(const RsPgpId &id) ; - static bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); - static bool getGPGAllList(std::list &ids); - static bool getGPGValidList(std::list &ids); - static bool getGPGAcceptedList(std::list &ids); - static bool getGPGSignedList(std::list &ids); + static bool getPGPDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getPGPAllList(std::list &ids); + static bool getPGPValidList(std::list &ids); + static bool getPGPAcceptedList(std::list &ids); + static bool getPGPSignedList(std::list &ids); static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 75dcf2fe3..cfded5951 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPGPOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPGPOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthPGP::getGPGDetails(issuer, pd)) + if (!AuthPGP::getPGPDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthPGP::getGPGAcceptedList(gpgIds); + AuthPGP::getPGPAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthPGP::getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getPGPOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getGPGOwnId()) + if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPGPOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthPGP::getGPGOwnId(); + mOwnState.gpg_id = AuthPGP::getPGPOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPGPOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPGPOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index f56f73180..75ed02faa 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 8986a9a19..9cf2d4aef 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 48c0b79c2..931b75aa6 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthPGP::getGPGOwnId(); + ps.gpg_id = AuthPGP::getPGPOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthPGP::getGPGOwnName(); + return AuthPGP::getPGPOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGAllList(ids); + AuthPGP::getPGPAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGValidList(ids); + AuthPGP::getPGPValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGSignedList(ids); + AuthPGP::getPGPSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthPGP::getGPGAcceptedList(ids)) + if(AuthPGP::getPGPAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthPGP::getGPGAcceptedList(ids); + AuthPGP::getPGPAcceptedList(ids); return true; } @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthPGP::getGPGDetails(pgp_id, d); + bool res = AuthPGP::getPGPDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthPGP::getGPGOwnId()) { + if (gpgId == AuthPGP::getPGPOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 2aa859fe1..ae48ebb16 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthPGP::getGPGOwnName(); + status.ownName = AuthPGP::getPGPOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index eb2b07790..d4d87ba60 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthPGP::getGPGOwnId(), - AuthPGP::getGPGOwnName(), + AuthPGP::getPGPOwnId(), + AuthPGP::getPGPOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 49bfc36dc..bffdaccde 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthPGP::getGPGOwnId(); + ssdata.pgp.pgpId = AuthPGP::getPGPOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } From 7672ffa0ecd9d2ab9ad573ae3ab19ec66976eca0 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 19:05:54 +0200 Subject: [PATCH 188/697] fixed casing of PGP into Pgp --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 8 +++---- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 22 ++++++++--------- libretroshare/src/pqi/authgpg.h | 18 +++++++------- libretroshare/src/pqi/authssl.cc | 8 +++---- libretroshare/src/pqi/p3peermgr.cc | 14 +++++------ libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 24 +++++++++---------- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 4 ++-- libretroshare/src/rsserver/rsinit.cc | 4 ++-- libretroshare/src/services/p3idservice.cc | 2 +- 13 files changed, 57 insertions(+), 57 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index b14efb550..30e71763a 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthPGP::getPGPOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getPgpOwnId()] = DiscPgpInfo(); } @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); - AuthPGP::getPGPAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getPgpOwnId(); + AuthPGP::getPgpAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -1058,7 +1058,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); + RsPgpId ownPgpId = AuthPGP::getPgpOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index a95424973..377e5261d 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -59,7 +59,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthPGP::getPGPAllList(ids); + return AuthPGP::getPgpAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 371cebe0d..9cbcade21 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -373,7 +373,7 @@ bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::stri } /**** These Two are common */ -std::string AuthPGP::getGPGName(const RsPgpId& id,bool *success) +std::string AuthPGP::getPgpName(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -406,7 +406,7 @@ bool AuthPGP::isPGPId(const RsPgpId& id) return instance()->mPgpHandler->isGPGId(id); } /**** These Two are common */ -std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) +std::string AuthPGP::getPgpEmail(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -425,18 +425,18 @@ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthPGP::getPGPOwnId() +const RsPgpId& AuthPGP::getPgpOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthPGP::getPGPOwnName() +std::string AuthPGP::getPgpOwnName() { - return getGPGName(instance()->mOwnGpgId) ; + return getPgpName(instance()->mOwnGpgId) ; } -bool AuthPGP::getPGPAllList(std::list &ids) +bool AuthPGP::getPgpAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -470,7 +470,7 @@ bool AuthPGP::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthPGP::getPGPDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getPgpDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -510,17 +510,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthPGP::getPGPValidList(std::list &ids) +bool AuthPGP::getPgpValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthPGP::getPGPAcceptedList(std::list &ids) +bool AuthPGP::getPgpAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthPGP::getPGPSignedList(std::list &ids) +bool AuthPGP::getPgpSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -739,7 +739,7 @@ bool AuthPGP::saveList(bool& cleanup, std::list& lst) std::cerr << "AuthGPG::saveList() called" << std::endl ; #endif std::list ids ; - getPGPAcceptedList(ids) ; // needs to be done before the lock + getPgpAcceptedList(ids) ; // needs to be done before the lock RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index a94d0161f..5a8839b67 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -146,25 +146,25 @@ public: * provide access to details in cache list. * ****/ - static std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); - static std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getPgpName(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getPgpEmail(const RsPgpId &pgp_id,bool *success = NULL); static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); /* PGP web of trust management */ - static const RsPgpId& getPGPOwnId(); - static std::string getPGPOwnName(); + static const RsPgpId& getPgpOwnId(); + static std::string getPgpOwnName(); //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); static bool haveSecretKey(const RsPgpId &id) ; - static bool getPGPDetails(const RsPgpId& id, RsPeerDetails &d); - static bool getPGPAllList(std::list &ids); - static bool getPGPValidList(std::list &ids); - static bool getPGPAcceptedList(std::list &ids); - static bool getPGPSignedList(std::list &ids); + static bool getPgpDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getPgpAllList(std::list &ids); + static bool getPgpValidList(std::list &ids); + static bool getPgpAcceptedList(std::list &ids); + static bool getPgpSignedList(std::list &ids); static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index cfded5951..9d70121a3 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPGPOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPgpOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPGPOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPgpOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthPGP::getPGPDetails(issuer, pd)) + if (!AuthPGP::getPgpDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthPGP::getPGPAcceptedList(gpgIds); + AuthPGP::getPgpAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthPGP::getPGPOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getPgpOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPGPOwnId()) + if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPgpOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthPGP::getGPGName(gpg_id); + pstate.name = AuthPGP::getPgpName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthPGP::getPGPOwnId(); + mOwnState.gpg_id = AuthPGP::getPgpOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPGPOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPgpOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPGPOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPgpOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 75ed02faa..60be4ae7b 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPgpOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 9cf2d4aef..ad2129928 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPgpOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 931b75aa6..50d4dc3dc 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthPGP::getPGPOwnId(); + ps.gpg_id = AuthPGP::getPgpOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -565,7 +565,7 @@ bool p3Peers::isKeySupported(const RsPgpId& id) std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthPGP::getGPGName(gpg_id); + return AuthPGP::getPgpName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthPGP::getPGPOwnName(); + return AuthPGP::getPgpOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPAllList(ids); + AuthPGP::getPgpAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPValidList(ids); + AuthPGP::getPgpValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPSignedList(ids); + AuthPGP::getPgpSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthPGP::getPGPAcceptedList(ids)) + if(AuthPGP::getPgpAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthPGP::getPGPAcceptedList(ids); + AuthPGP::getPgpAcceptedList(ids); return true; } @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthPGP::getPGPDetails(pgp_id, d); + bool res = AuthPGP::getPgpDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthPGP::getPGPOwnId()) { + if (gpgId == AuthPGP::getPgpOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index ae48ebb16..c50eb2c89 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthPGP::getPGPOwnName(); + status.ownName = AuthPGP::getPgpOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 83867b943..737254f73 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -864,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthPGP::getGPGName(id,&ok); + name = AuthPGP::getPgpName(id,&ok); if(!ok) return 0 ; - email = AuthPGP::getGPGEmail(id,&ok); + email = AuthPGP::getPgpEmail(id,&ok); if(!ok) return 0 ; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index d4d87ba60..2dc034f56 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthPGP::getPGPOwnId(), - AuthPGP::getPGPOwnName(), + AuthPGP::getPgpOwnId(), + AuthPGP::getPgpOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index bffdaccde..b89c963b6 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthPGP::getPGPOwnId(); + ssdata.pgp.pgpId = AuthPGP::getPgpOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } From 7821b29893cf58a7246b9c6c90d9d5647878db3a Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 20:29:18 +0200 Subject: [PATCH 189/697] fixed additional GPG->Pgp names --- libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc | 2 +- libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- libretroshare/src/gxs/rsgxsnetutils.cc | 4 ++-- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pgp/pgpauxutils.h | 8 ++++---- libretroshare/src/pqi/authgpg.cc | 8 ++++---- libretroshare/src/pqi/authgpg.h | 8 ++++---- libretroshare/src/rsserver/p3peers.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 6 +++--- libretroshare/src/rsserver/rsinit.cc | 2 +- libretroshare/src/services/p3idservice.cc | 4 ++-- .../libretroshare/gxs/nxs_test/nxsdummyservices.cc | 4 ++-- .../libretroshare/gxs/nxs_test/nxsdummyservices.h | 4 ++-- .../libretroshare/services/gxs/FakePgpAuxUtils.cc | 8 ++++---- .../libretroshare/services/gxs/FakePgpAuxUtils.h | 4 ++-- 15 files changed, 35 insertions(+), 35 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 30e71763a..948fa3ccc 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthPGP::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthPGP::getPgpDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e1b70a670..6e61c72c4 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4688,7 +4688,7 @@ bool RsGxsNetService::checkPermissionsForFriendGroup(const RsPeerId& sslId,const if(!grpMeta.mInternalCircle.isNull()) { RsGroupInfo ginfo ; - RsPgpId pgpId = mPgpUtils->getPGPId(sslId) ; + RsPgpId pgpId = mPgpUtils->getPgpId(sslId) ; #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Group internal circle: " << grpMeta.mInternalCircle << ", We're owner. Sending to everyone in the group." << std::endl; diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index b74abcb0f..6d759da7e 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -223,7 +223,7 @@ bool GrpCircleVetting::canSend( { if(mCircles->isLoaded(circleId)) { - const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); + const RsPgpId& pgpId = mPgpUtils->getPgpId(peerId); return mCircles->canSend(circleId, pgpId,should_encrypt); } @@ -302,7 +302,7 @@ bool MsgCircleIdsRequestVetting::cleared() if(filtered_out_msgs>0) std::cerr << "(WW) " << filtered_out_msgs << " messages not sent because they are signed by author(s) not member of that circle " << mCircleId << std::endl; - RsPgpId pgpId = mPgpUtils->getPGPId(mPeerId); + RsPgpId pgpId = mPgpUtils->getPgpId(mPeerId); bool can_send_res = mCircles->canSend(mCircleId, pgpId,mShouldEncrypt); if(mShouldEncrypt) // that means the circle is external diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index 377e5261d..c87985fab 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -37,7 +37,7 @@ const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() return AuthPGP::getPgpOwnId(); } -RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) +RsPgpId PgpAuxUtilsImpl::getPgpId(const RsPeerId& sslid) { return rsPeers->getGPGId(sslid); } @@ -57,7 +57,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, return AuthPGP::VerifySignBin(data, len, sign, signlen, withfingerprint); } -bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) +bool PgpAuxUtilsImpl::getPgpAllList(std::list &ids) { return AuthPGP::getPgpAllList(ids); } diff --git a/libretroshare/src/pgp/pgpauxutils.h b/libretroshare/src/pgp/pgpauxutils.h index 4b188e3ae..aa897c0e1 100644 --- a/libretroshare/src/pgp/pgpauxutils.h +++ b/libretroshare/src/pgp/pgpauxutils.h @@ -35,8 +35,8 @@ class PgpAuxUtils virtual ~PgpAuxUtils(){} virtual const RsPgpId &getPGPOwnId() = 0; - virtual RsPgpId getPGPId(const RsPeerId& sslid) = 0; - virtual bool getGPGAllList(std::list &ids) = 0; + virtual RsPgpId getPgpId(const RsPeerId& sslid) = 0; + virtual bool getPgpAllList(std::list &ids) = 0; virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const = 0; virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0; @@ -49,12 +49,12 @@ public: PgpAuxUtilsImpl(); virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); + virtual RsPgpId getPgpId(const RsPeerId& sslid); virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const ; virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint); - virtual bool getGPGAllList(std::list &ids); + virtual bool getPgpAllList(std::list &ids); }; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 9cbcade21..f7a6fb6c3 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -54,11 +54,11 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ -int AuthPGP::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +int AuthPGP::availablePgpCertificatesWithPrivateKeys(std::list& pgpIds) { return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); } -bool AuthPGP::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +bool AuthPGP::getPgpDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) { return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); } @@ -178,7 +178,7 @@ AuthPGP::AuthPGP(const std::string& path_to_public_keyring,const std::string& pa * This function must be called successfully (return == 1) * before anything else can be done. (except above fn). */ -int AuthPGP::GPGInit(const RsPgpId &ownId) +int AuthPGP::PgpInit(const RsPgpId &ownId) { #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; @@ -365,7 +365,7 @@ bool AuthPGP::active() return instance()->gpgKeySelected; } -bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) +bool AuthPGP::GeneratePgpCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 5a8839b67..1db1ad482 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -129,11 +129,11 @@ public: /* Init by generating new Own PGP Cert, or selecting existing PGP Cert */ - static int GPGInit(const RsPgpId &ownId); - static bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); + static int PgpInit(const RsPgpId &ownId); + static bool GeneratePgpCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - static bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; - static int availableGPGCertificatesWithPrivateKeys(std::list& pgpIds); + static bool getPgpDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; + static int availablePgpCertificatesWithPrivateKeys(std::list& pgpIds); /*********************************************************************************/ /************************* STAGE 3 ***********************************************/ diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 50d4dc3dc..ff50ec091 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1670,7 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthPGP::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthPGP::getPgpDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 737254f73..32ecd1e2a 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -853,7 +853,7 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) { - AuthPGP::availableGPGCertificatesWithPrivateKeys(pgpIds); + AuthPGP::availablePgpCertificatesWithPrivateKeys(pgpIds); return 1; } @@ -887,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthPGP::GPGInit(pgpId)) + if (0 < AuthPGP::PgpInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -907,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthPGP::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthPGP::GeneratePgpCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 2dc034f56..84d2b659b 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -510,7 +510,7 @@ RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates( if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location)) throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - if(0 == AuthPGP::GPGInit(pgpId)) + if(0 == AuthPGP::PgpInit(pgpId)) throw RsInit::ERR_UNKNOWN; // PGP Error. LoadCertificateStatus retVal = diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b89c963b6..bf034bcb2 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -4096,7 +4096,7 @@ void p3IdService::getPgpIdList() #endif // DEBUG_IDS std::list list; - mPgpUtils->getGPGAllList(list); + mPgpUtils->getPgpAllList(list); RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -4593,7 +4593,7 @@ void p3IdService::generateDummy_FriendPGP() // Now Generate for friends. std::list gpgids; std::list::const_iterator it; - mPgpUtils->getGPGAllList(gpgids); + mPgpUtils->getPgpAllList(gpgids); RsGxsIdGroup id; diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc index 925e90be2..442a25cc1 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc @@ -134,11 +134,11 @@ const RsPgpId& rs_nxs_test::RsDummyPgpUtils::getPGPOwnId() { return mOwnId; } -RsPgpId rs_nxs_test::RsDummyPgpUtils::getPGPId(const RsPeerId& /*sslid*/) { +RsPgpId rs_nxs_test::RsDummyPgpUtils::getPgpId(const RsPeerId& /*sslid*/) { return RsPgpId().random(); } -bool rs_nxs_test::RsDummyPgpUtils::getGPGAllList(std::list& /*ids*/) { +bool rs_nxs_test::RsDummyPgpUtils::getPgpAllList(std::list& /*ids*/) { return true; } diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h index aee8f989e..6e993a658 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h @@ -164,8 +164,8 @@ namespace rs_nxs_test virtual ~RsDummyPgpUtils(){} const RsPgpId &getPGPOwnId() ; - RsPgpId getPGPId(const RsPeerId& sslid) ; - bool getGPGAllList(std::list &ids) ; + RsPgpId getPgpId(const RsPeerId& sslid) ; + bool getPgpAllList(std::list &ids) ; bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc index 2d274897a..49e440e5e 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc @@ -24,7 +24,7 @@ FakePgpAuxUtils::FakePgpAuxUtils(const RsPeerId& ownId) { - mOwnId = getPGPId(ownId); + mOwnId = getPgpId(ownId); addPeerIdToPgpList(ownId); } @@ -39,7 +39,7 @@ void FakePgpAuxUtils::addPeerListToPgpList(const std::list &ids) void FakePgpAuxUtils::addPeerIdToPgpList(const RsPeerId &id) { - RsPgpId pgpId = getPGPId(id); + RsPgpId pgpId = getPgpId(id); if (mPgpList.end() == std::find(mPgpList.begin(), mPgpList.end(), pgpId)) { mPgpList.push_back(pgpId); @@ -51,7 +51,7 @@ const RsPgpId & FakePgpAuxUtils::getPGPOwnId() return mOwnId; } -RsPgpId FakePgpAuxUtils::getPGPId(const RsPeerId& sslid) +RsPgpId FakePgpAuxUtils::getPgpId(const RsPeerId& sslid) { /* convert an sslId */ std::string idstring = sslid.toStdString(); @@ -95,7 +95,7 @@ bool FakePgpAuxUtils::VerifySignBin(const void* /*data*/, uint32_t /*len*/, unsi return true; } -bool FakePgpAuxUtils::getGPGAllList(std::list &ids) +bool FakePgpAuxUtils::getPgpAllList(std::list &ids) { ids = mPgpList; return true; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h index 63b20b85d..f866164a6 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h @@ -28,7 +28,7 @@ public: FakePgpAuxUtils(const RsPeerId& ownId); virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); + virtual RsPgpId getPgpId(const RsPeerId& sslid); virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; @@ -36,7 +36,7 @@ public: virtual void addPeerListToPgpList(const std::list &ids); virtual void addPeerIdToPgpList(const RsPeerId &id); - virtual bool getGPGAllList(std::list &ids); + virtual bool getPgpAllList(std::list &ids); private: RsPgpId mOwnId; std::list mPgpList; From d948086b5eedfa622bb7761d1741e77be7e095ca Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 21:44:30 +0200 Subject: [PATCH 190/697] added logic to stop/start FriendServer from GUI --- libretroshare/src/friend_server/fsmanager.cc | 44 +++++++++++++++++++ libretroshare/src/friend_server/fsmanager.h | 41 +++++++++++++++++ libretroshare/src/retroshare/rsfriendserver.h | 4 +- libretroshare/src/rsserver/rsinit.cc | 4 ++ .../src/retroshare-friendserver.cc | 20 ++++----- .../src/gui/FriendServerControl.cpp | 7 ++- retroshare-gui/src/gui/FriendServerControl.ui | 2 +- 7 files changed, 105 insertions(+), 17 deletions(-) diff --git a/libretroshare/src/friend_server/fsmanager.cc b/libretroshare/src/friend_server/fsmanager.cc index e69de29bb..7abaca3d4 100644 --- a/libretroshare/src/friend_server/fsmanager.cc +++ b/libretroshare/src/friend_server/fsmanager.cc @@ -0,0 +1,44 @@ +#include "fsmanager.h" + +RsFriendServer *rsFriendServer = nullptr; + +void FriendServerManager::startServer() +{ + if(!isRunning()) + { + std::cerr << "Starting Friend Server Manager." << std::endl; + RsTickingThread::start() ; + } +} +void FriendServerManager::stopServer() +{ + if(isRunning() && !shouldStop()) + { + std::cerr << "Stopping Friend Server Manager." << std::endl; + RsTickingThread::askForStop() ; + } +} +void FriendServerManager::checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) +{ +#warning TODO + std::this_thread::sleep_for(std::chrono::seconds(1)); + + callback(addr,true); +} + +void FriendServerManager::setServerAddress(const std::string& addr,uint16_t port) +{ + mServerAddress = addr; + mServerPort = port; +} + +void FriendServerManager::setFriendsToRequest(uint32_t n) +{ + mFriendsToRequest = n; +} + +void FriendServerManager::threadTick() +{ + std::cerr << "Ticking FriendServerManager..." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(2)); +} diff --git a/libretroshare/src/friend_server/fsmanager.h b/libretroshare/src/friend_server/fsmanager.h index e69de29bb..df98173c6 100644 --- a/libretroshare/src/friend_server/fsmanager.h +++ b/libretroshare/src/friend_server/fsmanager.h @@ -0,0 +1,41 @@ +#include + +#include "util/rsthreads.h" +#include "retroshare/rsfriendserver.h" +#include "retroshare/rspeers.h" + +struct FriendServerPeerInfo +{ + enum FriendServerPeerStatus: uint8_t + { + UNKNOWN = 0x00, + LOCALLY_ACCEPTED = 0x01, + HAS_ACCEPTED_ME = 0x02, + ALREADY_CONNECTED = 0x03 + }; + + uint32_t status ; +}; + +class FriendServerManager: public RsFriendServer, public RsTickingThread +{ +public: + virtual void startServer() override ; + virtual void stopServer() override ; + + virtual void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) override ; + virtual void setServerAddress(const std::string&,uint16_t) override ; + virtual void setFriendsToRequest(uint32_t) override ; + +protected: + virtual void threadTick() override; + +private: + uint32_t mFriendsToRequest; + + // encode the current list of friends obtained through the friendserver and their status + + std::map mPeers; + std::string mServerAddress ; + uint16_t mServerPort; +}; diff --git a/libretroshare/src/retroshare/rsfriendserver.h b/libretroshare/src/retroshare/rsfriendserver.h index 9ce4b25ef..c8fa446b0 100644 --- a/libretroshare/src/retroshare/rsfriendserver.h +++ b/libretroshare/src/retroshare/rsfriendserver.h @@ -23,8 +23,8 @@ class RsFriendServer { public: - virtual void start() =0; - virtual void stop() =0; + virtual void startServer() =0; + virtual void stopServer() =0; virtual void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) =0; virtual void setServerAddress(const std::string&,uint16_t) =0; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..ebfad8fa5 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -48,6 +48,7 @@ #include "retroshare/rsversion.h" #include "rsserver/rsloginhandler.h" #include "rsserver/rsaccounts.h" +#include "friend_server/fsmanager.h" #include #include @@ -1170,6 +1171,9 @@ int RsServer::StartupRetroShare() serviceCtrl->setServiceServer(pqih) ; + // setup friend server + rsFriendServer = new FriendServerManager(); + /****** New Ft Server **** !!! */ ftServer *ftserver = new ftServer(mPeerMgr, serviceCtrl); ftserver->setConfigDirectory(RsAccounts::AccountDirectory()); diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc index c93c59609..4c5bfc61c 100644 --- a/retroshare-friendserver/src/retroshare-friendserver.cc +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -61,16 +61,16 @@ int main(int argc, char* argv[]) { std::this_thread::sleep_for(std::chrono::seconds(2)); - // send one request for testing to see what happens - - RsFriendServerClientPublishItem *item = new RsFriendServerClientPublishItem(); - item->long_invite = std::string("[Long Invite]"); - item->n_requested_friends = 10; - - std::cerr << "Sending fake request item for testing..." << std::endl; - FsClient(std::string("127.0.0.1")).sendItem(item); - - std::this_thread::sleep_for(std::chrono::seconds(4)); +// // send one request for testing to see what happens +// +// RsFriendServerClientPublishItem *item = new RsFriendServerClientPublishItem(); +// item->long_invite = std::string("[Long Invite]"); +// item->n_requested_friends = 10; +// +// std::cerr << "Sending fake request item for testing..." << std::endl; +// FsClient(std::string("127.0.0.1")).sendItem(item); +// +// std::this_thread::sleep_for(std::chrono::seconds(4)); } return 0; } diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp index 82a7df829..fdfd5be3d 100644 --- a/retroshare-gui/src/gui/FriendServerControl.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -31,8 +31,6 @@ #include -RsFriendServer *rsFriendServer = new RsFriendServer; - #define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" #define ICON_STATUS_OK ":/images/ledon1.png" @@ -44,6 +42,7 @@ FriendServerControl::FriendServerControl(QWidget *parent) mConnectionCheckTimer = new QTimer; + QObject::connect(friendServerOnOff_CB,SIGNAL(toggled(bool)),this,SLOT(onOnOffClick(bool))); QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress())); QObject::connect(torServerAddress_LE,SIGNAL(textChanged(const QString&)),this,SLOT(onOnionAddressEdit(const QString&))); @@ -62,9 +61,9 @@ FriendServerControl::~FriendServerControl() void FriendServerControl::onOnOffClick(bool b) { if(b) - rsFriendServer->start(); + rsFriendServer->startServer(); else - rsFriendServer->stop(); + rsFriendServer->stopServer(); } void FriendServerControl::onOnionAddressEdit(const QString&) diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui index 681399c15..b1c5bec40 100644 --- a/retroshare-gui/src/gui/FriendServerControl.ui +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -12,7 +12,7 @@ - + On/Off From ffa28000e37fbaadc5638f12f10260e8645f79e5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 30 Oct 2021 15:50:28 +0200 Subject: [PATCH 191/697] added basic communication between FriendServer and its clients --- libretroshare/src/friend_server/fsclient.cc | 53 +++++++++++++-- libretroshare/src/friend_server/fsclient.h | 6 +- libretroshare/src/friend_server/fsmanager.cc | 66 +++++++++++++++++++ libretroshare/src/friend_server/fsmanager.h | 7 ++ libretroshare/src/retroshare/rsfriendserver.h | 4 ++ .../src/gui/FriendServerControl.cpp | 33 +++++++++- retroshare-gui/src/gui/FriendServerControl.h | 3 +- retroshare-gui/src/gui/FriendServerControl.ui | 5 +- 8 files changed, 165 insertions(+), 12 deletions(-) diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index c332aee24..2f486122f 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -21,19 +21,60 @@ ******************************************************************************/ #include "pqi/pqithreadstreamer.h" +#include "retroshare/rspeers.h" #include "fsclient.h" #include "fsbio.h" -FsClient::FsClient(const std::string& address) - : mServerAddress(address) +bool FsClient::requestFriends(const std::string& address,uint16_t port,uint32_t reqs,std::map& friend_certificates) { + // send our own certificate to publish and expects response frmo the server , decrypts it and reutnrs friend list + + RsFriendServerClientPublishItem *pitem = new RsFriendServerClientPublishItem(); + + pitem->n_requested_friends = reqs; + pitem->long_invite = rsPeers->GetRetroshareInvite(); + + std::list response; + + sendItem(address,port,pitem,response); + + // now decode the response + + friend_certificates.clear(); + + for(auto item:response) + { + auto *encrypted_response_item = dynamic_cast(item); + + if(!encrypted_response_item) + { + delete item; + continue; + } + + // For now, also handle unencrypted response items. Will be disabled in production + + auto *response_item = dynamic_cast(item); + + if(!response_item) + { + delete item; + continue; + } + + for(const auto& it:response_item->friend_invites) + friend_certificates.insert(it); + } + return friend_certificates.size(); } -bool FsClient::sendItem(RsItem *item) +bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,std::list& response) { // open a connection + RsDbg() << "Sending item to friend server at \"" << address << ":" << port ; + int CreateSocket = 0,n = 0; char dataReceived[1024]; struct sockaddr_in ipOfServer; @@ -47,8 +88,8 @@ bool FsClient::sendItem(RsItem *item) } ipOfServer.sin_family = AF_INET; - ipOfServer.sin_port = htons(2017); - ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1"); + ipOfServer.sin_port = htons(port); + ipOfServer.sin_addr.s_addr = inet_addr(address.c_str()); if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) { @@ -89,7 +130,7 @@ bool FsClient::sendItem(RsItem *item) if(!item) { - rstime::rs_usleep(1000*200); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); continue; } diff --git a/libretroshare/src/friend_server/fsclient.h b/libretroshare/src/friend_server/fsclient.h index c29a10671..76af44a43 100644 --- a/libretroshare/src/friend_server/fsclient.h +++ b/libretroshare/src/friend_server/fsclient.h @@ -28,11 +28,11 @@ class FsClient { public: - FsClient(const std::string& address); + FsClient() {} - bool sendItem(RsItem *item); + bool requestFriends(const std::string& address,uint16_t port,uint32_t reqs,std::map& friend_certificates); private: - std::string mServerAddress; + bool sendItem(const std::string &address, uint16_t port, RsItem *item, std::list &response); }; diff --git a/libretroshare/src/friend_server/fsmanager.cc b/libretroshare/src/friend_server/fsmanager.cc index 7abaca3d4..ca520bb4f 100644 --- a/libretroshare/src/friend_server/fsmanager.cc +++ b/libretroshare/src/friend_server/fsmanager.cc @@ -1,7 +1,24 @@ +#include #include "fsmanager.h" +#include "fsclient.h" RsFriendServer *rsFriendServer = nullptr; +static const rstime_t MIN_DELAY_BETWEEN_FS_REQUESTS = 30; +static const rstime_t MAX_DELAY_BETWEEN_FS_REQUESTS = 3600; +static const uint32_t DEFAULT_FRIENDS_TO_REQUEST = 10; + +static const std::string DEFAULT_FRIEND_SERVER_ADDRESS = "127.0.0.1"; +static const uint16_t DEFAULT_FRIEND_SERVER_PORT = 2017; + +FriendServerManager::FriendServerManager() +{ + mLastFriendReqestCampain = 0; + mFriendsToRequest = DEFAULT_FRIENDS_TO_REQUEST; + + mServerAddress = DEFAULT_FRIEND_SERVER_ADDRESS; + mServerPort = DEFAULT_FRIEND_SERVER_PORT; +} void FriendServerManager::startServer() { if(!isRunning()) @@ -41,4 +58,53 @@ void FriendServerManager::threadTick() { std::cerr << "Ticking FriendServerManager..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(2)); + + // Check for requests. Compute how much to wait based on how many friends we have already + + std::vector friends; + rsPeers->getPgpFriendList(friends); + + // log-scale interpolation of the delay between two requests. + + if(mFriendsToRequest == 0 || mFriendsToRequest < friends.size()) + { + RsErr() << "No friends to request! This is unexpected. Returning." << std::endl; + return; + } + + // This formula makes RS wait much longuer between two requests to the server when the number of friends is close the + // wanted number + // Delay for 0 friends: 30 secs. + // Delay for 1 friends: 30 secs. + // Delay for 2 friends: 32 secs. + // Delay for 3 friends: 35 secs. + // Delay for 4 friends: 44 secs. + // Delay for 5 friends: 66 secs. + // Delay for 6 friends: 121 secs. + // Delay for 7 friends: 258 secs. + // Delay for 8 friends: 603 secs. + // Delay for 9 friends: 1466 secs. + + RsDbg() << friends.size() << " friends already, " << mFriendsToRequest << " friends to request"; + + double s = (friends.size() < mFriendsToRequest)? ( (mFriendsToRequest - friends.size())/(double)mFriendsToRequest) : 1.0; + rstime_t delay_for_request = MIN_DELAY_BETWEEN_FS_REQUESTS + (int)floor(exp(-1*s + log(MAX_DELAY_BETWEEN_FS_REQUESTS)*(1.0-s))); + + std::cerr << "Delay for " << friends.size() << " friends: " << delay_for_request << " secs." << std::endl; + + rstime_t now = time(nullptr); + + if(mLastFriendReqestCampain + delay_for_request < now) + { + std::cerr << "Requesting new friends to friend server..." << std::endl; + + std::map friend_certificates; + FsClient().requestFriends(mServerAddress,mServerPort,mFriendsToRequest,friend_certificates); // blocking call + + std::cerr << "Got the following list of friend certificates:" << std::endl; + + for(const auto& it:friend_certificates) + std::cerr << it.first << " : " << it.second << std::endl; + } } + diff --git a/libretroshare/src/friend_server/fsmanager.h b/libretroshare/src/friend_server/fsmanager.h index df98173c6..ef5887afa 100644 --- a/libretroshare/src/friend_server/fsmanager.h +++ b/libretroshare/src/friend_server/fsmanager.h @@ -15,11 +15,14 @@ struct FriendServerPeerInfo }; uint32_t status ; + rstime_t received_TS; }; class FriendServerManager: public RsFriendServer, public RsTickingThread { public: + FriendServerManager(); + virtual void startServer() override ; virtual void stopServer() override ; @@ -27,11 +30,15 @@ public: virtual void setServerAddress(const std::string&,uint16_t) override ; virtual void setFriendsToRequest(uint32_t) override ; + virtual uint32_t friendsToRequest() override { return mFriendsToRequest ; } + virtual uint16_t friendsServerPort() override { return mServerPort ; } + virtual std::string friendsServerAddress() override { return mServerAddress ; } protected: virtual void threadTick() override; private: uint32_t mFriendsToRequest; + rstime_t mLastFriendReqestCampain; // encode the current list of friends obtained through the friendserver and their status diff --git a/libretroshare/src/retroshare/rsfriendserver.h b/libretroshare/src/retroshare/rsfriendserver.h index c8fa446b0..df9951cee 100644 --- a/libretroshare/src/retroshare/rsfriendserver.h +++ b/libretroshare/src/retroshare/rsfriendserver.h @@ -29,6 +29,10 @@ public: virtual void checkServerAddress_async(const std::string& addr,uint16_t, const std::function& callback) =0; virtual void setServerAddress(const std::string&,uint16_t) =0; virtual void setFriendsToRequest(uint32_t) =0; + + virtual uint32_t friendsToRequest() =0; + virtual uint16_t friendsServerPort() =0; + virtual std::string friendsServerAddress() =0; }; extern RsFriendServer *rsFriendServer; diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp index fdfd5be3d..50c98217d 100644 --- a/retroshare-gui/src/gui/FriendServerControl.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -40,12 +40,28 @@ FriendServerControl::FriendServerControl(QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ setupUi(this); + if(!rsFriendServer) + { + setEnabled(false); + return; + } + mConnectionCheckTimer = new QTimer; + // init values + + torServerFriendsToRequest_SB->setValue(rsFriendServer->friendsToRequest()); + torServerAddress_LE->setText(QString::fromStdString(rsFriendServer->friendsServerAddress().c_str())); + torServerPort_SB->setValue(rsFriendServer->friendsServerPort()); + + // connect slignals/slots + QObject::connect(friendServerOnOff_CB,SIGNAL(toggled(bool)),this,SLOT(onOnOffClick(bool))); - QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress())); + QObject::connect(torServerFriendsToRequest_SB,SIGNAL(valueChanged(int)),this,SLOT(onFriendsToRequestChanged(int))); QObject::connect(torServerAddress_LE,SIGNAL(textChanged(const QString&)),this,SLOT(onOnionAddressEdit(const QString&))); + QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress())); + mCheckingServerMovie = new QMovie(":/images/loader/circleball-16.gif"); serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); @@ -65,6 +81,21 @@ void FriendServerControl::onOnOffClick(bool b) else rsFriendServer->stopServer(); } +void FriendServerControl::onOnionPortEdit(int) +{ + // Setup timer to auto-check the friend server address + + mConnectionCheckTimer->setSingleShot(true); + mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time. + + mConnectionCheckTimer->start(); + + if(mCheckingServerMovie->fileName() != QString(":/images/loader/circleball-16.gif" )) + { + mCheckingServerMovie->setFileName(":/images/loader/circleball-16.gif"); + mCheckingServerMovie->start(); + } +} void FriendServerControl::onOnionAddressEdit(const QString&) { diff --git a/retroshare-gui/src/gui/FriendServerControl.h b/retroshare-gui/src/gui/FriendServerControl.h index 76cbb5b28..d453d37bc 100644 --- a/retroshare-gui/src/gui/FriendServerControl.h +++ b/retroshare-gui/src/gui/FriendServerControl.h @@ -35,10 +35,11 @@ public: protected slots: void onOnOffClick(bool b); void onOnionAddressEdit(const QString&); + void onOnionPortEdit(int); void onNbFriendsToRequestsChanged(int n); - void checkServerAddress(); private: + void checkServerAddress(); void updateFriendServerStatusIcon(bool ok); QTimer *mConnectionCheckTimer; diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui index b1c5bec40..d00ae32e0 100644 --- a/retroshare-gui/src/gui/FriendServerControl.ui +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -72,6 +72,9 @@ 0 + + 127.0.0.1 + @@ -108,7 +111,7 @@ 65536 - 1729 + 2017
From d659f768b5a9c42d39e8315bc57f57a8e16c42bc Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 31 Oct 2021 12:01:07 +0100 Subject: [PATCH 192/697] fixed debug output in pqistreamer --- libretroshare/src/pqi/pqistreamer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/pqi/pqistreamer.cc b/libretroshare/src/pqi/pqistreamer.cc index db38bfde2..96b91dae6 100644 --- a/libretroshare/src/pqi/pqistreamer.cc +++ b/libretroshare/src/pqi/pqistreamer.cc @@ -683,7 +683,7 @@ int pqistreamer::handleoutgoing_locked() outSentBytes_locked(mPkt_wpending_size); // this is the only time where we know exactly what was sent. #ifdef DEBUG_TRANSFERS - std::cerr << "pqistreamer::handleoutgoing_locked() Sent Packet len: " << mPkt_wpending_size << " @ " << RsUtil::AccurateTimeString(); + std::cerr << "pqistreamer::handleoutgoing_locked() Sent Packet len: " << mPkt_wpending_size << " @ " << getCurrentTS(); std::cerr << std::endl; #endif @@ -693,7 +693,7 @@ int pqistreamer::handleoutgoing_locked() mPkt_wpending = NULL; mPkt_wpending_size = 0 ; - sent = true; + sent = true; } } #ifdef DEBUG_PQISTREAMER From f0b23b84f169777328b798b8bcb15b86b6e5733b Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 31 Oct 2021 12:01:44 +0100 Subject: [PATCH 193/697] added missing override in pqithreadstreamer --- libretroshare/src/pqi/pqithreadstreamer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/pqi/pqithreadstreamer.h b/libretroshare/src/pqi/pqithreadstreamer.h index 7ba1690c8..5b6fa3763 100644 --- a/libretroshare/src/pqi/pqithreadstreamer.h +++ b/libretroshare/src/pqi/pqithreadstreamer.h @@ -31,8 +31,8 @@ public: pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin); // from pqistreamer - virtual bool RecvItem(RsItem *item); - virtual int tick(); + virtual bool RecvItem(RsItem *item) override; + virtual int tick() override; protected: void threadTick() override; /// @see RsTickingThread From 42b4a821bd1aaf5465bf477bc4321121877f30d4 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 31 Oct 2021 12:02:09 +0100 Subject: [PATCH 194/697] fixed basic incoming communication at server side --- libretroshare/src/friend_server/fsbio.cc | 18 ++-- libretroshare/src/friend_server/fsbio.h | 1 + libretroshare/src/friend_server/fsclient.cc | 20 +++- retroshare-friendserver/src/friendserver.cc | 10 +- retroshare-friendserver/src/network.cc | 107 ++++++++++++++++++-- retroshare-friendserver/src/network.h | 19 +++- 6 files changed, 148 insertions(+), 27 deletions(-) diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc index 517738225..ecff610ea 100644 --- a/libretroshare/src/friend_server/fsbio.cc +++ b/libretroshare/src/friend_server/fsbio.cc @@ -24,7 +24,7 @@ #include "fsbio.h" FsBioInterface::FsBioInterface(int socket) - : mCLintConnt(socket) + : mCLintConnt(socket),mIsActive(true) { mTotalReadBytes=0; mTotalBufferBytes=0; @@ -43,21 +43,22 @@ int FsBioInterface::tick() if(readbytes == 0) { - std::cerr << "Reached END of the stream!" << std::endl; - return 0; + RsDbg() << "Reached END of the stream!" << std::endl; + RsDbg() << "Closing!" << std::endl; + + mIsActive = false; + return mTotalBufferBytes; } if(readbytes < 0) { if(errno != EWOULDBLOCK && errno != EAGAIN) RsErr() << "read() failed. Errno=" << errno ; - return false; + return mTotalBufferBytes; } std::cerr << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes << std::endl; - //::close(clintConnt); - // display some debug info if(readbytes > 0) @@ -79,7 +80,7 @@ int FsBioInterface::tick() std::cerr << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalBufferBytes << std::endl ; } - return true; + return mTotalBufferBytes; } int FsBioInterface::readdata(void *data, int len) @@ -134,7 +135,7 @@ int FsBioInterface::senddata(void *data, int len) } int FsBioInterface::netstatus() { - return 1; // dummy response. + return mIsActive; // dummy response. } int FsBioInterface::isactive() @@ -154,6 +155,7 @@ bool FsBioInterface::cansend(uint32_t) int FsBioInterface::close() { RsDbg() << "Stopping network interface" << std::endl; + mIsActive = false; return 1; } diff --git a/libretroshare/src/friend_server/fsbio.h b/libretroshare/src/friend_server/fsbio.h index 446ad29f8..6b2ed06bd 100644 --- a/libretroshare/src/friend_server/fsbio.h +++ b/libretroshare/src/friend_server/fsbio.h @@ -51,6 +51,7 @@ public: private: int mCLintConnt; + bool mIsActive; uint32_t mTotalReadBytes; uint32_t mTotalBufferBytes; diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index 2f486122f..377055505 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -117,7 +117,7 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st // TODO: we should write in multiple chunks just in case the socket is not fully ready write(CreateSocket,data,size); - // Now attempt to read and deserialize anything that comes back from that connexion + // Now attempt to read and deserialize anything that comes back from that connexion until it gets closed by the server. FsBioInterface bio(CreateSocket); pqistreamer pqi(&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); @@ -128,14 +128,26 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st { RsItem *item = p.GetItem(); - if(!item) + if(item) + { + response.push_back(item); + std::cerr << "Got a response item: " << std::endl; + std::cerr << *item << std::endl; + } + else { std::this_thread::sleep_for(std::chrono::milliseconds(200)); continue; } - std::cerr << "Got a response item: " << std::endl; - std::cerr << *item << std::endl; + if(!bio.isactive()) // socket has probably closed + { + RsDbg() << "(client side) Socket has been closed by server. Killing pqistreamer and closing socket." ; + p.fullstop(); + + close(CreateSocket); + CreateSocket=0; + } } return 0; diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index fa4591955..32d3ea8a2 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -37,7 +37,15 @@ void FriendServer::threadTick() void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *item) { - RsDbg() << "Received a client publish item:" << *item ; + RsDbg() << "Received a client publish item from " << item->PeerId() << ":" << *item ; + + // Respond with a list of potential friends + + // Close client connection from server side, to tell the client that nothing more is coming. + + RsDbg() << "Closing client connection." ; + + mni->closeConnection(item->PeerId()); } void FriendServer::handleClientRemove(const RsFriendServerClientRemoveItem *item) { diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index 5f697e9b0..33c26c297 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -41,12 +41,11 @@ #include "friend_server/fsitem.h" FsNetworkInterface::FsNetworkInterface() - : mFsNiMtx(std::string("FsNetworkInterface")) + : PQInterface(RsPeerId()),mFsNiMtx(std::string("FsNetworkInterface")) { RS_STACK_MUTEX(mFsNiMtx); mClintListn = 0; - mClintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket int flags = fcntl(mClintListn, F_GETFL); @@ -76,9 +75,10 @@ FsNetworkInterface::FsNetworkInterface() FsNetworkInterface::~FsNetworkInterface() { + RS_STACK_MUTEX(mFsNiMtx); for(auto& it:mConnections) { - delete it.second.pqi; + delete it.second.pqi_thread; std::cerr << "Releasing socket " << it.second.socket << std::endl; close(it.second.socket); } @@ -93,8 +93,11 @@ void FsNetworkInterface::threadTick() // 2 - tick all streamers + RS_STACK_MUTEX(mFsNiMtx); for(auto& it:mConnections) - it.second.pqi->tick(); + { + it.second.pqi_thread->tick(); + } rstime::rs_usleep(1000*200); } @@ -102,6 +105,8 @@ void FsNetworkInterface::threadTick() static RsPeerId makePeerId(int t) { unsigned char s[RsPeerId::SIZE_IN_BYTES]; + memset(s,0,sizeof(s)); + *reinterpret_cast(&s) = t; return RsPeerId::fromBufferUnsafe(s); } @@ -145,28 +150,110 @@ bool FsNetworkInterface::checkForNewConnections() FsBioInterface *bio = new FsBioInterface(clintConnt); - auto p = new pqistreamer(rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); - auto pqi = new pqithreadstreamer(p,rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); - c.pqi = pqi; + auto pqi = new pqithreadstreamer(this,rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); + + c.pqi_thread = pqi; + c.bio = bio; pqi->start(); RS_STACK_MUTEX(mFsNiMtx); - mConnections[makePeerId(clintConnt)] = c; + mConnections[pid] = c; return true; } +bool FsNetworkInterface::RecvItem(RsItem *item) +{ + RS_STACK_MUTEX(mFsNiMtx); + + auto it = mConnections.find(item->PeerId()); + + if(it == mConnections.end()) + { + RsErr() << "Receiving an item for peer ID " << item->PeerId() << " but no connection is known for that peer." << std::endl; + delete item; + return false; + } + + it->second.incoming_items.push_back(item); + return true; +} + RsItem *FsNetworkInterface::GetItem() { RS_STACK_MUTEX(mFsNiMtx); for(auto& it:mConnections) { - RsItem *item = it.second.pqi->GetItem(); - if(item) + if(!it.second.incoming_items.empty()) + { + RsItem *item = it.second.incoming_items.front(); + it.second.incoming_items.pop_front(); + return item; + } } return nullptr; } +int FsNetworkInterface::SendItem(RsItem *item) +{ + RS_STACK_MUTEX(mFsNiMtx); + + const auto& it = mConnections.find(item->PeerId()); + + if(it == mConnections.end()) + { + RsErr() << "Cannot send item to peer " << item->PeerId() << ": no pending sockets available." ; + delete item; + return 0; + } + + return it->second.pqi_thread->SendItem(item); +} + +void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) +{ + const auto& it = mConnections.find(peer_id); + + if(it == mConnections.end()) + { + RsErr() << "Cannot close connection to peer " << peer_id << ": no pending sockets available." ; + return; + } + + if(!it->second.incoming_items.empty()) + { + RsErr() << "Trying to close an incoming connection with incoming items still pending! The items will be lost." << std::endl; + + for(auto& item:it->second.incoming_items) + delete item; + + it->second.incoming_items.clear(); + } + // Close the socket and delete everything. + + it->second.pqi_thread->fullstop(); + it->second.bio->close(); + + close(it->second.socket); + + delete it->second.pqi_thread; + delete it->second.bio; +} + + + + + + + + + + + + + + + diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index e842ec77c..5729b515c 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -22,20 +22,25 @@ #pragma once #include "util/rsthreads.h" +#include "pqi/pqi_base.h" #include "retroshare/rspeers.h" -class pqistreamer; +class pqithreadstreamer; +class FsBioInterface; struct ConnectionData { sockaddr client_address; int socket; - pqistreamer *pqi; + pqithreadstreamer *pqi_thread; + FsBioInterface *bio; + + std::list incoming_items; }; // This class handles multiple connections to the server and supplies RsItem elements -class FsNetworkInterface: public RsTickingThread +class FsNetworkInterface: public RsTickingThread, public PQInterface { public: FsNetworkInterface() ; @@ -43,7 +48,13 @@ public: // basic functionality - RsItem *GetItem(); + void closeConnection(const RsPeerId& peer_id); + + // Implements PQInterface + + bool RecvItem(RsItem *item) override; + int SendItem(RsItem *item) override; + RsItem *GetItem() override; // Implements RsTickingThread From a69f9dc09b73d138851d4f0b720b76bb25956e9f Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 31 Oct 2021 16:46:06 +0100 Subject: [PATCH 195/697] fixed two-ways communication between RS and friend server --- libretroshare/src/friend_server/fsbio.cc | 8 ++-- libretroshare/src/friend_server/fsclient.cc | 42 ++++++++++++++------ libretroshare/src/friend_server/fsclient.h | 14 ++++++- libretroshare/src/friend_server/fsmanager.cc | 2 + retroshare-friendserver/src/network.cc | 5 ++- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc index ecff610ea..8d6933a76 100644 --- a/libretroshare/src/friend_server/fsbio.cc +++ b/libretroshare/src/friend_server/fsbio.cc @@ -43,10 +43,10 @@ int FsBioInterface::tick() if(readbytes == 0) { - RsDbg() << "Reached END of the stream!" << std::endl; - RsDbg() << "Closing!" << std::endl; + RsDbg() << "Reached END of the stream!" ; + RsDbg() << "Closing!" ; - mIsActive = false; + close(); return mTotalBufferBytes; } if(readbytes < 0) @@ -140,7 +140,7 @@ int FsBioInterface::netstatus() int FsBioInterface::isactive() { - return mCLintConnt > 0; + return mIsActive ; } bool FsBioInterface::moretoread(uint32_t /* usec */) diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index 377055505..9b2459b7c 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -113,20 +113,24 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st rss.addSerialType(fss); FsSerializer().serialise(item,data,&size); + write(CreateSocket,data,size); // shouldn't we use the pqistreamer in R/W mode instead? - // TODO: we should write in multiple chunks just in case the socket is not fully ready - write(CreateSocket,data,size); + RsDbg() << "Item sent. Waiting for response..." ; // Now attempt to read and deserialize anything that comes back from that connexion until it gets closed by the server. FsBioInterface bio(CreateSocket); - pqistreamer pqi(&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); - pqithreadstreamer p(&pqi,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE); + pqithreadstreamer p(this,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE | BIN_FLAGS_NO_DELETE); p.start(); + uint32_t ss; + p.SendItem(item,ss); + while(true) { - RsItem *item = p.GetItem(); + p.tick(); + + RsItem *item = GetItem(); if(item) { @@ -134,11 +138,6 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st std::cerr << "Got a response item: " << std::endl; std::cerr << *item << std::endl; } - else - { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - continue; - } if(!bio.isactive()) // socket has probably closed { @@ -147,11 +146,28 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st close(CreateSocket); CreateSocket=0; + break; } + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } - return 0; - - // if ok, stream the item through it + return true; } +bool FsClient::RecvItem(RsItem *item) +{ + mIncomingItems.push_back(item); + return true; +} + +RsItem *FsClient::GetItem() +{ + if(mIncomingItems.empty()) + return nullptr; + + RsItem *item = mIncomingItems.front(); + mIncomingItems.pop_front(); + + return item; +} diff --git a/libretroshare/src/friend_server/fsclient.h b/libretroshare/src/friend_server/fsclient.h index 76af44a43..a14fc82ef 100644 --- a/libretroshare/src/friend_server/fsclient.h +++ b/libretroshare/src/friend_server/fsclient.h @@ -22,17 +22,27 @@ #include #include "fsitem.h" +#include "pqi/pqi_base.h" // This class runs a client connection to the friend server. It opens a socket at each connection. -class FsClient +class FsClient: public PQInterface { public: - FsClient() {} + FsClient() :PQInterface(RsPeerId()) {} bool requestFriends(const std::string& address,uint16_t port,uint32_t reqs,std::map& friend_certificates); +protected: + // Implements PQInterface + + bool RecvItem(RsItem *item) override; + int SendItem(RsItem *) override { RsErr() << "FsClient::SendItem() called although it should not." ; return 0;} + RsItem *GetItem() override; + private: bool sendItem(const std::string &address, uint16_t port, RsItem *item, std::list &response); + + std::list mIncomingItems; }; diff --git a/libretroshare/src/friend_server/fsmanager.cc b/libretroshare/src/friend_server/fsmanager.cc index ca520bb4f..876ae8170 100644 --- a/libretroshare/src/friend_server/fsmanager.cc +++ b/libretroshare/src/friend_server/fsmanager.cc @@ -96,6 +96,8 @@ void FriendServerManager::threadTick() if(mLastFriendReqestCampain + delay_for_request < now) { + mLastFriendReqestCampain = now; + std::cerr << "Requesting new friends to friend server..." << std::endl; std::map friend_certificates; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index 33c26c297..18ef4c7fa 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -215,6 +215,8 @@ int FsNetworkInterface::SendItem(RsItem *item) void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) { + RS_STACK_MUTEX(mFsNiMtx); + const auto& it = mConnections.find(peer_id); if(it == mConnections.end()) @@ -240,7 +242,8 @@ void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) close(it->second.socket); delete it->second.pqi_thread; - delete it->second.bio; + + mConnections.erase(it); } From e058b3a35fb02c1a91df37bf171b8840c2e86981 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 31 Oct 2021 18:00:43 +0100 Subject: [PATCH 196/697] fixed memory error --- libretroshare/src/friend_server/fsclient.cc | 17 ++++-- libretroshare/src/friend_server/fsmanager.cc | 4 +- retroshare-friendserver/src/friendserver.cc | 57 +++++++++++++++++++ retroshare-friendserver/src/friendserver.h | 17 ++++++ retroshare-friendserver/src/network.cc | 10 ++++ retroshare-friendserver/src/network.h | 1 + .../src/retroshare-friendserver.cc | 12 ---- 7 files changed, 98 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index 9b2459b7c..b5f385d65 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -109,8 +109,8 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st } FsSerializer *fss = new FsSerializer; - RsSerialiser rss; - rss.addSerialType(fss); + RsSerialiser *rss = new RsSerialiser(); // deleted by ~pqistreamer() + rss->addSerialType(fss); FsSerializer().serialise(item,data,&size); write(CreateSocket,data,size); // shouldn't we use the pqistreamer in R/W mode instead? @@ -119,8 +119,9 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st // Now attempt to read and deserialize anything that comes back from that connexion until it gets closed by the server. - FsBioInterface bio(CreateSocket); - pqithreadstreamer p(this,&rss,RsPeerId(),&bio,BIN_FLAGS_READABLE | BIN_FLAGS_NO_DELETE); + FsBioInterface *bio = new FsBioInterface(CreateSocket); // deleted by ~pqistreamer() + + pqithreadstreamer p(this,rss,RsPeerId(),bio,BIN_FLAGS_READABLE | BIN_FLAGS_NO_DELETE | BIN_FLAGS_NO_CLOSE); p.start(); uint32_t ss; @@ -139,13 +140,17 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st std::cerr << *item << std::endl; } - if(!bio.isactive()) // socket has probably closed + if(!bio->isactive()) // socket has probably closed { - RsDbg() << "(client side) Socket has been closed by server. Killing pqistreamer and closing socket." ; + RsDbg() << "(client side) Socket has been closed by server."; + RsDbg() << " Stopping/killing pqistreamer" ; p.fullstop(); + RsDbg() << " Closing socket." ; close(CreateSocket); CreateSocket=0; + + RsDbg() << " Exiting loop." ; break; } diff --git a/libretroshare/src/friend_server/fsmanager.cc b/libretroshare/src/friend_server/fsmanager.cc index 876ae8170..199bb99d7 100644 --- a/libretroshare/src/friend_server/fsmanager.cc +++ b/libretroshare/src/friend_server/fsmanager.cc @@ -4,9 +4,9 @@ RsFriendServer *rsFriendServer = nullptr; -static const rstime_t MIN_DELAY_BETWEEN_FS_REQUESTS = 30; +static const rstime_t MIN_DELAY_BETWEEN_FS_REQUESTS = 30; static const rstime_t MAX_DELAY_BETWEEN_FS_REQUESTS = 3600; -static const uint32_t DEFAULT_FRIENDS_TO_REQUEST = 10; +static const uint32_t DEFAULT_FRIENDS_TO_REQUEST = 10; static const std::string DEFAULT_FRIEND_SERVER_ADDRESS = "127.0.0.1"; static const uint16_t DEFAULT_FRIEND_SERVER_PORT = 2017; diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 32d3ea8a2..7464129f8 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -3,6 +3,10 @@ #include "friendserver.h" #include "friend_server/fsitem.h" +static const rstime_t MAXIMUM_PEER_INACTIVE_DELAY = 600; +static const rstime_t DELAY_BETWEEN_TWO_AUTOWASH = 60; +static const rstime_t DELAY_BETWEEN_TWO_DEBUG_PRINT = 10; + void FriendServer::threadTick() { // Listen to the network interface, capture incoming data etc. @@ -33,6 +37,23 @@ void FriendServer::threadTick() } delete item; } + + static rstime_t last_autowash_TS = time(nullptr); + rstime_t now = time(nullptr); + + if(last_autowash_TS + DELAY_BETWEEN_TWO_AUTOWASH < now) + { + last_autowash_TS = now; + autoWash(); + } + + static rstime_t last_debugprint_TS = time(nullptr); + + if(last_debugprint_TS + DELAY_BETWEEN_TWO_DEBUG_PRINT < now) + { + last_debugprint_TS = now; + debugPrint(); + } } void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *item) @@ -67,3 +88,39 @@ void FriendServer::run() while(!shouldStop()) { threadTick() ; } } +void FriendServer::autoWash() +{ + rstime_t now = time(nullptr); + + for(std::map::iterator it(mCurrentClientPeers.begin());it!=mCurrentClientPeers.end();) + { + if(it->second.last_connection_TS + MAXIMUM_PEER_INACTIVE_DELAY < now) + { + RsDbg() << "Removing client peer " << it->first << " because it's inactive for more than " << MAXIMUM_PEER_INACTIVE_DELAY << " seconds." ; + auto tmp = it; + ++tmp; + mCurrentClientPeers.erase(it); + it = tmp; + } + } +} + +void FriendServer::debugPrint() +{ + RsDbg() << "========== FriendServer statistics ============"; + RsDbg() << " Base directory: "<< mBaseDirectory; + RsDbg() << " Network interface: "; + RsDbg() << " Current peers: " << mCurrentClientPeers.size() ; + + rstime_t now = time(nullptr); + + for(auto& it:mCurrentClientPeers) + RsDbg() << " " << it.first << ": " << "last contact: " << now - it.second.last_connection_TS; + + RsDbg() << "==============================================="; + +} + + + + diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 83e7eaaa7..51917cb5a 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -29,19 +29,36 @@ class RsFriendServerClientRemoveItem; class RsFriendServerClientPublishItem; +struct PeerInfo +{ + std::string short_certificate; + rstime_t last_connection_TS; +}; + class FriendServer : public RsTickingThread { public: FriendServer(const std::string& base_directory); private: + // overloads RsTickingThread + virtual void threadTick() override; virtual void run() override; + // Own algorithmics + void handleClientRemove(const RsFriendServerClientRemoveItem *item); void handleClientPublish(const RsFriendServerClientPublishItem *item); + void autoWash(); + void debugPrint(); + + // Local members + FsNetworkInterface *mni; std::string mBaseDirectory; + + std::map mCurrentClientPeers; }; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index 18ef4c7fa..243981717 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -246,6 +246,16 @@ void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) mConnections.erase(it); } +void FsNetworkInterface::debugPrint() +{ + RsDbg() << " " << mClintListn ; // listening socket + RsDbg() << " Connections: " << mConnections.size() ; + + for(auto& it:mConnections) + RsDbg() << " " << it.first << ": from \"" << sockaddr_storage_tostring(*(sockaddr_storage*)(&it.second.client_address)) << "\", socket=" << it.second.socket ; + + std::map mConnections; +} diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h index 5729b515c..b92c60a2e 100644 --- a/retroshare-friendserver/src/network.h +++ b/retroshare-friendserver/src/network.h @@ -49,6 +49,7 @@ public: // basic functionality void closeConnection(const RsPeerId& peer_id); + void debugPrint(); // Implements PQInterface diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc index 4c5bfc61c..585d400a9 100644 --- a/retroshare-friendserver/src/retroshare-friendserver.cc +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -58,20 +58,8 @@ int main(int argc, char* argv[]) fs.start(); while(fs.isRunning()) - { std::this_thread::sleep_for(std::chrono::seconds(2)); -// // send one request for testing to see what happens -// -// RsFriendServerClientPublishItem *item = new RsFriendServerClientPublishItem(); -// item->long_invite = std::string("[Long Invite]"); -// item->n_requested_friends = 10; -// -// std::cerr << "Sending fake request item for testing..." << std::endl; -// FsClient(std::string("127.0.0.1")).sendItem(item); -// -// std::this_thread::sleep_for(std::chrono::seconds(4)); - } return 0; } From 5da31592f2e0f4798fc0ef97719073a683aec135 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 1 Nov 2021 09:16:41 +0100 Subject: [PATCH 197/697] send/recv PGP public key and short invite --- libretroshare/src/friend_server/fsclient.cc | 14 +++- libretroshare/src/friend_server/fsitem.h | 10 ++- retroshare-friendserver/src/friendserver.cc | 78 ++++++++++++++++++- retroshare-friendserver/src/friendserver.h | 2 + .../src/retroshare-friendserver.cc | 12 ++- 5 files changed, 107 insertions(+), 9 deletions(-) diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index b5f385d65..5548168a2 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -33,10 +33,20 @@ bool FsClient::requestFriends(const std::string& address,uint16_t port,uint32_t RsFriendServerClientPublishItem *pitem = new RsFriendServerClientPublishItem(); pitem->n_requested_friends = reqs; - pitem->long_invite = rsPeers->GetRetroshareInvite(); + + std::string pgp_base64_string,pgp_base64_checksum,short_invite; + rsPeers->GetPGPBase64StringAndCheckSum(rsPeers->getGPGOwnId(),pgp_base64_string,pgp_base64_checksum); + + if(!rsPeers->getShortInvite(short_invite,RsPeerId(),RetroshareInviteFlags::RADIX_FORMAT | RetroshareInviteFlags::DNS)) + { + RsErr() << "Cannot request own short invite! Something's very wrong." ; + return false; + } + + pitem->pgp_public_key_b64 = pgp_base64_string; + pitem->short_invite = short_invite; std::list response; - sendItem(address,port,pitem,response); // now decode the response diff --git a/libretroshare/src/friend_server/fsitem.h b/libretroshare/src/friend_server/fsitem.h index 3ca7e50d5..e3990b19f 100644 --- a/libretroshare/src/friend_server/fsitem.h +++ b/libretroshare/src/friend_server/fsitem.h @@ -26,6 +26,7 @@ #include "serialiser/rsserializer.h" #include "rsitems/rsitem.h" +#include "serialiser/rstlvbinary.h" #include "rsitems/rsserviceids.h" #include "rsitems/itempriorities.h" @@ -53,18 +54,21 @@ public: void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override { RS_SERIAL_PROCESS(n_requested_friends); - RS_SERIAL_PROCESS(long_invite); + RS_SERIAL_PROCESS(short_invite); + RS_SERIAL_PROCESS(pgp_public_key_b64); } virtual void clear() override { - long_invite = std::string(); + pgp_public_key_b64.clear(); + short_invite.clear(); n_requested_friends=0; } // specific members for that item uint32_t n_requested_friends; - std::string long_invite; + std::string short_invite; + std::string pgp_public_key_b64; }; class RsFriendServerClientRemoveItem: public RsFriendServerItem diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 7464129f8..bc5e09d76 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -1,4 +1,8 @@ #include "util/rsdebug.h" +#include "util/rsprint.h" +#include "util/rsdir.h" +#include "util/rsbase64.h" +#include "util/radix64.h" #include "friendserver.h" #include "friend_server/fsitem.h" @@ -58,9 +62,68 @@ void FriendServer::threadTick() void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *item) { - RsDbg() << "Received a client publish item from " << item->PeerId() << ":" << *item ; + try + { + RsDbg() << "Received a client publish item from " << item->PeerId() ; + RsDbg() << *item ; - // Respond with a list of potential friends + // First of all, read PGP key and short invites, parse them, and check that they contain the same information + + RsDbg() << " Checking item data..."; + + std::string error_string; + RsPgpId pgp_id ; + std::vector key_binary_data ; + + key_binary_data = Radix64::decode(item->pgp_public_key_b64); + + if(key_binary_data.empty()) + throw std::runtime_error(" Cannot decode client pgp public key: \"" + item->pgp_public_key_b64 + "\". Wrong format??"); +// if(!RsBase64::decode(item->pgp_public_key_b64,key_binary_data)) +// throw std::runtime_error(" Cannot decode client pgp public key: \"" + item->pgp_public_key_b64 + "\". Wrong format??"); + + RsDbg() << " Public key radix is fine." ; + + if(!mPgpHandler->LoadCertificateFromBinaryData(key_binary_data.data(),key_binary_data.size(), pgp_id, error_string)) + throw std::runtime_error("Cannot load client's pgp public key into keyring: " + error_string) ; + + RsDbg() << " Public key added to keyring."; + + RsPeerDetails shortInviteDetails; + uint32_t errorCode = 0; + + if(item->short_invite.empty() || !rsPeers->parseShortInvite(item->short_invite, shortInviteDetails,errorCode )) + throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode)); + + RsDbg() << " Short invite is fine. PGP fingerprint: " << shortInviteDetails.fpr ; + + RsPgpFingerprint fpr_test; + if(!mPgpHandler->getKeyFingerprint(pgp_id,fpr_test)) + throw std::runtime_error("Cannot get fingerprint from keyring for client public key. Something's really wrong.") ; + + if(fpr_test != shortInviteDetails.fpr) + throw std::runtime_error("Cannot get fingerprint from keyring for client public key. Something's really wrong.") ; + + RsDbg() << " Short invite PGP fingerprint matches the public key fingerprint." ; + + // Check the item's data signature + + // All good. +#warning TODO + + // Store/update the peer info + + auto& pi(mCurrentClientPeers[shortInviteDetails.id]); + + pi.short_certificate = item->short_invite; + pi.last_connection_TS = time(nullptr); + + // Respond with a list of potential friends + } + catch(std::exception& e) + { + RsErr() << e.what() ; + } // Close client connection from server side, to tell the client that nothing more is coming. @@ -68,6 +131,7 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it mni->closeConnection(item->PeerId()); } + void FriendServer::handleClientRemove(const RsFriendServerClientRemoveItem *item) { RsDbg() << "Received a client remove item:" << *item ; @@ -76,6 +140,16 @@ FriendServer::FriendServer(const std::string& base_dir) { RsDbg() << "Creating friend server." ; mBaseDirectory = base_dir; + + // Create a PGP Handler + + std::string pgp_public_keyring_path = RsDirUtil::makePath(base_dir,"pgp_public_keyring") ; + std::string pgp_lock_path = RsDirUtil::makePath(base_dir,"pgp_lock") ; + + std::string pgp_private_keyring_path = RsDirUtil::makePath(base_dir,"pgp_private_keyring") ; // not used. + std::string pgp_trustdb_path = RsDirUtil::makePath(base_dir,"pgp_trustdb") ; // not used. + + mPgpHandler = new PGPHandler(pgp_public_keyring_path,pgp_private_keyring_path,pgp_trustdb_path,pgp_lock_path); } void FriendServer::run() diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 51917cb5a..49dd89359 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -23,6 +23,7 @@ #include "util/rsthreads.h" #include "pqi/pqistreamer.h" +#include "pgp/pgphandler.h" #include "network.h" @@ -57,6 +58,7 @@ private: // Local members FsNetworkInterface *mni; + PGPHandler *mPgpHandler; std::string mBaseDirectory; diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc index 585d400a9..d4327c668 100644 --- a/retroshare-friendserver/src/retroshare-friendserver.cc +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -20,6 +20,7 @@ */ #include "util/stacktrace.h" +#include "util/rsdir.h" #include "util/argstream.h" #include "util/rstime.h" #include "util/rsdebug.h" @@ -43,15 +44,22 @@ int main(int argc, char* argv[]) //RsInit::InitRsConfig(); //RsControl::earlyInitNotificationSystem(); - std::string base_directory; + std::string base_directory = "FSData"; argstream as(argc,argv); - as >> parameter( 'c',"base-dir", base_directory, "directory", "Set base directory.", false ) + as >> parameter( 'c',"base-dir", base_directory, "set base directory to store data files (keys, etc)", false ) >> help( 'h', "help", "Display this Help" ); as.defaultErrorHandling(true, true); + // Create the base directory if needed + + if(!RsDirUtil::checkCreateDirectory(base_directory)) + { + RsErr() << "Cannot create base directory \"" << base_directory << "\". Check permissions, paths, etc." ; + return 1; + } // Now start the real thing. FriendServer fs(base_directory); From b7c7c4c3f54bf5ef95277a6a499178dc76729454 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 1 Nov 2021 10:47:07 +0100 Subject: [PATCH 198/697] moved static/parsing of radix parts of short invites into RsCertificate (more code should be moved static there) and fixed adding incoming keys to friend server --- libretroshare/src/pgp/rscertificate.cc | 135 ++++++++++++++++ libretroshare/src/pgp/rscertificate.h | 17 ++ libretroshare/src/rsserver/p3peers.cc | 170 ++------------------ retroshare-friendserver/src/friendserver.cc | 4 +- 4 files changed, 171 insertions(+), 155 deletions(-) diff --git a/libretroshare/src/pgp/rscertificate.cc b/libretroshare/src/pgp/rscertificate.cc index f3007bb01..3f01b3d52 100644 --- a/libretroshare/src/pgp/rscertificate.cc +++ b/libretroshare/src/pgp/rscertificate.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "rscertificate.h" #include "util/rsstring.h" #include "util/stacktrace.h" @@ -621,6 +622,140 @@ bool RsCertificate::cleanRadix64(const std::string& instr,std::string& str,uint3 return true ; } +bool RsCertificate::decodeRadix64ShortInvite(const std::string& rsInvite, RsPeerDetails& details, uint32_t& err_code) +{ + err_code = 0; + std::vector bf = Radix64::decode(rsInvite); + size_t size = bf.size(); + + unsigned char* buf = bf.data(); + size_t total_s = 0; + bool CRC_ok = false ; // not checked yet + + while(total_s < size) + { + RsShortInviteFieldType ptag = RsShortInviteFieldType(buf[0]); + buf = &buf[1]; + + unsigned char *buf2 = buf; + uint32_t s = 0; + + try { s = PGPKeyParser::read_125Size(buf); } + catch (...) + { + err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; + return false; + } + + total_s += 1 + ( reinterpret_cast(buf) - reinterpret_cast(buf2) ); + + if(total_s > size) + { + err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; + return false; + } + + Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: " + << static_cast(ptag) + << ", size " << s << ", total_s = " << total_s + << ", expected total = " << size << std::endl; + + switch(ptag) + { + case RsShortInviteFieldType::SSL_ID: + details.id = RsPeerId::fromBufferUnsafe(buf) ; + break; + + case RsShortInviteFieldType::PEER_NAME: + details.name = std::string((char*)buf,s); + break; + + case RsShortInviteFieldType::PGP_FINGERPRINT: + details.fpr = RsPgpFingerprint::fromBufferUnsafe(buf); + details.gpg_id = PGPHandler::pgpIdFromFingerprint(details.fpr); + break; + + case RsShortInviteFieldType::LOCATOR: + { + std::string locatorStr((char*)buf,s); + details.ipAddressList.push_back(locatorStr); + } + break; + + case RsShortInviteFieldType::DNS_LOCATOR: + details.extPort = (((int)buf[0]) << 8) + buf[1]; + details.dyndns = std::string((char*)&buf[2],s-2); + break; + + case RsShortInviteFieldType::LOC4_LOCATOR: + { + uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; + sockaddr_in tLocalAddr; + tLocalAddr.sin_addr.s_addr = t4Addr; + + details.localAddr = rs_inet_ntoa(tLocalAddr.sin_addr); + details.localPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; + } + break; + + case RsShortInviteFieldType::EXT4_LOCATOR: + { + uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; + sockaddr_in tExtAddr; + tExtAddr.sin_addr.s_addr = t4Addr; + + details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr); + details.extPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; + } + break; + + case RsShortInviteFieldType::HIDDEN_LOCATOR: + details.hiddenType = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; + details.hiddenNodePort = (((uint32_t)buf[4]) << 8)+ (uint32_t)buf[5]; + details.isHiddenNode = true; + details.hiddenNodeAddress = std::string((char*)&buf[6],s-6); + break; + + case RsShortInviteFieldType::CHECKSUM: + { + if(s != 3 || total_s+3 != size) // make sure the checksum is the last section + { + err_code = CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION; + return false; + } + uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(bf.data(),size-5); + uint32_t certificate_crc = static_cast( buf[0] + (buf[1] << 8) + (buf[2] << 16) ); + + if(computed_crc != certificate_crc) + { + err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; + return false; + } + CRC_ok = true; + break; + } + + } + + buf = &buf[s]; + total_s += s; + } + + if(details.id.isNull()) + { + err_code = CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID; + return false; + } + if(!CRC_ok) + { + err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; + return false; + } + + return true; +} + + diff --git a/libretroshare/src/pgp/rscertificate.h b/libretroshare/src/pgp/rscertificate.h index 1ba3db633..17a7e4cb8 100644 --- a/libretroshare/src/pgp/rscertificate.h +++ b/libretroshare/src/pgp/rscertificate.h @@ -36,6 +36,21 @@ struct RsPeerDetails; class RsCertificate { public: + enum class RsShortInviteFieldType : uint8_t + { + SSL_ID = 0x00, + PEER_NAME = 0x01, + LOCATOR = 0x02, + PGP_FINGERPRINT = 0x03, + CHECKSUM = 0x04, + + /* The following will be deprecated, and ported to LOCATOR when generic transport layer will be implemented */ + HIDDEN_LOCATOR = 0x90, + DNS_LOCATOR = 0x91, + EXT4_LOCATOR = 0x92, // external IPv4 address + LOC4_LOCATOR = 0x93 // local IPv4 address + }; + typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format; /** @@ -64,6 +79,8 @@ public: ~RsCertificate(); + static bool decodeRadix64ShortInvite(const std::string& short_invite_b64,RsPeerDetails& det,uint32_t& error_code); + /// Convert to certificate radix string std::string toStdString() const; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index c44877fc5..eeed8aa3d 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -48,6 +48,7 @@ #include "pqi/authssl.h" +typedef RsCertificate::RsShortInviteFieldType RsShortInviteFieldType; // locally in this file to avoid renaming everything. RsPeers *rsPeers = NULL; @@ -1159,22 +1160,6 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( return true; } -enum class RsShortInviteFieldType : uint8_t -{ - SSL_ID = 0x00, - PEER_NAME = 0x01, - LOCATOR = 0x02, - PGP_FINGERPRINT = 0x03, - CHECKSUM = 0x04, - - /* The following will be deprecated, and ported to LOCATOR when generic - * trasport layer will be implemented */ - HIDDEN_LOCATOR = 0x90, - DNS_LOCATOR = 0x91, - EXT4_LOCATOR = 0x92, // external IPv4 address - LOC4_LOCATOR = 0x93 // local IPv4 address -}; - static void addPacketHeader(RsShortInviteFieldType ptag, size_t size, unsigned char *& buf, uint32_t& offset, uint32_t& buf_size) { // Check that the buffer has sufficient size. If not, increase it. @@ -1351,136 +1336,23 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& details, uint32_t &err_code ) { - if(inviteStrUrl.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite" - << std::endl; - return false; - } - std::string rsInvite = inviteStrUrl; + if(inviteStrUrl.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite" + << std::endl; + return false; + } + std::string rsInvite = inviteStrUrl; - RsUrl inviteUrl(inviteStrUrl); + RsUrl inviteUrl(inviteStrUrl); - if(inviteUrl.hasQueryK("rsInvite")) - rsInvite = *inviteUrl.getQueryV("rsInvite"); + if(inviteUrl.hasQueryK("rsInvite")) + rsInvite = *inviteUrl.getQueryV("rsInvite"); - std::vector bf = Radix64::decode(rsInvite); - size_t size = bf.size(); + if(!RsCertificate::decodeRadix64ShortInvite(rsInvite, details, err_code)) + return false; - unsigned char* buf = bf.data(); - size_t total_s = 0; - bool CRC_ok = false ; // not checked yet - - while(total_s < size) - { - RsShortInviteFieldType ptag = RsShortInviteFieldType(buf[0]); - buf = &buf[1]; - - unsigned char *buf2 = buf; - uint32_t s = 0; - - try { s = PGPKeyParser::read_125Size(buf); } - catch (...) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return false; - } - - total_s += 1 + ( reinterpret_cast(buf) - reinterpret_cast(buf2) ); - - if(total_s > size) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return false; - } - - Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: " - << static_cast(ptag) - << ", size " << s << ", total_s = " << total_s - << ", expected total = " << size << std::endl; - - switch(ptag) - { - case RsShortInviteFieldType::SSL_ID: - details.id = RsPeerId::fromBufferUnsafe(buf) ; - break; - - case RsShortInviteFieldType::PEER_NAME: - details.name = std::string((char*)buf,s); - break; - - case RsShortInviteFieldType::PGP_FINGERPRINT: - details.fpr = RsPgpFingerprint::fromBufferUnsafe(buf); - details.gpg_id = PGPHandler::pgpIdFromFingerprint(details.fpr); - break; - - case RsShortInviteFieldType::LOCATOR: - { - std::string locatorStr((char*)buf,s); - details.ipAddressList.push_back(locatorStr); - } - break; - - case RsShortInviteFieldType::DNS_LOCATOR: - details.extPort = (((int)buf[0]) << 8) + buf[1]; - details.dyndns = std::string((char*)&buf[2],s-2); - break; - - case RsShortInviteFieldType::LOC4_LOCATOR: - { - uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - sockaddr_in tLocalAddr; - tLocalAddr.sin_addr.s_addr = t4Addr; - - details.localAddr = rs_inet_ntoa(tLocalAddr.sin_addr); - details.localPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; - } - break; - - case RsShortInviteFieldType::EXT4_LOCATOR: - { - uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - sockaddr_in tExtAddr; - tExtAddr.sin_addr.s_addr = t4Addr; - - details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr); - details.extPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; - } - break; - - case RsShortInviteFieldType::HIDDEN_LOCATOR: - details.hiddenType = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - details.hiddenNodePort = (((uint32_t)buf[4]) << 8)+ (uint32_t)buf[5]; - details.isHiddenNode = true; - details.hiddenNodeAddress = std::string((char*)&buf[6],s-6); - break; - - case RsShortInviteFieldType::CHECKSUM: - { - if(s != 3 || total_s+3 != size) // make sure the checksum is the last section - { - err_code = CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION; - return false; - } - uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(bf.data(),size-5); - uint32_t certificate_crc = static_cast( buf[0] + (buf[1] << 8) + (buf[2] << 16) ); - - if(computed_crc != certificate_crc) - { - err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; - return false; - } - CRC_ok = true; - break; - } - - } - - buf = &buf[s]; - total_s += s; - } - - // now check if the PGP key is available. If so, add it in the PeerDetails: + // Also check if the PGP key is available. If so, add it in the PeerDetails: RsPeerDetails pgp_det ; if(getGPGDetails(PGPHandler::pgpIdFromFingerprint(details.fpr),pgp_det) && pgp_det.fpr == details.fpr) @@ -1497,23 +1369,13 @@ bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& d else details.skip_pgp_signature_validation = true; - if(!CRC_ok) - { - err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; - return false; - } if(details.gpg_id.isNull()) { err_code = CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT; return false; } - if(details.id.isNull()) - { - err_code = CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID; - return false; - } - err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR; - return true; + err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR; + return true; } bool p3Peers::acceptInvite( const std::string& invite, diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index bc5e09d76..15b5f3801 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -4,6 +4,8 @@ #include "util/rsbase64.h" #include "util/radix64.h" +#include "pgp/rscertificate.h" + #include "friendserver.h" #include "friend_server/fsitem.h" @@ -92,7 +94,7 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it RsPeerDetails shortInviteDetails; uint32_t errorCode = 0; - if(item->short_invite.empty() || !rsPeers->parseShortInvite(item->short_invite, shortInviteDetails,errorCode )) + if(item->short_invite.empty() || !RsCertificate::decodeRadix64ShortInvite(item->short_invite, shortInviteDetails,errorCode )) throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode)); RsDbg() << " Short invite is fine. PGP fingerprint: " << shortInviteDetails.fpr ; From 6b6d556e982d69bf187f76c7a45752e7352e23c9 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 1 Nov 2021 16:14:13 +0100 Subject: [PATCH 199/697] added nonce system for safe peer removal --- libretroshare/src/friend_server/fsitem.h | 15 +++- retroshare-friendserver/src/friendserver.cc | 80 +++++++++++++++------ retroshare-friendserver/src/friendserver.h | 3 + 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/libretroshare/src/friend_server/fsitem.h b/libretroshare/src/friend_server/fsitem.h index e3990b19f..d523f5726 100644 --- a/libretroshare/src/friend_server/fsitem.h +++ b/libretroshare/src/friend_server/fsitem.h @@ -76,10 +76,23 @@ class RsFriendServerClientRemoveItem: public RsFriendServerItem public: RsFriendServerClientRemoveItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_CLIENT_REMOVE) {} - void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) + void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { + RS_SERIAL_PROCESS(peer_id); + RS_SERIAL_PROCESS(nonce); } + + // Peer ID for the peer to remove. + + RsPeerId peer_id; + + // Nonce that was returned by the server after the last client request. Should match in order to proceed. This prevents + // a malicious actor from removing peers from the server. Since the nonce is sent through Tor tunnels, it cannot be known by + // anyone else than the client. + + uint64_t nonce; }; + class RsFriendServerEncryptedServerResponseItem: public RsFriendServerItem { public: diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index 15b5f3801..b2c2ba38b 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -66,21 +66,44 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it { try { - RsDbg() << "Received a client publish item from " << item->PeerId() ; + RsDbg() << "Received a client publish item from " << item->PeerId() << ":"; RsDbg() << *item ; // First of all, read PGP key and short invites, parse them, and check that they contain the same information + FriendServer::handleIncomingClientData(item->pgp_public_key_b64,item->short_invite); + + // Respond with a list of potential friends + + + } + catch(std::exception& e) + { + RsErr() << "ERROR: " << e.what() ; + } + + // Close client connection from server side, to tell the client that nothing more is coming. + + RsDbg() << "Closing client connection." ; + + mni->closeConnection(item->PeerId()); +} + +bool FriendServer::handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64) +{ RsDbg() << " Checking item data..."; std::string error_string; RsPgpId pgp_id ; std::vector key_binary_data ; - key_binary_data = Radix64::decode(item->pgp_public_key_b64); + key_binary_data = Radix64::decode(pgp_public_key_b64); if(key_binary_data.empty()) - throw std::runtime_error(" Cannot decode client pgp public key: \"" + item->pgp_public_key_b64 + "\". Wrong format??"); + throw std::runtime_error(" Cannot decode client pgp public key: \"" + pgp_public_key_b64 + "\". Wrong format??"); + +// Apparently RsBase64 doesn't work correctly. +// // if(!RsBase64::decode(item->pgp_public_key_b64,key_binary_data)) // throw std::runtime_error(" Cannot decode client pgp public key: \"" + item->pgp_public_key_b64 + "\". Wrong format??"); @@ -94,7 +117,7 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it RsPeerDetails shortInviteDetails; uint32_t errorCode = 0; - if(item->short_invite.empty() || !RsCertificate::decodeRadix64ShortInvite(item->short_invite, shortInviteDetails,errorCode )) + if(short_invite_b64.empty() || !RsCertificate::decodeRadix64ShortInvite(short_invite_b64, shortInviteDetails,errorCode )) throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode)); RsDbg() << " Short invite is fine. PGP fingerprint: " << shortInviteDetails.fpr ; @@ -106,38 +129,53 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it if(fpr_test != shortInviteDetails.fpr) throw std::runtime_error("Cannot get fingerprint from keyring for client public key. Something's really wrong.") ; - RsDbg() << " Short invite PGP fingerprint matches the public key fingerprint." ; + RsDbg() << " Short invite PGP fingerprint matches the public key fingerprint."; + RsDbg() << " Sync-ing the PGP keyring on disk"; - // Check the item's data signature + mPgpHandler->syncDatabase(); + + // Check the item's data signature. Is that needed? Not sure, since the data is sent PGP-encrypted, so only the owner + // of the secret PGP key can actually use it. +#warning TODO // All good. -#warning TODO // Store/update the peer info auto& pi(mCurrentClientPeers[shortInviteDetails.id]); - pi.short_certificate = item->short_invite; + pi.short_certificate = short_invite_b64; pi.last_connection_TS = time(nullptr); + pi.last_nonce = RsRandom::random_u64(); - // Respond with a list of potential friends - } - catch(std::exception& e) - { - RsErr() << e.what() ; - } - - // Close client connection from server side, to tell the client that nothing more is coming. - - RsDbg() << "Closing client connection." ; - - mni->closeConnection(item->PeerId()); + return true; } + void FriendServer::handleClientRemove(const RsFriendServerClientRemoveItem *item) { RsDbg() << "Received a client remove item:" << *item ; + + auto it = mCurrentClientPeers.find(item->peer_id); + + if(it == mCurrentClientPeers.end()) + { + RsErr() << " ERROR: Client " << item->peer_id << " is not known to the server." ; + return; + } + + if(it->second.last_nonce != item->nonce) + { + RsErr() << " ERROR: Client supplied a nonce " << std::hex << item->nonce << std::dec << " that is not correct (expected " + << std::hex << it->second.last_nonce << std::dec << ")"; + return; + } + + RsDbg() << " Nonce is correct: " << std::hex << item->nonce << std::dec << ". Removing peer " << item->peer_id ; + + mCurrentClientPeers.erase(it); } + FriendServer::FriendServer(const std::string& base_dir) { RsDbg() << "Creating friend server." ; @@ -191,7 +229,7 @@ void FriendServer::debugPrint() rstime_t now = time(nullptr); for(auto& it:mCurrentClientPeers) - RsDbg() << " " << it.first << ": " << "last contact: " << now - it.second.last_connection_TS; + RsDbg() << " " << it.first << ": nonce=" << std::hex << it.second.last_nonce << std::dec << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; RsDbg() << "==============================================="; diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 49dd89359..711256d69 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -34,6 +34,7 @@ struct PeerInfo { std::string short_certificate; rstime_t last_connection_TS; + uint64_t last_nonce; }; class FriendServer : public RsTickingThread @@ -52,6 +53,8 @@ private: void handleClientRemove(const RsFriendServerClientRemoveItem *item); void handleClientPublish(const RsFriendServerClientPublishItem *item); + bool handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64); + void autoWash(); void debugPrint(); From 7be575045b2be10cebdc502743a90833e6b95e4e Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 1 Nov 2021 18:45:10 +0100 Subject: [PATCH 200/697] Fixed git update of submodule supportlibs/libsam3 for MinGW compile --- libretroshare/src/libretroshare.pro | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d410e8a52..364d69622 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1034,14 +1034,24 @@ rs_sam3_libsam3 { libsam3.output = $$clean_path($${LIBSAM3_BUILD_PATH}/libsam3.a) libsam3.CONFIG += target_predeps combine libsam3.variable_out = PRE_TARGETDEPS - libsam3.commands = \ - cd $${RS_SRC_PATH} && ( \ - git submodule update --init supportlibs/libsam3 || \ - true ) && \ - mkdir -p $${LIBSAM3_BUILD_PATH} && \ - (cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} || true) && \ - cd $${LIBSAM3_BUILD_PATH} && \ - $(MAKE) build + win32-g++:isEmpty(QMAKE_SH) { + LIBSAM3_MAKE_PARAMS = CC=gcc + libsam3.commands = \ + cd /D $$shell_path($${RS_SRC_PATH}) && git submodule update --init supportlibs/libsam3 || cd . $$escape_expand(\\n\\t) \ + $(CHK_DIR_EXISTS) $$shell_path($$LIBSAM3_BUILD_PATH) $(MKDIR) $$shell_path($${LIBSAM3_BUILD_PATH}) $$escape_expand(\\n\\t) \ + $(COPY_DIR) $$shell_path($${LIBSAM3_SRC_PATH}) $$shell_path($${LIBSAM3_BUILD_PATH}) || cd . $$escape_expand(\\n\\t) + } else { + LIBSAM3_MAKE_PARAMS = + libsam3.commands = \ + cd $${RS_SRC_PATH} && ( \ + git submodule update --init supportlibs/libsam3 || \ + true ) && \ + mkdir -p $${LIBSAM3_BUILD_PATH} && \ + (cp -r $${LIBSAM3_SRC_PATH}/* $${LIBSAM3_BUILD_PATH} || true) && + } + libsam3.commands += \ + cd $$shell_path($${LIBSAM3_BUILD_PATH}) && \ + $(MAKE) build $${LIBSAM3_MAKE_PARAMS} QMAKE_EXTRA_COMPILERS += libsam3 } From 0191072326543e61256e38e27c5f2accebe30c86 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 1 Nov 2021 22:01:59 +0100 Subject: [PATCH 201/697] added response system from friend server --- libretroshare/src/friend_server/fsitem.h | 3 ++ libretroshare/src/pgp/pgphandler.cc | 14 +++++--- retroshare-friendserver/src/friendserver.cc | 39 ++++++++++++++++++--- retroshare-friendserver/src/friendserver.h | 7 +++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/friend_server/fsitem.h b/libretroshare/src/friend_server/fsitem.h index d523f5726..ca6d4d076 100644 --- a/libretroshare/src/friend_server/fsitem.h +++ b/libretroshare/src/friend_server/fsitem.h @@ -123,15 +123,18 @@ public: void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override { + RS_SERIAL_PROCESS(nonce); RS_SERIAL_PROCESS(friend_invites); } virtual void clear() override { friend_invites.clear(); + nonce = 0; } // specific members for that item + uint64_t nonce; std::map friend_invites; }; diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index b1e96b00b..b0ffd31cd 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -1926,7 +1926,10 @@ bool PGPHandler::locked_syncPublicKeyring() #else if(-1 == stat64(_pubring_path.c_str(), &buf)) #endif + { std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; + buf.st_mtime = 0; + } if(_pubring_last_update_time < buf.st_mtime) { @@ -1968,12 +1971,13 @@ bool PGPHandler::locked_syncTrustDatabase() librs::util::ConvertUtf8ToUtf16(_trustdb_path, wfullname); if(-1 == _wstati64(wfullname.c_str(), &buf)) #else - if(-1 == stat64(_trustdb_path.c_str(), &buf)) + if(-1 == stat64(_trustdb_path.c_str(), &buf)) #endif - { - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _trustdb_path << ". Will force write it." << std::endl; - _trustdb_changed = true ; // we force write of trust database if it does not exist. - } + { + std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _trustdb_path << ". Will force write it." << std::endl; + _trustdb_changed = true ; // we force write of trust database if it does not exist. + buf.st_mtime = 0; + } if(_trustdb_last_update_time < buf.st_mtime) { diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index b2c2ba38b..c74fd4801 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -70,12 +70,21 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it RsDbg() << *item ; // First of all, read PGP key and short invites, parse them, and check that they contain the same information + RsPeerId pid; + RsPgpFingerprint fpr; - FriendServer::handleIncomingClientData(item->pgp_public_key_b64,item->short_invite); + std::map::iterator pi = handleIncomingClientData(item->pgp_public_key_b64,item->short_invite); + // No need to test for it==mCurrentClients.end() because it will be directly caught by the exception handling below even before. // Respond with a list of potential friends + RsFriendServerServerResponseItem *sr_item = new RsFriendServerServerResponseItem; + sr_item->nonce = pi->second.last_nonce; + sr_item->friend_invites = computeListOfFriendInvites(item->n_requested_friends,pi->first,pi->second.pgp_fingerprint); + sr_item->PeerId(item->PeerId()); + + mni->SendItem(sr_item); } catch(std::exception& e) { @@ -89,7 +98,27 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it mni->closeConnection(item->PeerId()); } -bool FriendServer::handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64) +std::map FriendServer::computeListOfFriendInvites(uint32_t nb_reqs_invites, const RsPeerId &pid, const RsPgpFingerprint &fpr) +{ + // For now, returns the first nb_reqs_invites from the currently known peer, that would not be the peer who's asking + + std::map res; + + for(auto it:mCurrentClientPeers) + { + if(it.first == pid) + continue; + + res.insert(std::make_pair(it.second.short_certificate,false)); // for now we say that peers havn't been warned already + + if(res.size() >= nb_reqs_invites) + break; + } + + return res; +} + +std::map::iterator FriendServer::handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64) { RsDbg() << " Checking item data..."; @@ -146,9 +175,11 @@ bool FriendServer::handleIncomingClientData(const std::string& pgp_public_key_b6 pi.short_certificate = short_invite_b64; pi.last_connection_TS = time(nullptr); - pi.last_nonce = RsRandom::random_u64(); - return true; + while(pi.last_nonce == 0) // reuse the same identifier (so it's not really a nonce, but it's kept secret whatsoever). + pi.last_nonce = RsRandom::random_u64(); + + return mCurrentClientPeers.find(shortInviteDetails.id); } diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 711256d69..ba5f9d06b 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -32,6 +32,7 @@ class RsFriendServerClientPublishItem; struct PeerInfo { + RsPgpFingerprint pgp_fingerprint; std::string short_certificate; rstime_t last_connection_TS; uint64_t last_nonce; @@ -53,7 +54,11 @@ private: void handleClientRemove(const RsFriendServerClientRemoveItem *item); void handleClientPublish(const RsFriendServerClientPublishItem *item); - bool handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64); + // Adds the incoming peer data to the list of current clients and returns the + std::map::iterator handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64); + + // Computes the appropriate list of short invites to send to a given peer. + std::map computeListOfFriendInvites(uint32_t nb_reqs_invites,const RsPeerId& pid,const RsPgpFingerprint& fpr); void autoWash(); void debugPrint(); From a9a7b556d5e60228439b97d8b6b07a19fb227494 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 3 Nov 2021 16:23:35 +0100 Subject: [PATCH 202/697] Upgrade MSYS2 for Windows build --- .../Windows-msys2/env/tools/prepare-msys2.bat | 13 +++++++------ .../env/tools/root/update-msys2.bat | 6 +++--- .../Windows/env/tools/prepare-msys2.bat | 17 +++++++---------- .../Windows/env/tools/root/update-msys2.bat | 6 +++--- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat b/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat index 2f85c42be..b1e0c4187 100644 --- a/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat +++ b/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat @@ -25,8 +25,11 @@ if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( ) ) -set MSYS2Install=msys2-base-%MSYS2Architecture%-20200720.tar.xz -set MSYS2Url=http://sourceforge.net/projects/msys2/files/Base/%MSYS2Architecture%/%MSYS2Install%/download +if "%MSYS2Architecture%"=="i686" set MSYS2Version=20210705 +if "%MSYS2Architecture%"=="x86_64" set MSYS2Version=20210725 + +set MSYS2Install=msys2-base-%MSYS2Architecture%-%MSYS2Version%.tar.xz +set MSYS2Url=https://repo.msys2.org/distrib/%MSYS2Architecture%/%MSYS2Install% %cecho% info "Remove previous MSYS2 version" call "%ToolsPath%\remove-dir.bat" "%EnvMSYS2Path%" @@ -41,12 +44,10 @@ if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download M set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh %cecho% info "Initialize MSYS2" -"%MSYS2SH%" -lc "pacman -Sy" -"%MSYS2SH%" -lc "pacman --noconfirm --needed -S bash pacman pacman-mirrors msys2-runtime" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat" -call "%EnvRootPath%\update-msys2.bat" -call "%EnvRootPath%\update-msys2.bat" :exit endlocal diff --git a/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat b/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat index 3075e392b..a3d2398cd 100644 --- a/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat +++ b/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat @@ -8,11 +8,11 @@ if exist "%~dp0msys2\msys64" call :update 64 goto :EOF :update -set MSYSSH=%~dp0msys2\msys%~1\usr\bin\sh +set MSYS2SH=%~dp0msys2\msys%~1\usr\bin\sh echo Update MSYS2 %~1 -"%MSYSSH%" -lc "pacman -Sy" -"%MSYSSH%" -lc "pacman --noconfirm -Su" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" :exit endlocal diff --git a/build_scripts/Windows/env/tools/prepare-msys2.bat b/build_scripts/Windows/env/tools/prepare-msys2.bat index 0a649ae0e..a0483289a 100644 --- a/build_scripts/Windows/env/tools/prepare-msys2.bat +++ b/build_scripts/Windows/env/tools/prepare-msys2.bat @@ -25,8 +25,11 @@ if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( ) ) -set MSYS2Install=msys2-base-%MSYS2Architecture%-20190524.tar.xz -set MSYS2Url=http://sourceforge.net/projects/msys2/files/Base/%MSYS2Architecture%/%MSYS2Install%/download +if "%MSYS2Architecture%"=="i686" set MSYS2Version=20210705 +if "%MSYS2Architecture%"=="x86_64" set MSYS2Version=20210725 + +set MSYS2Install=msys2-base-%MSYS2Architecture%-%MSYS2Version%.tar.xz +set MSYS2Url=https://repo.msys2.org/distrib/%MSYS2Architecture%/%MSYS2Install% set CMakeInstall=cmake-3.19.0-win32-x86.zip set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall% set CMakeUnpackPath=%EnvMSYS2Path%\msys%MSYS2Base% @@ -64,17 +67,11 @@ if "%FoundProfile%"=="0" ( set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh -%cecho% info "Update keyring" -"%MSYS2SH%" -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -"%MSYS2SH%" -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - %cecho% info "Initialize MSYS2" -"%MSYS2SH%" -lc "pacman -Sy" -"%MSYS2SH%" -lc "pacman --noconfirm --needed -S bash pacman pacman-mirrors msys2-runtime" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat" -call "%EnvRootPath%\update-msys2.bat" -call "%EnvRootPath%\update-msys2.bat" :exit endlocal diff --git a/build_scripts/Windows/env/tools/root/update-msys2.bat b/build_scripts/Windows/env/tools/root/update-msys2.bat index 3075e392b..a3d2398cd 100644 --- a/build_scripts/Windows/env/tools/root/update-msys2.bat +++ b/build_scripts/Windows/env/tools/root/update-msys2.bat @@ -8,11 +8,11 @@ if exist "%~dp0msys2\msys64" call :update 64 goto :EOF :update -set MSYSSH=%~dp0msys2\msys%~1\usr\bin\sh +set MSYS2SH=%~dp0msys2\msys%~1\usr\bin\sh echo Update MSYS2 %~1 -"%MSYSSH%" -lc "pacman -Sy" -"%MSYSSH%" -lc "pacman --noconfirm -Su" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" :exit endlocal From 5e9bc9c2b87b9eb6ea32f44e69d9902f5535de21 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 3 Nov 2021 15:28:19 +0100 Subject: [PATCH 203/697] Fix RsThread when nothing to do and run finish before start. --- libretroshare/src/gxs/rsgenexchange.cc | 6 +++--- libretroshare/src/util/rsthreads.cc | 16 +++++----------- libretroshare/src/util/rsthreads.h | 3 +++ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 0a9db1e58..da8973eb1 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -322,12 +322,12 @@ void RsGenExchange::tick() { mIntegrityCheck = new RsGxsIntegrityCheck( mDataStore, this, *mSerialiser, mGixs); - mIntegrityCheck->start("gxs integrity"); - mChecking = true; + std::string thisName = typeid(*this).name(); + mChecking = mIntegrityCheck->start("gxs IC4 "+thisName); } } - if(mIntegrityCheck->isDone()) + if(mIntegrityCheck->isDone() || !mChecking) { std::vector grpIds; GxsMsgReq msgIds; diff --git a/libretroshare/src/util/rsthreads.cc b/libretroshare/src/util/rsthreads.cc index 035ad214a..85f96b69a 100644 --- a/libretroshare/src/util/rsthreads.cc +++ b/libretroshare/src/util/rsthreads.cc @@ -92,11 +92,11 @@ void RsThread::resetTid() #ifdef WINDOWS_SYS memset (&mTid, 0, sizeof(mTid)); #else - mTid = 0; + mTid = pthread_t(); //Thread identifiers should be considered opaque and can be null. #endif } -RsThread::RsThread() : mHasStopped(true), mShouldStop(false), mLastTid() +RsThread::RsThread() : mInitMtx("RsThread"), mHasStopped(true), mShouldStop(false), mLastTid() #ifdef RS_THREAD_FORCE_STOP , mStopTimeout(0) #endif @@ -115,6 +115,7 @@ void RsThread::askForStop() void RsThread::wrapRun() { + {RS_STACK_MUTEX(mInitMtx);} // Waiting Init done. run(); resetTid(); mHasStopped = true; @@ -184,6 +185,8 @@ bool RsThread::start(const std::string& threadName) // Atomically check if the thread was already started and set it as running if(mHasStopped.exchange(false)) { + RS_STACK_MUTEX(mInitMtx); // Block thread starting to run + mShouldStop = false; int pError = pthread_create( &mTid, nullptr, &rsthread_init, static_cast(this) ); @@ -196,15 +199,6 @@ bool RsThread::start(const std::string& threadName) print_stacktrace(); return false; } - if(!mTid) - { - RsErr() << __PRETTY_FUNCTION__ << " pthread_create could not create" - << " new thread: " << threadName << " mTid: " << mTid - << std::endl; - mHasStopped = true; - print_stacktrace(); - return false; - } /* Store an extra copy of thread id for debugging */ mLastTid = mTid; diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h index 82221ebbb..c33a608a8 100644 --- a/libretroshare/src/util/rsthreads.h +++ b/libretroshare/src/util/rsthreads.h @@ -261,6 +261,9 @@ private: /** Call @see run() setting the appropriate flags around it*/ void wrapRun(); + // To be sure Init (pthread_setname_np) is done before continue thread. Else can finish before and crash. + RsMutex mInitMtx; + /// True if thread is stopped, false otherwise std::atomic mHasStopped; From 433f6f763ddbbc53284e3a1f217df1867971b14b Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 3 Nov 2021 18:38:46 +0100 Subject: [PATCH 204/697] Fixed linking of plugins for Windows compile --- plugins/Common/retroshare_plugin.pri | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/Common/retroshare_plugin.pri b/plugins/Common/retroshare_plugin.pri index 5159aa9b1..77812db81 100644 --- a/plugins/Common/retroshare_plugin.pri +++ b/plugins/Common/retroshare_plugin.pri @@ -102,8 +102,6 @@ win32 { for(lib, LIB_DIR):LIBS += -L"$$lib" for(bin, BIN_DIR):LIBS += -L"$$bin" LIBS += -lpthread - - QMAKE_LFLAGS += -Wl,--end-group } macx { From d6c4a086f3d83d880d4fd8d18c21ab511d84a61f Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Nov 2021 11:58:42 +0100 Subject: [PATCH 205/697] Add test for JSON API DirDetails handle type --- ...tails_handle_correct_64bit_integer_type.sh | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh diff --git a/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh new file mode 100755 index 000000000..95918256c --- /dev/null +++ b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see +# +# SPDX-FileCopyrightText: Retroshare Team +# SPDX-License-Identifier: AGPL-3.0-only + + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true +} + +define_default_value API_BASE_URL "http://127.0.0.1:9092" +define_default_value API_TOKEN "0000:0000" + +function tLog() +{ + local mCategory="$1" ; shift + echo "$mCategory $(date) $@" >&2 +} + +mReply="$(curl -u "$API_TOKEN" "$API_BASE_URL/rsFiles/requestDirDetails")" + +[ "$(echo "$mReply" | jq '.retval')" == "true" ] || +{ + tLog E "/rsFiles/requestDirDetails failed: '$mReply'" + exit -1 +} + +[ "$(echo "$mReply" | jq '.details.handle')" != "0" ] || +{ + tLog E ".details.handle has wrong type int: '$mReply'" + exit -1 +} + +[ "$(echo "$mReply" | jq '.details.handle.xstr64')" == "\"0\"" ] && + [ "$(echo "$mReply" | jq '.details.handle.xint64')" == "0" ] && +{ + tLog I '.details.handle has correct type' + exit 0 +} + +tLog E "Unkown error in test $0: '$mReply'" +exit -2 From 53f2891b7865abafea14314124caa597ce4b41b7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Nov 2021 13:29:32 +0100 Subject: [PATCH 206/697] Improve JSON API DirDetails handle type test --- ...API_DirDetails_handle_correct_64bit_integer_type.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh index 95918256c..03b99a94e 100755 --- a/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh +++ b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh @@ -39,7 +39,15 @@ function tLog() echo "$mCategory $(date) $@" >&2 } -mReply="$(curl -u "$API_TOKEN" "$API_BASE_URL/rsFiles/requestDirDetails")" +mCmd="curl -u $API_TOKEN $API_BASE_URL/rsFiles/requestDirDetails" + +mReply="$($mCmd)" +mCurlRet="$?" + +if [ "$mCurlRet" != 0 ]; then + tLog E "$mCmd failed: $mCurlRet '$mReply'" + exit -3 +fi [ "$(echo "$mReply" | jq '.retval')" == "true" ] || { From 01da2fbe9e1b754375b5d1bc58c206aa731e7499 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 4 Nov 2021 14:24:19 +0100 Subject: [PATCH 207/697] added debug output and fixed one bug in pqistreamer --- libretroshare/src/friend_server/fsbio.cc | 11 ++- libretroshare/src/friend_server/fsclient.cc | 79 +++++++++++++-------- libretroshare/src/friend_server/fsclient.h | 1 + libretroshare/src/friend_server/fsitem.h | 23 ++++++ libretroshare/src/pqi/pqistreamer.cc | 13 ++-- retroshare-friendserver/src/friendserver.cc | 38 ++++++---- retroshare-friendserver/src/network.cc | 5 +- 7 files changed, 117 insertions(+), 53 deletions(-) diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc index 8d6933a76..6668a59c9 100644 --- a/libretroshare/src/friend_server/fsbio.cc +++ b/libretroshare/src/friend_server/fsbio.cc @@ -129,9 +129,14 @@ int FsBioInterface::readdata(void *data, int len) int FsBioInterface::senddata(void *data, int len) { -// int written = write(mCLintConnt, data, len); -// return written; - return len; + // shouldn't we better send in multiple packets, similarly to how we read? + + RsDbg() << "FsBioInterface: sending data packet of size " << len ; + + int written = write(mCLintConnt, data, len); + RsDbg() << "FsBioInterface: done."; + + return written; } int FsBioInterface::netstatus() { diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index 5548168a2..e76e75d71 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -55,30 +55,35 @@ bool FsClient::requestFriends(const std::string& address,uint16_t port,uint32_t for(auto item:response) { - auto *encrypted_response_item = dynamic_cast(item); + // auto *encrypted_response_item = dynamic_cast(item); - if(!encrypted_response_item) - { - delete item; - continue; - } + // if(!encrypted_response_item) + // { + // delete item; + // continue; + // } // For now, also handle unencrypted response items. Will be disabled in production auto *response_item = dynamic_cast(item); - if(!response_item) - { - delete item; - continue; - } + if(response_item) + handleServerResponse(response_item); - for(const auto& it:response_item->friend_invites) - friend_certificates.insert(it); + delete item; } return friend_certificates.size(); } +void FsClient::handleServerResponse(RsFriendServerServerResponseItem *item) +{ + std::cerr << "Received a response item from server: " << std::endl; + std::cerr << *item << std::endl; + + // for(const auto& it:response_item->friend_invites) + // friend_certificates.insert(it); +} + bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,std::list& response) { // open a connection @@ -131,42 +136,56 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st FsBioInterface *bio = new FsBioInterface(CreateSocket); // deleted by ~pqistreamer() - pqithreadstreamer p(this,rss,RsPeerId(),bio,BIN_FLAGS_READABLE | BIN_FLAGS_NO_DELETE | BIN_FLAGS_NO_CLOSE); + pqithreadstreamer p(this,rss,RsPeerId(),bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE | BIN_FLAGS_NO_CLOSE); p.start(); uint32_t ss; p.SendItem(item,ss); + bool should_close = false; while(true) { - p.tick(); + p.tick(); // ticks bio RsItem *item = GetItem(); + RsDbg() << "Ticking for response..."; + if(item) { response.push_back(item); std::cerr << "Got a response item: " << std::endl; std::cerr << *item << std::endl; + + if(dynamic_cast(item) != nullptr) + { + RsDbg() << "End of transmission. " ; + should_close = true; + break; + } + + if(!bio->isactive()) // socket has probably closed + { + RsDbg() << "(client side) Socket has been closed by server."; + should_close =true; + break; + } } - - if(!bio->isactive()) // socket has probably closed - { - RsDbg() << "(client side) Socket has been closed by server."; - RsDbg() << " Stopping/killing pqistreamer" ; - p.fullstop(); - - RsDbg() << " Closing socket." ; - close(CreateSocket); - CreateSocket=0; - - RsDbg() << " Exiting loop." ; - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds(200)); } + if(should_close) + { + RsDbg() << " Stopping/killing pqistreamer" ; + p.fullstop(); + + RsDbg() << " Closing socket." ; + close(CreateSocket); + CreateSocket=0; + + RsDbg() << " Exiting loop." ; + } + return true; } diff --git a/libretroshare/src/friend_server/fsclient.h b/libretroshare/src/friend_server/fsclient.h index a14fc82ef..4c17c142d 100644 --- a/libretroshare/src/friend_server/fsclient.h +++ b/libretroshare/src/friend_server/fsclient.h @@ -42,6 +42,7 @@ protected: private: bool sendItem(const std::string &address, uint16_t port, RsItem *item, std::list &response); + void handleServerResponse(RsFriendServerServerResponseItem *item); std::list mIncomingItems; }; diff --git a/libretroshare/src/friend_server/fsitem.h b/libretroshare/src/friend_server/fsitem.h index ca6d4d076..95522b550 100644 --- a/libretroshare/src/friend_server/fsitem.h +++ b/libretroshare/src/friend_server/fsitem.h @@ -34,6 +34,7 @@ const uint8_t RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH = 0x01 ; const uint8_t RS_PKT_SUBTYPE_FS_CLIENT_REMOVE = 0x02 ; const uint8_t RS_PKT_SUBTYPE_FS_SERVER_RESPONSE = 0x03 ; const uint8_t RS_PKT_SUBTYPE_FS_SERVER_ENCRYPTED_RESPONSE = 0x04 ; +const uint8_t RS_PKT_SUBTYPE_FS_SERVER_STATUS = 0x05 ; class RsFriendServerItem: public RsItem { @@ -71,6 +72,27 @@ public: std::string pgp_public_key_b64; }; +class RsFriendServerStatusItem: public RsFriendServerItem +{ +public: + RsFriendServerStatusItem() : RsFriendServerItem(RS_PKT_SUBTYPE_FS_SERVER_STATUS) {} + + void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RS_SERIAL_PROCESS(status); + } + + enum ConnectionStatus: uint8_t + { + UNKNOWN = 0x00, + END_OF_TRANSMISSION = 0x01 + }; + + // specific members for that item + + ConnectionStatus status; +}; + class RsFriendServerClientRemoveItem: public RsFriendServerItem { public: @@ -152,6 +174,7 @@ struct FsSerializer : RsServiceSerializer case RS_PKT_SUBTYPE_FS_CLIENT_REMOVE: return new RsFriendServerClientRemoveItem(); case RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH: return new RsFriendServerClientPublishItem(); case RS_PKT_SUBTYPE_FS_SERVER_RESPONSE: return new RsFriendServerServerResponseItem(); + case RS_PKT_SUBTYPE_FS_SERVER_STATUS: return new RsFriendServerStatusItem(); case RS_PKT_SUBTYPE_FS_SERVER_ENCRYPTED_RESPONSE: return new RsFriendServerEncryptedServerResponseItem(); default: RsErr() << "Unknown subitem type " << item_sub_id << " in FsSerialiser" ; diff --git a/libretroshare/src/pqi/pqistreamer.cc b/libretroshare/src/pqi/pqistreamer.cc index 96b91dae6..6e01b8e71 100644 --- a/libretroshare/src/pqi/pqistreamer.cc +++ b/libretroshare/src/pqi/pqistreamer.cc @@ -357,6 +357,7 @@ int pqistreamer::status() // this method is overloaded by pqiqosstreamer void pqistreamer::locked_storeInOutputQueue(void *ptr,int,int) { + RsDbg() << "Storing packet " << std::hex << ptr << std::dec << " in outqueue."; mOutPkts.push_back(ptr); } @@ -375,9 +376,9 @@ int pqistreamer::queue_outpqi_locked(RsItem *pqi,uint32_t& pktsize) if(ptr == NULL) return 0 ; -#ifdef DEBUG_PQISTREAMER +//#ifdef DEBUG_PQISTREAMER std::cerr << "pqistreamer::queue_outpqi() serializing packet with packet size : " << pktsize << std::endl; -#endif +//#endif /*******************************************************************************************/ // keep info for stats for a while. Only keep the items for the last two seconds. sec n is ongoing and second n-1 @@ -521,7 +522,7 @@ int pqistreamer::handleoutgoing_locked() { /* if we are not active - clear anything in the queues. */ locked_clear_out_queue() ; -#ifdef DEBUG_PACKET_SLICING +#ifdef DEBUG_PACKET_SLICING std::cerr << "(II) Switching off packet slicing." << std::endl; #endif mAcceptsPacketSlicing = false ; @@ -1430,8 +1431,12 @@ void *pqistreamer::locked_pop_out_data(uint32_t /*max_slice_size*/, uint32_t &si { res = *(mOutPkts.begin()); mOutPkts.pop_front(); + + // In pqistreamer, we do not split outgoing packets. For now only pqiQoSStreamer supports packet slicing. + size = getRsItemSize(res); + #ifdef DEBUG_TRANSFERS - std::cerr << "pqistreamer::locked_pop_out_data() getting next pkt from mOutPkts queue"; + std::cerr << "pqistreamer::locked_pop_out_data() getting next pkt " << std::hex << res << std::dec << " from mOutPkts queue"; std::cerr << std::endl; #endif } diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index c74fd4801..a9e699730 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -17,8 +17,6 @@ void FriendServer::threadTick() { // Listen to the network interface, capture incoming data etc. - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - RsItem *item; while(nullptr != (item = mni->GetItem())) @@ -43,6 +41,7 @@ void FriendServer::threadTick() } delete item; } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); static rstime_t last_autowash_TS = time(nullptr); rstime_t now = time(nullptr); @@ -78,6 +77,8 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it // No need to test for it==mCurrentClients.end() because it will be directly caught by the exception handling below even before. // Respond with a list of potential friends + RsDbg() << "Sending response item to " << item->PeerId() ; + RsFriendServerServerResponseItem *sr_item = new RsFriendServerServerResponseItem; sr_item->nonce = pi->second.last_nonce; @@ -85,17 +86,30 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it sr_item->PeerId(item->PeerId()); mni->SendItem(sr_item); + } catch(std::exception& e) { RsErr() << "ERROR: " << e.what() ; + + RsFriendServerStatusItem *status_item = new RsFriendServerStatusItem; + status_item->status = RsFriendServerStatusItem::END_OF_TRANSMISSION; + status_item->PeerId(item->PeerId()); + mni->SendItem(status_item); + return; } // Close client connection from server side, to tell the client that nothing more is coming. + //RsDbg() << "Closing client connection." ; + //mni->closeConnection(item->PeerId()); - RsDbg() << "Closing client connection." ; + RsDbg() << "Sending end-of-stream item to " << item->PeerId() ; - mni->closeConnection(item->PeerId()); + RsFriendServerStatusItem *status_item = new RsFriendServerStatusItem; + status_item->status = RsFriendServerStatusItem::END_OF_TRANSMISSION; + status_item->PeerId(item->PeerId()); + + mni->SendItem(status_item); } std::map FriendServer::computeListOfFriendInvites(uint32_t nb_reqs_invites, const RsPeerId &pid, const RsPgpFingerprint &fpr) @@ -126,16 +140,11 @@ std::map::iterator FriendServer::handleIncomingClientData(con RsPgpId pgp_id ; std::vector key_binary_data ; - key_binary_data = Radix64::decode(pgp_public_key_b64); + // key_binary_data = Radix64::decode(pgp_public_key_b64); - if(key_binary_data.empty()) + if(RsBase64::decode(pgp_public_key_b64,key_binary_data)) throw std::runtime_error(" Cannot decode client pgp public key: \"" + pgp_public_key_b64 + "\". Wrong format??"); -// Apparently RsBase64 doesn't work correctly. -// -// if(!RsBase64::decode(item->pgp_public_key_b64,key_binary_data)) -// throw std::runtime_error(" Cannot decode client pgp public key: \"" + item->pgp_public_key_b64 + "\". Wrong format??"); - RsDbg() << " Public key radix is fine." ; if(!mPgpHandler->LoadCertificateFromBinaryData(key_binary_data.data(),key_binary_data.size(), pgp_id, error_string)) @@ -236,9 +245,9 @@ void FriendServer::run() void FriendServer::autoWash() { rstime_t now = time(nullptr); + RsDbg() << "autoWash..." ; for(std::map::iterator it(mCurrentClientPeers.begin());it!=mCurrentClientPeers.end();) - { if(it->second.last_connection_TS + MAXIMUM_PEER_INACTIVE_DELAY < now) { RsDbg() << "Removing client peer " << it->first << " because it's inactive for more than " << MAXIMUM_PEER_INACTIVE_DELAY << " seconds." ; @@ -247,7 +256,10 @@ void FriendServer::autoWash() mCurrentClientPeers.erase(it); it = tmp; } - } + else + ++it; + + RsDbg() << "done." ; } void FriendServer::debugPrint() diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index 243981717..f02cb6395 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -95,9 +95,7 @@ void FsNetworkInterface::threadTick() RS_STACK_MUTEX(mFsNiMtx); for(auto& it:mConnections) - { it.second.pqi_thread->tick(); - } rstime::rs_usleep(1000*200); } @@ -210,7 +208,8 @@ int FsNetworkInterface::SendItem(RsItem *item) return 0; } - return it->second.pqi_thread->SendItem(item); + uint32_t ss; + return it->second.pqi_thread->SendItem(item,ss); } void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) From 16ca0dc52c5b8c637a09d7a75fafbcd5b4dc1560 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Nov 2021 19:17:57 +0100 Subject: [PATCH 208/697] RsThread fix warning and cleanup Avoid compiler warning due to virtual method being called in destructor at this point the empty default version would be called without damage but making the compiler concernig about the semantic being different from the one the programmer meant. Delete old superseeded function and do not depend on it on RsThread. --- libretroshare/src/libretroshare.pro | 6 ++-- libretroshare/src/util/rserrno.cc | 54 ----------------------------- libretroshare/src/util/rserrno.h | 24 ------------- libretroshare/src/util/rsthreads.cc | 32 ++++++++++------- libretroshare/src/util/rsthreads.h | 10 ++++-- 5 files changed, 29 insertions(+), 97 deletions(-) delete mode 100644 libretroshare/src/util/rserrno.cc delete mode 100644 libretroshare/src/util/rserrno.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 364d69622..075da3581 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -507,8 +507,7 @@ HEADERS += util/folderiterator.h \ util/cxx11retrocompat.h \ util/cxx14retrocompat.h \ util/cxx17retrocompat.h \ - util/rsurl.h \ - util/rserrno.h + util/rsurl.h SOURCES += ft/ftchunkmap.cc \ ft/ftcontroller.cc \ @@ -646,8 +645,7 @@ SOURCES += util/folderiterator.cc \ util/rsrecogn.cc \ util/rstime.cc \ util/rsurl.cc \ - util/rsbase64.cc \ - util/rserrno.cc + util/rsbase64.cc equals(RS_UPNP_LIB, miniupnpc) { HEADERS += rs_upnp/upnputil.h rs_upnp/upnphandler_miniupnp.h diff --git a/libretroshare/src/util/rserrno.cc b/libretroshare/src/util/rserrno.cc deleted file mode 100644 index b62394d69..000000000 --- a/libretroshare/src/util/rserrno.cc +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rserrno.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#define RS_INTERNAL_ERRNO_CASE(e) case e: return #e - -const char* rsErrnoName(int err) -{ - switch (err) - { - RS_INTERNAL_ERRNO_CASE(EINVAL); - RS_INTERNAL_ERRNO_CASE(EBUSY); - RS_INTERNAL_ERRNO_CASE(EAGAIN); - RS_INTERNAL_ERRNO_CASE(EDEADLK); - RS_INTERNAL_ERRNO_CASE(EPERM); - RS_INTERNAL_ERRNO_CASE(EBADF); - RS_INTERNAL_ERRNO_CASE(EFAULT); - RS_INTERNAL_ERRNO_CASE(ENOTSOCK); - RS_INTERNAL_ERRNO_CASE(EISCONN); - RS_INTERNAL_ERRNO_CASE(ECONNREFUSED); - RS_INTERNAL_ERRNO_CASE(ETIMEDOUT); - RS_INTERNAL_ERRNO_CASE(ENETUNREACH); - RS_INTERNAL_ERRNO_CASE(EADDRINUSE); - RS_INTERNAL_ERRNO_CASE(EINPROGRESS); - RS_INTERNAL_ERRNO_CASE(EALREADY); - RS_INTERNAL_ERRNO_CASE(ENOTCONN); - RS_INTERNAL_ERRNO_CASE(EPIPE); - RS_INTERNAL_ERRNO_CASE(ECONNRESET); - RS_INTERNAL_ERRNO_CASE(EHOSTUNREACH); - RS_INTERNAL_ERRNO_CASE(EADDRNOTAVAIL); - } - - return "rsErrnoName UNKNOWN ERROR CODE"; -} diff --git a/libretroshare/src/util/rserrno.h b/libretroshare/src/util/rserrno.h deleted file mode 100644 index 526a4890a..000000000 --- a/libretroshare/src/util/rserrno.h +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rserrno.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -const char* rsErrnoName(int err); diff --git a/libretroshare/src/util/rsthreads.cc b/libretroshare/src/util/rsthreads.cc index 85f96b69a..519ab129f 100644 --- a/libretroshare/src/util/rsthreads.cc +++ b/libretroshare/src/util/rsthreads.cc @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2016-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2016-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -25,7 +25,6 @@ #include "rsthreads.h" #include "util/rsdebug.h" -#include "util/rserrno.h" #include #include @@ -96,7 +95,8 @@ void RsThread::resetTid() #endif } -RsThread::RsThread() : mInitMtx("RsThread"), mHasStopped(true), mShouldStop(false), mLastTid() +RsThread::RsThread() : mInitMtx("RsThread"), mHasStopped(true), + mShouldStop(false), mLastTid() #ifdef RS_THREAD_FORCE_STOP , mStopTimeout(0) #endif @@ -122,13 +122,17 @@ void RsThread::wrapRun() } void RsThread::fullstop() +{ + askForStop(); + waitWhileStopping(); +} + +void RsThread::waitWhileStopping() { #ifdef RS_THREAD_FORCE_STOP const rstime_t stopRequTS = time(nullptr); #endif - askForStop(); - const pthread_t callerTid = pthread_self(); if(pthread_equal(mTid, callerTid)) { @@ -170,7 +174,8 @@ void RsThread::fullstop() { RsErr() << __PRETTY_FUNCTION__ << " pthread_cancel(" << std::hex << mTid << std::dec <<") returned " - << terr << " " << rsErrnoName(terr) << std::endl; + << terr << " " << rs_errno_to_condition(terr) + << std::endl; print_stacktrace(); } @@ -192,9 +197,8 @@ bool RsThread::start(const std::string& threadName) &mTid, nullptr, &rsthread_init, static_cast(this) ); if(pError) { - RsErr() << __PRETTY_FUNCTION__ << " pthread_create could not create" - << " new thread: " << threadName << " pError: " << pError - << std::endl; + RS_ERR( "pthread_create could not create new thread: ", threadName, + rs_errno_to_condition(pError) ); mHasStopped = true; print_stacktrace(); return false; @@ -275,7 +279,7 @@ void RsMutex::lock() if( err != 0) { RsErr() << __PRETTY_FUNCTION__ << "pthread_mutex_lock returned: " - << rsErrnoName(err) + << rs_errno_to_condition(err) #ifdef RS_MUTEX_DEBUG << " name: " << name() #endif @@ -319,7 +323,11 @@ RsThread::~RsThread() << "likely to crash because of this." << std::endl; print_stacktrace(); - fullstop(); + /* Last resort attempt to stop the thread in a less pathological state. + * Don't call fullstop() as it rely on virtual methods that at this + * point are not anymore the one from inerithing classes causing + * compilers to output a warning */ + waitWhileStopping(); } } diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h index c33a608a8..d1ed91dc9 100644 --- a/libretroshare/src/util/rsthreads.h +++ b/libretroshare/src/util/rsthreads.h @@ -4,8 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2016-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * + * Copyright (C) 2016-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -261,7 +261,11 @@ private: /** Call @see run() setting the appropriate flags around it*/ void wrapRun(); - // To be sure Init (pthread_setname_np) is done before continue thread. Else can finish before and crash. + /** Wait the thread while it is stopping */ + void waitWhileStopping(); + + /** To be sure Init (pthread_setname_np) is done before continue thread. + * Else can finish before and crash. */ RsMutex mInitMtx; /// True if thread is stopped, false otherwise From 62655779e55c96f7d1b2f291b015a9ba981b4a50 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 4 Nov 2021 20:52:38 +0100 Subject: [PATCH 209/697] use recv(...,MSG_DONTWAIT), since read() may return multiple times the same data apparently --- libretroshare/src/friend_server/fsbio.cc | 2 +- libretroshare/src/friend_server/fsclient.cc | 5 ++++- retroshare-friendserver/src/network.cc | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libretroshare/src/friend_server/fsbio.cc b/libretroshare/src/friend_server/fsbio.cc index 6668a59c9..e5be9389b 100644 --- a/libretroshare/src/friend_server/fsbio.cc +++ b/libretroshare/src/friend_server/fsbio.cc @@ -39,7 +39,7 @@ int FsBioInterface::tick() char inBuffer[1025]; memset(inBuffer,0,1025); - int readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); + ssize_t readbytes = recv(mCLintConnt, inBuffer, sizeof(inBuffer),MSG_DONTWAIT); if(readbytes == 0) { diff --git a/libretroshare/src/friend_server/fsclient.cc b/libretroshare/src/friend_server/fsclient.cc index e76e75d71..e9bc3d325 100644 --- a/libretroshare/src/friend_server/fsclient.cc +++ b/libretroshare/src/friend_server/fsclient.cc @@ -157,6 +157,8 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st std::cerr << "Got a response item: " << std::endl; std::cerr << *item << std::endl; + should_close = true; // always close the socket after one packet + if(dynamic_cast(item) != nullptr) { RsDbg() << "End of transmission. " ; @@ -171,7 +173,8 @@ bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,st break; } } - std::this_thread::sleep_for(std::chrono::milliseconds(200)); + else + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } if(should_close) diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc index f02cb6395..aa449e646 100644 --- a/retroshare-friendserver/src/network.cc +++ b/retroshare-friendserver/src/network.cc @@ -93,11 +93,19 @@ void FsNetworkInterface::threadTick() // 2 - tick all streamers + std::list to_close; + RS_STACK_MUTEX(mFsNiMtx); for(auto& it:mConnections) - it.second.pqi_thread->tick(); + if(it.second.bio->isactive()) + it.second.pqi_thread->tick(); + else + to_close.push_back(it.first); - rstime::rs_usleep(1000*200); + for(const auto& pid:to_close) + closeConnection(pid); + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } static RsPeerId makePeerId(int t) @@ -216,17 +224,19 @@ void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) { RS_STACK_MUTEX(mFsNiMtx); + RsDbg() << "Closing connection to virtual peer " << peer_id ; + const auto& it = mConnections.find(peer_id); if(it == mConnections.end()) { - RsErr() << "Cannot close connection to peer " << peer_id << ": no pending sockets available." ; + RsErr() << " Cannot close connection to peer " << peer_id << ": no pending sockets available." ; return; } if(!it->second.incoming_items.empty()) { - RsErr() << "Trying to close an incoming connection with incoming items still pending! The items will be lost." << std::endl; + RsErr() << " Trying to close an incoming connection with incoming items still pending! The items will be lost." << std::endl; for(auto& item:it->second.incoming_items) delete item; From d7981f3811ac8c6643c2f4a2cfb015198ef85658 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 9 Apr 2021 11:54:57 +0200 Subject: [PATCH 210/697] StyleSheet Rewrite Use QDarkStyle to make Standard_Dark.qss and Standard_Light.qss Use Widget name to stylize them. --- plugins/FeedReader/gui/AddFeedDialog.ui | 23 +- plugins/FeedReader/gui/FeedReaderDialog.ui | 14 +- plugins/FeedReader/gui/FeedReaderFeedItem.ui | 36 +- plugins/FeedReader/gui/PreviewFeedDialog.ui | 44 +- .../qss/FeedReader_default.qss} | 6 - plugins/FeedReader/qss/FeedReader_qss.qrc | 2 +- plugins/VOIP/gui/VOIPConfigPanel.cpp | 2 +- plugins/VOIP/gui/VOIPConfigPanel.ui | 9 +- plugins/VOIP/gui/VOIPToasterItem.ui | 27 +- plugins/VOIP/qss/VOIP_Standard.qss | 2 +- .../qss/VOIP_default.qss} | 6 - plugins/VOIP/qss/VOIP_qss.qrc | 2 +- retroshare-gui/src/changelog.txt | 10 +- retroshare-gui/src/gui/AboutWidget.cpp | 16 +- retroshare-gui/src/gui/AboutWidget.ui | 2 +- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 55 +- retroshare-gui/src/gui/ChatLobbyWidget.ui | 41 +- .../src/gui/Circles/CirclesDialog.ui | 16 +- .../src/gui/Circles/CreateCircleDialog.cpp | 8 +- .../src/gui/Circles/CreateCircleDialog.ui | 413 +-- .../src/gui/FileTransfer/SearchDialog.cpp | 96 +- .../src/gui/FileTransfer/SearchDialog.h | 2 +- .../src/gui/FileTransfer/SearchDialog.ui | 50 +- .../gui/FileTransfer/SharedFilesDialog.cpp | 19 +- .../src/gui/FileTransfer/SharedFilesDialog.ui | 24 +- .../src/gui/FileTransfer/TransfersDialog.ui | 14 +- retroshare-gui/src/gui/FriendsDialog.ui | 41 +- retroshare-gui/src/gui/GenCertDialog.cpp | 22 +- retroshare-gui/src/gui/GenCertDialog.h | 2 +- retroshare-gui/src/gui/GenCertDialog.ui | 70 +- retroshare-gui/src/gui/GetStartedDialog.cpp | 44 +- retroshare-gui/src/gui/GetStartedDialog.ui | 131 +- retroshare-gui/src/gui/HelpDialog.ui | 18 +- retroshare-gui/src/gui/HomePage.ui | 13 +- .../src/gui/Identity/IdDetailsDialog.ui | 20 +- retroshare-gui/src/gui/Identity/IdDialog.cpp | 12 +- retroshare-gui/src/gui/Identity/IdDialog.h | 2 +- retroshare-gui/src/gui/Identity/IdDialog.ui | 88 +- .../src/gui/Identity/IdEditDialog.cpp | 6 +- .../src/gui/Identity/IdEditDialog.ui | 47 +- retroshare-gui/src/gui/MainWindow.cpp | 9 +- retroshare-gui/src/gui/MainWindow.h | 6 +- retroshare-gui/src/gui/MainWindow.ui | 11 +- retroshare-gui/src/gui/MessengerWindow.ui | 11 +- retroshare-gui/src/gui/NetworkDialog.h | 6 +- .../gui/NetworkDialog/pgpid_item_model.cpp | 4 + .../src/gui/NetworkDialog/pgpid_item_model.h | 2 + retroshare-gui/src/gui/NewsFeed.cpp | 2 +- retroshare-gui/src/gui/NewsFeed.ui | 17 +- .../src/gui/PhotoShare/AlbumDialog.ui | 8 +- .../src/gui/PhotoShare/AlbumExtra.ui | 9 +- .../src/gui/PhotoShare/PhotoDialog.ui | 9 +- .../src/gui/PhotoShare/PhotoShare.ui | 21 +- .../src/gui/PhotoShare/PhotoSlideShow.ui | 7 +- .../src/gui/Posted/BoardPostDisplayWidget.cpp | 59 +- .../src/gui/Posted/BoardPostDisplayWidget.h | 12 +- .../gui/Posted/BoardPostDisplayWidget_card.ui | 46 +- .../Posted/BoardPostDisplayWidget_compact.ui | 186 +- retroshare-gui/src/gui/Posted/PhotoView.ui | 10 +- .../src/gui/Posted/PostedCardView.cpp | 28 +- .../src/gui/Posted/PostedCardView.ui | 21 +- .../src/gui/Posted/PostedCreatePostDialog.cpp | 44 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 118 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 6 +- retroshare-gui/src/gui/Posted/PostedItem.ui | 25 +- .../src/gui/Posted/PostedListWidget.cpp | 8 +- .../src/gui/Posted/PostedListWidget.ui | 28 +- .../gui/Posted/PostedListWidgetWithModel.cpp | 2 +- .../gui/Posted/PostedListWidgetWithModel.ui | 67 +- retroshare-gui/src/gui/QuickStartWizard.cpp | 32 +- retroshare-gui/src/gui/QuickStartWizard.ui | 9 +- .../src/gui/ServicePermissionDialog.ui | 19 +- retroshare-gui/src/gui/ShareManager.cpp | 2 +- retroshare-gui/src/gui/ShareManager.ui | 86 +- retroshare-gui/src/gui/StartDialog.ui | 19 +- .../src/gui/TheWire/PulseAddDialog.cpp | 21 +- .../src/gui/TheWire/PulseAddDialog.h | 2 +- .../src/gui/TheWire/PulseAddDialog.ui | 75 +- retroshare-gui/src/gui/TheWire/PulseReply.cpp | 4 +- retroshare-gui/src/gui/TheWire/PulseReply.ui | 13 +- .../src/gui/TheWire/PulseTopLevel.cpp | 6 +- .../src/gui/TheWire/PulseTopLevel.ui | 89 +- .../src/gui/TheWire/PulseViewGroup.cpp | 2 +- .../src/gui/TheWire/PulseViewGroup.ui | 75 +- retroshare-gui/src/gui/TheWire/WireDialog.cpp | 98 +- retroshare-gui/src/gui/TheWire/WireDialog.h | 12 +- retroshare-gui/src/gui/TheWire/WireDialog.ui | 44 +- .../src/gui/WikiPoos/WikiAddDialog.ui | 17 +- .../src/gui/WikiPoos/WikiEditDialog.cpp | 36 +- .../src/gui/WikiPoos/WikiEditDialog.ui | 48 +- .../src/gui/advsearch/AdvancedSearchDialog.ui | 85 +- .../gui/advsearch/advancedsearchdialog.cpp | 122 +- .../src/gui/advsearch/advancedsearchdialog.h | 10 +- .../src/gui/advsearch/expressionwidget.cpp | 159 +- .../src/gui/advsearch/expressionwidget.h | 24 +- .../src/gui/advsearch/expressionwidget.ui | 134 +- .../src/gui/advsearch/guiexprelement.cpp | 485 +-- .../src/gui/advsearch/guiexprelement.h | 42 +- .../src/gui/chat/ChatLobbyDialog.ui | 8 +- retroshare-gui/src/gui/chat/ChatWidget.cpp | 20 +- retroshare-gui/src/gui/chat/ChatWidget.ui | 84 +- .../src/gui/chat/CreateLobbyDialog.ui | 42 +- .../src/gui/chat/PopupChatWindow.cpp | 4 +- .../src/gui/chat/PopupChatWindow.ui | 2 +- .../src/gui/common/AvatarDialog.cpp | 4 +- retroshare-gui/src/gui/common/AvatarDialog.ui | 26 +- retroshare-gui/src/gui/common/Emoticons.cpp | 5 +- retroshare-gui/src/gui/common/FriendList.h | 2 +- .../src/gui/common/FriendListModel.h | 2 +- .../src/gui/common/FriendSelectionWidget.h | 2 +- .../src/gui/common/GroupChooser.cpp | 9 +- retroshare-gui/src/gui/common/GroupChooser.h | 7 +- .../src/gui/common/GroupTreeWidget.h | 2 +- retroshare-gui/src/gui/common/HeaderFrame.ui | 32 +- .../src/gui/common/LineEditClear.cpp | 54 +- retroshare-gui/src/gui/common/LineEditClear.h | 1 + .../src/gui/common/NewFriendList.cpp | 4 +- .../src/gui/common/NewFriendList.ui | 13 +- .../{StyledElidedLabel.cpp => RSComboBox.cpp} | 53 +- .../common/{StyledLabel.h => RSComboBox.h} | 26 +- .../src/gui/common/RSElidedItemDelegate.cpp | 6 +- .../src/gui/common/RSImageBlockWidget.cpp | 2 +- .../src/gui/common/RSImageBlockWidget.ui | 31 +- .../src/gui/common/RsCollectionDialog.ui | 18 +- .../src/gui/common/StyledElidedLabel.h | 42 - retroshare-gui/src/gui/common/StyledLabel.cpp | 49 - .../src/gui/connect/ConfCertDialog.ui | 8 +- .../src/gui/connect/ConnectFriendWizard.cpp | 22 +- .../src/gui/connect/ConnectFriendWizard.ui | 92 +- .../src/gui/connect/PGPKeyDialog.ui | 37 +- .../src/gui/feeds/AttachFileItem.ui | 21 +- .../src/gui/feeds/BoardsCommentsItem.cpp | 6 +- .../src/gui/feeds/BoardsCommentsItem.ui | 41 +- .../src/gui/feeds/ChannelsCommentsItem.cpp | 20 +- .../src/gui/feeds/ChannelsCommentsItem.ui | 30 +- retroshare-gui/src/gui/feeds/ChatMsgItem.ui | 30 +- .../src/gui/feeds/GxsChannelGroupItem.ui | 59 +- .../src/gui/feeds/GxsChannelPostItem.cpp | 12 +- .../src/gui/feeds/GxsChannelPostItem.ui | 29 +- retroshare-gui/src/gui/feeds/GxsCircleItem.ui | 61 +- .../src/gui/feeds/GxsForumGroupItem.ui | 53 +- .../src/gui/feeds/GxsForumMsgItem.cpp | 16 +- .../src/gui/feeds/GxsForumMsgItem.ui | 82 +- retroshare-gui/src/gui/feeds/MsgItem.cpp | 10 +- retroshare-gui/src/gui/feeds/MsgItem.ui | 59 +- retroshare-gui/src/gui/feeds/PeerItem.ui | 52 +- .../src/gui/feeds/PostedGroupItem.ui | 54 +- .../src/gui/feeds/SecurityIpItem.ui | 333 +- retroshare-gui/src/gui/feeds/SecurityItem.ui | 65 +- retroshare-gui/src/gui/feeds/SubFileItem.ui | 10 +- retroshare-gui/src/gui/groups/CreateGroup.ui | 23 +- .../src/gui/gxs/GxsCircleChooser.cpp | 4 +- retroshare-gui/src/gui/gxs/GxsCircleChooser.h | 11 +- .../src/gui/gxs/GxsCommentContainer.ui | 16 +- .../src/gui/gxs/GxsCommentDialog.ui | 19 +- .../src/gui/gxs/GxsCreateCommentDialog.cpp | 10 +- .../src/gui/gxs/GxsCreateCommentDialog.ui | 60 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 20 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 485 +-- .../src/gui/gxs/GxsGroupFrameDialog.ui | 14 +- .../src/gui/gxs/GxsGroupShareKey.cpp | 6 +- .../src/gui/gxs/GxsGroupShareKey.ui | 27 +- retroshare-gui/src/gui/gxs/GxsIdChooser.cpp | 7 +- retroshare-gui/src/gui/gxs/GxsIdChooser.h | 11 +- .../gui/gxschannels/CreateGxsChannelMsg.cpp | 58 +- .../gui/gxschannels/CreateGxsChannelMsg.ui | 62 +- .../GxsChannelFilesStatusWidget.ui | 6 +- .../GxsChannelPostsWidgetWithModel.ui | 30 +- .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 6 +- .../src/gui/gxsforums/CreateGxsForumMsg.ui | 60 +- .../src/gui/gxsforums/GxsForumGroupDialog.cpp | 2 +- .../src/gui/gxsforums/GxsForumThreadWidget.h | 2 +- .../src/gui/gxsforums/GxsForumThreadWidget.ui | 71 +- retroshare-gui/src/gui/images.qrc | 5 +- .../src/gui/msgs/MessageComposer.cpp | 128 +- retroshare-gui/src/gui/msgs/MessageComposer.h | 4 +- .../src/gui/msgs/MessageComposer.ui | 1051 +++---- retroshare-gui/src/gui/msgs/MessageWidget.cpp | 72 +- retroshare-gui/src/gui/msgs/MessageWidget.ui | 41 +- retroshare-gui/src/gui/msgs/MessagesDialog.h | 2 +- retroshare-gui/src/gui/msgs/MessagesDialog.ui | 46 +- .../src/gui/profile/ProfileManager.ui | 37 +- .../src/gui/profile/ProfileWidget.cpp | 4 +- .../src/gui/profile/ProfileWidget.ui | 102 +- .../src/gui/profile/StatusMessage.ui | 35 +- .../src/gui/qss/stylesheet/Standard.qss | 1231 -------- .../src/gui/qss/stylesheet/Standard_Dark.qss | 2545 ++++++++++++++++ .../src/gui/qss/stylesheet/Standard_Light.qss | 2685 +++++++++++++++++ .../src/gui/qss/stylesheet/default.qss | 420 +++ .../qdarkstyle/dark/Standard_Dark.qrc | 214 ++ .../qss/stylesheet/qdarkstyle/dark/rc/.keep | 1 + .../qdarkstyle/dark/rc/arrow_down.png | Bin 0 -> 522 bytes .../qdarkstyle/dark/rc/arrow_down@2x.png | Bin 0 -> 1025 bytes .../dark/rc/arrow_down_disabled.png | Bin 0 -> 546 bytes .../dark/rc/arrow_down_disabled@2x.png | Bin 0 -> 1068 bytes .../qdarkstyle/dark/rc/arrow_down_focus.png | Bin 0 -> 523 bytes .../dark/rc/arrow_down_focus@2x.png | Bin 0 -> 992 bytes .../qdarkstyle/dark/rc/arrow_down_pressed.png | Bin 0 -> 567 bytes .../dark/rc/arrow_down_pressed@2x.png | Bin 0 -> 1070 bytes .../qdarkstyle/dark/rc/arrow_left.png | Bin 0 -> 558 bytes .../qdarkstyle/dark/rc/arrow_left@2x.png | Bin 0 -> 1138 bytes .../dark/rc/arrow_left_disabled.png | Bin 0 -> 557 bytes .../dark/rc/arrow_left_disabled@2x.png | Bin 0 -> 1141 bytes .../qdarkstyle/dark/rc/arrow_left_focus.png | Bin 0 -> 551 bytes .../dark/rc/arrow_left_focus@2x.png | Bin 0 -> 1119 bytes .../qdarkstyle/dark/rc/arrow_left_pressed.png | Bin 0 -> 574 bytes .../dark/rc/arrow_left_pressed@2x.png | Bin 0 -> 1155 bytes .../qdarkstyle/dark/rc/arrow_right.png | Bin 0 -> 546 bytes .../qdarkstyle/dark/rc/arrow_right@2x.png | Bin 0 -> 1127 bytes .../dark/rc/arrow_right_disabled.png | Bin 0 -> 545 bytes .../dark/rc/arrow_right_disabled@2x.png | Bin 0 -> 1143 bytes .../qdarkstyle/dark/rc/arrow_right_focus.png | Bin 0 -> 541 bytes .../dark/rc/arrow_right_focus@2x.png | Bin 0 -> 1112 bytes .../dark/rc/arrow_right_pressed.png | Bin 0 -> 574 bytes .../dark/rc/arrow_right_pressed@2x.png | Bin 0 -> 1162 bytes .../qdarkstyle/dark/rc/arrow_up.png | Bin 0 -> 525 bytes .../qdarkstyle/dark/rc/arrow_up@2x.png | Bin 0 -> 1008 bytes .../qdarkstyle/dark/rc/arrow_up_disabled.png | Bin 0 -> 549 bytes .../dark/rc/arrow_up_disabled@2x.png | Bin 0 -> 1074 bytes .../qdarkstyle/dark/rc/arrow_up_focus.png | Bin 0 -> 532 bytes .../qdarkstyle/dark/rc/arrow_up_focus@2x.png | Bin 0 -> 990 bytes .../qdarkstyle/dark/rc/arrow_up_pressed.png | Bin 0 -> 554 bytes .../dark/rc/arrow_up_pressed@2x.png | Bin 0 -> 1053 bytes .../qdarkstyle/dark/rc/base_icon.png | Bin 0 -> 1256 bytes .../qdarkstyle/dark/rc/base_icon@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/dark/rc/base_icon_disabled.png | Bin 0 -> 1256 bytes .../dark/rc/base_icon_disabled@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/dark/rc/base_icon_focus.png | Bin 0 -> 1256 bytes .../qdarkstyle/dark/rc/base_icon_focus@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/dark/rc/base_icon_pressed.png | Bin 0 -> 1256 bytes .../dark/rc/base_icon_pressed@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/dark/rc/branch_closed.png | Bin 0 -> 397 bytes .../qdarkstyle/dark/rc/branch_closed@2x.png | Bin 0 -> 824 bytes .../dark/rc/branch_closed_disabled.png | Bin 0 -> 426 bytes .../dark/rc/branch_closed_disabled@2x.png | Bin 0 -> 862 bytes .../dark/rc/branch_closed_focus.png | Bin 0 -> 395 bytes .../dark/rc/branch_closed_focus@2x.png | Bin 0 -> 810 bytes .../dark/rc/branch_closed_pressed.png | Bin 0 -> 415 bytes .../dark/rc/branch_closed_pressed@2x.png | Bin 0 -> 867 bytes .../qdarkstyle/dark/rc/branch_end.png | Bin 0 -> 151 bytes .../qdarkstyle/dark/rc/branch_end@2x.png | Bin 0 -> 205 bytes .../dark/rc/branch_end_disabled.png | Bin 0 -> 152 bytes .../dark/rc/branch_end_disabled@2x.png | Bin 0 -> 205 bytes .../qdarkstyle/dark/rc/branch_end_focus.png | Bin 0 -> 149 bytes .../dark/rc/branch_end_focus@2x.png | Bin 0 -> 203 bytes .../qdarkstyle/dark/rc/branch_end_pressed.png | Bin 0 -> 152 bytes .../dark/rc/branch_end_pressed@2x.png | Bin 0 -> 204 bytes .../qdarkstyle/dark/rc/branch_line.png | Bin 0 -> 133 bytes .../qdarkstyle/dark/rc/branch_line@2x.png | Bin 0 -> 238 bytes .../dark/rc/branch_line_disabled.png | Bin 0 -> 135 bytes .../dark/rc/branch_line_disabled@2x.png | Bin 0 -> 240 bytes .../qdarkstyle/dark/rc/branch_line_focus.png | Bin 0 -> 134 bytes .../dark/rc/branch_line_focus@2x.png | Bin 0 -> 238 bytes .../dark/rc/branch_line_pressed.png | Bin 0 -> 135 bytes .../dark/rc/branch_line_pressed@2x.png | Bin 0 -> 239 bytes .../qdarkstyle/dark/rc/branch_more.png | Bin 0 -> 166 bytes .../qdarkstyle/dark/rc/branch_more@2x.png | Bin 0 -> 260 bytes .../dark/rc/branch_more_disabled.png | Bin 0 -> 167 bytes .../dark/rc/branch_more_disabled@2x.png | Bin 0 -> 263 bytes .../qdarkstyle/dark/rc/branch_more_focus.png | Bin 0 -> 164 bytes .../dark/rc/branch_more_focus@2x.png | Bin 0 -> 260 bytes .../dark/rc/branch_more_pressed.png | Bin 0 -> 161 bytes .../dark/rc/branch_more_pressed@2x.png | Bin 0 -> 262 bytes .../qdarkstyle/dark/rc/branch_open.png | Bin 0 -> 404 bytes .../qdarkstyle/dark/rc/branch_open@2x.png | Bin 0 -> 813 bytes .../dark/rc/branch_open_disabled.png | Bin 0 -> 422 bytes .../dark/rc/branch_open_disabled@2x.png | Bin 0 -> 872 bytes .../qdarkstyle/dark/rc/branch_open_focus.png | Bin 0 -> 396 bytes .../dark/rc/branch_open_focus@2x.png | Bin 0 -> 791 bytes .../dark/rc/branch_open_pressed.png | Bin 0 -> 421 bytes .../dark/rc/branch_open_pressed@2x.png | Bin 0 -> 860 bytes .../qdarkstyle/dark/rc/checkbox_checked.png | Bin 0 -> 650 bytes .../dark/rc/checkbox_checked@2x.png | Bin 0 -> 1255 bytes .../dark/rc/checkbox_checked_disabled.png | Bin 0 -> 731 bytes .../dark/rc/checkbox_checked_disabled@2x.png | Bin 0 -> 1334 bytes .../dark/rc/checkbox_checked_focus.png | Bin 0 -> 655 bytes .../dark/rc/checkbox_checked_focus@2x.png | Bin 0 -> 1269 bytes .../dark/rc/checkbox_checked_pressed.png | Bin 0 -> 704 bytes .../dark/rc/checkbox_checked_pressed@2x.png | Bin 0 -> 1319 bytes .../dark/rc/checkbox_indeterminate.png | Bin 0 -> 476 bytes .../dark/rc/checkbox_indeterminate@2x.png | Bin 0 -> 955 bytes .../rc/checkbox_indeterminate_disabled.png | Bin 0 -> 545 bytes .../rc/checkbox_indeterminate_disabled@2x.png | Bin 0 -> 1003 bytes .../dark/rc/checkbox_indeterminate_focus.png | Bin 0 -> 466 bytes .../rc/checkbox_indeterminate_focus@2x.png | Bin 0 -> 930 bytes .../rc/checkbox_indeterminate_pressed.png | Bin 0 -> 518 bytes .../rc/checkbox_indeterminate_pressed@2x.png | Bin 0 -> 995 bytes .../qdarkstyle/dark/rc/checkbox_unchecked.png | Bin 0 -> 393 bytes .../dark/rc/checkbox_unchecked@2x.png | Bin 0 -> 846 bytes .../dark/rc/checkbox_unchecked_disabled.png | Bin 0 -> 391 bytes .../rc/checkbox_unchecked_disabled@2x.png | Bin 0 -> 868 bytes .../dark/rc/checkbox_unchecked_focus.png | Bin 0 -> 387 bytes .../dark/rc/checkbox_unchecked_focus@2x.png | Bin 0 -> 850 bytes .../dark/rc/checkbox_unchecked_pressed.png | Bin 0 -> 403 bytes .../dark/rc/checkbox_unchecked_pressed@2x.png | Bin 0 -> 862 bytes .../qdarkstyle/dark/rc/line_horizontal.png | Bin 0 -> 120 bytes .../qdarkstyle/dark/rc/line_horizontal@2x.png | Bin 0 -> 137 bytes .../dark/rc/line_horizontal_disabled.png | Bin 0 -> 121 bytes .../dark/rc/line_horizontal_disabled@2x.png | Bin 0 -> 139 bytes .../dark/rc/line_horizontal_focus.png | Bin 0 -> 119 bytes .../dark/rc/line_horizontal_focus@2x.png | Bin 0 -> 137 bytes .../dark/rc/line_horizontal_pressed.png | Bin 0 -> 120 bytes .../dark/rc/line_horizontal_pressed@2x.png | Bin 0 -> 138 bytes .../qdarkstyle/dark/rc/line_vertical.png | Bin 0 -> 133 bytes .../qdarkstyle/dark/rc/line_vertical@2x.png | Bin 0 -> 246 bytes .../dark/rc/line_vertical_disabled.png | Bin 0 -> 135 bytes .../dark/rc/line_vertical_disabled@2x.png | Bin 0 -> 249 bytes .../dark/rc/line_vertical_focus.png | Bin 0 -> 133 bytes .../dark/rc/line_vertical_focus@2x.png | Bin 0 -> 246 bytes .../dark/rc/line_vertical_pressed.png | Bin 0 -> 134 bytes .../dark/rc/line_vertical_pressed@2x.png | Bin 0 -> 248 bytes .../qdarkstyle/dark/rc/radio_checked.png | Bin 0 -> 1258 bytes .../qdarkstyle/dark/rc/radio_checked@2x.png | Bin 0 -> 2702 bytes .../dark/rc/radio_checked_disabled.png | Bin 0 -> 1336 bytes .../dark/rc/radio_checked_disabled@2x.png | Bin 0 -> 2871 bytes .../dark/rc/radio_checked_focus.png | Bin 0 -> 1232 bytes .../dark/rc/radio_checked_focus@2x.png | Bin 0 -> 2656 bytes .../dark/rc/radio_checked_pressed.png | Bin 0 -> 1288 bytes .../dark/rc/radio_checked_pressed@2x.png | Bin 0 -> 2804 bytes .../qdarkstyle/dark/rc/radio_unchecked.png | Bin 0 -> 1012 bytes .../qdarkstyle/dark/rc/radio_unchecked@2x.png | Bin 0 -> 2156 bytes .../dark/rc/radio_unchecked_disabled.png | Bin 0 -> 1045 bytes .../dark/rc/radio_unchecked_disabled@2x.png | Bin 0 -> 2277 bytes .../dark/rc/radio_unchecked_focus.png | Bin 0 -> 979 bytes .../dark/rc/radio_unchecked_focus@2x.png | Bin 0 -> 2127 bytes .../dark/rc/radio_unchecked_pressed.png | Bin 0 -> 1027 bytes .../dark/rc/radio_unchecked_pressed@2x.png | Bin 0 -> 2263 bytes .../dark/rc/toolbar_move_horizontal.png | Bin 0 -> 154 bytes .../dark/rc/toolbar_move_horizontal@2x.png | Bin 0 -> 304 bytes .../rc/toolbar_move_horizontal_disabled.png | Bin 0 -> 155 bytes .../toolbar_move_horizontal_disabled@2x.png | Bin 0 -> 309 bytes .../dark/rc/toolbar_move_horizontal_focus.png | Bin 0 -> 154 bytes .../rc/toolbar_move_horizontal_focus@2x.png | Bin 0 -> 305 bytes .../rc/toolbar_move_horizontal_pressed.png | Bin 0 -> 155 bytes .../rc/toolbar_move_horizontal_pressed@2x.png | Bin 0 -> 308 bytes .../dark/rc/toolbar_move_vertical.png | Bin 0 -> 141 bytes .../dark/rc/toolbar_move_vertical@2x.png | Bin 0 -> 208 bytes .../rc/toolbar_move_vertical_disabled.png | Bin 0 -> 140 bytes .../rc/toolbar_move_vertical_disabled@2x.png | Bin 0 -> 214 bytes .../dark/rc/toolbar_move_vertical_focus.png | Bin 0 -> 139 bytes .../rc/toolbar_move_vertical_focus@2x.png | Bin 0 -> 211 bytes .../dark/rc/toolbar_move_vertical_pressed.png | Bin 0 -> 143 bytes .../rc/toolbar_move_vertical_pressed@2x.png | Bin 0 -> 209 bytes .../dark/rc/toolbar_separator_horizontal.png | Bin 0 -> 151 bytes .../rc/toolbar_separator_horizontal@2x.png | Bin 0 -> 288 bytes .../toolbar_separator_horizontal_disabled.png | Bin 0 -> 151 bytes ...olbar_separator_horizontal_disabled@2x.png | Bin 0 -> 291 bytes .../rc/toolbar_separator_horizontal_focus.png | Bin 0 -> 149 bytes .../toolbar_separator_horizontal_focus@2x.png | Bin 0 -> 288 bytes .../toolbar_separator_horizontal_pressed.png | Bin 0 -> 151 bytes ...oolbar_separator_horizontal_pressed@2x.png | Bin 0 -> 294 bytes .../dark/rc/toolbar_separator_vertical.png | Bin 0 -> 137 bytes .../dark/rc/toolbar_separator_vertical@2x.png | Bin 0 -> 192 bytes .../toolbar_separator_vertical_disabled.png | Bin 0 -> 136 bytes ...toolbar_separator_vertical_disabled@2x.png | Bin 0 -> 200 bytes .../rc/toolbar_separator_vertical_focus.png | Bin 0 -> 135 bytes .../toolbar_separator_vertical_focus@2x.png | Bin 0 -> 197 bytes .../rc/toolbar_separator_vertical_pressed.png | Bin 0 -> 138 bytes .../toolbar_separator_vertical_pressed@2x.png | Bin 0 -> 196 bytes .../qdarkstyle/dark/rc/transparent.png | Bin 0 -> 104 bytes .../qdarkstyle/dark/rc/transparent@2x.png | Bin 0 -> 117 bytes .../dark/rc/transparent_disabled.png | Bin 0 -> 104 bytes .../dark/rc/transparent_disabled@2x.png | Bin 0 -> 117 bytes .../qdarkstyle/dark/rc/transparent_focus.png | Bin 0 -> 104 bytes .../dark/rc/transparent_focus@2x.png | Bin 0 -> 117 bytes .../dark/rc/transparent_pressed.png | Bin 0 -> 104 bytes .../dark/rc/transparent_pressed@2x.png | Bin 0 -> 117 bytes .../qdarkstyle/dark/rc/window_close.png | Bin 0 -> 714 bytes .../qdarkstyle/dark/rc/window_close@2x.png | Bin 0 -> 1637 bytes .../dark/rc/window_close_disabled.png | Bin 0 -> 820 bytes .../dark/rc/window_close_disabled@2x.png | Bin 0 -> 1717 bytes .../qdarkstyle/dark/rc/window_close_focus.png | Bin 0 -> 728 bytes .../dark/rc/window_close_focus@2x.png | Bin 0 -> 1659 bytes .../dark/rc/window_close_pressed.png | Bin 0 -> 744 bytes .../dark/rc/window_close_pressed@2x.png | Bin 0 -> 1777 bytes .../qdarkstyle/dark/rc/window_grip.png | Bin 0 -> 434 bytes .../qdarkstyle/dark/rc/window_grip@2x.png | Bin 0 -> 708 bytes .../dark/rc/window_grip_disabled.png | Bin 0 -> 434 bytes .../dark/rc/window_grip_disabled@2x.png | Bin 0 -> 764 bytes .../qdarkstyle/dark/rc/window_grip_focus.png | Bin 0 -> 408 bytes .../dark/rc/window_grip_focus@2x.png | Bin 0 -> 730 bytes .../dark/rc/window_grip_pressed.png | Bin 0 -> 455 bytes .../dark/rc/window_grip_pressed@2x.png | Bin 0 -> 747 bytes .../qdarkstyle/dark/rc/window_minimize.png | Bin 0 -> 200 bytes .../qdarkstyle/dark/rc/window_minimize@2x.png | Bin 0 -> 327 bytes .../dark/rc/window_minimize_disabled.png | Bin 0 -> 207 bytes .../dark/rc/window_minimize_disabled@2x.png | Bin 0 -> 336 bytes .../dark/rc/window_minimize_focus.png | Bin 0 -> 206 bytes .../dark/rc/window_minimize_focus@2x.png | Bin 0 -> 333 bytes .../dark/rc/window_minimize_pressed.png | Bin 0 -> 210 bytes .../dark/rc/window_minimize_pressed@2x.png | Bin 0 -> 337 bytes .../qdarkstyle/dark/rc/window_undock.png | Bin 0 -> 517 bytes .../qdarkstyle/dark/rc/window_undock@2x.png | Bin 0 -> 865 bytes .../dark/rc/window_undock_disabled.png | Bin 0 -> 536 bytes .../dark/rc/window_undock_disabled@2x.png | Bin 0 -> 924 bytes .../dark/rc/window_undock_focus.png | Bin 0 -> 503 bytes .../dark/rc/window_undock_focus@2x.png | Bin 0 -> 866 bytes .../dark/rc/window_undock_pressed.png | Bin 0 -> 539 bytes .../dark/rc/window_undock_pressed@2x.png | Bin 0 -> 905 bytes .../qdarkstyle/light/Standard_Light.qrc | 214 ++ .../qss/stylesheet/qdarkstyle/light/rc/.keep | 1 + .../qdarkstyle/light/rc/arrow_down.png | Bin 0 -> 552 bytes .../qdarkstyle/light/rc/arrow_down@2x.png | Bin 0 -> 1014 bytes .../light/rc/arrow_down_disabled.png | Bin 0 -> 524 bytes .../light/rc/arrow_down_disabled@2x.png | Bin 0 -> 1042 bytes .../qdarkstyle/light/rc/arrow_down_focus.png | Bin 0 -> 523 bytes .../light/rc/arrow_down_focus@2x.png | Bin 0 -> 1005 bytes .../light/rc/arrow_down_pressed.png | Bin 0 -> 508 bytes .../light/rc/arrow_down_pressed@2x.png | Bin 0 -> 964 bytes .../qdarkstyle/light/rc/arrow_left.png | Bin 0 -> 549 bytes .../qdarkstyle/light/rc/arrow_left@2x.png | Bin 0 -> 1081 bytes .../light/rc/arrow_left_disabled.png | Bin 0 -> 562 bytes .../light/rc/arrow_left_disabled@2x.png | Bin 0 -> 1158 bytes .../qdarkstyle/light/rc/arrow_left_focus.png | Bin 0 -> 560 bytes .../light/rc/arrow_left_focus@2x.png | Bin 0 -> 1138 bytes .../light/rc/arrow_left_pressed.png | Bin 0 -> 529 bytes .../light/rc/arrow_left_pressed@2x.png | Bin 0 -> 1107 bytes .../qdarkstyle/light/rc/arrow_right.png | Bin 0 -> 532 bytes .../qdarkstyle/light/rc/arrow_right@2x.png | Bin 0 -> 1099 bytes .../light/rc/arrow_right_disabled.png | Bin 0 -> 549 bytes .../light/rc/arrow_right_disabled@2x.png | Bin 0 -> 1168 bytes .../qdarkstyle/light/rc/arrow_right_focus.png | Bin 0 -> 542 bytes .../light/rc/arrow_right_focus@2x.png | Bin 0 -> 1137 bytes .../light/rc/arrow_right_pressed.png | Bin 0 -> 529 bytes .../light/rc/arrow_right_pressed@2x.png | Bin 0 -> 1098 bytes .../qdarkstyle/light/rc/arrow_up.png | Bin 0 -> 529 bytes .../qdarkstyle/light/rc/arrow_up@2x.png | Bin 0 -> 998 bytes .../qdarkstyle/light/rc/arrow_up_disabled.png | Bin 0 -> 521 bytes .../light/rc/arrow_up_disabled@2x.png | Bin 0 -> 1044 bytes .../qdarkstyle/light/rc/arrow_up_focus.png | Bin 0 -> 519 bytes .../qdarkstyle/light/rc/arrow_up_focus@2x.png | Bin 0 -> 1004 bytes .../qdarkstyle/light/rc/arrow_up_pressed.png | Bin 0 -> 507 bytes .../light/rc/arrow_up_pressed@2x.png | Bin 0 -> 978 bytes .../qdarkstyle/light/rc/base_icon.png | Bin 0 -> 1256 bytes .../qdarkstyle/light/rc/base_icon@2x.png | Bin 0 -> 3286 bytes .../light/rc/base_icon_disabled.png | Bin 0 -> 1256 bytes .../light/rc/base_icon_disabled@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/light/rc/base_icon_focus.png | Bin 0 -> 1256 bytes .../light/rc/base_icon_focus@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/light/rc/base_icon_pressed.png | Bin 0 -> 1256 bytes .../light/rc/base_icon_pressed@2x.png | Bin 0 -> 3286 bytes .../qdarkstyle/light/rc/branch_closed.png | Bin 0 -> 401 bytes .../qdarkstyle/light/rc/branch_closed@2x.png | Bin 0 -> 838 bytes .../light/rc/branch_closed_disabled.png | Bin 0 -> 415 bytes .../light/rc/branch_closed_disabled@2x.png | Bin 0 -> 847 bytes .../light/rc/branch_closed_focus.png | Bin 0 -> 406 bytes .../light/rc/branch_closed_focus@2x.png | Bin 0 -> 841 bytes .../light/rc/branch_closed_pressed.png | Bin 0 -> 389 bytes .../light/rc/branch_closed_pressed@2x.png | Bin 0 -> 804 bytes .../qdarkstyle/light/rc/branch_end.png | Bin 0 -> 148 bytes .../qdarkstyle/light/rc/branch_end@2x.png | Bin 0 -> 206 bytes .../light/rc/branch_end_disabled.png | Bin 0 -> 149 bytes .../light/rc/branch_end_disabled@2x.png | Bin 0 -> 205 bytes .../qdarkstyle/light/rc/branch_end_focus.png | Bin 0 -> 152 bytes .../light/rc/branch_end_focus@2x.png | Bin 0 -> 204 bytes .../light/rc/branch_end_pressed.png | Bin 0 -> 147 bytes .../light/rc/branch_end_pressed@2x.png | Bin 0 -> 202 bytes .../qdarkstyle/light/rc/branch_line.png | Bin 0 -> 134 bytes .../qdarkstyle/light/rc/branch_line@2x.png | Bin 0 -> 240 bytes .../light/rc/branch_line_disabled.png | Bin 0 -> 134 bytes .../light/rc/branch_line_disabled@2x.png | Bin 0 -> 240 bytes .../qdarkstyle/light/rc/branch_line_focus.png | Bin 0 -> 135 bytes .../light/rc/branch_line_focus@2x.png | Bin 0 -> 239 bytes .../light/rc/branch_line_pressed.png | Bin 0 -> 134 bytes .../light/rc/branch_line_pressed@2x.png | Bin 0 -> 239 bytes .../qdarkstyle/light/rc/branch_more.png | Bin 0 -> 167 bytes .../qdarkstyle/light/rc/branch_more@2x.png | Bin 0 -> 263 bytes .../light/rc/branch_more_disabled.png | Bin 0 -> 161 bytes .../light/rc/branch_more_disabled@2x.png | Bin 0 -> 262 bytes .../qdarkstyle/light/rc/branch_more_focus.png | Bin 0 -> 168 bytes .../light/rc/branch_more_focus@2x.png | Bin 0 -> 263 bytes .../light/rc/branch_more_pressed.png | Bin 0 -> 162 bytes .../light/rc/branch_more_pressed@2x.png | Bin 0 -> 259 bytes .../qdarkstyle/light/rc/branch_open.png | Bin 0 -> 440 bytes .../qdarkstyle/light/rc/branch_open@2x.png | Bin 0 -> 875 bytes .../light/rc/branch_open_disabled.png | Bin 0 -> 416 bytes .../light/rc/branch_open_disabled@2x.png | Bin 0 -> 816 bytes .../qdarkstyle/light/rc/branch_open_focus.png | Bin 0 -> 426 bytes .../light/rc/branch_open_focus@2x.png | Bin 0 -> 837 bytes .../light/rc/branch_open_pressed.png | Bin 0 -> 399 bytes .../light/rc/branch_open_pressed@2x.png | Bin 0 -> 778 bytes .../qdarkstyle/light/rc/checkbox_checked.png | Bin 0 -> 719 bytes .../light/rc/checkbox_checked@2x.png | Bin 0 -> 1329 bytes .../light/rc/checkbox_checked_disabled.png | Bin 0 -> 667 bytes .../light/rc/checkbox_checked_disabled@2x.png | Bin 0 -> 1280 bytes .../light/rc/checkbox_checked_focus.png | Bin 0 -> 696 bytes .../light/rc/checkbox_checked_focus@2x.png | Bin 0 -> 1278 bytes .../light/rc/checkbox_checked_pressed.png | Bin 0 -> 653 bytes .../light/rc/checkbox_checked_pressed@2x.png | Bin 0 -> 1254 bytes .../light/rc/checkbox_indeterminate.png | Bin 0 -> 524 bytes .../light/rc/checkbox_indeterminate@2x.png | Bin 0 -> 1024 bytes .../rc/checkbox_indeterminate_disabled.png | Bin 0 -> 482 bytes .../rc/checkbox_indeterminate_disabled@2x.png | Bin 0 -> 948 bytes .../light/rc/checkbox_indeterminate_focus.png | Bin 0 -> 501 bytes .../rc/checkbox_indeterminate_focus@2x.png | Bin 0 -> 962 bytes .../rc/checkbox_indeterminate_pressed.png | Bin 0 -> 460 bytes .../rc/checkbox_indeterminate_pressed@2x.png | Bin 0 -> 943 bytes .../light/rc/checkbox_unchecked.png | Bin 0 -> 385 bytes .../light/rc/checkbox_unchecked@2x.png | Bin 0 -> 855 bytes .../light/rc/checkbox_unchecked_disabled.png | Bin 0 -> 385 bytes .../rc/checkbox_unchecked_disabled@2x.png | Bin 0 -> 878 bytes .../light/rc/checkbox_unchecked_focus.png | Bin 0 -> 384 bytes .../light/rc/checkbox_unchecked_focus@2x.png | Bin 0 -> 873 bytes .../light/rc/checkbox_unchecked_pressed.png | Bin 0 -> 385 bytes .../rc/checkbox_unchecked_pressed@2x.png | Bin 0 -> 843 bytes .../qdarkstyle/light/rc/line_horizontal.png | Bin 0 -> 121 bytes .../light/rc/line_horizontal@2x.png | Bin 0 -> 139 bytes .../light/rc/line_horizontal_disabled.png | Bin 0 -> 121 bytes .../light/rc/line_horizontal_disabled@2x.png | Bin 0 -> 139 bytes .../light/rc/line_horizontal_focus.png | Bin 0 -> 120 bytes .../light/rc/line_horizontal_focus@2x.png | Bin 0 -> 138 bytes .../light/rc/line_horizontal_pressed.png | Bin 0 -> 120 bytes .../light/rc/line_horizontal_pressed@2x.png | Bin 0 -> 138 bytes .../qdarkstyle/light/rc/line_vertical.png | Bin 0 -> 134 bytes .../qdarkstyle/light/rc/line_vertical@2x.png | Bin 0 -> 248 bytes .../light/rc/line_vertical_disabled.png | Bin 0 -> 134 bytes .../light/rc/line_vertical_disabled@2x.png | Bin 0 -> 248 bytes .../light/rc/line_vertical_focus.png | Bin 0 -> 134 bytes .../light/rc/line_vertical_focus@2x.png | Bin 0 -> 249 bytes .../light/rc/line_vertical_pressed.png | Bin 0 -> 133 bytes .../light/rc/line_vertical_pressed@2x.png | Bin 0 -> 246 bytes .../qdarkstyle/light/rc/radio_checked.png | Bin 0 -> 1293 bytes .../qdarkstyle/light/rc/radio_checked@2x.png | Bin 0 -> 2792 bytes .../light/rc/radio_checked_disabled.png | Bin 0 -> 1289 bytes .../light/rc/radio_checked_disabled@2x.png | Bin 0 -> 2752 bytes .../light/rc/radio_checked_focus.png | Bin 0 -> 1292 bytes .../light/rc/radio_checked_focus@2x.png | Bin 0 -> 2772 bytes .../light/rc/radio_checked_pressed.png | Bin 0 -> 1210 bytes .../light/rc/radio_checked_pressed@2x.png | Bin 0 -> 2580 bytes .../qdarkstyle/light/rc/radio_unchecked.png | Bin 0 -> 1008 bytes .../light/rc/radio_unchecked@2x.png | Bin 0 -> 2256 bytes .../light/rc/radio_unchecked_disabled.png | Bin 0 -> 1022 bytes .../light/rc/radio_unchecked_disabled@2x.png | Bin 0 -> 2205 bytes .../light/rc/radio_unchecked_focus.png | Bin 0 -> 1032 bytes .../light/rc/radio_unchecked_focus@2x.png | Bin 0 -> 2215 bytes .../light/rc/radio_unchecked_pressed.png | Bin 0 -> 978 bytes .../light/rc/radio_unchecked_pressed@2x.png | Bin 0 -> 2079 bytes .../light/rc/toolbar_move_horizontal.png | Bin 0 -> 153 bytes .../light/rc/toolbar_move_horizontal@2x.png | Bin 0 -> 306 bytes .../rc/toolbar_move_horizontal_disabled.png | Bin 0 -> 155 bytes .../toolbar_move_horizontal_disabled@2x.png | Bin 0 -> 310 bytes .../rc/toolbar_move_horizontal_focus.png | Bin 0 -> 155 bytes .../rc/toolbar_move_horizontal_focus@2x.png | Bin 0 -> 307 bytes .../rc/toolbar_move_horizontal_pressed.png | Bin 0 -> 154 bytes .../rc/toolbar_move_horizontal_pressed@2x.png | Bin 0 -> 305 bytes .../light/rc/toolbar_move_vertical.png | Bin 0 -> 142 bytes .../light/rc/toolbar_move_vertical@2x.png | Bin 0 -> 209 bytes .../rc/toolbar_move_vertical_disabled.png | Bin 0 -> 142 bytes .../rc/toolbar_move_vertical_disabled@2x.png | Bin 0 -> 214 bytes .../light/rc/toolbar_move_vertical_focus.png | Bin 0 -> 144 bytes .../rc/toolbar_move_vertical_focus@2x.png | Bin 0 -> 213 bytes .../rc/toolbar_move_vertical_pressed.png | Bin 0 -> 139 bytes .../rc/toolbar_move_vertical_pressed@2x.png | Bin 0 -> 206 bytes .../light/rc/toolbar_separator_horizontal.png | Bin 0 -> 148 bytes .../rc/toolbar_separator_horizontal@2x.png | Bin 0 -> 288 bytes .../toolbar_separator_horizontal_disabled.png | Bin 0 -> 152 bytes ...olbar_separator_horizontal_disabled@2x.png | Bin 0 -> 292 bytes .../rc/toolbar_separator_horizontal_focus.png | Bin 0 -> 151 bytes .../toolbar_separator_horizontal_focus@2x.png | Bin 0 -> 290 bytes .../toolbar_separator_horizontal_pressed.png | Bin 0 -> 150 bytes ...oolbar_separator_horizontal_pressed@2x.png | Bin 0 -> 290 bytes .../light/rc/toolbar_separator_vertical.png | Bin 0 -> 137 bytes .../rc/toolbar_separator_vertical@2x.png | Bin 0 -> 194 bytes .../toolbar_separator_vertical_disabled.png | Bin 0 -> 138 bytes ...toolbar_separator_vertical_disabled@2x.png | Bin 0 -> 199 bytes .../rc/toolbar_separator_vertical_focus.png | Bin 0 -> 141 bytes .../toolbar_separator_vertical_focus@2x.png | Bin 0 -> 199 bytes .../rc/toolbar_separator_vertical_pressed.png | Bin 0 -> 135 bytes .../toolbar_separator_vertical_pressed@2x.png | Bin 0 -> 192 bytes .../qdarkstyle/light/rc/transparent.png | Bin 0 -> 104 bytes .../qdarkstyle/light/rc/transparent@2x.png | Bin 0 -> 117 bytes .../light/rc/transparent_disabled.png | Bin 0 -> 104 bytes .../light/rc/transparent_disabled@2x.png | Bin 0 -> 117 bytes .../qdarkstyle/light/rc/transparent_focus.png | Bin 0 -> 104 bytes .../light/rc/transparent_focus@2x.png | Bin 0 -> 117 bytes .../light/rc/transparent_pressed.png | Bin 0 -> 104 bytes .../light/rc/transparent_pressed@2x.png | Bin 0 -> 117 bytes .../qdarkstyle/light/rc/window_close.png | Bin 0 -> 814 bytes .../qdarkstyle/light/rc/window_close@2x.png | Bin 0 -> 1727 bytes .../light/rc/window_close_disabled.png | Bin 0 -> 745 bytes .../light/rc/window_close_disabled@2x.png | Bin 0 -> 1682 bytes .../light/rc/window_close_focus.png | Bin 0 -> 716 bytes .../light/rc/window_close_focus@2x.png | Bin 0 -> 1709 bytes .../light/rc/window_close_pressed.png | Bin 0 -> 714 bytes .../light/rc/window_close_pressed@2x.png | Bin 0 -> 1644 bytes .../qdarkstyle/light/rc/window_grip.png | Bin 0 -> 415 bytes .../qdarkstyle/light/rc/window_grip@2x.png | Bin 0 -> 766 bytes .../light/rc/window_grip_disabled.png | Bin 0 -> 438 bytes .../light/rc/window_grip_disabled@2x.png | Bin 0 -> 728 bytes .../qdarkstyle/light/rc/window_grip_focus.png | Bin 0 -> 427 bytes .../light/rc/window_grip_focus@2x.png | Bin 0 -> 744 bytes .../light/rc/window_grip_pressed.png | Bin 0 -> 440 bytes .../light/rc/window_grip_pressed@2x.png | Bin 0 -> 711 bytes .../qdarkstyle/light/rc/window_minimize.png | Bin 0 -> 200 bytes .../light/rc/window_minimize@2x.png | Bin 0 -> 334 bytes .../light/rc/window_minimize_disabled.png | Bin 0 -> 206 bytes .../light/rc/window_minimize_disabled@2x.png | Bin 0 -> 332 bytes .../light/rc/window_minimize_focus.png | Bin 0 -> 204 bytes .../light/rc/window_minimize_focus@2x.png | Bin 0 -> 333 bytes .../light/rc/window_minimize_pressed.png | Bin 0 -> 202 bytes .../light/rc/window_minimize_pressed@2x.png | Bin 0 -> 327 bytes .../qdarkstyle/light/rc/window_undock.png | Bin 0 -> 522 bytes .../qdarkstyle/light/rc/window_undock@2x.png | Bin 0 -> 907 bytes .../light/rc/window_undock_disabled.png | Bin 0 -> 505 bytes .../light/rc/window_undock_disabled@2x.png | Bin 0 -> 881 bytes .../light/rc/window_undock_focus.png | Bin 0 -> 531 bytes .../light/rc/window_undock_focus@2x.png | Bin 0 -> 876 bytes .../light/rc/window_undock_pressed.png | Bin 0 -> 499 bytes .../light/rc/window_undock_pressed@2x.png | Bin 0 -> 855 bytes .../src/gui/qss/stylesheet/qss.default | 275 -- .../src/gui/settings/AppearancePage.cpp | 70 +- .../src/gui/settings/AppearancePage.ui | 19 +- retroshare-gui/src/gui/settings/ChatPage.cpp | 54 +- retroshare-gui/src/gui/settings/ChatPage.ui | 91 +- retroshare-gui/src/gui/settings/CryptoPage.ui | 16 +- .../src/gui/settings/MessagePage.ui | 11 +- retroshare-gui/src/gui/settings/NotifyPage.ui | 9 +- retroshare-gui/src/gui/settings/PluginItem.ui | 53 +- .../src/gui/settings/ServerPage.cpp | 8 +- retroshare-gui/src/gui/settings/ServerPage.ui | 676 ++++- .../gui/settings/ServicePermissionsPage.cpp | 4 +- .../gui/settings/ServicePermissionsPage.ui | 10 +- .../src/gui/settings/TransferPage.ui | 13 +- .../src/gui/settings/rsettingswin.cpp | 4 +- .../src/gui/settings/rsettingswin.h | 4 +- .../src/gui/settings/rsharesettings.cpp | 2 +- retroshare-gui/src/gui/settings/settings.ui | 12 +- retroshare-gui/src/gui/settings/settingsw.ui | 12 +- .../gui/statistics/BandwidthStatsWidget.ui | 17 +- .../src/gui/statusbar/OpModeStatus.cpp | 2 +- .../src/gui/statusbar/OpModeStatus.h | 4 +- retroshare-gui/src/gui/style/StyleDialog.ui | 7 +- .../src/gui/toaster/ChatLobbyToaster.ui | 41 +- retroshare-gui/src/gui/toaster/ChatToaster.ui | 41 +- .../src/gui/toaster/DownloadToaster.ui | 41 +- .../src/gui/toaster/FriendRequestToaster.ui | 41 +- .../src/gui/toaster/GroupChatToaster.ui | 41 +- .../src/gui/toaster/MessageToaster.ui | 41 +- .../src/gui/toaster/OnlineToaster.ui | 41 +- .../src/gui/unfinished/ApplicationWindow.ui | 27 + .../src/gui/unfinished/CalDialog.ui | 202 +- .../src/gui/unfinished/GamesDialog.ui | 9 +- .../src/gui/unfinished/LibraryDialog.ui | 9 +- .../src/gui/unfinished/PhotoShow.ui | 13 +- .../src/gui/unfinished/StatisticDialog.ui | 98 +- .../src/gui/unfinished/profile/ProfileEdit.ui | 144 +- .../src/qss/blacknight/check_sel.png | Bin 317 -> 0 bytes .../src/qss/blacknight/check_unsel.png | Bin 301 -> 0 bytes retroshare-gui/src/qss/blacknight/clbg.png | Bin 200 -> 0 bytes retroshare-gui/src/qss/blacknight/down.png | Bin 113 -> 0 bytes .../src/qss/blacknight/radio_sel.png | Bin 697 -> 0 bytes .../src/qss/blacknight/radio_unsel.png | Bin 656 -> 0 bytes retroshare-gui/src/qss/blacknight/up.png | Bin 116 -> 0 bytes retroshare-gui/src/qss/blue.qss | 199 -- retroshare-gui/src/qss/blue/blue.png | Bin 313 -> 0 bytes retroshare-gui/src/qss/blue/blue2.png | Bin 971 -> 0 bytes retroshare-gui/src/qss/blue/tab1.png | Bin 1042 -> 0 bytes retroshare-gui/src/qss/blue/tab_hover.png | Bin 1228 -> 0 bytes retroshare-gui/src/qss/blue/tabselected.png | Bin 1052 -> 0 bytes retroshare-gui/src/qss/groove.qss | 94 - retroshare-gui/src/qss/orangesurfer.qss | 231 -- .../src/qss/orangesurfer/border.png | Bin 1003 -> 0 bytes retroshare-gui/src/qss/orangesurfer/main.png | Bin 1220 -> 0 bytes retroshare-gui/src/qss/orangesurfer/main2.png | Bin 1171 -> 0 bytes .../src/qss/orangesurfer/sizegrip.png | Bin 288 -> 0 bytes .../src/qss/orangesurfer/tab_hover.png | Bin 1228 -> 0 bytes .../src/qss/orangesurfer/tab_normal.png | Bin 1504 -> 0 bytes .../src/qss/orangesurfer/tab_pressed.png | Bin 1081 -> 0 bytes .../src/qss/orangesurfer/toolbar.png | Bin 1053 -> 0 bytes retroshare-gui/src/qss/qdarkstyle-v2.qss | 2329 -------------- retroshare-gui/src/qss/qdarkstyle.qss | 1558 ---------- .../src/qss/qdarkstyle/Hmovetoolbar.png | Bin 225 -> 0 bytes .../src/qss/qdarkstyle/Hsepartoolbar.png | Bin 206 -> 0 bytes .../src/qss/qdarkstyle/Vmovetoolbar.png | Bin 228 -> 0 bytes .../src/qss/qdarkstyle/Vsepartoolbar.png | Bin 187 -> 0 bytes .../src/qss/qdarkstyle/branch_closed-on.png | Bin 147 -> 0 bytes .../src/qss/qdarkstyle/branch_closed.png | Bin 160 -> 0 bytes .../src/qss/qdarkstyle/branch_open-on.png | Bin 150 -> 0 bytes .../src/qss/qdarkstyle/branch_open.png | Bin 166 -> 0 bytes .../src/qss/qdarkstyle/checkbox.png | Bin 343 -> 0 bytes retroshare-gui/src/qss/qdarkstyle/close.png | Bin 625 -> 0 bytes .../src/qss/qdarkstyle/down_arrow.png | Bin 165 -> 0 bytes .../qss/qdarkstyle/down_arrow_disabled.png | Bin 166 -> 0 bytes .../src/qss/qdarkstyle/left_arrow.png | Bin 166 -> 0 bytes .../qss/qdarkstyle/left_arrow_disabled.png | Bin 166 -> 0 bytes .../src/qss/qdarkstyle/rc/Hmovetoolbar.png | Bin 220 -> 0 bytes .../src/qss/qdarkstyle/rc/Hsepartoolbar.png | Bin 172 -> 0 bytes .../src/qss/qdarkstyle/rc/Vmovetoolbar.png | Bin 2847 -> 0 bytes .../src/qss/qdarkstyle/rc/Vsepartoolbar.png | Bin 2839 -> 0 bytes .../qss/qdarkstyle/rc/branch_closed-on.png | Bin 147 -> 0 bytes .../src/qss/qdarkstyle/rc/branch_closed.png | Bin 160 -> 0 bytes .../src/qss/qdarkstyle/rc/branch_open-on.png | Bin 150 -> 0 bytes .../src/qss/qdarkstyle/rc/branch_open.png | Bin 166 -> 0 bytes .../qss/qdarkstyle/rc/checkbox_checked.png | Bin 418 -> 0 bytes .../qss/qdarkstyle/rc/checkbox_checked@2x.png | Bin 850 -> 0 bytes .../rc/checkbox_checked_disabled.png | Bin 413 -> 0 bytes .../rc/checkbox_checked_disabled@2x.png | Bin 898 -> 0 bytes .../qdarkstyle/rc/checkbox_checked_focus.png | Bin 418 -> 0 bytes .../rc/checkbox_checked_focus@2x.png | Bin 888 -> 0 bytes .../qdarkstyle/rc/checkbox_indeterminate.png | Bin 424 -> 0 bytes .../rc/checkbox_indeterminate@2x.png | Bin 851 -> 0 bytes .../rc/checkbox_indeterminate_disabled.png | Bin 412 -> 0 bytes .../rc/checkbox_indeterminate_disabled@2x.png | Bin 899 -> 0 bytes .../rc/checkbox_indeterminate_focus.png | Bin 420 -> 0 bytes .../rc/checkbox_indeterminate_focus@2x.png | Bin 889 -> 0 bytes .../qss/qdarkstyle/rc/checkbox_unchecked.png | Bin 397 -> 0 bytes .../qdarkstyle/rc/checkbox_unchecked@2x.png | Bin 805 -> 0 bytes .../rc/checkbox_unchecked_disabled.png | Bin 386 -> 0 bytes .../rc/checkbox_unchecked_disabled@2x.png | Bin 855 -> 0 bytes .../rc/checkbox_unchecked_focus.png | Bin 394 -> 0 bytes .../rc/checkbox_unchecked_focus@2x.png | Bin 848 -> 0 bytes .../src/qss/qdarkstyle/rc/close-hover.png | Bin 565 -> 0 bytes .../src/qss/qdarkstyle/rc/close-pressed.png | Bin 565 -> 0 bytes .../src/qss/qdarkstyle/rc/close.png | Bin 555 -> 0 bytes .../src/qss/qdarkstyle/rc/down_arrow.png | Bin 165 -> 0 bytes .../qss/qdarkstyle/rc/down_arrow_disabled.png | Bin 166 -> 0 bytes .../src/qss/qdarkstyle/rc/left_arrow.png | Bin 166 -> 0 bytes .../qss/qdarkstyle/rc/left_arrow_disabled.png | Bin 166 -> 0 bytes .../src/qss/qdarkstyle/rc/radio_checked.png | Bin 737 -> 0 bytes .../qss/qdarkstyle/rc/radio_checked@2x.png | Bin 1703 -> 0 bytes .../qdarkstyle/rc/radio_checked_disabled.png | Bin 792 -> 0 bytes .../rc/radio_checked_disabled@2x.png | Bin 1820 -> 0 bytes .../qss/qdarkstyle/rc/radio_checked_focus.png | Bin 778 -> 0 bytes .../qdarkstyle/rc/radio_checked_focus@2x.png | Bin 1766 -> 0 bytes .../src/qss/qdarkstyle/rc/radio_unchecked.png | Bin 644 -> 0 bytes .../qss/qdarkstyle/rc/radio_unchecked@2x.png | Bin 1385 -> 0 bytes .../rc/radio_unchecked_disabled.png | Bin 673 -> 0 bytes .../rc/radio_unchecked_disabled@2x.png | Bin 1449 -> 0 bytes .../qdarkstyle/rc/radio_unchecked_focus.png | Bin 619 -> 0 bytes .../rc/radio_unchecked_focus@2x.png | Bin 1424 -> 0 bytes .../src/qss/qdarkstyle/rc/right_arrow.png | Bin 160 -> 0 bytes .../qdarkstyle/rc/right_arrow_disabled.png | Bin 160 -> 0 bytes .../src/qss/qdarkstyle/rc/sizegrip.png | Bin 129 -> 0 bytes .../qdarkstyle/rc/stylesheet-branch-end.png | Bin 224 -> 0 bytes .../qdarkstyle/rc/stylesheet-branch-more.png | Bin 182 -> 0 bytes .../qss/qdarkstyle/rc/stylesheet-vline.png | Bin 239 -> 0 bytes .../src/qss/qdarkstyle/rc/transparent.png | Bin 195 -> 0 bytes .../src/qss/qdarkstyle/rc/undock.png | Bin 553 -> 0 bytes .../src/qss/qdarkstyle/rc/up_arrow.png | Bin 158 -> 0 bytes .../qss/qdarkstyle/rc/up_arrow_disabled.png | Bin 159 -> 0 bytes .../src/qss/qdarkstyle/right_arrow.png | Bin 160 -> 0 bytes .../qss/qdarkstyle/right_arrow_disabled.png | Bin 160 -> 0 bytes .../src/qss/qdarkstyle/sizegrip.png | Bin 129 -> 0 bytes .../qss/qdarkstyle/stylesheet-branch-end.png | Bin 224 -> 0 bytes .../qss/qdarkstyle/stylesheet-branch-more.png | Bin 182 -> 0 bytes .../src/qss/qdarkstyle/stylesheet-vline.png | Bin 239 -> 0 bytes .../src/qss/qdarkstyle/transparent.png | Bin 195 -> 0 bytes retroshare-gui/src/qss/qdarkstyle/undock.png | Bin 456 -> 0 bytes .../src/qss/qdarkstyle/up_arrow.png | Bin 158 -> 0 bytes .../src/qss/qdarkstyle/up_arrow_disabled.png | Bin 159 -> 0 bytes retroshare-gui/src/qss/qlive.qss | 141 - retroshare-gui/src/qss/qlive/qb.png | Bin 1000 -> 0 bytes retroshare-gui/src/qss/qlive/qb2.png | Bin 923 -> 0 bytes retroshare-gui/src/qss/redscorpion.qss | 321 -- retroshare-gui/src/qss/redscorpion/red.png | Bin 2357 -> 0 bytes retroshare-gui/src/qss/redscorpion/red2.png | Bin 2897 -> 0 bytes retroshare-gui/src/qss/silver.qss | 164 - retroshare-gui/src/qss/silver/silver.png | Bin 306 -> 0 bytes retroshare-gui/src/qss/silver/silver2.png | Bin 971 -> 0 bytes retroshare-gui/src/qss/uus.qss | 317 -- retroshare-gui/src/qss/uus/uus.png | Bin 1146 -> 0 bytes retroshare-gui/src/qss/uus/uus2.png | Bin 1116 -> 0 bytes retroshare-gui/src/qss/yaba.qss | 228 -- retroshare-gui/src/qss/yaba/yaba.png | Bin 1082 -> 0 bytes retroshare-gui/src/qss/yaba/yaba2.png | Bin 1022 -> 0 bytes retroshare-gui/src/qss/yaba/yaba3.png | Bin 1074 -> 0 bytes retroshare-gui/src/qss/yeah.qss | 183 -- retroshare-gui/src/qss/yeah/yeah.png | Bin 579 -> 0 bytes retroshare-gui/src/retroshare-gui.pro | 11 +- retroshare-gui/src/rshare.cpp | 59 +- retroshare-gui/src/rshare.h | 8 +- retroshare-gui/src/util/RichTextEdit.ui | 9 +- 772 files changed, 12162 insertions(+), 11459 deletions(-) rename plugins/{VOIP/qss/VOIP_qss.default => FeedReader/qss/FeedReader_default.qss} (52%) rename plugins/{FeedReader/qss/FeedReader_qss.default => VOIP/qss/VOIP_default.qss} (51%) rename retroshare-gui/src/gui/common/{StyledElidedLabel.cpp => RSComboBox.cpp} (52%) rename retroshare-gui/src/gui/common/{StyledLabel.h => RSComboBox.h} (74%) delete mode 100644 retroshare-gui/src/gui/common/StyledElidedLabel.h delete mode 100644 retroshare-gui/src/gui/common/StyledLabel.cpp delete mode 100644 retroshare-gui/src/gui/qss/stylesheet/Standard.qss create mode 100644 retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss create mode 100644 retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss create mode 100644 retroshare-gui/src/gui/qss/stylesheet/default.qss create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/.keep create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus@2x.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed.png create mode 100644 retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed@2x.png delete mode 100644 retroshare-gui/src/gui/qss/stylesheet/qss.default delete mode 100644 retroshare-gui/src/qss/blacknight/check_sel.png delete mode 100644 retroshare-gui/src/qss/blacknight/check_unsel.png delete mode 100644 retroshare-gui/src/qss/blacknight/clbg.png delete mode 100644 retroshare-gui/src/qss/blacknight/down.png delete mode 100644 retroshare-gui/src/qss/blacknight/radio_sel.png delete mode 100644 retroshare-gui/src/qss/blacknight/radio_unsel.png delete mode 100644 retroshare-gui/src/qss/blacknight/up.png delete mode 100644 retroshare-gui/src/qss/blue.qss delete mode 100644 retroshare-gui/src/qss/blue/blue.png delete mode 100644 retroshare-gui/src/qss/blue/blue2.png delete mode 100644 retroshare-gui/src/qss/blue/tab1.png delete mode 100644 retroshare-gui/src/qss/blue/tab_hover.png delete mode 100644 retroshare-gui/src/qss/blue/tabselected.png delete mode 100644 retroshare-gui/src/qss/groove.qss delete mode 100644 retroshare-gui/src/qss/orangesurfer.qss delete mode 100644 retroshare-gui/src/qss/orangesurfer/border.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/main.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/main2.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/sizegrip.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/tab_hover.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/tab_normal.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/tab_pressed.png delete mode 100644 retroshare-gui/src/qss/orangesurfer/toolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle-v2.qss delete mode 100644 retroshare-gui/src/qss/qdarkstyle.qss delete mode 100644 retroshare-gui/src/qss/qdarkstyle/Hmovetoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/Hsepartoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/Vmovetoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/Vsepartoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/branch_closed-on.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/branch_closed.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/branch_open-on.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/branch_open.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/checkbox.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/close.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/down_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/down_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/left_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/left_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/Hmovetoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/Hsepartoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/Vmovetoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/Vsepartoolbar.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/branch_closed-on.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/branch_closed.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/branch_open-on.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/branch_open.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/close-hover.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/close-pressed.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/close.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/down_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/down_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/left_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/left_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus@2x.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/right_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/right_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/sizegrip.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-end.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-more.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-vline.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/transparent.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/undock.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/up_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/rc/up_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/right_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/right_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/sizegrip.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-end.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-more.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/stylesheet-vline.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/transparent.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/undock.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/up_arrow.png delete mode 100644 retroshare-gui/src/qss/qdarkstyle/up_arrow_disabled.png delete mode 100644 retroshare-gui/src/qss/qlive.qss delete mode 100644 retroshare-gui/src/qss/qlive/qb.png delete mode 100644 retroshare-gui/src/qss/qlive/qb2.png delete mode 100644 retroshare-gui/src/qss/redscorpion.qss delete mode 100644 retroshare-gui/src/qss/redscorpion/red.png delete mode 100644 retroshare-gui/src/qss/redscorpion/red2.png delete mode 100644 retroshare-gui/src/qss/silver.qss delete mode 100644 retroshare-gui/src/qss/silver/silver.png delete mode 100644 retroshare-gui/src/qss/silver/silver2.png delete mode 100644 retroshare-gui/src/qss/uus.qss delete mode 100644 retroshare-gui/src/qss/uus/uus.png delete mode 100644 retroshare-gui/src/qss/uus/uus2.png delete mode 100644 retroshare-gui/src/qss/yaba.qss delete mode 100644 retroshare-gui/src/qss/yaba/yaba.png delete mode 100644 retroshare-gui/src/qss/yaba/yaba2.png delete mode 100644 retroshare-gui/src/qss/yaba/yaba3.png delete mode 100644 retroshare-gui/src/qss/yeah.qss delete mode 100644 retroshare-gui/src/qss/yeah/yeah.png diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index ff657b6ff..a10cec8a4 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -6,8 +6,8 @@ 0 0 - 715 - 605 + 1068 + 880 @@ -37,14 +37,14 @@
- + QFrame::NoFrame QFrame::Raised - + @@ -73,7 +73,7 @@ - + @@ -306,6 +306,14 @@
+ + + 11 + 75 + true + true + + Name: @@ -405,6 +413,11 @@
gui/common/HeaderFrame.h
1 + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
urlLineEdit diff --git a/plugins/FeedReader/gui/FeedReaderDialog.ui b/plugins/FeedReader/gui/FeedReaderDialog.ui index 7c77717bb..5eed95bc7 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.ui +++ b/plugins/FeedReader/gui/FeedReaderDialog.ui @@ -86,7 +86,14 @@
- + + + + 12 + 75 + true + + Feeds @@ -178,11 +185,6 @@
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
RSTreeWidget QTreeWidget diff --git a/plugins/FeedReader/gui/FeedReaderFeedItem.ui b/plugins/FeedReader/gui/FeedReaderFeedItem.ui index 37c2df915..47d56f441 100644 --- a/plugins/FeedReader/gui/FeedReaderFeedItem.ui +++ b/plugins/FeedReader/gui/FeedReaderFeedItem.ui @@ -10,7 +10,7 @@ 123 - + 1 @@ -30,7 +30,7 @@ 1 - + 0 @@ -46,9 +46,9 @@ QFrame::Sunken - + - + @@ -66,9 +66,9 @@ - + - + @@ -92,7 +92,7 @@ - + 0 @@ -101,7 +101,9 @@ + 11 75 + true true @@ -127,7 +129,7 @@ - + 8 @@ -195,7 +197,7 @@ p, li { white-space: pre-wrap; } Expand - + :/icons/png/down-arrow.png:/icons/png/down-arrow.png @@ -221,7 +223,7 @@ p, li { white-space: pre-wrap; } Set as read and remove item - + :/icons/png/correct.png:/icons/png/correct.png @@ -247,7 +249,7 @@ p, li { white-space: pre-wrap; } Remove Item - + :/icons/png/exit2.png:/icons/png/exit2.png @@ -260,7 +262,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -287,7 +289,7 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - + 5 @@ -336,16 +338,8 @@ p, li { white-space: pre-wrap; } - - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
- diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.ui b/plugins/FeedReader/gui/PreviewFeedDialog.ui index 14868c082..41cebc153 100644 --- a/plugins/FeedReader/gui/PreviewFeedDialog.ui +++ b/plugins/FeedReader/gui/PreviewFeedDialog.ui @@ -7,7 +7,7 @@ 0 0 800 - 521 + 564 @@ -16,7 +16,7 @@ true - + 0 @@ -28,7 +28,7 @@ 0 - + 0 @@ -57,6 +57,14 @@ 0 + + + 11 + 75 + true + true + + Name: @@ -284,7 +292,7 @@ - + @@ -324,6 +332,14 @@ 0 + + + 11 + 75 + true + true + + Title: @@ -365,7 +381,7 @@ false - + 0 @@ -387,7 +403,7 @@ - + 0 @@ -451,7 +467,7 @@ QFrame::Raised - + 0 @@ -472,7 +488,7 @@ QFrame::Raised - + 0 @@ -499,7 +515,7 @@ QFrame::Raised - + 0 @@ -513,7 +529,7 @@ 0 - + @@ -572,11 +588,13 @@ - titleFrame - splitter - buttonBox + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
RSPlainTextEdit QPlainTextEdit diff --git a/plugins/VOIP/qss/VOIP_qss.default b/plugins/FeedReader/qss/FeedReader_default.qss similarity index 52% rename from plugins/VOIP/qss/VOIP_qss.default rename to plugins/FeedReader/qss/FeedReader_default.qss index abe80ad93..9b964468c 100644 --- a/plugins/VOIP/qss/VOIP_qss.default +++ b/plugins/FeedReader/qss/FeedReader_default.qss @@ -1,9 +1,3 @@ /* Default stylesheet This file is used as default for all stylesheets and can be overloaded */ -/* Font */ - -VOIPToasterItem QLabel#textLabel -{ - qproperty-fontSizeFactor: 115; -} diff --git a/plugins/FeedReader/qss/FeedReader_qss.qrc b/plugins/FeedReader/qss/FeedReader_qss.qrc index 437503d74..adefd6b1b 100644 --- a/plugins/FeedReader/qss/FeedReader_qss.qrc +++ b/plugins/FeedReader/qss/FeedReader_qss.qrc @@ -1,6 +1,6 @@ - FeedReader_qss.default + FeedReader_default.qss FeedReader_Standard.qss diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index b30df639c..a46169dcb 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -375,7 +375,7 @@ void VOIPConfigPanel::on_qpbAudioWizard_clicked() { void VOIPConfigPanel::on_changedCurrentInputDevice(int i) { - QString s = dynamic_cast(sender())->itemData(i).toString(); + QString s = dynamic_cast(sender())->itemData(i).toString(); videoInput->stop(); diff --git a/plugins/VOIP/gui/VOIPConfigPanel.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui index 178436808..9fbb9008c 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.ui +++ b/plugins/VOIP/gui/VOIPConfigPanel.ui @@ -63,7 +63,7 @@
- + @@ -257,7 +257,7 @@ - + When to transmit your speech @@ -510,6 +510,11 @@
gui/AudioStats.h
1
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
qsDoublePush diff --git a/plugins/VOIP/gui/VOIPToasterItem.ui b/plugins/VOIP/gui/VOIPToasterItem.ui index ef1a3e402..676e787e2 100644 --- a/plugins/VOIP/gui/VOIPToasterItem.ui +++ b/plugins/VOIP/gui/VOIPToasterItem.ui @@ -22,7 +22,7 @@ 102 - + 0 @@ -39,14 +39,14 @@ 0 - + QFrame::WinPanel QFrame::Raised - + 2 @@ -63,7 +63,7 @@ 2 - + 6 @@ -97,13 +97,20 @@ + + + 12 + 75 + true + + RetroShare - + Qt::Horizontal @@ -141,7 +148,7 @@ - + 6 @@ -240,7 +247,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - + 0 @@ -255,6 +262,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, + 12 75 true @@ -272,11 +280,6 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
AvatarWidget QLabel diff --git a/plugins/VOIP/qss/VOIP_Standard.qss b/plugins/VOIP/qss/VOIP_Standard.qss index ee40c6344..851f9af4f 100644 --- a/plugins/VOIP/qss/VOIP_Standard.qss +++ b/plugins/VOIP/qss/VOIP_Standard.qss @@ -1 +1 @@ -/* Standard stylesheet for FeedReader */ +/* Standard stylesheet for VOIP */ diff --git a/plugins/FeedReader/qss/FeedReader_qss.default b/plugins/VOIP/qss/VOIP_default.qss similarity index 51% rename from plugins/FeedReader/qss/FeedReader_qss.default rename to plugins/VOIP/qss/VOIP_default.qss index 27ca35f0c..9b964468c 100644 --- a/plugins/FeedReader/qss/FeedReader_qss.default +++ b/plugins/VOIP/qss/VOIP_default.qss @@ -1,9 +1,3 @@ /* Default stylesheet This file is used as default for all stylesheets and can be overloaded */ -/* Font */ - -FeedReaderFeedItem QLabel#titleLabel -{ - qproperty-fontSizeFactor: 135; -} diff --git a/plugins/VOIP/qss/VOIP_qss.qrc b/plugins/VOIP/qss/VOIP_qss.qrc index f82c259d4..81df6f74d 100644 --- a/plugins/VOIP/qss/VOIP_qss.qrc +++ b/plugins/VOIP/qss/VOIP_qss.qrc @@ -1,6 +1,6 @@ - VOIP_qss.default + VOIP_default.qss VOIP_Standard.qss diff --git a/retroshare-gui/src/changelog.txt b/retroshare-gui/src/changelog.txt index 3da31f03c..24c784d1a 100644 --- a/retroshare-gui/src/changelog.txt +++ b/retroshare-gui/src/changelog.txt @@ -439,7 +439,7 @@ Changes for 0.5.4e - Enabled embedded images in private chat and messages (only for QT version 4.7.0 and higher) - added tooltips to GroupFlagsWidget when buttons are unchecked (Patch from Anonym) - when an unknow user attempt to connect, show the name in the security item (Patch from Anonym) - - Load new stylesheets for locale depended things. Loading order: qss.default (internal), qss. (internal e.g. qss.de_DE) + - Load new stylesheets for locale depended things. Loading order: default.qss (internal), .qss (internal e.g. de_DE.qss) stylesheet.qss (internal or external), stylesheet_.lqss (parallel to stylesheet) - Added api for news feeds to the plugin interface. Added news feeds to the FeedReader plugin. - Removed toaster for muted participant of a chat lobby. @@ -586,7 +586,7 @@ Changes for 0.5.4c - GUI * patch from AC to perform html optimization of forum posts using the canonical function optimizeHtml() * fixed bug preventing share manager to modify more than one directory at once - * Moved most of the hardcoded colors of lists and trees to the file qss.default (with help from braindead). + * Moved most of the hardcoded colors of lists and trees to the file default.qss (with help from braindead). Now the stylesheet can redefine these colors. * Added multiselective mute/unmute to chat lobby. Added mute/unmute with double click on icon. * Added flag for hungarian language. @@ -790,10 +790,10 @@ Changes for 0.5.4a * Set the built-in stylesheet "Standard" as default for new profiles. * Removed some unnecessary style sheets. * Added two internal stylesheets: - - qss.default - This file is used as default for all stylesheets (e.g. the frames of + - default.qss - This file is used as default for all stylesheets (e.g. the frames of the AvatarWidget) and can be overloaded from the selected stylesheet - Standard.qss - The standard stylesheet for the current look of RetroShare. More internal stylesheets can be added. - The plan is to move nearly all internal stylesheets to the files Standard.qss/qss.default. + The plan is to move nearly all internal stylesheets to the files Standard.qss/default.qss. After that the "empty" stylesheet should represent the system theme of the os. - Added clear chat history to the context menu of the message text browser @@ -3121,4 +3121,4 @@ We have available for those interested in retroshare: (2) deb installation files for debian/etch and kubuntu/feisty (3) Language pack for those interested in translating. - \ No newline at end of file + diff --git a/retroshare-gui/src/gui/AboutWidget.cpp b/retroshare-gui/src/gui/AboutWidget.cpp index aa239650e..7dccb1693 100644 --- a/retroshare-gui/src/gui/AboutWidget.cpp +++ b/retroshare-gui/src/gui/AboutWidget.cpp @@ -52,8 +52,8 @@ AboutWidget::AboutWidget(QWidget* parent) l->setMargin(0); l->addStretch(1); l->addStretch(1); - frame->setContentsMargins(0, 0, 0, 0); - frame->setLayout(l); + specialFrame->setContentsMargins(0, 0, 0, 0); + specialFrame->setLayout(l); tWidget = NULL; aWidget = NULL; installAWidget(); @@ -67,7 +67,7 @@ AboutWidget::AboutWidget(QWidget* parent) void AboutWidget::installAWidget() { assert(tWidget == NULL); aWidget = new AWidget(); - QVBoxLayout* l = (QVBoxLayout*)frame->layout(); + QVBoxLayout* l = (QVBoxLayout*)specialFrame->layout(); l->insertWidget(0, aWidget); l->setStretchFactor(aWidget, 100); aWidget->setFocus(); @@ -96,10 +96,10 @@ void AboutWidget::installTWidget() { vl->addWidget(levelLabel); vl->addStretch(); - QHBoxLayout* l = (QHBoxLayout*)frame->layout(); + QHBoxLayout* l = (QHBoxLayout*)specialFrame->layout(); l->insertWidget(0, pan); l->insertWidget(0, tWidget); - QRect cRect = frame->contentsRect(); + QRect cRect = specialFrame->contentsRect(); int height = tWidget->heightForWidth(cRect.width()); tWidget->setFixedSize(cRect.width() * cRect.height() / height, cRect.height()); npLabel->setFixedSize(tWidget->squareWidth()*4, tWidget->squareHeight()*5); @@ -117,7 +117,7 @@ void AboutWidget::installTWidget() { void AboutWidget::switchPages() { QLayoutItem* li = NULL; - QLayout* l = frame->layout(); + QLayout* l = specialFrame->layout(); while ((li = l->takeAt(0)) && li->widget()) { li->widget()->deleteLater(); } @@ -158,9 +158,9 @@ void AboutWidget::updateTitle() void AboutWidget::mousePressEvent(QMouseEvent *e) { QPoint globalPos = mapToGlobal(e->pos()); - QPoint framePos = frame->mapFromGlobal(globalPos); + QPoint framePos = specialFrame->mapFromGlobal(globalPos); - if (frame->contentsRect().contains(framePos)) { + if (specialFrame->contentsRect().contains(framePos)) { { if(e->modifiers() & Qt::ControlModifier) switchPages(); diff --git a/retroshare-gui/src/gui/AboutWidget.ui b/retroshare-gui/src/gui/AboutWidget.ui index 99b638388..548d6fd9a 100644 --- a/retroshare-gui/src/gui/AboutWidget.ui +++ b/retroshare-gui/src/gui/AboutWidget.ui @@ -57,7 +57,7 @@
- + QFrame::StyledPanel diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 475495674..d369c9bcf 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -94,14 +94,14 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) myInviteIdChooser = NULL; QObject::connect( NotifyQt::getInstance(), SIGNAL(lobbyListChanged()), SLOT(lobbyChanged())); - QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&)), this, SLOT(displayChatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&))); + QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,RsGxsId,QString)), this, SLOT(displayChatLobbyEvent(qulonglong,int,RsGxsId,QString))); QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyInviteReceived()), this, SLOT(readChatLobbyInvites())); QObject::connect( ui.lobbyTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(lobbyTreeWidgetCustomPopupMenu(QPoint))); QObject::connect( ui.lobbyTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*,int))); QObject::connect( ui.lobbyTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateCurrentLobby())); - QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString))); + QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); QObject::connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); QObject::connect( ui.createLobbyToolButton, SIGNAL(clicked()), this, SLOT(createChatLobby())); @@ -194,25 +194,25 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) // load settings processSettings(true); - int S = QFontMetricsF(font()).height(); - QString help_str = tr("\ -

  Chat Rooms

\ -

Chat rooms work pretty much like IRC. \ - They allow you to talk anonymously with tons of people without the need to make friends.

\ -

A chat room can be public (your friends see it) or private (your friends can't see it, unless you \ - invite them with ). \ - Once you have been invited to a private room, you will be able to see it when your friends \ - are using it.

\ -

The list at left shows \ - chat lobbies your friends are participating in. You can either \ -

    \ -
  • Right click to create a new chat room
  • \ -
  • Double click a chat room to enter, chat, and show it to your friends
  • \ -
\ - Note: For the chat rooms to work properly, your computer needs be on time. So check your system clock!\ -

\ + int S = QFontMetricsF(font()).height(); + QString help_str = tr("\ +

  Chat Rooms

\ +

Chat rooms work pretty much like IRC. \ + They allow you to talk anonymously with tons of people without the need to make friends.

\ +

A chat room can be public (your friends see it) or private (your friends can't see it, unless you \ + invite them with ). \ + Once you have been invited to a private room, you will be able to see it when your friends \ + are using it.

\ +

The list at left shows \ + chat lobbies your friends are participating in. You can either \ +

    \ +
  • Right click to create a new chat room
  • \ +
  • Double click a chat room to enter, chat, and show it to your friends
  • \ +
\ + Note: For the chat rooms to work properly, your computer needs be on time. So check your system clock!\ +

\ " - ).arg(QString::number(2*S)).arg(QString::number(S)) ; + ).arg(QString::number(2*S), QString::number(S)) ; registerHelpButton(ui.helpButton,help_str,"ChatLobbyDialog") ; @@ -232,7 +232,7 @@ ChatLobbyWidget::~ChatLobbyWidget() UserNotify *ChatLobbyWidget::createUserNotify(QObject *parent) { myChatLobbyUserNotify = new ChatLobbyUserNotify(parent); - connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, unsigned int)), this, SLOT(updateNotify(ChatLobbyId, unsigned int))); + connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, uint)), this, SLOT(updateNotify(ChatLobbyId, uint))); return myChatLobbyUserNotify; } @@ -920,7 +920,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/) } } - ui.lobbyInfoLabel->setText(text); + ui.info_Label_Lobby->setText(text); return ; } @@ -932,7 +932,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/) ui.lobbysec_lineEdit->clear(); QString text = tr("No chat room selected. \nSelect chat rooms at left to show details.\nDouble click a chat room to enter and chat.") ; - ui.lobbyInfoLabel->setText(text) ; + ui.info_Label_Lobby->setText(text) ; } void ChatLobbyWidget::subscribeItem() @@ -1116,6 +1116,7 @@ void ChatLobbyWidget::updateCurrentLobby() filterItems(ui.filterLineEdit->text()); } } + void ChatLobbyWidget::updateMessageChanged(bool incoming, ChatLobbyId id, QDateTime time, QString senderName, QString msg) { QTreeWidgetItem *current_item = ui.lobbyTreeWidget->currentItem(); @@ -1174,9 +1175,11 @@ void ChatLobbyWidget::readChatLobbyInvites() if(found) continue ; - QMessageBox mb(QObject::tr("Join chat room"), - tr("%1 invites you to chat room named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)), - QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0); + QMessageBox mb(QObject::tr("Join chat room") + , tr("%1 invites you to chat room named %2") + .arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str()) + , RsHtml::plainText(it->lobby_name)) + , QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0); QLabel *label; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.ui b/retroshare-gui/src/gui/ChatLobbyWidget.ui index 4a4f863ef..5a679189e 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.ui +++ b/retroshare-gui/src/gui/ChatLobbyWidget.ui @@ -70,7 +70,14 @@
- + + + + 12 + 75 + true + + Chat rooms @@ -183,7 +190,7 @@ - + 16 @@ -228,6 +235,13 @@ + + + 12 + 75 + true + + @@ -244,6 +258,7 @@ + 12 75 true @@ -261,6 +276,13 @@ 0 + + + 16 + 75 + true + + TextLabel @@ -270,6 +292,7 @@ + 12 75 true @@ -296,6 +319,7 @@ + 12 75 true @@ -325,6 +349,7 @@ + 12 75 true @@ -351,6 +376,7 @@ + 12 75 true @@ -371,6 +397,7 @@ + 12 75 true @@ -396,7 +423,7 @@ - + TextLabel @@ -432,12 +459,12 @@ LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
- StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSTreeWidget + QTreeWidget +
gui/common/RSTreeWidget.h
diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.ui b/retroshare-gui/src/gui/Circles/CirclesDialog.ui index da9da0b8b..05b89146b 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.ui +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.ui @@ -49,7 +49,14 @@
- + + + + 12 + 75 + true + + Circles @@ -247,13 +254,6 @@
- - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index 2b9d3b804..b8ee868ad 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -98,7 +98,7 @@ CreateCircleDialog::CreateCircleDialog() connect(ui.addButton, SIGNAL(clicked()), this, SLOT(addMember())); connect(ui.removeButton, SIGNAL(clicked()), this, SLOT(removeMember())); - connect(ui.createButton, SIGNAL(clicked()), this, SLOT(createCircle())); + connect(ui.postButton, SIGNAL(clicked()), this, SLOT(createCircle())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(close())); connect(ui.treeWidget_membership, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectedMember(QTreeWidgetItem*, QTreeWidgetItem*))); @@ -187,14 +187,14 @@ void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool ui.idChooser->setVisible(true) ; } - ui.createButton->setText(tr("Update")); + ui.postButton->setText(tr("Update")); ui.addButton->setEnabled(!readonly) ; ui.removeButton->setEnabled(!readonly) ; if(readonly) { - ui.createButton->hide() ; + ui.postButton->hide() ; ui.cancelButton->setText(tr("Close")); ui.peersSelection_GB->hide() ; ui.addButton->hide() ; @@ -216,7 +216,7 @@ void CreateCircleDialog::editNewId(bool isExternal) { setupForExternalCircle(); ui.headerFrame->setHeaderText(tr("Create New Circle")); - ui.createButton->setText(tr("Create")); + ui.postButton->setText(tr("Create")); } else { diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui index 54e1fe80f..62390e56a 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui @@ -13,7 +13,7 @@ - + 0 @@ -40,226 +40,225 @@
- + QFrame::StyledPanel QFrame::Raised - + Circle Details - + + + 11 + - - - - - - 75 - true - - - - Qt::LeftToRight - - - Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - <html><head/><body><p>The circle name, contact author and invited member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.</p></body></html> - - - - - - - - 75 - true - - - - Contact author: - - - - - - - - 0 - 0 - - - - <html><head/><body><p>The creator of a circle is purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.</p></body></html> - - - - - - - [Circle Admin] - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - 75 - true - - - - Distribution: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 2 + + + + 75 + true + + + + Qt::LeftToRight + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <html><head/><body><p>The circle name, contact author and invited member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.</p></body></html> + + + + + + + + 75 + true + + + + Contact author: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>The creator of a circle is purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.</p></body></html> + + + + + + + [Circle Admin] + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 75 + true + + + + Distribution: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + <html><head/><body><p>Publicly distributed circles are visible to your friends, which will get to know the circle data (Creator, members, etc)</p></body></html> - - 2 + + Public - - 2 + + + :/icons/png/network-puplic.png:/icons/png/network-puplic.png - - 2 + + + 24 + 24 + - - - - <html><head/><body><p>Publicly distributed circles are visible to your friends, which will get to know the circle data (Creator, members, etc)</p></body></html> - - - Public - - - - :/icons/png/network-puplic.png:/icons/png/network-puplic.png - - - - 24 - 24 - - - - - - - - <html><head/><body><p>Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. </p></body></html> - - - Private - - - - :/icons/png/person.png:/icons/png/person.png - - - - 24 - 24 - - - - - - - - <html><head/><body><p>Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).</p></body></html> - - - Only &visible to members of: - - - - :/icons/png/circles.png:/icons/png/circles.png - - - - 24 - 24 - - - - - - - - - - - Qt::Horizontal - - - - 147 - 20 - - - - - - - - + + + + + + <html><head/><body><p>Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. </p></body></html> + + + Private + + + + :/icons/png/person.png:/icons/png/person.png + + + + 24 + 24 + + + + + + + + <html><head/><body><p>Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).</p></body></html> + + + Only &visible to members of: + + + + :/icons/png/circles.png:/icons/png/circles.png + + + + 24 + 24 + + + + + + + + + + + Qt::Horizontal + + + + 147 + 20 + + + + + + - + Invited Members - + @@ -287,9 +286,9 @@ - + - + Qt::Vertical @@ -330,7 +329,7 @@ - + Qt::Vertical @@ -378,7 +377,7 @@ QFrame::Raised - + 0 @@ -419,9 +418,9 @@ - + - + Filter @@ -438,7 +437,7 @@ - + Qt::Horizontal @@ -451,7 +450,14 @@ - + + + + 12 + 75 + true + + Create @@ -503,7 +509,6 @@ - diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 9c3703032..b6da4de7b 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -121,10 +121,10 @@ SearchDialog::SearchDialog(QWidget *parent) connect( ui.searchSummaryWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( searchSummaryWidgetCustomPopupMenu( QPoint ) ) ); connect( ui.showBannedFiles_TB, SIGNAL( clicked() ), this, SLOT( openBannedFiles() ) ); - connect( ui.lineEdit, SIGNAL( returnPressed ( void ) ), this, SLOT( searchKeywords( void ) ) ); + connect( ui.lineEdit, SIGNAL( returnPressed () ), this, SLOT( searchKeywords() ) ); connect( ui.lineEdit, SIGNAL( textChanged ( const QString& ) ), this, SLOT( checkText( const QString& ) ) ); - connect( ui.pushButtonSearch, SIGNAL( released ( void ) ), this, SLOT( searchKeywords( void ) ) ); - connect( ui.pushButtonDownload, SIGNAL( released ( void ) ), this, SLOT( download( void ) ) ); + connect( ui.searchButton, SIGNAL( released () ), this, SLOT( searchKeywords() ) ); + connect( ui.pushButtonDownload, SIGNAL( released () ), this, SLOT( download() ) ); connect( ui.cloaseallsearchresultsButton, SIGNAL(clicked()), this, SLOT(searchRemoveAll())); connect( ui.searchResultWidget, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *, int)), this, SLOT(download())); @@ -186,11 +186,6 @@ SearchDialog::SearchDialog(QWidget *parent) _smheader->resizeSection ( SR_AGE_COL, 90*f ); _smheader->resizeSection ( SR_HASH_COL, 240*f ); - // set header text aligment - QTreeWidgetItem * headerItem = ui.searchResultWidget->headerItem(); - headerItem->setTextAlignment(SR_NAME_COL, Qt::AlignRight | Qt::AlignRight); - headerItem->setTextAlignment(SR_SIZE_COL, Qt::AlignRight | Qt::AlignRight); - ui.searchResultWidget->sortItems(SR_NAME_COL, Qt::AscendingOrder); /* Set initial size the splitter */ @@ -276,30 +271,9 @@ void SearchDialog::processSettings(bool bLoad) void SearchDialog::checkText(const QString& txt) { - bool valid; - QColor color; - - if(txt.length() < 3) - { - std::cout << "setting palette 1" << std::endl ; - valid = false; - color = QApplication::palette().color(QPalette::Disabled, QPalette::Base); - } - else - { - std::cout << "setting palette 2" << std::endl ; - valid = true; - color = QApplication::palette().color(QPalette::Active, QPalette::Base); - } - - /* unpolish widget to clear the stylesheet's palette cache */ + ui.searchButton->setDisabled(txt.length() < 3); + ui.searchLineFrame->setProperty("valid", (txt.length() >= 3)); ui.searchLineFrame->style()->unpolish(ui.searchLineFrame); - - QPalette palette = ui.lineEdit->palette(); - palette.setColor(ui.lineEdit->backgroundRole(), color); - ui.lineEdit->setPalette(palette); - - ui.searchLineFrame->setProperty("valid", valid); Rshare::refreshStyleSheet(ui.searchLineFrame, false); } @@ -393,11 +367,10 @@ void SearchDialog::download() /* should also be able to handle multi-selection */ QList itemsForDownload = ui.searchResultWidget->selectedItems() ; int numdls = itemsForDownload.size() ; - QTreeWidgetItem * item ; bool attemptDownloadLocal = false ; for (int i = 0; i < numdls; ++i) { - item = itemsForDownload.at(i) ; + QTreeWidgetItem *item = itemsForDownload.at(i) ; // call the download // * if (item->text(SR_HASH_COL).isEmpty()) { // we have a folder @@ -421,8 +394,8 @@ void SearchDialog::download() std::cout << *it << "-" << std::endl; QColor foreground = textColorDownloading(); - for (int i = 0; i < item->columnCount(); ++i) - item->setData(i, Qt::ForegroundRole, foreground ); + for (int j = 0; j < item->columnCount(); ++j) + item->setData(j, Qt::ForegroundRole, foreground ); } } } @@ -1209,17 +1182,16 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s // bool found = false ; bool altname = false ; - int sources; - int friendSource = 0; - int anonymousSource = 0; QString modifiedResult; - QList itms = ui.searchResultWidget->findItems(QString::fromStdString(file.hash.toStdString()),Qt::MatchExactly,SR_HASH_COL) ; + QList itms = ui.searchResultWidget->findItems(QString::fromStdString(file.hash.toStdString()),Qt::MatchExactly,SR_HASH_COL) ; - for(QList::const_iterator it(itms.begin());it!=itms.end();++it) - if((*it)->text(SR_SEARCH_ID_COL) == sid_hexa) + for(auto &it : itms) + if(it->text(SR_SEARCH_ID_COL) == sid_hexa) { - QString resultCount = (*it)->text(SR_SOURCES_COL); + int friendSource = 0; + int anonymousSource = 0; + QString resultCount = it->text(SR_SOURCES_COL); QStringList modifiedResultCount = resultCount.split("/", QString::SkipEmptyParts); if(searchType == FRIEND_SEARCH) { @@ -1233,13 +1205,13 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } modifiedResult = QString::number(friendSource) + "/" + QString::number(anonymousSource); float fltRes = friendSource + (float)anonymousSource/1000; - (*it)->setText(SR_SOURCES_COL,modifiedResult); - (*it)->setData(SR_SOURCES_COL, ROLE_SORT, fltRes); - QTreeWidgetItem *item = (*it); + it->setText(SR_SOURCES_COL,modifiedResult); + it->setData(SR_SOURCES_COL, ROLE_SORT, fltRes); + QTreeWidgetItem *item = it; found = true ; - if(QString::compare((*it)->text(SR_NAME_COL), QString::fromUtf8(file.name.c_str()), Qt::CaseSensitive)!=0) + if(QString::compare(it->text(SR_NAME_COL), QString::fromUtf8(file.name.c_str()), Qt::CaseSensitive)!=0) altname = true; if (!item->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool()) { @@ -1280,19 +1252,18 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } } - if(altname) - { - QTreeWidgetItem *item = new RSTreeWidgetItem(compareResultRole); - item->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); - item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); - setIconAndType(item, QString::fromUtf8(file.name.c_str())); - item->setText(SR_SIZE_COL, QString::number(file.size)); - setIconAndType(item, QString::fromUtf8(file.name.c_str())); - (*it)->addChild(item); + if(altname) + { + QTreeWidgetItem *altItem = new RSTreeWidgetItem(compareResultRole); + altItem->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); + altItem->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); + setIconAndType(altItem, QString::fromUtf8(file.name.c_str())); + altItem->setText(SR_SIZE_COL, QString::number(file.size)); + setIconAndType(altItem, QString::fromUtf8(file.name.c_str())); + it->addChild(altItem); + } } - } - if(!found) { ++nb_results[searchId] ; @@ -1301,7 +1272,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s QTreeWidgetItem *item = new RSTreeWidgetItem(compareResultRole); item->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); - item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); + item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); setIconAndType(item, QString::fromUtf8(file.name.c_str())); @@ -1314,6 +1285,8 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s item->setText(SR_AGE_COL, QString::number(file.age)); item->setData(SR_AGE_COL, ROLE_SORT, file.age); item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); + int friendSource = 0; + int anonymousSource = 0; if(searchType == FRIEND_SEARCH) { friendSource = 1; @@ -1344,7 +1317,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } else { item->setData(SR_DATA_COL, SR_ROLE_LOCAL, false); - sources = item->text(SR_SOURCES_COL).toInt(); + int sources = item->text(SR_SOURCES_COL).toInt(); if (sources == 1) { foreground = ui.searchResultWidget->palette().color(QPalette::Text); @@ -1369,11 +1342,8 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s /* hide/show this search result */ hideOrShowSearchResult(item); - } - /* update the summary as well */ - if(!found) // only increment result when it's a new item. - { + // only increment result when it's a new item. int s = ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->text(SS_RESULTS_COL).toInt() ; ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->setText(SS_RESULTS_COL, QString::number(s+1)); ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->setData(SS_RESULTS_COL, ROLE_SORT, s+1); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index 83eb3b1b2..55db103ca 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -159,7 +159,7 @@ private: QAbstractItemDelegate *mAgeColumnDelegate; QAbstractItemDelegate *mSizeColumnDelegate; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorLocal; QColor mTextColorDownloading; QColor mTextColorNoSources; diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui index 4aa868b56..47fd2179e 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui @@ -6,7 +6,7 @@ 0 0 - 793 + 783 511 @@ -16,7 +16,7 @@ 1 - + @@ -31,7 +31,7 @@ QFrame::Plain - + 3 @@ -45,42 +45,30 @@ 3 - + 2 - - - 0 - 22 - - - - - 16777215 - 22 - - - + - 0 + 2 - 0 + 2 - 0 + 2 - 0 + 2 0 - 1 + 0 @@ -93,7 +81,14 @@ - + + + + 12 + 75 + true + + Qt::NoFocus @@ -342,7 +337,7 @@ - + Any @@ -466,6 +461,11 @@ QLineEdit
gui/common/LineEditClear.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
SearchTreeWidget QTreeWidget @@ -473,8 +473,8 @@ - + diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp index 20de4b9e9..61e01ab24 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp @@ -213,15 +213,20 @@ SharedFilesDialog::SharedFilesDialog(bool remote_mode, QWidget *parent) /* Set header resize modes and initial section sizes */ QHeaderView * header = ui.dirTreeView->header () ; +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int charWidth = ui.dirTreeView->fontMetrics().width("_"); +#else + int charWidth = ui.dirTreeView->fontMetrics().horizontalAdvance("_"); +#endif - header->resizeSection ( COLUMN_NAME, 490 ); - header->resizeSection ( COLUMN_FILENB, 70 ); - header->resizeSection ( COLUMN_SIZE, 70 ); - header->resizeSection ( COLUMN_AGE, 100 ); - header->resizeSection ( COLUMN_FRIEND_ACCESS,100); - header->resizeSection ( COLUMN_WN_VISU_DIR, 100 ); + header->resizeSection ( COLUMN_NAME , charWidth*100 ); + header->resizeSection ( COLUMN_FILENB , charWidth*15 ); + header->resizeSection ( COLUMN_SIZE , charWidth*10 ); + header->resizeSection ( COLUMN_AGE , charWidth*6 ); + header->resizeSection ( COLUMN_FRIEND_ACCESS, charWidth*10 ); + header->resizeSection ( COLUMN_WN_VISU_DIR , charWidth*20 ); - header->setStretchLastSection(false); + header->setStretchLastSection(true); /* Set Multi Selection */ ui.dirTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui index 8bf177546..6915c1c44 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui @@ -61,7 +61,14 @@
- + + + + 12 + 75 + true + + Files @@ -216,7 +223,7 @@ border-image: url(:/images/closepressed.png)
- + Tree view @@ -230,7 +237,7 @@ border-image: url(:/images/closepressed.png) - + All @@ -304,7 +311,7 @@ border-image: url(:/images/closepressed.png) Download - + :/images/download16.png:/images/download16.png @@ -369,9 +376,6 @@ border-image: url(:/images/closepressed.png) false - - false -
@@ -382,9 +386,9 @@ border-image: url(:/images/closepressed.png)
- StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui index 121af8a85..f329509b1 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui @@ -70,7 +70,14 @@
- + + + + 12 + 75 + true + + File Transfers @@ -300,11 +307,6 @@
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
LineEditClear QLineEdit diff --git a/retroshare-gui/src/gui/FriendsDialog.ui b/retroshare-gui/src/gui/FriendsDialog.ui index b32c71465..02408e382 100644 --- a/retroshare-gui/src/gui/FriendsDialog.ui +++ b/retroshare-gui/src/gui/FriendsDialog.ui @@ -10,7 +10,7 @@ 491 - + 0 @@ -37,7 +37,7 @@ QFrame::Sunken - + 2 @@ -70,14 +70,21 @@
- + + + + 12 + 75 + true + + Network - + Qt::Horizontal @@ -115,12 +122,12 @@ Qt::Horizontal - + 1 - + @@ -130,7 +137,7 @@ QFrame::Sunken - + 1 @@ -192,7 +199,14 @@ - + + + + 20 + 75 + true + + Nickname (Location) @@ -240,7 +254,7 @@ Broadcast - + @@ -362,11 +376,6 @@
gui/common/AvatarWidget.h
1 - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
ChatWidget QWidget @@ -380,9 +389,9 @@ 1 - StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
NewFriendList diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index c0646f5e9..6aa4e1ce1 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -53,7 +53,7 @@ class EntropyCollectorWidget: public QTextBrowser { public: - EntropyCollectorWidget(QProgressBar *pr,QWidget *p = NULL) + explicit EntropyCollectorWidget(QProgressBar *pr,QWidget *p = NULL) : QTextBrowser(p) { progress = pr ; @@ -288,8 +288,6 @@ void GenCertDialog::setupState() break; } - //ui.no_node_label->setVisible(false); - setWindowTitle(generate_new?tr("Create new profile and new Retroshare node"):tr("Create new Retroshare node")); //ui.headerFrame->setHeaderText(generate_new?tr("Create a new profile and node"):tr("Create a new node")); @@ -300,15 +298,9 @@ void GenCertDialog::setupState() ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ; - //ui.genprofileinfo_label->setVisible(false); - //ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); - //no_gpg_key_label->setVisible(false); - ui.name_label->setVisible(true); ui.name_input->setVisible(generate_new); - //ui.header_label->setVisible(false) ; - ui.nickname_label->setVisible(adv_state && !mOnlyGenerateIdentity); ui.nickname_input->setVisible(adv_state && !mOnlyGenerateIdentity); @@ -352,8 +344,8 @@ void GenCertDialog::setupState() ui.genButton->setVisible(false) ; ui.generate_label->setVisible(false) ; - ui.info_label->setText("Please choose a profile name and password...") ; - ui.info_label->setVisible(true) ; + ui.info_Label->setText("Please choose a profile name and password...") ; + ui.info_Label->setVisible(true) ; } else if(!mEntropyOk) { @@ -361,8 +353,8 @@ void GenCertDialog::setupState() ui.genButton->setVisible(false) ; ui.generate_label->setVisible(false) ; - ui.info_label->setText("Please move your mouse randomly to generate enough random data to create your profile.") ; - ui.info_label->setVisible(true) ; + ui.info_Label->setText("Please move your mouse randomly to generate enough random data to create your profile.") ; + ui.info_Label->setVisible(true) ; } else { @@ -371,7 +363,7 @@ void GenCertDialog::setupState() ui.genButton->setToolTip(tr("Click to create your node and/or profile")) ; ui.genButton->setVisible(true) ; ui.generate_label->setVisible(false) ; - ui.info_label->setVisible(false) ; + ui.info_Label->setVisible(false) ; } } @@ -591,7 +583,6 @@ void GenCertDialog::genPerson() //generate a new gpg key std::string err_string; //_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); - //ui.no_gpg_key_label->show(); //ui.reuse_existing_node_CB->hide(); ui.name_label->hide(); ui.name_input->hide(); @@ -609,7 +600,6 @@ void GenCertDialog::genPerson() ui.node_input->hide(); ui.genButton->hide(); ui.importIdentity_PB->hide(); - //ui.genprofileinfo_label->hide(); ui.nodeType_CB->hide(); //ui.adv_checkbox->hide(); ui.keylength_label->hide(); diff --git a/retroshare-gui/src/gui/GenCertDialog.h b/retroshare-gui/src/gui/GenCertDialog.h index 5bef44485..6d9d3610a 100644 --- a/retroshare-gui/src/gui/GenCertDialog.h +++ b/retroshare-gui/src/gui/GenCertDialog.h @@ -31,7 +31,7 @@ class GenCertDialog : public QDialog public: /** Default constructor */ - GenCertDialog(bool onlyGenerateIdentity, QWidget *parent = 0); + explicit GenCertDialog(bool onlyGenerateIdentity, QWidget *parent = 0); virtual ~GenCertDialog() ; virtual void mouseMoveEvent(QMouseEvent *e) ; diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 482150beb..a747709d3 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -111,7 +111,7 @@
- + 0 @@ -187,7 +187,7 @@ - + 0 @@ -245,6 +245,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> @@ -303,6 +309,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> @@ -340,6 +352,12 @@ 32 + + + 75 + true + + <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> @@ -352,13 +370,19 @@ - + 0 0 + + + 75 + true + + Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. @@ -417,6 +441,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> @@ -456,6 +486,12 @@ 32 + + + 75 + true + + <html><head/><body><p>This should be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> @@ -479,6 +515,12 @@ 0 + + + 75 + true + + <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> @@ -510,6 +552,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> @@ -532,6 +580,8 @@ 12 + 75 + true @@ -721,7 +771,12 @@
- + + + + 12 + + TextLabel @@ -751,6 +806,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
name_input node_input diff --git a/retroshare-gui/src/gui/GetStartedDialog.cpp b/retroshare-gui/src/gui/GetStartedDialog.cpp index d525808b6..21fe60be0 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.cpp +++ b/retroshare-gui/src/gui/GetStartedDialog.cpp @@ -53,19 +53,19 @@ GetStartedDialog::GetStartedDialog(QWidget *parent) mFirstShow = true; - connect(ui.inviteCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickInviteChanged())); - connect(ui.addCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickAddChanged())); - connect(ui.connectCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickConnectChanged())); - connect(ui.firewallCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickFirewallChanged())); + connect(ui.inviteCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickInviteChanged())); + connect(ui.addCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickAddChanged())); + connect(ui.connectCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickConnectChanged())); + connect(ui.firewallCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickFirewallChanged())); - connect(ui.pushButton_InviteFriends, SIGNAL(clicked( bool )), this, SLOT(inviteFriends())); - connect(ui.pushButton_AddFriend, SIGNAL(clicked( bool )), this, SLOT(addFriends())); + connect(ui.pushButton_InviteFriends, SIGNAL(clicked(bool)), this, SLOT(inviteFriends())); + connect(ui.pushButton_AddFriend, SIGNAL(clicked(bool)), this, SLOT(addFriends())); - connect(ui.pushButton_FAQ, SIGNAL(clicked( bool )), this, SLOT(OpenFAQ())); - connect(ui.pushButton_Forums, SIGNAL(clicked( bool )), this, SLOT(OpenForums())); - connect(ui.pushButton_Website, SIGNAL(clicked( bool )), this, SLOT(OpenWebsite())); - connect(ui.pushButton_EmailFeedback, SIGNAL(clicked( bool )), this, SLOT(emailFeedback())); - connect(ui.pushButton_EmailSupport, SIGNAL(clicked( bool )), this, SLOT(emailSupport())); + connect(ui.pushButton_FAQ, SIGNAL(clicked(bool)), this, SLOT(OpenFAQ())); + connect(ui.pushButton_Forums, SIGNAL(clicked(bool)), this, SLOT(OpenForums())); + connect(ui.pushButton_Website, SIGNAL(clicked(bool)), this, SLOT(OpenWebsite())); + connect(ui.pushButton_EmailFeedback, SIGNAL(clicked(bool)), this, SLOT(emailFeedback())); + connect(ui.pushButton_EmailSupport, SIGNAL(clicked(bool)), this, SLOT(emailSupport())); } GetStartedDialog::~GetStartedDialog() @@ -105,8 +105,7 @@ void GetStartedDialog::showEvent ( QShowEvent * /*event*/ ) void GetStartedDialog::updateFromUserLevel() { - RsConfigUserLvl userLevel = RsConfigUserLvl::NEW; - userLevel = rsConfig->getUserLevel(); + RsConfigUserLvl userLevel = rsConfig->getUserLevel(); ui.inviteCheckBox->setChecked(false); ui.addCheckBox->setChecked(false); @@ -185,17 +184,12 @@ void GetStartedDialog::tickFirewallChanged() } } -static void sendMail(const QString &address, const QString &subject, QString body) +static void sendMail(const QString &address, const QString &subject, const QString &body) { - /* Only under windows do we need to do this! */ -#ifdef Q_OS_WIN - /* search and replace the end of lines with: "%0D%0A" */ - body.replace("\n", "%0D%0A"); -#endif QString mailstr = "mailto:" + address; - mailstr += "?subject=" + subject; - mailstr += "&body=" + body; + mailstr += "?subject=" + QUrl::toPercentEncoding(subject); + mailstr += "&body=" + QUrl::toPercentEncoding(body); std::cerr << "MAIL STRING:" << mailstr.toStdString() << std::endl; @@ -240,7 +234,7 @@ void GetStartedDialog::inviteFriends() RsAutoUpdatePage::unlockAllEvents() ; } - QString text = QString("%1\n%2\n\n%3\n").arg(GetInviteText()).arg(GetCutBelowText()).arg(QString::fromUtf8(cert.c_str())); + QString text = QString("%1\n%2\n\n%3\n").arg(GetInviteText(), GetCutBelowText(), QString::fromUtf8(cert.c_str())); sendMail("", tr("RetroShare Invitation"), text); } @@ -427,8 +421,10 @@ void GetStartedDialog::emailSupport() sysVersion = "Linux"; #endif #endif - text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true)).arg(sysVersion).arg(static_cast::type>(userLevel)) + "\n"; - text += "\n"; + text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true) + , sysVersion + ).arg(static_cast::type>(userLevel)) + "\n"; + text += "\n"; text += QString("I am having trouble with RetroShare."); text += QString(" Can you help me with....") + "\n"; diff --git a/retroshare-gui/src/gui/GetStartedDialog.ui b/retroshare-gui/src/gui/GetStartedDialog.ui index 13698c204..5c0a78e6b 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.ui +++ b/retroshare-gui/src/gui/GetStartedDialog.ui @@ -10,7 +10,7 @@ 582 - + 0 @@ -32,11 +32,20 @@ Getting Started - + 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -53,12 +62,12 @@ 732 - + 0 - + @@ -121,20 +130,20 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">RetroShare is nothing without your Friends. Click on the Button to start the process.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Email an Invitation with your &quot;ID Certificate&quot; to your friends.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Be sure to get their invitation back as well... </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">You can only connect with friends if you have both added each other.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:12pt;">RetroShare is nothing without your Friends. Click on the Button to start the process.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Email an Invitation with your &quot;ID Certificate&quot; to your friends.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Be sure to get their invitation back as well... </span></p> +<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:12pt;">You can only connect with friends if you have both added each other.</span></p></body></html> - + @@ -197,17 +206,17 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">When your friends send you their invitations, click to open the Add Friends window.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Paste your Friends' &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:12pt;">When your friends send you their invitations, click to open the Add Friends window.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Paste your Friends' &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html> - + 0 @@ -282,25 +291,25 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Be Online at the same time as your friends, and RetroShare will automatically connect you!</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Your client needs to find the RetroShare Network before it can make connections.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">This takes 5-30 minutes the first time you start up RetroShare</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">The DHT indicator (in the Status Bar) turns Green when it can make connections.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">After a couple of minutes, the NAT indicator (also in the Status Bar) switch to Yellow or Green.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">If it remains Red, then you have a Nasty Firewall, that RetroShare struggles to connect through.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Look in the Further Help section for more advice about connecting.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:12pt;">Be Online at the same time as your friends, and RetroShare will automatically connect you!</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Your client needs to find the RetroShare Network before it can make connections.</span></p> +<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:12pt;">This takes 5-30 minutes the first time you start up RetroShare</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">The DHT indicator (in the Status Bar) turns Green when it can make connections.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">After a couple of minutes, the NAT indicator (also in the Status Bar) switch to Yellow or Green.</span></p> +<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:12pt;">If it remains Red, then you have a Nasty Firewall, that RetroShare struggles to connect through.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Look in the Further Help section for more advice about connecting.</span></p></body></html> - + @@ -366,23 +375,23 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">You can improve your Retroshare performance by opening an External Port. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">This will speed up connections and allow more people to connect with you. </span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">The easiest way to do this is by enabling UPnP on your Wireless Box or Router.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">As each router is different, you will need to find out your Router Model and search the Internet for instructions.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">If none of this makes sense to you, don't worry about it Retroshare will still work.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:12pt;">You can improve your Retroshare performance by opening an External Port. </span></p> +<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:12pt;">This will speed up connections and allow more people to connect with you. </span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">The easiest way to do this is by enabling UPnP on your Wireless Box or Router.</span></p> +<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:12pt;">As each router is different, you will need to find out your Router Model and search the Internet for instructions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">If none of this makes sense to you, don't worry about it Retroshare will still work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html> - + Qt::Vertical @@ -407,31 +416,31 @@ p, li { white-space: pre-wrap; } Further Help and Support - + - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Having trouble getting started with RetroShare?</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1) Look at the FAQ Wiki. This is a bit old, we are trying to bring it up to date.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2) Check out the Online Forums. Ask questions and discuss features.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3) Try the Internal RetroShare Forums </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;"> - These come online once you are connected to friends.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">4) If you are still stuck. Email us.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Enjoy Retrosharing</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:12pt;">Having trouble getting started with RetroShare?</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">1) Look at the FAQ Wiki. This is a bit old, we are trying to bring it up to date.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">2) Check out the Online Forums. Ask questions and discuss features.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">3) Try the Internal RetroShare Forums </span></p> +<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:12pt;"> - These come online once you are connected to friends.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">4) If you are still stuck. Email us.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></p> +<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:12pt;">Enjoy Retrosharing</span></p></body></html> - + @@ -454,7 +463,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -481,7 +490,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -494,7 +503,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical diff --git a/retroshare-gui/src/gui/HelpDialog.ui b/retroshare-gui/src/gui/HelpDialog.ui index 66884029f..3d40a8a90 100644 --- a/retroshare-gui/src/gui/HelpDialog.ui +++ b/retroshare-gui/src/gui/HelpDialog.ui @@ -56,7 +56,7 @@ 6 - + @@ -72,13 +72,13 @@ - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" 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-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" 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-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" 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-weight:600;">It lets you share securely your friends, </span></p> @@ -97,16 +97,6 @@ p, li { white-space: pre-wrap; } - - - - QFrame::StyledPanel - - - QFrame::Raised - - - @@ -223,7 +213,7 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; 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; font-weight:600;">RetroShare Translations:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> diff --git a/retroshare-gui/src/gui/HomePage.ui b/retroshare-gui/src/gui/HomePage.ui index 60743b3c1..5de0fa6fe 100644 --- a/retroshare-gui/src/gui/HomePage.ui +++ b/retroshare-gui/src/gui/HomePage.ui @@ -89,6 +89,8 @@ 11 + 75 + true @@ -105,7 +107,7 @@ ... - + :/icons/help_64.png:/icons/help_64.png @@ -289,6 +291,13 @@ private and secure decentralized communication platform. + + + 15 + 75 + true + + Add friend @@ -415,8 +424,8 @@ private and secure decentralized communication platform. - + diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui index 6a681f142..f54a19b8c 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui @@ -355,7 +355,7 @@ - + 0 @@ -493,12 +493,16 @@ p, li { white-space: pre-wrap; } - - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 + + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1
-
- + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index e8c39e75d..2585a286c 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -259,7 +259,7 @@ IdDialog::IdDialog(QWidget *parent) ui->editButton->hide(); - ui->avlabel_Circles->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/circles.png")); + ui->avLabel_Circles->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/circles.png")); ui->headerTextLabel_Circles->setText(tr("Circles")); @@ -475,10 +475,10 @@ void IdDialog::clearPerson() { QFontMetricsF f(ui->avLabel_Person->font()) ; - ui->avLabel_Person->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); + ui->avLabel_Person->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation)); ui->headerTextLabel_Person->setText(tr("People")); - ui->inviteFrame->hide(); + ui->info_Frame_Invite->hide(); ui->avatarLabel->clear(); whileBlocking(ui->ownOpinion_CB)->setCurrentIndex(1); @@ -2490,7 +2490,7 @@ void IdDialog::sendInvite() { MessageComposer::sendInvite(id,false); - ui->inviteFrame->show(); + ui->info_Frame_Invite->show(); ui->inviteButton->setEnabled(false); } @@ -2572,9 +2572,9 @@ void IdDialog::removefromContacts() updateIdList(); } -void IdDialog::on_closeInfoFrameButton_clicked() +void IdDialog::on_closeInfoFrameButton_Invite_clicked() { - ui->inviteFrame->setVisible(false); + ui->info_Frame_Invite->setVisible(false); } // We need to use indexes here because saving items is not possible since they can be re-created. diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 4e465fc5d..403b3a437 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -89,7 +89,7 @@ private slots: void chatIdentityItem(QTreeWidgetItem* item); void sendMsg(); void copyRetroshareLink(); - void on_closeInfoFrameButton_clicked(); + void on_closeInfoFrameButton_Invite_clicked(); void updateSelection(); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 256849509..7b16da166 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -88,7 +88,14 @@ - + + + + 12 + 75 + true + + People @@ -287,7 +294,7 @@ - -155 + 0 0 634 523 @@ -295,7 +302,7 @@ - + 0 @@ -308,14 +315,19 @@ QFrame::Raised - + 12 - + + + + 22 + + People @@ -335,10 +347,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -359,6 +380,15 @@ + + + + 0 + 0 + 0 + + + @@ -379,6 +409,15 @@ + + + + 154 + 154 + 154 + + + @@ -409,7 +448,7 @@ QFrame::Box - + 6 @@ -423,7 +462,7 @@ 6 - + 16 @@ -442,14 +481,14 @@ - + Invite messages stay into your Outbox until an acknowledgement of receipt has been received. - + 16 @@ -803,7 +842,7 @@ border-image: url(:/images/closepressed.png) - + <html><head/><body><p><span style=" font-family:'Sans'; font-size:9pt;">Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the difference between friend's positive and negative opinions. If not, your own opinion gives the score.</span></p><p><span style=" font-family:'Sans'; font-size:9pt;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -1, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a non negative reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 5 days).</span></p><p><span style=" font-family:'Sans'; font-size:9pt;">You can change the thresholds and the time of inactivity to delete identities in preferences -&gt; people. </span></p></body></html> @@ -938,7 +977,7 @@ border-image: url(:/images/closepressed.png) detailsGroupBox usageStatisticsGBox - headerFramePerson + headerBFramePerson @@ -954,19 +993,19 @@ border-image: url(:/images/closepressed.png) - + QFrame::StyledPanel QFrame::Raised - + 12 - + 64 @@ -991,7 +1030,12 @@ border-image: url(:/images/closepressed.png) - + + + + 22 + + Circles @@ -1074,7 +1118,7 @@ border-image: url(:/images/closepressed.png) LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
RSTreeWidget @@ -1082,14 +1126,14 @@ border-image: url(:/images/closepressed.png)
gui/common/RSTreeWidget.h
- StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
- StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSTextBrowser diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index a77713e1e..9396a9758 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -77,7 +77,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) : /* Connect signals */ connect(ui->radioButton_GpgId, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); connect(ui->radioButton_Pseudo, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); - connect(ui->createButton, SIGNAL(clicked()), this, SLOT(submit())); + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(submit())); connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(ui->plainTextEdit_Tag, SIGNAL(textChanged()), this, SLOT(checkNewTag())); @@ -238,7 +238,7 @@ void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId) setWindowTitle(tr("Edit identity")); ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/person.png")); ui->headerFrame->setHeaderText(tr("Edit identity")); - ui->createButton->setText(tr("Update")); + ui->postButton->setText(tr("Update")); mStateHelper->setLoading(IDEDITDIALOG_LOADID, true); @@ -601,7 +601,7 @@ void IdEditDialog::createId() if(rsIdentity->createIdentity(keyId,params.nickname,params.mImage,!params.isPgpLinked,gpg_password)) { - ui->createButton->setEnabled(false); + ui->postButton->setEnabled(false); if(!keyId.isNull()) { diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.ui b/retroshare-gui/src/gui/Identity/IdEditDialog.ui index e30c12d8a..1b4e53186 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.ui @@ -55,10 +55,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -79,6 +88,15 @@ + + + + 0 + 0 + 0 + + + @@ -99,6 +117,15 @@ + + + + 154 + 154 + 154 + + + @@ -120,6 +147,11 @@ + + + 12 + + true @@ -365,7 +397,7 @@ QFrame::Raised - + @@ -477,7 +509,7 @@ - + 9 @@ -507,7 +539,14 @@ - + + + + 12 + 75 + true + + Create diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 8ba6a0a90..bf5dc6230 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -247,12 +247,13 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) statusBar()->setVisible(Settings->valueFromGroup("StatusBar", "ShowStatusBar", QVariant(true)).toBool()); /* initialize combobox in status bar */ - statusComboBox = new QComboBox(statusBar()); + statusComboBox = new RSComboBox(statusBar()); statusComboBox->setVisible(Settings->valueFromGroup("StatusBar", "ShowStatus", QVariant(true)).toBool()); statusComboBox->setFocusPolicy(Qt::ClickFocus); initializeStatusObject(statusComboBox, true); QWidget *widget = new QWidget(); + widget->setObjectName("trans_statusComboBoxFrame"); QHBoxLayout *hbox = new QHBoxLayout(); hbox->setMargin(0); hbox->setSpacing(6); @@ -1300,7 +1301,7 @@ static void setStatusObject(QObject *pObject, int nStatus) } return; } - QComboBox *pComboBox = dynamic_cast(pObject); + RSComboBox *pComboBox = dynamic_cast(pObject); if (pComboBox) { /* set index of combobox */ int nIndex = pComboBox->findData(nStatus, Qt::UserRole); @@ -1389,7 +1390,7 @@ void MainWindow::initializeStatusObject(QObject *pObject, bool bConnect) } } else { /* initialize combobox */ - QComboBox *pComboBox = dynamic_cast(pObject); + RSComboBox *pComboBox = dynamic_cast(pObject); if (pComboBox) { pComboBox->addItem(QIcon(StatusDefs::imageStatus(RS_STATUS_ONLINE)), StatusDefs::name(RS_STATUS_ONLINE), RS_STATUS_ONLINE); pComboBox->addItem(QIcon(StatusDefs::imageStatus(RS_STATUS_BUSY)), StatusDefs::name(RS_STATUS_BUSY), RS_STATUS_BUSY); @@ -1613,7 +1614,7 @@ void MainWindow::switchVisibilityStatus(StatusElement e,bool b) //{ // ServicePermissionDialog::showYourself(); //} -QComboBox *MainWindow::statusComboBoxInstance() +RSComboBox *MainWindow::statusComboBoxInstance() { return statusComboBox; } diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h index be459d295..e34fda42a 100644 --- a/retroshare-gui/src/gui/MainWindow.h +++ b/retroshare-gui/src/gui/MainWindow.h @@ -25,12 +25,12 @@ #include #include "gui/common/rwindow.h" +#include "gui/common/RSComboBox.h" namespace Ui { class MainWindow; } -class QComboBox; class QLabel; class QActionGroup; class QListWidgetItem; @@ -174,7 +174,7 @@ public: void removeStatusObject(QObject *pObject); void setStatus(QObject *pObject, int nStatus); - QComboBox *statusComboBoxInstance(); + RSComboBox *statusComboBoxInstance(); PeerStatus *peerstatusInstance(); NATStatus *natstatusInstance(); DHTStatus *dhtstatusInstance(); @@ -294,7 +294,7 @@ private: QAction *toggleVisibilityAction, *toolAct; QList userNotifyList; - QComboBox *statusComboBox; + RSComboBox *statusComboBox; PeerStatus *peerstatus; NATStatus *natstatus; DHTStatus *dhtstatus; diff --git a/retroshare-gui/src/gui/MainWindow.ui b/retroshare-gui/src/gui/MainWindow.ui index d1dc1c2f7..55a7145e0 100644 --- a/retroshare-gui/src/gui/MainWindow.ui +++ b/retroshare-gui/src/gui/MainWindow.ui @@ -33,6 +33,11 @@ 0 + + + 12 + + QFrame::NoFrame @@ -143,7 +148,7 @@ - + :/images/add-share24.png:/images/add-share24.png @@ -161,7 +166,7 @@ - + :/images/messenger.png:/images/messenger.png @@ -187,7 +192,7 @@ - + :/images/exit_24x24.png:/images/exit_24x24.png diff --git a/retroshare-gui/src/gui/MessengerWindow.ui b/retroshare-gui/src/gui/MessengerWindow.ui index 7e952e86b..cc81303b8 100644 --- a/retroshare-gui/src/gui/MessengerWindow.ui +++ b/retroshare-gui/src/gui/MessengerWindow.ui @@ -74,7 +74,7 @@ - + true @@ -124,7 +124,7 @@ - + 0 @@ -175,7 +175,7 @@ 0 0 258 - 21 + 27 @@ -199,6 +199,11 @@
gui/LogoBar.h
1
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/NetworkDialog.h b/retroshare-gui/src/gui/NetworkDialog.h index 6a5b1c367..216cd8cc5 100644 --- a/retroshare-gui/src/gui/NetworkDialog.h +++ b/retroshare-gui/src/gui/NetworkDialog.h @@ -43,6 +43,7 @@ class NetworkDialog : public RsAutoUpdatePage Q_PROPERTY(QColor backgroundColorAcceptConnection READ backgroundColorAcceptConnection WRITE setBackgroundColorAcceptConnection) Q_PROPERTY(QColor backgroundColorHasSignedMe READ backgroundColorHasSignedMe WRITE setBackgroundColorHasSignedMe) Q_PROPERTY(QColor backgroundColorDenied READ backgroundColorDenied WRITE setBackgroundColorDenied) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) public: /** Default Constructor */ @@ -55,12 +56,14 @@ public: QColor backgroundColorAcceptConnection() const { return mBackgroundColorAcceptConnection; } QColor backgroundColorHasSignedMe() const { return mBackgroundColorHasSignedMe; } QColor backgroundColorDenied() const { return mBackgroundColorDenied; } + QColor textColor() const { return mTextColor; } void setBackgroundColorSelf(QColor color) { PGPIdItemModel->setBackgroundColorSelf(color); mBackgroundColorSelf = color; } void setBackgroundColorOwnSign(QColor color) { PGPIdItemModel->setBackgroundColorOwnSign(color); mBackgroundColorOwnSign = color; } void setBackgroundColorAcceptConnection(QColor color) { PGPIdItemModel->setBackgroundColorAcceptConnection(color); mBackgroundColorAcceptConnection = color; } void setBackgroundColorHasSignedMe(QColor color) { PGPIdItemModel->setBackgroundColorHasSignedMe(color); mBackgroundColorHasSignedMe = color; } void setBackgroundColorDenied(QColor color) { PGPIdItemModel->setBackgroundColorDenied(color); mBackgroundColorDenied = color; } + void setTextColor(QColor color) { PGPIdItemModel->setTextColor(color); mTextColor = color; } protected: void changeEvent(QEvent *e); @@ -89,12 +92,13 @@ private: void removeKeys(std::set selected) ; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mBackgroundColorSelf; QColor mBackgroundColorOwnSign; QColor mBackgroundColorAcceptConnection; QColor mBackgroundColorHasSignedMe; QColor mBackgroundColorDenied; + QColor mTextColor; RSTreeWidgetItemCompareRole *compareNetworkRole ; diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp index 96ab24e92..49bba065f 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp @@ -299,6 +299,10 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const } } } + else if(role == Qt::ForegroundRole) + { + return QBrush(mTextColor); + } return QVariant(); } diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h index 1e38e0461..c4ae73400 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h @@ -60,6 +60,7 @@ public: void setBackgroundColorAcceptConnection(QColor color) { mBackgroundColorAcceptConnection = color; } void setBackgroundColorHasSignedMe(QColor color) { mBackgroundColorHasSignedMe = color; } void setBackgroundColorDenied(QColor color) { mBackgroundColorDenied = color; } + void setTextColor(QColor color) { mTextColor = color; } public slots: @@ -73,6 +74,7 @@ private: QColor mBackgroundColorAcceptConnection; QColor mBackgroundColorHasSignedMe; QColor mBackgroundColorDenied; + QColor mTextColor; }; #endif // KEY_ITEM_MODEL_H diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 4e59685b3..d86ba2d7a 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -504,7 +504,7 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr event) MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")")); } -void NewsFeed::testFeeds(uint notifyFlags) +void NewsFeed::testFeeds(uint /*notifyFlags*/) { #ifdef TO_REMOVE if (!instance) { diff --git a/retroshare-gui/src/gui/NewsFeed.ui b/retroshare-gui/src/gui/NewsFeed.ui index 1314c60c7..32a679a74 100644 --- a/retroshare-gui/src/gui/NewsFeed.ui +++ b/retroshare-gui/src/gui/NewsFeed.ui @@ -67,7 +67,14 @@
- + + + + 12 + 75 + true + + Activity Stream @@ -87,7 +94,7 @@ - + @@ -143,9 +150,9 @@ - StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSFeedWidget diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index 2d1e7de4e..ef39eac4a 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -138,14 +138,14 @@
- + 0 1 - + 0 @@ -185,8 +185,8 @@ p, li { white-space: pre-wrap; } 0 0 - 757 - 395 + 741 + 316 diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui b/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui index 23b0a462f..ee8c173fc 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui @@ -28,7 +28,7 @@ - + 0 @@ -111,6 +111,13 @@
+ + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index cf809286c..7be276b77 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -153,7 +153,7 @@
- + 50 % @@ -302,6 +302,13 @@
+ + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 19230a67f..e5476486f 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -61,7 +61,7 @@ Edit Album Details - + :/images/edit_16.png:/images/edit_16.png @@ -186,6 +186,11 @@ + + + 12 + + My Albums @@ -212,6 +217,11 @@ + + + 12 + + Subscribed Albums @@ -238,6 +248,11 @@ + + + 12 + + Shared Albums @@ -286,7 +301,7 @@ 0 0 804 - 208 + 205 @@ -322,7 +337,7 @@ 0 0 804 - 208 + 205 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui index b8509703e..03c5093ad 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui @@ -24,6 +24,11 @@ 0 + + + 12 + + Album Name @@ -155,8 +160,6 @@
- - diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp index 7dc90eb82..241c713d1 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp @@ -108,15 +108,15 @@ void BoardPostDisplayWidgetBase::makeUpVote() void BoardPostDisplayWidgetBase::setReadStatus(bool isNew, bool isUnread) { if (isUnread) - readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); + readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); else - readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); + readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); - newLabel()->setVisible(isNew); + newLabel()->setVisible(isNew); - mainFrame()->setProperty("new", isNew); - mainFrame()->style()->unpolish(mainFrame()); - mainFrame()->style()->polish(mainFrame()); + feedFrame()->setProperty("new", isNew); + feedFrame()->style()->unpolish(feedFrame()); + feedFrame()->style()->polish( feedFrame()); } void BoardPostDisplayWidget_compact::doExpand(bool e) @@ -174,8 +174,9 @@ void BoardPostDisplayWidgetBase::setup() menu->addAction(CopyLinkAction); menu->addSeparator(); shareButton()->setMenu(menu); + shareButton()->setPopupMode(QToolButton::InstantPopup); - connect(shareButton(),SIGNAL(pressed()),this,SLOT(handleShareButtonClicked())); + connect(menu,SIGNAL(aboutToShow()),this,SLOT(handleShareButtonClicked())); RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId); bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE); @@ -293,17 +294,17 @@ void BoardPostDisplayWidgetBase::handleCopyLinkClicked() BoardPostDisplayWidget_compact::BoardPostDisplayWidget_compact(const RsPostedPost& post, uint8_t display_flags,QWidget *parent=nullptr) : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_compact()) { - ui->setupUi(this); - setup(); + ui->setupUi(this); + setup(); - ui->verticalLayout->addStretch(); - ui->verticalLayout->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->verticalLayout_2->addStretch(); + ui->right_VL->addStretch(); + ui->right_VL->setAlignment(Qt::AlignTop); + ui->topLayout->setAlignment(Qt::AlignTop); + ui->arrowsLayout->addStretch(); + ui->arrowsLayout->setAlignment(Qt::AlignTop); + ui->feedFrame_VL->addStretch(); - adjustSize(); + adjustSize(); } BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact() @@ -414,9 +415,9 @@ QLabel *BoardPostDisplayWidget_compact::dateLabel() { return ui->da QLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; } QLabel *BoardPostDisplayWidget_compact::scoreLabel() { return ui->scoreLabel; } QLabel *BoardPostDisplayWidget_compact::notes() { return ui->notes; } -QPushButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; } +QToolButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; } QLabel *BoardPostDisplayWidget_compact::pictureLabel() { return ui->pictureLabel; } -QFrame *BoardPostDisplayWidget_compact::mainFrame() { return ui->mainFrame; } +QFrame *BoardPostDisplayWidget_compact::feedFrame() { return ui->feedFrame; } //=================================================================================================================================== //== class BoardPostDisplayWidget_card == @@ -425,17 +426,17 @@ QFrame *BoardPostDisplayWidget_compact::mainFrame() { return ui->ma BoardPostDisplayWidget_card::BoardPostDisplayWidget_card(const RsPostedPost& post, uint8_t display_flags, QWidget *parent) : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_card()) { - ui->setupUi(this); - setup(); + ui->setupUi(this); + setup(); - ui->verticalLayout->addStretch(); - ui->verticalLayout->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->verticalLayout_2->addStretch(); + ui->right_VL->addStretch(); + ui->right_VL->setAlignment(Qt::AlignTop); + ui->topLayout->setAlignment(Qt::AlignTop); + ui->arrowsLayout->addStretch(); + ui->arrowsLayout->setAlignment(Qt::AlignTop); + ui->feedFrame_VL->addStretch(); - adjustSize(); + adjustSize(); } BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card() @@ -493,7 +494,7 @@ QLabel *BoardPostDisplayWidget_card::dateLabel() { return ui->dateL QLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; } QLabel *BoardPostDisplayWidget_card::scoreLabel() { return ui->scoreLabel; } QLabel *BoardPostDisplayWidget_card::notes() { return ui->notes; } -QPushButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; } +QToolButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; } QLabel *BoardPostDisplayWidget_card::pictureLabel() { return ui->pictureLabel; } -QFrame *BoardPostDisplayWidget_card::mainFrame() { return ui->mainFrame; } +QFrame *BoardPostDisplayWidget_card::feedFrame() { return ui->feedFrame; } diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h index 32ce60a2a..a6d4a04d6 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h @@ -78,8 +78,8 @@ protected slots: virtual QLabel *notes() =0; virtual QLabel *pictureLabel()=0; virtual QToolButton *readButton() =0; - virtual QPushButton *shareButton() =0; - virtual QFrame *mainFrame() =0; + virtual QToolButton *shareButton() =0; + virtual QFrame *feedFrame() =0; void loadComments(bool e); void readToggled(); @@ -126,8 +126,8 @@ public: QLabel *notes() override; QLabel *pictureLabel() override; QToolButton *readButton() override; - QPushButton *shareButton() override; - QFrame *mainFrame() override; + QToolButton *shareButton() override; + QFrame *feedFrame() override; public slots: void viewPicture() ; @@ -164,9 +164,9 @@ public: QLabel *scoreLabel() override; QLabel *notes() override; QToolButton *readButton() override; - QPushButton *shareButton() override; + QToolButton *shareButton() override; QLabel *pictureLabel() override; - QFrame *mainFrame() override; + QFrame *feedFrame() override; protected slots: /* GxsGroupFeedItem */ diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui index 42dc90f44..28ce4fd1d 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui @@ -22,7 +22,7 @@ - + 0 @@ -42,7 +42,7 @@ 2 - + 0 @@ -55,7 +55,7 @@ QFrame::Raised - + 2 @@ -127,10 +127,10 @@ - + - 9 + 14 @@ -177,9 +177,9 @@ - + - + 5 @@ -199,8 +199,8 @@ - 50 - false + 75 + true @@ -277,7 +277,7 @@ - + Qt::Horizontal @@ -295,7 +295,7 @@ - + 0 @@ -304,9 +304,9 @@ - Arial - 10 + 12 75 + true true @@ -340,7 +340,7 @@ - + Qt::Horizontal @@ -371,7 +371,7 @@ - + @@ -393,7 +393,7 @@ - + Share @@ -401,13 +401,16 @@ :/images/share.png:/images/share.png - + true + + Qt::ToolButtonTextBesideIcon + - + Qt::Horizontal @@ -436,15 +439,10 @@ QLabel
gui/gxs/GxsIdLabel.h
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- + diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui index 411d4583e..f27524f08 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui @@ -22,7 +22,7 @@ - + 0 @@ -42,7 +42,7 @@ 2 - + 0 @@ -55,7 +55,7 @@ QFrame::Raised - + 2 @@ -89,78 +89,80 @@ 2 - - - - - - 0 - 0 - - - - Vote up - - - - - - - :/images/up-arrow.png:/images/up-arrow.png - - - true - - - - - - - - 9 - - - - 0 - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Vote down - - - - - - \/ - - - - :/images/down-arrow.png:/images/down-arrow.png - - - true - - - - + + + + + + + 0 + 0 + + + + Vote up + + + + + + + :/images/up-arrow.png:/images/up-arrow.png + + + true + + + + + + + + 14 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Vote down + + + + + + \/ + + + + :/images/down-arrow.png:/images/down-arrow.png + + + true + + + + + @@ -182,12 +184,12 @@ - + 3 - + 0 @@ -196,9 +198,9 @@ - Arial - 10 + 12 75 + true true @@ -220,7 +222,7 @@ - + 6 @@ -243,8 +245,8 @@ - 50 - false + 75 + true @@ -285,7 +287,7 @@ - + Qt::Horizontal @@ -303,7 +305,7 @@
- + @@ -345,7 +347,7 @@ - + Share @@ -353,7 +355,10 @@ :/images/share.png:/images/share.png - + + Qt::ToolButtonTextBesideIcon + + true @@ -395,7 +400,7 @@ - + Qt::Horizontal @@ -421,7 +426,7 @@ QFrame::Raised - + 2 @@ -474,11 +479,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
GxsIdLabel QLabel diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index e0d4dce64..e1e7a21e5 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -24,6 +24,7 @@ MS Sans Serif 11 75 + true true @@ -36,14 +37,14 @@
- + 0 0 - + 0 @@ -133,7 +134,10 @@ MS Sans Serif - 9 + 11 + 75 + true + true diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index b7ead3c0b..9824cfda2 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -104,12 +104,12 @@ void PostedCardView::setReadStatus(bool isNew, bool isUnread) ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } -void PostedCardView::setComment(const RsGxsComment& cmt) {} +void PostedCardView::setComment(const RsGxsComment& /*cmt*/) {} PostedCardView::~PostedCardView() { @@ -192,11 +192,11 @@ void PostedCardView::fill() ui->dateLabel->setText(timestamp); } else { - QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); + //QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); mInFill = true; - int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); - int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); + //int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); + //int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); @@ -211,7 +211,6 @@ void PostedCardView::fill() // The only combination that seems to work: load as EncodedUrl, extract toEncoded(). QByteArray urlarray(mPost.mLink.c_str()); QUrl url = QUrl::fromEncoded(urlarray.trimmed()); - QString urlstr = "Invalid Link"; QString sitestr = "Invalid Link"; bool urlOkay = url.isValid(); @@ -230,7 +229,7 @@ void PostedCardView::fill() if (urlOkay) { - urlstr = QString(" "); urlstr += messageName(); @@ -259,7 +258,6 @@ void PostedCardView::fill() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap scaledpixmap; if(pixmap.width() > 800){ QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); ui->pictureLabel->setPixmap(scaledpixmap); @@ -267,14 +265,14 @@ void PostedCardView::fill() ui->pictureLabel->setPixmap(pixmap); } } - else if (mPost.mImage.mData == NULL) + else //if (mPost.mImage.mData == NULL) { ui->picture_frame->hide(); } - else - { - ui->picture_frame->show(); - } + //else + //{ + // ui->picture_frame->show(); + //} } //QString score = "Hot" + QString::number(post.mHotScore); diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index 8cbbd4d56..a55acad24 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -33,7 +33,7 @@ 0 - + 0 @@ -49,7 +49,7 @@ QFrame::Sunken - + 0 @@ -69,7 +69,7 @@ 6 - + 0 @@ -78,9 +78,9 @@ - Arial - 10 + 11 75 + true true @@ -290,10 +290,10 @@ - + - 9 + 14 @@ -506,11 +506,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
GxsIdLabel QLabel @@ -518,9 +513,9 @@
- + diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 6bbfa3e37..9c08c8169 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -53,10 +53,10 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou ui->setupUi(this); Settings->loadWidgetInformation(this); - connect(ui->submitButton, SIGNAL(clicked()), this, SLOT(createPost())); + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createPost())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->addPicButton, SIGNAL(clicked() ), this , SLOT(addPicture())); - connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->submitButton, SLOT(setEnabled(bool))); + connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->postButton, SLOT(setEnabled(bool))); ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/postedlinks.png")); ui->headerFrame->setHeaderText(tr("Create a new Post")); @@ -74,13 +74,13 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, default_author); QSignalMapper *signalMapper = new QSignalMapper(this); - connect(ui->postButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - connect(ui->imageButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - connect(ui->linkButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewPostButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewImageButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewLinkButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - signalMapper->setMapping(ui->postButton, VIEW_POST); - signalMapper->setMapping(ui->imageButton, VIEW_IMAGE); - signalMapper->setMapping(ui->linkButton, VIEW_LINK); + signalMapper->setMapping(ui->viewPostButton, VIEW_POST); + signalMapper->setMapping(ui->viewImageButton, VIEW_IMAGE); + signalMapper->setMapping(ui->viewLinkButton, VIEW_LINK); connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setPage(int))); ui->removeButton->hide(); @@ -189,7 +189,7 @@ void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString())); ui->linkEdit->setText(link.toString()); } - ui->submitButton->setEnabled(true); + ui->postButton->setEnabled(true); ui->addPicButton->setEnabled(true); } @@ -233,7 +233,7 @@ void PostedCreatePostDialog::addPicture() //If still yes then link it if(answer == QMessageBox::Yes) { - ui->submitButton->setEnabled(false); + ui->postButton->setEnabled(false); ui->addPicButton->setEnabled(false); QStringList files; files.append(imagefilename); @@ -245,11 +245,11 @@ void PostedCreatePostDialog::addPicture() int PostedCreatePostDialog::viewMode() { - if (ui->postButton->isChecked()) { + if (ui->viewPostButton->isChecked()) { return VIEW_POST; - } else if (ui->imageButton->isChecked()) { + } else if (ui->viewImageButton->isChecked()) { return VIEW_IMAGE; - } else if (ui->linkButton->isChecked()) { + } else if (ui->viewLinkButton->isChecked()) { return VIEW_LINK; } @@ -263,25 +263,25 @@ void PostedCreatePostDialog::setPage(int viewMode) case VIEW_POST: ui->stackedWidget->setCurrentIndex(0); - ui->postButton->setChecked(true); - ui->imageButton->setChecked(false); - ui->linkButton->setChecked(false); + ui->viewPostButton->setChecked(true); + ui->viewImageButton->setChecked(false); + ui->viewLinkButton->setChecked(false); break; case VIEW_IMAGE: ui->stackedWidget->setCurrentIndex(1); - ui->imageButton->setChecked(true); - ui->postButton->setChecked(false); - ui->linkButton->setChecked(false); + ui->viewImageButton->setChecked(true); + ui->viewPostButton->setChecked(false); + ui->viewLinkButton->setChecked(false); break; case VIEW_LINK: ui->stackedWidget->setCurrentIndex(2); - ui->linkButton->setChecked(true); - ui->postButton->setChecked(false); - ui->imageButton->setChecked(false); + ui->viewLinkButton->setChecked(true); + ui->viewPostButton->setChecked(false); + ui->viewImageButton->setChecked(false); break; default: diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index bd44c4d0a..a9ae69b46 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -40,21 +40,21 @@
- + QFrame::StyledPanel QFrame::Raised - + 0 - + 0 @@ -73,7 +73,7 @@ - + 0 @@ -104,7 +104,7 @@ Preview - + 0 @@ -115,7 +115,7 @@ 0 - + Qt::Horizontal @@ -128,7 +128,7 @@ - + Qt::Horizontal @@ -143,17 +143,17 @@ - 0 + 1 - + - + 9 - + Qt::Horizontal @@ -190,7 +190,7 @@ - + Qt::Horizontal @@ -203,7 +203,7 @@ - + Qt::Vertical @@ -218,7 +218,7 @@ - + Qt::Horizontal @@ -233,7 +233,7 @@ - + 2 @@ -267,7 +267,7 @@ - + Qt::Horizontal @@ -305,7 +305,7 @@
- + 0 @@ -323,7 +323,7 @@
- + Qt::Vertical @@ -340,7 +340,7 @@ - + @@ -367,13 +367,20 @@ - + 0 0 + + + 12 + 75 + true + + @@ -399,12 +406,12 @@ - + 2 - + Post @@ -424,7 +431,7 @@ - + Image @@ -450,7 +457,7 @@ - + Link @@ -473,7 +480,7 @@ - + Qt::Horizontal @@ -488,10 +495,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -512,6 +528,15 @@ + + + + 0 + 0 + 0 + + + @@ -532,6 +557,15 @@ + + + + 154 + 154 + 154 + + + @@ -553,6 +587,11 @@ + + + 12 + + true @@ -584,7 +623,7 @@ - + 6 @@ -613,15 +652,9 @@ - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
HeaderFrame @@ -629,21 +662,22 @@
gui/common/HeaderFrame.h
1
- - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
-
RichTextEdit QWidget
util/RichTextEdit.h
1
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
- + diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index fa79b9d70..90f393dab 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -705,9 +705,9 @@ void PostedItem::setReadStatus(bool isNew, bool isUnread) //ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index f16c7b100..fc316a632 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -33,7 +33,7 @@ 0 - + 0 @@ -49,7 +49,7 @@ QFrame::Sunken - + 0 @@ -125,7 +125,12 @@ - + + + + 14 + + 0 @@ -248,7 +253,7 @@ 6 - + 0 @@ -257,7 +262,9 @@ + 11 75 + true true @@ -327,6 +334,7 @@ + 11 75 true true @@ -718,15 +726,10 @@
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
ElidedLabel QLabel -
gui/common/ElidedLabel.h
+
gui/common/ElidedLabel.h
1
@@ -741,9 +744,9 @@
- + diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index a88a1d6b5..c5f95aa24 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -102,7 +102,7 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent available posts from your subscribed friends, and make the \ links visible to all other friends.

Afterwards you can unsubscribe from the context menu of the links list at left.

")); - ui->infoframe->hide(); + ui->infoFrame->hide(); /* load settings */ processSettings(true); @@ -417,7 +417,7 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group) if (IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) { - ui->infoframe->hide(); + ui->infoFrame->hide(); } else { @@ -472,7 +472,7 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group) ui->infoDistribution->setText(distrib_string); - ui->infoframe->show(); + ui->infoFrame->show(); } } @@ -771,7 +771,7 @@ void PostedListWidget::applyRanking() void PostedListWidget::blank() { clearPosts(); - ui->infoframe->hide(); + ui->infoFrame->hide(); } void PostedListWidget::clearPosts() { diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.ui b/retroshare-gui/src/gui/Posted/PostedListWidget.ui index f59ee76ee..22f1761ca 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.ui @@ -30,7 +30,7 @@ 0 - + QFrame::Box @@ -106,7 +106,7 @@ - + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -260,7 +260,7 @@ - + QFrame::StyledPanel @@ -323,7 +323,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; 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> @@ -515,7 +515,10 @@ p, li { white-space: pre-wrap; } - 14 + 11 + 75 + true + true @@ -658,16 +661,21 @@ p, li { white-space: pre-wrap; } QLabel
gui/gxs/GxsIdLabel.h
- - SubscribeToolButton - QToolButton -
gui/common/SubscribeToolButton.h
-
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + SubscribeToolButton + QToolButton +
gui/common/SubscribeToolButton.h
+
diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp index 8ff178af6..087eebe3c 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp @@ -923,7 +923,7 @@ void PostedListWidgetWithModel::insertBoardDetails(const RsPostedGroup& group) formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag); - ui->infoDescription->setText(formatDescription); + ui->trans_Description->setText(formatDescription); ui->infoAdministrator->setId(group.mMeta.mAuthorId) ; link = RetroShareLink::createMessage(group.mMeta.mAuthorId, ""); diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui index ccba99f67..0433fe838 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui @@ -46,7 +46,7 @@
- + @@ -54,7 +54,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; 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>
@@ -271,9 +271,10 @@ p, li { white-space: pre-wrap; } - 50 + 15 + 75 false - false + true @@ -300,7 +301,7 @@ p, li { white-space: pre-wrap; }
- + 0 @@ -309,7 +310,9 @@ p, li { white-space: pre-wrap; } + 11 75 + true true @@ -344,7 +347,7 @@ p, li { white-space: pre-wrap; } - + QFrame::Box @@ -372,6 +375,12 @@ p, li { white-space: pre-wrap; } 0 + + + 75 + true + + Create Post @@ -394,7 +403,13 @@ p, li { white-space: pre-wrap; } - + + + + 75 + true + + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -572,14 +587,15 @@ p, li { white-space: pre-wrap; } - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
+ ElidedLabel + QLabel +
gui/common/ElidedLabel.h
+ 1
- SubscribeToolButton - QToolButton -
gui/common/SubscribeToolButton.h
+ GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
GxsIdLabel @@ -587,15 +603,14 @@ p, li { white-space: pre-wrap; }
gui/gxs/GxsIdLabel.h
- RSTreeView - QTreeView -
gui/common/RSTreeView.h
- 1 + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
- StyledElidedLabel - QLabel -
gui/common/StyledElidedLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSTabWidget @@ -604,9 +619,15 @@ p, li { white-space: pre-wrap; } 1 - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
+ RSTreeView + QTreeView +
gui/common/RSTreeView.h
+ 1 +
+ + SubscribeToolButton + QToolButton +
gui/common/SubscribeToolButton.h
diff --git a/retroshare-gui/src/gui/QuickStartWizard.cpp b/retroshare-gui/src/gui/QuickStartWizard.cpp index f442d2f1b..200e75948 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.cpp +++ b/retroshare-gui/src/gui/QuickStartWizard.cpp @@ -20,20 +20,23 @@ #include "QuickStartWizard.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "gui/common/FilesDefs.h" +#ifdef USE_COMBOBOX +#include "gui/common/RSComboBox.h" +#endif #include "settings/rsharesettings.h" #include "util/QtVersion.h" -#include "gui/common/FilesDefs.h" + +#include "retroshare/rsfiles.h" +#include "retroshare/rsconfig.h" +#include "retroshare/rspeers.h" +#include "retroshare/rstypes.h" + +#include +#include +#include +#include +#include QuickStartWizard::QuickStartWizard(QWidget *parent) : QDialog(parent) @@ -53,7 +56,7 @@ QuickStartWizard::QuickStartWizard(QWidget *parent) : // ui.checkBoxF2FRouting->setChecked(true) ; // ui.checkBoxF2FRouting->setEnabled(false) ; - connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) ); + connect( ui.netModeComboBox, SIGNAL( activated(int) ), this, SLOT( toggleUPnP() ) ); // connect( ui.checkBoxTunnelConnection, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) ); // bool b = rsPeers->getAllowTunnelConnection() ; @@ -299,7 +302,7 @@ void QuickStartWizard::loadShare() listWidget->insertRow(row) ; listWidget->setItem(row,0,new QTableWidgetItem(QString::fromStdString((*it).filename))); #ifdef USE_COMBOBOX - QComboBox *cb = new QComboBox ; + RSComboBox *cb = new RSComboBox ; cb->addItem(tr("Network Wide")) ; cb->addItem(tr("Browsable")) ; cb->addItem(tr("Universal")) ; @@ -494,7 +497,6 @@ void QuickStartWizard::loadNetwork() void QuickStartWizard::saveChanges() { - QString str; //bool saveAddr = false; diff --git a/retroshare-gui/src/gui/QuickStartWizard.ui b/retroshare-gui/src/gui/QuickStartWizard.ui index ede111c52..fc8832637 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.ui +++ b/retroshare-gui/src/gui/QuickStartWizard.ui @@ -334,7 +334,7 @@ p, li { white-space: pre-wrap; }
- + Automatic (UPnP) @@ -360,7 +360,7 @@ p, li { white-space: pre-wrap; } - + Public: DHT & Discovery @@ -1072,6 +1072,11 @@ p, li { white-space: pre-wrap; }
gui/common/HeaderFrame.h
1 + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/ServicePermissionDialog.ui b/retroshare-gui/src/gui/ServicePermissionDialog.ui index 0acd51c75..7354fe9ae 100644 --- a/retroshare-gui/src/gui/ServicePermissionDialog.ui +++ b/retroshare-gui/src/gui/ServicePermissionDialog.ui @@ -16,8 +16,17 @@ true - - + + + 0 + + + 0 + + + 0 + + 0 @@ -37,14 +46,14 @@
- + QFrame::StyledPanel QFrame::Raised - + @@ -69,7 +78,7 @@ - frame + gradFrame headerFrame diff --git a/retroshare-gui/src/gui/ShareManager.cpp b/retroshare-gui/src/gui/ShareManager.cpp index 8f4e32542..6681e30c5 100644 --- a/retroshare-gui/src/gui/ShareManager.cpp +++ b/retroshare-gui/src/gui/ShareManager.cpp @@ -66,7 +66,7 @@ ShareManager::ShareManager() Settings->loadWidgetInformation(this); connect(ui.addButton, SIGNAL(clicked( bool ) ), this , SLOT( addShare() ) ); - connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(ui.shareddirList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(shareddirListCustomPopupMenu(QPoint))); diff --git a/retroshare-gui/src/gui/ShareManager.ui b/retroshare-gui/src/gui/ShareManager.ui index e20074f9a..2799737c9 100644 --- a/retroshare-gui/src/gui/ShareManager.ui +++ b/retroshare-gui/src/gui/ShareManager.ui @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -47,14 +47,14 @@ - + QFrame::NoFrame QFrame::Raised - + 6 @@ -63,10 +63,7 @@ Shared Folder Manager - - - 2 - + @@ -97,7 +94,7 @@ false - 22 + 43 @@ -132,17 +129,12 @@ - - - 0 - 0 - - - - - 200 - 200 - + + + 12 + 75 + true + Add a Share Directory @@ -150,16 +142,10 @@ Add new - - - 24 - 24 - - - + Qt::Horizontal @@ -172,7 +158,14 @@ - + + + + 12 + 75 + true + + Apply and close @@ -186,10 +179,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -210,6 +212,15 @@ + + + + 0 + 0 + 0 + + + @@ -230,6 +241,15 @@ + + + + 154 + 154 + 154 + + + @@ -251,6 +271,11 @@ + + + 12 + + true @@ -274,11 +299,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
HeaderFrame QFrame diff --git a/retroshare-gui/src/gui/StartDialog.ui b/retroshare-gui/src/gui/StartDialog.ui index a49d51e9b..8c491caeb 100644 --- a/retroshare-gui/src/gui/StartDialog.ui +++ b/retroshare-gui/src/gui/StartDialog.ui @@ -252,7 +252,7 @@
- + @@ -298,6 +298,8 @@ 12 + 75 + true @@ -355,16 +357,21 @@ p, li { white-space: pre-wrap; }
- - - - - LineEditClear QLineEdit
gui/common/LineEditClear.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + + + + diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index ee9c562a2..15fe997a6 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -35,7 +35,7 @@ PulseAddDialog::PulseAddDialog(QWidget *parent) { ui.setupUi(this); - connect(ui.pushButton_Post, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) ); + connect(ui.postButton, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) ); connect(ui.pushButton_AddURL, SIGNAL( clicked( void ) ), this, SLOT( addURL( void ) ) ); connect(ui.pushButton_ClearDisplayAs, SIGNAL( clicked( void ) ), this, SLOT( clearDisplayAs( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) ); @@ -98,10 +98,9 @@ void PulseAddDialog::cleanup() QLayout *layout = ui.widget_replyto->layout(); // completely delete layout and sublayouts QLayoutItem * item; - QWidget * widget; while ((item = layout->takeAt(0))) { - if ((widget = item->widget()) != 0) + if (QWidget *widget = item->widget()) { std::cerr << "PulseAddDialog::cleanup() removing widget"; std::cerr << std::endl; @@ -129,8 +128,8 @@ void PulseAddDialog::cleanup() ui.frame_URL->setEnabled(false); ui.frame_URL->hide(); - ui.pushButton_Post->setEnabled(false); - ui.pushButton_Post->setText(tr("Post")); + ui.postButton->setEnabled(false); + ui.postButton->setText(tr("Post")); ui.textEdit_Pulse->setPlaceholderText(tr("Whats happening?")); ui.frame_input->setVisible(true); ui.widget_sentiment->setVisible(true); @@ -163,12 +162,12 @@ void PulseAddDialog::pulseTextChanged() { std::string pulseText = ui.textEdit_Pulse->toPlainText().toStdString(); bool enable = (pulseText.size() > 0) && (pulseText.size() < PULSE_MAX_SIZE); - ui.pushButton_Post->setEnabled(enable); + ui.postButton->setEnabled(enable); } // Old Interface, deprecate / make internal. // TODO: Convert mReplyToPulse to be an SPtr, and remove &pulse parameter. -void PulseAddDialog::setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType) +void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &/*groupName*/, uint32_t replyType) { mIsReply = true; mReplyToPulse = pulse; @@ -191,21 +190,21 @@ void PulseAddDialog::setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std: if (mReplyType & WIRE_PULSE_TYPE_REPLY) { - ui.pushButton_Post->setText(tr("Reply to Pulse")); + ui.postButton->setText(tr("Reply to Pulse")); ui.textEdit_Pulse->setPlaceholderText(tr("Pulse your reply")); } else { // cannot add msg for like / republish. - ui.pushButton_Post->setEnabled(true); + ui.postButton->setEnabled(true); ui.frame_input->setVisible(false); ui.widget_sentiment->setVisible(false); if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) { - ui.pushButton_Post->setText(tr("Republish Pulse")); + ui.postButton->setText(tr("Republish Pulse")); ui.pushButton_picture->hide(); } else if (mReplyType & WIRE_PULSE_TYPE_LIKE) { - ui.pushButton_Post->setText(tr("Like Pulse")); + ui.postButton->setText(tr("Like Pulse")); ui.pushButton_picture->hide(); } } diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h index ab386df2e..258efb736 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h @@ -57,7 +57,7 @@ private slots: private: // OLD VERSIONs, private now. void setGroup(RsWireGroup &group); - void setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType); + void setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType); void postOriginalPulse(); void postReplyPulse(); diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui index 1b8fb24cc..940d8f895 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui @@ -13,7 +13,7 @@ - + 0 @@ -21,7 +21,7 @@ 6 - + 0 @@ -34,18 +34,12 @@ 16777215 - - QFrame::StyledPanel - - - QFrame::Raised - - + 0 - + 100 @@ -72,7 +66,7 @@ - + Qt::Horizontal @@ -86,6 +80,11 @@ + + + 12 + + GroupLabel @@ -118,13 +117,7 @@ - - QFrame::StyledPanel - - - QFrame::Raised - - + 0 @@ -142,7 +135,7 @@ - + 20 @@ -175,7 +168,7 @@ - + Qt::Horizontal @@ -188,14 +181,14 @@ - + Response Sentiment: - + 0 @@ -238,13 +231,7 @@ - - QFrame::StyledPanel - - - QFrame::Raised - - + 0 @@ -275,7 +262,7 @@ QFrame::Raised - + @@ -345,9 +332,9 @@ - + - + URL @@ -364,7 +351,7 @@ - + Display As @@ -387,7 +374,7 @@ - + 6 @@ -408,7 +395,7 @@ - + Qt::Horizontal @@ -421,7 +408,14 @@ - + + + + 12 + 75 + true + + Post @@ -444,9 +438,12 @@ QLabel
gui/gxs/GxsIdLabel.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
- - - + diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.cpp b/retroshare-gui/src/gui/TheWire/PulseReply.cpp index 92dccabf5..5067b5f9b 100644 --- a/retroshare-gui/src/gui/TheWire/PulseReply.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseReply.cpp @@ -50,7 +50,7 @@ void PulseReply::setup() // connect(pushButton_tmpViewGroup, SIGNAL(clicked()), this, SLOT(actionViewGroup())); // connect(pushButton_tmpViewParent, SIGNAL(clicked()), this, SLOT(actionViewParent())); - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); // connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate())); connect(toolButton_reply, SIGNAL(clicked()), this, SLOT(actionReply())); @@ -118,7 +118,7 @@ void PulseReply::setPulseStatus(PulseStatus status) { widget_actions->setVisible(status == PulseStatus::FULL); widget_follow->setVisible(status != PulseStatus::FULL); - toolButton_follow->setEnabled(status == PulseStatus::UNSUBSCRIBED); + followButton->setEnabled(status == PulseStatus::UNSUBSCRIBED); switch(status) { diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.ui b/retroshare-gui/src/gui/TheWire/PulseReply.ui index 1ffbbdf85..3af469f63 100644 --- a/retroshare-gui/src/gui/TheWire/PulseReply.ui +++ b/retroshare-gui/src/gui/TheWire/PulseReply.ui @@ -26,7 +26,7 @@ - + 0 @@ -48,7 +48,7 @@ QFrame::Raised - + 0 @@ -380,7 +380,14 @@ - + + + + 12 + 75 + true + + FOLLOW diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp index e8c830a0b..0948e745b 100644 --- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp @@ -48,7 +48,7 @@ void PulseTopLevel::setup() { connect(toolButton_viewGroup, SIGNAL(clicked()), this, SLOT(actionViewGroup())); connect(toolButton_viewParent, SIGNAL(clicked()), this, SLOT(actionViewParent())); - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); connect(toolButton_followParent, SIGNAL(clicked()), this, SLOT(actionFollowParent())); // connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate())); @@ -58,7 +58,7 @@ void PulseTopLevel::setup() connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse())); } -void PulseTopLevel::setRefMessage(QString msg, uint32_t image_count) +void PulseTopLevel::setRefMessage(QString /*msg*/, uint32_t /*image_count*/) { // This should never happen. //widget_message->setRefMessage(msg, image_count); @@ -149,7 +149,7 @@ void PulseTopLevel::setReferenceString(QString ref) } } -void PulseTopLevel::mousePressEvent(QMouseEvent *event) +void PulseTopLevel::mousePressEvent(QMouseEvent */*event*/) { } diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui index 35f763948..077b72473 100644 --- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui +++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui @@ -24,9 +24,9 @@ - + - + 0 @@ -48,7 +48,7 @@ QFrame::Raised - + @@ -63,7 +63,7 @@ 40 - + 0 @@ -77,7 +77,7 @@ 0 - + Qt::Horizontal @@ -171,7 +171,7 @@ - + Qt::Horizontal @@ -200,9 +200,9 @@ 60 - + - + Qt::Vertical @@ -256,7 +256,7 @@ - + Qt::Horizontal @@ -336,7 +336,7 @@ 16777215 - + @@ -345,7 +345,7 @@ - + Qt::Horizontal @@ -361,7 +361,7 @@
- + Qt::Horizontal @@ -381,9 +381,9 @@ 40 - + - + @@ -392,14 +392,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Replies</span></p></body></html> - + Qt::Horizontal @@ -417,7 +417,7 @@ - + @@ -426,14 +426,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Republishes</span></p></body></html> - + Qt::Horizontal @@ -451,7 +451,7 @@ - + @@ -460,14 +460,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Likes</span></p></body></html> - + Qt::Horizontal @@ -485,7 +485,7 @@ - + Qt::Horizontal @@ -501,7 +501,7 @@ - + Qt::Horizontal @@ -521,11 +521,11 @@ 40 - + - + - + Qt::Horizontal @@ -562,7 +562,7 @@ - + Qt::Horizontal @@ -577,9 +577,9 @@
- + - + Qt::Horizontal @@ -616,7 +616,7 @@
- + Qt::Horizontal @@ -631,9 +631,9 @@
- + - + Qt::Horizontal @@ -670,7 +670,7 @@ - + Qt::Horizontal @@ -685,9 +685,9 @@ - + - + Qt::Horizontal @@ -717,7 +717,7 @@ - + Qt::Horizontal @@ -748,9 +748,9 @@ 40 - + - + Qt::Horizontal @@ -763,7 +763,14 @@ - + + + + 12 + 75 + true + + FOLLOW @@ -773,7 +780,7 @@ - + Qt::Horizontal diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp index 547fabbab..8707eaf8c 100644 --- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp @@ -42,7 +42,7 @@ PulseViewGroup::PulseViewGroup(PulseViewHolder *holder, RsWireGroupSPtr group) void PulseViewGroup::setup() { if (mGroup) { - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName)); label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString()))); diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui index 41a2bf23a..77329e3c2 100644 --- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui +++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui @@ -24,9 +24,9 @@ - + - + 0 @@ -48,12 +48,12 @@ QFrame::Raised - + - + - + Qt::Horizontal @@ -85,7 +85,7 @@ - + Qt::Horizontal @@ -114,9 +114,9 @@ 60 - + - + Qt::Horizontal @@ -167,7 +167,7 @@ - + Qt::Vertical @@ -205,7 +205,7 @@ 16777215 - + @@ -226,7 +226,7 @@ - + Qt::Horizontal @@ -261,7 +261,7 @@ - + Qt::Horizontal @@ -296,7 +296,7 @@ - + Qt::Horizontal @@ -316,9 +316,9 @@ 40 - + - + @@ -327,14 +327,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Pulses</span></p></body></html> - + Qt::Horizontal @@ -352,7 +352,7 @@ - + @@ -361,14 +361,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Replies</span></p></body></html> - + Qt::Horizontal @@ -386,7 +386,7 @@ - + @@ -395,14 +395,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Republishes</span></p></body></html> - + Qt::Horizontal @@ -420,7 +420,7 @@ - + @@ -429,14 +429,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Likes</span></p></body></html> - + Qt::Horizontal @@ -454,7 +454,7 @@ - + Qt::Horizontal @@ -470,7 +470,7 @@ - + Qt::Horizontal @@ -490,9 +490,9 @@ 40 - + - + Qt::Horizontal @@ -505,7 +505,14 @@ - + + + + 12 + 75 + true + + FOLLOW @@ -515,7 +522,7 @@ - + Qt::Horizontal @@ -535,8 +542,6 @@ - - - + diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.cpp b/retroshare-gui/src/gui/TheWire/WireDialog.cpp index ed2ee5edd..23031d6ec 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireDialog.cpp @@ -57,14 +57,12 @@ /** Constructor */ WireDialog::WireDialog(QWidget *parent) -: MainPage(parent), mGroupSet(GROUP_SET_ALL) + : MainPage(parent), mGroupSet(GROUP_SET_ALL) + , mAddDialog(nullptr), mGroupSelected(nullptr), mWireQueue(nullptr) + , mHistoryIndex(-1) { ui.setupUi(this); - mAddDialog = NULL; - mGroupSelected = NULL; - mHistoryIndex = -1; - connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup())); connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse())); connect( ui.toolButton_refresh, SIGNAL(clicked()), this, SLOT(refreshGroups())); @@ -98,6 +96,7 @@ WireDialog::~WireDialog() // save settings processSettings(false); + clearTwitterView(); delete(mWireQueue); } @@ -127,7 +126,7 @@ void WireDialog::refreshGroups() void WireDialog::addGroup(QWidget *item) { - QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + QLayout *alayout = ui.groupsWidget->layout(); alayout->addWidget(item); } @@ -268,7 +267,7 @@ void WireDialog::deleteGroups() mGroupSelected = NULL; - QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + QLayout *alayout = ui.groupsWidget->layout(); QLayoutItem *item; int i = 0; while (i < alayout->count()) @@ -300,17 +299,16 @@ void WireDialog::updateGroups(std::vector& groups) mOwnGroups.clear(); ui.groupChooser->clear(); - std::vector::const_iterator it; - for(it = groups.begin(); it != groups.end(); it++) { + for(auto &it : groups) { // save list of all groups. - mAllGroups[it->mMeta.mGroupId] = *it; + mAllGroups[it.mMeta.mGroupId] = it; - if (it->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + if (it.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { // grab own groups. // setup Chooser too. - mOwnGroups.push_back(*it); - ui.groupChooser->addItem(QString::fromStdString(it->mMeta.mGroupName)); + mOwnGroups.push_back(it); + ui.groupChooser->addItem(QString::fromStdString(it.mMeta.mGroupName)); } } } @@ -362,16 +360,15 @@ void WireDialog::showGroups() std::list allGroupIds; /* depends on the comboBox */ - std::map::const_iterator it; - for (it = mAllGroups.begin(); it != mAllGroups.end(); it++) + for (auto &it : mAllGroups) { bool add = (mGroupSet == GROUP_SET_ALL); - if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + if (it.second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { if (mGroupSet == GROUP_SET_OWN) { add = true; } } - else if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { + else if (it.second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { if (mGroupSet == GROUP_SET_SUBSCRIBED) { add = true; } @@ -383,11 +380,11 @@ void WireDialog::showGroups() } if (add) { - addGroup(it->second); + addGroup(it.second); // request data. std::list grpIds; - grpIds.push_back(it->second.mMeta.mGroupId); - allGroupIds.push_back(it->second.mMeta.mGroupId); + grpIds.push_back(it.second.mMeta.mGroupId); + allGroupIds.push_back(it.second.mMeta.mGroupId); } } @@ -790,20 +787,21 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId // fetch data from backend. RsWirePulseSPtr pPulse; int type = 0; - bool success = rsWire->getPulseFocus(groupId, msgId, type, pPulse); - - // sleep(2); - - /* now insert the pulse + children into the layput */ - RsQThreadUtils::postToObject([pPulse,this]() + if(rsWire->getPulseFocus(groupId, msgId, type, pPulse)) { - /* Here it goes any code you want to be executed on the Qt Gui + // sleep(2); + + /* now insert the pulse + children into the layput */ + RsQThreadUtils::postToObject([pPulse,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - postPulseFocus(pPulse); + postPulseFocus(pPulse); - }, this); + }, this); + } }); } @@ -822,10 +820,9 @@ void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse) addTwitterView(new PulseTopLevel(this, pPulse)); - std::list::iterator it; - for(it = pPulse->mReplies.begin(); it != pPulse->mReplies.end(); it++) + for(auto &it : pPulse->mReplies) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; PulseReply *firstReply = new PulseReply(this, reply); addTwitterView(firstReply); @@ -857,9 +854,9 @@ void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse) addTwitterView(new PulseReplySeperator()); } - for(it = pPulse->mRepublishes.begin(); it != pPulse->mRepublishes.end(); it++) + for(auto &it : pPulse->mRepublishes) { - RsWirePulseSPtr repub = *it; + RsWirePulseSPtr repub = it; PulseReply *firstRepub = new PulseReply(this, repub); firstRepub->showReplyLine(false); @@ -928,10 +925,9 @@ void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list::iterator it; - for(it = pulses.begin(); it != pulses.end(); it++) + for(auto &it : pulses) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; // don't show likes if (reply->mPulseType & WIRE_PULSE_TYPE_LIKE) { @@ -949,7 +945,7 @@ void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list groupIds) +void WireDialog::requestGroupsPulses(const std::list& groupIds) { WireViewHistory view; view.viewType = WireViewType::GROUPS; @@ -959,7 +955,7 @@ void WireDialog::requestGroupsPulses(const std::list groupIds) showGroupsPulses(groupIds); } -void WireDialog::showGroupsPulses(const std::list groupIds) +void WireDialog::showGroupsPulses(const std::list& groupIds) { clearTwitterView(); @@ -968,20 +964,21 @@ void WireDialog::showGroupsPulses(const std::list groupIds) { // fetch data from backend. std::list pulses; - bool success = rsWire->getPulsesForGroups(groupIds, pulses); - - // sleep(2); - - /* now insert the pulse + children into the layput */ - RsQThreadUtils::postToObject([pulses,this]() + if(rsWire->getPulsesForGroups(groupIds, pulses)) { - /* Here it goes any code you want to be executed on the Qt Gui + // sleep(2); + + /* now insert the pulse + children into the layput */ + RsQThreadUtils::postToObject([pulses,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - postGroupsPulses(pulses); + postGroupsPulses(pulses); - }, this); + }, this); + } }); } @@ -992,10 +989,9 @@ void WireDialog::postGroupsPulses(std::list pulses) ui.label_viewMode->setText("Groups Pulses"); - std::list::iterator it; - for(it = pulses.begin(); it != pulses.end(); it++) + for(auto &it : pulses) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; // don't show likes if (reply->mPulseType & WIRE_PULSE_TYPE_LIKE) { std::cerr << "WireDialog::postGroupsPulses() Not showing LIKE"; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.h b/retroshare-gui/src/gui/TheWire/WireDialog.h index 100cedeec..8ccf13377 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.h +++ b/retroshare-gui/src/gui/TheWire/WireDialog.h @@ -76,9 +76,9 @@ public: WireDialog(QWidget *parent = 0); ~WireDialog(); - virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; } - virtual QString pageName() const { return tr("The Wire") ; } - virtual QString helpText() const { return ""; } + virtual QIcon iconPixmap() const override { return QIcon(IMAGE_WIRE) ; } + virtual QString pageName() const override { return tr("The Wire") ; } + virtual QString helpText() const override { return ""; } // WireGroupHolder interface. virtual void subscribe(RsGxsGroupId &groupId) override; @@ -114,8 +114,8 @@ public: void showGroupFocus(const RsGxsGroupId groupId); void postGroupFocus(RsWireGroupSPtr group, std::list pulses); - void requestGroupsPulses(const std::list groupIds); - void showGroupsPulses(const std::list groupIds); + void requestGroupsPulses(const std::list& groupIds); + void showGroupsPulses(const std::list& groupIds); void postGroupsPulses(std::list pulses); private slots: @@ -153,7 +153,7 @@ private: bool loadGroupData(const uint32_t &token); void acknowledgeGroup(const uint32_t &token, const uint32_t &userType); - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override; int mGroupSet; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.ui b/retroshare-gui/src/gui/TheWire/WireDialog.ui index 2aeefe92f..23eb87a78 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.ui +++ b/retroshare-gui/src/gui/TheWire/WireDialog.ui @@ -6,7 +6,7 @@ 0 0 - 804 + 809 586 @@ -33,7 +33,7 @@ 0 - + 0 @@ -46,7 +46,7 @@ QFrame::Plain - + 0 @@ -108,7 +108,7 @@ - + @@ -134,7 +134,7 @@ Qt::Horizontal - + 1 @@ -159,9 +159,9 @@ QFrame::Raised - + - + All @@ -199,22 +199,22 @@ - + true - + 0 0 - 228 - 488 + 220 + 444 - + - + Qt::Vertical @@ -305,6 +305,11 @@ + + + 12 + + Most Recent @@ -337,7 +342,7 @@ - + 0 @@ -382,8 +387,8 @@ 0 0 - 523 - 484 + 521 + 437 @@ -429,6 +434,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui index 9de9e6a3e..28f2e41ce 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui @@ -51,7 +51,7 @@
- + Travel @@ -110,7 +110,7 @@ - + 0 @@ -135,7 +135,7 @@ - + 0 @@ -170,7 +170,7 @@ - + 0 @@ -195,7 +195,7 @@ - + 0 @@ -266,6 +266,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 077641621..8dd0404d6 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -56,18 +56,18 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) { ui.setupUi(this); - connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelEdit( void ) ) ); - connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); - connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); - connect(ui.pushButton_Preview, SIGNAL( clicked( void ) ), this, SLOT( previewToggle( void ) ) ); - connect(ui.pushButton_History, SIGNAL( clicked( void ) ), this, SLOT( historyToggle( void ) ) ); - connect(ui.toolButton_Show, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); - connect(ui.toolButton_Hide, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); - connect(ui.textEdit, SIGNAL( textChanged( void ) ), this, SLOT( textChanged( void ) ) ); - connect(ui.checkBox_OldHistory, SIGNAL( clicked( void ) ), this, SLOT( oldHistoryChanged( void ) ) ); - connect(ui.checkBox_Merge, SIGNAL( clicked( void ) ), this, SLOT( mergeModeToggle( void ) ) ); - connect(ui.pushButton_Merge, SIGNAL( clicked( void ) ), this, SLOT( generateMerge( void ) ) ); - connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged( void ) ), this, SLOT( historySelected( void ) ) ); + connect(ui.pushButton_Cancel, SIGNAL( clicked() ), this, SLOT( cancelEdit() ) ); + connect(ui.pushButton_Revert, SIGNAL( clicked() ), this, SLOT( revertEdit() ) ); + connect(ui.postButton, SIGNAL( clicked() ), this, SLOT( submitEdit() ) ); + connect(ui.pushButton_Preview, SIGNAL( clicked() ), this, SLOT( previewToggle() ) ); + connect(ui.pushButton_History, SIGNAL( clicked() ), this, SLOT( historyToggle() ) ); + connect(ui.toolButton_Show, SIGNAL( clicked() ), this, SLOT( detailsToggle() ) ); + connect(ui.toolButton_Hide, SIGNAL( clicked() ), this, SLOT( detailsToggle() ) ); + connect(ui.textEdit, SIGNAL( textChanged() ), this, SLOT( textChanged() ) ); + connect(ui.checkBox_OldHistory, SIGNAL( clicked() ), this, SLOT( oldHistoryChanged() ) ); + connect(ui.checkBox_Merge, SIGNAL( clicked() ), this, SLOT( mergeModeToggle() ) ); + connect(ui.pushButton_Merge, SIGNAL( clicked() ), this, SLOT( generateMerge() ) ); + connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged() ), this, SLOT( historySelected() ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); @@ -125,7 +125,7 @@ void WikiEditDialog::textChanged() mTextChanged = true; ui.pushButton_Revert->setEnabled(true); - ui.pushButton_Submit->setEnabled(true); + ui.postButton->setEnabled(true); ui.label_Status->setText("Modified"); // Disable Selection in Edit History. @@ -142,7 +142,7 @@ void WikiEditDialog::textReset() mTextChanged = false; ui.pushButton_Revert->setEnabled(false); - ui.pushButton_Submit->setEnabled(false); + ui.postButton->setEnabled(false); ui.label_Status->setText("Original"); // Enable Selection in Edit History. @@ -434,11 +434,11 @@ void WikiEditDialog::setNewPage() void WikiEditDialog::setRepublishMode(RsGxsMessageId &origMsgId) { - mRepublishMode = true; - mRepublishOrigId = origMsgId; - ui.pushButton_Submit->setText(tr("Republish")); + mRepublishMode = true; + mRepublishOrigId = origMsgId; + ui.postButton->setText(tr("Republish")); /* No need for for REQUIRED ID */ - ui.comboBox_IdChooser->loadIds(0, RsGxsId()); + ui.comboBox_IdChooser->loadIds(0, RsGxsId()); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index c971c1398..5433f4a7f 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -13,7 +13,7 @@ - + 0 @@ -40,14 +40,14 @@
- + QFrame::StyledPanel QFrame::Raised - + @@ -63,7 +63,7 @@ Page Edit History - + @@ -109,18 +109,18 @@ - + QFrame::StyledPanel QFrame::Raised - + - + 6 @@ -132,7 +132,7 @@ - + Qt::Vertical @@ -157,7 +157,7 @@ - + 0 @@ -177,7 +177,7 @@ Wiki Group: - frame + formFrame @@ -254,16 +254,23 @@
- + + + + 15 + 75 + true + + History - + Qt::Horizontal @@ -298,7 +305,7 @@ - + @@ -314,7 +321,7 @@ - + Qt::Horizontal @@ -327,7 +334,14 @@ - + + + + 12 + 75 + true + + Submit @@ -357,8 +371,6 @@
gui/gxs/GxsIdChooser.h
- - - + diff --git a/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui b/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui index 5926e8d94..9427358cd 100644 --- a/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui +++ b/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui @@ -6,8 +6,8 @@ 0 0 - 838 - 130 + 297 + 138 @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -31,20 +31,14 @@ 0 - - - - 0 - 130 - - + QFrame::StyledPanel QFrame::Raised - + @@ -53,12 +47,6 @@ 1 - - - 800 - 60 - - false @@ -68,59 +56,15 @@ Qt::AlignJustify|Qt::AlignTop - + 0 - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 1 - 0 - - - - - 600 - 26 - - - - false - - - - - - - Qt::Vertical - - - - 20 - 9 - - - - - + 6 @@ -142,8 +86,8 @@ Add a further search criterion. - - :/images/add_24x24.png:/images/add_24x24.png + + :/icons/png/add.png:/icons/png/add.png @@ -174,16 +118,10 @@ - + Qt::Horizontal - - - 381 - 27 - - @@ -203,7 +141,7 @@
- + 0 @@ -227,6 +165,7 @@ + diff --git a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp index eb9b9ce83..da3d24057 100644 --- a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp +++ b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp @@ -21,97 +21,79 @@ *******************************************************************************/ #include "advancedsearchdialog.h" + #include "gui/common/FilesDefs.h" +#include + AdvancedSearchDialog::AdvancedSearchDialog(QWidget * parent) : QDialog (parent) { - setupUi(this); - dialogLayout = this->layout(); - metrics = new QFontMetrics(this->font()); + setupUi(this); - // the list of expressions - expressions = new QList(); + QFontMetrics metrics = QFontMetrics(this->font()); + searchCriteriaBox_VL->setContentsMargins(2, metrics.height()/2, 2, 2); + addExprButton->setIconSize(QSize(metrics.height(),metrics.height())*1.5); + resetButton->setIconSize(QSize(metrics.height(),metrics.height())*1.5); - // a area for holding the objects - expressionsLayout = new QVBoxLayout(); - expressionsLayout->setSpacing(0); - expressionsLayout->setMargin(0); - expressionsLayout->setObjectName(QString::fromUtf8("expressionsLayout")); - expressionsFrame->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - expressionsFrame->setLayout(expressionsLayout); - - // we now add the first expression widgets to the dialog via a vertical - // layout - reset();//addNewExpression(); + // Save current default size as minimum to only add expresssions size to it. + this->adjustSize(); + this->setMinimumSize(this->size()); - connect (this->addExprButton, SIGNAL(clicked()), - this, SLOT(addNewExpression())); - connect (this->resetButton, SIGNAL(clicked()), - this, SLOT(reset())); - connect(this->executeButton, SIGNAL(clicked()), - this, SLOT(prepareSearch())); + // the list of expressions + expressions = new QList(); - addExprButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/add.png")); + // we now add the first expression widgets to the dialog + reset();//addNewExpression(); + + connect ( addExprButton, SIGNAL(clicked()) + , this, SLOT(addNewExpression())); + connect ( resetButton, SIGNAL(clicked()) + , this, SLOT(reset())); + connect ( searchButton, SIGNAL(clicked()) + , this, SLOT(prepareSearch())); } void AdvancedSearchDialog::addNewExpression() { - int sizeChange = metrics->height() + 26; + ExpressionWidget *expr = new ExpressionWidget(searchCriteriaBox, (expressions->size() == 0)); + expressions->append(expr); - ExpressionWidget *expr; - if (expressions->size() == 0) - { - //create an initial expression - expr = new ExpressionWidget(expressionsFrame, true); - } else { - expr = new ExpressionWidget(expressionsFrame); - } - - expressions->append(expr); - expressionsLayout->addWidget(expr, 1, Qt::AlignLeft); - - - connect(expr, SIGNAL(signalDelete(ExpressionWidget*)), - this, SLOT(deleteExpression(ExpressionWidget*))); - - //expressionsLayout->invalidate(); - //searchCriteriaBox->setMinimumSize(searchCriteriaBox->minimumWidth(), - // searchCriteriaBox->minimumHeight() + sizeChange); - //searchCriteriaBox->adjustSize(); - expressionsFrame->adjustSize(); - this->setMinimumSize(this->minimumWidth(), this->minimumHeight()+sizeChange); - this->adjustSize(); + searchCriteriaBox_VL->addWidget(expr); + searchCriteriaBox_VL->setAlignment(Qt::AlignTop); + expr->adjustSize(); + if (searchCriteriaBox->minimumWidth() < expr->minimumWidth()) + searchCriteriaBox->setMinimumWidth(expr->minimumWidth()); + QSize exprHeight = QSize(0,expr->height()); + + connect( expr, SIGNAL(signalDelete(ExpressionWidget*)) + , this, SLOT(deleteExpression(ExpressionWidget*)) ); + + this->setMinimumSize(this->minimumSize() + exprHeight); + int marg = gradFrame_GL->contentsMargins().left()+gradFrame_GL->contentsMargins().right(); + marg += this->contentsMargins().left()+this->contentsMargins().right(); + if (this->minimumWidth() < (searchCriteriaBox->minimumWidth()+marg)) + this->setMinimumWidth(searchCriteriaBox->minimumWidth()+marg); } void AdvancedSearchDialog::deleteExpression(ExpressionWidget* expr) { - int sizeChange = metrics->height() + 26; - - expressions->removeAll(expr); - expr->hide(); - expressionsLayout->removeWidget(expr); - delete expr; - - expressionsLayout->invalidate(); - //searchCriteriaBox->setMinimumSize(searchCriteriaBox->minimumWidth(), - // searchCriteriaBox->minimumHeight() - sizeChange); - //searchCriteriaBox->adjustSize(); - expressionsFrame->adjustSize(); - this->setMinimumSize(this->minimumWidth(), this->minimumHeight()-sizeChange); - this->adjustSize(); + QSize exprHeight = QSize(0,expr->height()); + + expressions->removeAll(expr); + expr->hide(); + searchCriteriaBox_VL->removeWidget(expr); + delete expr; + + this->setMinimumSize(this->minimumSize() - exprHeight); + this->resize(this->size() - exprHeight); } void AdvancedSearchDialog::reset() { - ExpressionWidget *expr; while (!expressions->isEmpty()) - { - expr = expressions->takeLast(); - deleteExpression(expr); - } + deleteExpression(expressions->takeLast()); // now add a new default expressions addNewExpression(); @@ -129,7 +111,6 @@ RsRegularExpression::Expression * AdvancedSearchDialog::getRsExpr() // process the special case: first expression wholeExpression = expressions->at(0)->getRsExpression(); - // iterate through the items in elements and #warning Phenom (2017-07-21): I don t know if it is a real memLeak for wholeExpression. If not remove this warning and add a comment how it is deleted. @@ -140,21 +121,20 @@ RsRegularExpression::Expression * AdvancedSearchDialog::getRsExpr() wholeExpression = new RsRegularExpression::CompoundExpression(expressions->at(i)->getOperator(), wholeExpression, expressions->at(i)->getRsExpression()); - } + } return wholeExpression; } QString AdvancedSearchDialog::getSearchAsString() { QString str = expressions->at(0)->toString(); - // iterate through the items in elements and for (int i = 1; i < expressions->size(); ++i) { // extract the expression information and compound it with the // first expression str += QString(" ") + expressions->at(i)->toString(); - } + } return str; } diff --git a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h index 317809e6f..25ea74129 100644 --- a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h +++ b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h @@ -22,13 +22,10 @@ #ifndef _AdvancedSearch_h_ #define _AdvancedSearch_h_ -#include -#include -#include -#include -#include #include "ui_AdvancedSearchDialog.h" + #include "expressionwidget.h" + #include class AdvancedSearchDialog : public QDialog, public Ui::AdvancedSearchDialog @@ -49,10 +46,7 @@ private slots: void prepareSearch(); private: - QLayout * dialogLayout; - QVBoxLayout * expressionsLayout; QList * expressions; - QFontMetrics * metrics; }; #endif // _AdvancedSearch_h_ diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.cpp b/retroshare-gui/src/gui/advsearch/expressionwidget.cpp index 2b6ad3b2e..5e5eee1ea 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.cpp +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.cpp @@ -21,107 +21,60 @@ *******************************************************************************/ #include "expressionwidget.h" -ExpressionWidget::ExpressionWidget(QWidget * parent, bool initial) : QWidget(parent) +ExpressionWidget::ExpressionWidget(QWidget * parent, bool initial) + : QWidget(parent) + , isFirst (initial), inRangedConfig(false) + , searchType (NameSearch) // the default search type { - setupUi(this); - - inRangedConfig = false; - - // the default search type - searchType = NameSearch; - - exprLayout = this->layout(); - - exprOpFrame->setLayout (createLayout()); - exprTermFrame->setLayout (createLayout()); - exprConditionFrame->setLayout (createLayout()); - exprParamFrame->setLayout (createLayout()); - exprParamFrame->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::Fixed); - - elements = new QList(); - - exprOpElem = new ExprOpElement(); - exprOpFrame->layout()->addWidget(exprOpElem); - elements->append(exprOpElem); - - exprTermElem = new ExprTermsElement(); - exprTermFrame->layout()->addWidget(exprTermElem); - elements->append(exprTermElem); - connect (exprTermElem, SIGNAL(currentIndexChanged(int)), - this, SLOT (adjustExprForTermType(int))); - - exprCondElem = new ExprConditionElement(searchType); - exprConditionFrame->layout()->addWidget(exprCondElem); - elements->append(exprCondElem); - connect (exprCondElem, SIGNAL (currentIndexChanged(int)), - this, SLOT (adjustExprForConditionType(int))); - - exprParamElem= new ExprParamElement(searchType); - exprParamFrame->layout()->addWidget(exprParamElem); - elements->append(exprParamElem); - - // set up the default search: a search on name - adjustExprForTermType(searchType); - isFirst = initial; - deleteExprButton ->setVisible(!isFirst); - exprOpElem ->setVisible(!isFirst); - exprTermFrame ->show(); - exprConditionFrame ->show(); - exprParamFrame ->show(); - - // connect the delete button signal - connect (deleteExprButton, SIGNAL (clicked()), - this, SLOT(deleteExpression())); - - this->show(); -} + setupUi(this); -QLayout * ExpressionWidget::createLayout(QWidget * parent) -{ - QHBoxLayout * hboxLayout; - if (parent == 0) - { - hboxLayout = new QHBoxLayout(); - } else { - hboxLayout = new QHBoxLayout(parent); - } - hboxLayout->setSpacing(0); - hboxLayout->setMargin(0); - return hboxLayout; + connect (exprTermElem, SIGNAL(currentIndexChanged(int)), + this, SLOT (adjustExprForTermType(int))); + + connect (exprCondElem, SIGNAL (currentIndexChanged(int)), + this, SLOT (adjustExprForConditionType(int))); + + // set up the default search: a search on name + adjustExprForTermType(searchType); + exprOpElem ->setVisible(!isFirst); + deleteExprButton ->setVisible(!isFirst); + + // connect the delete button signal + connect (deleteExprButton, SIGNAL (clicked()), + this, SLOT(deleteExpression()) ); + + this->show(); } bool ExpressionWidget::isStringSearchExpression() { - return (searchType == NameSearch || searchType == PathSearch - || searchType == ExtSearch || searchType == HashSearch); + return ( searchType == NameSearch || searchType == PathSearch + || searchType == ExtSearch || searchType == HashSearch); } void ExpressionWidget::adjustExprForTermType(int index) { - ExprSearchType type = GuiExprElement::TermsIndexMap[index]; - searchType = type; - - // now adjust the relevant elements - // the condition combobox - exprCondElem->adjustForSearchType(type); - - // the parameter expression: can be a date, 1-2 edit fields - // or a size with units etc - exprParamElem->adjustForSearchType(type); - exprParamFrame->adjustSize(); - - exprLayout->invalidate(); - this->adjustSize(); + ExprSearchType type = GuiExprElement::TermsIndexMap[index]; + searchType = type; + + // now adjust the relevant elements + // the condition combobox + exprCondElem->adjustForSearchType(type); + + // the parameter expression: can be a date, 1-2 edit fields + // or a size with units etc + exprParamElem->adjustForSearchType(type); + + this->setMinimumWidth( exprOpElem->width()+exprTermElem->width() + + exprCondElem->width()+exprParamElem->width() + + deleteExprButton->width() ); } void ExpressionWidget::adjustExprForConditionType(int newCondition) { - // we adjust the appearance for a ranged selection - inRangedConfig = (newCondition == GuiExprElement::RANGE_INDEX); - exprParamElem->setRangedSearch(inRangedConfig); - exprParamFrame->layout()->invalidate(); - exprParamFrame->adjustSize(); + // we adjust the appearance for a ranged selection + inRangedConfig = (newCondition == GuiExprElement::RANGE_INDEX); + exprParamElem->setRangedSearch(inRangedConfig); } void ExpressionWidget::deleteExpression() @@ -156,7 +109,11 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() if (isStringSearchExpression()) { QString txt = exprParamElem->getStrSearchValue(); +#if QT_VERSION < QT_VERSION_CHECK(5,15,0) QStringList words = txt.split(" ", QString::SkipEmptyParts); +#else + QStringList words = txt.split(" ", Qt::SkipEmptyParts); +#endif for (int i = 0; i < words.size(); ++i) wordList.push_back(words.at(i).toUtf8().constData()); } else if (inRangedConfig){ @@ -170,7 +127,7 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() lowVal = lowVal^highVal; } } - + switch (searchType) { case NameSearch: @@ -208,20 +165,20 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() break; case SizeSearch: if (inRangedConfig) - { - if(lowVal >= (uint64_t)(1024*1024*1024) || highVal >= (uint64_t)(1024*1024*1024)) - expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(lowVal / (1024*1024)), (int)(highVal / (1024*1024))); - else - expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), lowVal, highVal); - } - else - { - uint64_t s = exprParamElem->getIntValue() ; + { + if(lowVal >= (uint64_t)(1024*1024*1024) || highVal >= (uint64_t)(1024*1024*1024)) + expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(lowVal / (1024*1024)), (int)(highVal / (1024*1024))); + else + expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), lowVal, highVal); + } + else + { + uint64_t s = exprParamElem->getIntValue() ; - if(s >= (uint64_t)(1024*1024*1024)) - expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(s/(1024*1024))) ; - else - expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), (int)s) ; + if(s >= (uint64_t)(1024*1024*1024)) + expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(s/(1024*1024))) ; + else + expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), (int)s) ; } break; }; diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.h b/retroshare-gui/src/gui/advsearch/expressionwidget.h index 40ef3ec47..109ea2a35 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.h +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.h @@ -21,14 +21,16 @@ *******************************************************************************/ #ifndef _ExpressionWidget_h_ #define _ExpressionWidget_h_ -#include -#include -#include -#include -#include "guiexprelement.h" #include "ui_expressionwidget.h" +#include "guiexprelement.h" + +#include + +#include + +#include /** Represents an Advanced Search GUI Expression object which acts as a container @@ -74,20 +76,10 @@ private slots: private: - QLayout * createLayout(QWidget* parent = 0); - bool isStringSearchExpression(); - - QList * elements; - QLayout * exprLayout; - ExprOpElement * exprOpElem; - ExprTermsElement * exprTermElem; - ExprConditionElement * exprCondElem; - ExprParamElement* exprParamElem; - - bool inRangedConfig; bool isFirst; + bool inRangedConfig; ExprSearchType searchType; }; diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.ui b/retroshare-gui/src/gui/advsearch/expressionwidget.ui index 9e7d2d780..5b8584f00 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.ui +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.ui @@ -2,104 +2,33 @@ ExpressionWidget - - - 0 - 0 - 800 - 34 - - - + 0 0 - - - 800 - 30 - - - - - 16777215 - 55 - - Expression Widget - - 6 - - - 6 - - + + + + + + + + + + - + 0 0 - - - 90 - 26 - - - - - - - - - 0 - 0 - - - - - 100 - 26 - - - - - - - - - 0 - 0 - - - - - 180 - 26 - - - - - - - - - 1 - 0 - - - - - 350 - 26 - - @@ -113,21 +42,34 @@ - - - - Qt::Horizontal - - - - 0 - 30 - - - -
+ + + ExprOpElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprTermsElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprConditionElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprParamElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+
diff --git a/retroshare-gui/src/gui/advsearch/guiexprelement.cpp b/retroshare-gui/src/gui/advsearch/guiexprelement.cpp index 44d1350a4..23317c168 100644 --- a/retroshare-gui/src/gui/advsearch/guiexprelement.cpp +++ b/retroshare-gui/src/gui/advsearch/guiexprelement.cpp @@ -21,14 +21,10 @@ *******************************************************************************/ #include "guiexprelement.h" -#define STR_FIELDS_MIN_WIDTH 200 -#define SIZE_FIELDS_MIN_WIDTH 80 -#define DATE_FIELDS_MIN_WIDTH 100 -#define FIELDS_MIN_HEIGHT 26 - -#define LOGICAL_OP_CB_WIDTH 70 -#define STD_CB_WIDTH 90 -#define CONDITION_CB_WIDTH 170 +#define STR_FIELDS_MIN_WFACTOR 20.0 +#define SIZE_FIELDS_MIN_WFACTOR 8.0 +#define DATE_FIELDS_MIN_WFACTOR 10.0 +#define FIELDS_MIN_HFACTOR 1.2 const int GuiExprElement::AND_INDEX = 0; const int GuiExprElement::OR_INDEX = 1; @@ -37,10 +33,10 @@ const int GuiExprElement::XOR_INDEX = 2; const int GuiExprElement::NAME_INDEX = 0; const int GuiExprElement::PATH_INDEX = 1; const int GuiExprElement::EXT_INDEX = 2; -const int GuiExprElement::HASH_INDEX = 3; -/*const int GuiExprElement::KEYWORDS_INDEX = ???; -const int GuiExprElement::COMMENTS_INDEX = ???; -const int GuiExprElement::META_INDEX = ???;*/ +const int GuiExprElement::HASH_INDEX = 3; +//const int GuiExprElement::KEYWORDS_INDEX = ???; +//const int GuiExprElement::COMMENTS_INDEX = ???; +//const int GuiExprElement::META_INDEX = ???; const int GuiExprElement::DATE_INDEX = 4; const int GuiExprElement::SIZE_INDEX = 5; const int GuiExprElement::POP_INDEX = 6; @@ -76,14 +72,13 @@ bool GuiExprElement::initialised = false; GuiExprElement::GuiExprElement(QWidget * parent) - : QWidget(parent) + : QFrame(parent), searchType(NameSearch) { - if (!GuiExprElement::initialised) - { - initialiseOptionsLists(); - } - searchType = NameSearch; + if (!GuiExprElement::initialised) + initialiseOptionsLists(); + setObjectName("trans_InternalFrame"); + createLayout(this); } @@ -96,7 +91,7 @@ void GuiExprElement::initialiseOptionsLists() const QString NAME = tr("Name"); const QString PATH = tr("Path"); const QString EXT = tr("Extension"); - const QString HASH = tr("Hash"); + const QString HASH = tr("Hash"); //const QString KEYWORDS= tr("Keywords"); //const QString COMMENTS= tr("Comments"); //const QString META = tr("Meta"); @@ -128,7 +123,7 @@ void GuiExprElement::initialiseOptionsLists() //GuiExprElement::searchTermsOptionsList.append(META); GuiExprElement::searchTermsOptionsList.append(DATE); GuiExprElement::searchTermsOptionsList.append(SIZE); -// GuiExprElement::searchTermsOptionsList.append(POP); + //GuiExprElement::searchTermsOptionsList.append(POP); GuiExprElement::stringOptionsList.append(CONTAINS); GuiExprElement::stringOptionsList.append(CONTALL); @@ -220,24 +215,29 @@ QStringList GuiExprElement::getConditionOptions(ExprSearchType t) return QStringList(); } -QHBoxLayout * GuiExprElement::createLayout(QWidget * parent) +QHBoxLayout * GuiExprElement::createLayout(QWidget * parent /*= nullptr*/) { - QHBoxLayout * hboxLayout; - if (parent == 0) - { - hboxLayout = new QHBoxLayout(); - } else { - hboxLayout = new QHBoxLayout(parent); - } + QHBoxLayout * hboxLayout = new QHBoxLayout(parent); hboxLayout->setMargin(0); hboxLayout->setSpacing(0); return hboxLayout; } +QSize GuiExprElement::getMinSize(float widthFactor/*=1*/, float heightFactor/*=1*/) +{ + QFontMetrics fm = QFontMetrics(font()); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + QSize size = QSize(fm.width("_")*widthFactor, fm.height()*heightFactor); +#else + QSize size = QSize(fm.horizontalAdvance("_")*widthFactor, fm.height()*heightFactor); +#endif + return size; +} + bool GuiExprElement::isStringSearchExpression() { - return (searchType == NameSearch || searchType == PathSearch - || searchType == ExtSearch || searchType == HashSearch); + return (searchType == NameSearch || searchType == PathSearch + || searchType == ExtSearch || searchType == HashSearch); } @@ -245,14 +245,12 @@ bool GuiExprElement::isStringSearchExpression() /* *********** L O G I C A L O P E L E M E N T ******************/ /* ********************************************************************/ ExprOpElement::ExprOpElement(QWidget * parent) - : GuiExprElement(parent) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(LOGICAL_OP_CB_WIDTH, FIELDS_MIN_HEIGHT); - cb->addItems(GuiExprElement::exprOpsList); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + cb->addItems(GuiExprElement::exprOpsList); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } QString ExprOpElement::toString() @@ -271,16 +269,14 @@ RsRegularExpression::LogicalOperator ExprOpElement::getLogicalOperator() /* *********** T E R M S E L E M E N T ******************/ /* **********************************************************/ ExprTermsElement::ExprTermsElement(QWidget * parent) - : GuiExprElement(parent) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(STD_CB_WIDTH, FIELDS_MIN_HEIGHT); - connect (cb, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - cb->addItems(GuiExprElement::searchTermsOptionsList); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + connect (cb, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + cb->addItems(GuiExprElement::searchTermsOptionsList); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } QString ExprTermsElement::toString() { @@ -290,17 +286,15 @@ QString ExprTermsElement::toString() /* ******************************************************************/ /* *********** C O N D I T I O N E L E M E N T ******************/ /* ******************************************************************/ -ExprConditionElement::ExprConditionElement(ExprSearchType type, QWidget * parent) - : GuiExprElement(parent) +ExprConditionElement::ExprConditionElement(QWidget * parent, ExprSearchType type) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(CONDITION_CB_WIDTH, FIELDS_MIN_HEIGHT); - connect (cb, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - cb->addItems(getConditionOptions(type)); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + connect (cb, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + cb->addItems(getConditionOptions(type)); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } @@ -334,174 +328,189 @@ void ExprConditionElement::adjustForSearchType(ExprSearchType type) /* **********************************************************/ /* *********** P A R A M E L E M E N T ******************/ /* **********************************************************/ -ExprParamElement::ExprParamElement(ExprSearchType type, QWidget * parent) - : GuiExprElement(parent) +ExprParamElement::ExprParamElement(QWidget * parent, ExprSearchType type) + : GuiExprElement(parent), inRangedConfig(false) { - internalframe = new QFrame(this); - internalframe->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - internalframe->setLayout(createLayout()); - inRangedConfig = false; - searchType = type; - adjustForSearchType(type); + adjustForSearchType(type); } QString ExprParamElement::toString() { - QString str = ""; - if (isStringSearchExpression()) - { - str = QString("\"") + getStrSearchValue() + QString("\""); - // we don't bother with case if hash search - if (searchType != HashSearch) { - str += (ignoreCase() ? QString(" (ignore case)") - : QString(" (case sensitive)")); + QString str = ""; + if (isStringSearchExpression()) + { + str = QString("\"") + getStrSearchValue() + QString("\""); + // we don't bother with case if hash search + if (searchType != HashSearch) { + str += (ignoreCase() ? QString(" (ignore case)") + : QString(" (case sensitive)")); + } + } else + { + if (searchType == DateSearch) { + QDateEdit * dateEdit = findChild ("param1"); + str = dateEdit->text(); + if (inRangedConfig) + { + str += QString(" ") + tr("to") + QString(" "); + dateEdit = findChild ("param2"); + str += dateEdit->text(); + } + } else if (searchType == SizeSearch) + { + QLineEdit * lineEditSize = findChild("param1"); + str = ("" == lineEditSize->text()) ? "0" + : lineEditSize->text(); + RSComboBox * cb = findChild ("unitsCb1"); + str += QString(" ") + cb->itemText(cb->currentIndex()); + if (inRangedConfig) + { + str += QString(" ") + tr("to") + QString(" "); + lineEditSize = findChild("param2"); + str += ("" == lineEditSize->text()) ? "0" + : lineEditSize->text(); + cb = findChild ("unitsCb2"); + str += QString(" ") + cb->itemText(cb->currentIndex()); + } + } } - } else - { - if (searchType == DateSearch) { - QDateEdit * dateEdit = internalframe->findChild ("param1"); - str = dateEdit->text(); - if (inRangedConfig) - { - str += QString(" ") + tr("to") + QString(" "); - dateEdit = internalframe->findChild ("param2"); - str += dateEdit->text(); - } - } else if (searchType == SizeSearch) - { - QLineEdit * lineEditSize = internalframe->findChild("param1"); - str = ("" == lineEditSize->text()) ? "0" - : lineEditSize->text(); - QComboBox * cb = internalframe->findChild ("unitsCb1"); - str += QString(" ") + cb->itemText(cb->currentIndex()); - if (inRangedConfig) - { - str += QString(" ") + tr("to") + QString(" "); - lineEditSize = internalframe->findChild("param2"); - str += ("" == lineEditSize->text()) ? "0" - : lineEditSize->text(); - cb = internalframe->findChild ("unitsCb2"); - str += QString(" ") + cb->itemText(cb->currentIndex()); - } - } - } - return str; + return str; } +void clearLayout(QLayout *layout) { + if (layout == NULL) + return; + QLayoutItem *item; + while((item = layout->takeAt(0))) { + if (item->layout()) { + clearLayout(item->layout()); + delete item->layout(); + } + if (item->widget()) { + delete item->widget(); + } + delete item; + } +} void ExprParamElement::adjustForSearchType(ExprSearchType type) -{ - // record which search type is active - searchType = type; - QRegExp regExp("0|[1-9][0-9]*"); - numValidator = new QRegExpValidator(regExp, this); - QRegExp hexRegExp("[A-Fa-f0-9]*"); - hexValidator = new QRegExpValidator(hexRegExp, this); - - // remove all elements - QList children = internalframe->findChildren(); - QWidget* child; - QLayout * lay_out = internalframe->layout(); - while (!children.isEmpty()) - { - child = children.takeLast(); - child->hide(); - lay_out->removeWidget(child); - delete child; - } - delete lay_out; +{ + // record which search type is active + searchType = type; + QRegExp regExp("0|[1-9][0-9]*"); + numValidator = new QRegExpValidator(regExp, this); + QRegExp hexRegExp("[A-Fa-f0-9]*"); + hexValidator = new QRegExpValidator(hexRegExp, this); - QHBoxLayout* hbox = createLayout(); - internalframe->setLayout(hbox); - internalframe->setMinimumSize(320,26); + QHBoxLayout* hbox = static_cast(layout()); + clearLayout(hbox); + + setMinimumSize(getMinSize(STR_FIELDS_MIN_WFACTOR,FIELDS_MIN_HFACTOR) ); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + + if (isStringSearchExpression()) + { + // set up for default of a simple input field + QLineEdit* lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(STR_FIELDS_MIN_WFACTOR,FIELDS_MIN_HFACTOR)); + lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + lineEdit->setObjectName("param1"); + hbox->addWidget(lineEdit); + + hbox->addSpacing(9); + + QCheckBox* icCb = new QCheckBox(tr("ignore case"), this); + icCb->setMinimumSize(getMinSize(icCb->text().length()+2,FIELDS_MIN_HFACTOR)); + icCb->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + icCb->setObjectName("ignoreCaseCB"); + icCb->setCheckState(Qt::Checked); + hbox->addWidget(icCb); + + // hex search specifics: hidden case sensitivity and hex validator + if (searchType == HashSearch) { + icCb->hide(); + lineEdit->setValidator(hexValidator); + } + setMinimumSize(lineEdit->minimumSize() + + QSize((searchType != HashSearch ? icCb->minimumWidth() : 0),0) ); + + } else if (searchType == DateSearch) + { + QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), this); + dateEdit->setMinimumSize(getMinSize(DATE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dateEdit->setDisplayFormat(tr("yyyy-MM-dd")); + dateEdit->setObjectName("param1"); + dateEdit->setMinimumDate(QDate(1970, 1, 1)); + dateEdit->setMaximumDate(QDate(2099, 12,31)); + hbox->addWidget(dateEdit, Qt::AlignLeft); + hbox->addStretch(); + setMinimumSize(dateEdit->minimumSize()); + + } else if (searchType == SizeSearch) + { + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setMaximumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + lineEdit->setObjectName("param1"); + lineEdit->setValidator(numValidator); + hbox->addWidget(lineEdit, Qt::AlignLeft); + + hbox->addSpacing(9); + + RSComboBox * cb = new RSComboBox(this); + cb->setObjectName("unitsCb1"); + cb->addItem(tr("KB"), QVariant(1024)); + cb->addItem(tr("MB"), QVariant(1024*1024)); + cb->addItem(tr("GB"), QVariant(1024*1024*1024)); + hbox->addWidget(cb); + hbox->addStretch(); + setMinimumSize(lineEdit->minimumSize() + QSize(9,0) + + QSize(cb->minimumWidth(),0) ); - if (isStringSearchExpression()) - { - // set up for default of a simple input field - QLineEdit* lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(STR_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - lineEdit->setObjectName("param1"); - hbox->addWidget(lineEdit); - hbox->addSpacing(9); - QCheckBox* icCb = new QCheckBox(tr("ignore case"), internalframe); - icCb->setObjectName("ignoreCaseCB"); - icCb->setCheckState(Qt::Checked); - // hex search specifics: hidden case sensitivity and hex validator - if (searchType == HashSearch) { - icCb->hide(); - lineEdit->setValidator(hexValidator); } - hbox->addWidget(icCb); - hbox->addStretch(); - - } else if (searchType == DateSearch) - { - QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), internalframe); - dateEdit->setMinimumSize(DATE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - dateEdit->setDisplayFormat(tr("dd.MM.yyyy")); - dateEdit->setObjectName("param1"); - dateEdit->setMinimumDate(QDate(1970, 1, 1)); - dateEdit->setMaximumDate(QDate(2099, 12,31)); - hbox->addWidget(dateEdit, Qt::AlignLeft); - hbox->addStretch(); - } else if (searchType == SizeSearch) - { - QLineEdit * lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setMaximumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - lineEdit->setObjectName("param1"); - lineEdit->setValidator(numValidator); - hbox->addWidget(lineEdit, Qt::AlignLeft); - QComboBox * cb = new QComboBox(internalframe); - cb->setObjectName("unitsCb1"); - cb-> addItem(tr("KB"), QVariant(1024)); - cb->addItem(tr("MB"), QVariant(1048576)); - cb->addItem(tr("GB"), QVariant(1073741824)); - hbox->addSpacing(9); - internalframe->layout()->addWidget(cb); - hbox->addStretch(); - } - - /* POP Search not implemented - else if (searchType == PopSearch) - { - QLineEdit * lineEdit = new QLineEdit(elem); - lineEdit->setObjectName("param1"); - lineEdit->setValidator(numValidator); - elem->layout()->addWidget(lineEdit); - }*/ - hbox->invalidate(); - internalframe->adjustSize(); - internalframe->show(); - this->adjustSize(); + /* POP Search not implemented + else if (searchType == PopSearch) + { + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setObjectName("param1"); + lineEdit->setValidator(numValidator); + hbox->addWidget(lineEdit); + hbox->addStretch(); + setMinimumSize(lineEdit->minimumSize()); + }*/ + hbox->invalidate(); + adjustSize(); + show(); } void ExprParamElement::setRangedSearch(bool ranged) -{ +{ if (inRangedConfig == ranged) return; // nothing to do here inRangedConfig = ranged; - QHBoxLayout* hbox = (dynamic_cast(internalframe->layout())); + QHBoxLayout* hbox = static_cast(layout()); // add additional or remove extra input fields depending on whether // ranged search or not if (inRangedConfig) { + + if(hbox->itemAt(hbox->count()-1)->spacerItem()) + delete hbox->takeAt(hbox->count()-1); + QLabel * toLbl = new QLabel(tr("to")); - toLbl->setMinimumSize(10, FIELDS_MIN_HEIGHT); + toLbl->setMinimumSize(getMinSize(2, FIELDS_MIN_HFACTOR)); toLbl->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); if (searchType == DateSearch) { - internalframe->setMinimumSize(250,26); - QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), internalframe); - dateEdit->setMinimumSize(DATE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); + QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), this); + dateEdit->setMinimumSize(getMinSize(DATE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dateEdit->setDisplayFormat(tr("yyyy-MM-dd")); dateEdit->setObjectName("param2"); - dateEdit->setDisplayFormat(tr("dd.MM.yyyy")); dateEdit->setMinimumDate(QDate(1970, 1, 1)); dateEdit->setMaximumDate(QDate(2099, 12,31)); @@ -510,18 +519,21 @@ void ExprParamElement::setRangedSearch(bool ranged) hbox->addSpacing(9); hbox->addWidget(dateEdit, Qt::AlignLeft); hbox->addStretch(); + setMinimumSize(minimumSize() + QSize(9,0) + + QSize(toLbl->minimumWidth(),0) + QSize(9,0) + + QSize(dateEdit->minimumWidth(),0) ); + } else if (searchType == SizeSearch) { - internalframe->setMinimumSize(340,26); - QLineEdit * lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setMaximumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setMaximumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); lineEdit->setObjectName("param2"); lineEdit->setValidator(numValidator); - QComboBox * cb = new QComboBox(internalframe); + RSComboBox * cb = new RSComboBox(this); cb->setObjectName("unitsCb2"); - cb-> addItem(tr("KB"), QVariant(1024)); + cb->addItem(tr("KB"), QVariant(1024)); cb->addItem(tr("MB"), QVariant(1048576)); cb->addItem(tr("GB"), QVariant(1073741824)); @@ -532,28 +544,39 @@ void ExprParamElement::setRangedSearch(bool ranged) hbox->addSpacing(9); hbox->addWidget(cb); hbox->addStretch(); - } -// else if (searchType == PopSearch) -// { -// elem->layout()->addWidget(new QLabel(tr("to")), Qt::AlignCenter); -// QLineEdit * lineEdit = new QLineEdit(elem); -// lineEdit->setObjectName("param2"); -// lineEdit->setValidator(numValidator); -// elem->layout()->addWidget(slineEdit); -// } + setMinimumSize(minimumSize() + QSize(9,0) + + QSize(toLbl->minimumWidth(),0) + QSize(9,0) + + QSize(lineEdit->minimumWidth(),0) + QSize(9,0) + + QSize(cb->minimumWidth(),0) ); + + } +// else if (searchType == PopSearch) +// { +// QLineEdit * lineEdit = new QLineEdit(this); +// lineEdit->setObjectName("param2"); +// lineEdit->setValidator(numValidator); + +// hbox->addSpacing(9); +// hbox->addWidget(toLbl, Qt::AlignLeft); +// hbox->addSpacing(9); +// hbox->addWidget(lineEdit, Qt::AlignLeft); +// hbox->addStretch(); +// setMinimumSize(minimumSize() + QSize(9,0) +// + QSize(toLbl->minimumWidth(),0) + QSize(9,0) +// + QSize(lineEdit->minimumWidth(),0) ); +// } hbox->invalidate(); - internalframe->adjustSize(); - internalframe->show(); - this->adjustSize(); + adjustSize(); + show(); } else { adjustForSearchType(searchType); } } bool ExprParamElement::ignoreCase() -{ +{ return (isStringSearchExpression() - && (internalframe->findChild("ignoreCaseCB")) + && (findChild("ignoreCaseCB")) ->checkState()==Qt::Checked); } @@ -561,15 +584,15 @@ QString ExprParamElement::getStrSearchValue() { if (!isStringSearchExpression()) return ""; - QLineEdit * lineEdit = internalframe->findChild("param1"); + QLineEdit * lineEdit = findChild("param1"); return lineEdit->displayText(); } uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToField,bool *ok) { uint64_t val = 0; - if(ok!=NULL) - *ok=true ; + if(ok!=NULL) + *ok=true ; QString suffix = (isToField) ? "2": "1" ; // NOTE qFindChild necessary for MSVC 6 compatibility!! @@ -577,25 +600,29 @@ uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToFiel { case DateSearch: { - QDateEdit * dateEdit = internalframe->findChild (fieldName + suffix); - QDateTime * time = new QDateTime(dateEdit->date()); - val = (uint64_t)time->toTime_t(); + QDateEdit * dateEdit = findChild (fieldName + suffix); +#if QT_VERSION < QT_VERSION_CHECK(5,15,0) + QDateTime time = QDateTime(dateEdit->date()); +#else + QDateTime time = dateEdit->date().startOfDay(); +#endif + val = (uint64_t)time.toTime_t(); break; - } + } case SizeSearch: { - QLineEdit * lineEditSize = internalframe->findChild(fieldName + suffix); + QLineEdit * lineEditSize = findChild(fieldName + suffix); bool ok2 = false; val = (lineEditSize->displayText()).toULongLong(&ok2); if (ok2) - { - QComboBox * cb = internalframe->findChild((QString("unitsCb") + suffix)); + { + RSComboBox * cb = findChild((QString("unitsCb") + suffix)); QVariant data = cb->itemData(cb->currentIndex()); val *= data.toULongLong(); - } - else - if(ok!=NULL) - *ok=false ; + } + else + if(ok!=NULL) + *ok=false ; break; } @@ -615,8 +642,8 @@ uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToFiel case HashSearch: default: // shouldn't be here...val stays at -1 - if(ok!=NULL) - *ok=false ; + if(ok!=NULL) + *ok=false ; } return val; diff --git a/retroshare-gui/src/gui/advsearch/guiexprelement.h b/retroshare-gui/src/gui/advsearch/guiexprelement.h index 00748f4f7..50ebeaa15 100644 --- a/retroshare-gui/src/gui/advsearch/guiexprelement.h +++ b/retroshare-gui/src/gui/advsearch/guiexprelement.h @@ -22,25 +22,18 @@ #ifndef _GuiExprElement_h_ #define _GuiExprElement_h_ -#include -#include -#include -#include -#include +#include "gui/common/RSComboBox.h" + +#include "retroshare/rsexpr.h" + #include -#include -#include #include -#include -#include -#include #include -#include +#include +#include #include -#include - enum ExprSearchType { NameSearch, @@ -53,13 +46,13 @@ enum ExprSearchType }; -class GuiExprElement: public QWidget +class GuiExprElement: public QFrame { Q_OBJECT public: GuiExprElement(QWidget * parent = 0); - virtual void adjustForSearchType(ExprSearchType) {} + void adjustForSearchType(ExprSearchType) {} virtual ~GuiExprElement(){} virtual void set(int){} virtual void set(QObject*){} @@ -103,8 +96,8 @@ protected: condition combobox */ QStringList getConditionOptions(ExprSearchType t); - QHBoxLayout* createLayout(QWidget* parent = 0); - QFrame * internalframe; + QHBoxLayout* createLayout(QWidget* parent = nullptr); + QSize getMinSize(float widthFactor = 1.0, float heightFactor = 1.0); ExprSearchType searchType; @@ -125,7 +118,6 @@ protected: static QMap strConditionStrMap; static QMap relConditionStrMap; - }; /** the Expression operator combobox element */ @@ -134,11 +126,11 @@ class ExprOpElement : public GuiExprElement Q_OBJECT public: - ExprOpElement(QWidget * parent = 0); + ExprOpElement(QWidget * parent = nullptr); RsRegularExpression::LogicalOperator getLogicalOperator(); QString toString(); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Terms combobox element */ @@ -147,7 +139,7 @@ class ExprTermsElement : public GuiExprElement Q_OBJECT public: - ExprTermsElement(QWidget * parent = 0); + ExprTermsElement(QWidget * parent = nullptr); int getTermsIndex(); RsRegularExpression::RelOperator getRelOperator(); RsRegularExpression::StringOperator getStringOperator(); @@ -158,7 +150,7 @@ signals: void currentIndexChanged(int); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Conditions combobox element */ @@ -167,7 +159,7 @@ class ExprConditionElement : public GuiExprElement Q_OBJECT public: - ExprConditionElement(ExprSearchType, QWidget * parent = 0); + ExprConditionElement(QWidget * parent = nullptr, ExprSearchType type = NameSearch); RsRegularExpression::RelOperator getRelOperator(); RsRegularExpression::StringOperator getStringOperator(); void adjustForSearchType(ExprSearchType); @@ -178,7 +170,7 @@ signals: void currentIndexChanged(int); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Parameter element */ @@ -187,7 +179,7 @@ class ExprParamElement : public GuiExprElement Q_OBJECT public: - ExprParamElement(ExprSearchType, QWidget * parent = 0); + ExprParamElement(QWidget * parent = nullptr, ExprSearchType type = NameSearch); QVariant* getRSExprValue(); void adjustForSearchType(ExprSearchType); void setRangedSearch(bool ranged = true); diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui b/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui index 0a1635735..4446a0bef 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui @@ -13,7 +13,7 @@ MainWindow - + 0 @@ -48,7 +48,7 @@
- + 0 @@ -61,7 +61,7 @@ 0 - + 0 @@ -82,7 +82,7 @@ QFrame::Sunken - + 2 diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 491d2ca21..d4a20fe74 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -183,7 +183,7 @@ ChatWidget::ChatWidget(QWidget *parent) connect(ui->chatTextEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(chatCharFormatChanged())); connect(ui->chatTextEdit, SIGNAL(textChanged()), this, SLOT(updateLenOfChatTextEdit())); - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); ui->statusMessageLabel->hide(); setAcceptDrops(true); @@ -290,12 +290,12 @@ void ChatWidget::addChatBarWidget(QWidget *w) void ChatWidget::addTitleBarWidget(QWidget *w) { - ui->pluginTitleFrame->layout()->addWidget(w) ; + ui->trans_Frame_PluginTitle->layout()->addWidget(w) ; } void ChatWidget::addTopBarWidget(QWidget *w) { - ui->pluginTopFrame->layout()->addWidget(w) ; + ui->trans_Frame_PluginTop->layout()->addWidget(w) ; } void ChatWidget::hideChatText(bool hidden) @@ -642,7 +642,7 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event) } } - } else if (obj == ui->chatTextEdit) { + } else if (obj == ui->chatTextEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); @@ -1286,7 +1286,7 @@ void ChatWidget::sendChat() void ChatWidget::on_closeInfoFrameButton_clicked() { - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); } void ChatWidget::on_searchButton_clicked(bool bValue) @@ -1804,27 +1804,27 @@ void ChatWidget::updateStatus(const QString &peer_id, int status) switch (status) { case RS_STATUS_OFFLINE: - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online.")); break; case RS_STATUS_INACTIVE: - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply")); break; case RS_STATUS_ONLINE: - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); break; case RS_STATUS_AWAY: ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply")); - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); break; case RS_STATUS_BUSY: ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply")); - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); break; } diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 7ecbcfdc2..88e501335 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -84,10 +84,12 @@ - + + 11 75 + true true @@ -100,7 +102,14 @@ - + + + + 12 + 75 + true + + (Status) @@ -121,14 +130,14 @@ - + QFrame::NoFrame QFrame::Plain - + 3 @@ -311,14 +320,14 @@ - + QFrame::NoFrame QFrame::Plain - + 3 @@ -355,12 +364,6 @@ 0 - - QFrame::StyledPanel - - - QFrame::Raised - 0 @@ -375,10 +378,19 @@ 0 - + + + + + 0 + 0 + 0 + + + @@ -399,6 +411,15 @@ + + + + 0 + 0 + 0 + + + @@ -419,6 +440,15 @@ + + + + 154 + 154 + 154 + + + @@ -1089,21 +1119,6 @@ border-image: url(:/images/closepressed.png) - - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - RSTextBrowser - QTextBrowser -
gui/common/RSTextBrowser.h
-
HashBox QScrollArea @@ -1115,11 +1130,20 @@ border-image: url(:/images/closepressed.png) QTextEdit
gui/common/MimeTextEdit.h
+ + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + RSTextBrowser + QTextBrowser +
gui/common/RSTextBrowser.h
+
- - + diff --git a/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui b/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui index 7c4d01aaa..15dab649d 100644 --- a/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui +++ b/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui @@ -37,10 +37,15 @@
- - + + - + + + + 15 + + A chat room is a decentralized and anonymous chat group. All participants receive all messages. Once the room is created you can invite other friend nodes with invite button on top right. @@ -103,7 +108,7 @@ - + Public (Visible by friends) @@ -230,6 +235,13 @@ + + + 12 + 75 + true + + Create @@ -250,17 +262,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 -
FriendSelectionWidget QWidget @@ -272,6 +273,17 @@ QComboBox
gui/gxs/GxsIdChooser.h
+ + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp index 6c1f9128d..f9324d5fc 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp @@ -88,7 +88,7 @@ PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags f // ui.actionSetOnTop->setVisible(false);// removed, because the window manager should handle this already. // ui.actionColor->setVisible(false);// moved to the context menu - ui.chattoolBar->hide(); // no widgets left! + ui.headerToolBar->hide(); // no widgets left! setAttribute(Qt::WA_DeleteOnClose, true); @@ -440,7 +440,7 @@ void PopupChatWindow::calculateStyle(ChatDialog *dialog) } } - ui.chattoolBar->setStyleSheet(toolSheet); + ui.headerToolBar->setStyleSheet(toolSheet); ui.chatstatusbar->setStyleSheet(statusSheet); ui.chatcentralwidget->setStyleSheet(widgetSheet); } diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.ui b/retroshare-gui/src/gui/chat/PopupChatWindow.ui index ea6ea79af..0394a1c31 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.ui +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.ui @@ -43,7 +43,7 @@
- + false diff --git a/retroshare-gui/src/gui/common/AvatarDialog.cpp b/retroshare-gui/src/gui/common/AvatarDialog.cpp index 8eb24a184..632fa2948 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.cpp +++ b/retroshare-gui/src/gui/common/AvatarDialog.cpp @@ -166,7 +166,7 @@ void AvatarDialog::loadAvatarWidget() message += "\n RetroShare/stickers\n RetroShare/Data/stickers\n RetroShare/Data/Location/stickers"; ui->nostickersLabel->setText(message); } else { - ui->infoframe->hide(); + ui->info_Frame->hide(); } bool bOnlyOneGroup = (stickerTabs.count() == 1); @@ -272,7 +272,7 @@ void AvatarDialog::loadAvatarWidget() loadToolTips(firstpage); //Get widget's size - QSize sizeWidget = ui->avatarWidget->sizeHint(); + //QSize sizeWidget = ui->avatarWidget->sizeHint(); } diff --git a/retroshare-gui/src/gui/common/AvatarDialog.ui b/retroshare-gui/src/gui/common/AvatarDialog.ui index 9c5bc9482..a7b98cbcf 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.ui +++ b/retroshare-gui/src/gui/common/AvatarDialog.ui @@ -13,7 +13,7 @@ Change Avatar - + 0 @@ -37,14 +37,14 @@
- + QFrame::StyledPanel QFrame::Raised - + 3 @@ -52,14 +52,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + @@ -74,7 +74,7 @@ - + @@ -121,7 +121,7 @@ - + Qt::Vertical @@ -146,7 +146,7 @@ 0 0 431 - 359 + 356 @@ -180,7 +180,7 @@ - + 9 @@ -194,7 +194,7 @@ 9 - + Qt::Horizontal @@ -219,7 +219,7 @@ - frame + gradFrame headerFrame @@ -235,9 +235,7 @@
gui/gxschannels/GxsChannelPostThumbnail.h
- - - + buttonBox diff --git a/retroshare-gui/src/gui/common/Emoticons.cpp b/retroshare-gui/src/gui/common/Emoticons.cpp index d6bb17e4a..0f37eebfc 100644 --- a/retroshare-gui/src/gui/common/Emoticons.cpp +++ b/retroshare-gui/src/gui/common/Emoticons.cpp @@ -205,10 +205,11 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s // (Cyril) Never use an absolute size. It needs to be scaled to the actual font size on the screen. // QFontMetricsF fm(parent->font()) ; - smTab->setIconSize(QSize(28*fm.height()/14.0,28*fm.height()/14.0)); + QSize size(28*fm.height()/14.0,28*fm.height()/14.0); + smTab->setIconSize(size); smTab->setMinimumWidth(400); smTab->setTabPosition(QTabWidget::South); - smTab->setStyleSheet("QTabBar::tab { height: 44px; width: 44px; }"); + smTab->setStyleSheet(QString("QTabBar::tab { height: %1px; width: %1px; padding: 0px; margin: 0px;}").arg(size.width()*1.1)); if (groupName.right(4).toLower() == ".png") smTab->addTab( tabGrpWidget, FilesDefs::getIconFromQtResourcePath(groupName), ""); diff --git a/retroshare-gui/src/gui/common/FriendList.h b/retroshare-gui/src/gui/common/FriendList.h index 3a5c15bbe..efcf034d4 100644 --- a/retroshare-gui/src/gui/common/FriendList.h +++ b/retroshare-gui/src/gui/common/FriendList.h @@ -125,7 +125,7 @@ private: std::set openGroups; std::set openPeers; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorGroup; QColor mTextColorStatus[RS_STATUS_COUNT]; diff --git a/retroshare-gui/src/gui/common/FriendListModel.h b/retroshare-gui/src/gui/common/FriendListModel.h index 871dc14b9..646159377 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.h +++ b/retroshare-gui/src/gui/common/FriendListModel.h @@ -156,7 +156,7 @@ public: void clear() ; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorGroup; QColor mTextColorStatus[RS_STATUS_COUNT]; diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.h b/retroshare-gui/src/gui/common/FriendSelectionWidget.h index 7a2fb718e..20c4a15e9 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.h +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.h @@ -162,7 +162,7 @@ private: QAction *mActionSortByState; QAction *mActionFilterConnected; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorOnline; Ui::FriendSelectionWidget *ui; diff --git a/retroshare-gui/src/gui/common/GroupChooser.cpp b/retroshare-gui/src/gui/common/GroupChooser.cpp index be456f96d..8cdf2fd2d 100644 --- a/retroshare-gui/src/gui/common/GroupChooser.cpp +++ b/retroshare-gui/src/gui/common/GroupChooser.cpp @@ -20,15 +20,16 @@ #include "GroupChooser.h" +#include + +#include + #include #include -#include -#include - /** Constructor */ GroupChooser::GroupChooser(QWidget *parent) -: QComboBox(parent), mFlags(0) + : RSComboBox(parent), mFlags(0) { return; } diff --git a/retroshare-gui/src/gui/common/GroupChooser.h b/retroshare-gui/src/gui/common/GroupChooser.h index fa7e2eba7..04d821bc2 100644 --- a/retroshare-gui/src/gui/common/GroupChooser.h +++ b/retroshare-gui/src/gui/common/GroupChooser.h @@ -20,13 +20,14 @@ #pragma once -#include +#include "gui/common/RSComboBox.h" + #include -class GroupChooser : public QComboBox +class GroupChooser : public RSComboBox { public: - GroupChooser(QWidget *parent = NULL); + GroupChooser(QWidget *parent = nullptr); void loadGroups(uint32_t chooserFlags, const RsNodeGroupId& defaultId); bool getChosenGroup(RsNodeGroupId& id); diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.h b/retroshare-gui/src/gui/common/GroupTreeWidget.h index 6125dac28..b27c37014 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.h +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.h @@ -158,7 +158,7 @@ private: private: - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColor[GROUPTREEWIDGET_COLOR_COUNT]; // Compare role used for each column diff --git a/retroshare-gui/src/gui/common/HeaderFrame.ui b/retroshare-gui/src/gui/common/HeaderFrame.ui index 45a65943a..f9c436f68 100644 --- a/retroshare-gui/src/gui/common/HeaderFrame.ui +++ b/retroshare-gui/src/gui/common/HeaderFrame.ui @@ -16,15 +16,24 @@ 76 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + 0 @@ -37,7 +46,7 @@ 76 - + 12 @@ -67,7 +76,14 @@ - + + + + 22 + 75 + true + + Header text @@ -77,7 +93,7 @@ - + QFrame::HLine @@ -90,9 +106,9 @@ - StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
diff --git a/retroshare-gui/src/gui/common/LineEditClear.cpp b/retroshare-gui/src/gui/common/LineEditClear.cpp index b439aaa07..c3d68b512 100644 --- a/retroshare-gui/src/gui/common/LineEditClear.cpp +++ b/retroshare-gui/src/gui/common/LineEditClear.cpp @@ -29,17 +29,18 @@ #include #endif -#define IMAGE_FILTER ":/images/find-16.png" +#define IMAGE_FILTER ":/images/find.png" LineEditClear::LineEditClear(QWidget *parent) - : QLineEdit(parent) + : QLineEdit(parent) { mActionGroup = NULL; mFilterButton = NULL; + QFontMetrics fm(this->font()); mClearButton = new QToolButton(this); - mClearButton->setFixedSize(16, 16); - mClearButton->setIconSize(QSize(16, 16)); + mClearButton->setFixedSize(fm.height(), fm.height()); + mClearButton->setIconSize(QSize(fm.height(), fm.height())); mClearButton->setCursor(Qt::ArrowCursor); mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" "QToolButton { border-image: url(:/images/closenormal.png) }" @@ -50,7 +51,7 @@ LineEditClear::LineEditClear(QWidget *parent) mClearButton->setToolTip("Clear Filter"); connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); + connect(this, SIGNAL(textChanged(QString)), this, SLOT(updateClearButton(QString))); //#if QT_VERSION < 0x040700 #if QT_VERSION < 0x050000//PlaceHolder text only shown when not have focus in Qt4 @@ -124,15 +125,18 @@ void LineEditClear::showFilterIcon() } mFilterButton = new QToolButton(this); - mFilterButton->setFixedSize(16, 16); - mFilterButton->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER)); - //mFilterButton->setIconSize(filterPixmap.size()); - mFilterButton->setCursor(Qt::ArrowCursor); - mFilterButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" - "QToolButton[popupMode=\"2\"] { padding-right: 10px; }" - "QToolButton::menu-indicator[popupMode=\"2\"] { subcontrol-origin: padding; subcontrol-position: bottom right; top: 5px; left: -3px; width: 7px; }"); - mFilterButton->move(2, 2); + mFilterButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); mFilterButton->setFocusPolicy(Qt::NoFocus); + mFilterButton->setPopupMode(QToolButton::InstantPopup); + mFilterButton->setAutoFillBackground(true); + mFilterButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + setFilterButtonIcon(QIcon()); + mFilterButton->setCursor(Qt::ArrowCursor); + mFilterButton->setStyleSheet("QToolButton { background: transparent; border: none; margin: 0px; padding: 0px; }" + "QToolButton[popupMode=\"2\"] { padding-right: 10px; }" + "QToolButton::menu-indicator[popupMode=\"2\"] { subcontrol-origin: padding; subcontrol-position: bottom right; top: 5px; left: -3px; width: 7px; }" + ); + mFilterButton->move(2, 2); reposButtons(); } @@ -155,9 +159,6 @@ void LineEditClear::addFilter(const QIcon &icon, const QString &text, int id, co showFilterIcon(); if (mActionGroup == NULL) { - mFilterButton->setFixedSize(26, 16); - mFilterButton->setPopupMode(QToolButton::InstantPopup); - mActionGroup = new QActionGroup(this); mActionGroup->setExclusive(true); @@ -222,10 +223,19 @@ void LineEditClear::activateAction(QAction *action) setPlaceholderText(*description); } - QIcon icon = action->icon(); - if (icon.isNull()) { - icon = FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER); - } - - mFilterButton->setIcon(icon); + setFilterButtonIcon(action->icon()); +} + +void LineEditClear::setFilterButtonIcon(const QIcon &icon) +{ + if (icon.isNull()) + mFilterButton->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER)); + else + mFilterButton->setIcon(icon); + + ensurePolished(); + QFontMetrics fm(this->font()); + QSize size(fm.width("___"), fm.height()); + mFilterButton->setFixedSize(size); + mFilterButton->setIconSize(size); } diff --git a/retroshare-gui/src/gui/common/LineEditClear.h b/retroshare-gui/src/gui/common/LineEditClear.h index e8aea0626..ae30f6127 100644 --- a/retroshare-gui/src/gui/common/LineEditClear.h +++ b/retroshare-gui/src/gui/common/LineEditClear.h @@ -61,6 +61,7 @@ protected: #endif void reposButtons(); void activateAction(QAction *action); + void setFilterButtonIcon(const QIcon &icon); private slots: void updateClearButton(const QString &text); diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 1b0a684a3..d151c6430 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -237,7 +237,7 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_ID , 32 * fontWidth); ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT, 12 * fontWidth); - int avatarHeight = fontMetrics.height() * 3; + int avatarHeight = fontMetrics.height() * 2; ui->peerTreeWidget->setIconSize(QSize(avatarHeight, avatarHeight)); mModel->checkInternalData(true); @@ -376,7 +376,7 @@ void NewFriendList::addToolButton(QToolButton *toolButton) toolButton->setIconSize(QSize(S*1.5,S*1.5)); toolButton->setFocusPolicy(Qt::NoFocus); - ui->titleBarFrame->layout()->addWidget(toolButton); + ui->toolBarFrame->layout()->addWidget(toolButton); } void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel) diff --git a/retroshare-gui/src/gui/common/NewFriendList.ui b/retroshare-gui/src/gui/common/NewFriendList.ui index 3ec1c6c03..20ae02eb2 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.ui +++ b/retroshare-gui/src/gui/common/NewFriendList.ui @@ -10,7 +10,7 @@ 292
- + 0 @@ -27,14 +27,14 @@ 0 - + QFrame::Box QFrame::Sunken - + 3 @@ -58,6 +58,11 @@ + + + 12 + + Qt::CustomContextMenu @@ -124,7 +129,7 @@ LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
diff --git a/retroshare-gui/src/gui/common/StyledElidedLabel.cpp b/retroshare-gui/src/gui/common/RSComboBox.cpp similarity index 52% rename from retroshare-gui/src/gui/common/StyledElidedLabel.cpp rename to retroshare-gui/src/gui/common/RSComboBox.cpp index 43fc85220..e11a3c99d 100644 --- a/retroshare-gui/src/gui/common/StyledElidedLabel.cpp +++ b/retroshare-gui/src/gui/common/RSComboBox.cpp @@ -1,7 +1,7 @@ /******************************************************************************* - * gui/common/StyleElidedLabel.cpp * + * gui/common/RSComboBox.cpp * * * - * Copyright (c) 2014, RetroShare Team * + * Copyright (C) 2010, Retroshare Team * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -18,29 +18,42 @@ * * *******************************************************************************/ -#include -#include "StyledElidedLabel.h" +#include "RSComboBox.h" -/** Constructor */ -StyledElidedLabel::StyledElidedLabel(QWidget *parent) - : ElidedLabel(parent), _lastFactor(-1) +#include "gui/common/RSElidedItemDelegate.h" + +#include +#include + +RSComboBox::RSComboBox(QWidget *parent /*= nullptr*/) + :QComboBox(parent) { + // To Fix ComboBox item delegate not respecting stylesheet. See QDarkStyleSheet issues 214 + setItemDelegate(new RSElidedItemDelegate()); + view()->installEventFilter(this); } -StyledElidedLabel::StyledElidedLabel(const QString &text, QWidget *parent) - : ElidedLabel(text, parent), _lastFactor(-1) +bool RSComboBox::eventFilter(QObject *obj, QEvent *event) { -} + if(QAbstractItemView* view = dynamic_cast(obj)) + { + // To Fix ComboBox item delegate not respecting stylesheet. See QDarkStyleSheet issues 214 + // With QStyleItemDelegate QComboBox::item:checked doesn't works. + // With QComboBox ::item:checked, it's applied to hover ones. + if (event->type() == QEvent::Show) + { + if(QComboBox* cmb = dynamic_cast(view->parent()->parent()) ) + { + for (int curs = 0; curs < cmb->count(); ++curs) + { + QFont font = cmb->itemData(curs, Qt::FontRole).value(); + font.setBold(curs == cmb->currentIndex()); + cmb->setItemData(curs, QVariant(font), Qt::FontRole); -void StyledElidedLabel::setFontSizeFactor(int factor) -{ - int newFactor = factor; - if (factor > 0) { - if (_lastFactor > 0) newFactor = 100 + factor - _lastFactor; - _lastFactor = factor; - QFont f = font(); - qreal fontSize = newFactor * f.pointSizeF() / 100; - f.setPointSizeF(fontSize); - setFont(f); + } + } + } } + // pass the event on to the parent class + return QWidget::eventFilter(obj, event); } diff --git a/retroshare-gui/src/gui/common/StyledLabel.h b/retroshare-gui/src/gui/common/RSComboBox.h similarity index 74% rename from retroshare-gui/src/gui/common/StyledLabel.h rename to retroshare-gui/src/gui/common/RSComboBox.h index faf0654da..8ce46a649 100644 --- a/retroshare-gui/src/gui/common/StyledLabel.h +++ b/retroshare-gui/src/gui/common/RSComboBox.h @@ -1,7 +1,7 @@ /******************************************************************************* - * gui/common/StyledLabel.h * + * gui/common/RSComboBox.h * * * - * Copyright (c) 2014, RetroShare Team * + * Copyright (C) 2010, Retroshare Team * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -18,25 +18,19 @@ * * *******************************************************************************/ -#ifndef _STYLEDLABEL_H -#define _STYLEDLABEL_H +#ifndef RSCOMBOBOX_H +#define RSCOMBOBOX_H -#include +#include -class StyledLabel : public QLabel +class RSComboBox : public QComboBox { Q_OBJECT - Q_PROPERTY(int fontSizeFactor READ fontSizeFactor WRITE setFontSizeFactor) - public: - StyledLabel(QWidget *parent = NULL); - StyledLabel(const QString &text, QWidget *parent = NULL); + explicit RSComboBox(QWidget *parent = nullptr); - int fontSizeFactor(); - void setFontSizeFactor(int factor); - -private: - int mFontSizeFactor; +protected: + bool eventFilter(QObject *obj, QEvent *event); }; -#endif +#endif // RSCOMBOBOX_H diff --git a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp index 34879b10c..eb017a033 100644 --- a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp +++ b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp @@ -20,7 +20,7 @@ #include "RSElidedItemDelegate.h" -#include "gui/common/StyledElidedLabel.h" +#include "gui/common/ElidedLabel.h" #include "util/rsdebug.h" #include @@ -385,7 +385,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & const int textVMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameVMargin, nullptr, widget) + 1; textRect = textRect.adjusted(textHMargin, textVMargin, -textHMargin, -textVMargin); // remove width padding - StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),mPaintRoundedRect); + ElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),mPaintRoundedRect); } painter->restore(); #ifdef DEBUG_EID_PAINT @@ -436,7 +436,7 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, //Update RSElidedItemDelegate as only one delegate for all items QRect rectElision; - bool elided = StyledElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),true,&rectElision); + bool elided = ElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),true,&rectElision); if (elided && (rectElision.contains(ev->pos()))){ QToolTip::showText(ev->globalPos(),QString("") + text + QString("")); return true; // eat event diff --git a/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp b/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp index e1f517f42..63dd224f1 100644 --- a/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp +++ b/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp @@ -31,7 +31,7 @@ RSImageBlockWidget::RSImageBlockWidget(QWidget *parent) : ui->setupUi(this); mDefaultRect = this->geometry(); - ui->infoFrame->installEventFilter(this); + ui->info_Frame->installEventFilter(this); mTimer = new RsProtectedTimer(this); mTimer->setSingleShot(true); diff --git a/retroshare-gui/src/gui/common/RSImageBlockWidget.ui b/retroshare-gui/src/gui/common/RSImageBlockWidget.ui index f483a1afd..ab40c379d 100644 --- a/retroshare-gui/src/gui/common/RSImageBlockWidget.ui +++ b/retroshare-gui/src/gui/common/RSImageBlockWidget.ui @@ -33,10 +33,19 @@ 0 - + + + + + 0 + 0 + 0 + + + @@ -57,6 +66,15 @@ + + + + 0 + 0 + 0 + + + @@ -77,6 +95,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,7 +131,7 @@ QFrame::Box - + 6 diff --git a/retroshare-gui/src/gui/common/RsCollectionDialog.ui b/retroshare-gui/src/gui/common/RsCollectionDialog.ui index ceaea3b99..d8693ef0a 100644 --- a/retroshare-gui/src/gui/common/RsCollectionDialog.ui +++ b/retroshare-gui/src/gui/common/RsCollectionDialog.ui @@ -23,7 +23,7 @@ true - + 0 @@ -50,14 +50,14 @@ - + QFrame::StyledPanel QFrame::Raised - + @@ -70,7 +70,7 @@ QFrame::Plain - + @@ -88,7 +88,7 @@ 0 - + 0 @@ -334,7 +334,7 @@ - + :/images/deletemail24.png:/images/deletemail24.png @@ -410,7 +410,7 @@ - + @@ -419,7 +419,7 @@ - + Qt::Horizontal @@ -498,7 +498,7 @@
- frame + gradFrame headerFrame
diff --git a/retroshare-gui/src/gui/common/StyledElidedLabel.h b/retroshare-gui/src/gui/common/StyledElidedLabel.h deleted file mode 100644 index d6467ab1f..000000000 --- a/retroshare-gui/src/gui/common/StyledElidedLabel.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * gui/common/StyleElidedLabel.h * - * * - * Copyright (c) 2014, RetroShare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef _STYLEDELIDEDLABEL_H -#define _STYLEDELIDEDLABEL_H - -#include "ElidedLabel.h" - -class StyledElidedLabel : public ElidedLabel -{ - Q_OBJECT - Q_PROPERTY(int fontSizeFactor READ fontSizeFactor WRITE setFontSizeFactor) - -public: - StyledElidedLabel(QWidget *parent = NULL); - StyledElidedLabel(const QString &text, QWidget *parent = NULL); - - void setFontSizeFactor(int factor); - int fontSizeFactor() {return _lastFactor;} - -private: - int _lastFactor; -}; - -#endif diff --git a/retroshare-gui/src/gui/common/StyledLabel.cpp b/retroshare-gui/src/gui/common/StyledLabel.cpp deleted file mode 100644 index 2eabc9852..000000000 --- a/retroshare-gui/src/gui/common/StyledLabel.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * gui/common/StyledLabel.cpp * - * * - * Copyright (c) 2014, RetroShare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#include "StyledLabel.h" - -/** Constructor */ -StyledLabel::StyledLabel(QWidget *parent) - : QLabel(parent) -{ -} - -StyledLabel::StyledLabel(const QString &text, QWidget *parent) - : QLabel(text, parent) -{ -} - -int StyledLabel::fontSizeFactor() -{ - return mFontSizeFactor; -} - -void StyledLabel::setFontSizeFactor(int factor) -{ - mFontSizeFactor = factor; - - QFont f = font(); - qreal fontSize = mFontSizeFactor * f.pointSizeF() / 100; - f.setPointSizeF(fontSize); - setFont(f); -} diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.ui b/retroshare-gui/src/gui/connect/ConfCertDialog.ui index a2f94bc5b..93f9a86ba 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.ui +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 658 - 419 + 666 + 522 @@ -47,14 +47,14 @@
- + QFrame::StyledPanel QFrame::Raised - + diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp index 90f532fd5..c3463a79b 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp @@ -107,8 +107,8 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) : //ui->foffRadioButton->hide(); //ui->rsidRadioButton->hide(); - ui->cp_Label->hide(); - ui->requestinfolabel->hide(); + ui->info_Label_FrdReq->hide(); + ui->info_Label_Request->hide(); connect(ui->acceptNoSignGPGCheckBox,SIGNAL(toggled(bool)), ui->_options_GB,SLOT(setEnabled(bool))) ; connect(ui->addKeyToKeyring_CB,SIGNAL(toggled(bool)), ui->acceptNoSignGPGCheckBox,SLOT(setChecked(bool))) ; @@ -295,8 +295,8 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -320,8 +320,8 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -358,8 +358,8 @@ void ConnectFriendWizard::setGpgId(const RsPgpId &gpgId, const RsPeerId &sslId, setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -374,8 +374,8 @@ void ConnectFriendWizard::setGpgId(const RsPgpId &gpgId, const RsPeerId &sslId, //setStartId(friendRequest ? Page_FriendRequest : Page_Conclusion); setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage,tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -530,7 +530,7 @@ void ConnectFriendWizard::initializePage(int id) } } - ui->cp_Label->setText(tr("You have a friend request from") + " " + QString::fromUtf8(peerDetails.name.c_str())); + ui->info_Label_FrdReq->setText(tr("You have a friend request from") + " " + QString::fromUtf8(peerDetails.name.c_str())); ui->nameEdit->setText(QString::fromUtf8(peerDetails.name.c_str())); ui->trustEdit->setText(trustString); ui->profileIdEdit->setText(QString::fromStdString(peerDetails.gpg_id.toStdString())); diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index 5e9cd7a34..f6ac10b5e 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -360,7 +360,7 @@ - + 0 @@ -370,6 +370,15 @@ + + + + 0 + 0 + 0 + + + @@ -390,6 +399,15 @@ + + + + 0 + 0 + 0 + + + @@ -410,6 +428,15 @@ + + + + 154 + 154 + 154 + + + @@ -431,6 +458,11 @@ + + + 10 + + true @@ -510,6 +542,14 @@ 0 + + + 11 + 75 + true + true + + Name: @@ -687,7 +727,7 @@ - + @@ -701,7 +741,7 @@ - +
@@ -767,10 +807,19 @@
- + + + + + 0 + 0 + 0 + + + @@ -791,6 +840,15 @@ + + + + 0 + 0 + 0 + + + @@ -811,6 +869,15 @@ + + + + 154 + 154 + 154 + + + @@ -832,6 +899,11 @@ + + + 12 + + true @@ -863,17 +935,17 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
ConnectFriendPage QWizardPage
gui/connect/ConnectFriendWizard.h
1
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
RSPlainTextEdit QPlainTextEdit @@ -881,8 +953,8 @@
- + diff --git a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui index d65df4758..a1e0f208e 100644 --- a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui +++ b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui @@ -30,14 +30,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + 3 @@ -56,11 +56,11 @@ 0 - + Profile info - + 0 @@ -68,9 +68,9 @@ 6 - + - + @@ -103,7 +103,7 @@ - + <html><head/><body><p>The trust level is an optional and local parameter that you can set in order to remember your option about a given PGP key. It is not used whatsoever to authorize connections. </p></body></html> @@ -350,11 +350,11 @@ p, li { white-space: pre-wrap; } - + PGP key - + @@ -391,11 +391,11 @@ p, li { white-space: pre-wrap; } - + Friend options - + @@ -518,17 +518,22 @@ p, li { white-space: pre-wrap; } - - RSTextBrowser - QTextBrowser -
gui/common/RSTextBrowser.h
-
HeaderFrame QFrame
gui/common/HeaderFrame.h
1
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + RSTextBrowser + QTextBrowser +
gui/common/RSTextBrowser.h
+
diff --git a/retroshare-gui/src/gui/feeds/AttachFileItem.ui b/retroshare-gui/src/gui/feeds/AttachFileItem.ui index d0421e864..b755fba22 100644 --- a/retroshare-gui/src/gui/feeds/AttachFileItem.ui +++ b/retroshare-gui/src/gui/feeds/AttachFileItem.ui @@ -16,15 +16,24 @@ 35 - + + + 0 + + + 0 + + + 0 + + + 0 + 0 - - 0 - - + 0 @@ -37,7 +46,7 @@ QFrame::Sunken - + 2 diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp index 670567f03..814a915d9 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp @@ -536,9 +536,9 @@ void BoardsCommentsItem::setReadStatus(bool isNew, bool isUnread) ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); } - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } void BoardsCommentsItem::toggle() diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui index b3e529091..53e233e0b 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui @@ -10,7 +10,14 @@ 157 - + + + 12 + 75 + true + + + 1 @@ -24,7 +31,7 @@ 1 - + 0 @@ -40,7 +47,7 @@ QFrame::Sunken - + 9 @@ -53,7 +60,7 @@ 8 - + @@ -68,6 +75,7 @@ + 12 75 true @@ -131,6 +139,7 @@ + 12 75 true @@ -147,6 +156,7 @@ + 12 75 true @@ -160,7 +170,7 @@ - + Qt::Horizontal @@ -242,7 +252,7 @@ - + @@ -275,7 +285,7 @@ - + Qt::Vertical @@ -291,7 +301,7 @@ - + 0 @@ -312,7 +322,7 @@ QFrame::Sunken - + 5 @@ -367,7 +377,7 @@ - + 3 @@ -384,7 +394,7 @@ 3 - + Qt::Horizontal @@ -403,6 +413,7 @@ + 12 75 true @@ -425,7 +436,9 @@ + 12 75 + true true @@ -449,6 +462,8 @@ MS Sans Serif 10 + 75 + true @@ -483,8 +498,6 @@
gui/gxs/GxsIdLabel.h
- - - + diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp index 88b724598..7f1b23a92 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp @@ -175,9 +175,9 @@ void ChannelsCommentsItem::setup() // hide expand button, replies is not implemented yet ui->expandButton->hide(); - ui->mainFrame->setProperty("new", false); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", false); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); ui->expandFrame->hide(); } @@ -305,7 +305,8 @@ void ChannelsCommentsItem::loadMessage() RsQThreadUtils::postToObject( [cmt,this]() { - uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height()) + / QFontMetricsF(ui->subjectLabel->font()).height()); ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -368,7 +369,7 @@ void ChannelsCommentsItem::loadComment() int comNb = comments.size(); - RsQThreadUtils::postToObject( [comNb,this]() + RsQThreadUtils::postToObject( [comNb]() { QString sComButText = tr("Comment"); if (comNb == 1) @@ -434,7 +435,8 @@ void ChannelsCommentsItem::fill() /* subject */ //ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str())); - uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + //uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height()) + // / QFontMetricsF(ui->subjectLabel->font()).height()); // fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy //ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -534,9 +536,9 @@ void ChannelsCommentsItem::setReadStatus(bool isNew, bool isUnread) ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); } - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } void ChannelsCommentsItem::doExpand(bool open) diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui index 45c55b841..cd0265c1d 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui @@ -10,7 +10,7 @@ 157
- + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,7 +40,7 @@ QFrame::Sunken - + 9 @@ -51,12 +51,12 @@ 3 - + 8 - + @@ -134,6 +134,7 @@ + 12 75 true @@ -150,6 +151,7 @@ + 12 75 true @@ -163,7 +165,7 @@ - + Qt::Horizontal @@ -272,7 +274,7 @@ 3 - + Qt::Horizontal @@ -313,7 +315,9 @@ + 11 75 + true true @@ -360,7 +364,7 @@ - + @@ -393,7 +397,7 @@ - + Qt::Vertical @@ -409,7 +413,7 @@ - + 0 @@ -430,7 +434,7 @@ QFrame::Sunken - + 5 @@ -486,8 +490,6 @@
gui/gxs/GxsIdLabel.h
- - - + diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.ui b/retroshare-gui/src/gui/feeds/ChatMsgItem.ui index 2a8725b09..64c994b6f 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.ui +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.ui @@ -10,7 +10,7 @@ 209 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,9 +40,9 @@ QFrame::Sunken - + - + @@ -60,7 +60,7 @@ - + Qt::Vertical @@ -75,7 +75,12 @@ - + + + + 17 + + Peer Name @@ -85,7 +90,7 @@ - + Qt::Horizontal @@ -149,7 +154,7 @@ - + 0 @@ -247,7 +252,7 @@ - + Qt::Horizontal @@ -307,7 +312,7 @@ - + 0 @@ -345,11 +350,6 @@
gui/common/AvatarWidget.h
1 - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui index b5c3eb9aa..6c568993d 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui @@ -10,7 +10,15 @@ 161
- + + + 11 + 75 + true + true + + + 1 @@ -24,7 +32,7 @@ 1 - + 0 @@ -34,6 +42,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +71,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +100,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +139,9 @@ QFrame::Sunken - + - + @@ -133,7 +168,7 @@ - + @@ -144,6 +179,7 @@ + 11 75 true true @@ -158,7 +194,9 @@ + 11 75 + true true @@ -171,7 +209,7 @@ - + Qt::Horizontal @@ -186,7 +224,7 @@ - + @@ -207,7 +245,7 @@ - + Qt::Horizontal @@ -282,7 +320,7 @@ - + 0 @@ -303,7 +341,7 @@ Channel Description - + @@ -341,7 +379,6 @@ - diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index 733e3048b..f95c9bcb3 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -221,9 +221,9 @@ void GxsChannelPostItem::setup() //ui->subjectLabel->setMinimumWidth(100); //ui->warning_label->setMinimumWidth(100); - ui->mainFrame->setProperty("new", false); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", false); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); ui->expandFrame->hide(); } @@ -647,9 +647,9 @@ void GxsChannelPostItem::setReadStatus(bool isNew, bool isUnread) ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } // void GxsChannelPostItem::setFileCleanUpWarning(uint32_t time_left) diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui index 3ce8c06b3..578fa1637 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -10,7 +10,7 @@ 231 - + 1 @@ -30,7 +30,7 @@ 1 - + 0 @@ -46,11 +46,11 @@ QFrame::Sunken - + - + @@ -86,6 +86,7 @@ + 11 75 true true @@ -125,7 +126,7 @@ - + Qt::Vertical @@ -139,6 +140,14 @@ + + + 11 + 75 + false + true + + TextLabel @@ -317,7 +326,7 @@ - + Qt::Horizontal @@ -385,7 +394,7 @@ - + 0 @@ -406,7 +415,7 @@ QFrame::Sunken - + 5 @@ -451,7 +460,7 @@ - + Qt::Vertical @@ -472,7 +481,7 @@ ElidedLabel QLabel -
gui/common/ElidedLabel.h
+
gui/common/ElidedLabel.h
1
diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.ui b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui index c295d1b57..7a77f5bda 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui @@ -10,7 +10,7 @@ 108
- + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,7 +131,7 @@ QFrame::Sunken - + @@ -131,9 +158,9 @@ - + - + @@ -154,8 +181,9 @@ - 10 + 11 75 + true true @@ -177,6 +205,7 @@ + 11 75 true true @@ -188,7 +217,7 @@ - + Qt::Horizontal @@ -203,9 +232,9 @@ - + - + 10 @@ -220,6 +249,14 @@ + + + 11 + 75 + true + true + + name @@ -244,7 +281,7 @@ - + @@ -306,7 +343,7 @@ - + Qt::Horizontal @@ -358,8 +395,8 @@ - + diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui index 88000d0cb..14cb13620 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui @@ -10,7 +10,7 @@ 464 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +131,9 @@ QFrame::Sunken - + - + @@ -133,7 +160,7 @@ - + @@ -144,6 +171,7 @@ + 11 75 true true @@ -158,7 +186,9 @@ + 11 75 + true true @@ -171,7 +201,7 @@ - + Qt::Horizontal @@ -186,7 +216,7 @@ - + @@ -207,7 +237,7 @@ - + Qt::Horizontal @@ -282,7 +312,7 @@ - + 0 @@ -303,7 +333,7 @@ Forum Description - + @@ -339,7 +369,7 @@ Moderator list - + 0 @@ -367,7 +397,6 @@ - diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index af80babd5..5c33b4f13 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -106,7 +106,7 @@ void GxsForumMsgItem::setup() connect(ui->subjectLabel, SIGNAL(linkActivated(QString)), this, SLOT(on_linkActivated(QString))); ui->timestamplabel->clear(); ui->parentNameLabel->clear(); - ui->nameLabel->clear(); + ui->currNameLabel->clear(); /* general ones */ connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle())); @@ -347,12 +347,12 @@ void GxsForumMsgItem::fillMessage() if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) pixmap = GxsIdDetails::makeDefaultIcon(mMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); - ui->avatar->setPixmap(pixmap); + ui->currAvatar->setPixmap(pixmap); - ui->nameLabel->setId(mMessage.mMeta.mAuthorId); + ui->currNameLabel->setId(mMessage.mMeta.mAuthorId); RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, mMessage.mMeta.mMsgId, messageName()); - ui->subLabel->setText(msgLink.toHtml()); + ui->currSubLabel->setText(msgLink.toHtml()); if (wasExpanded() || ui->expandFrame->isVisible()) fillExpandFrame(); @@ -386,7 +386,7 @@ void GxsForumMsgItem::fillGroup() void GxsForumMsgItem::fillExpandFrame() { - ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + ui->currMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); } QString GxsForumMsgItem::messageName() @@ -445,9 +445,9 @@ void GxsForumMsgItem::toggle() void GxsForumMsgItem::setReadStatus(bool isNew, bool /*isUnread*/) { - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } /*********** SPECIFIC FUNCTIONS ***********************/ diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui index 5967010b7..89aec4e1b 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui @@ -10,7 +10,7 @@ 360 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -45,6 +54,15 @@ + + + + 0 + 0 + 0 + + + @@ -56,6 +74,15 @@ + + + + 154 + 154 + 154 + + + @@ -77,7 +104,7 @@ QFrame::Sunken - + @@ -104,7 +131,7 @@ - + @@ -115,7 +142,9 @@ + 11 75 + true true @@ -134,7 +163,7 @@ - + Qt::Horizontal @@ -165,9 +194,9 @@ - + - + 75 @@ -196,7 +225,7 @@ - + Qt::Horizontal @@ -299,7 +328,7 @@ - + 32 @@ -331,9 +360,9 @@ - + - + 0 @@ -371,7 +400,7 @@ - + Qt::Horizontal @@ -389,7 +418,7 @@ - + Qt::Vertical @@ -402,7 +431,7 @@ - + @@ -426,7 +455,7 @@ - + Qt::Horizontal @@ -454,9 +483,9 @@ QFrame::Sunken - + - + 32 @@ -472,10 +501,12 @@ - + + 11 75 + true true @@ -488,9 +519,9 @@ - + - + 0 @@ -509,7 +540,7 @@ - + 0 @@ -530,7 +561,7 @@ - + Qt::Vertical @@ -543,9 +574,9 @@ - + - + 0 @@ -587,13 +618,12 @@ AvatarWidget - QLabel + QWidget
gui/common/AvatarWidget.h
1
- diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index 87a01bcd9..66ae5f49b 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -67,7 +67,7 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, expandFrame->hide(); - inviteFrame->hide(); + info_Frame_Invite->hide(); updateItemStatic(); updateItem(); @@ -122,14 +122,14 @@ void MsgItem::updateItemStatic() title = QString::fromUtf8(mi.title.c_str()) + " " + tr("from") + " " + srcName; replyButton->setText(tr("Reply to invite")); subjectLabel->hide(); - inviteFrame->show(); + info_Frame_Invite->show(); } else if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.rsgxsid_srcId.isNull()) { title = QString::fromUtf8(mi.title.c_str()) + " " + " " + srcName; subjectLabel->hide(); - inviteFrame->show(); - infoLabel->setText(tr("This message invites you to make friend! You may accept this request.")); + info_Frame_Invite->show(); + infoLabel_Invite->setText(tr("This message invites you to make friend! You may accept this request.")); sendinviteButton->hide(); replyButton->hide(); } @@ -137,7 +137,7 @@ void MsgItem::updateItemStatic() { title = tr("Message From") + ": " + srcName; sendinviteButton->hide(); - inviteFrame->hide(); + info_Frame_Invite->hide(); } } else diff --git a/retroshare-gui/src/gui/feeds/MsgItem.ui b/retroshare-gui/src/gui/feeds/MsgItem.ui index 9075554a9..b195e80c6 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.ui +++ b/retroshare-gui/src/gui/feeds/MsgItem.ui @@ -10,7 +10,7 @@ 180
- + 1 @@ -24,7 +24,7 @@ 1
- + 0 @@ -40,10 +40,10 @@ QFrame::Sunken - + - - + + 0 @@ -57,7 +57,7 @@ 0 - + 70 @@ -82,7 +82,7 @@ - 12 + 11 75 true true @@ -97,7 +97,7 @@ - + Qt::Horizontal @@ -142,7 +142,7 @@ - + @@ -164,7 +164,7 @@ - + Qt::Horizontal @@ -259,10 +259,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -283,6 +292,15 @@ + + + + 0 + 0 + 0 + + + @@ -303,6 +321,15 @@ + + + + 154 + 154 + 154 + + + @@ -333,7 +360,7 @@ QFrame::Box - + 6 @@ -347,7 +374,7 @@ 6 - + 16 @@ -366,7 +393,7 @@ - + This message invites you to make friend! You may accept this request and send your own Certificate back @@ -380,7 +407,7 @@ - + @@ -412,7 +439,7 @@ AvatarWidget - QLabel + QWidget
gui/common/AvatarWidget.h
1
diff --git a/retroshare-gui/src/gui/feeds/PeerItem.ui b/retroshare-gui/src/gui/feeds/PeerItem.ui index 230cbd7a4..cf66466f3 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.ui +++ b/retroshare-gui/src/gui/feeds/PeerItem.ui @@ -13,7 +13,7 @@ false - + 1 @@ -27,7 +27,7 @@ 1
- + 0 @@ -43,13 +43,13 @@ QFrame::Sunken - + 0 - + 0 @@ -60,7 +60,7 @@ 0 - + 70 @@ -76,9 +76,14 @@ - + - + + + + 17 + + Peer Name @@ -97,6 +102,7 @@ + 11 75 true true @@ -113,9 +119,9 @@ - + - + Qt::Horizontal @@ -152,7 +158,7 @@ - + @@ -203,7 +209,7 @@ - + Qt::Horizontal @@ -265,11 +271,11 @@ - + - + - + @@ -397,7 +403,7 @@ - + @@ -406,6 +412,14 @@ 0 + + + 11 + 75 + true + true + + TextLabel @@ -508,18 +522,12 @@ AvatarWidget - QLabel + QWidget
gui/common/AvatarWidget.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui index 27226fd28..636cc2c54 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui @@ -10,7 +10,7 @@ 161 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +131,9 @@ QFrame::Sunken - + - + @@ -133,7 +160,7 @@ - + @@ -144,6 +171,7 @@ + 11 75 true true @@ -158,7 +186,9 @@ + 11 75 + true true @@ -171,7 +201,7 @@ - + Qt::Horizontal @@ -186,7 +216,7 @@ - + @@ -207,7 +237,7 @@ - + Qt::Horizontal @@ -282,7 +312,7 @@ - + 0 @@ -303,14 +333,14 @@ Board Description - + - :/images/contacts24.png + :/images/contacts24.png @@ -340,8 +370,6 @@ - - diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.ui b/retroshare-gui/src/gui/feeds/SecurityIpItem.ui index a9471c6b1..11a742880 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.ui +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.ui @@ -10,7 +10,7 @@ 185 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -43,12 +43,12 @@ QFrame::Sunken - + 0 - + 0 @@ -66,7 +66,7 @@ 0 - + 70 @@ -79,13 +79,141 @@ 70 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + + + + 6 + + + 0 + + + + + + 11 + 75 + true + true + + + + Title + + + + + + + + 0 + 0 + + + + + 10 + + + + IP address: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>This warning is here to protect you against traffic forwarding attacks. In such a case, the friend you're connected to will not see your external IP, but the attacker's IP. </p><p><br/></p><p>However, if you just changed IPs for some reason (some ISPs regularly force change IPs) this warning just tells you that a friend connected to the new IP before Retroshare figured out the IP changed. Nothing's wrong in this case.</p><p><br/></p><p>You can easily suppress false warnings by white-listing your own IPs (e.g. the range of your ISP), or by completely disabling these warnings in Options-&gt;Notify-&gt;News Feed.</p></body></html> + + + IP Address + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + but reported: + + + + + + + + 0 + 0 + + + + IP address reported + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Peer: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Name (Location) + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + 75 + true + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + - + 6 @@ -142,7 +270,7 @@ - + Qt::Horizontal @@ -196,130 +324,12 @@ - - - - - - - 75 - true - - - - TextLabel - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - - - - - - 6 - - - 0 - - - - - - 0 - 0 - - - - IP address: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>This warning is here to protect you against traffic forwarding attacks. In such a case, the friend you're connected to will not see your external IP, but the attacker's IP. </p><p><br/></p><p>However, if you just changed IPs for some reason (some ISPs regularly force change IPs) this warning just tells you that a friend connected to the new IP before Retroshare figured out the IP changed. Nothing's wrong in this case.</p><p><br/></p><p>You can easily suppress false warnings by white-listing your own IPs (e.g. the range of your ISP), or by completely disabling these warnings in Options-&gt;Notify-&gt;News Feed.</p></body></html> - - - IP Address - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - but reported: - - - - - - - - 0 - 0 - - - - IP address reported - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Peer: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Title - - - - - - - - 0 - 0 - - - - Name (Location) - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - -
- + @@ -333,22 +343,6 @@ - - - - - 0 - 0 - - - - Location - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - @@ -365,19 +359,6 @@ - - - - - 75 - true - - - - Location: - - - @@ -401,6 +382,35 @@ + + + + + 75 + true + + + + Location: + + + + + + + + 0 + 0 + + + + Location + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + @@ -412,15 +422,10 @@ AvatarWidget - QLabel + QWidget
gui/common/AvatarWidget.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
RsBanListToolButton QToolButton diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.ui b/retroshare-gui/src/gui/feeds/SecurityItem.ui index de674a133..bc0524d18 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.ui +++ b/retroshare-gui/src/gui/feeds/SecurityItem.ui @@ -10,7 +10,7 @@ 246 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,13 +40,13 @@ QFrame::Sunken - + 0 - - + + 0 @@ -63,7 +63,7 @@ 0 - + 70 @@ -76,13 +76,10 @@ 70 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - + 6 @@ -90,7 +87,12 @@ 0 - + + + + 17 + + Peer Name @@ -109,6 +111,7 @@ + 11 75 true true @@ -123,13 +126,18 @@ - + 0 0 + + + 17 + + wants to be friend with you on RetroShare @@ -144,7 +152,7 @@ - + @@ -164,7 +172,7 @@ - + 6 @@ -276,7 +284,7 @@ - + Qt::Horizontal @@ -292,7 +300,7 @@ - + Qt::Horizontal @@ -351,11 +359,11 @@ - + - + - + @@ -463,7 +471,7 @@ - + @@ -472,6 +480,14 @@ 0 + + + 11 + 75 + true + true + + TextLabel @@ -570,19 +586,14 @@ AvatarWidget - QLabel + QWidget
gui/common/AvatarWidget.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- + diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.ui b/retroshare-gui/src/gui/feeds/SubFileItem.ui index 6717836b5..8fdd8230d 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.ui +++ b/retroshare-gui/src/gui/feeds/SubFileItem.ui @@ -10,7 +10,7 @@ 128 - + 0 @@ -27,16 +27,16 @@ 0 - + QFrame::Box QFrame::Sunken - + - + @@ -215,7 +215,7 @@ - + diff --git a/retroshare-gui/src/gui/groups/CreateGroup.ui b/retroshare-gui/src/gui/groups/CreateGroup.ui index 7abcd5a4e..838a15ac6 100644 --- a/retroshare-gui/src/gui/groups/CreateGroup.ui +++ b/retroshare-gui/src/gui/groups/CreateGroup.ui @@ -13,27 +13,36 @@ Create a Group - + + + 0 + + + 0 + + + 0 + + + 0 + 6 0 - - 0 - - + QFrame::StyledPanel QFrame::Raised - + - + diff --git a/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp b/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp index 630a3efbe..9e56c53cd 100644 --- a/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp @@ -20,15 +20,15 @@ #include "GxsCircleChooser.h" -#include #include +#include #include /** Constructor */ GxsCircleChooser::GxsCircleChooser(QWidget *parent) -: QComboBox(parent) + : RSComboBox(parent) { return; } diff --git a/retroshare-gui/src/gui/gxs/GxsCircleChooser.h b/retroshare-gui/src/gui/gxs/GxsCircleChooser.h index f78b350b8..37234b230 100644 --- a/retroshare-gui/src/gui/gxs/GxsCircleChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsCircleChooser.h @@ -21,17 +21,18 @@ #ifndef _GXS_CIRCLES_CHOOSER_H #define _GXS_CIRCLES_CHOOSER_H -#include +#include "gui/common/RSComboBox.h" + #include -class GxsCircleChooser : public QComboBox +class GxsCircleChooser : public RSComboBox { - Q_OBJECT + Q_OBJECT public: - GxsCircleChooser(QWidget *parent = NULL); + GxsCircleChooser(QWidget *parent = nullptr); - void loadCircles(const RsGxsCircleId &defaultId); + void loadCircles(const RsGxsCircleId &defaultId); bool getChosenCircle(RsGxsCircleId &id); private: diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui index bad001d4f..72b64e4e0 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui @@ -46,7 +46,14 @@ - + + + + 12 + 75 + true + + Comment Container @@ -87,12 +94,7 @@
gui/common/RSTabWidget.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
+ diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui index 734e490ca..7b50494d6 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui @@ -97,7 +97,13 @@
- + + + + 75 + true + + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">sort by</span></p></body></html> @@ -174,15 +180,20 @@
+ + GxsCommentTreeWidget + QTreeWidget +
gui/gxs/GxsCommentTreeWidget.h
+
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
- GxsCommentTreeWidget - QTreeWidget -
gui/gxs/GxsCommentTreeWidget.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp index 3dacc3e6c..67a538a94 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp @@ -51,8 +51,8 @@ void GxsCreateCommentDialog::loadComment(const QString &msgText, const QString & ui->avatarLabel->setGxsId(msgAuthorId); ui->avatarLabel->setFrameType(AvatarWidget::NO_FRAME); - ui->replaytolabel->setId(msgAuthorId); - ui->replaytolabel->setText( tr("Replying to") + " @" + msgAuthor); + ui->replyToLabel->setId(msgAuthorId); + ui->replyToLabel->setText( tr("Replying to") + " @" + msgAuthor); ui->commentTextEdit->setPlaceholderText( tr("Type your reply")); ui->postButton->setText("Reply"); @@ -116,11 +116,11 @@ void GxsCreateCommentDialog::checkLength(){ int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length(); if(charRemains >= 0) { text = tr("It remains %1 characters after HTML conversion.").arg(charRemains); - ui->infoLabel->setStyleSheet("QLabel#infoLabel { }"); + ui->info_Label->setStyleSheet("QLabel#info_Label { }"); }else{ text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); - ui->infoLabel->setStyleSheet("QLabel#infoLabel {color: red; font: bold; }"); + ui->info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }"); } ui->postButton->setEnabled(charRemains>=0); - ui->infoLabel->setText(text); + ui->info_Label->setText(text); } diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui index 9a40b6f4a..aecd1b794 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui @@ -7,13 +7,13 @@ 0 0 505 - 367 + 406 Make Comment - + 0 @@ -30,7 +30,7 @@ 0 - + 0 @@ -58,9 +58,9 @@ QFrame::Raised - + - + 52 @@ -73,16 +73,24 @@ 52 - + - + true + + + 11 + 75 + true + 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"> @@ -121,7 +129,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -138,12 +146,12 @@ p, li { white-space: pre-wrap; } - + 6 - + Qt::Horizontal @@ -176,14 +184,14 @@ p, li { white-space: pre-wrap; } - + TextLabel - + @@ -208,21 +216,31 @@ p, li { white-space: pre-wrap; } + + + 12 + 75 + true + + Post - + 0 0 - - + + + 75 + true + @@ -240,6 +258,12 @@ p, li { white-space: pre-wrap; } QLabel
gui/gxs/GxsIdLabel.h
+ + AvatarWidget + QWidget +
gui/common/AvatarWidget.h
+ 1 +
GxsIdChooser QComboBox @@ -250,12 +274,6 @@ p, li { white-space: pre-wrap; } QTextEdit
gui/common/MimeTextEdit.h
- - AvatarWidget - QLabel -
gui/common/AvatarWidget.h
- 1 -
diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ff1919403..f51c73be3 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -92,7 +92,7 @@ GxsGroupDialog::~GxsGroupDialog() void GxsGroupDialog::init() { // connect up the buttons. - connect(ui.createButton, SIGNAL(clicked()), this, SLOT(submitGroup())); + connect(ui.postButton, SIGNAL(clicked()), this, SLOT(submitGroup())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelDialog())); connect(ui.pubKeyShare_cb, SIGNAL(clicked()), this, SLOT(setShareList())); connect(ui.addAdmins_cb, SIGNAL(clicked()), this, SLOT(setAdminsList())); @@ -194,7 +194,7 @@ void GxsGroupDialog::setUiText(UiType uiType, const QString &text) //ui.contactsdockWidget->setWindowTitle(text); break; case UITYPE_BUTTONBOX_OK: - ui.createButton->setText(text); + ui.postButton->setText(text); break; } } @@ -210,7 +210,7 @@ void GxsGroupDialog::setUiToolTip(UiType uiType, const QString &text) ui.addAdmins_cb->setToolTip(text); break; case UITYPE_BUTTONBOX_OK: - ui.createButton->setToolTip(text); + ui.postButton->setToolTip(text); default: break; } @@ -232,14 +232,14 @@ void GxsGroupDialog::initMode() { ui.stackedWidget->setCurrentIndex(1); mReadonlyFlags = 0xffffffff; // Force all to readonly. - ui.createButton->hide(); + ui.postButton->hide(); } break; case MODE_EDIT: { ui.stackedWidget->setCurrentIndex(0); - ui.createButton->setText(tr("Submit Group Changes")); + ui.postButton->setText(tr("Submit Group Changes")); } break; } @@ -384,8 +384,8 @@ void GxsGroupDialog::setupVisibility() ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS); ui.addAdmins_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); - ui.label_8->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); ui.moderatorsLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); + ui.moderatorsValueLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); @@ -465,12 +465,12 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description) ui.lastpostline->setText(tr("Never")); else ui.lastpostline->setText(DateTime::formatLongDateTime(mGrpMeta.mLastPost)); - ui.authorLabel->setId(mGrpMeta.mAuthorId); + ui.authorValueLabel->setId(mGrpMeta.mAuthorId); ui.createdline->setText(DateTime::formatLongDateTime(mGrpMeta.mPublishTs)); link = RetroShareLink::createMessage(mGrpMeta.mAuthorId, ""); - ui.authorLabel->setText(link.toHtml()); + ui.authorValueLabel->setText(link.toHtml()); ui.IDline->setText(QString::fromStdString(mGrpMeta.mGroupId.toStdString())); ui.descriptiontextEdit->setPlainText(description); @@ -915,8 +915,8 @@ void GxsGroupDialog::setSelectedModerators(const std::set& ids) moderatorsListString += link.toHtml() + " "; } - //ui.moderatorsLabel->setId(det.mId); - ui.moderatorsLabel->setText(moderatorsListString); + //ui.moderatorsValueLabel->setId(det.mId); + ui.moderatorsValueLabel->setText(moderatorsListString); } /*********************************************************************************** diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index e6da1441e..b42e777de 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -13,7 +13,7 @@ Create New - + 0 @@ -47,7 +47,7 @@ 0
- + 0 @@ -59,7 +59,7 @@ - + 3 @@ -98,7 +98,7 @@
- + 6 @@ -106,7 +106,7 @@ 6
- + Name @@ -118,7 +118,7 @@
- + Qt::Horizontal @@ -131,7 +131,7 @@ - + <html><head/><body><p>The identity here can be used to send feedback.</p></body></html> @@ -178,7 +178,7 @@ Description - + @@ -190,7 +190,7 @@ Publish Signatures - + 6 @@ -235,7 +235,7 @@ - + Qt::Horizontal @@ -255,7 +255,7 @@ Personal Signatures - + @@ -278,7 +278,7 @@ - + Qt::Horizontal @@ -298,7 +298,7 @@ Comments - + 6 @@ -329,7 +329,7 @@
- + Qt::Horizontal @@ -349,16 +349,16 @@ Spam-protection - + - + Posts permissions: - + <html><head/><body><p>This combo box allows you to choose how posts are handled depending on the node the poster belongs to.</p><p><span style=" font-weight:600;">All allowed</span>: all posts are treated equally.</p><p><span style=" font-weight:600;">Defavor posts from unsigned IDs</span>: anonymous IDs will require a reputation of 0.4 to be received/forwarded.</p><p><span style=" font-weight:600;">Defavor posts from unsigned IDs and IDs from unknown nodes</span>: anonymous IDs and IDs signed by unknown Retroshare nodes will require a reputation of 0.4 to be received/forwarded.</p></body></html> @@ -380,7 +380,7 @@ - + Qt::Horizontal @@ -406,9 +406,9 @@
- + - + @@ -426,7 +426,7 @@ Message Distribution - + 6 @@ -532,20 +532,7 @@ - - - Qt::Horizontal - - - - 0 - 17 - - - - - - + Qt::Horizontal @@ -563,205 +550,213 @@
- + 0 - + Info - - - - - - - Author - - - - - - - Last Post - - - - - - - Name - - - - - - - Popularity - - - - - + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Author + + + + + + + Last Post + + + + + + + Name + + + + + + + Popularity + + + + + + + TextLabel + + + + + + + Anti Spam: + + + + + + + true + + + + + + + TextLabel + + + true + + + + + + + Comments: + + + + + + + GxsIdLabel + + + true + + + + + + + ID + + + + + + + true + + + + + + + Posts + + + + + + + + + + true + + + + + + + TextLabel - - - - Anti Spam: - - - - - - - true - - - - - - - TextLabel - - - true - - - - - - - Comments: - - - - - - - GxsIdLabel - - - true - - - - - - - ID - - - - - - - true - - - - - - - Posts - - - - - - - - - - true - - - - - - - - - TextLabel - - - - - - - - 0 - 0 - - - - - - - - - - Distribution: - - - - - - - true - - - - - - - true - - - - - - - Moderators: - - - - - - - TextLabel - - - true - - - - - - - - - - Created + + + + + 0 + 0 + + + + + Distribution: + + + + + + + true + + + + + + + true + + + + + + + Moderators: + + + + + + + TextLabel + + + true + + + + + + + + + + Created + + + - + Description - + @@ -777,14 +772,14 @@ - + QFrame::StyledPanel QFrame::Raised - + @@ -793,7 +788,7 @@ - + Qt::Horizontal @@ -806,7 +801,14 @@ - + + + + 12 + 75 + true + + Create @@ -819,25 +821,9 @@ - GxsIdLabel + ClickableLabel QLabel -
gui/gxs/GxsIdLabel.h
-
- - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
-
- - GxsCircleChooser - QComboBox -
gui/gxs/GxsCircleChooser.h
-
- - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 +
util/ClickableLabel.h
FriendSelectionWidget @@ -845,20 +831,41 @@
gui/common/FriendSelectionWidget.h
1
- - MimeTextEdit - QTextEdit -
gui/common/MimeTextEdit.h
-
GroupChooser QComboBox
gui/common/GroupChooser.h
- ClickableLabel + GxsCircleChooser + QComboBox +
gui/gxs/GxsCircleChooser.h
+
+ + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
+
+ + GxsIdLabel QLabel -
util/ClickableLabel.h
+
gui/gxs/GxsIdLabel.h
+
+ + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
+ + MimeTextEdit + QTextEdit +
gui/common/MimeTextEdit.h
+
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui index 0a8fa4587..8cb249020 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui @@ -70,7 +70,14 @@
- + + + + 12 + 75 + true + + Name @@ -168,11 +175,6 @@
gui/common/RSTabWidget.h
1 - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
GroupTreeWidget QWidget diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp index dfcafaaf2..9197e3665 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp @@ -79,14 +79,14 @@ void GroupShareKey::setTyp() ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/channels.png")); ui->headerFrame->setHeaderText(tr("Share channel publish permissions")); - ui->sharekeyinfo_label->setText(tr("You can allow your friends to publish in your channel, or send the publish permissions to another Retroshare instance of yours. Select the friends which you want to be allowed to publish in this channel. Note: it is currently not possible to revoke channel publish permissions.")); + ui->info_Label_ShareKey->setText(tr("You can allow your friends to publish in your channel, or send the publish permissions to another Retroshare instance of yours. Select the friends which you want to be allowed to publish in this channel. Note: it is currently not possible to revoke channel publish permissions.")); } else if(mGrpType == FORUM_KEY_SHARE) { ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); ui->headerFrame->setHeaderText(tr("Share forum admin permissions")); - ui->sharekeyinfo_label->setText(tr("You can let your friends know about your forum by sharing it with them. Select the friends with which you want to share your forum.")); + ui->info_Label_ShareKey->setText(tr("You can let your friends know about your forum by sharing it with them. Select the friends with which you want to share your forum.")); } else if (mGrpType == POSTED_KEY_SHARE) @@ -96,7 +96,7 @@ void GroupShareKey::setTyp() ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png")); ui->headerFrame->setHeaderText(tr("Share board admin permissions")); - ui->sharekeyinfo_label->setText(tr("You can allow your friends to edit the board. Select them in the list below. Note: it is not possible to revoke Board admin permissions.")); + ui->info_Label_ShareKey->setText(tr("You can allow your friends to edit the board. Select them in the list below. Note: it is not possible to revoke Board admin permissions.")); } else diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui index fb7db3b6e..b41aad127 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui @@ -17,7 +17,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -78,7 +87,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -140,15 +158,12 @@
- + 11 - - - QFrame::StyledPanel diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 9321c4de4..a3398e4cd 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -19,18 +19,19 @@ *******************************************************************************/ #include "GxsIdChooser.h" + #include "GxsIdDetails.h" #include "RsGxsUpdateBroadcastBase.h" -#include "gui/Identity/IdEditDialog.h" #include "gui/common/FilesDefs.h" +#include "gui/Identity/IdEditDialog.h" #include "util/misc.h" #include #include #include -#include +#include #include #define ROLE_SORT Qt::UserRole + 1 // Qt::UserRole is reserved for data @@ -50,7 +51,7 @@ /** Constructor */ GxsIdChooser::GxsIdChooser(QWidget *parent) - : QComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT) + : RSComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT) { // mBase = new RsGxsUpdateBroadcastBase(rsIdentity, this); // connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool))); diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h index 3cee770eb..205d0d13a 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h @@ -21,14 +21,14 @@ #ifndef _GXS_ID_CHOOSER_H #define _GXS_ID_CHOOSER_H -#include -#include +#include "gui/common/RSComboBox.h" + +#include "retroshare/rsgxsifacetypes.h" // This class implement a basic RS functionality which is that ComboBox displaying Id // should update regularly. They also should update only when visible, to save CPU time. // -struct RsGxsIfaceHelper; class RsGxsUpdateBroadcastBase; #define IDCHOOSER_ID_REQUIRED 0x0001 @@ -36,13 +36,12 @@ class RsGxsUpdateBroadcastBase; #define IDCHOOSER_NO_CREATE 0x0004 #define IDCHOOSER_NON_ANONYMOUS 0x0008 -class GxsIdChooser : public QComboBox +class GxsIdChooser : public RSComboBox { Q_OBJECT public: - GxsIdChooser(RsGxsIfaceHelper* ifaceImpl, QWidget *parent = NULL); - GxsIdChooser(QWidget *parent = NULL); + GxsIdChooser(QWidget *parent = nullptr); virtual ~GxsIdChooser(); void setFlags(uint32_t flags) ; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp index 3d51f0acb..e8f34d1eb 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp @@ -74,7 +74,7 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); connect(removeAllFilesButton, SIGNAL(clicked() ), this , SLOT(clearAllAttachments())); //connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); - connect(subjectEdit,SIGNAL(textChanged(const QString&)),this,SLOT(updatePreviewText(const QString&))); + connect(subjectEdit,SIGNAL(textChanged(QString)),this,SLOT(updatePreviewText(QString))); connect(expandButton, SIGNAL(clicked()), this, SLOT( toggle())); connect(addThumbnailButton, SIGNAL(clicked() ), this , SLOT(addThumbnail())); @@ -183,8 +183,8 @@ void CreateGxsChannelMsg::contextMenu(QPoint /*point*/) int n_file = 0 ; - for(QList::const_iterator it(links.begin());it!=links.end();++it) - if((*it).type() == RetroShareLink::TYPE_FILE) + for(auto &it : links) + if(it.type() == RetroShareLink::TYPE_FILE) ++n_file ; QMenu contextMnu(this) ; @@ -203,42 +203,42 @@ void CreateGxsChannelMsg::pasteLink() { std::cerr << "Pasting links: " << std::endl; - QList links; + QList links; RSLinkClipboard::pasteLinks(links) ; - for(QList::const_iterator it(links.begin());it!=links.end();++it) - if((*it).type() == RetroShareLink::TYPE_FILE) + for(auto &it : links) + if(it.type() == RetroShareLink::TYPE_FILE) { // 0 - check that we actually have the file! // - std::cerr << "Pasting " << (*it).toString().toStdString() << std::endl; + std::cerr << "Pasting " << it.toString().toStdString() << std::endl; - FileInfo info ; - RsFileHash hash( (*it).hash().toStdString()) ; + FileInfo info ; + RsFileHash hash( it.hash().toStdString()) ; #ifdef TO_REMOVE - if(rsFiles->alreadyHaveFile( hash,info ) ) + if(rsFiles->alreadyHaveFile( hash,info ) ) #endif - addAttachment(hash, (*it).name().toUtf8().constData(), (*it).size(), rsFiles->alreadyHaveFile( hash,info ), RsPeerId()) ; + addAttachment(hash, it.name().toUtf8().constData(), it.size(), rsFiles->alreadyHaveFile( hash,info ), RsPeerId()) ; #ifdef TO_REMOVE - else - not_have.push_back( *it ) ; + else + not_have.push_back( *it ) ; #endif - } + } #ifdef TO_REMOVE - if(!not_have.empty()) - { - QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"

" ; + if(!not_have.empty()) + { + QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"

" ; - for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) - msg += (*it).toString() + "
" ; + for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) + msg += (*it).toString() + "
" ; - if(QMessageBox::YesToAll == QMessageBox::question(NULL,tr("About to post un-owned files to a channel."),msg,QMessageBox::YesToAll | QMessageBox::No)) - for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) - addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ; - } + if(QMessageBox::YesToAll == QMessageBox::question(NULL,tr("About to post un-owned files to a channel."),msg,QMessageBox::YesToAll | QMessageBox::No)) + for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) + addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ; + } #endif } @@ -818,9 +818,9 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str post.mThumbnail.copy((uint8_t *) ba.data(), ba.size()); } - int generateCount = 0; #ifdef ENABLE_GENERATE + int generateCount = 0; if (generateCheckBox->isChecked()) { generateCount = generateSpinBox->value(); if (QMessageBox::question(this, tr("Generate mass data"), tr("Do you really want to generate %1 messages ?").arg(generateCount), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { @@ -830,18 +830,20 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str #endif uint32_t token; - if (generateCount) { #ifdef ENABLE_GENERATE + if (generateCount) { for (int count = 0; count < generateCount; ++count) { RsGxsChannelPost generatePost = post; generatePost.mMeta.mMsgName = QString("%1 %2").arg(QString::fromUtf8(post.mMeta.mMsgName.c_str())).arg(count + 1, 3, 10, QChar('0')).toUtf8().constData(); rsGxsChannels->createPost(token, generatePost); } -#endif } else { +#endif rsGxsChannels->createPost(token, post); +#ifdef ENABLE_GENERATE } +#endif } accept(); @@ -966,14 +968,14 @@ void CreateGxsChannelMsg::toggle() if (expandButton->isChecked()) { thumbnailFrame->hide(); - gridLayoutTextEdit->setContentsMargins(0,9,0,0); + subject_HL->setContentsMargins(0,9,0,0); expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png"))); expandButton->setToolTip(tr("Show")); } else { thumbnailFrame->show(); - gridLayoutTextEdit->setContentsMargins(0,0,0,0); + subject_HL->setContentsMargins(0,0,0,0); expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png"))); expandButton->setToolTip(tr("Hide")); } diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui index b29e9cdd8..510da23a1 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui @@ -20,7 +20,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -40,14 +40,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + 3 @@ -77,7 +77,7 @@ - + 9 @@ -99,7 +99,7 @@
- + Qt::Horizontal @@ -113,6 +113,13 @@ + + + 12 + 75 + true + + Post @@ -141,8 +148,8 @@ 0 - - + + 0 @@ -163,7 +170,7 @@ QFrame::Plain - + 6 @@ -193,7 +200,7 @@ p, li { white-space: pre-wrap; } - + @@ -208,7 +215,7 @@ p, li { white-space: pre-wrap; } - + <html><head/><body><p>Choose aspect ratio policy. In 'Auto' mode, the most suitable aspect ratio is chosen for you.</p></body></html> @@ -254,7 +261,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -272,7 +279,7 @@ p, li { white-space: pre-wrap; } - + 9 @@ -317,7 +324,7 @@ p, li { white-space: pre-wrap; } - + 6 @@ -332,7 +339,7 @@ p, li { white-space: pre-wrap; }
- + Qt::Vertical @@ -350,7 +357,7 @@ p, li { white-space: pre-wrap; }
- + 6 @@ -388,10 +395,10 @@ p, li { white-space: pre-wrap; }
- + - + @@ -481,7 +488,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -518,7 +525,7 @@ p, li { white-space: pre-wrap; } 0 - + 3 @@ -548,7 +555,7 @@ p, li { white-space: pre-wrap; } Drag and Drop Files from Search Results - +
@@ -579,7 +586,7 @@ p, li { white-space: pre-wrap; }
- + Qt::Horizontal @@ -604,6 +611,12 @@ p, li { white-space: pre-wrap; }
+ + ChannelPostThumbnailView + QWidget +
gui/gxschannels/GxsChannelPostThumbnail.h
+ 1 +
HeaderFrame QFrame @@ -617,10 +630,9 @@ p, li { white-space: pre-wrap; } 1 - ChannelPostThumbnailView - QWidget -
gui/gxschannels/GxsChannelPostThumbnail.h
- 1 + RSComboBox + QComboBox +
gui/common/RSComboBox.h
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui index c1b02ab83..463b05423 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui @@ -13,7 +13,7 @@ Form - + 0 @@ -27,11 +27,11 @@ 0 - + true - + 2 diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui index 4bdae007a..cc98c8e56 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui @@ -55,6 +55,13 @@ 0 + + + 12 + 75 + true + + Subscribe @@ -77,6 +84,12 @@ + + + 75 + true + + Qt::NoFocus @@ -189,12 +202,12 @@ - + + 25 75 true - false @@ -389,7 +402,7 @@ <!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:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; 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> @@ -649,6 +662,12 @@ p, li { white-space: pre-wrap; } QLabel
gui/gxs/GxsIdLabel.h
+ + ElidedLabel + QLabel +
gui/common/ElidedLabel.h
+ 1 +
SubscribeToolButton QToolButton @@ -666,11 +685,6 @@ p, li { white-space: pre-wrap; }
gui/gxs/GxsCommentDialog.h
1
- - StyledElidedLabel - QLabel -
gui/common/StyledElidedLabel.h
-
diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 3cf29ecf1..ffbcb2493 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -384,14 +384,14 @@ void CreateGxsForumMsg::checkLength() int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length(); if(charRemains >= 0) { text = tr("It remains %1 characters after HTML conversion.").arg(charRemains); - ui.infoLabel->setStyleSheet("QLabel#infoLabel { }"); + ui.info_Label->setStyleSheet("QLabel#info_Label { }"); }else{ text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); - ui.infoLabel->setStyleSheet("QLabel#infoLabel {color: red; font: bold; }"); + ui.info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }"); } ui.postButton->setToolTip(text); ui.postButton->setEnabled(charRemains>=0); - ui.infoLabel->setText(text); + ui.info_Label->setText(text); } void CreateGxsForumMsg::createMsg() diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui index 7af77f2d5..10105a630 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png
- + 0 @@ -37,17 +37,17 @@
- + QFrame::StyledPanel QFrame::Raised - + - + 0 @@ -68,7 +68,7 @@ QFrame::Raised - + 0 @@ -82,7 +82,7 @@ 0 - + 50 @@ -119,9 +119,9 @@ Forum Post - + - + @@ -141,8 +141,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Sans Serif'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Sans Serif';"><br /></p></body></html> +</style></head><body style=" font-family:'MS Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8.25pt;"><br /></p></body></html> @@ -160,7 +160,7 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - + 0 @@ -249,7 +249,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -298,7 +298,7 @@ p, li { white-space: pre-wrap; } Attach files via drag and drop - + @@ -322,7 +322,7 @@ p, li { white-space: pre-wrap; } - + @@ -341,7 +341,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -355,6 +355,13 @@ p, li { white-space: pre-wrap; } + + + 12 + 75 + true + + Post @@ -375,17 +382,6 @@ p, li { white-space: pre-wrap; } - - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 -
- - MimeTextEdit - QTextEdit -
gui/common/MimeTextEdit.h
-
GxsIdChooser QComboBox @@ -397,10 +393,20 @@ p, li { white-space: pre-wrap; }
gui/common/HeaderFrame.h
1
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
+ + MimeTextEdit + QTextEdit +
gui/common/MimeTextEdit.h
+
- diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 424091867..8f9b9ed0d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -63,7 +63,7 @@ GxsForumGroupDialog::GxsForumGroupDialog(QWidget *parent) : GxsGroupDialog(ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) { ui.pubKeyShare_cb->setEnabled(true) ; - ui.label_2->setToolTip(tr("

Put one of your identities here to allow others to send feedback and also have moderator rights on the forum. You may as well leave that field blank and keep the forum anonymously administrated.

")); + ui.idChooserLabel->setToolTip(tr("

Put one of your identities here to allow others to send feedback and also have moderator rights on the forum. You may as well leave that field blank and keep the forum anonymously administrated.

")); } GxsForumGroupDialog::GxsForumGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 6df3c5c89..29e56268f 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -214,7 +214,7 @@ private: unsigned int mNewCount; bool mDisplayBannedText; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorRead; QColor mTextColorUnread; QColor mTextColorUnreadChildren; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui index b5fe3f95d..b27354e8b 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui @@ -74,6 +74,13 @@ 0 + + + 12 + 75 + true + + Subscribe @@ -84,6 +91,12 @@
+ + + 75 + true + + Qt::NoFocus @@ -112,19 +125,29 @@ - + 0 0 + + + 12 + 75 + true + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> Forum Name + + 2 + @@ -173,7 +196,7 @@
- + Lastest post in thread @@ -405,7 +428,7 @@ - + @@ -521,40 +544,46 @@ - RSTextBrowser - QTextBrowser -
gui/common/RSTextBrowser.h
-
- - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
- - StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
-
- - SubscribeToolButton - QToolButton -
gui/common/SubscribeToolButton.h
+
gui/common/ElidedLabel.h
+ 1
GxsIdLabel QLabel
gui/gxs/GxsIdLabel.h
+ + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
RSImageBlockWidget QWidget
gui/common/RSImageBlockWidget.h
1
+ + RSTextBrowser + QTextBrowser +
gui/common/RSTextBrowser.h
+
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + SubscribeToolButton + QToolButton +
gui/common/SubscribeToolButton.h
+
- + diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index fcdd4f3cc..4dc8177bd 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -418,8 +418,9 @@ qss/chat/compact/history/main.css qss/chat/compact/history/variants/Standard.css qss/chat/compact/history/variants/Colored.css - qss/stylesheet/qss.default - qss/stylesheet/Standard.qss + qss/stylesheet/default.qss + qss/stylesheet/Standard_Light.qss + qss/stylesheet/Standard_Dark.qss images/tags/pgp-known.png images/tags/pgp-unknown.png images/tags/dev-ambassador.png diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 2be5efb35..f80434fd2 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -136,8 +137,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) m_completer = NULL; - ui.distantFrame->hide(); - ui.sizeLimitFrame->hide(); + ui.info_Frame_Distant->hide(); + ui.info_Frame_SizeLimit->hide(); ui.respond_to_CB->hide(); ui.fromLabel->hide(); @@ -148,7 +149,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.hashBox->hide(); // connect up the buttons. - connect( ui.actionSend, SIGNAL( triggered (bool)), this, SLOT( sendMessage( ) ) ); + connect( ui.actionSend, SIGNAL( triggered(bool)), this, SLOT( sendMessage() ) ); //connect( ui.actionReply, SIGNAL( triggered (bool)), this, SLOT( replyMessage( ) ) ); connect(ui.boldbtn, SIGNAL(clicked()), this, SLOT(textBold())); connect(ui.underlinebtn, SIGNAL(clicked()), this, SLOT(textUnderline())); @@ -162,16 +163,16 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) connect(ui.actionContactsView, SIGNAL(triggered()), this, SLOT(toggleContacts())); connect(ui.actionSaveas, SIGNAL(triggered()), this, SLOT(saveasDraft())); connect(ui.actionAttach, SIGNAL(triggered()), this, SLOT(attachFile())); - connect(ui.titleEdit, SIGNAL(textChanged(const QString &)), this, SLOT(titleChanged())); + connect(ui.titleEdit, SIGNAL(textChanged(QString)), this, SLOT(titleChanged())); connect(ui.sizeincreaseButton, SIGNAL (clicked()), this, SLOT (fontSizeIncrease())); connect(ui.sizedecreaseButton, SIGNAL (clicked()), this, SLOT (fontSizeDecrease())); connect(ui.actionQuote, SIGNAL(triggered()), this, SLOT(blockQuote())); connect(ui.codeButton, SIGNAL (clicked()), this, SLOT (toggleCode())); - connect(ui.msgText, SIGNAL( checkSpellingChanged( bool ) ), this, SLOT( spellChecking( bool ) ) ); + connect(ui.msgText, SIGNAL( checkSpellingChanged(bool) ), this, SLOT( spellChecking(bool) ) ); - connect(ui.msgText, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)), this, SLOT(currentCharFormatChanged(const QTextCharFormat &))); + connect(ui.msgText, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(currentCharFormatChanged(QTextCharFormat))); connect(ui.msgText, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged())); connect(ui.msgText->document(), SIGNAL(modificationChanged(bool)), actionSave, SLOT(setEnabled(bool))); @@ -206,12 +207,12 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) connect(ui.filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged(int))); - connect(ui.addToButton, SIGNAL(clicked(void)), this, SLOT(addTo())); - connect(ui.addCcButton, SIGNAL(clicked(void)), this, SLOT(addCc())); - connect(ui.addBccButton, SIGNAL(clicked(void)), this, SLOT(addBcc())); - connect(ui.addRecommendButton, SIGNAL(clicked(void)), this, SLOT(addRecommend())); + connect(ui.addToButton, SIGNAL(clicked()), this, SLOT(addTo())); + connect(ui.addCcButton, SIGNAL(clicked()), this, SLOT(addCc())); + connect(ui.addBccButton, SIGNAL(clicked()), this, SLOT(addBcc())); + connect(ui.addRecommendButton, SIGNAL(clicked()), this, SLOT(addRecommend())); - connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&,int)), this, SLOT(peerStatusChanged(const QString&,int))); + connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(QString,int)), this, SLOT(peerStatusChanged(QString,int))); connect(ui.friendSelectionWidget, SIGNAL(contentChanged()), this, SLOT(buildCompleter())); connect(ui.friendSelectionWidget, SIGNAL(doubleClicked(int,QString)), this, SLOT(addTo())); connect(ui.friendSelectionWidget, SIGNAL(itemSelectionChanged()), this, SLOT(friendSelectionChanged())); @@ -232,7 +233,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.friendSelectionWidget->start(); QActionGroup *grp = new QActionGroup(this); - connect(grp, SIGNAL(triggered(QAction *)), this, SLOT(textAlign(QAction *))); + connect(grp, SIGNAL(triggered(QAction*)), this, SLOT(textAlign(QAction*))); actionAlignLeft = new QAction(QIcon(""), tr("&Left"), grp); actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); @@ -248,7 +249,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) actionAlignJustify->setCheckable(true); QActionGroup *grp2 = new QActionGroup(this); - connect(grp2, SIGNAL(triggered(QAction *)), this, SLOT(textStyle(QAction *))); + connect(grp2, SIGNAL(triggered(QAction*)), this, SLOT(textStyle(QAction*))); actionDisc = new QAction(QIcon(""), tr("Bullet list (disc)"), grp2); actionDisc->setCheckable(true); @@ -283,17 +284,44 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.filterComboBox->setCurrentIndex(3); connect(ui.comboStyle, SIGNAL(activated(int)),this, SLOT(changeFormatType(int))); - connect(ui.comboFont, SIGNAL(activated(const QString &)), this, SLOT(textFamily(const QString &))); + connect(ui.comboFont, SIGNAL(activated(QString)), this, SLOT(textFamily(QString))); + +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + ui.comboFont->setMaximumWidth(QFontMetrics(ui.comboFont->font()).width("_")*20); +#else + ui.comboFont->setMaximumWidth(QFontMetrics(ui.comboFont->font()).horizontalAdvance("_")*20); +#endif ui.comboSize->setEditable(true); + ui.comboSize->style()->polish(ui.comboSize); // Needed else QLineEdit inside QComboBox background is painted with black color. QFontDatabase db; foreach(int size, db.standardSizes()) - ui.comboSize->addItem(QString::number(size)); + ui.comboSize->addItem(QString::number(size)); - connect(ui.comboSize, SIGNAL(activated(const QString &)),this, SLOT(textSize(const QString &))); + QStyleOptionComboBox opt; QSize sh; + opt.initFrom(ui.comboSize); + opt.subControls = QStyle::SC_All; + opt.activeSubControls = QStyle::SC_None; + opt.editable = ui.comboSize->isEditable(); + sh = ui.comboSize->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, ui.comboSize); + //+4 because there is hardcoded margins in QCommonStyle::drawControl(CE_ComboBoxLabel) +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + sh.setWidth(sh.width() + ui.comboSize->fontMetrics().width("8")*2 + 4); +#else + sh.setWidth(sh.width() + ui.comboSize->fontMetrics().horizontalAdvance("8")*2 + 4); +#endif + ui.comboSize->setMaximumWidth(sh.width()); + ui.comboSize->view()->setMinimumWidth(sh.width() + ui.comboSize->view()->verticalScrollBar()->minimumWidth() + 4); + + connect(ui.comboSize, SIGNAL(activated(QString)),this, SLOT(textSize(QString))); ui.comboSize->setCurrentIndex(ui.comboSize->findText(QString::number(QApplication::font().pointSize()))); + ui.toolBarFrame->setMinimumHeight( ui.comboStyle->height() + + ui.toolBarFrameHLayout->contentsMargins().top() + + ui.toolBarFrameHLayout->contentsMargins().bottom() + ); + QMenu * alignmentmenu = new QMenu(); alignmentmenu->addAction(actionAlignLeft); alignmentmenu->addAction(actionAlignCenter); @@ -313,11 +341,11 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.styleButton->setMenu(formatlistmenu); QPixmap pxm(24,24); - pxm.fill(Qt::black); + pxm.fill(ui.msgText->palette().text().color()); ui.colorbtn->setIcon(pxm); QPixmap pxm2(24,24); - pxm2.fill(Qt::white); + pxm2.fill(ui.msgText->palette().window().color()); ui.color2btn->setIcon(pxm2); /* Set header resize modes and initial section sizes */ @@ -369,7 +397,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) // create tag menu TagsMenu *menu = new TagsMenu (tr("Tags"), this); connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); - connect(menu, SIGNAL(tagSet(int, bool)), this, SLOT(tagSet(int, bool))); + connect(menu, SIGNAL(tagSet(int,bool)), this, SLOT(tagSet(int,bool))); connect(menu, SIGNAL(tagRemoveAll()), this, SLOT(tagRemoveAll())); ui.tagButton->setMenu(menu); @@ -408,21 +436,21 @@ void MessageComposer::updateCells(int,int) if(has_gxs) { ui.respond_to_CB->show(); - ui.distantFrame->show(); + ui.info_Frame_Distant->show(); ui.fromLabel->show(); checkLength(); } else { ui.respond_to_CB->hide(); - ui.distantFrame->hide() ; + ui.info_Frame_Distant->hide() ; ui.fromLabel->hide(); } if(rowCount > 20) - ui.sizeLimitFrame->show(); + ui.info_Frame_SizeLimit->show(); else - ui.sizeLimitFrame->hide(); + ui.info_Frame_SizeLimit->hide(); } void MessageComposer::processSettings(bool bLoad) @@ -619,7 +647,7 @@ void MessageComposer::addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId // PGPId+SslId are always here. But if the peer is not a friend the SSL id cannot be used. // (todo) If the PGP id doesn't get us a PGP key from the keyring, we need to create a short invite - RetroShareLink link = RetroShareLink::createUnknownSslCertificate(sslId, gpgId); + RetroShareLink link = RetroShareLink::createUnknownSslCertificate(sslId, gpgId); if (!link.valid()) return; @@ -772,7 +800,6 @@ void MessageComposer::buildCompleter() std::list::iterator peerIt; rsPeers->getFriendList(peers); - std::list gxsIds; QList gxsitems ; ui.friendSelectionWidget->items(gxsitems,FriendSelectionWidget::IDTYPE_GXS) ; @@ -781,9 +808,9 @@ void MessageComposer::buildCompleter() QStringList completerList; QStringList completerGroupList; - for (QList::const_iterator idIt = gxsitems.begin(); idIt != gxsitems.end(); ++idIt) + for (auto &idIt : gxsitems) { - RsGxsId id ( ui.friendSelectionWidget->idFromItem( *idIt ) ); + RsGxsId id ( ui.friendSelectionWidget->idFromItem( idIt ) ); RsIdentityDetails detail; if(rsIdentity->getIdDetails(id, detail)) @@ -1038,8 +1065,8 @@ MessageComposer *MessageComposer::newMsg(const std::string &msgId /* = ""*/) std::list groupInfoList; rsPeers->getGroupInfoList(groupInfoList); - std::list groupIds; - std::list::iterator groupIt; + // std::list groupIds; + // std::list::iterator groupIt; // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgto, groupIds); // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { @@ -1281,7 +1308,7 @@ MessageComposer *MessageComposer::forwardMsg(const std::string &msgId) msgComposer->setTitleText(QString::fromUtf8(msgInfo.title.c_str()), FORWARD); msgComposer->setQuotedMsg(QString::fromUtf8(msgInfo.msg.c_str()), buildReplyHeader(msgInfo)); - std::list& files_info = msgInfo.files; + const std::list& files_info = msgInfo.files; msgComposer->setFileList(files_info); @@ -1599,16 +1626,16 @@ bool MessageComposer::getRecipientFromRow(int row, enumType &type, destinationTy QString MessageComposer::getRecipientEmailAddress(const RsGxsId& id,const RsIdentityDetails& detail) { - return (QString("%2 <")+tr("Distant identity:")+" %2@%1>").arg(QString::fromStdString(id.toStdString())).arg(QString::fromUtf8(detail.mNickname.c_str())) ; + return (QString("%2 <")+tr("Distant identity:")+" %2@%1>").arg(QString::fromStdString(id.toStdString()), QString::fromUtf8(detail.mNickname.c_str())) ; } QString MessageComposer::getRecipientEmailAddress(const RsPeerId& /* id */,const RsPeerDetails& detail) { - QString location_name = detail.location.empty()?tr("[Missing]"):QString::fromUtf8(detail.location.c_str()) ; + QString location_name = detail.location.empty()?tr("[Missing]"):QString::fromUtf8(detail.location.c_str()) ; - return (QString("%1 (")+tr("Node name & id:")+" %2, %3)").arg(QString::fromUtf8(detail.name.c_str())) - .arg(location_name) - .arg(QString::fromUtf8(detail.id.toStdString().c_str())) ; + return (QString("%1 (")+tr("Node name & id:")+" %2, %3)").arg(QString::fromUtf8(detail.name.c_str()) + , location_name + , QString::fromUtf8(detail.id.toStdString().c_str())) ; } void MessageComposer::setRecipientToRow(int row, enumType type, destinationType dest_type, const std::string &id) @@ -1619,12 +1646,13 @@ void MessageComposer::setRecipientToRow(int row, enumType type, destinationType QComboBox *comboBox = dynamic_cast(ui.recipientWidget->cellWidget(row, COLUMN_RECIPIENT_TYPE)); if (comboBox == NULL) { - comboBox = new QComboBox; + comboBox = new RSComboBox; comboBox->addItem(tr("To"), TO); comboBox->addItem(tr("Cc"), CC); comboBox->addItem(tr("Bcc"), BCC); ui.recipientWidget->setCellWidget(row, COLUMN_RECIPIENT_TYPE, comboBox); + ui.recipientWidget->setRowHeight(row, comboBox->height()); comboBox->setLayoutDirection(Qt::RightToLeft); comboBox->installEventFilter(this); @@ -1789,7 +1817,7 @@ void MessageComposer::editingRecipientFinished() if (row >= rowCount) // not found return; - enumType type; + enumType type = TO; std::string id; // dummy destinationType dtype ; @@ -1818,13 +1846,13 @@ void MessageComposer::editingRecipientFinished() ui.friendSelectionWidget->items(gxsitems,FriendSelectionWidget::IDTYPE_GXS) ; RsIdentityDetails detail; - for (QList::const_iterator idIt = gxsitems.begin(); idIt != gxsitems.end(); ++idIt) + for (auto &idIt : gxsitems) { - RsGxsId id ( ui.friendSelectionWidget->idFromItem( *idIt ) ); + RsGxsId gxsId ( ui.friendSelectionWidget->idFromItem( idIt ) ); - if(rsIdentity->getIdDetails(id, detail) && text == getRecipientEmailAddress(id,detail)) + if(rsIdentity->getIdDetails(gxsId, detail) && text == getRecipientEmailAddress(gxsId,detail)) { - setRecipientToRow(row, type, PEER_TYPE_GXS, id.toStdString()); + setRecipientToRow(row, type, PEER_TYPE_GXS, gxsId.toStdString()); return ; } } @@ -2271,7 +2299,8 @@ void MessageComposer::addSmileys() // add trailing space smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) - if(!ui.msgText->textCursor().atStart() && ui.msgText->toPlainText()[ui.msgText->textCursor().position() - 1] != QChar(' ')) + QString plainText = ui.msgText->toPlainText(); + if(!ui.msgText->textCursor().atStart() && plainText[ui.msgText->textCursor().position() - 1] != QChar(' ')) smiley = QString(" ") + smiley; ui.msgText->textCursor().insertText(smiley); } @@ -2308,14 +2337,14 @@ void MessageComposer::fontChanged(const QFont &f) void MessageComposer::colorChanged(const QColor &c) { - QPixmap pix(16, 16); + QPixmap pix(24, 24); pix.fill(c); ui.colorbtn->setIcon(pix); } void MessageComposer::colorChanged2(const QColor &c) { - QPixmap pix(16, 16); + QPixmap pix(24, 24); pix.fill(c); ui.color2btn->setIcon(pix); } @@ -2810,7 +2839,7 @@ void MessageComposer::showTagLabels() tag = tags.types.find(*tagId); if (tag != tags.types.end()) { QLabel *tagLabel = new QLabel(TagDefs::name(tag->first, tag->second.first), this); - tagLabel->setMaximumHeight(16); + tagLabel->setMaximumHeight(QFontMetrics(tagLabel->font()).height()*1.2); tagLabel->setStyleSheet(TagDefs::labelStyleSheet(tag->second.second)); tagLabels.push_back(tagLabel); ui.tagLayout->addWidget(tagLabel); @@ -2820,13 +2849,14 @@ void MessageComposer::showTagLabels() ui.tagLayout->addStretch(); } } -void MessageComposer::on_closeSizeLimitFrameButton_clicked() + +void MessageComposer::on_closeInfoFrameButton_Distant_clicked() { - ui.sizeLimitFrame->setVisible(false); + ui.info_Frame_Distant->setVisible(false); } -void MessageComposer::on_closeInfoFrameButton_clicked() +void MessageComposer::on_closeInfoFrameButton_SizeLimit_clicked() { - ui.distantFrame->setVisible(false); + ui.info_Frame_SizeLimit->setVisible(false); } QString MessageComposer::inviteMessage() diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.h b/retroshare-gui/src/gui/msgs/MessageComposer.h index a5f6d773c..4db4f6ba9 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.h +++ b/retroshare-gui/src/gui/msgs/MessageComposer.h @@ -163,8 +163,8 @@ private slots: void tagSet(int tagId, bool set); void tagRemoveAll(); - void on_closeInfoFrameButton_clicked(); - void on_closeSizeLimitFrameButton_clicked(); + void on_closeInfoFrameButton_Distant_clicked(); + void on_closeInfoFrameButton_SizeLimit_clicked(); static QString inviteMessage(); diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.ui b/retroshare-gui/src/gui/msgs/MessageComposer.ui index ff76237f9..64f8b1332 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.ui +++ b/retroshare-gui/src/gui/msgs/MessageComposer.ui @@ -6,8 +6,8 @@ 0 0 - 1008 - 755 + 1000 + 750 @@ -70,7 +70,7 @@ 0 - + @@ -176,7 +176,7 @@
- + @@ -339,7 +339,7 @@ false - 25 + 30
@@ -350,7 +350,7 @@ Qt::Vertical - + @@ -366,7 +366,7 @@ QFrame::Sunken - + 6 @@ -379,504 +379,485 @@ 6 - - - - 1 + + + + + 150 + 16777215 + - - - - - 16777215 - 16777215 - - - - Qt::ClickFocus - - - - Paragraph - - - - - Heading 1 - - - - - Heading 2 - - - - - Heading 2 - - - - - Heading 3 - - - - - Heading 4 - - - - - Heading 5 - - - - - Heading 6 - - - + + Qt::ClickFocus + + + + Paragraph + - - - - - 100 - 16777215 - - - - Qt::ClickFocus - - + + + Heading 1 + - - - - - 45 - 16777215 - - - - Qt::ClickFocus - - - Font size - - - - 22 - 22 - - - + + + Heading 2 + - - - - - 1677 - 1677 - - - - Qt::NoFocus - - - Increase font size - - - - - - - :/icons/textedit/font-increase.png:/icons/textedit/font-increase.png - - - - 24 - 24 - - - - true - - + + + Heading 2 + - - - - - 167 - 167 - - - - Qt::NoFocus - - - Decrease font size - - - - - - - :/icons/textedit/font-decrease.png:/icons/textedit/font-decrease.png - - - - 24 - 24 - - - - true - - + + + Heading 3 + - - - - - 0 - 0 - - - - - 1677 - 1677 - - - - Qt::NoFocus - - - Bold - - - - - - - :/icons/textedit/bold.png:/icons/textedit/bold.png - - - - 24 - 24 - - - - true - - - true - - + + + Heading 4 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Italic - - - - - - - :/icons/textedit/italic.png:/icons/textedit/italic.png - - - - 24 - 24 - - - - true - - - true - - + + + Heading 5 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Add an Image - - - - - - - :/icons/textedit/photo-of-a-landscape.png:/icons/textedit/photo-of-a-landscape.png - - - - 24 - 24 - - - - true - - + + + Heading 6 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Alignment - - - - - - - :/icons/textedit/align.png:/icons/textedit/align.png - - - - 24 - 24 - - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::NoFocus - - - Sets text font to code style - - - - - - - :/icons/textedit/code.png:/icons/textedit/code.png - - - - 24 - 24 - - - - true - - - - - - - Qt::Horizontal - - - - 20 - 24 - - - - - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Underline - - - - - - - :/icons/textedit/underline.png:/icons/textedit/underline.png - - - - 24 - 24 - - - - true - - - true - - - - - - - Qt::NoFocus - - - - :/icons/textedit/smile.png:/icons/textedit/smile.png - - - - 24 - 24 - - - - true - - - - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Set Text color - - - - - - true - - - - - - - Set Text background color - - - - - - false - - - true - - - - - - - - - - - :/icons/textedit/numberd-list.png:/icons/textedit/numberd-list.png - - - - 24 - 24 - - - - false - - - QToolButton::InstantPopup - - - true - - - - + + + + + + Qt::ClickFocus + + + + + + + + 0 + 0 + + + + Qt::ClickFocus + + + Font size + + + + + + + Qt::NoFocus + + + Set Text color + + + + + + true + + + + + + + Qt::NoFocus + + + Set Text background color + + + + + + false + + + true + + + + + + + + 1677 + 1677 + + + + Qt::NoFocus + + + Increase font size + + + + + + + :/icons/textedit/font-increase.png:/icons/textedit/font-increase.png + + + + 24 + 24 + + + + true + + + + + + + + 167 + 167 + + + + Qt::NoFocus + + + Decrease font size + + + + + + + :/icons/textedit/font-decrease.png:/icons/textedit/font-decrease.png + + + + 24 + 24 + + + + true + + + + + + + + 0 + 0 + + + + + 1677 + 1677 + + + + Qt::NoFocus + + + Bold + + + + + + + :/icons/textedit/bold.png:/icons/textedit/bold.png + + + + 24 + 24 + + + + true + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Underline + + + + + + + :/icons/textedit/underline.png:/icons/textedit/underline.png + + + + 24 + 24 + + + + true + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Italic + + + + + + + :/icons/textedit/italic.png:/icons/textedit/italic.png + + + + 24 + 24 + + + + true + + + true + + + + + + + Qt::NoFocus + + + Sets text font to code style + + + + + + + :/icons/textedit/code.png:/icons/textedit/code.png + + + + 24 + 24 + + + + true + + + + + + + + + + + :/icons/textedit/numberd-list.png:/icons/textedit/numberd-list.png + + + + 24 + 24 + + + + false + + + QToolButton::InstantPopup + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Alignment + + + + + + + :/icons/textedit/align.png:/icons/textedit/align.png + + + + 24 + 24 + + + + QToolButton::InstantPopup + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Add an Image + + + + + + + :/icons/textedit/photo-of-a-landscape.png:/icons/textedit/photo-of-a-landscape.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + + :/icons/textedit/smile.png:/icons/textedit/smile.png + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 20 + 24 + + +
- + + + + + 0 + 0 + 0 + + + @@ -897,6 +878,15 @@ + + + + 0 + 0 + 0 + + + @@ -917,6 +907,15 @@ + + + + 154 + 154 + 154 + + + @@ -947,7 +946,7 @@ QFrame::Box - + 6 @@ -961,7 +960,7 @@ 6 - + 16 @@ -980,7 +979,7 @@ - + Distant messages stay into your Outbox until an acknowledgement of receipt has been received. @@ -990,7 +989,7 @@ - + 16 @@ -1027,10 +1026,19 @@ border-image: url(:/images/closepressed.png) - + + + + + 0 + 0 + 0 + + + @@ -1051,6 +1059,15 @@ border-image: url(:/images/closepressed.png) + + + + 0 + 0 + 0 + + + @@ -1071,6 +1088,15 @@ border-image: url(:/images/closepressed.png) + + + + 154 + 154 + 154 + + + @@ -1101,7 +1127,7 @@ border-image: url(:/images/closepressed.png) QFrame::Box - + 6 @@ -1115,7 +1141,7 @@ border-image: url(:/images/closepressed.png) 6 - + 16 @@ -1134,7 +1160,7 @@ border-image: url(:/images/closepressed.png) - + Sending messages to more than 20 people at once is not recommended. If you need to send invites, dedicated forums is what you need. @@ -1144,7 +1170,7 @@ border-image: url(:/images/closepressed.png) - + 16 @@ -1284,8 +1310,8 @@ border-image: url(:/images/closepressed.png) 0 0 - 1008 - 25 + 1176 + 20 @@ -1386,27 +1412,32 @@ border-image: url(:/images/closepressed.png) + + FriendSelectionWidget + QWidget +
gui/common/FriendSelectionWidget.h
+ 1 +
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
MimeTextEdit QTextEdit
gui/common/MimeTextEdit.h
- FriendSelectionWidget - QWidget -
gui/common/FriendSelectionWidget.h
- 1 -
- - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 + RSComboBox + QComboBox +
gui/common/RSComboBox.h
@@ -1421,8 +1452,8 @@ border-image: url(:/images/closepressed.png) hashBox - + diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.cpp b/retroshare-gui/src/gui/msgs/MessageWidget.cpp index 9b671129f..e614eeca0 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWidget.cpp @@ -65,7 +65,7 @@ class RsHtmlMsg : public RsHtml { public: - RsHtmlMsg(uint msgFlags) : RsHtml() + explicit RsHtmlMsg(uint msgFlags) : RsHtml() { this->msgFlags = msgFlags; } @@ -192,13 +192,13 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f QFont font = QFont("Arial", 10, QFont::Bold); ui.subjectText->setFont(font); - ui.toText->setMaximumHeight(ui.toText->fontMetrics().lineSpacing()*1.5); + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*1.5); ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->setMaximumHeight(ui.ccText->fontMetrics().lineSpacing()*1.5); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->setMaximumHeight(ui.trans_CCText->fontMetrics().lineSpacing()*1.5); ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->setMaximumHeight(ui.bccText->fontMetrics().lineSpacing()*1.5); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->setMaximumHeight(ui.trans_BCCText->fontMetrics().lineSpacing()*1.5); ui.tagsLabel->setVisible(false); @@ -210,7 +210,7 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f ui.dateText-> setText(""); - ui.inviteFrame->hide(); + ui.info_Frame_Invite->hide(); } MessageWidget::~MessageWidget() @@ -355,18 +355,18 @@ void MessageWidget::getcurrentrecommended() std::map files ; - for (QModelIndexList::const_iterator it(list.begin());it!=list.end();++it) { - FileInfo& fi(files[it->row()]) ; + for (auto &it : list) { + FileInfo& fi(files[it.row()]) ; - switch (it->column()) { + switch (it.column()) { case COLUMN_FILE_NAME: - fi.fname = it->data().toString().toUtf8().constData(); + fi.fname = it.data().toString().toUtf8().constData(); break ; case COLUMN_FILE_SIZE: - fi.size = it->data(Qt::UserRole).toULongLong() ; + fi.size = it.data(Qt::UserRole).toULongLong() ; break ; case COLUMN_FILE_HASH: - fi.hash = RsFileHash(it->data().toString().toStdString()) ; + fi.hash = RsFileHash(it.data().toString().toStdString()) ; break ; } } @@ -491,17 +491,17 @@ void MessageWidget::fill(const std::string &msgId) if (currMsgId.empty()) { /* blank it */ ui.dateText-> setText(""); - ui.toText->setText(""); + ui.trans_ToText->setText(""); ui.fromText->setText(""); ui.filesText->setText(""); ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->clear(); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->clear(); ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->clear(); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->clear(); ui.subjectText->setText(""); ui.msgList->clear(); @@ -511,7 +511,7 @@ void MessageWidget::fill(const std::string &msgId) clearTagLabels(); checkLength(); - ui.inviteFrame->hide(); + ui.info_Frame_Invite->hide(); ui.expandFilesButton->setChecked(false); ui.downloadButton->setEnabled(false); togglefileview(true); @@ -543,15 +543,15 @@ void MessageWidget::fill(const std::string &msgId) } if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && msgInfo.rsgxsid_srcId.isNull()){ - ui.inviteFrame->show(); + ui.info_Frame_Invite->show(); ui.sendInviteButton->hide(); - ui.infoLabel->setText(tr("You got an invite to make friend! You may accept this request.")); + ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request.")); } else if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && (!msgInfo.rsgxsid_srcId.isNull())){ - ui.inviteFrame->show(); + ui.info_Frame_Invite->show(); ui.sendInviteButton->show(); - ui.infoLabel->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back")); + ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back")); } else { - ui.inviteFrame->hide(); + ui.info_Frame_Invite->hide(); } const std::list &recList = msgInfo.files; @@ -594,12 +594,12 @@ void MessageWidget::fill(const std::string &msgId) text += link.toHtml() + " "; } - ui.toText->setText(text); + ui.trans_ToText->setText(text); - if (!msgInfo.rspeerid_msgcc.empty() || !msgInfo.rsgxsid_msgcc.empty()) - { + if (!msgInfo.rspeerid_msgcc.empty() || !msgInfo.rsgxsid_msgcc.empty()) + { ui.ccLabel->setVisible(true); - ui.ccText->setVisible(true); + ui.trans_CCText->setVisible(true); text.clear(); for(std::set::const_iterator pit = msgInfo.rspeerid_msgcc.begin(); pit != msgInfo.rspeerid_msgcc.end(); ++pit) { @@ -613,17 +613,17 @@ void MessageWidget::fill(const std::string &msgId) text += link.toHtml() + " "; } - ui.ccText->setText(text); + ui.trans_CCText->setText(text); } else { ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->clear(); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->clear(); } if (!msgInfo.rspeerid_msgbcc.empty() || !msgInfo.rsgxsid_msgbcc.empty()) { ui.bccLabel->setVisible(true); - ui.bccText->setVisible(true); + ui.trans_BCCText->setVisible(true); text.clear(); for(std::set::const_iterator pit = msgInfo.rspeerid_msgbcc.begin(); pit != msgInfo.rspeerid_msgbcc.end(); ++pit) { @@ -637,11 +637,11 @@ void MessageWidget::fill(const std::string &msgId) text += link.toHtml() + " "; } - ui.bccText->setText(text); + ui.trans_BCCText->setText(text); } else { ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->clear(); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->clear(); } ui.dateText->setText(DateTime::formatDateTime(msgInfo.ts)); @@ -916,4 +916,4 @@ void MessageWidget::checkLength() text = tr("%1 (%2) ").arg(charlength).arg(misc::friendlyUnit(charlength)); ui.sizeLabel->setText(text); -} \ No newline at end of file +} diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.ui b/retroshare-gui/src/gui/msgs/MessageWidget.ui index c781dc5d1..6f544a01b 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.ui +++ b/retroshare-gui/src/gui/msgs/MessageWidget.ui @@ -347,7 +347,7 @@
- + 0 @@ -366,7 +366,7 @@ - + 0 @@ -385,7 +385,7 @@ - + 0 @@ -461,10 +461,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -485,6 +494,15 @@ + + + + 0 + 0 + 0 + + + @@ -505,6 +523,15 @@ + + + + 154 + 154 + 154 + + + @@ -535,7 +562,7 @@ QFrame::Box - + 6 @@ -549,7 +576,7 @@ 6 - + 16 @@ -568,7 +595,7 @@ - + You got an invite to make friend! You may accept this request and send your own Certificate back diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index fab811ee7..497c7a06d 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -152,7 +152,7 @@ private: RsMessageModel *mMessageModel; MessageSortFilterProxyModel *mMessageProxyModel; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorInbox; /** Qt Designer generated object */ diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.ui b/retroshare-gui/src/gui/msgs/MessagesDialog.ui index 183396a2c..e0bf5c9a0 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.ui +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.ui @@ -10,7 +10,7 @@ 485 - + 0 @@ -36,7 +36,7 @@ Messages - + 0 @@ -55,7 +55,7 @@ Qt::Horizontal - + 0 @@ -72,11 +72,11 @@ 0 - + true - + 3 @@ -139,6 +139,11 @@ 0 + + + 11 + + Qt::CustomContextMenu @@ -188,23 +193,17 @@ - - + + 0 - + true - - QFrame::StyledPanel - - - QFrame::Raised - - + 3 @@ -254,6 +253,11 @@ 0 + + + 11 + + @@ -275,13 +279,13 @@
- - + + 0 - + 3 @@ -321,7 +325,7 @@
- + Qt::Horizontal @@ -352,7 +356,7 @@ Qt::NoFocus - + :/icons/help_64.png:/icons/help_64.png @@ -476,8 +480,8 @@ listWidget
- + diff --git a/retroshare-gui/src/gui/profile/ProfileManager.ui b/retroshare-gui/src/gui/profile/ProfileManager.ui index 9ec918e89..a2ffe541b 100644 --- a/retroshare-gui/src/gui/profile/ProfileManager.ui +++ b/retroshare-gui/src/gui/profile/ProfileManager.ui @@ -23,27 +23,36 @@ Profile Manager - + :/images/logo/logo_16.png:/images/logo/logo_16.png - - + + + 0 + + + 0 + + + 0 + + 0 0 - + 0 30 - + - + @@ -54,12 +63,12 @@ <!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:'Ubuntu'; font-size:11pt; 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;">Select a Retroshare node key from the list below to be used on another computer, and press &quot;Export selected key.&quot;</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">To create a new location on a different computer, select the identity manager in the login window. From there you can import the key file and create a new location for that key. </p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Creating a new node with the same key allows your friend nodes to accept you automatically.</p></body></html> +</style></head><body style=" font-family:'Sans Serif'; 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:'Ubuntu'; font-size:11pt;">Select a Retroshare node key from the list below to be used on another computer, and press &quot;Export selected key.&quot;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p> +<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:'Ubuntu'; font-size:11pt;">To create a new location on a different computer, select the identity manager in the login window. From there you can import the key file and create a new location for that key. </span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p> +<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:'Ubuntu'; font-size:11pt;">Creating a new node with the same key allows your friend nodes to accept you automatically.</span></p></body></html> @@ -71,11 +80,11 @@ p, li { white-space: pre-wrap; } - + Full keys available in your keyring: - + diff --git a/retroshare-gui/src/gui/profile/ProfileWidget.cpp b/retroshare-gui/src/gui/profile/ProfileWidget.cpp index b6418ae56..cf823ab53 100644 --- a/retroshare-gui/src/gui/profile/ProfileWidget.cpp +++ b/retroshare-gui/src/gui/profile/ProfileWidget.cpp @@ -45,7 +45,7 @@ ProfileWidget::ProfileWidget(QWidget *parent, Qt::WindowFlags flags) connect(ui.CopyCertButton,SIGNAL(clicked()), this, SLOT(copyCert())); connect(ui.profile_Button,SIGNAL(clicked()), this, SLOT(profilemanager())); - ui.onlinesince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); + ui.onLineSince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); } void ProfileWidget::showEvent ( QShowEvent * /*event*/ ) @@ -59,7 +59,7 @@ void ProfileWidget::showEvent ( QShowEvent * /*event*/ ) ui.name->setText(QString::fromUtf8(detail.name.c_str())); ui.country->setText(QString::fromUtf8(detail.location.c_str())); - ui.peerid->setText(QString::fromStdString(detail.id.toStdString())); + ui.peerId->setText(QString::fromStdString(detail.id.toStdString())); ui.ipAddressList->clear(); for(std::list::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) diff --git a/retroshare-gui/src/gui/profile/ProfileWidget.ui b/retroshare-gui/src/gui/profile/ProfileWidget.ui index 4462acad5..2bd1fae73 100644 --- a/retroshare-gui/src/gui/profile/ProfileWidget.ui +++ b/retroshare-gui/src/gui/profile/ProfileWidget.ui @@ -16,17 +16,35 @@ 0 - - + + 0 - + + 0 + + + 0 + + + 0 + + 0 - - + + + 2 + + + 2 + + + 2 + + 2 @@ -41,7 +59,7 @@ Edit status message - + :/images/edit_16.png:/images/edit_16.png @@ -61,7 +79,7 @@ Copy Certificate - + :/images/view-certificate-copy-32.png:/images/view-certificate-copy-32.png @@ -81,7 +99,7 @@ Profile Manager - + :/images/contact_new.png:/images/contact_new.png @@ -99,7 +117,7 @@ - + Qt::Horizontal @@ -128,18 +146,18 @@ 569 - + - + QFrame::Box QFrame::Sunken - + - + @@ -154,9 +172,10 @@ - + + 12 75 true @@ -169,7 +188,7 @@ - + 0 @@ -207,7 +226,7 @@ - + 0 @@ -245,7 +264,7 @@ - + 0 @@ -264,7 +283,7 @@ - + 0 @@ -286,16 +305,16 @@ - + QFrame::Box QFrame::Sunken - + - + 0 @@ -333,7 +352,7 @@ - + 0 @@ -352,7 +371,7 @@ - + 0 @@ -390,7 +409,7 @@ - + 0 @@ -409,7 +428,7 @@ - + @@ -427,9 +446,10 @@ - + + 12 75 true @@ -445,16 +465,16 @@ - + QFrame::Box QFrame::Sunken - + - + @@ -472,9 +492,10 @@ - + + 12 75 true @@ -487,7 +508,7 @@ - + 0 @@ -547,7 +568,7 @@ - + 0 @@ -566,7 +587,7 @@ - + Qt::Horizontal @@ -620,7 +641,7 @@ - + Qt::Horizontal @@ -633,7 +654,7 @@ - + Qt::Horizontal @@ -646,7 +667,7 @@ - + 0 @@ -675,7 +696,7 @@ - + 100 @@ -722,13 +743,6 @@ - - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
diff --git a/retroshare-gui/src/gui/profile/StatusMessage.ui b/retroshare-gui/src/gui/profile/StatusMessage.ui index 0f537c280..c5a29369f 100644 --- a/retroshare-gui/src/gui/profile/StatusMessage.ui +++ b/retroshare-gui/src/gui/profile/StatusMessage.ui @@ -35,7 +35,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png
- + 9 @@ -44,12 +44,7 @@ 113 - - QFrame#frame{background: white; -border: 1px solid #CCCCCC;} - - - + 91 @@ -73,7 +68,7 @@ border: 1px solid #CCCCCC;} - + 100 @@ -90,7 +85,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600;">Status message</span></p></body></html> - + 100 @@ -107,7 +102,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">Enter your message</span></p></body></html> - + 20 @@ -129,7 +124,7 @@ p, li { white-space: pre-wrap; } :/images/user/personal64.png - + 0 @@ -138,14 +133,6 @@ p, li { white-space: pre-wrap; } 241 - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, -stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - QFrame::StyledPanel @@ -166,11 +153,11 @@ border: 1px solid #CCCCCC;} - frame_2 - frame - label_3 - label_2 - label + gradFrame + plainBFrame + statusLabel + enterMsgLabel + iconLabel diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss deleted file mode 100644 index 442055f3b..000000000 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ /dev/null @@ -1,1231 +0,0 @@ -/* Standard stylesheet for RetroShare */ - -/* Standard rules */ - -QFrame#toolBarFrame, QFrame#toolBarFrameTop { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -/* HeaderFrame */ - -HeaderFrame > QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -HeaderFrame > QFrame#frame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} - -AvatarDialog QFrame#infoframe -{ - 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); -} - -/* GenCertDialog */ - -GenCertDialog QLabel#genprofileinfo_label, QLabel#header_label, QLabel#entropy_label -{ - 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); -} - -GenCertDialog QLabel#label_hiddenaddr { - border: 1px solid #50FF5B; - border-radius: 6px; - background: #CCFFCC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA); -} -GenCertDialog QLabel#no_node_label, GenCertDialog QLabel#no_gpg_key_label { - border: 1px solid #FFC550; - border-radius: 6px; - background: #FFEECC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFEECC, stop:1 #FFE3AB); - padding: 4px; - font-size: 14pt; -} - -GenCertDialog > QFrame#headerFrame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} - -GenCertDialog > QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -/* ConnectFriendWizard */ - -ConnectFriendWizard { -/* QWizard cannot be resized horizontal when banner pixmap is set - qproperty-bannerPixmap: url(:/images/connect/connectFriendBanner1.png);*/ - qproperty-titleFontSize: 16; - qproperty-titleFontWeight: 500; -/* qproperty-titleColor: white; */ -} - -/* FriendsDialog */ - -FriendsDialog QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -FriendsDialog QFrame#headFrame > QLabel#nicknameLabel { - color: rgb(255, 255, 255); -} - -FriendsDialog QTextEdit#msgText, FriendsDialog QTextEdit#lineEdit { - border: 1px solid #CCCCCC; -} - -/* Channels */ - -ChannelFeed QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F2F2F2, stop:1 #E6E6E6); - border: 1px solid #CCCCCC; -} - -ChannelFeed QLabel#logoLabel, EditChanDetails QLabel#logoLabel, CreateChannel QLabel#logoLabel { - border: 2px solid white; -} - -CreateChannelMsg QFrame#fileFrame { - border: 2px solid black; - background: white; -} - -GxsCreateCommentDialog QTextEdit#commentTextEdit { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; -} - -GxsCreateCommentDialog QLabel#titleLabel { - font-size: 12pt; - font-weight: 600; - color: black; -} - -GxsCreateCommentDialog QLabel#replaytolabel { - font-weight: bold; - color: gray; -} - -GxsCreateCommentDialog QFrame#frame { - background: white; -} - -CreateGxsChannelMsg QPushButton#postButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -CreateGxsChannelMsg QPushButton#postButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -CreateCircleDialog QPushButton#createButton, CreateLobbyDialog QPushButton#createButton, -IdEditDialog QPushButton#createButton, CreateGxsForumMsg QPushButton#postButton, -GxsCreateCommentDialog QPushButton#postButton, GxsGroupDialog QPushButton#createButton, -PulseAddDialog QPushButton#pushButton_Post, PulseTopLevel QToolButton#toolButton_follow, -PulseViewGroup QToolButton#toolButton_follow, WikiEditDialog QPushButton#pushButton_Submit{ - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -CreateCircleDialog QPushButton#createButton:hover, CreateLobbyDialog QPushButton#createButton:hover, -IdEditDialog QPushButton#createButton:hover, CreateGxsForumMsg QPushButton#postButton:hover, -GxsCreateCommentDialog QPushButton#postButton:hover, GxsGroupDialog QPushButton#createButton:hover, -ShareManager QPushButton#closeButton:hover, PulseAddDialog QPushButton#pushButton_Post:hover, -PulseTopLevel QToolButton#toolButton_follow:hover, PulseViewGroup QToolButton#toolButton_follow:hover, -WikiEditDialog QPushButton#pushButton_Submit:hover{ - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#closeButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#addButton{ - font: bold; - font-size: 12pt; - color: white; - background: #32CD32; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 4px; -} - -ShareManager QPushButton#addButton:hover{ - background: #5AD75A; - border-radius: 4px; - min-width: 4em; - padding: 4px; -} - -SearchDialog QPushButton#pushButtonSearch { - font: bold; - font-size: 12pt; - color: white; - background: #32CD32; - border-radius: 4px; - max-height: 25px; - min-width: 4em; - padding: 4px; -} - -SearchDialog QPushButton#pushButtonSearch:hover{ - background: #5AD75A; - border-radius: 4px; - min-width: 4em; - padding: 4px; -} - -CreateGxsForumMsg QPushButton#postButton:disabled, PostedCreatePostDialog QPushButton#submitButton:disabled, -CreateGxsChannelMsg QPushButton#postButton:disabled, GxsCreateCommentDialog QPushButton#postButton:disabled, -PulseAddDialog QPushButton#pushButton_Post:disabled, WikiEditDialog QPushButton#pushButton_Submit:disabled { - font: bold; - font-size: 12pt; - color: white; - background: #d40000; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding-left: 6px; - padding-right: 6px; -} - -/* Forums */ - -GxsForumThreadWidget QPushButton#forumName -{ - font: bold; - font-size: 12pt; -} - -CreateForumMsg > QToolBar#toolBar, CreateForumV2Msg > QToolBar#toolBar { - background-image: url(:/images/headerFrame.png); -} - -/* MessengerWindow */ - -MessengerWindow QFrame#logoFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -MessengerWindow QFrame#messengerframetop{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -/* Create Distant Chat Invite */ - -CreateMsgLinkDialog QLabel#distantchatinfo_label -{ - 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); -} - -/* Chat lobby */ - -ChatLobbyWidget QLabel#lobbyinfo_label -{ - 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); -} - -ChatLobbyWidget QLabel#lobbyname_lineEdit -{ - font: bold; - font-size: 16pt; -} - -ChatLobbyWidget QGroupBox#lobbyinfo_groupBox -{ - - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - border-radius: 6px; - border: 1px solid #CCCCCC; - - padding: 14 6px; - font-size: 12pt; - font-weight: bold; - -} - -ChatLobbyWidget QGroupBox::title#lobbyinfo_groupBox -{ - padding: 4 12px; - background: #039bd5; - color: white; -} - -ChatLobbyWidget QLabel#lobbyInfoLabel { - 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); -} - - -ChatLobbyDialog QFrame#participantsFrame { - border: transparent; -} - -ChatLobbyDialog QListWidget#participantsList { - border: 1px solid #B8B6B1; - border-radius: 6px; - background: white; -} - -CreateLobbyDialog QFrame#roomFrame { - border: 2px solid #CCCCCC; - border-radius:6px; - background: white; -} - -CreateLobbyDialog QLabel#lobbyInfoLabel { - 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); -} - -ChatWidget QTextEdit#chatTextEdit, ChatWidget QTextBrowser#textBrowser { - border: 1px solid #0099cc; - border-radius: 6px; - background: white; -} - -ChatWidget QFrame#infoFrame { - 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); -} - -ChatWidget QFrame#titleBarFrame, QFrame#toolBarFrameTop { - -} - -PopupChatWindow QToolBar#chattoolBar{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -/* Messages */ - -MessageComposer QToolBar#toolBar { - -} - -MessagesDialog QFrame#folderFrame, MessagesDialog QFrame#quickViewFrame { - background: transparent; - -} - -/* Profile */ - -ProfileWidget QFrame#frame_1, ProfileWidget QFrame#frame_2, ProfileWidget QFrame#frame_3 { - background-color: white; - border: 2px solid #CCCCCC; -} - -/* Settings */ - -PluginItem > QFrame#frame { - border: 2px solid #A8B8D1; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FCFDFE, stop: 1 #E2E8EF); - border-radius: 0px -} - -/* Network */ - -/*NetworkView > QGraphWidget#graphicsView -{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 lightgray, stop:1 darkgray); -} -*/ - -/* GetStartedDialog */ - -GetStartedDialog QTextEdit { - border: 1px solid #B8B6B1; - border-radius: 6px; - background: white; -} - -/* GenCertDialog */ - -/* GenCertDialog > QFrame#headerFrame { - background-image: url(:/images/genbackground.png); -} - -GenCertDialog > QFrame#headerFrame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} -*/ - -/* ConnectFriendWizard */ - -ConnectFriendWizard QWizardPage#ConclusionPage > QGroupBox#peerDetailsFrame { - border: 2px solid #039bd5; - border-radius:6px; - background: white; - padding: 12 12px; -} - -ConnectFriendWizard QLabel#fr_label, QLabel#requestinfolabel, QLabel#cp_Label -{ - 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); -} - -ConnectFriendWizard QGroupBox::title#peerDetailsFrame -{ - padding: 4 12px; - background: transparent; - padding: 4 12px; - background: #039bd5; - color: white; -} - -/* Toaster */ - -ChatToaster > QFrame#windowFrame, -ChatLobbyToaster > QFrame#windowFrame, -DownloadToaster > QFrame#windowFrame, -FriendRequestToaster > QFrame#windowFrame, -GroupChatToaster > QFrame#windowFrame, -MessageToaster >QFrame#windowFrame, -OnlineToaster > QFrame#windowFrame { - background-image: url(:/images/toaster/backgroundtoaster.png); -} - -/* Feeds */ - -AttachFileItem > QFrame#frame { - border: 2px solid black; - background: white; -} - -ChanNewItem > QFrame#frame { - border: 2px solid #D3D3D3; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFFF, stop:1 #F2F2F2); - border-radius: 10px; -} - -ChanNewItem QLabel#logoLabel { - border: 2px solid #D3D3D3; - border-radius: 2px; -} - -GxsChannelPostItem > QFrame#mainFrame[new=false] { - background-color: white; -} - -GxsChannelPostItem > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -GxsChannelPostItem QLabel#newLabel{ - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; - color: white; -} - -GxsChannelPostItem QLabel#subjectLabel, GxsChannelPostItem QLabel#titleLabel { - font: 11pt; - font: bold italic; -} - -GxsChannelPostItem QFrame#msgFrame { - border: 2px solid #82B9F4; - border-radius: 3px; -} - -GxsChannelPostItem QLabel#logoLabel { - border: 2px solid #D3D3D3; -} - -GxsChannelPostItem QLabel#logoLabel { - background-color: black; -} - -GxsCircleItem QFrame#mainFrame { - background-color: white; -} - -GxsCircleItem QLabel#gxsIdLabel, QLabel#nameLabel, QLabel#titleLabel { - font: 11pt; - font: bold italic; -} - - -ForumNewItem > QFrame#frame, ForumMsgItem > QFrame#frame { - border: 2px solid #CCCCCC; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC); - border-radius: 10px; -} - -ForumNewItem > QLabel#nextNameLabel, ForumMsgItem > QLabel#nameLabel { - color: rgb(59, 89, 152); -} - -ForumMsgItem QLabel#iconLabel { - border: 2px solid #CCCCCC; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC); - border-radius: 10px -} - -ForumMsgItem QFrame#prevFrame { - border: 2px solid black; - border-radius: 10px; -} - -SubFileItem QProgressBar#progressBar { - border: 1px solid black; - text-align: center; - color: white; - padding: 1px; - border-top-left-radius: 7px; - border-bottom-left-radius: 7px; - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fff, stop: 0.4999 #eee, stop: 0.5 #ddd, stop: 1 #eee); - min-width: 15px; -} - -SubFileItem QProgressBar#progressBar::chunk { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #78d, stop: 0.4999 #46a, stop: 0.5 #45a, stop: 1 #238); - border-top-left-radius: 7px; - border-bottom-left-radius: 7px; - border: 1px solid black; - min-width: 15px; -} - -PluginItem QLabel#infoLabel { - - color: #054A02; - font: bold; - -} - -ConfCertDialog QPlainTextEdit#plainTextEdit { - 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#plainTextEdit { - 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#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 { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px solid #CCCCCC; -} - -ProfileManager QTextEdit#textEdit -{ - 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); -} - -/* RSImageBlockWidget */ - -RSImageBlockWidget QFrame#infoFrame { - 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); -} - -/* ShareManager */ - -ShareManager QLabel#labelInstructions { - 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); -} - -/* MessageWidget */ - -MessageWidget QFrame#decryptFrame { - border: 1px solid #50FF5B; - border-radius: 6px; - background: #CCFFCC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA); -} - -MessageWidget QFrame#inviteFrame { - 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); -} - -/* Posted Links */ - -PostedCreatePostDialog QLabel#info_label { - 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); -} - -QLabel#sharekeyinfo_label{ - 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); -} - -QLabel#subscribersLabel{ - border: 1px solid #CCCCCC; - border-radius: 6px; - -} - -QFrame#distantFrame{ - 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); -} - -QLabel#avatarLabel{ - border: 2px solid #CCCCCC; - border-radius: 4px; -} - -IdDialog QFrame#headerFramePerson { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -IdDialog QFrame#headerFrameCircle { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -IdDialog QLabel#headerTextLabel { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#headerTextLabel_Person { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#headerTextLabel_Circles { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#avlabel { - border: 4px solid white; - border-radius: 10px; -} - -IdDialog QFrame#inviteFrame { - 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); -} - -IdEditDialog QLabel#info_label -{ - 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); -} - -GenCertDialog QComboBox#genPGPuser { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QSpinBox#hiddenport_spinBox { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#hiddenaddr_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#password2_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#password_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#nickname_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#node_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#name_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QPushButton#genButton { - border-image: url(:/images/btn_blue.png) 4; - border-width: 4; - font: bold; - color: white; -} - -GenCertDialog QPushButton#genButton:hover { - border-image: url(:/images/btn_blue_hover.png) 4; -} - -GenCertDialog QPushButton#genButton:disabled { - border-image: url(:/images/btn_27.png) 4; -/* font-size: 16pt; */ - font: bold; - color: black; -} - -ConnectFriendWizard QRadioButton { - font-size: 16pt; -} - -ConnectFriendWizard QPlainTextEdit#friendCertEdit { - border: none; - background: white; -} - -ConnectFriendWizard QFrame#friendFrame { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; -} - -StartDialog QPushButton#loadButton { - border-image: url(:/images/btn_blue.png) 4; - border-width: 4; - font: bold; - color: white; -} - -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{ - border-image: url(:/images/logo/background.png) 0 0 0 0 stretch stretch; - border-width: 0px; -} - -PostedListWidgetWithModel QComboBox#sortStrategy_CB { - font: bold; - color: #0099cc; -} - -PostedListWidgetWithModel QToolButton#submitPostButton, GxsChannelPostsWidgetWithModel QToolButton#postButton, -GxsForumThreadWidget QToolButton#newthreadButton { - font: bold; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -PostedListWidgetWithModel QFrame#headerFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsForumMsgItem QFrame#mainFrame, PeerItem QFrame#mainFrame, GxsForumGroupItem QFrame#mainFrame, -GxsChannelGroupItem QFrame#mainFrame, MsgItem QFrame#mainFrame, ChatMsgItem QFrame#mainFrame -SecurityIpItem QFrame#mainFrame, MsgItem QFrame#msgFrame, SecurityItem QFrame#mainFrame{ - background-color: white; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed { - background: #03b1f3; - border-radius: 4px; - border: 1px solid gray; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled { - background: gray; - border-radius: 4px; - border: 1px solid gray; - color: lightgray; -} - -/* only for MenuButtonPopup */ - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"], -PostedListWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"]{ - padding-right: 0px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow, -PostedListWidgetWithModel QToolButton#subscribeToolButton::menu-arrow{ - image: none; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button, -PostedListWidgetWithModel QToolButton#subscribeToolButton::menu-button{ - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { - padding-right: 0px; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { - padding-right: 0px; -} - -GxsGroupDialog QLabel#groupLogo{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -GxsChannelGroupItem QFrame#frame, GxsForumGroupItem QFrame#frame, -PostedGroupItem QFrame#frame { - background-color: white; -} - -HomePage QLabel#userCertLabel { - color: #0099cc; - font: bold; -} - -HomePage QPlainTextEdit#userCertEdit { - - background: transparent; -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - - -PostedItem QFrame#mainFrame { - background-color: white; -} - -PostedItem > QFrame#mainFrame [new=false]{ - background: white; -} - -PostedItem QFrame#voteFrame { - background: #f8f9fa; -} - -BoardPostDisplayWidget_compact QFrame#mainFrame { - background-color: white; -} - -BoardPostDisplayWidget_compact > QFrame#mainFrame [new=false]{ - background: white; -} - -BoardPostDisplayWidget_compact > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -BoardPostDisplayWidget_compact QLabel#pictureLabel{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -BoardPostDisplayWidget_compact QLabel#fromBoldLabel , -BoardPostDisplayWidget_card QLabel#fromBoldLabel { - font: bold; -} - -BoardPostDisplayWidget_compact QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel , -BoardPostDisplayWidget_card QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel{ - color: #787c7e; -} - -BoardPostDisplayWidget_compact QLabel#newLabel { - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; -} - -BoardPostDisplayWidget_card QLabel#newLabel { - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; -} - -PostedCardView QFrame#voteFrame { - background: #f8f9fa; -} - -BoardPostDisplayWidget_card QFrame#mainFrame{ - background: white; -} - -BoardPostDisplayWidget_card > QFrame#mainFrame [new=false]{ - background: white; -} - -BoardPostDisplayWidget_card > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -BoardPostDisplayWidget_compact QLabel#titleLabel, -BoardPostDisplayWidget_card QLabel#titleLabel{ - font-size: 12pt; - font: bold; -} - -GxsCommentDialog QComboBox#sortBox { - font: bold; - color: #0099cc; -} - -PostedListWidgetWithModel QTextBrowser#infoDescription { - background: transparent; - border: none; -} - -PostedCreatePostDialog QPushButton#submitButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -PostedCreatePostDialog QPushButton#submitButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MessageWidget QTextBrowser#toText , QTextBrowser#ccText , QTextBrowser#bccText { - background: transparent; - border: none; -} - -WireGroupItem QWidget:hover{ - background-color: #7ecbfb; -} - -WireDialog QFrame#frame{ - background-color: white; -} - -WireDialog QWidget#scrollAreaWidgetContents_groups{ - background-color: white; -} - -MessagesDialog QWidget#messageTreeWidget::item { - padding: 2px; -} - -MessagesDialog QWidget#messageTreeWidget::item:selected { - background-color: #cde8ff; - color: black; -} - -MessagesDialog QWidget#messageTreeWidget::item:hover { - background-color: #e5f3ff; - color: black; -} - -GxsForumThreadWidget QWidget#threadTreeWidget { - selection-background-color: #cde8ff; - show-decoration-selected: 1; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item { - padding: 2px; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { - background-color: #cde8ff; -} - -GxsChannelDialog GroupTreeWidget QTreeWidget#treeWidget::item{ - /*background-color: #F00000;*/ - /*padding: 2px*/ -} - -MainWindow QListWidget { - font-size: 12pt; -} - -PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame { - border: 2px solid #c4cfd6; - background: white; -} - -PulseAddDialog QTextEdit#textEdit_Pulse { - border: 2px solid #c4cfd6; - border-radius: 6px; - background: white; -} - -PulseAddDialog QFrame#frame_input, QFrame#frame_reply, QFrame#frame { - border: 0px; -} - -PulseAddDialog QLabel#label_groupName { - font-size: 12pt; -} - -PulseReply #line_replyLine , PulseMessage #line{ - color: #c4cfd6; -} - -PulseReply QLabel#label_groupName{ - color: #5b7083; -} - -WireDialog QLabel#label_viewMode { - font-size: 12pt; -} - -WireGroupDialog QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -PhotoShare QPushButton#pushButton_YourAlbums, QPushButton#pushButton_SubscribedAlbums, -QPushButton#pushButton_SharedAlbums { - font-size: 12pt; -} - -AlbumItem QFrame#albumFrame { - border: 2px solid #CCCCCC; - border-radius: 10px -} - -PhotoItem QFrame#photoFrame { - border: 2px solid #CCCCCC; - border-radius: 10px -} - -PhotoItem QWidget:hover { - background-color: #7ecbfb; -} - -PhotoSlideShow QLabel#albumLabel { - font-size: 12pt; -} - -ChannelsCommentsItem QFrame#mainFrame, BoardsCommentsItem QFrame#mainFrame { - background-color: white; -} - -ChannelsCommentsItem QLabel#newCommentLabel, BoardsCommentsItem QLabel#newCommentLabel { - font-size: 12pt; - font: bold; -} - -ChannelsCommentsItem QLabel#subjectLabel, ChannelsCommentsItem QLabel#titleLabel , QLabel#nameLabel { - font-size: 12pt; - font: bold; -} - -BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel { - font-size: 12pt; - font: bold; -} - -NewFriendList QTreeView#peerTreeWidget::item:selected, QTreeView#peerTreeWidget::branch:selected:active { - background: #cde8ff; -} - -NewFriendList QTreeView#peerTreeWidget { - font-size: 12pt; -} - -WikiEditDialog QPushButton#pushButton_History { - font: bold; - font-size: 15px; - color: white; - background: #5bb62b; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -WikiEditDialog QPushButton#pushButton_History:hover { - background: #57af29; -} diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss new file mode 100644 index 000000000..f2097d0be --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss @@ -0,0 +1,2545 @@ + /* Standard Dark stylesheet for RetroShare + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + + It use a public one for general widgets https://github.com/ColinDuquesnoy/QDarkStyleSheet + /qdarkstyle/dark/style.qss + Updated at 2021-11-04 Tag v3.0.2 + Replace all ":/qss_icons/dark" by ":/standard_dark" + */ + +/* --------------------------------------------------------------------------- + + WARNING! File created programmatically. All changes made in this file will be lost! + + Created by the qtsass compiler v0.3.0 + + The definitions are in the "qdarkstyle.qss._styles.scss" module + +--------------------------------------------------------------------------- */ +/* Light Style - QDarkStyleSheet ------------------------------------------ */ +/* + +See Qt documentation: + + - https://doc.qt.io/qt-5/stylesheet.html + - https://doc.qt.io/qt-5/stylesheet-reference.html + - https://doc.qt.io/qt-5/stylesheet-examples.html + +--------------------------------------------------------------------------- */ +/* Reset elements ------------------------------------------------------------ + +Resetting everything helps to unify styles across different operating systems + +--------------------------------------------------------------------------- */ +* { + padding: 0px; + margin: 0px; + border: 0px; + border-style: none; + border-image: none; + outline: 0; +} + +/* specific reset for elements inside QToolBar */ +QToolBar * { + margin: 0px; + padding: 0px; +} + +/* QWidget ---------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QWidget { + background-color: #19232D; + border: 0px solid #455364; + padding: 0px; + color: #E0E1E3; + selection-background-color: #346792; + selection-color: #E0E1E3; +} + +QWidget:disabled { + background-color: #19232D; + color: #9DA9B5; + selection-background-color: #26486B; + selection-color: #9DA9B5; +} + +QWidget::item:selected { + background-color: #346792; +} + +QWidget::item:hover:!selected { + background-color: #1A72BB; +} + +/* QMainWindow ------------------------------------------------------------ + +This adjusts the splitter in the dock widget, not qsplitter +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow + +--------------------------------------------------------------------------- */ +QMainWindow::separator { + background-color: #455364; + border: 0px solid #19232D; + spacing: 0px; + padding: 2px; +} + +QMainWindow::separator:hover { + background-color: #60798B; + border: 0px solid #1A72BB; +} + +QMainWindow::separator:horizontal { + width: 5px; + margin-top: 2px; + margin-bottom: 2px; + image: url(":/standard_dark/rc/toolbar_separator_vertical.png"); +} + +QMainWindow::separator:vertical { + height: 5px; + margin-left: 2px; + margin-right: 2px; + image: url(":/standard_dark/rc/toolbar_separator_horizontal.png"); +} + +/* QToolTip --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip + +--------------------------------------------------------------------------- */ +QToolTip { + background-color: #346792; + color: #E0E1E3; + /* If you remove the border property, background stops working on Windows */ + border: none; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Remove opacity, fix #174 - may need to use RGBA */ +} + +/* QStatusBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar + +--------------------------------------------------------------------------- */ +QStatusBar { + border: 1px solid #455364; + /* Fixes Spyder #9120, #9121 */ + background: #455364; + /* Fixes #205, white vertical borders separating items */ +} + +QStatusBar::item { + border: none; +} + +QStatusBar QToolTip { + background-color: #1A72BB; + border: 1px solid #19232D; + color: #19232D; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Reducing transparency to read better */ + opacity: 230; +} + +QStatusBar QLabel { + /* Fixes Spyder #9120, #9121 */ + background: transparent; +} + +/* QCheckBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox + +--------------------------------------------------------------------------- */ +QCheckBox { + background-color: #19232D; + color: #E0E1E3; + spacing: 4px; + outline: none; + padding-top: 4px; + padding-bottom: 4px; +} + +QCheckBox:focus { + border: none; +} + +QCheckBox QWidget:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QCheckBox::indicator { + margin-left: 2px; + height: 14px; + width: 14px; +} + +QCheckBox::indicator:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QCheckBox::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QCheckBox::indicator:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QCheckBox::indicator:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +QCheckBox::indicator:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QCheckBox::indicator:indeterminate:disabled { + image: url(":/standard_dark/rc/checkbox_indeterminate_disabled.png"); +} + +QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +/* QGroupBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox + +--------------------------------------------------------------------------- */ +QGroupBox { + font-weight: bold; + border: 1px solid #455364; + border-radius: 4px; + padding: 2px; + margin-top: 6px; + margin-bottom: 4px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 4px; + padding-left: 2px; + padding-right: 4px; + padding-top: -4px; +} + +QGroupBox::indicator { + margin-left: 2px; + margin-top: 2px; + padding: 0; + height: 14px; + width: 14px; +} + +QGroupBox::indicator:unchecked { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QGroupBox::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QGroupBox::indicator:checked { + border: none; + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QGroupBox::indicator:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +/* QRadioButton ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton + +--------------------------------------------------------------------------- */ +QRadioButton { + background-color: #19232D; + color: #E0E1E3; + spacing: 4px; + padding-top: 4px; + padding-bottom: 4px; + border: none; + outline: none; +} + +QRadioButton:focus { + border: none; +} + +QRadioButton:disabled { + background-color: #19232D; + color: #9DA9B5; + border: none; + outline: none; +} + +QRadioButton QWidget { + background-color: #19232D; + color: #E0E1E3; + spacing: 0px; + padding: 0px; + outline: none; + border: none; +} + +QRadioButton::indicator { + border: none; + outline: none; + margin-left: 2px; + height: 14px; + width: 14px; +} + +QRadioButton::indicator:unchecked { + image: url(":/standard_dark/rc/radio_unchecked.png"); +} + +QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_unchecked_focus.png"); +} + +QRadioButton::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/radio_unchecked_disabled.png"); +} + +QRadioButton::indicator:checked { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked.png"); +} + +QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked_focus.png"); +} + +QRadioButton::indicator:checked:disabled { + outline: none; + image: url(":/standard_dark/rc/radio_checked_disabled.png"); +} + +/* QMenuBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar + +--------------------------------------------------------------------------- */ +QMenuBar { + background-color: #455364; + padding: 2px; + border: 1px solid #19232D; + color: #E0E1E3; + selection-background-color: #1A72BB; +} + +QMenuBar:focus { + border: 1px solid #346792; +} + +QMenuBar::item { + background: transparent; + padding: 4px; +} + +QMenuBar::item:selected { + padding: 4px; + background: transparent; + border: 0px solid #455364; + background-color: #1A72BB; +} + +QMenuBar::item:pressed { + padding: 4px; + border: 0px solid #455364; + background-color: #1A72BB; + color: #E0E1E3; + margin-bottom: 0px; + padding-bottom: 0px; +} + +/* QMenu ------------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu + +--------------------------------------------------------------------------- */ +QMenu { + border: 0px solid #455364; + color: #E0E1E3; + margin: 0px; + background-color: #37414F; + selection-background-color: #1A72BB; +} + +QMenu::separator { + height: 1px; + background-color: #60798B; + color: #E0E1E3; +} + +QMenu::item { + background-color: #37414F; + padding: 4px 24px 4px 28px; + /* Reserve space for selection border */ + border: 1px transparent #455364; +} + +QMenu::item:selected { + color: #E0E1E3; + background-color: #1A72BB; +} + +QMenu::item:pressed { + background-color: #1A72BB; +} + +QMenu::icon { + padding-left: 10px; + width: 14px; + height: 14px; +} + +QMenu::indicator { + padding-left: 8px; + width: 12px; + height: 12px; + /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ + /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +} + +QMenu::indicator:non-exclusive:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QMenu::indicator:non-exclusive:unchecked:hover, QMenu::indicator:non-exclusive:unchecked:focus, QMenu::indicator:non-exclusive:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QMenu::indicator:non-exclusive:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QMenu::indicator:non-exclusive:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QMenu::indicator:non-exclusive:checked:hover, QMenu::indicator:non-exclusive:checked:focus, QMenu::indicator:non-exclusive:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:disabled { + image: url(":/standard_dark/rc/checkbox_indeterminate_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:focus, QMenu::indicator:non-exclusive:indeterminate:hover, QMenu::indicator:non-exclusive:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +QMenu::indicator:exclusive:unchecked { + image: url(":/standard_dark/rc/radio_unchecked.png"); +} + +QMenu::indicator:exclusive:unchecked:hover, QMenu::indicator:exclusive:unchecked:focus, QMenu::indicator:exclusive:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_unchecked_focus.png"); +} + +QMenu::indicator:exclusive:unchecked:disabled { + image: url(":/standard_dark/rc/radio_unchecked_disabled.png"); +} + +QMenu::indicator:exclusive:checked { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked.png"); +} + +QMenu::indicator:exclusive:checked:hover, QMenu::indicator:exclusive:checked:focus, QMenu::indicator:exclusive:checked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked_focus.png"); +} + +QMenu::indicator:exclusive:checked:disabled { + outline: none; + image: url(":/standard_dark/rc/radio_checked_disabled.png"); +} + +QMenu::right-arrow { + margin: 5px; + padding-left: 12px; + image: url(":/standard_dark/rc/arrow_right.png"); + height: 12px; + width: 12px; +} + +/* QAbstractItemView ------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QAbstractItemView { + alternate-background-color: #19232D; + color: #E0E1E3; + border: 1px solid #455364; + border-radius: 4px; +} + +QAbstractItemView QLineEdit { + padding: 2px; +} + +/* QAbstractScrollArea ---------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QAbstractScrollArea { + background-color: #19232D; + border: 1px solid #455364; + border-radius: 4px; + /* fix #159 */ + padding: 2px; + /* remove min-height to fix #244 */ + color: #E0E1E3; +} + +QAbstractScrollArea:disabled { + color: #9DA9B5; +} + +/* QScrollArea ------------------------------------------------------------ + +--------------------------------------------------------------------------- */ +QScrollArea QWidget QWidget:disabled { + background-color: #19232D; +} + +/* QScrollBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar + +--------------------------------------------------------------------------- */ +QScrollBar:horizontal { + height: 16px; + margin: 2px 16px 2px 16px; + border: 1px solid #455364; + border-radius: 4px; + background-color: #19232D; +} + +QScrollBar:vertical { + background-color: #19232D; + width: 16px; + margin: 16px 2px 16px 2px; + border: 1px solid #455364; + border-radius: 4px; +} + +QScrollBar::handle:horizontal { + background-color: #60798B; + border: 1px solid #455364; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:hover { + background-color: #346792; + border: #346792; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:focus { + border: 1px solid #1A72BB; +} + +QScrollBar::handle:vertical { + background-color: #60798B; + border: 1px solid #455364; + min-height: 8px; + border-radius: 4px; +} + +QScrollBar::handle:vertical:hover { + background-color: #346792; + border: #346792; + border-radius: 4px; + min-height: 8px; +} + +QScrollBar::handle:vertical:focus { + border: 1px solid #1A72BB; +} + +QScrollBar::add-line:horizontal { + margin: 0px 0px 0px 0px; + border-image: url(":/standard_dark/rc/arrow_right_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on { + border-image: url(":/standard_dark/rc/arrow_right.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on { + border-image: url(":/standard_dark/rc/arrow_down.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + margin: 0px 3px 0px 3px; + border-image: url(":/standard_dark/rc/arrow_left_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on { + border-image: url(":/standard_dark/rc/arrow_left.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_dark/rc/arrow_up_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on { + border-image: url(":/standard_dark/rc/arrow_up.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal { + background: none; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + background: none; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + +/* QTextEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets + +--------------------------------------------------------------------------- */ +QTextEdit { + background-color: #19232D; + color: #E0E1E3; + border-radius: 4px; + border: 1px solid #455364; +} + +QTextEdit:focus { + border: 1px solid #1A72BB; +} + +QTextEdit:selected { + background: #346792; + color: #455364; +} + +/* QPlainTextEdit --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QPlainTextEdit { + background-color: #19232D; + color: #E0E1E3; + border-radius: 4px; + border: 1px solid #455364; +} + +QPlainTextEdit:focus { + border: 1px solid #1A72BB; +} + +QPlainTextEdit:selected { + background: #346792; + color: #455364; +} + +/* QSizeGrip -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip + +--------------------------------------------------------------------------- */ +QSizeGrip { + background: transparent; + width: 12px; + height: 12px; + image: url(":/standard_dark/rc/window_grip.png"); +} + +/* QStackedWidget --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QStackedWidget { + padding: 2px; + border: 1px solid #455364; + border: 1px solid #19232D; +} + +/* QToolBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar + +--------------------------------------------------------------------------- */ +QToolBar { + background-color: #455364; + border-bottom: 1px solid #19232D; + padding: 1px; + font-weight: bold; + spacing: 2px; +} + +QToolBar:disabled { + /* Fixes #272 */ + background-color: #455364; +} + +QToolBar::handle:horizontal { + width: 16px; + image: url(":/standard_dark/rc/toolbar_move_horizontal.png"); +} + +QToolBar::handle:vertical { + height: 16px; + image: url(":/standard_dark/rc/toolbar_move_vertical.png"); +} + +QToolBar::separator:horizontal { + width: 16px; + image: url(":/standard_dark/rc/toolbar_separator_horizontal.png"); +} + +QToolBar::separator:vertical { + height: 16px; + image: url(":/standard_dark/rc/toolbar_separator_vertical.png"); +} + +QToolButton#qt_toolbar_ext_button { + background: #455364; + border: 0px; + color: #E0E1E3; + image: url(":/standard_dark/rc/arrow_right.png"); +} + +/* QAbstractSpinBox ------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractSpinBox { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; + /* min-width: 5px; removed to fix 109 */ +} + +QAbstractSpinBox:up-button { + background-color: transparent #19232D; + subcontrol-origin: border; + subcontrol-position: top right; + border-left: 1px solid #455364; + border-bottom: 1px solid #455364; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-bottom: -1px; +} + +QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off { + image: url(":/standard_dark/rc/arrow_up_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::up-arrow:hover { + image: url(":/standard_dark/rc/arrow_up.png"); +} + +QAbstractSpinBox:down-button { + background-color: transparent #19232D; + subcontrol-origin: border; + subcontrol-position: bottom right; + border-left: 1px solid #455364; + border-top: 1px solid #455364; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-top: -1px; +} + +QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::down-arrow:hover { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QAbstractSpinBox:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QAbstractSpinBox:focus { + border: 1px solid #1A72BB; +} + +QAbstractSpinBox:selected { + background: #346792; + color: #455364; +} + +/* ------------------------------------------------------------------------ */ +/* DISPLAYS --------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QLabel ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe + +--------------------------------------------------------------------------- */ +QLabel { + background-color: #19232D; + border: 0px solid #455364; + padding: 2px; + margin: 0px; + color: #E0E1E3; +} + +QLabel:disabled { + background-color: #19232D; + border: 0px solid #455364; + color: #9DA9B5; +} + +/* QTextBrowser ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QTextBrowser { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; +} + +QTextBrowser:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; +} + +QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed { + border: 1px solid #455364; +} + +/* QGraphicsView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QGraphicsView { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; +} + +QGraphicsView:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; +} + +QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed { + border: 1px solid #455364; +} + +/* QCalendarWidget -------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCalendarWidget { + border: 1px solid #455364; + border-radius: 4px; +} + +QCalendarWidget:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +/* QLCDNumber ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QLCDNumber { + background-color: #19232D; + color: #E0E1E3; +} + +QLCDNumber:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +/* QProgressBar ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar + +--------------------------------------------------------------------------- */ +QProgressBar { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; + text-align: center; +} + +QProgressBar:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #346792; + color: #19232D; + border-radius: 4px; +} + +QProgressBar::chunk:disabled { + background-color: #26486B; + color: #9DA9B5; + border-radius: 4px; +} + +/* ------------------------------------------------------------------------ */ +/* BUTTONS ---------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QPushButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton + +--------------------------------------------------------------------------- */ +QPushButton { + background-color: #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; +} + +QPushButton:disabled { + background-color: #455364; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; +} + +QPushButton:checked { + background-color: #60798B; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:disabled { + background-color: #60798B; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:selected { + background: #60798B; +} + +QPushButton:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QPushButton:pressed { + background-color: #60798B; +} + +QPushButton:selected { + background: #60798B; + color: #E0E1E3; +} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + bottom: 4px; +} + +QDialogButtonBox QPushButton { + /* Issue #194 #248 - Special case of QPushButton inside dialogs, for better UI */ + min-width: 80px; +} + +/* QToolButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton + +--------------------------------------------------------------------------- */ +QToolButton { + background-color: #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; + /* The subcontrols below are used only in the DelayedPopup mode */ + /* The subcontrols below are used only in the MenuButtonPopup mode */ + /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +} + +QToolButton:disabled { + background-color: #455364; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; +} + +QToolButton:checked { + background-color: #60798B; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:disabled { + background-color: #60798B; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QToolButton:checked:pressed { + background-color: #60798B; +} + +QToolButton:checked:selected { + background: #60798B; + color: #E0E1E3; +} + +QToolButton:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QToolButton:pressed { + background-color: #60798B; +} + +QToolButton:selected { + background: #60798B; + color: #E0E1E3; +} + +QToolButton[popupMode="0"] { + /* Only for DelayedPopup */ + padding-right: 2px; +} + +QToolButton[popupMode="1"] { + /* Only for MenuButtonPopup */ + padding-right: 20px; +} + +QToolButton[popupMode="1"]::menu-button { + border: none; +} + +QToolButton[popupMode="1"]::menu-button:hover { + border: none; + border-left: 1px solid #455364; + border-radius: 0; +} + +QToolButton[popupMode="2"] { + /* Only for InstantPopup */ + padding-right: 2px; +} + +QToolButton::menu-button { + padding: 2px; + border-radius: 4px; + width: 12px; + border: none; + outline: none; +} + +QToolButton::menu-button:hover { + border: 1px solid #346792; +} + +QToolButton::menu-button:checked:hover { + border: 1px solid #346792; +} + +QToolButton::menu-indicator { + image: url(":/standard_dark/rc/arrow_down.png"); + height: 8px; + width: 8px; + top: 0; + /* Exclude a shift for better image */ + left: -2px; + /* Shift it a bit */ +} + +QToolButton::menu-arrow { + image: url(":/standard_dark/rc/arrow_down.png"); + height: 8px; + width: 8px; +} + +QToolButton::menu-arrow:hover { + image: url(":/standard_dark/rc/arrow_down_focus.png"); +} + +/* QCommandLinkButton ----------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCommandLinkButton { + background-color: transparent; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 0px; + margin: 0px; +} + +QCommandLinkButton:disabled { + background-color: transparent; + color: #9DA9B5; +} + +/* ------------------------------------------------------------------------ */ +/* INPUTS - NO FIELDS ----------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QComboBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QComboBox { + border: 1px solid #455364; + border-radius: 4px; + selection-background-color: #346792; + padding-left: 4px; + padding-right: 4px; + /* padding-right = 36; 4 + 16*2 See scrollbar size */ + /* changed to 4px to fix #239 */ + /* Fixes #103, #111 */ + min-height: 1.5em; + /* padding-top: 2px; removed to fix #132 */ + /* padding-bottom: 2px; removed to fix #132 */ + /* min-width: 75px; removed to fix #109 */ + /* Needed to remove indicator - fix #132 */ +} + +QComboBox QAbstractItemView { + border: 1px solid #455364; + border-radius: 0; + background-color: #19232D; + selection-background-color: #346792; +} + +QComboBox QAbstractItemView:hover { + background-color: #19232D; + color: #E0E1E3; +} + +QComboBox QAbstractItemView:selected { + background: #346792; + color: #455364; +} + +QComboBox QAbstractItemView:alternate { + background: #19232D; +} + +QComboBox:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QComboBox:hover { + border: 1px solid #346792; +} + +QComboBox:focus { + border: 1px solid #1A72BB; +} + +QComboBox:on { + selection-background-color: #346792; +} + +QComboBox::indicator { + border: none; + border-radius: 0; + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + /* Needed to remove indicator - fix #132 */ +} + +QComboBox::indicator:alternate { + background: #19232D; +} + +QComboBox::item:alternate { + background: #19232D; +} + +QComboBox::item:checked { + font-weight: bold; +} + +QComboBox::item:selected { + border: 0px solid transparent; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #455364; +} + +QComboBox::down-arrow { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +/* QSlider ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider + +--------------------------------------------------------------------------- */ +QSlider:disabled { + background: #19232D; +} + +QSlider:focus { + border: none; +} + +QSlider::groove:horizontal { + background: #455364; + border: 1px solid #455364; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::groove:vertical { + background: #455364; + border: 1px solid #455364; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical { + background: #346792; + border: 1px solid #455364; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical :disabled { + background: #26486B; +} + +QSlider::sub-page:horizontal { + background: #346792; + border: 1px solid #455364; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { + background: #26486B; +} + +QSlider::handle:horizontal { + background: #9DA9B5; + border: 1px solid #455364; + width: 8px; + height: 8px; + margin: -8px 0px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: #346792; + border: 1px solid #346792; +} + +QSlider::handle:horizontal:focus { + border: 1px solid #1A72BB; +} + +QSlider::handle:vertical { + background: #9DA9B5; + border: 1px solid #455364; + width: 8px; + height: 8px; + margin: 0 -8px; + border-radius: 4px; +} + +QSlider::handle:vertical:hover { + background: #346792; + border: 1px solid #346792; +} + +QSlider::handle:vertical:focus { + border: 1px solid #1A72BB; +} + +/* QLineEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit + +--------------------------------------------------------------------------- */ +QLineEdit { + background-color: #19232D; + padding-top: 2px; + /* This QLineEdit fix 103, 111 */ + padding-bottom: 2px; + /* This QLineEdit fix 103, 111 */ + padding-left: 4px; + padding-right: 4px; + border-style: solid; + border: 1px solid #455364; + border-radius: 4px; + color: #E0E1E3; +} + +QLineEdit:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QLineEdit:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QLineEdit:focus { + border: 1px solid #1A72BB; +} + +QLineEdit:selected { + background-color: #346792; + color: #455364; +} + +/* QTabWiget -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabWidget { + padding: 2px; + selection-background-color: #455364; +} + +QTabWidget QWidget { + /* Fixes #189 */ + border-radius: 4px; +} + +QTabWidget::pane { + border: 1px solid #455364; + border-radius: 4px; + margin: 0px; + /* Fixes double border inside pane with pyqt5 */ + padding: 0px; +} + +QTabWidget::pane:selected { + background-color: #455364; + border: 1px solid #346792; +} + +/* QTabBar ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabBar, QDockWidget QTabBar { + qproperty-drawBase: 0; + border-radius: 4px; + margin: 0px; + padding: 2px; + border: 0; + /* left: 5px; move to the right by 5px - removed for fix */ +} + +QTabBar::close-button, QDockWidget QTabBar::close-button { + border: 0; + margin: 0; + padding: 4px; + image: url(":/standard_dark/rc/window_close.png"); +} + +QTabBar::close-button:hover, QDockWidget QTabBar::close-button:hover { + image: url(":/standard_dark/rc/window_close_focus.png"); +} + +QTabBar::close-button:pressed, QDockWidget QTabBar::close-button:pressed { + image: url(":/standard_dark/rc/window_close_pressed.png"); +} + +QTabBar::tab, QDockWidget QTabBar::tab { + /* !selected and disabled ----------------------------------------- */ + /* selected ------------------------------------------------------- */ +} + +QTabBar::tab:top:selected:disabled, QDockWidget QTabBar::tab:top:selected:disabled { + border-bottom: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:bottom:selected:disabled, QDockWidget QTabBar::tab:bottom:selected:disabled { + border-top: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:left:selected:disabled, QDockWidget QTabBar::tab:left:selected:disabled { + border-right: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:right:selected:disabled, QDockWidget QTabBar::tab:right:selected:disabled { + border-left: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:top:!selected:disabled, QDockWidget QTabBar::tab:top:!selected:disabled { + border-bottom: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:bottom:!selected:disabled, QDockWidget QTabBar::tab:bottom:!selected:disabled { + border-top: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:left:!selected:disabled, QDockWidget QTabBar::tab:left:!selected:disabled { + border-right: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:right:!selected:disabled, QDockWidget QTabBar::tab:right:!selected:disabled { + border-left: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:top:!selected, QDockWidget QTabBar::tab:top:!selected { + border-bottom: 2px solid #19232D; + margin-top: 2px; +} + +QTabBar::tab:bottom:!selected, QDockWidget QTabBar::tab:bottom:!selected { + border-top: 2px solid #19232D; + margin-bottom: 2px; +} + +QTabBar::tab:left:!selected, QDockWidget QTabBar::tab:left:!selected { + border-left: 2px solid #19232D; + margin-right: 2px; +} + +QTabBar::tab:right:!selected, QDockWidget QTabBar::tab:right:!selected { + border-right: 2px solid #19232D; + margin-left: 2px; +} + +QTabBar::tab:top, QDockWidget QTabBar::tab:top { + background-color: #455364; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + min-width: 5px; + border-bottom: 3px solid #455364; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:selected, QDockWidget QTabBar::tab:top:selected { + background-color: #54687A; + border-bottom: 3px solid #259AE9; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:!selected:hover, QDockWidget QTabBar::tab:top:!selected:hover { + border: 1px solid #1A72BB; + border-bottom: 3px solid #1A72BB; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:bottom, QDockWidget QTabBar::tab:bottom { + border-top: 3px solid #455364; + background-color: #455364; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + min-width: 5px; +} + +QTabBar::tab:bottom:selected, QDockWidget QTabBar::tab:bottom:selected { + background-color: #54687A; + border-top: 3px solid #259AE9; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabBar::tab:bottom:!selected:hover, QDockWidget QTabBar::tab:bottom:!selected:hover { + border: 1px solid #1A72BB; + border-top: 3px solid #1A72BB; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:left, QDockWidget QTabBar::tab:left { + background-color: #455364; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:left:selected, QDockWidget QTabBar::tab:left:selected { + background-color: #54687A; + border-right: 3px solid #259AE9; +} + +QTabBar::tab:left:!selected:hover, QDockWidget QTabBar::tab:left:!selected:hover { + border: 1px solid #1A72BB; + border-right: 3px solid #1A72BB; + /* Fixes different behavior #271 */ + margin-right: 0px; + padding-right: -1px; +} + +QTabBar::tab:right, QDockWidget QTabBar::tab:right { + background-color: #455364; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:right:selected, QDockWidget QTabBar::tab:right:selected { + background-color: #54687A; + border-left: 3px solid #259AE9; +} + +QTabBar::tab:right:!selected:hover, QDockWidget QTabBar::tab:right:!selected:hover { + border: 1px solid #1A72BB; + border-left: 3px solid #1A72BB; + /* Fixes different behavior #271 */ + margin-left: 0px; + padding-left: 0px; +} + +QTabBar QToolButton, QDockWidget QTabBar QToolButton { + /* Fixes #136 */ + background-color: #455364; + height: 12px; + width: 12px; +} + +QTabBar QToolButton:pressed, QDockWidget QTabBar QToolButton:pressed { + background-color: #455364; +} + +QTabBar QToolButton:pressed:hover, QDockWidget QTabBar QToolButton:pressed:hover { + border: 1px solid #346792; +} + +QTabBar QToolButton::left-arrow:enabled, QDockWidget QTabBar QToolButton::left-arrow:enabled { + image: url(":/standard_dark/rc/arrow_left.png"); +} + +QTabBar QToolButton::left-arrow:disabled, QDockWidget QTabBar QToolButton::left-arrow:disabled { + image: url(":/standard_dark/rc/arrow_left_disabled.png"); +} + +QTabBar QToolButton::right-arrow:enabled, QDockWidget QTabBar QToolButton::right-arrow:enabled { + image: url(":/standard_dark/rc/arrow_right.png"); +} + +QTabBar QToolButton::right-arrow:disabled, QDockWidget QTabBar QToolButton::right-arrow:disabled { + image: url(":/standard_dark/rc/arrow_right_disabled.png"); +} + +/* QDockWiget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QDockWidget { + outline: 1px solid #455364; + background-color: #19232D; + border: 1px solid #455364; + border-radius: 4px; + titlebar-close-icon: url(":/standard_dark/rc/transparent.png"); + titlebar-normal-icon: url(":/standard_dark/rc/transparent.png"); +} + +QDockWidget::title { + /* Better size for title bar */ + padding: 3px; + spacing: 4px; + border: none; + background-color: #455364; +} + +QDockWidget::close-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_dark/rc/window_close.png"); +} + +QDockWidget::close-button:hover { + image: url(":/standard_dark/rc/window_close_focus.png"); +} + +QDockWidget::close-button:pressed { + image: url(":/standard_dark/rc/window_close_pressed.png"); +} + +QDockWidget::float-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_dark/rc/window_undock.png"); +} + +QDockWidget::float-button:hover { + image: url(":/standard_dark/rc/window_undock_focus.png"); +} + +QDockWidget::float-button:pressed { + image: url(":/standard_dark/rc/window_undock_pressed.png"); +} + +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/standard_dark/rc/transparent.png"); +} + +QTreeView:branch:has-siblings:!adjoins-item { + border-image: url(":/standard_dark/rc/branch_line.png") 0; +} + +QTreeView:branch:has-siblings:adjoins-item { + border-image: url(":/standard_dark/rc/branch_more.png") 0; +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item { + border-image: url(":/standard_dark/rc/branch_end.png") 0; +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/standard_dark/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/standard_dark/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/standard_dark/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/standard_dark/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked, +QListView::indicator:checked, +QTableView::indicator:checked, +QColumnView::indicator:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed, +QListView::indicator:checked:hover, +QListView::indicator:checked:focus, +QListView::indicator:checked:pressed, +QTableView::indicator:checked:hover, +QTableView::indicator:checked:focus, +QTableView::indicator:checked:pressed, +QColumnView::indicator:checked:hover, +QColumnView::indicator:checked:focus, +QColumnView::indicator:checked:pressed { + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked, +QListView::indicator:unchecked, +QTableView::indicator:unchecked, +QColumnView::indicator:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed, +QListView::indicator:unchecked:hover, +QListView::indicator:unchecked:focus, +QListView::indicator:unchecked:pressed, +QTableView::indicator:unchecked:hover, +QTableView::indicator:unchecked:focus, +QTableView::indicator:unchecked:pressed, +QColumnView::indicator:unchecked:hover, +QColumnView::indicator:unchecked:focus, +QColumnView::indicator:unchecked:pressed { + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QTreeView::indicator:indeterminate, +QListView::indicator:indeterminate, +QTableView::indicator:indeterminate, +QColumnView::indicator:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed, +QListView::indicator:indeterminate:hover, +QListView::indicator:indeterminate:focus, +QListView::indicator:indeterminate:pressed, +QTableView::indicator:indeterminate:hover, +QTableView::indicator:indeterminate:focus, +QTableView::indicator:indeterminate:pressed, +QColumnView::indicator:indeterminate:hover, +QColumnView::indicator:indeterminate:focus, +QColumnView::indicator:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + gridline-color: #455364; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #346792; + color: #455364; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #1A72BB; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #346792; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #346792; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #E0E1E3; + background-color: #37414F; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #E0E1E3; + background-color: #37414F; +} + +QTableCornerButton::section { + background-color: #19232D; + border: 1px transparent #455364; + border-radius: 0px; +} + +/* QHeaderView ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview + +--------------------------------------------------------------------------- */ +QHeaderView { + background-color: #455364; + border: 0px transparent #455364; + padding: 0; + margin: 0; + border-radius: 0; +} + +QHeaderView:disabled { + background-color: #455364; + border: 1px transparent #455364; +} + +QHeaderView::section { + background-color: #455364; + color: #E0E1E3; + border-radius: 0; + text-align: left; + font-size: 13px; +} + +QHeaderView::section::horizontal { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-left: 1px solid #19232D; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one { + border-left: 1px solid #455364; +} + +QHeaderView::section::horizontal:disabled { + color: #9DA9B5; +} + +QHeaderView::section::vertical { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-top: 1px solid #19232D; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one { + border-top: 1px solid #455364; +} + +QHeaderView::section::vertical:disabled { + color: #9DA9B5; +} + +QHeaderView::down-arrow { + /* Those settings (border/width/height/background-color) solve bug */ + /* transparent arrow background and size */ + background-color: #455364; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QHeaderView::up-arrow { + background-color: #455364; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_dark/rc/arrow_up.png"); +} + +/* QToolBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox + +--------------------------------------------------------------------------- */ +QToolBox { + padding: 0px; + border: 0px; + border: 1px solid #455364; +} + +QToolBox:selected { + padding: 0px; + border: 2px solid #346792; +} + +QToolBox::tab { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QToolBox::tab:disabled { + color: #9DA9B5; +} + +QToolBox::tab:selected { + background-color: #60798B; + border-bottom: 2px solid #346792; +} + +QToolBox::tab:selected:disabled { + background-color: #455364; + border-bottom: 2px solid #26486B; +} + +QToolBox::tab:!selected { + background-color: #455364; + border-bottom: 2px solid #455364; +} + +QToolBox::tab:!selected:disabled { + background-color: #19232D; +} + +QToolBox::tab:hover { + border-color: #1A72BB; + border-bottom: 2px solid #1A72BB; +} + +QToolBox QScrollArea QWidget QWidget { + padding: 0px; + border: 0px; + background-color: #19232D; +} + +/* QFrame ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe +https://doc.qt.io/qt-5/qframe.html#-prop +https://doc.qt.io/qt-5/qframe.html#details +https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color + +--------------------------------------------------------------------------- */ +/* (dot) .QFrame fix #141, #126, #123 */ +.QFrame { + border-radius: 4px; + border: 1px solid #455364; + /* No frame */ + /* HLine */ + /* HLine */ +} + +.QFrame[frameShape="0"] { + border-radius: 4px; + border: 1px transparent #455364; +} + +.QFrame[frameShape="4"] { + max-height: 2px; + border: none; + background-color: #455364; +} + +.QFrame[frameShape="5"] { + max-width: 2px; + border: none; + background-color: #455364; +} + +/* QSplitter -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter + +--------------------------------------------------------------------------- */ +QSplitter { + background-color: #455364; + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QSplitter::handle { + background-color: #455364; + border: 0px solid #19232D; + spacing: 0px; + padding: 1px; + margin: 0px; +} + +QSplitter::handle:hover { + background-color: #9DA9B5; +} + +QSplitter::handle:horizontal { + width: 5px; + image: url(":/standard_dark/rc/line_vertical.png"); +} + +QSplitter::handle:vertical { + height: 5px; + image: url(":/standard_dark/rc/line_horizontal.png"); +} + +/* QDateEdit, QDateTimeEdit ----------------------------------------------- + +--------------------------------------------------------------------------- */ +QDateEdit, QDateTimeEdit { + selection-background-color: #346792; + border-style: solid; + border: 1px solid #455364; + border-radius: 4px; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + min-width: 10px; +} + +QDateEdit:on, QDateTimeEdit:on { + selection-background-color: #346792; +} + +QDateEdit::drop-down, QDateTimeEdit::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #455364; +} + +QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView { + background-color: #19232D; + border-radius: 4px; + border: 1px solid #455364; + selection-background-color: #346792; +} + +/* QAbstractView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractView:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QAbstractView:selected { + background: #346792; + color: #455364; +} + +/* PlotWidget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +PlotWidget { + /* Fix cut labels in plots #134 */ + padding: 0px; +} + +/**********************************/ +/* RetroShare specific part */ +/**********************************/ + +/**** Fix QTreeView Items ****/ + +QTreeView::item, +QListView::item, +QTableView::item, +QColumnView::item { + color: #F0F0F0; + background: transparent; +} +QTreeView:branch:!selected:hover, +QTreeView:branch:selected:!active { + color: #E0E1E3; + background-color: #37414F; +} + +/**** Fix QSplitter ****/ + +QSplitter { + background-color: #19232D; +} + +QSplitter::handle { + background-color: #455364; + border: 0px solid #455364; + border-radius: 4px; +} + + +/**** Standard rules ****/ + +QFrame[objectName^="feedFrame"],/* Frame used in Feeds*/ +QFrame[objectName^="plainFrame"],/* Frame used in Widget with plain background*/ +QFrame[objectName^="plainBFrame"] {/* Frame used in Widget with plain bordered background*/ + background-color: #19232D; +} +QFrame[objectName^="plainBFrame"] { + border: 1px solid #32414B; +} + +/* Frame used in old Feeds*/ +QFrame#feedFrame[new=false] { + background-color: #19232D; +} +/* Frame used in new Feeds*/ +QFrame#feedFrame[new=true] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #19232D, stop:0.8 #1251A0, stop: 0.81 #1251A0, stop: 1 #19232D); +} +QFrame#feedFrame QLabel { + background: transparent; +} + +QFrame[objectName^="gradFrame"],/* Frame used in Widget with gradient colored background*/ +QFrame#bottomFrame,/* Frame used at the bottom of dialog*/ +QFrame#toasterFrame,/* Frame used in Toasters*/ +QFrame#toolBarFrame {/* Frame used for buttons*/ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #19232D, stop:1 #32414B); + border: 1px solid #CCCCCC; +} +QFrame#toolBarFrame > LineEditClear { + background-color: #29333D; +} +QFrame[objectName^="gradFrame"] QComboBox, +QFrame[objectName^="gradFrame"] QLineEdit, +QFrame[objectName^="gradFrame"] QTextEdit { + background-color: #29333D; +} +QFrame[objectName^="gradFrame"] QComboBox QAbstractItemView { + background-color: #555555; + selection-background-color: #1464A0; +} + +QLabel#avatarLabel{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} + + +/* HeaderFrame & TitleBarFrame */ + +QFrame[objectName^="headerFrame"], +QFrame[objectName^="headerBFrame"], +QToolBar#headerToolBar, +QFrame#titleBarFrame { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #455364, stop: 0.5 #54687A,stop: 0.6 #44586A, stop:1 #455364); + border: 0px; +} +QFrame[objectName^="#headerBFrame"] { + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover, +QFrame#titleBarFrame > *:!hover { + background: transparent; + color: white; +} +QFrame#titleBarFrame QComboBox, +QFrame#titleBarFrame QLineEdit, +QFrame#titleBarFrame QTextEdit { + background: #29333D; +} + + +/**** Special Page tweak ****/ + + +/* Forums */ + +GxsForumThreadWidget QWidget#threadTreeWidget { + selection-background-color: #005599; + show-decoration-selected: 1; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item { + padding: 2px; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { + background-color: #005599; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 80, 80, 80, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background-color: #166716; + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background-color: #673232; + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background-color: #166716; + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background-color: #673232; + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_card QLabel#pictureLabel, +BoardPostDisplayWidget_compact QLabel#pictureLabel{ + border: 2px solid #444444; + border-radius: 3px; +} + + +/*************** Optional ***************/ + +/**** WikiPoos ****/ +WikiEditDialog QPushButton#pushButton_History { + color: white; + background: #5bb62b; + border-radius: 4px; + max-height: 20px; + min-width: 4em; + padding: 2px; + padding-left: 6px; + padding-right: 6px; +} + +WikiEditDialog QPushButton#pushButton_History:hover { + background: #57af29; +} + + +/**** The Wire ****/ + +WireGroupItem QFrame#wire_frame QLabel{ + background: transparent; +} +WireGroupItem QFrame#wire_frame:hover { + background-color: #2e8bab; +} + +PulseTopLevel QFrame#frame, +PulseViewGroup QFrame#frame, +PulseReply QFrame#frame { + border: 2px solid #38444d; + border-radius: 6px; +} + +PulseAddDialog QTextEdit#textEdit_Pulse { + border: 2px solid #c4cfd6; + border-radius: 6px; + background: white; + color: black; +} + +PulseReply #line_replyLine, +PulseMessage #line{ + color: #c4cfd6; +} + +PulseReply QLabel#label_groupName{ + color: #5b7083; +} + +/**** Color definitions ****/ + +ForumsDialog, GxsForumThreadWidget +{ + qproperty-textColorRead: darkgray; + qproperty-textColorUnread: white; + qproperty-textColorUnreadChildren: red; + qproperty-textColorNotSubscribed: white; + qproperty-textColorMissing: darkred; + qproperty-textColorPinned: #D07000; + + qproperty-backgroundColorPinned: #19232D; + qproperty-backgroundColorFiltered: darkGreen; +} + +GroupTreeWidget +{ + qproperty-textColorCategory: rgb(99, 99, 99); + qproperty-textColorPrivateKey: rgb(85,151,209); +} + +NetworkDialog { + qproperty-backgroundColorSelf: darkred; + qproperty-backgroundColorOwnSign: darkred; + qproperty-backgroundColorAcceptConnection: black; + qproperty-backgroundColorHasSignedMe: darkred; + qproperty-backgroundColorDenied: #201F1F; + qproperty-textColor: white; +} + +NewFriendList { + qproperty-textColorStatusAway: #4040A0; + qproperty-textColorStatusBusy: #A04040; + qproperty-textColorStatusOnline: #40A040; + qproperty-textColorStatusInactive: #A0A040; + qproperty-textColorStatusOffline: gray; + qproperty-textColorGroup: rgb(123, 123, 123); +} + +RSTextBrowser, MimeTextEdit +{ + /*qproperty-textColorQuote: rgb(125, 125, 255);*/ + qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); +} + +/* OpModeStatus need to be at end to overload other values*/ + +OpModeStatus { + qproperty-opMode_Full_Color: #007000; + qproperty-opMode_NoTurtle_Color: #000070; + qproperty-opMode_Gaming_Color: #707000; + qproperty-opMode_Minimal_Color: #700000; +} +OpModeStatus[opMode="Full"] { + color: #F0F0F0; + background: #007000; +} +OpModeStatus[opMode="NoTurtle"] { + color: #F0F0F0; + background: #000070; +} +OpModeStatus[opMode="Gaming"] { + color: #F0F0F0; + background: #707000; +} +OpModeStatus[opMode="Minimal"] { + color: #F0F0F0; + background: #700000; +} + +/*Property Values at end to overwrite other settings*/ + +[new=false] { + background: #19232D; +} +[new=true] { + background: #1251A0; +} + +[valid=true] { + background: rgba(0,255,0,15%); +} + +[valid=false] { + background: rgba(255,0,0,15%); +} + +[WrongValue="true"] { + background-color: #702020; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss new file mode 100644 index 000000000..85f601e3e --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss @@ -0,0 +1,2685 @@ +/* Standard Light stylesheet for RetroShare + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + + It use a public one for general widgets https://github.com/ColinDuquesnoy/QDarkStyleSheet + /qdarkstyle/light/style.qss + Updated at 2021-11-04 Tag v3.0.2 + Replace all ":/qss_icons/light" by ":/standard_light" + */ + +/* --------------------------------------------------------------------------- + + WARNING! File created programmatically. All changes made in this file will be lost! + + Created by the qtsass compiler v0.3.0 + + The definitions are in the "qdarkstyle.qss._styles.scss" module + +--------------------------------------------------------------------------- */ +/* Dark Style - QDarkStyleSheet ------------------------------------------ */ +/* + +See Qt documentation: + + - https://doc.qt.io/qt-5/stylesheet.html + - https://doc.qt.io/qt-5/stylesheet-reference.html + - https://doc.qt.io/qt-5/stylesheet-examples.html + +--------------------------------------------------------------------------- */ +/* Reset elements ------------------------------------------------------------ + +Resetting everything helps to unify styles across different operating systems + +--------------------------------------------------------------------------- */ +* { + padding: 0px; + margin: 0px; + border: 0px; + border-style: none; + border-image: none; + outline: 0; +} + +/* specific reset for elements inside QToolBar */ +QToolBar * { + margin: 0px; + padding: 0px; +} + +/* QWidget ---------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QWidget { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + padding: 0px; + color: #19232D; + selection-background-color: #9FCBFF; + selection-color: #19232D; +} + +QWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; + selection-background-color: #DAEDFF; + selection-color: #788D9C; +} + +QWidget::item:selected { + background-color: #9FCBFF; +} + +QWidget::item:hover:!selected { + background-color: #73C7FF; +} + +/* QMainWindow ------------------------------------------------------------ + +This adjusts the splitter in the dock widget, not qsplitter +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow + +--------------------------------------------------------------------------- */ +QMainWindow::separator { + background-color: #C9CDD0; + border: 0px solid #FAFAFA; + spacing: 0px; + padding: 2px; +} + +QMainWindow::separator:hover { + background-color: #ACB1B6; + border: 0px solid #73C7FF; +} + +QMainWindow::separator:horizontal { + width: 5px; + margin-top: 2px; + margin-bottom: 2px; + image: url(":/standard_light/rc/toolbar_separator_vertical.png"); +} + +QMainWindow::separator:vertical { + height: 5px; + margin-left: 2px; + margin-right: 2px; + image: url(":/standard_light/rc/toolbar_separator_horizontal.png"); +} + +/* QToolTip --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip + +--------------------------------------------------------------------------- */ +QToolTip { + background-color: #9FCBFF; + color: #19232D; + /* If you remove the border property, background stops working on Windows */ + border: none; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Remove opacity, fix #174 - may need to use RGBA */ +} + +/* QStatusBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar + +--------------------------------------------------------------------------- */ +QStatusBar { + border: 1px solid #C9CDD0; + /* Fixes Spyder #9120, #9121 */ + background: #C9CDD0; + /* Fixes #205, white vertical borders separating items */ +} + +QStatusBar::item { + border: none; +} + +QStatusBar QToolTip { + background-color: #73C7FF; + border: 1px solid #FAFAFA; + color: #FAFAFA; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Reducing transparency to read better */ + opacity: 230; +} + +QStatusBar QLabel { + /* Fixes Spyder #9120, #9121 */ + background: transparent; +} + +/* QCheckBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox + +--------------------------------------------------------------------------- */ +QCheckBox { + background-color: #FAFAFA; + color: #19232D; + spacing: 4px; + outline: none; + padding-top: 4px; + padding-bottom: 4px; +} + +QCheckBox:focus { + border: none; +} + +QCheckBox QWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QCheckBox::indicator { + margin-left: 2px; + height: 14px; + width: 14px; +} + +QCheckBox::indicator:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QCheckBox::indicator:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QCheckBox::indicator:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QCheckBox::indicator:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +QCheckBox::indicator:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QCheckBox::indicator:indeterminate:disabled { + image: url(":/standard_light/rc/checkbox_indeterminate_disabled.png"); +} + +QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +/* QGroupBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox + +--------------------------------------------------------------------------- */ +QGroupBox { + font-weight: bold; + border: 1px solid #C9CDD0; + border-radius: 4px; + padding: 2px; + margin-top: 6px; + margin-bottom: 4px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 4px; + padding-left: 2px; + padding-right: 4px; + padding-top: -4px; +} + +QGroupBox::indicator { + margin-left: 2px; + margin-top: 2px; + padding: 0; + height: 14px; + width: 14px; +} + +QGroupBox::indicator:unchecked { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QGroupBox::indicator:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QGroupBox::indicator:checked { + border: none; + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QGroupBox::indicator:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +/* QRadioButton ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton + +--------------------------------------------------------------------------- */ +QRadioButton { + background-color: #FAFAFA; + color: #19232D; + spacing: 4px; + padding-top: 4px; + padding-bottom: 4px; + border: none; + outline: none; +} + +QRadioButton:focus { + border: none; +} + +QRadioButton:disabled { + background-color: #FAFAFA; + color: #788D9C; + border: none; + outline: none; +} + +QRadioButton QWidget { + background-color: #FAFAFA; + color: #19232D; + spacing: 0px; + padding: 0px; + outline: none; + border: none; +} + +QRadioButton::indicator { + border: none; + outline: none; + margin-left: 2px; + height: 14px; + width: 14px; +} + +QRadioButton::indicator:unchecked { + image: url(":/standard_light/rc/radio_unchecked.png"); +} + +QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_unchecked_focus.png"); +} + +QRadioButton::indicator:unchecked:disabled { + image: url(":/standard_light/rc/radio_unchecked_disabled.png"); +} + +QRadioButton::indicator:checked { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked.png"); +} + +QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked_focus.png"); +} + +QRadioButton::indicator:checked:disabled { + outline: none; + image: url(":/standard_light/rc/radio_checked_disabled.png"); +} + +/* QMenuBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar + +--------------------------------------------------------------------------- */ +QMenuBar { + background-color: #C9CDD0; + padding: 2px; + border: 1px solid #FAFAFA; + color: #19232D; + selection-background-color: #73C7FF; +} + +QMenuBar:focus { + border: 1px solid #9FCBFF; +} + +QMenuBar::item { + background: transparent; + padding: 4px; +} + +QMenuBar::item:selected { + padding: 4px; + background: transparent; + border: 0px solid #C9CDD0; + background-color: #73C7FF; +} + +QMenuBar::item:pressed { + padding: 4px; + border: 0px solid #C9CDD0; + background-color: #73C7FF; + color: #19232D; + margin-bottom: 0px; + padding-bottom: 0px; +} + +/* QMenu ------------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu + +--------------------------------------------------------------------------- */ +QMenu { + border: 0px solid #C9CDD0; + color: #19232D; + margin: 0px; + background-color: #CED1D4; + selection-background-color: #73C7FF; +} + +QMenu::separator { + height: 1px; + background-color: #ACB1B6; + color: #19232D; +} + +QMenu::item { + background-color: #CED1D4; + padding: 4px 24px 4px 28px; + /* Reserve space for selection border */ + border: 1px transparent #C9CDD0; +} + +QMenu::item:selected { + color: #19232D; + background-color: #73C7FF; +} + +QMenu::item:pressed { + background-color: #73C7FF; +} + +QMenu::icon { + padding-left: 10px; + width: 14px; + height: 14px; +} + +QMenu::indicator { + padding-left: 8px; + width: 12px; + height: 12px; + /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ + /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +} + +QMenu::indicator:non-exclusive:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QMenu::indicator:non-exclusive:unchecked:hover, QMenu::indicator:non-exclusive:unchecked:focus, QMenu::indicator:non-exclusive:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QMenu::indicator:non-exclusive:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QMenu::indicator:non-exclusive:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QMenu::indicator:non-exclusive:checked:hover, QMenu::indicator:non-exclusive:checked:focus, QMenu::indicator:non-exclusive:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:disabled { + image: url(":/standard_light/rc/checkbox_indeterminate_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:focus, QMenu::indicator:non-exclusive:indeterminate:hover, QMenu::indicator:non-exclusive:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +QMenu::indicator:exclusive:unchecked { + image: url(":/standard_light/rc/radio_unchecked.png"); +} + +QMenu::indicator:exclusive:unchecked:hover, QMenu::indicator:exclusive:unchecked:focus, QMenu::indicator:exclusive:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_unchecked_focus.png"); +} + +QMenu::indicator:exclusive:unchecked:disabled { + image: url(":/standard_light/rc/radio_unchecked_disabled.png"); +} + +QMenu::indicator:exclusive:checked { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked.png"); +} + +QMenu::indicator:exclusive:checked:hover, QMenu::indicator:exclusive:checked:focus, QMenu::indicator:exclusive:checked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked_focus.png"); +} + +QMenu::indicator:exclusive:checked:disabled { + outline: none; + image: url(":/standard_light/rc/radio_checked_disabled.png"); +} + +QMenu::right-arrow { + margin: 5px; + padding-left: 12px; + image: url(":/standard_light/rc/arrow_right.png"); + height: 12px; + width: 12px; +} + +/* QAbstractItemView ------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QAbstractItemView { + alternate-background-color: #FAFAFA; + color: #19232D; + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QAbstractItemView QLineEdit { + padding: 2px; +} + +/* QAbstractScrollArea ---------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QAbstractScrollArea { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + border-radius: 4px; + /* fix #159 */ + padding: 2px; + /* remove min-height to fix #244 */ + color: #19232D; +} + +QAbstractScrollArea:disabled { + color: #788D9C; +} + +/* QScrollArea ------------------------------------------------------------ + +--------------------------------------------------------------------------- */ +QScrollArea QWidget QWidget:disabled { + background-color: #FAFAFA; +} + +/* QScrollBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar + +--------------------------------------------------------------------------- */ +QScrollBar:horizontal { + height: 16px; + margin: 2px 16px 2px 16px; + border: 1px solid #C9CDD0; + border-radius: 4px; + background-color: #FAFAFA; +} + +QScrollBar:vertical { + background-color: #FAFAFA; + width: 16px; + margin: 16px 2px 16px 2px; + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QScrollBar::handle:horizontal { + background-color: #ACB1B6; + border: 1px solid #C9CDD0; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:hover { + background-color: #9FCBFF; + border: #9FCBFF; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:focus { + border: 1px solid #73C7FF; +} + +QScrollBar::handle:vertical { + background-color: #ACB1B6; + border: 1px solid #C9CDD0; + min-height: 8px; + border-radius: 4px; +} + +QScrollBar::handle:vertical:hover { + background-color: #9FCBFF; + border: #9FCBFF; + border-radius: 4px; + min-height: 8px; +} + +QScrollBar::handle:vertical:focus { + border: 1px solid #73C7FF; +} + +QScrollBar::add-line:horizontal { + margin: 0px 0px 0px 0px; + border-image: url(":/standard_light/rc/arrow_right_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on { + border-image: url(":/standard_light/rc/arrow_right.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on { + border-image: url(":/standard_light/rc/arrow_down.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + margin: 0px 3px 0px 3px; + border-image: url(":/standard_light/rc/arrow_left_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on { + border-image: url(":/standard_light/rc/arrow_left.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_light/rc/arrow_up_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on { + border-image: url(":/standard_light/rc/arrow_up.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal { + background: none; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + background: none; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + +/* QTextEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets + +--------------------------------------------------------------------------- */ +QTextEdit { + background-color: #FAFAFA; + color: #19232D; + border-radius: 4px; + border: 1px solid #C9CDD0; +} + +QTextEdit:focus { + border: 1px solid #73C7FF; +} + +QTextEdit:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* QPlainTextEdit --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QPlainTextEdit { + background-color: #FAFAFA; + color: #19232D; + border-radius: 4px; + border: 1px solid #C9CDD0; +} + +QPlainTextEdit:focus { + border: 1px solid #73C7FF; +} + +QPlainTextEdit:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* QSizeGrip -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip + +--------------------------------------------------------------------------- */ +QSizeGrip { + background: transparent; + width: 12px; + height: 12px; + image: url(":/standard_light/rc/window_grip.png"); +} + +/* QStackedWidget --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QStackedWidget { + padding: 2px; + border: 1px solid #C9CDD0; + border: 1px solid #FAFAFA; +} + +/* QToolBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar + +--------------------------------------------------------------------------- */ +QToolBar { + background-color: #C9CDD0; + border-bottom: 1px solid #FAFAFA; + padding: 1px; + font-weight: bold; + spacing: 2px; +} + +QToolBar:disabled { + /* Fixes #272 */ + background-color: #C9CDD0; +} + +QToolBar::handle:horizontal { + width: 16px; + image: url(":/standard_light/rc/toolbar_move_horizontal.png"); +} + +QToolBar::handle:vertical { + height: 16px; + image: url(":/standard_light/rc/toolbar_move_vertical.png"); +} + +QToolBar::separator:horizontal { + width: 16px; + image: url(":/standard_light/rc/toolbar_separator_horizontal.png"); +} + +QToolBar::separator:vertical { + height: 16px; + image: url(":/standard_light/rc/toolbar_separator_vertical.png"); +} + +QToolButton#qt_toolbar_ext_button { + background: #C9CDD0; + border: 0px; + color: #19232D; + image: url(":/standard_light/rc/arrow_right.png"); +} + +/* QAbstractSpinBox ------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractSpinBox { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; + /* min-width: 5px; removed to fix 109 */ +} + +QAbstractSpinBox:up-button { + background-color: transparent #FAFAFA; + subcontrol-origin: border; + subcontrol-position: top right; + border-left: 1px solid #C9CDD0; + border-bottom: 1px solid #C9CDD0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-bottom: -1px; +} + +QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off { + image: url(":/standard_light/rc/arrow_up_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::up-arrow:hover { + image: url(":/standard_light/rc/arrow_up.png"); +} + +QAbstractSpinBox:down-button { + background-color: transparent #FAFAFA; + subcontrol-origin: border; + subcontrol-position: bottom right; + border-left: 1px solid #C9CDD0; + border-top: 1px solid #C9CDD0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-top: -1px; +} + +QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::down-arrow:hover { + image: url(":/standard_light/rc/arrow_down.png"); +} + +QAbstractSpinBox:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QAbstractSpinBox:focus { + border: 1px solid #73C7FF; +} + +QAbstractSpinBox:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* ------------------------------------------------------------------------ */ +/* DISPLAYS --------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QLabel ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe + +--------------------------------------------------------------------------- */ +QLabel { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + padding: 2px; + margin: 0px; + color: #19232D; +} + +QLabel:disabled { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + color: #788D9C; +} + +/* QTextBrowser ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QTextBrowser { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; +} + +QTextBrowser:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; +} + +QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed { + border: 1px solid #C9CDD0; +} + +/* QGraphicsView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QGraphicsView { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; +} + +QGraphicsView:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; +} + +QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed { + border: 1px solid #C9CDD0; +} + +/* QCalendarWidget -------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCalendarWidget { + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QCalendarWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +/* QLCDNumber ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QLCDNumber { + background-color: #FAFAFA; + color: #19232D; +} + +QLCDNumber:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +/* QProgressBar ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar + +--------------------------------------------------------------------------- */ +QProgressBar { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; + text-align: center; +} + +QProgressBar:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #9FCBFF; + color: #FAFAFA; + border-radius: 4px; +} + +QProgressBar::chunk:disabled { + background-color: #DAEDFF; + color: #788D9C; + border-radius: 4px; +} + +/* ------------------------------------------------------------------------ */ +/* BUTTONS ---------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QPushButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton + +--------------------------------------------------------------------------- */ +QPushButton { + background-color: #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; +} + +QPushButton:disabled { + background-color: #C9CDD0; + color: #788D9C; + border-radius: 4px; + padding: 2px; +} + +QPushButton:checked { + background-color: #ACB1B6; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:disabled { + background-color: #ACB1B6; + color: #788D9C; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:selected { + background: #ACB1B6; +} + +QPushButton:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QPushButton:pressed { + background-color: #ACB1B6; +} + +QPushButton:selected { + background: #ACB1B6; + color: #19232D; +} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + bottom: 4px; +} + +QDialogButtonBox QPushButton { + /* Issue #194 #248 - Special case of QPushButton inside dialogs, for better UI */ + min-width: 80px; +} + +/* QToolButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton + +--------------------------------------------------------------------------- */ +QToolButton { + background-color: #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; + /* The subcontrols below are used only in the DelayedPopup mode */ + /* The subcontrols below are used only in the MenuButtonPopup mode */ + /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +} + +QToolButton:disabled { + background-color: #C9CDD0; + color: #788D9C; + border-radius: 4px; + padding: 2px; +} + +QToolButton:checked { + background-color: #ACB1B6; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:disabled { + background-color: #ACB1B6; + color: #788D9C; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QToolButton:checked:pressed { + background-color: #ACB1B6; +} + +QToolButton:checked:selected { + background: #ACB1B6; + color: #19232D; +} + +QToolButton:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QToolButton:pressed { + background-color: #ACB1B6; +} + +QToolButton:selected { + background: #ACB1B6; + color: #19232D; +} + +QToolButton[popupMode="0"] { + /* Only for DelayedPopup */ + padding-right: 2px; +} + +QToolButton[popupMode="1"] { + /* Only for MenuButtonPopup */ + padding-right: 20px; +} + +QToolButton[popupMode="1"]::menu-button { + border: none; +} + +QToolButton[popupMode="1"]::menu-button:hover { + border: none; + border-left: 1px solid #C9CDD0; + border-radius: 0; +} + +QToolButton[popupMode="2"] { + /* Only for InstantPopup */ + padding-right: 2px; +} + +QToolButton::menu-button { + padding: 2px; + border-radius: 4px; + width: 12px; + border: none; + outline: none; +} + +QToolButton::menu-button:hover { + border: 1px solid #9FCBFF; +} + +QToolButton::menu-button:checked:hover { + border: 1px solid #9FCBFF; +} + +QToolButton::menu-indicator { + image: url(":/standard_light/rc/arrow_down.png"); + height: 8px; + width: 8px; + top: 0; + /* Exclude a shift for better image */ + left: -2px; + /* Shift it a bit */ +} + +QToolButton::menu-arrow { + image: url(":/standard_light/rc/arrow_down.png"); + height: 8px; + width: 8px; +} + +QToolButton::menu-arrow:hover { + image: url(":/standard_light/rc/arrow_down_focus.png"); +} + +/* QCommandLinkButton ----------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCommandLinkButton { + background-color: transparent; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 0px; + margin: 0px; +} + +QCommandLinkButton:disabled { + background-color: transparent; + color: #788D9C; +} + +/* ------------------------------------------------------------------------ */ +/* INPUTS - NO FIELDS ----------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QComboBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QComboBox { + border: 1px solid #C9CDD0; + border-radius: 4px; + selection-background-color: #9FCBFF; + padding-left: 4px; + padding-right: 4px; + /* padding-right = 36; 4 + 16*2 See scrollbar size */ + /* changed to 4px to fix #239 */ + /* Fixes #103, #111 */ + min-height: 1.5em; + /* padding-top: 2px; removed to fix #132 */ + /* padding-bottom: 2px; removed to fix #132 */ + /* min-width: 75px; removed to fix #109 */ + /* Needed to remove indicator - fix #132 */ +} + +QComboBox QAbstractItemView { + border: 1px solid #C9CDD0; + border-radius: 0; + background-color: #FAFAFA; + selection-background-color: #9FCBFF; +} + +QComboBox QAbstractItemView:hover { + background-color: #FAFAFA; + color: #19232D; +} + +QComboBox QAbstractItemView:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +QComboBox QAbstractItemView:alternate { + background: #FAFAFA; +} + +QComboBox:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QComboBox:hover { + border: 1px solid #9FCBFF; +} + +QComboBox:focus { + border: 1px solid #73C7FF; +} + +QComboBox:on { + selection-background-color: #9FCBFF; +} + +QComboBox::indicator { + border: none; + border-radius: 0; + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + /* Needed to remove indicator - fix #132 */ +} + +QComboBox::indicator:alternate { + background: #FAFAFA; +} + +QComboBox::item:alternate { + background: #FAFAFA; +} + +QComboBox::item:checked { + font-weight: bold; +} + +QComboBox::item:selected { + border: 0px solid transparent; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #C9CDD0; +} + +QComboBox::down-arrow { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus { + image: url(":/standard_light/rc/arrow_down.png"); +} + +/* QSlider ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider + +--------------------------------------------------------------------------- */ +QSlider:disabled { + background: #FAFAFA; +} + +QSlider:focus { + border: none; +} + +QSlider::groove:horizontal { + background: #C9CDD0; + border: 1px solid #C9CDD0; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::groove:vertical { + background: #C9CDD0; + border: 1px solid #C9CDD0; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical { + background: #9FCBFF; + border: 1px solid #C9CDD0; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical :disabled { + background: #DAEDFF; +} + +QSlider::sub-page:horizontal { + background: #9FCBFF; + border: 1px solid #C9CDD0; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { + background: #DAEDFF; +} + +QSlider::handle:horizontal { + background: #788D9C; + border: 1px solid #C9CDD0; + width: 8px; + height: 8px; + margin: -8px 0px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: #9FCBFF; + border: 1px solid #9FCBFF; +} + +QSlider::handle:horizontal:focus { + border: 1px solid #73C7FF; +} + +QSlider::handle:vertical { + background: #788D9C; + border: 1px solid #C9CDD0; + width: 8px; + height: 8px; + margin: 0 -8px; + border-radius: 4px; +} + +QSlider::handle:vertical:hover { + background: #9FCBFF; + border: 1px solid #9FCBFF; +} + +QSlider::handle:vertical:focus { + border: 1px solid #73C7FF; +} + +/* QLineEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit + +--------------------------------------------------------------------------- */ +QLineEdit { + background-color: #FAFAFA; + padding-top: 2px; + /* This QLineEdit fix 103, 111 */ + padding-bottom: 2px; + /* This QLineEdit fix 103, 111 */ + padding-left: 4px; + padding-right: 4px; + border-style: solid; + border: 1px solid #C9CDD0; + border-radius: 4px; + color: #19232D; +} + +QLineEdit:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QLineEdit:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QLineEdit:focus { + border: 1px solid #73C7FF; +} + +QLineEdit:selected { + background-color: #9FCBFF; + color: #C9CDD0; +} + +/* QTabWiget -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabWidget { + padding: 2px; + selection-background-color: #C9CDD0; +} + +QTabWidget QWidget { + /* Fixes #189 */ + border-radius: 4px; +} + +QTabWidget::pane { + border: 1px solid #C9CDD0; + border-radius: 4px; + margin: 0px; + /* Fixes double border inside pane with pyqt5 */ + padding: 0px; +} + +QTabWidget::pane:selected { + background-color: #C9CDD0; + border: 1px solid #9FCBFF; +} + +/* QTabBar ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabBar, QDockWidget QTabBar { + qproperty-drawBase: 0; + border-radius: 4px; + margin: 0px; + padding: 2px; + border: 0; + /* left: 5px; move to the right by 5px - removed for fix */ +} + +QTabBar::close-button, QDockWidget QTabBar::close-button { + border: 0; + margin: 0; + padding: 4px; + image: url(":/standard_light/rc/window_close.png"); +} + +QTabBar::close-button:hover, QDockWidget QTabBar::close-button:hover { + image: url(":/standard_light/rc/window_close_focus.png"); +} + +QTabBar::close-button:pressed, QDockWidget QTabBar::close-button:pressed { + image: url(":/standard_light/rc/window_close_pressed.png"); +} + +QTabBar::tab, QDockWidget QTabBar::tab { + /* !selected and disabled ----------------------------------------- */ + /* selected ------------------------------------------------------- */ +} + +QTabBar::tab:top:selected:disabled, QDockWidget QTabBar::tab:top:selected:disabled { + border-bottom: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:bottom:selected:disabled, QDockWidget QTabBar::tab:bottom:selected:disabled { + border-top: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:left:selected:disabled, QDockWidget QTabBar::tab:left:selected:disabled { + border-right: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:right:selected:disabled, QDockWidget QTabBar::tab:right:selected:disabled { + border-left: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:top:!selected:disabled, QDockWidget QTabBar::tab:top:!selected:disabled { + border-bottom: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:bottom:!selected:disabled, QDockWidget QTabBar::tab:bottom:!selected:disabled { + border-top: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:left:!selected:disabled, QDockWidget QTabBar::tab:left:!selected:disabled { + border-right: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:right:!selected:disabled, QDockWidget QTabBar::tab:right:!selected:disabled { + border-left: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:top:!selected, QDockWidget QTabBar::tab:top:!selected { + border-bottom: 2px solid #FAFAFA; + margin-top: 2px; +} + +QTabBar::tab:bottom:!selected, QDockWidget QTabBar::tab:bottom:!selected { + border-top: 2px solid #FAFAFA; + margin-bottom: 2px; +} + +QTabBar::tab:left:!selected, QDockWidget QTabBar::tab:left:!selected { + border-left: 2px solid #FAFAFA; + margin-right: 2px; +} + +QTabBar::tab:right:!selected, QDockWidget QTabBar::tab:right:!selected { + border-right: 2px solid #FAFAFA; + margin-left: 2px; +} + +QTabBar::tab:top, QDockWidget QTabBar::tab:top { + background-color: #C9CDD0; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + min-width: 5px; + border-bottom: 3px solid #C9CDD0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:selected, QDockWidget QTabBar::tab:top:selected { + background-color: #B9BDC1; + border-bottom: 3px solid #37AEFE; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:!selected:hover, QDockWidget QTabBar::tab:top:!selected:hover { + border: 1px solid #73C7FF; + border-bottom: 3px solid #73C7FF; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:bottom, QDockWidget QTabBar::tab:bottom { + border-top: 3px solid #C9CDD0; + background-color: #C9CDD0; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + min-width: 5px; +} + +QTabBar::tab:bottom:selected, QDockWidget QTabBar::tab:bottom:selected { + background-color: #B9BDC1; + border-top: 3px solid #37AEFE; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabBar::tab:bottom:!selected:hover, QDockWidget QTabBar::tab:bottom:!selected:hover { + border: 1px solid #73C7FF; + border-top: 3px solid #73C7FF; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:left, QDockWidget QTabBar::tab:left { + background-color: #C9CDD0; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:left:selected, QDockWidget QTabBar::tab:left:selected { + background-color: #B9BDC1; + border-right: 3px solid #37AEFE; +} + +QTabBar::tab:left:!selected:hover, QDockWidget QTabBar::tab:left:!selected:hover { + border: 1px solid #73C7FF; + border-right: 3px solid #73C7FF; + /* Fixes different behavior #271 */ + margin-right: 0px; + padding-right: -1px; +} + +QTabBar::tab:right, QDockWidget QTabBar::tab:right { + background-color: #C9CDD0; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:right:selected, QDockWidget QTabBar::tab:right:selected { + background-color: #B9BDC1; + border-left: 3px solid #37AEFE; +} + +QTabBar::tab:right:!selected:hover, QDockWidget QTabBar::tab:right:!selected:hover { + border: 1px solid #73C7FF; + border-left: 3px solid #73C7FF; + /* Fixes different behavior #271 */ + margin-left: 0px; + padding-left: 0px; +} + +QTabBar QToolButton, QDockWidget QTabBar QToolButton { + /* Fixes #136 */ + background-color: #C9CDD0; + height: 12px; + width: 12px; +} + +QTabBar QToolButton:pressed, QDockWidget QTabBar QToolButton:pressed { + background-color: #C9CDD0; +} + +QTabBar QToolButton:pressed:hover, QDockWidget QTabBar QToolButton:pressed:hover { + border: 1px solid #9FCBFF; +} + +QTabBar QToolButton::left-arrow:enabled, QDockWidget QTabBar QToolButton::left-arrow:enabled { + image: url(":/standard_light/rc/arrow_left.png"); +} + +QTabBar QToolButton::left-arrow:disabled, QDockWidget QTabBar QToolButton::left-arrow:disabled { + image: url(":/standard_light/rc/arrow_left_disabled.png"); +} + +QTabBar QToolButton::right-arrow:enabled, QDockWidget QTabBar QToolButton::right-arrow:enabled { + image: url(":/standard_light/rc/arrow_right.png"); +} + +QTabBar QToolButton::right-arrow:disabled, QDockWidget QTabBar QToolButton::right-arrow:disabled { + image: url(":/standard_light/rc/arrow_right_disabled.png"); +} + +/* QDockWiget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QDockWidget { + outline: 1px solid #C9CDD0; + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + border-radius: 4px; + titlebar-close-icon: url(":/standard_light/rc/transparent.png"); + titlebar-normal-icon: url(":/standard_light/rc/transparent.png"); +} + +QDockWidget::title { + /* Better size for title bar */ + padding: 3px; + spacing: 4px; + border: none; + background-color: #C9CDD0; +} + +QDockWidget::close-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_light/rc/window_close.png"); +} + +QDockWidget::close-button:hover { + image: url(":/standard_light/rc/window_close_focus.png"); +} + +QDockWidget::close-button:pressed { + image: url(":/standard_light/rc/window_close_pressed.png"); +} + +QDockWidget::float-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_light/rc/window_undock.png"); +} + +QDockWidget::float-button:hover { + image: url(":/standard_light/rc/window_undock_focus.png"); +} + +QDockWidget::float-button:pressed { + image: url(":/standard_light/rc/window_undock_pressed.png"); +} + +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/standard_light/rc/transparent.png"); +} + +QTreeView:branch:has-siblings:!adjoins-item { + border-image: url(":/standard_light/rc/branch_line.png") 0; +} + +QTreeView:branch:has-siblings:adjoins-item { + border-image: url(":/standard_light/rc/branch_more.png") 0; +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item { + border-image: url(":/standard_light/rc/branch_end.png") 0; +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked, +QListView::indicator:checked, +QTableView::indicator:checked, +QColumnView::indicator:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed, +QListView::indicator:checked:hover, +QListView::indicator:checked:focus, +QListView::indicator:checked:pressed, +QTableView::indicator:checked:hover, +QTableView::indicator:checked:focus, +QTableView::indicator:checked:pressed, +QColumnView::indicator:checked:hover, +QColumnView::indicator:checked:focus, +QColumnView::indicator:checked:pressed { + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked, +QListView::indicator:unchecked, +QTableView::indicator:unchecked, +QColumnView::indicator:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed, +QListView::indicator:unchecked:hover, +QListView::indicator:unchecked:focus, +QListView::indicator:unchecked:pressed, +QTableView::indicator:unchecked:hover, +QTableView::indicator:unchecked:focus, +QTableView::indicator:unchecked:pressed, +QColumnView::indicator:unchecked:hover, +QColumnView::indicator:unchecked:focus, +QColumnView::indicator:unchecked:pressed { + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QTreeView::indicator:indeterminate, +QListView::indicator:indeterminate, +QTableView::indicator:indeterminate, +QColumnView::indicator:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed, +QListView::indicator:indeterminate:hover, +QListView::indicator:indeterminate:focus, +QListView::indicator:indeterminate:pressed, +QTableView::indicator:indeterminate:hover, +QTableView::indicator:indeterminate:focus, +QTableView::indicator:indeterminate:pressed, +QColumnView::indicator:indeterminate:hover, +QColumnView::indicator:indeterminate:focus, +QColumnView::indicator:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + gridline-color: #C9CDD0; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #9FCBFF; + color: #C9CDD0; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #73C7FF; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #9FCBFF; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #9FCBFF; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #19232D; + background-color: #CED1D4; +} + +QTableCornerButton::section { + background-color: #FAFAFA; + border: 1px transparent #C9CDD0; + border-radius: 0px; +} + +/* QHeaderView ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview + +--------------------------------------------------------------------------- */ +QHeaderView { + background-color: #C9CDD0; + border: 0px transparent #C9CDD0; + padding: 0; + margin: 0; + border-radius: 0; +} + +QHeaderView:disabled { + background-color: #C9CDD0; + border: 1px transparent #C9CDD0; +} + +QHeaderView::section { + background-color: #C9CDD0; + color: #19232D; + border-radius: 0; + text-align: left; + font-size: 13px; +} + +QHeaderView::section::horizontal { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-left: 1px solid #FAFAFA; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one { + border-left: 1px solid #C9CDD0; +} + +QHeaderView::section::horizontal:disabled { + color: #788D9C; +} + +QHeaderView::section::vertical { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-top: 1px solid #FAFAFA; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one { + border-top: 1px solid #C9CDD0; +} + +QHeaderView::section::vertical:disabled { + color: #788D9C; +} + +QHeaderView::down-arrow { + /* Those settings (border/width/height/background-color) solve bug */ + /* transparent arrow background and size */ + background-color: #C9CDD0; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_light/rc/arrow_down.png"); +} + +QHeaderView::up-arrow { + background-color: #C9CDD0; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_light/rc/arrow_up.png"); +} + +/* QToolBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox + +--------------------------------------------------------------------------- */ +QToolBox { + padding: 0px; + border: 0px; + border: 1px solid #C9CDD0; +} + +QToolBox:selected { + padding: 0px; + border: 2px solid #9FCBFF; +} + +QToolBox::tab { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QToolBox::tab:disabled { + color: #788D9C; +} + +QToolBox::tab:selected { + background-color: #ACB1B6; + border-bottom: 2px solid #9FCBFF; +} + +QToolBox::tab:selected:disabled { + background-color: #C9CDD0; + border-bottom: 2px solid #DAEDFF; +} + +QToolBox::tab:!selected { + background-color: #C9CDD0; + border-bottom: 2px solid #C9CDD0; +} + +QToolBox::tab:!selected:disabled { + background-color: #FAFAFA; +} + +QToolBox::tab:hover { + border-color: #73C7FF; + border-bottom: 2px solid #73C7FF; +} + +QToolBox QScrollArea QWidget QWidget { + padding: 0px; + border: 0px; + background-color: #FAFAFA; +} + +/* QFrame ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe +https://doc.qt.io/qt-5/qframe.html#-prop +https://doc.qt.io/qt-5/qframe.html#details +https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color + +--------------------------------------------------------------------------- */ +/* (dot) .QFrame fix #141, #126, #123 */ +.QFrame { + border-radius: 4px; + border: 1px solid #C9CDD0; + /* No frame */ + /* HLine */ + /* HLine */ +} + +.QFrame[frameShape="0"] { + border-radius: 4px; + border: 1px transparent #C9CDD0; +} + +.QFrame[frameShape="4"] { + max-height: 2px; + border: none; + background-color: #C9CDD0; +} + +.QFrame[frameShape="5"] { + max-width: 2px; + border: none; + background-color: #C9CDD0; +} + +/* QSplitter -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter + +--------------------------------------------------------------------------- */ +QSplitter { + background-color: #C9CDD0; + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QSplitter::handle { + background-color: #C9CDD0; + border: 0px solid #FAFAFA; + spacing: 0px; + padding: 1px; + margin: 0px; +} + +QSplitter::handle:hover { + background-color: #788D9C; +} + +QSplitter::handle:horizontal { + width: 5px; + image: url(":/standard_light/rc/line_vertical.png"); +} + +QSplitter::handle:vertical { + height: 5px; + image: url(":/standard_light/rc/line_horizontal.png"); +} + +/* QDateEdit, QDateTimeEdit ----------------------------------------------- + +--------------------------------------------------------------------------- */ +QDateEdit, QDateTimeEdit { + selection-background-color: #9FCBFF; + border-style: solid; + border: 1px solid #C9CDD0; + border-radius: 4px; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + min-width: 10px; +} + +QDateEdit:on, QDateTimeEdit:on { + selection-background-color: #9FCBFF; +} + +QDateEdit::drop-down, QDateTimeEdit::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #C9CDD0; +} + +QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus { + image: url(":/standard_light/rc/arrow_down.png"); +} + +QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView { + background-color: #FAFAFA; + border-radius: 4px; + border: 1px solid #C9CDD0; + selection-background-color: #9FCBFF; +} + +/* QAbstractView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractView:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QAbstractView:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* PlotWidget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +PlotWidget { + /* Fix cut labels in plots #134 */ + padding: 0px; +} + +/**********************************/ +/* RetroShare specific part */ +/**********************************/ + +/**** Fix QTreeView Items ****/ + +QTreeView::item, +QListView::item, +QTableView::item, +QColumnView::item { + color: #101010; + background: transparent; +} +QTreeView:branch:!selected:hover, +QTreeView:branch:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +/**** Fix QSplitter ****/ + +QSplitter { + background-color: white; +} + +QSplitter::handle { + background-color: #C9CDD0; + border: 0px solid #C9CDD0; + border-radius: 4px; +} + + +/**** Standard rules ****/ + +QFrame[objectName^="feedFrame"],/* Frame used in Feeds*/ +QFrame[objectName^="plainFrame"],/* Frame used in Widget with plain background*/ +QFrame[objectName^="plainBFrame"] {/* Frame used in Widget with plain bordered background*/ + background-color: white; +} +QFrame[objectName^="plainBFrame"] { + border: 1px solid #CCCCCC; +} + +/* Frame used in old Feeds*/ +QFrame#feedFrame[new=false] { + background-color: #white; +} +/* Frame used in new Feeds*/ +QFrame#feedFrame[new=true] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); +} +QFrame#feedFrame QLabel { + background: transparent; +} + +QFrame[objectName^="gradFrame"],/* Frame used in Widget with gradient colored background*/ +QFrame#bottomFrame,/* Frame used at the bottom of dialog*/ +QFrame#toasterFrame,/* Frame used in Toasters*/ +QFrame#toolBarFrame {/* Frame used for buttons*/ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); + border: 1px solid #CCCCCC; +} +QFrame#toolBarFrame > LineEditClear { + background-color: white; +} +QFrame[objectName^="gradFrame"] QComboBox, +QFrame[objectName^="gradFrame"] QLineEdit, +QFrame[objectName^="gradFrame"] QTextEdit { + background-color: white; +} +QFrame[objectName^="gradFrame"] QComboBox QAbstractItemView { + background-color: #CCCCCC; + selection-background-color: #1464A0; +} + +QLabel#avatarLabel{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} + + +/* HeaderFrame & TitleBarFrame */ + +QFrame[objectName^="headerFrame"], +QFrame[objectName^="headerBFrame"], +QToolBar#headerToolBar, +QFrame#titleBarFrame { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 0px; +} +QFrame[objectName^="#headerBFrame"] { + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover, +QFrame#titleBarFrame > *:!hover { + background: transparent; + color: white; +} +QFrame#titleBarFrame QComboBox, +QFrame#titleBarFrame QLineEdit, +QFrame#titleBarFrame QTextEdit { + background: white; +} + +/**** Special Page tweak ****/ + + +/* ConnectFriendWizard */ + +ConnectFriendWizard QPlainTextEdit#friendCertEdit { + border: none; + background: white; + color: black; +} + +ConnectFriendWizard QFrame#friendFrame { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; +} + +ConnectFriendWizard QWizardPage#ConclusionPage > QGroupBox#peerDetailsFrame { + border: 2px solid #039bd5; + border-radius:6px; + background: white; + color: black; + padding: 12 12px; +} + +ConnectFriendWizard QGroupBox::title#peerDetailsFrame +{ + padding: 4 12px; + background: transparent; + padding: 4 12px; + background: #039bd5; + color: white; +} + + +/* GetStartedDialog */ + +GetStartedDialog QTextEdit { + border: 1px solid #B8B6B1; + border-radius: 6px; + background: white; + color: black; +} + + +/* HomePage */ + +HomePage QLabel#userCertLabel { + color: #0099cc; +} + + +/* Chat lobby */ + +ChatLobbyWidget QGroupBox#lobbyinfo_groupBox +{ + color: black; + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + border-radius: 6px; + border: 1px solid #CCCCCC; + + padding: 14 6px; + +} +ChatLobbyWidget QGroupBox#lobbyinfo_groupBox > QLabel +{ + color: black;/*Needed for white font system*/ +} + +ChatLobbyWidget QGroupBox::title#lobbyinfo_groupBox +{ + padding: 4 12px; + background: #039bd5; + color: white; +} + +ChatLobbyDialog QListWidget#participantsList { + border: 1px solid #B8B6B1; + border-radius: 6px; + background: white; + color: black; +} + +CreateLobbyDialog QFrame#roomFrame { + border: 2px solid #CCCCCC; + border-radius:6px; + background: white; +} + +ChatWidget QTextEdit#chatTextEdit, +ChatWidget QTextBrowser#textBrowser { + border: 1px solid #0099cc; + border-radius: 6px; + background: white; + color: black; +} + + +/* MessagesDialog */ + +MessagesDialog QWidget#messageTreeWidget::item { + padding: 2px; +} + +MessagesDialog QWidget#messageTreeWidget::item:selected { + background-color: #cde8ff; + color: black; +} + +MessagesDialog QWidget#messageTreeWidget::item:hover { + background-color: #e5f3ff; + color: black; +} + + +/* Forums */ + +GxsForumThreadWidget QWidget#threadTreeWidget { + selection-background-color: #cde8ff; + show-decoration-selected: 1; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item { + padding: 2px; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { + background-color: #cde8ff; +} + +/* GxsCreateCommentDialog */ + +GxsCreateCommentDialog QTextEdit#commentTextEdit { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; + color: black;/*Needed for white font system*/ +} + + +/* GxsCommentDialog */ + +GxsCommentDialog QComboBox#sortBox { + color: #0099cc; +} + + +/* GxsGroupDialog */ + +GxsGroupDialog QLabel#groupLogo{ + border: 2px solid #CCCCCC; + border-radius: 3px; +} + + +/* Settings */ + +PluginItem > QFrame#pluginFrame { + border: 2px solid #A8B8D1; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FCFDFE, stop: 1 #E2E8EF); + border-radius: 0px +} +PluginItem QLabel#infoLabel { + color: #054A02; +} + + +/* Feeds */ + +AttachFileItem > QFrame#frame { + border: 2px solid black; + background: white; +} + +GxsChannelPostItem QLabel#newLabel{ + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; + color: white; +} +GxsChannelPostItem QFrame#msgFrame { + border: 2px solid #82B9F4; + border-radius: 3px; +} +GxsChannelPostItem QLabel#logoLabel { + border: 2px solid #D3D3D3; + background-color: black; +} + +SubFileItem QProgressBar#progressBar { + border: 1px solid black; + text-align: center; + color: white; + padding: 1px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fff, stop: 0.4999 #eee, stop: 0.5 #ddd, stop: 1 #eee); + min-width: 15px; +} +SubFileItem QProgressBar#progressBar::chunk { + background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #78d, stop: 0.4999 #46a, stop: 0.5 #45a, stop: 1 #238); + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + border: 1px solid black; + min-width: 15px; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 20, 20, 20, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background: #32CD32; + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background: #CD3232; + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background: #32CD32; + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background: #CD3232; + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_compact QLabel#pictureLabel { + border: 2px solid #CCCCCC; + border-radius: 3px; +} + +PostedListWidgetWithModel QComboBox#sortStrategy_CB { + color: #0099cc; +} + +PostedListWidgetWithModel QTextBrowser#infoDescription { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_compact QLabel#fromBoldLabel, +BoardPostDisplayWidget_compact QLabel#fromLabel, +BoardPostDisplayWidget_compact QLabel#dateLabel, +BoardPostDisplayWidget_compact QLabel#siteBoldLabel, +BoardPostDisplayWidget_card QLabel#fromBoldLabel, +BoardPostDisplayWidget_card QLabel#fromLabel, +BoardPostDisplayWidget_card QLabel#dateLabel, +BoardPostDisplayWidget_card QLabel#siteBoldLabel { + color: #787c7e; +} + + +/* MessengerWindow */ + +MessengerWindow QFrame#messengerframetop{ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 0px; +} + + +/*************** Optional ***************/ + +/**** WikiPoos ****/ +WikiEditDialog QPushButton#pushButton_History { + color: white; + background: #5bb62b; + border-radius: 4px; + max-height: 20px; + min-width: 4em; + padding: 2px; + padding-left: 6px; + padding-right: 6px; +} + +WikiEditDialog QPushButton#pushButton_History:hover { + background: #57af29; +} + + +/**** The Wire ****/ + +WireGroupItem QFrame#wire_frame:hover { + background-color: #7ecbfb; +} +WireGroupItem QFrame#wire_frame > QLabel { + color: black; +} + +PulseTopLevel QFrame#plainFrame, +PulseViewGroup QFrame#plainFrame, +PulseReply QFrame#plainFrame { + border: 2px solid #c4cfd6; + background: white; +} + +PulseAddDialog QTextEdit#textEdit_Pulse { + border: 2px solid #c4cfd6; + border-radius: 6px; + background: white; + color: black; +} + +PulseReply #line_replyLine, +PulseMessage #line{ + color: #c4cfd6; +} + +PulseReply QLabel#label_groupName{ + color: #5b7083; +} + +/**** PhotoShare ****/ +AlbumItem QFrame#albumFrame { + border: 2px solid #CCCCCC; + border-radius: 10px +} + +PhotoItem QFrame#photoFrame { + border: 2px solid #CCCCCC; + border-radius: 10px +} + +PhotoItem QWidget:hover { + background-color: #7ecbfb; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/default.qss b/retroshare-gui/src/gui/qss/stylesheet/default.qss new file mode 100644 index 000000000..d1730bfef --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/default.qss @@ -0,0 +1,420 @@ +/* Default stylesheet + This file is used as default for all stylesheets and can be overloaded + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + https://doc.qt.io/qt-5/stylesheet-syntax.html + */ + +/**** Standard rules ****/ + +/* Transparent background objects = name starting by trans_*/ +QObject[objectName^="trans_"] { + background: transparent; +} +/* Specific for scrollarea contents */ +QScrollArea[objectName^="trans_"] > QWidget > QWidget { + background: transparent; +} + +/* Informatives background objects = name starting by info*/ +QObject[objectName^="info_"]:enabled {/*enabled is needed for not be overrided :https://doc.qt.io/qt-5/stylesheet-syntax.html#conflict-resolution*/ + color: black; + border: 1px solid #DCDC41; + border-radius: 6px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); +} +/* For label inside informative frame */ +QFrame[objectName^="info_"] > QLabel +{ + color: black; + background: transparent; +} + +/* Specifics Buttons */ +QPushButton#applyButton:enabled,/*enabled is needed for not be overrided :https://doc.qt.io/qt-5/stylesheet-syntax.html#conflict-resolution*/ +QPushButton#createButton:enabled, +QPushButton#postButton:enabled, +QToolButton#addButton:enabled, +QToolButton#followButton:enabled { + color: white; + background: #0099cc; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ + min-width: 4em; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#applyButton:disabled, +QPushButton#createButton:disabled, +QPushButton#postButton:disabled, +QToolButton#addButton:disabled, +QToolButton#followButton:disabled { + color: white; + background: #d40000; + border-radius: 4px; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#applyButton:hover, +QPushButton#createButton:hover, +QPushButton#postButton:hover, +QToolButton#addButton:hover, +QToolButton#followButton:hover { + color: white; + background: #03b1f3; + border-radius: 4px; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#searchButton:enabled, +QPushButton#addButton:enabled { + color: white; + background: #32CD32; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ + min-width: 4em; + padding: 4px; +} + +QPushButton#searchButton:hover, +QPushButton#addButton:hover { + color: white; + background: #5AD75A; + border-radius: 4px; + padding: 4px; +} + +QToolButton#subscribeToolButton:enabled { + color: white; + background: #0099cc; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ +} + +QToolButton#subscribeToolButton:disabled { + background: gray; + border-radius: 4px; + border: 1px solid gray; + color: lightgray; +} + +QToolButton#subscribeToolButton:hover { + background: #03b1f3; + border-radius: 4px; +} + +QToolButton#subscribeToolButton:pressed { + background: #03b1f3; + border-radius: 4px; + border: 1px solid gray; +} + +QToolButton#subscribeToolButton[popupMode="1"]{ + padding-right: 0px; +} + +QToolButton#subscribeToolButton::menu-arrow{ + image: none; +} + +QToolButton#subscribeToolButton::menu-button{ + image: none; +} + + +QLabel#newLabel:enabled { + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; + color: black; +} + + +/* StartDialog + To get the same style for all user and not use last connected one. */ + +StartDialog QFrame#loginframe{ + border-image: url(:/images/logo/background_lessblue.png) 0 0 0 0 stretch stretch; + border-width: 0px; +} +StartDialog QFrame#loginframe QCheckBox, +StartDialog QFrame#loginframe QLabel { + background: transparent; +} +StartDialog QGroupBox#profilGBox { + background: rgba(0,0,0,10%); + border-radius: 3px; + border-width: 0px; +} + +StartDialog QGroupBox#profilGBox * { + background-color: white; + color: black; +} + +StartDialog QPushButton#loadButton { + background: transparent; + border-image: url(:/images/btn_blue.png) 4; + border-width: 4; + color: white; +} +StartDialog QPushButton#loadButton:hover { + background: transparent; + border-image: url(:/images/btn_blue_hover.png) 4; +} + + + +/* GenCertDialog + Change colors here because GUI is not started yet so no user StyleSheet loads */ + +GenCertDialog QFrame#profileframe{ + border-image: url(:/images/logo/background.png) 0 0 0 0 stretch stretch; + border-width: 0px; +} +GenCertDialog QFrame#profileframe QCheckBox, +GenCertDialog QFrame#profileframe QLabel { + background: transparent; +} + +GenCertDialog QLabel#info_Label:enabled { + color: black; + border: 1px solid #DCDC41; + border-radius: 6px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); +} + +GenCertDialog QGroupBox#groupBox, +GenCertDialog QGroupBox#profile_groupBox { + background: rgba(0,0,0,10%); +} +GenCertDialog QGroupBox#profile_groupBox QComboBox, +GenCertDialog QGroupBox#profile_groupBox QSpinBox, +GenCertDialog QGroupBox#profile_groupBox QLineEdit, +GenCertDialog QComboBox#genPGPuser { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; + color: black; +} + +GenCertDialog QPushButton#genButton { + border-image: url(:/images/btn_blue.png) 4; + border-width: 4; + color: white; +} +GenCertDialog QPushButton#genButton:hover { + border-image: url(:/images/btn_blue_hover.png) 4; +} +GenCertDialog QPushButton#genButton:disabled { + border-image: url(:/images/btn_27.png) 4; + color: black; +} + + +/* AvatarWidget */ + +AvatarWidget{border-width: 10px;} +AvatarWidget[frameState="NORMAL"]{border-image:url(:/images/avatarstatus-bg-116.png);} +AvatarWidget[frameState="OFFLINE"]{border-image:url(:/images/avatarstatus-bg-offline-116.png);} +AvatarWidget[frameState="INACTIVE"]{border-image:url(:/images/avatarstatus-bg-idle-116.png);} +AvatarWidget[frameState="ONLINE"]{border-image:url(:/images/avatarstatus-bg-online-116.png);} +AvatarWidget[frameState="AWAY"]{border-image:url(:/images/avatarstatus-bg-away-116.png);} +AvatarWidget[frameState="BUSY"]{border-image:url(:/images/avatarstatus-bg-busy-116.png);} + + +/* ConnectFriendWizard */ + +ConnectFriendWizard { +/* QWizard cannot be resized horizontal when banner pixmap is set + qproperty-bannerPixmap: url(:/images/connect/connectFriendBanner1.png);*/ + qproperty-titleFontSize: 16; + qproperty-titleFontWeight: 500; +/* qproperty-titleColor: white; */ +} + + +/* GxsChannelFilesStatusWidget */ + +GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { + padding-right: 0px; +} + +GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { + image: none; +} + + +/* Forums */ + +GxsForumThreadWidget QLabel#forumName +{ + color: #0099cc; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 20, 20, 20, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background: rgba(50,205,50,50%); + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background: rgba(205,50,50,50%); + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background: rgba(50,205,50,75%); + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background: rgba(205,50,50,75%); + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + + +/**** Color definitions ****/ + +ForumsDialog, GxsForumThreadWidget +{ + qproperty-textColorRead: darkgray; + qproperty-textColorUnread: black; + qproperty-textColorUnreadChildren: darkgray; + qproperty-textColorNotSubscribed: black; + qproperty-textColorMissing: darkRed; + qproperty-textColorPinned: darkOrange; + + qproperty-backgroundColorPinned: rgb(255, 200, 180); + qproperty-backgroundColorFiltered: rgb(255, 240, 210); +} + +FriendSelectionWidget +{ + qproperty-textColorOnline: blue; +} + +GroupTreeWidget +{ + qproperty-textColorCategory: rgb(79, 79, 79); + qproperty-textColorPrivateKey: rgb(35,91,159); +} + +MessagesDialog +{ + qproperty-textColorInbox: rgb(49, 106, 197); +} + +NetworkDialog +{ + qproperty-backgroundColorSelf: yellow; + qproperty-backgroundColorOwnSign: rgb(69, 255, 69); + qproperty-backgroundColorAcceptConnection: rgb(67, 192, 67); + qproperty-backgroundColorHasSignedMe: rgb(178, 66, 178); + qproperty-backgroundColorDenied: lightGray; + qproperty-textColor: black; +} + +NewFriendList +{ + qproperty-textColorStatusOffline: black; + qproperty-textColorStatusAway: gray; + qproperty-textColorStatusBusy: gray; + qproperty-textColorStatusOnline: darkGreen; + qproperty-textColorStatusInactive: gray; + qproperty-textColorGroup: rgb(123, 123, 123); +} + +SearchDialog +{ + qproperty-textColorLocal: red; + qproperty-textColorDownloading: green; + qproperty-textColorNoSources: rgb(0, 0, 19); + qproperty-textColorLowSources: rgb(0, 0, 38); + qproperty-textColorHighSources: rgb(0, 0, 228); +} + +RSTextBrowser, MimeTextEdit +{ + /*qproperty-textColorQuote: rgb(120, 153, 34);*/ + qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); +} + +/* OpModeStatus need to be at end to overload other values*/ + +OpModeStatus { + qproperty-opMode_Full_Color: #CCFFCC; + qproperty-opMode_NoTurtle_Color: #CCCCFF; + qproperty-opMode_Gaming_Color: #FFFFCC; + qproperty-opMode_Minimal_Color: #FFCCCC; +} +OpModeStatus[opMode="Full"] { + color: black; + background: #CCFFCC; +} +OpModeStatus[opMode="NoTurtle"] { + color: black; + background: #CCCCFF; +} +OpModeStatus[opMode="Gaming"] { + color: black; + background: #FFFFCC; +} +OpModeStatus[opMode="Minimal"] { + color: black; + background: #FFCCCC; +} + +/*Property Values at end to overwrite other settings*/ + +[new=false] { + /*background: rgba(248,248,248,75%);*/ +} +[new=true] { + background: rgba(220,236,253,75%); +} + +[valid=true] { + background: rgba(0,255,0,15%); +} + +[valid=false] { + background: rgba(255,0,0,15%); +} + +[WrongValue="true"] { + background-color: #FF8080; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc new file mode 100644 index 000000000..be5703005 --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc @@ -0,0 +1,214 @@ + + + rc/.keep + rc/arrow_down.png + rc/arrow_down@2x.png + rc/arrow_down_disabled.png + rc/arrow_down_disabled@2x.png + rc/arrow_down_focus.png + rc/arrow_down_focus@2x.png + rc/arrow_down_pressed.png + rc/arrow_down_pressed@2x.png + rc/arrow_left.png + rc/arrow_left@2x.png + rc/arrow_left_disabled.png + rc/arrow_left_disabled@2x.png + rc/arrow_left_focus.png + rc/arrow_left_focus@2x.png + rc/arrow_left_pressed.png + rc/arrow_left_pressed@2x.png + rc/arrow_right.png + rc/arrow_right@2x.png + rc/arrow_right_disabled.png + rc/arrow_right_disabled@2x.png + rc/arrow_right_focus.png + rc/arrow_right_focus@2x.png + rc/arrow_right_pressed.png + rc/arrow_right_pressed@2x.png + rc/arrow_up.png + rc/arrow_up@2x.png + rc/arrow_up_disabled.png + rc/arrow_up_disabled@2x.png + rc/arrow_up_focus.png + rc/arrow_up_focus@2x.png + rc/arrow_up_pressed.png + rc/arrow_up_pressed@2x.png + rc/base_icon.png + rc/base_icon@2x.png + rc/base_icon_disabled.png + rc/base_icon_disabled@2x.png + rc/base_icon_focus.png + rc/base_icon_focus@2x.png + rc/base_icon_pressed.png + rc/base_icon_pressed@2x.png + rc/branch_closed.png + rc/branch_closed@2x.png + rc/branch_closed_disabled.png + rc/branch_closed_disabled@2x.png + rc/branch_closed_focus.png + rc/branch_closed_focus@2x.png + rc/branch_closed_pressed.png + rc/branch_closed_pressed@2x.png + rc/branch_end.png + rc/branch_end@2x.png + rc/branch_end_disabled.png + rc/branch_end_disabled@2x.png + rc/branch_end_focus.png + rc/branch_end_focus@2x.png + rc/branch_end_pressed.png + rc/branch_end_pressed@2x.png + rc/branch_line.png + rc/branch_line@2x.png + rc/branch_line_disabled.png + rc/branch_line_disabled@2x.png + rc/branch_line_focus.png + rc/branch_line_focus@2x.png + rc/branch_line_pressed.png + rc/branch_line_pressed@2x.png + rc/branch_more.png + rc/branch_more@2x.png + rc/branch_more_disabled.png + rc/branch_more_disabled@2x.png + rc/branch_more_focus.png + rc/branch_more_focus@2x.png + rc/branch_more_pressed.png + rc/branch_more_pressed@2x.png + rc/branch_open.png + rc/branch_open@2x.png + rc/branch_open_disabled.png + rc/branch_open_disabled@2x.png + rc/branch_open_focus.png + rc/branch_open_focus@2x.png + rc/branch_open_pressed.png + rc/branch_open_pressed@2x.png + rc/checkbox_checked.png + rc/checkbox_checked@2x.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_disabled@2x.png + rc/checkbox_checked_focus.png + rc/checkbox_checked_focus@2x.png + rc/checkbox_checked_pressed.png + rc/checkbox_checked_pressed@2x.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate@2x.png + rc/checkbox_indeterminate_disabled.png + rc/checkbox_indeterminate_disabled@2x.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_indeterminate_focus@2x.png + rc/checkbox_indeterminate_pressed.png + rc/checkbox_indeterminate_pressed@2x.png + rc/checkbox_unchecked.png + rc/checkbox_unchecked@2x.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_disabled@2x.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked_focus@2x.png + rc/checkbox_unchecked_pressed.png + rc/checkbox_unchecked_pressed@2x.png + rc/line_horizontal.png + rc/line_horizontal@2x.png + rc/line_horizontal_disabled.png + rc/line_horizontal_disabled@2x.png + rc/line_horizontal_focus.png + rc/line_horizontal_focus@2x.png + rc/line_horizontal_pressed.png + rc/line_horizontal_pressed@2x.png + rc/line_vertical.png + rc/line_vertical@2x.png + rc/line_vertical_disabled.png + rc/line_vertical_disabled@2x.png + rc/line_vertical_focus.png + rc/line_vertical_focus@2x.png + rc/line_vertical_pressed.png + rc/line_vertical_pressed@2x.png + rc/radio_checked.png + rc/radio_checked@2x.png + rc/radio_checked_disabled.png + rc/radio_checked_disabled@2x.png + rc/radio_checked_focus.png + rc/radio_checked_focus@2x.png + rc/radio_checked_pressed.png + rc/radio_checked_pressed@2x.png + rc/radio_unchecked.png + rc/radio_unchecked@2x.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_disabled@2x.png + rc/radio_unchecked_focus.png + rc/radio_unchecked_focus@2x.png + rc/radio_unchecked_pressed.png + rc/radio_unchecked_pressed@2x.png + rc/toolbar_move_horizontal.png + rc/toolbar_move_horizontal@2x.png + rc/toolbar_move_horizontal_disabled.png + rc/toolbar_move_horizontal_disabled@2x.png + rc/toolbar_move_horizontal_focus.png + rc/toolbar_move_horizontal_focus@2x.png + rc/toolbar_move_horizontal_pressed.png + rc/toolbar_move_horizontal_pressed@2x.png + rc/toolbar_move_vertical.png + rc/toolbar_move_vertical@2x.png + rc/toolbar_move_vertical_disabled.png + rc/toolbar_move_vertical_disabled@2x.png + rc/toolbar_move_vertical_focus.png + rc/toolbar_move_vertical_focus@2x.png + rc/toolbar_move_vertical_pressed.png + rc/toolbar_move_vertical_pressed@2x.png + rc/toolbar_separator_horizontal.png + rc/toolbar_separator_horizontal@2x.png + rc/toolbar_separator_horizontal_disabled.png + rc/toolbar_separator_horizontal_disabled@2x.png + rc/toolbar_separator_horizontal_focus.png + rc/toolbar_separator_horizontal_focus@2x.png + rc/toolbar_separator_horizontal_pressed.png + rc/toolbar_separator_horizontal_pressed@2x.png + rc/toolbar_separator_vertical.png + rc/toolbar_separator_vertical@2x.png + rc/toolbar_separator_vertical_disabled.png + rc/toolbar_separator_vertical_disabled@2x.png + rc/toolbar_separator_vertical_focus.png + rc/toolbar_separator_vertical_focus@2x.png + rc/toolbar_separator_vertical_pressed.png + rc/toolbar_separator_vertical_pressed@2x.png + rc/transparent.png + rc/transparent@2x.png + rc/transparent_disabled.png + rc/transparent_disabled@2x.png + rc/transparent_focus.png + rc/transparent_focus@2x.png + rc/transparent_pressed.png + rc/transparent_pressed@2x.png + rc/window_close.png + rc/window_close@2x.png + rc/window_close_disabled.png + rc/window_close_disabled@2x.png + rc/window_close_focus.png + rc/window_close_focus@2x.png + rc/window_close_pressed.png + rc/window_close_pressed@2x.png + rc/window_grip.png + rc/window_grip@2x.png + rc/window_grip_disabled.png + rc/window_grip_disabled@2x.png + rc/window_grip_focus.png + rc/window_grip_focus@2x.png + rc/window_grip_pressed.png + rc/window_grip_pressed@2x.png + rc/window_minimize.png + rc/window_minimize@2x.png + rc/window_minimize_disabled.png + rc/window_minimize_disabled@2x.png + rc/window_minimize_focus.png + rc/window_minimize_focus@2x.png + rc/window_minimize_pressed.png + rc/window_minimize_pressed@2x.png + rc/window_undock.png + rc/window_undock@2x.png + rc/window_undock_disabled.png + rc/window_undock_disabled@2x.png + rc/window_undock_focus.png + rc/window_undock_focus@2x.png + rc/window_undock_pressed.png + rc/window_undock_pressed@2x.png + + + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep @@ -0,0 +1 @@ + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..5575ab5ce569d09e2708b0a16a90a5a5a381790e GIT binary patch literal 522 zcmV+l0`>igP)-~a#tyh%hsR9J=Wls#({VHAa*^KOKNfM_Fwo1Hfc{s4c0ohTBt(Nah& zLGmB;4~Q0)HWrFlX`xtJXsNxJ%Me)7XWm--TB?!U(XGf21yHn`2!3R4j?eE>h%-XlO);MHvxboNp`ljHm?dj9i$6; zLzc8xUqfI$+1}o~Hg3*g;zl$?Y>g&ib;^)SZ9ZArboeFq*qNxc{w zD@b=G0R)wpgg}NM3B#Qj8!HEy4|ynrnZNz?SptXdTn6&1(IZ@kx}a>v}z^#A|> M07*qoM6N<$f||$TF8}}l literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4596a5ce8addad7f348c21132be688271c6c3c51 GIT binary patch literal 1025 zcmV+c1pfPpP)-~a#vvq?ljRCt{2nNMh3MI6V!-`PzFh$maIyu6)_jk0GIPwgT8qgp6} z7d;8aSiz&Bpoo-uX$8GjvEWG%q}q#>LZx0U^(+#SeR)|Cji(4rHv8u5VK;R5y|-kO zeY+d!d``>!X6E<(&YO8}W)|>xJRXn76`GdCCBOxMpH004-h=yAdP2;fMni2%6*w2lIU ztfvjaowC;6?$;m}Ywc~9m=grz-iXLU`0ikyd1B2a=0rd9$TY}dxzPyAEq5J2E!9#G z-Q-^v1SkV#y!_TGo9E_(AkJ-exAopM8jT}6Eq4vT6W!$!Kr)%+AV?@N9Tnt z2!f5h+7C39gCN-0x-;_>fS=5dr1z?zTf5~TQ;0s0`N&rH19K1B)R4VT(sfr(tgc%Iy^X06u&FrLQbggLloOn zD{trep0(k{A^IJTdOdy}#OFwhBOO%Go{=P^w0Q^NjcPT#JXF`iG~T6Nk6!}uHGt_< zNNCT7gCiI)qq7O&m1;G-GF0CvaJ@!R;~Bwy58%F3NF?@sejou!rv0mje+j;5?d**q z0}rBbp#>3gh80`~^x*0%)W{1P9NR zyRQeZv#HaJ(EYrQ--H@7uPePcPm zNGh+b#a{}1b&&c5zp7M%C6cXCYa7eW4#`%f621oMvpp+|pH?ct;yBC$W4ziT>8uUk z2Khn1Is)IfHh8D=hs=0%jVn<%tI_&dLYKOVMBq(p!!O3IWippJ09K>;0)a&U3Bk9l vo&9!FT09<)$K&yMJRXn7-~a#t)Ja4^R9J=Wl(B0QQ5?rV-xq|SAaT&aNr?zb1|_&Ud9_ICPz{cP zZD#)hLEZcd9Fn+Jyau6l@OncB2Xztc5Em^j3NE!|v7zRE4wo~hZDW!ayWAHJ-rf7Y z@AvzD@AnQeWXO==fT3jIU7!076#kR%M%b($191H)a=X&^8!4~;K+$R7b&3`N-Tiok zqTk-etDe`N0Rq3VuEU)xKmdT@NFC80cB=?;@sJlB>3D(PSWl*NY3`@h)va==`1FV6 z&q|aqw6_Qnm=l26lY(pCT$-QXOfzzSFKM+}-Eyh;tYi7(h)axH1;ysX0*?y0cGdU& zpWA4IB)plq`-r=}*9gppbx+Je55i{c9$UH||907*qoM6N<$f&y{_y#N3J literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1bcb5241e732dd725009b80f10d48b108142bb GIT binary patch literal 1068 zcmV+{1k?M8P)-~a#v-bqA3RCt{2n9plmRTRfR=e{&Fk&0k(leR9h(2yd=LKm%B#HMKq zS~W2X7a~m)@E;I=K#`z=x=;!(G@WS#i3KyAbcC8RGbtnDsy6AWFVOhRCr#|5Y?*M-fCszJmPm%;+Vk#sDQ@xLB80RUZn z1A8>jd4%o$FMx43Uu_gX4gQ#vd2#4YjzumN8&#CS;r(_v_`$xm}OF zaK>p|Xab%IQWZ9G_t&<0anr=zoX;A4R|101><))^@X8W6n5C#l%U zw<+VhW$)j)nWFgcs74#dR-e;=#UqMk5kWx!3yqb`+=)I zQ}7YyLkSH2sv5Ju+QCCe9ia>H=x^fIwJS_{49h9K*2&}e3!cJMoyk9&9vi+Eg4FO@ zV#)C@{@k*4u><7?zfA)tA@EL-*|K%9V`6ONuMi{xA@>9)Mn`XDAI^0n`rWyP#bU8o mEEbE!VzF2(7K_F5pz#l6b~h4l)L{bv0000-~a#ty-7qtR9J=Wls#({Q5c1vbJs!%h&C1$LBU#Vl0^hNS&`tni>6V* ze~@1wsJ}pLQrcK3vWY!OX5~e@d=|ztn`tAm%f{js>Fn@-?0fgb@_L#1&RkXG11OV15+WOkkW#lJFNDhM` z^I#)GNF@CDTU*tB^IZV|)~B^I-U`=k&!*nN&L6@ci6FrC?07reSfAF;;JV)n+bTbc zcd>3Kf{MbK+F>N&baTG9S_^lOe);X5J1ft72K#Nb>1fLh z-$Z^0l!k@qGw&eXTCM5PUfP*^J2~em;iteslAAghqC2qLM%S8ky~v`QYq%yFJ|E=g zz+r=xhA;#rT3;MA)x4rtSv7M{_r$!<1bY!UhA`3HmVb`Y#Wyv*&7(Kc9Y4F^Q?cVE z;6(cBLn!IOa#ip1YK{DpIk({B?T$YJ?+%o7>2+0~M%5}PC@9!hegLHSu?BdH$G89h N002ovPDHLkV1g!5^f3Sc literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2b12f74d0a38ab95428c3ff012c9150e9b20ac2a GIT binary patch literal 992 zcmV<610Vc}P)-~a#vl1W5CRCt{2m`!M0RTze!_ufzvMWNcA=vG{}WFo0(R7#sd(n%oT zO0@ogYkxsRtYEs(t%?O#u9}R=q7_Oto61bm6m-*{oyBED(zu8^b6*#sGP(CAnVH;~ zM0%d(`R+OAeZTW_&p8kX1OkCTAP@)y0)apv5V*Hcx?pg|A4>iJhz*Ird!VZ@3=%{@ z!`8=(llrJRo=HGyHmL(~uLSm(Mr|VMYc7cPO38j9lK@+1(Eoed=OS$DOtv_O(u_xt z=YR)NAp=Pl5p?008py)tQ&3+_q*CQRfIg>G^C^3nTH)_z+Dc{`%quQ7coatT?1;gBer-Pr)>z9{^`@`@|ae3s@>8kE{|!Y zFVeHX51S(bh*3*YBPZs=wN4uQS26N|j_9 z^j40*L|r;aHJ$4>A^U7~B6=68?S6MPVuKaGEqgkr*#ul@5{x9AJ-JHnES7b)({^_~ zWrt?`isdiKj7)J!*us2b>9xhOGRv_Y3R$zIiYKwZ1r9WqTehrS9hi(GWq&h&3%yXC z(Clv7h5~o)q4R#;@^^^)o6C(YI!;2~x&F^YI<-{Rn5OXG*3hhLtr%C-9qo;stsgR7fd2Vx@bE&y@psu6KQ@UNS z%nd=^X!I_n3x3e+o)Xo)Osyp|s>Nqf;jXGvy z0JMeqxq(%k=%#t-(FNw2AKkb9NAk7Ni!D{KzZrNadUat$^)5^6&7;P`i0aj!qnCw0 z-|1W9&uYI!r+Z-@dU%Bez}Da_?@9h7Uya_co#N9@E;XIf`-~a#t=}AOER9J=Wlrd-%VHC%I?~YK7AaziRlPTgPqNQ;W+(eO%ic>*{ z+Mr2_gOdpA>R?S#ROSQTCJ0xe%V4J&G>~cRi z_>Oz;|NigZ_kEC%kdUy-Sg`0kUYf;d{V!F;=VznE4FFEainCBf#W?>0g=^GQ)yKAO4*CacKI+>F>dJ zHyk`OJ-*P|zWYvUZF(EV_Nu`@JjN?-EEbpDo}2x6mkcR-R!;Cr1i5 z8)-)#Y)5Xe%aK0@tN}#537Lb*fO+4X!{w{_2T^om?W}BX|6bwT2iDh_2!8ul-=V8K zTzni=GxizF_FUSD<318>0#w`W05j%$2PUtbdJ#vjsYBjzVrZ**-nhXQ0Kr?i?!NMs zlW*c`HGRwM$`5RI7xYf>(ofmJ=Yxg!&1xkiBqXdVzW}c|tb*cE5EB3Z002ovPDHLk FV1l>03RwUE literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d43b0affaf60565a553974132719110d39ba4a2d GIT binary patch literal 1070 zcmV+}1kwA6P)-~a#v;7LS5RCt{2m`!M0RTRg6=e;tinz*r)v{J;4){S5?7P=@jeuRip zluA)o&7$d~X(kcsCj<#ruwAIl)O?JTM1+EyVqF+%sZ18G=1mH2{J=$NH4B?aA%Uh- z=N%WxXy(0_PG;u4NlNc;dC$A&{?EDZ-h1u^gTY`h7z_r3!C){L3jSJ6 ze*#pGD{@!=_CYA3s2=yW`}P2U)~-`+B61#R@_eqKZX^oB!@?ieJRNcSibuUA<=+o<8#V4lNWe06RThH%Jl$z``H=FJjy6+2NjRcj{gC6vz(u zTvN^O0i05cilTP;6h?;tirT*5g{*3RPr2Y>jmKaveQdVj_RVJme((uU?Dfcjg17{Z zeW@XT^VwYb*z8*TRHS|H!ST)W4GU)leZ?tdLqE9i-w&96@q47ySs>;yE!PS)5megd1zyjNCC}C9JG@DX9~ycN zi*JAjR<`TXmR)5MB&fhy5cK8jSl^}Ue0oL*!%2~NVrUo2cfdoQVXC-91qMGSuKPmv zi~ejaI!i_g%TbY*BcDDYg-sU)eb{5FU^xT^|A%WA+NX!#{5b@f|Bn==vm#IRoPNaq z$GreNR$@?5P>HG?AZfag zr{nT?@_H0HBYP72X|($RKfqJCQ9}m9N)YUoBtYN zpVy|#d%`M@ujdRxc8k^@{jXHR! zu@YP>SEi=inHP6`yM6w?2NBs_=JQW-&2vYu3=aDDi3q6kRbD0Dm3j~1qhK-mes(PR zaW$8kYFU@}oOojBFv{qPCPg*jr2EqK)>4-x;AO^{%x!P&xF3<70t-N=lkWR!J+v4M o27|$1Fc=I5gTY`h816Ox1uyPFn?G+z{r~^~07*qoM6N<$g33PkH~;_u literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png new file mode 100644 index 0000000000000000000000000000000000000000..7fbc35065bb5941a78725becd5f810d7619e616c GIT binary patch literal 558 zcmV+}0@3}6P)-~a#t;7LS5R9J=Omc45fQ5400XGV=6@vD%9&FmP#E`_C)WdtRSg;ol7 zHbVXYu@HL^1WQ3HEo_2?rn9mX*-pqhJG-!0X@Zasc82-X2?H->1nhIyVnMtUe| zrsZIW)=iXW-TPQi>yZ*WtP-sOBstH!cZFWo<1o!Ads)(SXXo23!Mo78(N46Lm6iR4 wg~QhnAN~peK&R9Bk&3Ifx53|IYX7_O6SfPX0b!oaO8@`>07*qoM6N<$g1oo!2LJ#7 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc649ca7093e1b7155c59e8fb08ed00094ae7e67 GIT binary patch literal 1138 zcmV-&1daQNP)-~a#wBuPX;RCt{2n@xxuRTPE4TipqYiXbXtPgivf85DQI;8IXD8pPla z=t@LU(1jR55p)qDiV*}CA{ubx!l16gfJR4M2!h~35JZAzrss9dB+-b9U>NM~cU{bg zRW(DHA@99ncXH1}rSB zq)B4ufy+0M)m5A*4fyfo$tzlIJFn379Vr|dw#a!OJTzPZ#uSe#9IW#qj6>znm;p;m#k~q|ZB+c1eHo1y zV9d%b2!}VsSM2)47YxA-SS*Sg6ng~NS>_ci;%#bkDt0yTH{ZFPMH_5Xmf*y04=bvuyARsJ^UD$sVb@( zc*5HZUJWRU;zDbgQ@Fk+DY$#6aW3%I0;<{`S$R+4#=1nHUEWsU#Q;@J27}^lLHCw< ziEQxT!2neiV~ST5d9cijpc>iW!NVM2isCs$o+@)84>#L|(+cPhmLEgq#X2AIaI;-F zGoWvZgQEK8MkVawX1j1^fYcsn!213^g0=o^aMuExlz9VZn{C5g1t3pS+tVu&#Ur<~ z!C8V?HuV9jPn0lIQ2#N8WRmvEkx zh-j8h?E~Je2#O$aJccjBOF|-Ie>wfrL%@d>K@pHdBI*WjcVu>UcDSRR+z0YyRZ(&I zfy24NYa*Ra=ZxCnoe1An6%jO!cJQ7=p69>ocyv3kP!R+{ns0_6cOlR7Q|S0s;6z1G zP1cr(<`Aq5d%a#i5xougt*U53gPVk)eVC@{cc|O}oT=xb4Ve&pBI@;~zEaV9fMJ;z zNL0g{(8x@jr|Bmu`T(`VlL!fDP!k$kit;plUy;W*Dq&BMjjqLcHgyP*=j*&GPCkR( z3L4*xWZllosJ>R_ME+?9|7hF*5z#E`J}u}wWnS0M4ZhWnq`%%8AOL)vP8Uq0GJYO9SSNDQ`QnJFX7I-d!002qUe6Oosi&S`=PCis8gZ$3~?7>4<9qW}N^07*qoM6N<$ Ef?m-A?*IS* literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3b282cce48aa69e35c3334cdcfde8575fc560f GIT binary patch literal 557 zcmV+|0@D47P)-~a#t-$_J4R9J=Oma%ITQ4oi}-@8MCf=4WDtnDqWEF`x9CC$Z+)dge~ z(+K$k#6s*v5LDtJc$KbqO|bAbSXfz#tsoZK*ysfeL2_>_R>ey9?LH#tbOSpx-~4vw zG4Q{eVkcZovm@T?Envmy{`{Z5Z^ta2^!tbWj-CRYsxdBB@ia{j*v{M-I2jTb1t3k+ z)+gV22$qD##sJV~-?=R~j{)HK6=309b{$y504ERMF)CW4AzbKPT$gbb0Lfz(R2&*8 z(CuY?iJL!*6JESFK(d@IAw4L)dY#t>NP5{RLyv)$VOF>ES^(Yj(g~B>1m-X^p`eLx z1khc+d>n7jzz!Q&`QMvcC4kfE+A)|Fz)`>yxa+^ON^98id+&d7qZNmW3J6|9;0qHI zV9&MBfW1>dOjLm9`P~oDPJoYqEFwhZM8)Xd8=MwF+bR#4C=fwOihSdh%r61EfXtdh z1Sgn`2QP%J05b`J8l82uI+%eQind}CD zd7Nq}(Rhfqo(!%D?jSJ35vW9rRkDtoUNLxtfWXa&vdej%&*t596*LKrjrOADdHz)g vcYDCgzXAX-84kZVXJ?VNfoaU#|E_%lXh)R_h<{1o00000NkvXXu0mjf0haK3 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..87c928ea3ed00ccf8025e343918b55a4287f27f3 GIT binary patch literal 1141 zcmV-*1d98KP)-~a#wCrLy>RCt{2n@?z5RTRd5=gqWQj0m>6FsLh0)QwPtB1mi}i9rl@ z#?h77{FzV}q6J0p5982^6$BR|wn?VOMT(jx4WSx4Nn{F&ASejMg&^XhK?JQ7Z3~mR z$3+}@^Jc&l-@Wf*=39Or+;i@C&i(h8fet$8U^7FKPGF~vfM*+Oq_c&8y)kmhcUt#Dp8$3@AXb9 z-#{V;?8z1~f*x;)A7HR}VUqz`)^DMOF(y+7bLODH(a znq=i0u-XB;@&~qwF$=&w5lO-REpH>RWr6pO`R%l31V zs0>CVZz|t_4Flwhv#W0cPd2gIsC?qfz6r4#kjag{DCmI}LHud^Fk&^JH&@s%aHv%g zXOEjJMQjH2W=9T#z8mGm!?q72z77zHe$W6U(Ocd|5Sszg_6_g#+<_PkFvv5s&N%Te zPXC735?r30_y~BqRnb&jF>D~#3N6h}z5`lpW(B}o6Jl@CrP=a95#EmSih8*mY$T<- z?&^M4mFX}kh**mEpI{}SQmJIl?+Atv`8Xm8o^^t?WWF9BuU&On9z*r>W<^9j>IAEa zoH{jrv1aNIgM1t21;m#B(f7P&rX~c@_Wnn-t@100000NkvXX Hu0mjf&T{}7 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..52a0d91028955151cd7f12db4cb3c66986c52333 GIT binary patch literal 551 zcmV+?0@(eDP)-~a#t*-1n}R9J=OmN9EoK@^3*Gg(CmDq7fBSlL*JP1vNdOh5^^iLR9a zI~yTCKrBLf5d=#iseHPL5G{=&9$P``tVD z&U^5`OSugv3ZIA#zqjz~Ryh8<^NpOz&#ikj_WTSuCYOr|xssnPeDHA3E5LY4To!<< zg-4DYh)cj^$-*-N*!tLr_pz>FBNP89KyxK77~KSe6cI^Hs0GmMcpm9CfUO8=$!h^L zJHC#5mqFI3#L8;{j6d}>@8pAYgHa0qOn zq=~Nu(0t-E!CnWBT9^#UO9M<4K1J{g;3UGSyZ$Scnt|BxCjet|wEbt5y@D-(vLBf2 z0AXJjfe%QfW3mFgYHORQN#HX^Rz8T*M%^oV7o{m+M@Gh3Ad*ZrTY3|%Y2dq17Kmhn z%~`!vP#fqEAXMwOu2KaXm$im<13-f=REDVB!tSh=k>-a!t_V@<4!bSg!(IeXMTpu% z)SU@;Y(D^yoeWWbl_a0;hg-;xkdV_hBg-y7Zma)wFU$eYQ-~a#w5lKWrRCt{2n@wmPRUE~CXY!B~m7=H{QCFh45oyUsMM*`gRSeC0 zrLIIOigqC?D1r*Hv|c9h3Oid5gY*CWsT-FW~hx4MG{FgWh36?s2!UeY(jd9@KN zfOTWOJdQjIT$IfO&a0gu0o*X=i)%H{0+$utR;}m;R;%mZ@%ewoeh+h18SMo%1BPCA z?^4UtnDt5DIZpYkf&nmez_rD--Ur;23WSy8qL)<|0Brrf5brgNWD{Im=OGXP{ZsMt zpnFrMFa?hMvML8KFzF{ik0(91@A|?!4;2F#nDqU|d$PV1waTiYG64NkZWzCsG7UB{ zE^N{7P$d8c#(gvPzHIvzu~gh6?@THkz~GeoEKdXHBz>DW&n@msRVsk~X{;N#bfTDwIu9kC1vX6jk{13DxHO$8rpy)Z3@UsEtQ+&%CHZ~e z%2Xh`>dr&KGhlGcYvP(`FxRC5VXRU%I{&1?X28$^*W#Mr0&YzDE@6Ma8WjUz)Y0NX z{2DNv@(VuM{Tt;Ez}CRE@e4-xWRs9aep$H#7?|QoqeoL_d#wwu^N=%uzDYl5yt^Zi zN;}-FR=EM_n{4e7ekJQWz-gaUjx!+hLWB1E`>M9MD^+d)1fA17=&rYw9{}lLGF_I4 zLjU}j8-TeHje#EOOq|O{%%YU*Q((TXmqDYQNw^Sl-v`W(u*>pGX;&bk5buWkcY>0e z$D&7!-%R;NxcaxySrt>zPQ|SsqwT=EnM5co2!$1M{xZ+RMHnjcKHx0S&5rl z^?|Ir$sV36fKb_^Xs)5RZS6>zT0TLRr%Ip2&4%{cda5IEd55RUHzUnD&k4VnGIjd! zRDvo8faJO3(PP4Ir2LY$%+&(`*r~Ypg6KYACX*C?cnSjmaB!oR*8HNo44xUj|6Yy=(Z3PJc;7~)~ z5NQ+eQ#Q-<+z>1PfcY)@GLkl9eoOkwvF@M&0304sQ`VNu52?=nzsw{xw^biu?V|np lt%dY#)irh1Raa++{sND%QC95D7mWY_002ovPDHLkV1mhh4e|g0 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..c04ce09435c23ac5720f55d7d12e7ffcc6e74248 GIT binary patch literal 574 zcmV-E0>S->P)-~a#t@JU2LR9J=OmN95kQ51&1KYguIK{0{|E-o$(;?SU794l112&q#A z5lxn~so*Ax;wH3BE7*sFU?&@JDGuu9qVhUO2Nyvd6hWw9p+(!|9fzb&g74m3BIwy3 z-1Gn6J@4FeFZ}PJ(1L>(rt(`+?>jJCj>q@@X?+yZ{OH*2U5zMu47Mk0PA-)Bk>d5f zzWyDL3{JS@1pz1)7km2i`yK#8uDJmKOz-ob?*L~pFf8pVK%q2u6I2GnWT}vK4PfBX zY}Mc@fJx5g9RUoKYh#FM0E1M9v$;1wp)@;!>3;h&6@KPk0EN=bNrOe8hnBIoxidiF z;`A{iw*>5L8#{IU?;`UgJYK3DPSF!!w}B~uIb^KBV0r3b)AY<>KNij$GFD*AqL06> zErm0OtUX|?gfw*q=*=~T4L-DCf?Z&l0ba~s{uE(Df-khjT`-8uLa*Y9x1`Nez?xbQ znII5OBFVkU*CHJOz7q(-Ss;n4&jq7E6A3uG9p#0A%I`(Qy+capjuCT@XsiwI+2J0YG+W^*{x9h(O3mGss!4*GHQh zUsuloPhE3^O|&=l8=IROKh6kV{uKa#m4z$oQKNAhSOa|vsr~Q9PZ2Vd3~y^7-T(jq M07*qoM6N<$f+RHc!2kdN literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..02218c80dd467beda61fa8b7ee3efcd2d32eae36 GIT binary patch literal 1155 zcmV-}1bq96P)-~a#wHAzH4RCt{2n@flsRTPH5Q{9s>BteMrg{Ui0TnIzA5fNk*jRrCJ z09}brFw-59o_0VHe9$(Dn1J}`Hl}+F7#9Y06$Ugqx=28f%yi-daUqDf(5Qqcnh9oR zx_%dJpsE;y(Ry4=|I7bC-E+S>eeXS0)zDX8eVxs+tP}XBDvma5W_n6sNLxD-)o0?k zt{2Bel2&2#<(n{Sf;^DJ?CH3!?L2_hrDoC0CPBe!jV*7d0Tf1?SNUikusrAs{J6$& z7C>S2rOV7T1+0q33>4Qm`M53=r-nuv=bJGFT$=P)&Q-t->$k7SE#W=j$~4Av3c&C~ zub(qFuyij_4El<(L9#kSxYUFDgd>$c`U5uWjh=ux}#4$%7*R zilydujP*fJm_Uh69vlErC^a4j9*g>x!sH=i0N0iq8w|EB66&UvLuLSq<>tK-t*Eb* z?))ib0-(5|aSPI(MaK87xA3K=)BzOBjn#PU1(pPT89oW__kX8U0bEyVT#eWVEQ^GE zQ~HyK6afrvdgby3YzkNz^#AJYGMPN21mK$T&I`N+|3gEU1bu-YXJ_|slz2B-7;T?x zI{7|uMbKC8h@0u;A>j(Re*A@{W^*6L0hQuZ4H?MGfSrSKiDj@Pe1A3jE3w!B4>UMi6`;d?(tu}T<&(@n@Grd)sU@HxeGI|Zu-&d z+O3EmLIL3^V+g60;qQ|LEkV>8B{_hEAio0{(603`P_>8F%CpRrUdhJ1^~eR-6MbG23Q9i4*Hhh*60)ffP>Ak z-{x#!E%0?3<2eTa;EUGApSyW)jj->N9?MAp0H5yI{9PWc0ggpuah?{P1psicJ@ysG zT3|Nl+u8D$8Gue}Y#N`t6!?BH&W|ab2LRA{ZR{h^7O<{~F6KR(bxwWt)z|++e*%|w VK7(S3j)MRI002ovPDHLkV1jqp6pa7? literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..fd31b4f2a4276b8085e1ee20ea9787cd7dbb5c53 GIT binary patch literal 546 zcmV+-0^R+IP)-~a#t)Ja4^R9J=W)-h`oK^VsI|1%ejAklOl-tDa%mV&kxmXan`A~u4y z7LrdOB7Ol;uokfp#O@Hq(!yG}Qb=|;k+V?)5sY&4SnOR|Z|{~(q0{Ux%sbC--<^Sl ze|>0{Nn2U|4Ww3}pCrlGIssv}X<7wNjw6H7XmtD#00-mZ{{HV*!{PAg;Q(w5Ybz_O z&uq7v2cRfny9 zD{eFl0I-p!h^JY$z1}bYuuZuqTE;K)JipW|06;{rfn(7cY;JB}XckZ^B4FTz0&j|< zINLA)fH*lJr^Zq5@;pD?Gyp>^8{sn%y>1*ZRZOnu8wUsi5}>UhcV?+ssxdzp1p3kn zzMLez&odR(lkGtHbF&-AtR+eEY1Ybx0fs=?_n$$&((iXaR;gbQAgO%wvCy?%ulK&{ z3X1?VX+45lY1$pkv&g&v*$3epX_`ErbDip^z~u)IW%KnQ?R6i`8x9paV3*G z=iVaWl>w5c;V;s(b4QZ@Qc^Dfgy8Mo-uIiD{ERF*s_uag%gaZurs=s~b%a*{c-KZt kEv>iP?H_f8{~rK<0AW9%HGP5Y*Z=?k07*qoM6N<$f}r2=&j0`b literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbc931200bbce38c512374d0f6c6ca2f294e856 GIT binary patch literal 1127 zcmV-t1ep7YP)-~a#w8A(JzRCt{2n@xxuMHq(Pw`V6=k$5qPFgxATJBdG6UAzjxL?ZaZ zBH}?1{6WE!A^|<9paDhjpx_@09z@Yo3}R%15bz=hf(J1;%WT*5bTCE{MRCpa)aPL) z#_ej&j;X5d!#uZbmU_Q>rna=iaDOrwKJPyJ!g#p|3ZSKMG7vbVRC>rq{(s@?E&vka;xPeUNRspcUp18BO~3>x z?iK;!jU-7|{nl|F&jKhA6eR>8-d8HS$!{&^!hJ&sU`W^@&`0`ddV}wB{0o>+CgIXR zhde=71-M3n*nfzVtDtsoe$t*?K7g^v=d6#zg0k>W;) zxN4z!_E@jiyUcZd~;ZftBUy3DSHfGMT~;zk6`4_r1+brJxSG*5)w zHW;LD6`na-qizBKh$gqL1Oe|=DtpmI2U$Y_fQZ>Vf%2G2vnOn4)lvXZ-aJ9%@P-;b zWHYC>0w$Qv6CtlDHN4YSLd^wG#B81@kXLLa)La1m?d6@d+hT1VPL?s9yYV3j@V2dt z8Vevaq+u)o$|G?YzG^F_rl$ZQQZjjwr#coV57bovC17Fp0=yhW?dNPq)lL9`0AgJF z-tB}-kCH5V0eex@M!@6~XCUTv|KlIeoW8H*^}7{nBVf|(Y~AY%@OdM^T`MaqBUicg z5FiqqTLXVXe691dx3=5uKU_vve;XtTbJ?%!d~|cS+x^9Le8nq(gxTkx5}of~US2-! zqk<||00Cq2KNI>uCyol{5lTp-u(^m~;c)1JET=szQ zrB2kU{A)5ERsaJjG&cm_iK5oyE}ENJaV@~u-xK&K3|kM@Ve)`m0Rf6zT;hb*`Q0RQ zhq*K1Qb6&M##f_1H*b&Qc++9#%=p;~3%<+q9S8UB4S)5LHv>LygTwJS*uQ7bl|OjM zni-n{%AVl=1Q{Rbc3T6BIaYD?lNkW`Eub9ibUNSK%5Z_BpUhAQ-Vui3m$t@tg*5>I tc^Kdrz?k5(QMB}#t+D6KnKQ=~e*sArOHpYU)lvWe002ovPDHLkV1m-c051Rl literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4cdb03617db3e7f16f1055faedd523b5485d70 GIT binary patch literal 545 zcmV++0^a?JP)-~a#t(@8`@R9J=W)jNw5Q5eSY|1X2P&1zwGuyIi| zDJ*0^fk^NRh=PsTAnq1IHZI5_&c@Ed+TOxSuyKi?cp>MpmMTzsZ;=fjWY`s+uho7<3g!`JVFjR5UlMuX`U?`Kz0;1_%QaXT5|JL zseqgj0Ar4XKtH~8<7mkM0D?2j3HDZA&I9nr)95qv0ObArfnVWRsQ_oag!mLi#QhhY zkK@$sDQ3DONdgAZFx1km&iipoXWjwhh-~=xNL);}I`1Z_pAjGl2^dOB(#`gpNjuB} z5O`F7eP{FW_B2hV1!z<&Snc=P8&md~3Lu=Bg}-GN4v=}PgFousZue&q!(r?@paDXP j!cw}v{{IP)-~a#wDM>^@RCt{2n@@<_MHI)sZ<4K5*}38yclYd8lhVo zvZ7S5-DI^O9uz4kY7DlZ2o@^nx=CaYR#7+Ux`vv1UMjECL9Oh4e&WhsF3#uxWtq|AT;0?&8$L6O(sY z)Ub|C1K1cLZ0%~*Oz%Co-J*_FY#MMawsSnzNIdcMRspSnkuU%N?jE_U7stmZM}_p( zjWYw7Ik+Y6Z*Nlbnap!HxzfBIoEbnw8o|22*wwkE{c$2ujJwhu6xUlo!(0j3k+E~r zuy_gE2<~e@*h&EMsod0?&b8NpR1wt12=n1oHh)-1|C&e{003QMgy^kQE?*GL!9dc0 zwe4^rVrKvTEw1$=H=u`kTO{DVPW$GC#DN2wT`GHG002PuRzn|z2S+Z(K6TkV z`D6fyNVCyF()h^Oxk|BEbdsxA1^^7|oeaU6@YJ`b&%O-@9i(RlT*16DgI-AG3NP6f z^3?zUWHwKXqp4i}8Jj8|8^8ddjm^OHemYyo*;4V?006zB5Zn#~!n?Kvd^Z3TQudf( z?O62Q0Oqh9xoRuEH~*athhxE$kBFXa)GF`UQt)^Mn3D(LwZ>f8+T;O$4NxI>p5x8A z$`J=bK0yGpf;sz-9=Lbg^9cI^c7u3U1GEBNUH2LI^1_&!ER{+jx5JI&%?jY&vJX!F zn@ei+u^(qL9f0xQ5Dg%g3?Mn=r+=qWuSWh%#=QZd%?-~sYtU_dzWWt|8u2zJxCS7UzLt$7Ehe`S4eN& zNEmRIl}a^EPX8^SH83{s0bxH}o@b48t2Xn8MIEa+`DA95i<&9ZI$8O}qK0+seKdvs zS6|E^esrl`{=rs!S6KXNjE{oQ1-J{~jpkf+$yV$kLxv1-#s34LGQBCC9?}2+002ov JPDHLkV1jX45&HlD literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd8f0f0b1230a22d763fee2d397742aba9a96ec GIT binary patch literal 541 zcmV+&0^-~a#t&q+iUjaBh z8oRc{y9+C>WCvg(!dU0uRpKq|k$Pxq010DkgQUy#)wrA$P?Uj~-gLFz@=|U9683L| zZ`519kQD$Ru+b24r}oIRSpf-Q8ylzyKd7zxR8~MjD3TD{6x}}2^6{*If)SmXb9bm6<=$3D{B*J}_G7HTA6Q8e^Y; zjU=ZHNSAu^YLBzdxF;Z`rbB3{JFk0Vu2UXhBN*=7*I%5~&2hs^1Dt*Z(p{Htcbnnb zB;ln2!XfpX?{{B@D@e`?NIPf!b3a^Ux%e5Gu*%+o&bJ*p_oksA(+DpE*hE(N8D?KM f^krJ%{|n$351ynzm+_qH00000NkvXXu0mjf8Pf1^ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1ac9d5c9ebf44016af725d780287f7a9e31fd555 GIT binary patch literal 1112 zcmV-e1gHCnP)-~a#w3Q0skRCt{2n@fmXMHq$8sTnjuqM#ug3GRHX1QUDOxG)A2nSdtU z9R?SI;DZRR6bU4V8caYDTqyWL(S<0A-Sa>uGC>>=WO|wrvJgRB1Q9`l2@xd?>08G| zrgHJwyd7uetOF6#XMxmADFe;>ez5hMQ3Fw{Vmrk*vlPl=Q)k1RKMIMmoN31+}V zvnW8C)lo%o$5M@pp~jDe2{zJN@&F)E(%i(fwgekL62S}*U`v-aK>Bp+tZoRU5rbd` z5Rm8c#<4=jZ=KQRP&%Orw*>x~&BkhB%bYeQ&>EN&1^~c~^g^|%hf~GiBbfn^e5XZ- zdZXG>Jy{$j(iwpMY0+bX5%fXzW8IZ9mOsT)3lh-k?(lam6E$<&v?{6NNp1iDfS#E^ zTw$g8YD+hz3}rY5V6Ay#c_v&V==ip#u1gii&JQ$OZs?6I4De zUSB}RCgyczZ1oHb003I2c>-=xS99Cn(Ylz*nHaFzJe5o!aL2i;^kK~ADH{V;@ikBP zcF)+i@Qk9wnwtTDuXzF=sN8H{jL|{nXh6S>F4aYXPgGhs7+NY%0|0<@n+=x6W5DCq4_64^YR z^&*YA*ZA0S!@L?wBI6n0P5$Y2gTayqax{Q|2;;uF*URlXj)a!W&HxF9Drc|v+9%B8 zAbl@jFNwSiAPh^lp1>!)Q|3V&cAgsqAtwV2oI8&%*yGg7ex8pdn#nF8@#~baB(DJi$a3<)c^KB)H7=!&C+Q53K+4e+$@|+iE~JcQ zjdU}BglEkIS->P)-~a#t@JU2LR9J=W)<0+yVHn5p@AF<_rGknb6kSA|9Q+f^;NU1->LkHM z(M8hQGzGy?N^o>gl3Hs(5OolXTM)(3p`dNV#mS+QC`e0(iZ#jo9PY9>-Cd5$pby-3 z&-?rE-22`g{Oe^=ZaQ7AZ-808+c~oQ=*D`Q02lGTy`VjvT&{Ke@||770QBq3$mqz+ zW2Lzr!vY`}AKf?hq*Qw0WeyPdU;-|#jeTo?BJH8n00t7i03@c0ll5ArfB<2V;Rgu2 zRV+7VGX(&ckWhd?_lo7lrAz_v*Cf#6!sPr!rT_>gfe_$1`AdbV`q@kYfdW57>~ub@ z;Zdr(gFXTaubywN)P7KT7k7cg6OhUJ{f1p_FIHMf)=4@6GnoUBm|bbkJWIGv zk_pH_E>zrJZC2|^!(#)44E4{t7CtOi=LQLn4KQ#RAbY-gV0|Wh_YYJt_kdyWW^3ce z6`D1F&~S*q2bQ;gZeRGkRQsJqI7FO)VAH_z-R{K7)0-~a#wJV``BRCt{2n@@-wMHI%r*E5;KKPzGu6(o2O|6BxjJ9_ZoA|?{S zKP)011T~tO*(5W&5eX>jxR`)JF>a5#nNGwUMA1_WVq}A`kb{xgSuh}icn}duged9; zbvIp~hg~)4>S!jZsxEMT$2!#a>Z@0;Uvt!u)Q&_rzwCm2*VLlrwlvQLYX*owAypR$+*EG+W(E4A}CDv2!P1eu-e?}ME_rK^%MYrL>nP@43;Mz zcNl|)O9QgHMTkgibtM{h8ONzOHDIY*Oq&o8csJY--QhBpzr}OVB%sxV5(4ZCtI^G_ zgUQ1H07B}8@gfi(4Q$+bgUd*AG5`)tmx6PG)eb46Q$r}Rz0Fq&X;GPr5`uCvGuoA0Z1^|GFV(JD-^5O94%9m{1ApJ7{ zgn$avUNJrqmYYwRR`bw+MMNag%A#OTA!D}LOP@r~iU@hbxeZSewrNUm6q@o~K; zFn~t}NB}`<@i%ZBQ_8|i#z4IWxE+*>E zPF(rfws@`vaIx13QiI)sI{Be|7J5Lcl)QRg;E@Sx%r!_zzy5VHC-5P!0 zWgMsCG6M?f0Rf+$iAQ6HF=#k3fLS{aywYyfbN`u)gCih;K-~a#tzez+vR9J=Wl(A}5K@^6+e>O^x;A#_#jgbVcW06WpEn-R=QSbpo zeFc34gAX7m*jOkiV!D8N0Ac&x+1V8WDXeV5o!{c_CNaAK_qt+pzv41*?wtRdbB7Bx zH8nN=8CBhwQfd|E6J{;Qt>xwA?^XJQis9Fatgo0gfb6iFQo35D*VGf}bo$p7`~_G9 zA8Vt%TySf3b?MtQ{id2guh-j9@D8vjFsJ|(<=U4*!#llRZ{wc`#Ms}=);4e+upy6X z!?l5Cwzj+7{+*c$#F!o!zX#^a?4$5w6o%mwU*X`s61RK*9k8;`5nCxZ7&AevS#m7%!Ue5x7xaW@Yqu;m0fl4oHA^or}$t zm6aa=bE9{%Lr0=nY6&X-rYEAq2cVk@b6w!V?;%w`a|Jx3!PeB&)XaomFnzh3OOLV` P00000NkvXXu0mjfHy-#g literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..51b1d7234c0a17996fa9d0d149fa44a447a01cae GIT binary patch literal 1008 zcmV-~a#vqDe$SRCt{2m%VQsMHt4PXKt~Kl+eT}qWg}pFg2lvAS{#$r%VS? z1b+Y!QA7wKAwFuPC^6{}1qf(}B}?D}I-tgpiFS7PPAQy@0tesCLvb>?+uieh`1YKS z`IYnTJM+BHzPmF6csw4D$K&yMJRXn7uZ7HgPkGlK1AVXKo!JiBZz}48l7j9{s#t zt6U|idFYyp0g{3!YTp3$##jl&t$MZc7RgS*(uy}A48uh-_!`9P{o?{a$f+m6WP}jk ztJ}HMY&Q3b)K};~U}tCN8JggBrg#Aax&TE$1iG1i7uINkAGf!6PZp`MunyR{cklF5 z|8_P2yf6@u0Ge*E2U1exN?=CP@B0hEh2=A6c8kzihyi!+wri!pZ31{MwVD7rXxRUa z0A-+zt~;H;y!vdpoXlG5%nh*CJ`a{Q0aQ{e34$9_lu=3>fy6np+H97$XQy_?|A07- zUj$3PAYDAhFTVFM95A>I3aHY!U*kAFHw&!?%*=o&YQ5sbp8=dog+z{D`~jpKvfs)n zCvI8WIzP406f-fv+T^03+W<}s1Ox$aLqGXL=;hEsnd}pwHmpt7rc*n}kqxjmxeVeP z01E>F(qW1>pMi8B)AKBV_}1F^&7)3#Bm=BX-UYFqo`*o*o0}e~w|fj?Kz?a$JnCqD zC{yhMl4#@BCj{~?FAmvFepV1UFHOLwjaudXY3>gb8z3o&lGb$ymve+T7FYbi8f1Rw zuGedow@G#x7^7{#jgGSvmdpIJ1mpK)c;u+V8jx00V~*_4;w5mYX#a zO6lu^fZrAZbD>-=-yfAf(ty9(?P}0*n*de@5(#O7(_N8}Fv{E?^k+~qtCdQnb!hHk z!7yyE7~?htR8wi{wf(~cP4BblA42RpX7%jZ@|~es!vb*}pL5~{fTdJOz{Bz8b1=x( zbf0jq)$8>?h9zXMw)L_TxA15c59FUgmISjEhRI8L37HPCaeNKphk3C_9D(|vQLBB_ zKbR>pijt0i()@JI4+7nKy&Ck7kl7+}bcb1oi_0d&3EJRXn7Hva*O1WtpnFNmT50000-~a#t*GWV{R9J=Wl|5(^Q5?X3|9Abu!6+>{bSc^n>JYJ;rBK8ql*Ym4 zPVfuCCe|+9oP(Qtw+zzF#i2?>tcwTfBG^$UKPJc0NjT4Ye}`ObLaI#O$ zm&(gP4KRwTi0sllRuGitpJjmgQ)ec(K7H7Hn^Zt@rOHF#QG9EqwdVeeio`y`?D)A0 z^6~wqzb}DmwQ2@NCRTt4ajDiE_l)dZW=@}-9KL<+$}8XZyJ~c8M4smjY}?E#a6Jy$ zck{OL0@_+Z2T@hiY@{y-1IMk`Yu~yA z=58z<{~m;O;9~s9(%YQx?SP2xe2I-P`cZtdwz>__*9r=P@UuXsEichFy&Kv&j;Vg9 n?+b9Oqe-~a#vr7~|5_yf4AkH&_E z!}m+Y!uOqwr;`GZmCU>k@aftkD7N>&$YZ7A>ZOha)rn0ak-1>#$+dY9rWzT~poQ{Z zPrtFU@^0Dh*nAftGCA23yc=2~@JWMP69LRnhRD9&=qtara_-!^pYi!Bz_E#m-5cwV zo+t28yPY>Tu2hfafV(Z=O78=G^5VsXyMD#!n*hhgr=BWT0yz*48{8Fx4KVklpM$D$ zJeOVk!^7~l@kM~>`0O5NohM+Q-OgYpkghkE!HPgsZNm*!uEg>e7H@eStLFkl%AaJP30eck^k3(M0A2Qn(6d^4vu706?SxW`}i< zp|8b~(?{A4)P`pQ#8NY(iuekE{%Q|1sEOpaA)&Kr_2U=wpRkERl(~x~`qJZ-Q1LJppWbMEqOi>;Pu--iG?vG-v3Ug>(_hgR2Z zRRD^mGVcL+$L)cJ$I06lhf8d-hK9qvrDEZ7%PTfRBr+Ea^{;&lV8-C~G5Ku>rryOk z`$XW*o7rr()+NhGQxy=Ioa_k&?kxeBaBS}LH*bJJjsr2W&OL|rJ^SK?n>T-KScHZv zU~Fvq@%y{fc`#g$AV1E01DGoTxZJy;tP@j%91P?E?5}b#TD;)+f`U7jVvu3wzB+rm-o&~BSjpM_44nrs zXty)K)Xdek6PVv0eh(;ZeVbjlQEOVwn_w(CeS}$Gg)@1^j&F2bfymT^_f#tCnl+v_ zy^;f{A;2q%>7#&J24TSAVj}1+pZR*YMIa1ljpb-69WhOCHIUIn`V-~a#t#z{m$R9J=Wl(A|QQ51&1|L&kc&}b8jwA$FLAntC|)FK8&u@MDJ z3sE0I^9TkXKu{1ucC(R)m@eRg2m$p4v=YR|N?5aVe~X!fB)ieB~VQ&n(SQGmm+yWkwf(bACHOO09Alq>dw@Xj}^%^bO%l^ z`ed+Q0~6SJ76E)UI{)sfJ`9s@s1DTHo(}dZFo7^ZDM2Y<;HdCwt?lW*VxZRYjG|Y7 zLl(wFoJ&J=wi;LTO0DUOBQ;Q8^iAP5Fb1|v+!-T?WHT9)ywqs<#z+h_TE2(<6sQ;* z)F-~hM$BTU7(Z(?eYdy)TlH2tYy2qxjQXv3ZUIH-ahB&A&GaGmu9toA#si0XHO_(V z02rb+roBg;y^R1M`|;b4;Xbqd1@sv>G4Fi`llTO5-C3q64JW>7!Uz#E5kK#J3%Ay8 zYkgM(r(XC#((?jvAse?MLsmWjfkQ6!s+Z{6+9mzyGjML%M}Bs_EOEwwOr&7tJK5d| zI$dez{S|!&NH&7jyZ$6GzUfNEe$#`{_CcTBZ+`|3!-~a#vkV!;ARCt{2n9pxiRUF07x%1N01Tjk8i7tV4+nF)OWU7IfF0|7c z7VMA^{R33uf*4{#{IND6P+&z&p!24B-qG^tkpH{BpTzQRoZ)8%z)E(Z#%!< zo2hs|%lq#Ae$V&3@7#Cq0D(Xt5C{YUfj}S-2m}Iw{}&up;(SGAQeOfvkS;V9a;Hb3 zVce5{8D0lSEL8310N?L0 z@ry>;oC2v~$Qp_PrMjZE-|cyT$GcmhOHVy(-n})$jck<-!GO|bjj!$1S0Lt+&m>qj z6*xad0@d+9c=}|qx>}sotYRgc~vh)kyZd4NMsWQyW{Rg7|7A} zvo$~tpIo-@kk&nI_>QQBpABd?iuAIbgb?X+gK) zD;`}G-(lBQA-+afgsrmK40P&WbWYabWXEWTF+3pgh1qftE{>$Sdx zCP>AAVyt;1-2kwseO!TtB~6uTcJ7GwLVNayk* zz|#HgrUl`7X@WlczHC0~=l;;M0j0X4_229{ktbXsnHJy7A&~T%u=vu3dGFfM?G9Of zdNQDNS>tQZ=n8=OMD}L!?x!mgB#?mdsE?l;=ds!>|LQhY*9N?DT~BXpY8im@32I$x zhEjZ6PH!g=_$HTQx!e0gR|ZUet%+z;H3(Y|AripeS}s*cz}g(RwG0AxA4Z(L_a+~7 z4AE)A^s@FFs}%qT6OZ~k;ADaS{_rEjBaH?AveVKXKZ7qX>7cP%#cnPh*zVMLh(@bZ z*LA?RP6G^zoZaMJCj;@k0e!UK?RG|If^TjK42LPaw)sv}Xnc60Fn(7b9V zJ7EG+y;xPrx5VjyLPe)xbjIW4aJTsZal{jX<;RT$ezN1dVr(}A`2L>y&qHAI&b*1* z$2=#hCl_CB?jAs%ZSAU07J>zNcGNNgfj}S-2m}IwKp+qZ1OlVxA3TpxeLL5q^#A|> M07*qoM6N<$f~7^#Jpcdz literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..c3368d096febea4a232751a41d2983faec3a6248 GIT binary patch literal 554 zcmV+_0@eMAP)-~a#t+(|@1R9J=WmA`9KQ545N-1>OgLbV1%8?&cyvDXH}9aCQ%oL`=sdEZOEo;r{!lqbx^Y6im?1~glb3^?MUmMWAd z{)s>;Uzv8EMc{yeA$)t*yqOFba-PL>wtS(l0-4;yYtH;LU;r?&wRj83e9)BviRYPo z`RZ0>jeky-fm^hydhMq8R((uDE_kV|jC{RAskD9TItNZ%F76*Z zoSX-)0GRNy-imKZ2+20TvnOVW>-B1GV@H8>c5YB^?J33-1}5`r9kI~-)(Np-K5?mD z&HdOWaI*0DP{JB7FwO>ndoJFVKx&`3rN&xw`rZ89?*Q>%ixR%^0T^nVDb#Pe8y)+6 sE}n>g1P(&TyI}A1rLhqa5fT02Cur)Jpk8i6-T(jq07*qoM6N<$f|=0(4FCWD literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a63819665cb7acac0824a9a0607e2866c2c3da92 GIT binary patch literal 1053 zcmV+&1mgRNP)-~a#v&q+iAxE&$JMc6R>qYw6;*?bg!v0Gw>`Fn|I=yN~3HJ?Wu^ z`MJrNcIs(k0756*eVoACRX((%$KCbFd}-n zxlPIp(6Rv1*}@BAS(gE9s(da20i+J|Wf;2?HW|otU(S2J38?{E5XiUw_kv90I5LXp7AEkSDhzigrB>);=X35Z>kk` zGsU++c!=EE61RPuLI^Op4gtLMxV!WAeCguXjn3O(075sj@fgT=A{D@}#pZ#sa|!^4 z!scL)yKCKiY2s2N?+p6o8XC(M_f%0R)>65s>uT>O72y9laJXD`s)1bmq_>D-B;U zfb_vrz2f^*077jj8*6Y9KtPL-pcmoywvoYa&W`?EZEV#5oQ$`Plqmqcp%n$BY4fgM z0a^%$0Q?Bc49P)-~a#wnn^@KR9J<@m)UmWMi7R-W)Tu#P@Ke`@gzA}-v6C)F`h{r&lqeY z86>D&)ZeI)adMZ`IUI>r*Y?-e4Oj^l_|M4#SQ(^z39KPl_mN8=8kQyRlSE2fvt(_X ztnKuE03Lesm%uvo77oA#FaWAVS&$JE*bO0!fpO2J7Oa7+l@U?70S%B#{v$9vb=dbU zzwfD+-!PhL4>|eny`Va#40r(^&40r(w*u97B zqr3oE$cuB7ew)DV2C`crl1twjxPfpBFp~0s!#3Ctah)eK5paH!7%U~{0w^QF@BfG6}0c*5iV z4X}c+8716fDbMBI8n}|hIh0R=aRO!?4eUXrwtFhPn6$`XARKZN$5itN`2hO3Y*K#Spx6K@~9ljK{K;^&`PnLv;z$wIg+o zY$2I7FqH#Sy3!j-_8bqvmlS~sv@c0*7K*jumR-Yi6-g8I8P5;g|z zd%gY2jgEY@V0(Xt9oREoh6B1JKdFLYQr}6Fsnb2$$Gv-F=`g!X9Ey}qS;-7l=WNF? zg7G2ohUC3Xgp7d3J-0RLOn63H(jQVv9e6c82g!4PhPh9Np1?kxYtNRvzuFgt?VwRt z3)XE82KBIKz%YS*rQb4{Cw+rYMsDAjl%Z8A^{g%Wb>HF%r+FS?+rFkd14Ih1->m>U z?u$8K%5YN|&NNuSOS6>X0&lr$HkLx%0N+ZuNwy9l7CRs^b|3ko0XqmomD|=2BsBit zz%zd%A)o(Y8tyorcGe{Yy0z)Lvp*}+K&#&zQL7Bvb{1us9z^K+Sgv_KwyfaO!S zyegy|H*CC#Uj_-|2I{h7qV|Rq4;uL`KHd6f!IUD@f8gyl__IugS2mL|Cn4DT=HeOb zhHl^#_(|q>Jf3@?bfoG*m!S1f0@Wdpdw<5epN@Adp}3XIZE65+KzIfl(8YWtZw?SP zU@hdhsV;8zK^e-k0 zsDA7&BmZ_W0q3ngbY*>VG5PJx#pKxA_kwL8D>EGafq!o@c`$@=diTq9Fm8R+j%vJT z?8V#A4W>28)$EPSY4qZlaKq$%qW1}GH9IDilo;LRR0g@Q81tUPYxtk9=YIo;eA7Ga SGEd(C0000-~a#&h)G02RCt`_n_F*N#}RlQa0Hj9P&x8#Q>Y-FpZ~=FpYm-EXaT3beJSXB0q$`zZ-r8lEszP2k3d$9 zF>4?TM*9ZHy#GA~au4LL|IC2g0U5F*r0&NosNm(U$1&mi=Rh{|M^%~y?HeG!1}R_j zh|2`XpY_39-!@3aXn)&3x8f&Tj_}494R~76m)hYQJPYsux=*0?DroB{U6jcwyqGtbFp$Q?G*IRrpjy4{ z$7}&FRG|+A@x(0o|B2~JGy*nHn?3sQ3W+!o50uLuJnAl6LKKVkDEe$fp15cpZM8DU>Y^4d-k)^hWZQCpI8BY z02YAHfaid>JnZ=Ad#c;qRnf#-1M?ljDC62KI27BLTc=D+h>=`mR$pc=W^SH|7t z_&kma?ox3#`_XO)J-i<91U-7;kRIwOPRCd+B{=6-F96v_l}srxcL%_I;L@9`SLp5u zO`f07+yo`)`r}qR#P;{6fi6gRX8Sr;?gK~Y%73k61)u|+6R0ne(P!=maVoVST8zP|2;R97W=%S^(?TA4-QOOUE3;3c?2G}CjIkNl(o^)k5Uc~pXD zegQZ}SL_>OceVZaGP>dio{s-$UoLt(@utsbe?yvN9~GDvnrs43;G_eMDYD_QsRK%= z1aE`e3GDYRY~?o%M+IqUr2x(JZUIk+hs3Ebe;*BJhXqn67{0w<2%oufC#bi&0gVIn zNM)c%2`=U10Vp880rN*jdje%8wDORgvy_`UQFxzW-#>)36bK+UPJC*7&FZxTumD*0 z-@1et2UZv)Gz^b1ft-``5-yC?dj^VxY0>%$Ltq6*;9BAAD8cjxJEt&|HatAnh3cq$ z+ck0x?hIAt8HfciL2*=f6PsRxZe-qKAq>5-xv3vf^jxkzwgSs=Woh%kKghI~?DiCz zP#g}Z%?G;`3y&eo2K1$q^jxX$)Z>~#_JNA$lY)Evb}aIASF z0hFJi_BY1Wvk{KW@*a?yq!7|=|HywvScgI=5wqp%yc|Fgv%?6#%Fhv> z`BBzkC=`t!TRFx8NOI>nZFvJC66llOCl)C@O9(PU>gnBh?f}H+7qeiQ!6OE@I6nqF z2UbRCdm>gjN%8^7|0IO&c>H^MuL(Ybo%2az0d#!Z zGI}1-3k8lmy#nlKx3QqPLs`$}5Yuz_PjKyEj)FX+1p=Bl*^TC0(_k%OJPC)zp}YDx z+YSs0wldl2_y~ko*B0!d!Hosa$P`xKZ)IQmZZNhED-`A=lfcV_4F5 zUx~8nZQK>m@@Fu~+rJL;2?RoD-9{56R!*`U&=~hEqt<9FCD=yor5Qi_ZEj>=0XT!k zGMt=^;U!)JoG8wj6$WK@F)UMjypkG)oLRL5aE2ZJq>XVJ=SACa?li(*aKzhy`##nly0UbjiAn*X=8EO4#o06|e{OOI2L5IG(RB z&W~MzNsl8u^PvzZ0jqZU4%9SXRKR`f8|p+>AU1>XmD49^IU2w+S|`*G#$5uxMX$$~ z4V{;ypia^F{5>y(VTlhRtu>&5y3tlm&n57C;8O;dqlpLtDgv*Uuypeg(B(ag^ddBwParr^U1p5$&K1C{`~K$T2M?92I8m0sjq{4W}l-%cmU@oP(4y23(Z?!=V&Aqn@Jmh zgA2dAs>ur!Asl;Vys0xC%VotcOCE0$BYXfn1P;Kx491t^dq(RB#LRR(ArH}lMbInn zW#7IZv>PB|_ltw-q-U^G;Ki+vzp5|rw)o7ClR}d_1Lr4GE?>`D2k>U- zee6U@GUoqKE)Ti@^7Fj;m8M#XT)F%m%(7k^`N!BVOstZ7VL}}Gf`#z{Lpo-A%!xys z1-x&F&(O1s;E2$8wjQ_$!is(-TPRK@H2mtaP`pQb~r37B-upHHDRaz_av&seE|j?RH4oWc=iTPlkLEbxT20hCNN6PJf1pvEgQc$ zSwgSMk|R`Q;9uaGI3#QHtQRMRLEP)-~a#wnn^@KR9J<@m)UmWMi7R-W)Tu#P@Ke`@gzA}-v6C)F`h{r&lqeY z86>D&)ZeI)adMZ`IUI>r*Y?-e4Oj^l_|M4#SQ(^z39KPl_mN8=8kQyRlSE2fvt(_X ztnKuE03Lesm%uvo77oA#FaWAVS&$JE*bO0!fpO2J7Oa7+l@U?70S%B#{v$9vb=dbU zzwfD+-!PhL4>|eny`Va#40r(^&40r(w*u97B zqr3oE$cuB7ew)DV2C`crl1twjxPfpBFp~0s!#3Ctah)eK5paH!7%U~{0w^QF@BfG6}0c*5iV z4X}c+8716fDbMBI8n}|hIh0R=aRO!?4eUXrwtFhPn6$`XARKZN$5itN`2hO3Y*K#Spx6K@~9ljK{K;^&`PnLv;z$wIg+o zY$2I7FqH#Sy3!j-_8bqvmlS~sv@c0*7K*jumR-Yi6-g8I8P5;g|z zd%gY2jgEY@V0(Xt9oREoh6B1JKdFLYQr}6Fsnb2$$Gv-F=`g!X9Ey}qS;-7l=WNF? zg7G2ohUC3Xgp7d3J-0RLOn63H(jQVv9e6c82g!4PhPh9Np1?kxYtNRvzuFgt?VwRt z3)XE82KBIKz%YS*rQb4{Cw+rYMsDAjl%Z8A^{g%Wb>HF%r+FS?+rFkd14Ih1->m>U z?u$8K%5YN|&NNuSOS6>X0&lr$HkLx%0N+ZuNwy9l7CRs^b|3ko0XqmomD|=2BsBit zz%zd%A)o(Y8tyorcGe{Yy0z)Lvp*}+K&#&zQL7Bvb{1us9z^K+Sgv_KwyfaO!S zyegy|H*CC#Uj_-|2I{h7qV|Rq4;uL`KHd6f!IUD@f8gyl__IugS2mL|Cn4DT=HeOb zhHl^#_(|q>Jf3@?bfoG*m!S1f0@Wdpdw<5epN@Adp}3XIZE65+KzIfl(8YWtZw?SP zU@hdhsV;8zK^e-k0 zsDA7&BmZ_W0q3ngbY*>VG5PJx#pKxA_kwL8D>EGafq!o@c`$@=diTq9Fm8R+j%vJT z?8V#A4W>28)$EPSY4qZlaKq$%qW1}GH9IDilo;LRR0g@Q81tUPYxtk9=YIo;eA7Ga SGEd(C0000-~a#&h)G02RCt`_n_F*N#}RlQa0Hj9P&x8#Q>Y-FpZ~=FpYm-EXaT3beJSXB0q$`zZ-r8lEszP2k3d$9 zF>4?TM*9ZHy#GA~au4LL|IC2g0U5F*r0&NosNm(U$1&mi=Rh{|M^%~y?HeG!1}R_j zh|2`XpY_39-!@3aXn)&3x8f&Tj_}494R~76m)hYQJPYsux=*0?DroB{U6jcwyqGtbFp$Q?G*IRrpjy4{ z$7}&FRG|+A@x(0o|B2~JGy*nHn?3sQ3W+!o50uLuJnAl6LKKVkDEe$fp15cpZM8DU>Y^4d-k)^hWZQCpI8BY z02YAHfaid>JnZ=Ad#c;qRnf#-1M?ljDC62KI27BLTc=D+h>=`mR$pc=W^SH|7t z_&kma?ox3#`_XO)J-i<91U-7;kRIwOPRCd+B{=6-F96v_l}srxcL%_I;L@9`SLp5u zO`f07+yo`)`r}qR#P;{6fi6gRX8Sr;?gK~Y%73k61)u|+6R0ne(P!=maVoVST8zP|2;R97W=%S^(?TA4-QOOUE3;3c?2G}CjIkNl(o^)k5Uc~pXD zegQZ}SL_>OceVZaGP>dio{s-$UoLt(@utsbe?yvN9~GDvnrs43;G_eMDYD_QsRK%= z1aE`e3GDYRY~?o%M+IqUr2x(JZUIk+hs3Ebe;*BJhXqn67{0w<2%oufC#bi&0gVIn zNM)c%2`=U10Vp880rN*jdje%8wDORgvy_`UQFxzW-#>)36bK+UPJC*7&FZxTumD*0 z-@1et2UZv)Gz^b1ft-``5-yC?dj^VxY0>%$Ltq6*;9BAAD8cjxJEt&|HatAnh3cq$ z+ck0x?hIAt8HfciL2*=f6PsRxZe-qKAq>5-xv3vf^jxkzwgSs=Woh%kKghI~?DiCz zP#g}Z%?G;`3y&eo2K1$q^jxX$)Z>~#_JNA$lY)Evb}aIASF z0hFJi_BY1Wvk{KW@*a?yq!7|=|HywvScgI=5wqp%yc|Fgv%?6#%Fhv> z`BBzkC=`t!TRFx8NOI>nZFvJC66llOCl)C@O9(PU>gnBh?f}H+7qeiQ!6OE@I6nqF z2UbRCdm>gjN%8^7|0IO&c>H^MuL(Ybo%2az0d#!Z zGI}1-3k8lmy#nlKx3QqPLs`$}5Yuz_PjKyEj)FX+1p=Bl*^TC0(_k%OJPC)zp}YDx z+YSs0wldl2_y~ko*B0!d!Hosa$P`xKZ)IQmZZNhED-`A=lfcV_4F5 zUx~8nZQK>m@@Fu~+rJL;2?RoD-9{56R!*`U&=~hEqt<9FCD=yor5Qi_ZEj>=0XT!k zGMt=^;U!)JoG8wj6$WK@F)UMjypkG)oLRL5aE2ZJq>XVJ=SACa?li(*aKzhy`##nly0UbjiAn*X=8EO4#o06|e{OOI2L5IG(RB z&W~MzNsl8u^PvzZ0jqZU4%9SXRKR`f8|p+>AU1>XmD49^IU2w+S|`*G#$5uxMX$$~ z4V{;ypia^F{5>y(VTlhRtu>&5y3tlm&n57C;8O;dqlpLtDgv*Uuypeg(B(ag^ddBwParr^U1p5$&K1C{`~K$T2M?92I8m0sjq{4W}l-%cmU@oP(4y23(Z?!=V&Aqn@Jmh zgA2dAs>ur!Asl;Vys0xC%VotcOCE0$BYXfn1P;Kx491t^dq(RB#LRR(ArH}lMbInn zW#7IZv>PB|_ltw-q-U^G;Ki+vzp5|rw)o7ClR}d_1Lr4GE?>`D2k>U- zee6U@GUoqKE)Ti@^7Fj;m8M#XT)F%m%(7k^`N!BVOstZ7VL}}Gf`#z{Lpo-A%!xys z1-x&F&(O1s;E2$8wjQ_$!is(-TPRK@H2mtaP`pQb~r37B-upHHDRaz_av&seE|j?RH4oWc=iTPlkLEbxT20hCNN6PJf1pvEgQc$ zSwgSMk|R`Q;9uaGI3#QHtQRMRLEP)-~a#wnn^@KR9J<@m)UmWMi7R-W)Tu#P@Ke`@gzA}-v6C)F`h{r&lqeY z86>D&)ZeI)adMZ`IUI>r*Y?-e4Oj^l_|M4#SQ(^z39KPl_mN8=8kQyRlSE2fvt(_X ztnKuE03Lesm%uvo77oA#FaWAVS&$JE*bO0!fpO2J7Oa7+l@U?70S%B#{v$9vb=dbU zzwfD+-!PhL4>|eny`Va#40r(^&40r(w*u97B zqr3oE$cuB7ew)DV2C`crl1twjxPfpBFp~0s!#3Ctah)eK5paH!7%U~{0w^QF@BfG6}0c*5iV z4X}c+8716fDbMBI8n}|hIh0R=aRO!?4eUXrwtFhPn6$`XARKZN$5itN`2hO3Y*K#Spx6K@~9ljK{K;^&`PnLv;z$wIg+o zY$2I7FqH#Sy3!j-_8bqvmlS~sv@c0*7K*jumR-Yi6-g8I8P5;g|z zd%gY2jgEY@V0(Xt9oREoh6B1JKdFLYQr}6Fsnb2$$Gv-F=`g!X9Ey}qS;-7l=WNF? zg7G2ohUC3Xgp7d3J-0RLOn63H(jQVv9e6c82g!4PhPh9Np1?kxYtNRvzuFgt?VwRt z3)XE82KBIKz%YS*rQb4{Cw+rYMsDAjl%Z8A^{g%Wb>HF%r+FS?+rFkd14Ih1->m>U z?u$8K%5YN|&NNuSOS6>X0&lr$HkLx%0N+ZuNwy9l7CRs^b|3ko0XqmomD|=2BsBit zz%zd%A)o(Y8tyorcGe{Yy0z)Lvp*}+K&#&zQL7Bvb{1us9z^K+Sgv_KwyfaO!S zyegy|H*CC#Uj_-|2I{h7qV|Rq4;uL`KHd6f!IUD@f8gyl__IugS2mL|Cn4DT=HeOb zhHl^#_(|q>Jf3@?bfoG*m!S1f0@Wdpdw<5epN@Adp}3XIZE65+KzIfl(8YWtZw?SP zU@hdhsV;8zK^e-k0 zsDA7&BmZ_W0q3ngbY*>VG5PJx#pKxA_kwL8D>EGafq!o@c`$@=diTq9Fm8R+j%vJT z?8V#A4W>28)$EPSY4qZlaKq$%qW1}GH9IDilo;LRR0g@Q81tUPYxtk9=YIo;eA7Ga SGEd(C0000-~a#&h)G02RCt`_n_F*N#}RlQa0Hj9P&x8#Q>Y-FpZ~=FpYm-EXaT3beJSXB0q$`zZ-r8lEszP2k3d$9 zF>4?TM*9ZHy#GA~au4LL|IC2g0U5F*r0&NosNm(U$1&mi=Rh{|M^%~y?HeG!1}R_j zh|2`XpY_39-!@3aXn)&3x8f&Tj_}494R~76m)hYQJPYsux=*0?DroB{U6jcwyqGtbFp$Q?G*IRrpjy4{ z$7}&FRG|+A@x(0o|B2~JGy*nHn?3sQ3W+!o50uLuJnAl6LKKVkDEe$fp15cpZM8DU>Y^4d-k)^hWZQCpI8BY z02YAHfaid>JnZ=Ad#c;qRnf#-1M?ljDC62KI27BLTc=D+h>=`mR$pc=W^SH|7t z_&kma?ox3#`_XO)J-i<91U-7;kRIwOPRCd+B{=6-F96v_l}srxcL%_I;L@9`SLp5u zO`f07+yo`)`r}qR#P;{6fi6gRX8Sr;?gK~Y%73k61)u|+6R0ne(P!=maVoVST8zP|2;R97W=%S^(?TA4-QOOUE3;3c?2G}CjIkNl(o^)k5Uc~pXD zegQZ}SL_>OceVZaGP>dio{s-$UoLt(@utsbe?yvN9~GDvnrs43;G_eMDYD_QsRK%= z1aE`e3GDYRY~?o%M+IqUr2x(JZUIk+hs3Ebe;*BJhXqn67{0w<2%oufC#bi&0gVIn zNM)c%2`=U10Vp880rN*jdje%8wDORgvy_`UQFxzW-#>)36bK+UPJC*7&FZxTumD*0 z-@1et2UZv)Gz^b1ft-``5-yC?dj^VxY0>%$Ltq6*;9BAAD8cjxJEt&|HatAnh3cq$ z+ck0x?hIAt8HfciL2*=f6PsRxZe-qKAq>5-xv3vf^jxkzwgSs=Woh%kKghI~?DiCz zP#g}Z%?G;`3y&eo2K1$q^jxX$)Z>~#_JNA$lY)Evb}aIASF z0hFJi_BY1Wvk{KW@*a?yq!7|=|HywvScgI=5wqp%yc|Fgv%?6#%Fhv> z`BBzkC=`t!TRFx8NOI>nZFvJC66llOCl)C@O9(PU>gnBh?f}H+7qeiQ!6OE@I6nqF z2UbRCdm>gjN%8^7|0IO&c>H^MuL(Ybo%2az0d#!Z zGI}1-3k8lmy#nlKx3QqPLs`$}5Yuz_PjKyEj)FX+1p=Bl*^TC0(_k%OJPC)zp}YDx z+YSs0wldl2_y~ko*B0!d!Hosa$P`xKZ)IQmZZNhED-`A=lfcV_4F5 zUx~8nZQK>m@@Fu~+rJL;2?RoD-9{56R!*`U&=~hEqt<9FCD=yor5Qi_ZEj>=0XT!k zGMt=^;U!)JoG8wj6$WK@F)UMjypkG)oLRL5aE2ZJq>XVJ=SACa?li(*aKzhy`##nly0UbjiAn*X=8EO4#o06|e{OOI2L5IG(RB z&W~MzNsl8u^PvzZ0jqZU4%9SXRKR`f8|p+>AU1>XmD49^IU2w+S|`*G#$5uxMX$$~ z4V{;ypia^F{5>y(VTlhRtu>&5y3tlm&n57C;8O;dqlpLtDgv*Uuypeg(B(ag^ddBwParr^U1p5$&K1C{`~K$T2M?92I8m0sjq{4W}l-%cmU@oP(4y23(Z?!=V&Aqn@Jmh zgA2dAs>ur!Asl;Vys0xC%VotcOCE0$BYXfn1P;Kx491t^dq(RB#LRR(ArH}lMbInn zW#7IZv>PB|_ltw-q-U^G;Ki+vzp5|rw)o7ClR}d_1Lr4GE?>`D2k>U- zee6U@GUoqKE)Ti@^7Fj;m8M#XT)F%m%(7k^`N!BVOstZ7VL}}Gf`#z{Lpo-A%!xys z1-x&F&(O1s;E2$8wjQ_$!is(-TPRK@H2mtaP`pQb~r37B-upHHDRaz_av&seE|j?RH4oWc=iTPlkLEbxT20hCNN6PJf1pvEgQc$ zSwgSMk|R`Q;9uaGI3#QHtQRMRLEP)-~a#wnn^@KR9J<@m)UmWMi7R-W)Tu#P@Ke`@gzA}-v6C)F`h{r&lqeY z86>D&)ZeI)adMZ`IUI>r*Y?-e4Oj^l_|M4#SQ(^z39KPl_mN8=8kQyRlSE2fvt(_X ztnKuE03Lesm%uvo77oA#FaWAVS&$JE*bO0!fpO2J7Oa7+l@U?70S%B#{v$9vb=dbU zzwfD+-!PhL4>|eny`Va#40r(^&40r(w*u97B zqr3oE$cuB7ew)DV2C`crl1twjxPfpBFp~0s!#3Ctah)eK5paH!7%U~{0w^QF@BfG6}0c*5iV z4X}c+8716fDbMBI8n}|hIh0R=aRO!?4eUXrwtFhPn6$`XARKZN$5itN`2hO3Y*K#Spx6K@~9ljK{K;^&`PnLv;z$wIg+o zY$2I7FqH#Sy3!j-_8bqvmlS~sv@c0*7K*jumR-Yi6-g8I8P5;g|z zd%gY2jgEY@V0(Xt9oREoh6B1JKdFLYQr}6Fsnb2$$Gv-F=`g!X9Ey}qS;-7l=WNF? zg7G2ohUC3Xgp7d3J-0RLOn63H(jQVv9e6c82g!4PhPh9Np1?kxYtNRvzuFgt?VwRt z3)XE82KBIKz%YS*rQb4{Cw+rYMsDAjl%Z8A^{g%Wb>HF%r+FS?+rFkd14Ih1->m>U z?u$8K%5YN|&NNuSOS6>X0&lr$HkLx%0N+ZuNwy9l7CRs^b|3ko0XqmomD|=2BsBit zz%zd%A)o(Y8tyorcGe{Yy0z)Lvp*}+K&#&zQL7Bvb{1us9z^K+Sgv_KwyfaO!S zyegy|H*CC#Uj_-|2I{h7qV|Rq4;uL`KHd6f!IUD@f8gyl__IugS2mL|Cn4DT=HeOb zhHl^#_(|q>Jf3@?bfoG*m!S1f0@Wdpdw<5epN@Adp}3XIZE65+KzIfl(8YWtZw?SP zU@hdhsV;8zK^e-k0 zsDA7&BmZ_W0q3ngbY*>VG5PJx#pKxA_kwL8D>EGafq!o@c`$@=diTq9Fm8R+j%vJT z?8V#A4W>28)$EPSY4qZlaKq$%qW1}GH9IDilo;LRR0g@Q81tUPYxtk9=YIo;eA7Ga SGEd(C0000-~a#&h)G02RCt`_n_F*N#}RlQa0Hj9P&x8#Q>Y-FpZ~=FpYm-EXaT3beJSXB0q$`zZ-r8lEszP2k3d$9 zF>4?TM*9ZHy#GA~au4LL|IC2g0U5F*r0&NosNm(U$1&mi=Rh{|M^%~y?HeG!1}R_j zh|2`XpY_39-!@3aXn)&3x8f&Tj_}494R~76m)hYQJPYsux=*0?DroB{U6jcwyqGtbFp$Q?G*IRrpjy4{ z$7}&FRG|+A@x(0o|B2~JGy*nHn?3sQ3W+!o50uLuJnAl6LKKVkDEe$fp15cpZM8DU>Y^4d-k)^hWZQCpI8BY z02YAHfaid>JnZ=Ad#c;qRnf#-1M?ljDC62KI27BLTc=D+h>=`mR$pc=W^SH|7t z_&kma?ox3#`_XO)J-i<91U-7;kRIwOPRCd+B{=6-F96v_l}srxcL%_I;L@9`SLp5u zO`f07+yo`)`r}qR#P;{6fi6gRX8Sr;?gK~Y%73k61)u|+6R0ne(P!=maVoVST8zP|2;R97W=%S^(?TA4-QOOUE3;3c?2G}CjIkNl(o^)k5Uc~pXD zegQZ}SL_>OceVZaGP>dio{s-$UoLt(@utsbe?yvN9~GDvnrs43;G_eMDYD_QsRK%= z1aE`e3GDYRY~?o%M+IqUr2x(JZUIk+hs3Ebe;*BJhXqn67{0w<2%oufC#bi&0gVIn zNM)c%2`=U10Vp880rN*jdje%8wDORgvy_`UQFxzW-#>)36bK+UPJC*7&FZxTumD*0 z-@1et2UZv)Gz^b1ft-``5-yC?dj^VxY0>%$Ltq6*;9BAAD8cjxJEt&|HatAnh3cq$ z+ck0x?hIAt8HfciL2*=f6PsRxZe-qKAq>5-xv3vf^jxkzwgSs=Woh%kKghI~?DiCz zP#g}Z%?G;`3y&eo2K1$q^jxX$)Z>~#_JNA$lY)Evb}aIASF z0hFJi_BY1Wvk{KW@*a?yq!7|=|HywvScgI=5wqp%yc|Fgv%?6#%Fhv> z`BBzkC=`t!TRFx8NOI>nZFvJC66llOCl)C@O9(PU>gnBh?f}H+7qeiQ!6OE@I6nqF z2UbRCdm>gjN%8^7|0IO&c>H^MuL(Ybo%2az0d#!Z zGI}1-3k8lmy#nlKx3QqPLs`$}5Yuz_PjKyEj)FX+1p=Bl*^TC0(_k%OJPC)zp}YDx z+YSs0wldl2_y~ko*B0!d!Hosa$P`xKZ)IQmZZNhED-`A=lfcV_4F5 zUx~8nZQK>m@@Fu~+rJL;2?RoD-9{56R!*`U&=~hEqt<9FCD=yor5Qi_ZEj>=0XT!k zGMt=^;U!)JoG8wj6$WK@F)UMjypkG)oLRL5aE2ZJq>XVJ=SACa?li(*aKzhy`##nly0UbjiAn*X=8EO4#o06|e{OOI2L5IG(RB z&W~MzNsl8u^PvzZ0jqZU4%9SXRKR`f8|p+>AU1>XmD49^IU2w+S|`*G#$5uxMX$$~ z4V{;ypia^F{5>y(VTlhRtu>&5y3tlm&n57C;8O;dqlpLtDgv*Uuypeg(B(ag^ddBwParr^U1p5$&K1C{`~K$T2M?92I8m0sjq{4W}l-%cmU@oP(4y23(Z?!=V&Aqn@Jmh zgA2dAs>ur!Asl;Vys0xC%VotcOCE0$BYXfn1P;Kx491t^dq(RB#LRR(ArH}lMbInn zW#7IZv>PB|_ltw-q-U^G;Ki+vzp5|rw)o7ClR}d_1Lr4GE?>`D2k>U- zee6U@GUoqKE)Ti@^7Fj;m8M#XT)F%m%(7k^`N!BVOstZ7VL}}Gf`#z{Lpo-A%!xys z1-x&F&(O1s;E2$8wjQ_$!is(-TPRK@H2mtaP`pQb~r37B-upHHDRaz_av&seE|j?RH4oWc=iTPlkLEbxT20hCNN6PJf1pvEgQc$ zSwgSMk|R`Q;9uaGI3#QHtQRMRLE-~a#tKS@MER9J=WlCeqyQ4mGXO#-4Af~~CCO)0odcBXb0*!+GGhsDa?`GDlR6vp!+Md=f%g2=p0K{>0gXv^ir|IyiQUQP@iH?AK z0K}Se*;%MSp(FfD>W20!Xg`iuE-Do;vxdv^$+Y&e^?tYeSR^Cp3#Lf&3-fdBS(xde zXhtakfYE651xiEbO9_~n7TcWxSOR+UlV(z>K$_*pzz*;!CY$~KvMZVqe1tD9-xYQV zc%iL0j_yKof?mM6d_&j(z@&rF0 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f49651b704519d8039548111b93554bd743616e8 GIT binary patch literal 824 zcmV-81IPS{P)-~a#u>PbXFRCt{2n89lkK^Vo~w`tn6MJl58kW4lS1W(?I6{;5z1TQLr zA|C8P5CrMPo1h21iGP8h9;A2?M4@T5Tk3rc33fY5#6mc?0=;ekJB0A2#!J>5YvH8)0n= zDy2RX=xFDJCcKh=+g6TttbT*8n|cYxm5u@9s^|IVZD#q4(R;u~XkB{1pbPDK;9xwb z)H|D5A}Ig>Jnb(4=(rC!#L09z{l!*}$O-@ePx~CE#~chPrB=gcy(ZFgczNk-f0*73 z@SB;fyqrjP002}fmEHA5uoN=5q{8I5RNeq`D|@&W)Lolbvb z;*;$*dq-YCrBWG+#o|u^WLpMAH#4r9 zFzp{{0n8k0G=gac4z!K#x+;0YMutcW@Ji)744h~Y8PDBx>M{|9UXprEWCdvLPZ2QH zA`;%$YKb#M)UcH!l8cb%`KLg5+~!}7IXI}4s@Tk8y?~ z&SUix&|2rHiDzhCe1j02j$-kE#R7ca-^FldK-kkVV7}zK?h9Kv+6nz*+iMDi!ayUy z69V?N42W)JTy@VzhK(@31DM%~#}oGnINUaR=&Iy()BfEsUVzsAH4x6Vh=kYmwc15n zXZ`;$dI}T@g@Jf~;s=1lKb1cbc*1qv?xxW4w}ce%i;mU1&oc2 z)xnqqunb_H13H$?W<8Uhf*=TjAP9mW2!bF8-S`7)W!yzEP{e%z0000-~a#tTuDShR9J=Wls`*CQ5c7xSFKH~A&OcIw`_8Ba0zW_2)f!91sXx$ zph?cq(kG}?a0)VwhFTP)zJSo=l++Z_kW)kIJxyAT_guJ3_t{=J=l4Fm=MVV!`22Uo z>H4%)umJ|6;q3iQweMCS;AC;JSeyt?1w$XXTrTLTfKtjv^!B*!+mWHC0syUgF|$)Ja{SqFvt5B=x5XYZUv-o&y+!;2yY{;qn-+6vV|h( z9pF=hjrMir#c77|E67;+U5!)$TSPXS_0p|Lj?q7m&gR!ZYCr(wu+=DCnB;)L5v*JL zakMmm5F#h7M(NbFxru<-Py-?wE|c-aBR9!`1tsI1Etqq U!Ivu(wg3PC07*qoM6N<$f+F|8m;e9( literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ac318f5b193feb6b94a0363406d7d66b0b99b327 GIT binary patch literal 862 zcmV-k1EKthP)-~a#v5J^NqRCt{2nbAvAQ5?s==WIGR%A$xKs)t4qBt2A+kqOb9F_AJa zBYH~dY7j_&K+qoQEu!9vxh)^kg0&foEVoi0!XU7y%o4O7%7Vx;SB{)JrzdG%uMNR- zuF&~Bet)p<_kQo$&bfDhLZMJ76bgkxp-?CkivJBF+Q6&n9RQ94061w(#ar7%doBi{ z1srH-C@D(YGx-|j>|l31(ks$;F;JnO{>x=IN{rARPkp0XsP7_>@fF}^x--j46NyM# zw0|MQt^fe5>5qA<001&YbTSYK2=_09@BqEC5!u>2&}cQg2v zFuucNw5m$eZ;AG|yZ``5c7_KzL7h=2z%kL@%c1}Ppqvg{;%kMe5zk?LJqPPD8TE_y zw!DDa+GZEEBLQIZoB_xAR4h~>+TYRw{C>Y}+QB+NuqR(9;H{~6C?F$)r3Fl|(n}mT zlCKeh2h-ylPXjPLBrP=-9)+9E0Q|~amAr6fbCojR6j}2yRNr(IgvSj2A9K{cw9bEcbx7Ll|Ao+9z~^gm%(yZW07~-YH^q*k zihCVbr9AH!Lg)(kvgtSDKsH~pCRsuf;zP3@~@uu3^IA;RGKDC3VSo@U2Ks og+ifFC=?2XLZMJ76pBLp0qPRnQ|A&%@&Et;07*qoM6N<$f-F6M9RL6T literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..0a98eab661d03ac7e32e571db7027a8288476f57 GIT binary patch literal 395 zcmV;60d)R}P)-~a#tJxN4CR9J=WlRqy*VHAg-b6dgCh;PtcV!PVOVl+rAY{F*n2_zCa zSbPD0(!r|qb}>sVqMg(S5G=x?lZ4d!Gf+)z_r1wo+-Ez;<)K7f1Q{$v7@6-HbgC<4zpSus_Ca^$v=tpIPB&0j6rL);ASUoaDC)zC5Ege`Qc zcJ7nowSlmuIYV^-VH>`~y#&HDO$AaD$eXm+soH_>@c06f1%VpC1g4Yg+h8-vaDaT= p27@QyZmbuqQ8SlRAR{9q;|oS`VxgOVQ)&PJ002ovPDHLkV1ir&sn-Ai literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..39fd0d0e20408fe2f4c44537abea487c927232a1 GIT binary patch literal 810 zcmV+_1J(SAP)-~a#u+(|@1RCt{2nNLVmQ5eO~dGpfIAW4W8K~NB_szu?OFd-rcB^qZe zBU)4t2tl-I7v!RL5ws7|MMzkV=3)pUZJ~|Na!~{!6h!|PB^C-P_}=|mgfV}f4TAT+ zp!-{X2j-kP?>_FGJAlPvu~;k?i^XEGSS*(R4eB=Va$z69Qvg8n+(d@Gx; zLYi+Cc{oC9_HyA3Q#r~p`VKzN@QIKYD-~W&<>a)003TO`5It*g&;hs+xwp= z0010?=~#T@FfGS>D4P`}Up^PXGu_^?7qE9&>JiE?h;1bT<=SM2)2!P+)&frSOTrDL z4?t6?BDei^r`tq^SPS^zs+$1P#WMjO)opYxfQ&pOtu^r-g$LylL~fOhU%Cmln7k>9 zrGTaZ$&fNo=KskFm@0Jgv&k&R3rG!#CrU;E)D?~Ap?JVQ&R3@MButw9z73WU0>xKk z0l>81!Gg&w%S2vS>R^ArG%82(0Lsq(?DDgGY$``NMs|VLywoaJh5+m=5k#*0S>7>` zVI}kz&@ImFqUr(AQYy$@KkHo8?q3D%1$eu0W%<9sBAzxTo%5#l`oE!d7ii5(?d+ob z0FW#izgbtq=CPwR@_WA;T35i=k5B-Xibo{d{*^BeXf9x?i%SI00+<0Xt;i!28NS!) oX|Y%=7K_DVu~;k?i^WonUqqD5zQp;Us{jB107*qoM6N<$g1Y}}+W-In literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..049f4bfe5b19f10aa7aff62c79504b1325cc580b GIT binary patch literal 415 zcmV;Q0bu@#P)-~a#tQAtEWR9J=Wlr2a@Q51l`^EMC^6=%_A7c9P2iVsLQUQG5 zv=WK_PN+C%(Fy>(Jbx+N+m?qEQ0W~St_h3*Pwk{L7PLdCkHlR{6+rSp%Q!l7xu3rY z+Qa%4OlFJoB2ov85oh+IymDgGCuviZ_KMSr)BqG&wjB-@JCI)78&~8QNTRxZUdfeh zhg%4!7{@e#LEx}C`nDcsI9ObPz=NQ-eV+ph_<0jnASNaz<_DfNVK)kGW#s?>002ov JPDHLkV1jNavM~Sv literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f58ae2238795878b095402957666e8e663cc4fed GIT binary patch literal 867 zcmV-p1DyPcP)-~a#v6-h)vRCt{2nO{g#VHn1r@0`u)pcE^Tyi$y=y4smmCPW0GHx*&g zRYu}bYqKQiB4`(N7nyC5bAfsh5=jsRCIs0F&d`ILRZl3rtsJ<*!lN_pz81Q8zrGOF8R;q}kE z&d>AK&j!~C0DzJoMHy2701<2696TQG`q|)aps(*pLd`+GQBV86A;DWe8$zzYE1!EV zsj6FzdYbNiCc?vV2phqXo2SMZXrDo=(xLmVi1Lw+DpG7BH1K(gvw8+VO=_J1yNaFF z;}gM0qayt*YKzC&=<6Y(;~5QxilE>9TBH|K0ssI__k9E?V;@LZS@D}2t_e{-ObY;5 zen+s{2M1_ zJRtB(aOcUkLL@EyAS~Ve8T4T1>Bpjcq$6Yk%3NMsJc|1Owx!k?aCzA8?h@f)IrvY2 z$D?r(gxig?sQ$`uAc?&0XQZ%UclmigDE_n&0+PT?)CqI>s_GC<+T+=F$*B~ zZ;{xCh^khOb~Fq5y`K%P6ObRVB>}|#yk@|ZMTys}mBRy^0|*857z646OamB0GO_=q t|Lhl@ni7dbB9TZW5{X12kw_%j_zhW`+6*7@B2NGS002ovPDHLkV1i$@iOv83 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png new file mode 100644 index 0000000000000000000000000000000000000000..2109845651ae107d5b42a132ebeb2b63c05fb867 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i3T zaSVxQeS7X8=K%vA7RQsG_X~aVJUFfjzEL{2;QYD&eWt=L*Lv2htl>$mVP<3zaA06$ v*}}f(Rpad1iC2Xm{Eoa`|CEV=;fuBQEM5oS2dteyLm50>{an^LB{Ts5_Wv)5 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..91f3bd02d3decdf453be0c3183e86d1046087629 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C|K|5 z;uumf=k3iv-Ub5!)`QIdPX#zO3ryIkGS{#`fA+spwUYJE_g?=zP5RuYAMzXl{3|%g vz`61dH2SZ{KQ{izZIQO_lO51v5XgDNJSUg?%M|NgZxGkh)z4*}Q$iB}bw@uC literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..fe819bc14156ed1ea3822956c893ec996017b404 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!h|R zaSVxQeS7X8?*Ri27RRO-Y0&_t+8MKg7R*)B6PiEw|J-Xn0+F(jYio8G{bOci5pZB& vWa(ko`T8L4_C!I*<`->PE7@pPgY~%FbRCtXCXexuJtDnm{r-UW|RNX9X literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..58024770943348ff8b9ff6b2f3cce0cbc8eb8894 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C|K|5 z;uumf=k3iv-Ub5!)`QIXp$)88l2)CF5K7~@b9!0*T+X$x@4entzVo3@e|;mv*M?bS v;9KvRWuAWgm0h!}jtd3hWcP$g>7CIdvoF?@{UplWxaMtU)#d~+(DVTozze7WngD)BQ t?GJ|V%02(2MwzB0j2riW+82{qyqI`4!%RGme||udFdi{lm`0q0qp< u#Noj&@#*l|`IS#t?pzMfjot|~=%?H#WzM@Pt$ZLiFnGH9xvX6^Hy&uZm3F=sUykL%i7?31yS(o1a&e?R==$|G$ypYr`xu u@U4%G>poTdHMMj5&vfsH9nfA7nDc=7)_V571?xpwKwM8(KbLh*2~7a)&rGZU literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png new file mode 100644 index 0000000000000000000000000000000000000000..75cc027f81737e367517a2b2c7fd7bd243ff0d37 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6g2mA zaSVxQeS7X8FM|OGv*DGKH$@c1UJ88p@>ke0De!B`*C)>&=N=Ph1gb>>HS?9(T9x>P QPJ_feUHx3vIVCg!03<#lcK`qY literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7273705589c0fa5f768274376eab813eda018b3a GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7e7W z#WAE}&f5!)ybKBq%!W<%69rltdOq!tx{;dfkUf9*x1F03PkodxY2dqH<-ndHyMTEM w-v!1f_7@CmnM)e3FV!Z literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..01c6cffa7a4c41e39c8b2f2ad8ac1f60807ae0d2 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twho zaSVxQeS6MOkime1#Zm21Km$vQg00emJFowzD~qLmP5GK*cQ36*5U3al9AHmXX10!~ RUe5^<^mO%eS?83{1OVDFAaVcz literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..57789e942675a34da6a6a113f14ac483cffb93f6 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7eVe z#WAE}&f5!)f(!}_hYk4hH4ZTS({1SakioNNyWxVZ=VO1z+%$OlgWt-5JwtW@^A^4f xj8W__7}heEG+bk}a(K-kyP&jz?*h%FZRh@CDdo|gd;#cM22WQ%mvv4FO#sySP9XpQ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..599626230bff816cfdf552ed76a7623fc1e83c58 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twVk zaSVxQeS6N4m%)L9*|BKVgmy)hNpmg%+uA+Wt~$(698VhB#Hn4 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..34e7d603f7aeb233f097c963069f24011c1324da GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7e7W z#WAE}&f5!)f(!}_hYk3Gcep7jDBDOezs}{!cw2nkF5Jw=@?SIG1;!}$7Yu8eOB${* vS~TNylE{an^LB{Ts5L7_@f literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..6a54b0948d7de3b7b5b7651abdb8caaa23f91080 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twho zaSVxQeS6MOkime1#ZhgRKr4^V0}G`EcV7QbR~Ae4P4~^WyO&lY2vm#&4zOF=GtacN RR+9$_db;|#taD0e0sxX|9*h70 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fb74fd3243db35b207fc12b7309450008792736d GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7etm z#WAE}&f5!)f(!}_hYk3AD-Q9uIl5JtuwAFVdQ&MBb@05qCSH2?qr literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png new file mode 100644 index 0000000000000000000000000000000000000000..045f963fac6eb74a5b978c23fe7e58ebb2bb5027 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6pZk6 zaSVxQO-@+AaHsyqj)(saALpGiEey(s8C@%HvK4LRui!vd=O%0LfRBOU*>|4Kg7PwPpdAdJu6{1-oD!M^pK-}Q|reBL$x^Dg<98%{pXU%(LM z5X_*vK(j&Yf`|im2G;^s6V?k%vzRg%eHphjEW;uFl)2_f;a{ownT(&WG8r2m|Cj6? kQ^!bzMl9y)$UopezJmK0vr5!)pbr>4UHx3vIVCg!0OJ5vvj6}9 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..8630b91c95381b851e7caab3ef7ec5b0e92e31ca GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6pZwA zaSVxQO-@+Au%mT}2?z%yu?efrTFK}pYw)TekiEw$;R@qoK8XVM4FOpP>e<-Xy;eP0 zD9_Zx!^2*-cIIV=b^jRo8xiVC53FEjyTi!9I*-$STkes)KuZ`rUHx3vIVCg!0Ndp- Axc~qF literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..37d2cdbbd5479aeb25be4e5f3f5dde5be7229c0a GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7e$p z#WAE}&fA-Tyv+dutQVIal;YaZuqJ8+(~-uW%TLZq+&KB<-&>w17VDo|tarDndGfJ- z0Yj8SFoW&_%?7axA`aXcTnkuDST8WmV#;9jW!%!R42Sen=A2JE>Uz&_X}G!dz?n0D ne{WLN+uuMy6AtNV{2!R~!Z^z2CJB86dV;~z)z4*}Q$iB}VAWbf literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..38067367f8da378cc48efc893076fbcf831bd6db GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6b$op zaSVxQO-@+A5V7X(?Szfr@|jiB3<4L;luEe5xR_6(^uP*cH(7&M4UFXs+)v&9lrLD~ zCC8_DpyGjxK{4~rUF% AasU7T literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d80ccb8ccba7e3fd3c279a3ddad6adf020d60855 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7ekj z#WAE}&fA-gyoVhGj$X(V@p~A!;Gtm9>_Zh(uc;YK`a*N(U);c!!m{_hhPTX1)2?F7epMmGq@J8n&6Pmk$<4v|N8n5AMP2!+-J_%+;7$` j{LM;06AtOkwGHy(>0B;9-o5q#`hdaH)z4*}Q$iB}i(XaZ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..a306eb288f0ce1ee9fcfe32e951f50d99a870320 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6b$xs zaSVxQO-@+AFeAk$$Kd3Q8xEb4K2tK5u}PF3Si$TjYw)TekiEw$;ehM`Cstz_jg^zy uT{&bdjFtB{#++rAV_M9ItdM61GsDiw9CO`u&z=Gr&*16m=d#Wzp$P!Ei7pWU literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7044b28223febf305198af5cabafa1779416736a GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7eGZ z#WAE}&fA*@d7A?Sj$Ghfq*C?B&G60(P1}h^aZB>eH%v3#KDSZk`Cqx`f4$m$<^HpC zEnqcay}&e!DTC3MaZAH8hA4+%2Hgdk4PqBW9Jn)ZNJrWoaF@Hj{^LwBgWX~?X8yDj nkAC!tTLZr)9A>8dWU&9WisQ!fES)DnKQMT@`njxgN@xNAcS=?0 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png new file mode 100644 index 0000000000000000000000000000000000000000..445ec718101e8becb0f4b3952a52b66dd5a62721 GIT binary patch literal 404 zcmV;F0c-w=P)-~a#tMoC0LR9J=W(IHDiQ5eSY|9i)ZK?Fg|cHQ;~1Z_5xsB3~rtAgLb zVlns;WFQy}CP5I3pa_N)!R&p{J=gA-U~zjb8Wgs>yCisi@$m5Q99{^5APD|D$qQ)e zk1-Y^v8_0cpGGN7lB6b4=@g_h7gyFr#0F)f+%{thnD3k1t7gl2ap&BEMCAvNC5-93 zeC~i!#1?Q4Od@vWT(&(ZtD3DD(Jk04aAWqdGVJ#w4X9SD?{jfw6X6Ib8+PKH-#4=# z=S$LT7qJUq0yur^c2?^3`fFZ)A*$(~I^R?0O*Lz^+wHQMMTzr=>b$A*rfGKYd)zQ1 z2fsP@(lq*Kz=Xk_Ko?jAJ}}#<)#6r>zQO|l(llM{n_L1jUr*h>*hV9cuZwn#H2^?W y>qzNY!1sF6Y&0s5<93bB%%sS@gCGckKj{9KeK literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..febb31878907d870b65c1a4c7cd426b9e179fe47 GIT binary patch literal 813 zcmV+|1JeA7P)-~a#u-$_J4RCt{2)jx<7XBfxv?=!P^2zqFf5Z#%ZS+@}4HIXZ#LW&>( zl_Xf$NHi%#u&@Y$U<#2y3c(Pt5khRDMI;e~#Kbff5iV$Bby#S0-kDiJ&r>)QJ#XE8 zQb@wyaQ@+Db`^X+<@?P0+vj~|Uj~dZ#u#IaF~%5Uj4{R-^SY3-0co1Pt$4?QI?8uZ z6nrZpT0w6MaxUM7a2Nn(UmS;L%j8usfc!6o_j;C2+`l)odu(iMu55NMRh2AjeW`G$ zXL)A&_N_O@$H&`?&Gkw*h7>b)E*n|?XObi<%4Yxn8>+P|%a0Zg4;8$?(g9hPjdfMd z0dE#cm%AN*%j(su(lYr|Q&YC%DBVQ; zt#Q2S(js$LBHkI0b%oMh!TTtR>Jy7=q4*DAif=StIb zEuMd2fx}<#__Dr=!$U;_00_hI?%dq$2Pi)kN=p&_HOaEQFPi0C>wU$WKpCA^P%gHI zYwtFL;7S!eLq%7hm#TVMmVcwjR|}L6N29@h5$Qf{f10*-DS8YTnpY4`5Bc6F^?Ln5 zmHk#efd8avzDMCG;PHLaL)O_#bAPDXNOioS?kBqGNUeV7A5i0O`6op6n)ni`=0N~t>caZMyz{=ir zg{!{k=61V1?bn7*fov*lokiIZ$KmOI_Sg3T09?CvW7My8{{Ys$;Ff9a%7=|caG{@l zL4{v|XK6O;S?BTGM&R7@o>jQ&d#oSC;bA}n0BAOwGxzV!Y!URwXFT@zaLwBghT%Vh z>T4iZpqHwO%UTBo4i-wMe2-mW7(N_yPcMZ_^B-KAKXz%}PSX64st)Ym_{vb#T9PD7 rUUnbG7-Nhv#u#IaF~%5U%xmIb(SY>Qkdfy&00000NkvXXu0mjf|GIq< literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..3b840d7678dbb711fdcbda65cd2501255a8e6c0d GIT binary patch literal 422 zcmV;X0a^ZuP)-~a#tSV=@dR9J=W(lIYXQ5eSY|2Y){i4a1%5u1syiAA(&&_uPh)xZ@J zAHZf3AHb}&G-7C(2(3gyNH-C})HDgY?~RN+UBXy3n`n+F63+a0*@@Z3De*Z+=n>S}yXQst;d+38X+Y(^mL}B^27D{=Ugbhw4xMQpc%+^=$E;p{oOZHzwr-zeZ*M>wg8Q=^W3GEr-MQ7 z>bA0pQfmOBWaBiKUdM2GT>}8Z@x`d1_J9_F3k6kR5^xo=T*#+0we;0I03Z}!7y*3< zbOQ)fmGTqCT&7TKS6u@D!bzu3e9FM1_WkI|LFT63u0|*tIKr|l%lZ>O0C$CJFw~&s QX8-^I07*qoM6N<$f-vB_JOBUy literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d6c5b40ed2195fb73751770d977a7673d4c3ce2b GIT binary patch literal 872 zcmV-u1DE`XP)-~a#v8c9S!RCt{2)=z8{Wf;ft?=#!2M8q@!qXdFV55xjd>j{Wth215j zsmN}Z5Mr^W+eS=07!z-%@kWA?aA`vSBm_-Vrhhmn=$0mwq=-h!tsa1y2q8ug!I02W z_IO$|C(_LNDa}D)E*HR5+X!GB$=KI83Ej6LD??@y%s#4i}XJGMwgua2H zH$aqKz@IaYp>M=v@zD*L*5||KCvxvU6<>7eFz{YrG$pvV!`yv{;1K{w=khN)$5DY5 zf$%>>y@nqKy2j>`yD8JYxG3&hf%?GcDynY|4fKxAx%3_39|54?_xu*~bS-eA^ti%v zPTYxPrnTY!W^T&1t#sl}&9e9j=VVP3iwB5B5dv_2{LIZ2FRc5@#c$UFt4l`JBC>sX zUH#>WU&nrVkgW99{00>Yz_T+a`cswXHWvDOFGSTlvJC(@ckbt6^R~vp3zu(H1Fx5i zM4(}LUH$y#ZH>btBO~{GO(vW2I}r{6PtF(!gHKGwwj4R!dp*j|k^BbCCY{N*tI)~a zn|x?`!R>dBA2=`>?2^j1egg98-D$e7#{1_Z-}j4A_bl560HmARHmj-+%nyu4ox8PV zc<|s~0J&VQ`kH%sKS)d9JO%l1sK0w(xjL400|1iQ)>j4j4p=;MqGyZ6*k&)z70-~a#tK1oDDR9J=W(!VQ(Q2@sA@AJxHkW#Gt1r)vamdzwTikp~NDSv>? zB$LT3QU(JrDJ6>{@rt6%7G<%}9i;BPkAVTj>)uVyXFNSUJ*RUZ2!bH^@01nDZeDa~)Y&GtItDIL}zlE2GFS!G5|KxZ93i4*r`<#XHavV8{hP@y?1pE)2Z zYXaB=8in`c#FO7;<1G(h9|5hv;Y*~xpKkxF0jFbnPOmi%UIgle*K&#Hus=OtoOoLD zF3(q{Q7-WecQsGyunlBBmcGfu_=eR;uZ%dH_JY>25{d16tmXib$jBhz_dls%Zc~yz6$Ad<)ze q4V@QsU29kEY<>NVK@bGNpYsY0D{=*p^zVWI0000-~a#u$w@>(RCt{2)=fxMQ5Xi`_q|?AvLJ$>2#i)iK~&N>8iYjzCMhP& zBFYk?pGAuZqJog1MPLPPf+&b;5%@D#q`yt{1Lim|ftwZ?1+Aj2upl+B_iZEOTr14E zGeLdN@_gsKeCN9yW&mT1F~%5Uj4{R-V~jDz{4bbmKt;D!AIxg5Pq@<1H;kcl4Q&xxl_gtJg z$nn|6IuW#%ogwa7;OhQbPYWZ+1^`q)lpFVgOQFjH5q!X$2QUF12JkMlym_wFTh*oI zx#m~5YyQY5bqhQ+bzQ(19q!KM>jM!?5CCF5T0vj;0IUp^-cqbhHS*bPa?884)TM3% zSRX2Vq*#|~WbbTpr;6eUAYI4Tj?XFpPeP?7f}X^>RQsoy8#=YR*ij18FaJtlWfYeO zA{qby^dXYjGj;qLWxLT2U{Zyr1CTBOD4M!1 zsD0kBv-eRmN3#w{tnhFe(3$CJYAf@dV;u=jMBQiJ1^@tYPc;hE0irZi>J?a@-pLOD zu&P~i78C`SLGBCf6Ud|e4Q$I-k9i#c091BrUEt^rfTf|*U=dj}HjW{;Se+2IhU%jd zccmNY<+H!M4*&ql+g0Yex(i_S437*!+|l32R6hFxBK#HjolJsne4iT$Jea}uL8pk7 zg}6LWpaB3tCc)v)KDQIP{;NF_p877U`s(?zP<<8T31pENPX;X_TSApi$7fStf+K}& zr|<)q6iZHAA=nH+f-a;7oKwI1fACMLekiy4no9n5AI2DCj4{R-V~jDz7-P(T;yYh@ V^6If}(3}7O002ovPDHLkV1ltwTaN$$ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..8a7cffab5491b36d923c598813ce2848ce763f97 GIT binary patch literal 421 zcmV;W0b2fvP)-~a#tS4l)cR9J=W(#A) zh>hK>WTmFLcQYe-saaT9DJ2_4BCevWZIogq+HerY!jM5x)62Lop1+&;@uM& z)0fZ*&<`{R{_-nRxWGCogt&B4uDo*-+%KXKi$5f0mtdNSFi1U zR8UJm9k9`3J1LMa&u7|hLMgU^Fi8I8;XZP)KKmHdANU78v*MXalyW|X%bG~Necpas zuF8O6k@Mx`UbS5{4FKpJcRPzAxdv_wh@R$>m$i2Nf~fDGQPVU{`*Yp_S1V~n#B@xB P00000NkvXXu0mjftnj$$ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..24e282c85cf22a5c2101f14a54effe7bff4249d8 GIT binary patch literal 860 zcmV-i1Ec(jP)-~a#v4oO5oRCt{2)k|ztbri?(@3~W^+JVr}m{3hhWMfh`z)Z(SqN&fM z79=ciK?F+zGXw2_V&cNYOu94iQ9A>r4~Ya87z!ydVBMHll2RDjS+W448-s+<3Q2>V z+RkxNqtk08*n4NX;Cz<j`lv_wN(Ydvt@+klXNsjg<2fgHZUO*(C83KLj?*rw;{olrSU+r(7_L@DP zN;sbRP~elI!+WZgPmJ}(|5$9Q<3q9e8N!aLRW;wQZ|SJ^o;{~Am8yuu(_OBIpL;cr zye~j>ufT2B>C1u2!0?9FLu*3`mr{FyA$HRk93ji27dT`=yP~QMfx<(-pz75CHdmlDy zV#|rK4EJZulPSk$T-~aZk-#tsV0D#DzOcRdw10mOF*r{-~WDmEE1JrLz z1s`8k(<9L0x=sao|4L7?vs4{Rx&VMkBE13SJWyMFu5cZt2`cZ1lRu5}n(NjnM|69( z`@ldc`;~kF0O8n|bt2Apz`BRL-~a#uJV``BR9J=Wmpy9~Q51%sbH^@VVKAU(+}U4YK#^E)%Cy=9)XK`l zACPJT76uF|Xq`H^U>6XCS{TI^0tCi}e;8-1(GId|qf^PUTH5B%%0 zav+57_j5Y0Otyq^vyv*}M5Y5r)U4I+d>aVh{n1Ozw)%lpq#S7@N$$SB1Q0@aAlz5r zmtilQQ!9?+pH);%)AUB3TSI6YxNf+IWhZEdqdgx|g^)e2qG&&bkUjAsRXZH*6){&V zOtu8zoLW}}5Jj{A47+y;pg3?<+1^i!i;F*c%Y`C#t?D8nWGg}+01SItt1W&Ww!cyU z?|ofp7nlR+f!rSUj2o7mM3NjX`cxDjSCs*TG<}X(z5r#~{3`(7`#Q3%Qg}a!A9FF={r>$Rjk&IgQipjZ4Ba7$>{dtWbdvsgbiKuL30 z^ih(V)%rpsTOiY>$#%|#9{DtVW?-{eUudKQJv;Z$$4s_^>}_f5MAnZDU}ib$tO2J( zwoPpP*Z=@YlC&{x49d&2o+Oi5KM?>xEsoz&YDG^|SwAtrfL2Ux{loy!ZG{}GU>?lN zu{y2wg(m(T*W>sLP#?K*O#N{{oIv*iS=GzS%Cc;}w>-WCAkzUro?GLp06HBS078dF z?5qWjs44Olq3sYdiy~U*?r<|H%d+`ShlbD_Aa_K~BG+#)X;R@urKG`wNujgRtb27{ kDCeitvCv_^(d@r|10S#f5LAedRR91007*qoM6N<$f-8U@7XSbN literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..60b4fb2ae13132b5a7c3c26cca5eac0a9969cc72 GIT binary patch literal 1255 zcmV-~a#wnMp)JRCt{2o4s!wMHt4PclR8mbg4{qA7dX*ktkA-k}hqa2~c39 zfJCDF0}*LJ*b+{#6at}vzW^jGP((rzIgO!8TBku^H{sZiyCM`&B8S_3D9$7HZuh)< z-cRHENiKHgy_?903NH!d9Dq827xGPQVs-%Z2yP1H zu2PK$BGQlhP^uq^jY2<``({_OuVb8=zf#Xs^&I1dIQ%xoj*1Y&V+uK7bSE;I*Fcxku+ zHxAm(13UHco;IL3DJAov)uDjs*SOKsI00i%ug4I^5^;_ESuDkkIs=Nq+E5LS+P)(E7h-HEtyYD8u@iOx^_? z$9c&kRssu?`=)`_X0!P;$>+ABtglHe z!0uaG$sC}X^*aEb z#DpF3Dc|^zHB`X*noI-`k-j0kiuh7^8N`{Gm_n?t$?Pf6YPEhzQVMYtWqnPikHLhc zuos0{Uz4c-6O=*}g<4;e`9f&FrBJl>HMy(=_fZOkTVIol027u%Dc0BI_AZdL6w0!` zCfApt1f@`#^)L!z}panH(3ZA)4)4rSznX;>u|H#d|ET)Jb-lofA9XS*9dqac( zN;Mt;+zvDyGtAoBK@#D=&C)|V#~@m^0h9?OwAiYrcvTBT3V; zta;mZuMIXy5A76(z`q`~=o)*H!g9LH|Azw;06@s{ylUKz>KnTbP|f;nLYDJOs}M+F zX|7fObX-8fLsP~V08V9^TK*(DG_{{&b7wKwbzQ|{b6tW@COI}YWy+Mp&A(ee_B^2f RoLm3^002ovPDHLkV1f{7Mx6iv literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..208f3709efd963dbb2a42821027180a49a6a899a GIT binary patch literal 731 zcmV<10wn#3P)-~a#ujY&j7R9J=OmrqDkQ5431=Z&}#f)WFDHMkJTO>HuaD4eE+5*Tl` z63k?+T&XRG!PNvU5|S(@C>I&VxJf7n69WIVsg2c6-Pl4YXyHbfds_J3^c zZ}r}}=brC--?^7}FZ}P2;=t7#@oq%!0$o5;Ks>v^8mj4BHnZ#<2zg&3c6?Zn7eG7E z5D+;|t#(9iwsoA_+xYr%)g34}5Qz<56l2~4KT#dBLd?IN&HM<0{aP%3%H-)qWE?nw z>Lu5Sx`Gm8Mgc)}D3{Gl2SMz@`H<;|oe)u;IW4{pV0rSo0IU%6L6Uo+`F*$cc{k=2 z(Bx5jELfa-{@r;z?Z)a#fw3M4; zl^gVfWHM=~;VC}1Z(sseKYzOeT=vEk#{P#`forsYv_D-OtOv);FW60NA&dfx)zpcTfb z4Y~!oWsKUjTJOU5?|5-8^9Bf4Oso=K2X^7$02x&AV)XP6G&+wve-f|;VDj`HmjDUX zyR|>KvEMCFO(W8W$aus~i01d_J!iNhp{IYKQ9|{-qC5Z$s_B9#Z(_ub4~t5g01qlf zFeszB?9_cXaOh^V@#WJ>TgTZ&M4Et;1a~{y0p6jS$YnDx1FHFt;1{nC38>@aaNz&| N002ovPDHLkV1hKtQ11W$ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7c8ad0c584186158c8ec9c8d0a282b319492a591 GIT binary patch literal 1334 zcmV-61-~a#w=t)FDRCt{2n@>y}RUF5^znNJ~dLdOBQfYc|n}{K)NN>GtT!BL? zk-$cc&@|bNy?U_+5?LTIruF2_=n@(wnr2%tgvJ13HZ6Lhk{Des#RFjv7;M9-S=gDM z2lmPA?Cj1g^JfRy&+X0pX5MeU`TpK}GkF6vXwcv!Lw159k))!u%7nXxowm75X1ri^k);4V{fTat@CAT&7n1Z5%96$(EzYKvszu4w?$AA$ z7y;o9fHSV<<_~8;7!J30?rp5E{Zc8Yq5$24i4ib9^(HqTA&Q3EJM$asYb&Ow%?=iA zzgTjR@r;Q_C5aw1V|O#1POBcIdt_p7mcG_1U1+cPykv&aPZ#(TPa01x1J~59ir>C+``wNr+ zHCTUj@9DYE-RLt=0@$^_1iEhLgQpz=vl8s-k9V+5>o3ft{&cI~KscZt))%nR{#sw)*a5wsp-Y7k1L(5$Ea__ z^Ffe_#(MhW9meDJw!Xlz0K~Xw5z@pGP3cP^2-X)k7C@ENTLAVf!b(aZ2-X)k7GOC& zl?7qkDo&I_P^>R-WenKgX}b-^V~emRmgrlSq-g}e`T|!3$YjO~#C#prrSLky7cF9Z zvA)2ySzvK?@((+uV1-}S7q~hN+AM`?_-1{9s{+(e3TF6feSzx>p`(_9-_{p+vJyN( zDfn)EfhPjgSPFHqzQD700lTG8FY60DeHpS*3U#x-z*7M-nel=o^LqfyHd$;+62D(B z>kB-89bQOJK2aE#8JGv~9Kdr1<`u?eyPwRw#FwwaKhC7K0KDx-U$qj5ufp}jOn|(; z5sSsD?I#X2Cb{R0F=hhf^o?CKpLa7UKQZP`z?Lz_On_B=L(}+*%X#^RrqWe?n^8U` zmkGdxyZSaUO+@<=t?sAiEz!P2D}hTEV#a3!Oav(Gw9Nrn|L*|dv>d|paS}mnmM+~f zPTAtKl~CJuc~DZ4c|OqF$;PE4GmlynRewYA2%p;34lb@NLt2o8|mHllc+}@c7 zQPjKCJck(=S(=%=RVkqA9KW%?wi15zjbB03g=6>M5M@cj(9%rmo2pTEZl(Wij)1P> suIs@4Hb=k~1CML@ZLUFs1}B?;0S^@mnVy2*k^lez07*qoM6N<$f|rqb1ONa4 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..a35def37feec07aad46c3f90bdc12e680d150cc8 GIT binary patch literal 655 zcmV;A0&x9_P)-~a#uK}keGR9J=WmoaM;Q51#0Gg+&Eg<>Ff`2%9LyP}AKT|$Z^_y+=N zmC7V#2&q=EFknzYLDB@lErJVn0YS36mG}peIzhoAmB}27owux;+3Zesw9&76+;?a0 znRDOFya)d}>JF6O`(})n5oN)ZJc<|&G4%*l>a+UXQ$VTe$KWSv!g3X0vRSNJ z!f#`|3`_$=?JQ9Sh)$^GS-guHfJ7+-+5*CY%ggpOnlt*A497yO&?EQU6sw*Reg$Ck zpgE%tXXWQApt$V`{qz=M6d)0D^{i{6vnDgK;z-AS6N(Q?ZURczcm&+(j7eJiD*}q! zo=84mo$S=V@bb?KNVDD?xuAJg75BTm?;`BCs#C3xwAh%|-XQw>I*=3}2gYS@wd_vB z4PkvC+iNIBb?n!y_#Qy2^%n-SeqaHT)@*NdgzlEF^UyJ32az;~n$y|?E%lmLq{U`N>oW-eXnf@bU9Ctsm-U$iq_$!R z>$3}>)rv@(1NMRaNSZsZ^?}U44oKSp!y&Xbka^v_n_|_Mli|TB0hl^K zJi_Fk5&*4x+cZL;-GT^JjHi&-i&YD#b?o7WB6;#j;b%Y`p-PxbJD60+bEot>y$>dV pa5PJ{&STy4=j6bqk#;ou&o8D<>#ezM%N_s#002ovPDHLkV1fcvFx~(F literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..925cd36208f8e985dec5e47bd4480413afd69dcc GIT binary patch literal 1269 zcmV-~a#wr%6OXRCt{2o6m0*RTRg+XQqY1%IBsb5Lj3iHcc?`r7x9Do2VO* zmI9&?2!DbbiEUzAn<$DK{R=d)(Ex4nk+P{KZ6JX>EgPeCgA1CnsEgJWEzr4N7kyJ^ z=FN2GF?W8{zEAQNbMATXo_pT++_^Kk7iiF+!A?e^ICamkX>A236x3OP6bbAXV0Y5N z)dPVi0z4u(XTZ4HQozmG9$63jUT6YJlY9%{HvnGM5@~wO1M*>|Uw+=o$p~yArE`LV z0H?A21`h!30H;egH~=#6j}A;g=OhM1_*pWsr3m?X=_h;~)a;v?s_dsd<`s$z!NjdY zYgoAcu2@)CD@)oV zPk>UHtxy~T@utH(zo#Hayc1(h39PN)1l%>hY*IehE`tYvO0O)zkaGZ59Om}w*j&^k zKtY{#UQ=ZFZomAaKg?vQ^vaS@hMhL=*Z`jd2&CvTn7E}qx|C4Om~va>b+1oN0toDP zULRV+g6_c5!YB3vULPL?xL0_2o9*kt8@u1?HFzPkLukr6fGBj8*`|~l0_D_(h2y3e zqjyir-*JCC_X;SD^RTjb8!J-7{>0!5;za^J(6vEcHp; zK60Ia$IG|`pyt-~9624gkKE1y#YuJuIFfWfxl};+44X{wI{?jF`3ZPEZeO`fK)Cb) z08eQcSK{`SyAp^jeUXt$pUlVYFINhPDt!p%_Pm6zbo8041Voj-vgBfv7oJhbO$pQ^ z{ohW@pSt?Zg#xmWzKs?Iym5oCSX4us3lrglVHl(LdgVcs?>}C~C6RQcZxdSqU1hde zIKlc)F#J zrxfxaeVf<`sPxG^DW8TqR!bo-(znqv2kduoS%DFl z;5y*feq4sgU~*BV0s$GQ^x=yjhp309z6Q{)HMHc3bZDyXV{_Fl=Lhn5Y!1L8!29(a fn`_XZ!OrGCw>RmF`CV2H00000NkvXXu0mjfWJOVu literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..f95dc13eb9b6e69937fe0b0e3bcc05bff1d823c0 GIT binary patch literal 704 zcmV;x0zdtUP)-~a#ua!Eu%R9J=Om(NZUVHCxG_iMW%F;Tz>yS{?ZiqRNMTnTZ-8_>`u zKuL_kvT0bAL?bPbLcqkZ!M#n`D2a)RKz#*RDG@Po!K!wyi_X-s&_7cK7kZZG-kEde z+;1{>;D3kI68(wXEmUU^22i?vQaM7|MkKSBpL|!>KqNl@NRhd-jQIphmFeP2^2sR! zePhpVizB>i5+^G?oinYHa`=0Jf3dM%S1|MNdejj1|!5j(Dr^ z%|PU^D*+6;IaOx=ih*b>7gltxhTban94}wIfwQAOF=ZJgowk}?-t-VQJJpfHu7sk4 zZcdfQJFAoXt@v-6fGyqw^cb}^qOn}qshuZ!2VP&p4lAH*q*C_)ti$%BZ`ptsl6)C=+HlS<+ltO`_i!xySw1z5Dd~~?qBM`};I*dxTKb{p6 zGzDjeJ1?T+3!S$3JYXS`smi(=?H`j2er`&C;?$2xz+L@Z+-~a#w*-1n}RCt{2n@?yIR~*N`znRfO(;{|--H@V(#zRH0BwP02Wudhf zZ7ywUOI19Ctc^D2(t?3zvVmf2FWF$kwSg8IS~T_&B9yd;puH^Fc#yii*n=U~tPn*o zNW#widPrV7yF0r(oB5k&Kd^^+^P73U`R?~O^JaJtXwaa+R)(wu#Z^^VUJP~Uz)=E4 z0d4{Cg3Gzp%L+gb7@U=Wt4)!m$(dxbQ0t(Y0z?xR4}m!a;@6$Y(;FDb5v0Cs`pmD@ z;-o64plJ6v=^qYy)Ie;tv(Q>67(e6+`2w%FBo|n*DEz!)%-*dnG zZo1d3F`Bq|2+*fXnxB9$AQkAwo~PmYiHQ$1$8)toXXiEf{*L@^UE#xE3<20#93j19 zRt{wX#8p*!_HfsoBHI&wlMDK>%vfLE`P7{!)-@c~6lolcw?!KRxtAkL2TE^@W%q#P z#ZX5{%|BknwvRW<#REWQtS>JY^kV>?h&BTDEiZ;TN@L3e(1D{x4FvVh-)}Hf*fCAlcK0R-cHEGJYO+b5TjLBn=TZ~(Ko`&b0PRuJza(}fn z#%vr=G{Oto-M$`7axWXbRv8Fw4HUlo8S(U^V$&}_21S<l1h|lkUyg?JrOQShYTYY*Xa%H%{~!C;_ZmpLFS@l@Fd)2#f&rSbz50Gk2ZpHxL5& zVSRxk?*i@JBd-x*0AgUm_*qxvq1%^E-?MVOAJ!Mxc0gOtXe$wJ0XP9MRwo>nH0@?A zk=k49c)zSKuq}X8&<0RptgeB6jH_xzm-%UZf&F{Hf3K)!M3)y|`K;1TKdmot{U*qu z!RV>f{?c~8tuJswfa^8(ZwJ$N#!?7^^#!&Ckb$oOtkwuCDup0eUtn8+Ou9D*MzU6% zD21R{U*O0+;HBoJ3t-IE2-^;peqg3?1i<^bur~uYW!4yxeFK~Pyw9!)V+WG=lMuHnC1<$Q7 za7BPROTicG3tW2_uv!X!SzqAl%aDaq@Xh)HR|S|!CJVYEe+a;AlEu6(%OCk=eSzz* z!?!P;z9(xqNZ=^|&jCCq@RY3Kpw&-iZsN)OfXrC$0)ThD=&N1=@m1JQ%mi35Zgh5D zt2muD=$PcbQW|3-06j2n-QSVl?PyjWVv_qpX-t^_49*(2b%hT*oR?>4vVO$4%_x5) zmkA&NSBn}LL$R*mu;baeOss1-OrWBHSlP9~M1ZEq(j=JvG&Jqh6lr`jiSX}aX~T?h z269c2rODFRx~9uBSd}$tD#+92HCaEh{?Bi0y1XFTJ@P+UFaZ#_e>Q#gyxG2rQ0wKX`K2dj&wHn40C?O2<29l&LCSYTkTo@H|l d8Z_A2`~&!{^7|S|Hr4-~a#tj!8s8R9J=WmqALyP!NW{d2y=?MP1m|l1nHkUZ7q<4m-Uk&qyHy<;@;|=_G$)Lm9+m)1LUsRS6 zW=qMUJgDfE!D}xrE?j;H5Qfn%B1d^(B`HO9ui0!I4*^(fR~2&sJPWd8jCSkw`coNM z<2as9Q)wyM0j31AHdqO6Y;+#lSgmy%WhBj$wQe)CvEJC|JoA~%5S3*BW3)Ri0MDZf zAjr}XKsIn?l|4_jTJ5oK&J6?nk}7}-;MV~rJ_`t=XbY7?VDgK1_Ygg3HX3I|L4_3v zf?yt%(-D#bOrp{Wf?$4RfS*tyfbaWvh;9SD5$^6Gy5sx)T~W}dGtlp0VIRMvzukfg zpaS?=0ObK*Kak@}=A4`9oA*NiDtZNwrqUW0K$6e`Q1m+Uy*)$*udSr(igv7Z;(2u6 z{o%eP=iE$^&{FgSNDW>)JIh;4+Kg{DK3+^Ry{%@iU+1~O^AUBg=yl#|R_O(D-;>_2 SpOZ`g0000KWyww=i?4*c~}? zJig(`B}O(D=GM8aDyJ^wl|NUJO<*_@Ht|WKhl*agc*f)1JC^>-t^0ed^3RdEOL(Pi9~}YgY~JY+Y+xatP%R7FokvLDt*@_f7kQ>z09!otEZD3 zW6=VEnU9krFYH}4rRw)~mHY@+&ra#Jm4~A5G|gpiXl~gq@$#C?$%Xb`0+>sROZlG6 zE!xt{&-ngW@733bUl+gNt&XediZ6hVX}ja z`FY0=HiEyd{WC30`2TNj{Ar;WHd|q}un97pM}EG1S*t&(a;9a&p_>O8^76KxV|LgZ z_h0G2*%Y12=1(Lp#6K4Us-PZ&F#BcAVOW9CR$ zsl6v`{nbnVqw^#l3ktlv=Gy;>?MUL3`;}kzKkjg^6b6c1KGwt2u_$AEgTIe!Pgg_# zVvSq5m)a&WDouUNP&R8z;)!+p+9uxoHhIBB#+2W-4f9zuC0pm$@+v2%I0&%VbL`By z)W+Eo!`Jkn-BbElzr%u6{<{waGuSQM?lP5EG2#`MKkKSrSGH_)`o{S8>x~NEZH=>8 za=AD38XwrkaNB}82P?BEDf=XoXT47pm%97!C@b~z4OdeZmj5Zqp0s%H)N?20rm)!a zxc#}@x=Kn}>EFzhnGcSa_^h7G_YT15x-~a#t(@8`@R9J=Wm$7S8Q5431UtZ}V6|}_u0Ub(5T`VXrdFl`eR9@F2 zxAfsCCgzx9)9Gkl<3tJr2GXpHg0leQ8DWP4}I9 zIN$Hyb9vkg|GV^i;QZzC8Kj%Q9FWh*XB$|@tlDliUMDBKHXVyqQ3+F!nLzm>*T3MPWWxbua_USm51jr|7hoa82 zN1vnNiQNDWMI(R_z@Y<-?UisLxO&~0-4;v?QrMuIlWx6u`rv+AUg{1MO5v25-5b;# zKrmruwL&SJ`eT5DP%1!Yt-dMghCz4G!UkPQmCjmyGc9k=GZ6JKwU7JJ-`#={zzE== z0k+}C1#(zsh55zFXt=c-z&e2IQ5+V4yz#j9yEyjqM`Tt-x`b5ogHYDnX(jG(`%+)p`H$#3sw<3hAG8=400000NkvXXu0mjfa!&nP literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3102eaa3f59bd213cb312df5d946016118eba943 GIT binary patch literal 1003 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq{9h zr;B4q#hkaZ?Q?VeBO;uea;u{>XRWHHfX9np>zrC7(ivn}AFyw@8k%}Gm??n4;B?Dz@A$tjbIK|* zxB9J?60noy-q?1VVVA7HO(zX^w)k^CD$Au(E2Tm?c#k|%=wZ0=cEz@98>Cx`WAEDT zfBv~x|F!B>Qw0-&?&iX~vbnk~8aJ-q4W4!W{Mj3J+qlExe*1(@_}JXJK1<5>^THpQ zB_&(lG~Fo`?sccvjqcn7ifXKFORd*Wbjw<;l>V z!nld`gqx&7bVCkyW{G-N3!7fc!FkaP@<*ipXA3ki?qQb+O%_hc9DI_#e#blK)hcI4q-f<_9~mY*gk#0afaWIDKG z%3PVBnnBJ#girJ=m22n`X1JGF*;ypb_QLjr#Y9POTLIl?C+rq%lH*=~(kNi^f*i(8 zfovzl6r@udurqzvq~y6QzUcP6)7-@DmiILoYi6!zZi4%2{kpPL!``ygYxRsI9E;hpWL){c7}dCfialzZikJ=!pa{n+wAn>mj$!P#eFaQx&M#3xEg~% zv5oP(U5VefOs(7A>g06w@x*;orMF@0xeUj$`MaKTq5BO}>(KQC!Zh zYUe4+%+0}%Pqy=Jz7}+(ZdCP%}^E`VppWT|{v@j$89|N0+w1DH>2o7NG OW$<+Mb6Mw<&;$U)aK3W@ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..370454348f95a416c5c2ba27ded03e72e8564835 GIT binary patch literal 466 zcmV;@0WJQCP)-~a#tgh@m}R9J=Wm(5BeK@^3*)4J7#GWsUz42mz1VFUv{gkV-;<`E`> z3nRE6+zr^^A}=r?rhO9?2PA9z%)+i9No+B8bih8V;?||kS3eZ@!e^I81NAenWw?!~ z3%-FbS+AWmx-ZQ-@;!apHCGAK)IV6+O_q+}7VRT)+PI zQZ`2exeF}H+6X5xACheEO9-o#Hg#HtaZtXI(^_H)|H^P1_zn;avqT*rdZ1UP`G|S| z5^)F&0m6eT>)0phYD;(daAgeOqf`M@03Qx8|58GH<{jjpz``rn9$@`Qn>r~xA0g%&dRKocsU>5i~(T!0NEUkSpmS~+BRtj3_qd>b&S6ucWa3S^q$mkZ&JSV zhVT)PMW_?zCN(Ac%FW)S6ZL2l3>DhUy7d`2YX_07*qo IM6N<$f-?TZ*8l(j literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8da0a8c983d3206248ed93b450c7c293b2d817db GIT binary patch literal 930 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq^;1 z)5S5QV$R#yd;Nn0CEDk2Z;fE@ohzYYb$WryB(uC38az@H)lMjI{%a?OxV^OW$(ZgejYUP?mu_3YK;@G4%e+uZ9tP6llB4@(N4$M7>Vckv?r0KXrHx_56b zQn4`%<81^wpXKswC!d^^d;0jSX9q(H!@R_i@?m_j5278WFzflo)!9N*!{)In7n#H?KgH1c_unU=+X}g}#RPBNK3u9) z_TYInF<9I7DhjAP0jboAt(G9uSnNg22RP2}9uDHj>xB29MDV~4_ zwo22x{tErOyD6`y+95BfJ+PKhM)Bv9kNXx2Ulrf!DQlK{=0w9e&AaL^YJ&xPm0s)x zvePfMO=Og`V0&Yjd3eI!d2MYsKTcjSkukM`yQbUITe;@5iAm2yM()3xR-Is-Y~~a2 zc}@RF>RIQ$Kd)U+Y%+l`4F_5HEH$8yHpH(J_~vEZ^$uy8c)4!#j1yol-X0u-g4{ ziq!g*U_JB0^9>~*j{I0OJ-T66-|6mC5lg40NB`VWlhu3q-t7E0JN~fkJZ|+XK4u1k zfTZrX(`Q$>n|^03X3bMFnl)$DvIPptM>pSD6`Htt`m%QnvKzg;=lRCYTJ`(Zobo4o rYPI8LGf#88f3-OG+{1!5IdzQAz3lC~pV`j>W;zB>S3j3^P6-~a#txJg7oR9J=Wm(NNYQ51*2Gf7q@LMy4@Yc&6g#Rq6gU!uX3YDOs~ z_7NJPC7IZwMHiBl4-jzEE(EJ-lh+V5D3mN?a$L-0491R_Ok!#CTi$!P-#7PMhI`?E zk6a&!zAnw7x{8oQiTFfmpd2BRuWe)x{wNU36yGVbc9WP->8O&ce>Fe$2|QUSJQFeY zf!~Olp;o(cxc&Cr59-rbpB}YBffOnhFono`cPE0bi5NLR5H)KX%Vj^n-8dgoj%F+Y zc2HdfUIG|ym5>Aowb~Uw;k_|}M#V;vaL3$P=fL^3?KkD;=cO|n#p8Z~d&)#$B5>~l z!P^RAnbI3YKLFu7uH6*m{jbgJ7q24E9Y~}LGm4f5fCGdTwG!#V%)kQUh^IhxYvn|c zEYKWa?WQ1Rb!+9stLWA<;PlY5kHh5eZox!gA~0S7p#k;f z0;y36bS^q68%4D{cJ(6?$)oxL6)T#t#0VOd?j3H}#24469e5GwAd+{ny@k%hB+uy1 zM&H9E&^vov-}^Bed;SfG2s{KH_(64g{vDBYebe0aW6ggjmjFYChd-R4{{R3007*qo IM6N<$f>I#jwEzGB literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9e37b8433ae4fc97f4a952769041f84726577b08 GIT binary patch literal 995 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq{9d zr;B4q#hkaZZ9Sp`MUMY}{?wCwqn4ObM9Dg5(Md{oTf$^T%wGpMvUiF^*)I!fXKPJ* z`N&;%m4(KR6|*%$ZZC9R*ui$?;JL1C%O?DCl+Br3Znfg+)2FVJ?@W(b`+fV}&whUY zzW=|s`}?Fj+!`WXuX$7_g}nU!+I=_cSGEft3i=0J8S<7yMsJc~-g5YXDDR9@dOT
p;YomhTP~ zD_b-7Jvp$~)cCW;qa9(4Qc}xeXYV|iQ6t^a>E-y|15 z^&InoOA+Z8fVvpo%stAXVS7t=#r9{%BoY{U0~wp@|K6P}|59Ly_Uy)5=0#x@({s1@ zvq`@-Tz$P*%;`FFYC{g=ra-n6VhYmOnRh#trYt}6$Y_wp{Qv3dndtF@~qDoR)`7h54 zuT)HFn78yk`vm16=LxfyO9ef<#oy$_*7Cn)KZ8Yyhqso@yetn%Mdq;MyT8rc8M~y7 z)E%F<8vDAe2ETN}q8?qiNa|7B_1(mu|~Vd=_*2Tc4*$u5b+4 z#&A=EIfZ*duaN^*<^i>`oIDc~pW}D^s&8(*SeJ8lqhUkYnYCx{By3!~%BZ9FTW+>r z4U;db7+*|OKB8Y<~6K6fWgA>nMNp#$@>MNB>SfbqEf@vBQduCE(rJJ>#p@VTFm z>`<1NA?6eByYNrPI^Q@|;eWZ)%-%|*Cn)bWFv&jao3-1f`7bbX%4cpr?H=QH_vKvw z+}(d9YX(t;d5xjAok?Q1#yY{OXxg_+64T&<6)K8u^Lms>N%a5e`p*D`pz`njxg HN@xNASp&lc literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png new file mode 100644 index 0000000000000000000000000000000000000000..80bcf2b660c529f9d19349f9180e8df76f0f466a GIT binary patch literal 393 zcmV;40e1e0P)-~a#tJ4r-AR9J=WmoZKPK@^6+w}GW}X;unDG}&e^;0a9R4x9pOwU8c8 z!5NH+C*T6xY`}oUh6XHI$UX~a4J=}zyRmToYBDp)_hqJeKm7Mdabr50T{|i_3YUOa z5@#ha&O`?n?e^1AftT59AJto64MZq!rQn4VAOsqS^v~O8_Xh&g`Me_;kD$-njoS@^ z)}j=+NgOABt)7lRu2i&>zl4)ta58$px(YZz5VRKCjoSrMN2T}4%@^j+qblIL5(trD z?F#^2X@CA*GFCwID}g_W6|e$UzzSFaD_{kzz^=f`Os`cFJz#ktATS2PI8OYk*m0cr zD4}8P3uK}Lpi!%*qbejOlga7FSdN>C4)gtDF?m4s4oDFqGeG`64jxJfxJQdg9#hSF nW^`^A&wrSusb<4sHM4mKCBJSgItxPQ00000NkvXXu0mjfVj-LP literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..df0fa4d5a841597365069e8027e0ad71910ad7d9 GIT binary patch literal 846 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq|L9 z)5S5QV$R#y{{F&&B1g|VI&gZgonpU@m)pESd)g;m2IbBjlQWcdwfHZ{HWi$nrPTRB zx8P*gp;N5R+)D#ug|;XhXVvAq+!*%g%eGH-tFQmQXYzdBKJ)e6)r{?j3uh+kc7OU= z^So}OgX`y-3}r#<`c_!r${t zuC?bj8F#w8cb{aHeQ_q6j=ui(qeC3SE^OkTd~zTE!LOohPd@)VCvVTc@6q|0|JnZTn(Vc7 zn{u!$}X5nZ0}Ko}F)AqM`TGiTR-E zR5qFaCpBvu%N9)xvuCpW!uDL7_d{%NZ`sw@76(4j>vc02r*ow@Y-Pxv!+4EpO(9zZ z_l9GV3AzWQs3CZW$3lnS!)&i(qYPj3=fu>aou2}d!c8{4a#v_y`=BOb=ABn3CrC{U z3HEnXR_a{jRv$XBWDYH?ko%lF)^LM|{zF_WyrdPX{wjR28@nArG zeSNT~@4EHtkDt6IDzGtV#kQoE6*l|a3!bSs9Epm$b!p!8xfyMb6*_@5hYEkw=0shS zg`A#AYLjcF--v0N`shr&mAOUhQqW^PZ)0b0D(*b8R^8Oxhv9$d=`%44H(1w( zo%Xr9Y^6`y>&6AsGxjZ8DRb~9x4G|6&8=s9r@ng2UJz4yw<5Rr`1e1vRwD g>zNGS@u$zsJ!c6vY2=;A17;8gPgg&ebxsLQ06pn;3;+NC literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ede58c818d906470a46438b5a038e478d67e475f GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qqvz`$tf z>Eaj?(faoKe!oKjBF8_z->GO2C0^6E&mq2{%SUa6wDOD%*CJ(8+NZjNyQP{a`Ckx! zVZ9;1o#Ua!6s`K$oW~FT_L`gjt-Z8+4)cH8O|=i=8n~~~K}jT^pFw@I`G3t- zhKD}d9hiTFN#_6zCCCb_Uv|Al`OyNO?+hv|ce3`zo?C7GbK5SChkOnTxu+O(JIZyO zs(j6|S%SgUwd&>1V@X9-7pok0Fh4u_WmTctTP3~~+#>vXYMGO+`Y?;+*H--voucWq g!Xv-hbn{P^!>VcePy4lPfg#J_>FVdQ&MBb@0Ko8?rvLx| literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6721b38f5f24dc28bee8ea4a3ca0e9f8108a4c01 GIT binary patch literal 868 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq_}f z)5S5QV$R#y`~8ChMUL;kFU~Q+?~^jqJG}_;a9^J_rNt{)l|3&mS?VHuLGT~b+=DJ_ zEHZ?B7i?_WQnX)%*5-zx!0?K+?vT zl!{rd4Y#?6;~rVEwsi5A*Y1r;4(c z_boa5!nbG~~UgjYor?37z1)j9F-HlRxmEHhWAhixZQBIWS7E`lE@Y3Gu_QZI{O!y_Axt8{E@Ny_BO@^=efBI9$$9~ z)>XXM+q3`UORI-POmTCw{)>!i;(Uf2BT@ta&wWb!pFuI(_xspBoaL zCZv3L!ajR#+pGou?_2J_|JY}t*TwR)%T@-M2rhmg8nrgF>jbAk@v~(siw-~a#tHAzH4R9J=WmoZKPQ4~ebWfCZn2G=kf7$UU^v>H2BfwfvlFRP$a zjFmC5HgPt<9%#T)lbLG)lOTeHnTdt}mhZp(d-DD--i7}zZ5NVT_f+#akN^iI`7D9d zxo*-kJ?#bP++`!A3&Xo$W_T;ZUC=bdf(G*F^(4Cb25>ZWKgW-V=g1nooN8W%d7tHOK}0+?ZvT>uAVz4=e_ z>O;160sM&qKmZ5;0U!VbfB+BxHUXA`X4QsTt@?{y0I4DFPTj7`e0_I}NWTF%*Nvc& z$&)G|IuAa~TcydBMgJ^^U4Z!dg7Cq4iG002ovPDHLkV1l-7pcnuE literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..35c061c0db3db83ddad5fb72cf43eeb06446b58a GIT binary patch literal 850 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq|LD z)5S5QV$R#yd;LWMMUI}IxrQ}orS!fk=}4(ZNs6YX^WB6tPR?M8IuyUabOy)LSssVd zbyjXvP%+U7xuzqu<<8QCxycVVS)bvNSK3`}z9)X`_q*07E7jkh%_-D>P+*Z~yvHl> z`mRa7l|2noN*6R2$~r7Mb?e_$rOr7Gu^p$6d+NOVVpxCESzKDdaC4iXQ$FLCyHhSn z6)F^Dt(Kqf_-fChV%`_?uFrKjHJ{ZYPPTTd)90hg`AOAt)C+I^NY*jj_-a4<52Yz5 zy?(h>*?asj*Zo>Q;eltJ_Q~T6m!|R@7uJ-Y5O-{D%MIZPkyj-a_BSq#7gFEOwxQr+ z;VN#Gw6Kp;uJAPMewzB>=QRfV*3-&te`+7TwAL#Bmmc`$mfRD^t1jVv){*XV&1VPJ@W>Kbkz%Pckln~R$$FqEW^!zNL7&8tG>vqu{=UI*YxolIjci2 zUx;$lNWFd=TrTTW-BI)HG0%=r3+6Sf5s!H`h$ZwIABbu&J;#vEc#Rr@!s!klzqDWZ z!PfdMfam$*+#;8CLO*n`P7HNE_b$Z@$MJ{c3yMzh{EhxooA0p9GB*c@23vRvj06HG|nJ z{)!ct-#L literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..d98639eedce57060249d9a5c39b5d189804b0c2a GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qqvz`*G0 z>Eaj?(faoKM!!P=BF8@d*Id{$jdlJ)Zf4FOOllwa)~HQ6C^6@%W0`>D3+@j*$BwA4 z=w$Z3-^ePX+4z{jG~$5cZHtQiAGe(R?w#LW{b0ZQq~GOk+d=sZ!qWqLDj!8r@4B`&+(tx>y}h>Mm;Nyg$$F$!v!y!EcWgXFs1Sk6^v9Fu00SJAF@8S#*7Wv@M+}>t8yK$WRxb_;dzzXbB2>WIWP2cL z3A;$nw8uIE>Eis$%}yI8tathK@z3j|N4)PspNe&e9D2+8>3ZN%!2-tLFOr0oKjM9D udG*}4S1~?z{}a=g4tgz_A9L2nj$wICp3&{SDXzd!X7F_Nb6Mw<&;$UQ6{}tV literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..88a52460dce4edef3484455c45dee9572511e6f5 GIT binary patch literal 862 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oyBSfq_}T z)5S5QV$R#yzW&02B5n7BFDjO-Y~lZ&x8d%VBfbB)4|)XMnGx2xc9TJ4`~psH-)QBx zex4?b|5)EGk>=9AF5+3jX~b0eKHXFQ{w?nvBM;l*RJU7_ zBEC8;Ya9Q0GJR*f$7aB_K>tR@|1*jWTne+9*4+Bdep=dF|9e#J6($Z!;dTZsz25>RA^cAK4^Y?)j!B+>7&i( z({-1>YY_5&Cf{Yi{b1MP4;gzW{CpwzR!{)w*!8>-_X{>Xub<$4F{rRiea3-<0^a*1 z1$S;@e89%gu;S0Z)cZyM4cqR>M=}4MT=3`N#7}#!tMM}|ee|Y}BhDm_!)@&b(}!}; z1p};KNlnQ?qHtLHUuIb&Y`v#l39bW7&dgyeUEc1#9UK~wG~ zG?n%R7Yp3^a&50k-?2RFSLd3u`Q|0x_dl@o5XS|+1-*g`WF4fH9jqJ7+#1Rla(fuw zGTf42yv4Z1kZB8ZMlwqV`-NkqDV*Qn?7s0i>&|BdFM_`ZSk|p*a&~NarLz2)L(cBk zc1$UoKeFs(->`OG)4P_S+0L>Pb-#1;Gcbn9+ABX^`6tETVUzklmER0~vmYzP6!w4Q z*zlcyT41&r14F=!-JgHtp3iOlIJ5k4LyEM1N7vr;?P3A@eQlrrDEP2KKcr8!IC$?y zS&fY;d0kf*^9nTgUT>=0FE&d}c+ru`JHOlARZ4BjRy>in{jL%(<3cTqko%t}UJlh; zCvIe1_kG^%k{*sur>Km>s)|YzI4-7b4`pAO`pNsK>n8ilZ!VReUbeDAYdXURslC@s zTtgIQ*q2|PGC3njF{gDcXONmh-_`us^7z{_8+j+{3a-0R{msidx0tQ@VbN#tFB_h! UCCUl90y7MQr>mdKI;Vst016a&i~s-t literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..bc858c8d0ce607e693694425a4e1e82f2b882f97 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6x8x` zaSVxQeS6MPkU@cmWuw@CrI!jUDKh;>4&;e42wbZ^=gYSyMTX(WA!d(t%*(I5UEmJX O#o+1c=d#Wzp$Py)1R%ix literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7ea4f9c1c178c6a22334bc9144c58451e74f99a3 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C}{2J z;uumf=j{bXP6h=5mV?*-DT+4#(0t;MCZrS13RD0D2mT+s^?aG~q%F$RV` Y*PX5~uRcFVdQ&MBb@0ITIC=l}o! literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..72e073a789692e5c2346142b990dcfa47c9c410c GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6x8-~ zaSVxQeS6N4kwJmy$OhhgjTx+eq8TKQD;r)2V`NC&`~1$61761%8}x0YUNHXuel}Yb PsExtX)z4*}Q$iB}g@7U^ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..09a439df962a68164c87bfda552670a44a941c18 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C}`{H z;uumf=j{bXP6h=5mV?*x)HXEz)&8OR#34;cCz=(g1PBiNKX&W+GUZ8WRtjeuN+4nk a412EcN@QY=T;G!q67h8Pb6Mw<&;$SmK_&43 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..c84512bb54d6bb2046f3552363db0b7faa1f6620 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6x8%| zaSVxQeS6N4kwJmy$Ohiv9rIiqj(zmt*%Hd&5b@s9+;YRDLWT$2{FgT|J?SvAie+q literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8dd58f609f7e73774edb47f36c7e53c20d419a08 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C}{2J z;uumf=j{bXP6h=5mV?)WwwW!eCAOJ?$U7%Rv^#26Uf Yo3>>!y}IaZoCFf_boFyt=akR{0Dprc`~Uy| literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca2605bd5a275df2266842439d0725f170647d3 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6x8x` zaSVxQeS6N4kwJmy$Oc~DidphJ%{`ANN@T2NXxMPCIIk!{^)bT%ak+isOa^avMo$Ck OV(@hJb6Mw<&;$TqU?BVe literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bd966178122b2875018a1430f7fa213f200fe6e4 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C}`v9 z;uumf=j{bXP6h=5mV?)Q$~N`4{uL=wFy@@LmImdKI;Vst0CLSDTL1t6 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..49a9105261779cb93e4a66ca49d4cd52681081c2 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6g2mA zaSVxQeS7X8FM|OGv*DG$?JR~IvP|>#)hoH{oO*Tg)yHq)$ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cbb017ee609e3f273e34f084775e4cc1824b89c6 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7eDY z#WAE}&f5zcc^eEEjyN2W6MSPY+TrMQn$112Jbv%fjf(4jN8YcME9U5ro%64gDTC3M zaZAH8hA4+%2Hgdk4PqBW9Jn*M7ObP0l+XkK D%za4J literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..96585468854c16306fb1bd201e9a047f57610e13 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twho zaSVxQeS6MOkime1#Zm2EKm+TaXa%JOcV7QbR~AeCn({Tr?p|7rAW$(9IKcko7>lV? R=TtqApr@;!%Q~loCIAisA^iXV literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7836a9465433e489635a9e48e45c748dddecb5d2 GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7f0w z#WAE}&f5!yq74QNM*_OGYaL+Pw4s6N$W&4G`HDC5cJ1lmHS900{azgJT=C}77k?24 z?hLL4tR}1%m}W6$F#0lXX;{V(;lcCD;YyCvNXt9?|KDvHiM_DpUXO@ GgeCy~j!M%2 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..512ee7d235a51e815b319907242ec62705bddc2c GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6g2mA zaSVxQeS2=BAcFx1v!R~%MpI>{wuYelx0iRgM%qT&&hFnX8P5V#iUd9|c4x9Nx7R#8 P3lj8n^>bP0l+XkKfT$oQ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..af503251d4abd58ec684d81819f531d97cc98f00 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D7eDY z#WAE}&f5!yq74QNM*^aPzcvQcByjC|^uSomdKI;Vst0J;Pq{{R30 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e1d43a83e28d6d433a5c9b9f8e8be57f3bba786a GIT binary patch literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+B81_Op80bR?glAL*@=Y0qXlc{M-+5Pg9k=YTObzkqEujPBVvHP-pAcO7# z%?7axA`aXcTnkuDST8WmV#;9jW!%!Rj3LS)m{!uySR)>?G{m$y?*Y1+!PC{xWt~$( F697?oOWgnf literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png new file mode 100644 index 0000000000000000000000000000000000000000..2a1d26a4f17cd1fe8d8839310a97b4bf80068f97 GIT binary patch literal 1258 zcmV-~a#woJmAMR9J=OmtAZWRTRg6XQo@K6>5|;Xm@6(i%pPJpDGCt_<;lx zkq=4K5RD`Vk@(<)2?|Q&0mb@af)Y?eVoZ25v4ILGi3FaI(1egw16kVLo!O;gjR_*C z?an<6>mZo93%ab9-j-2XZM|GjtaJ!j!gH<=0eN4Gp!~cJo1mjV0HJLO-G>RAe}8 zY8tsK3{4n@3sh}SMOO-}0}>_taTAVjP9~GrW-K5Gf`>w*M?oG2Mg(@dZv0CTDNH3= zRjo`AyeKN~14#tm6l85O8Nb-DfNVCKRIGEre1RilV}HNW)z$UKRKyc4l}gQt&1pG+ zvKhFETFX4Iq zd!BQ=JZ43sjq+hpIeR9OXZ_q)rKPM#4$!Kw&-a4^s#=*`cX#&~%DVt6^hU=j0y3G* z10YWWzu&lV{qyRT$?XDOR;3|RWSj5j-iZ1ViFhAyN#K!mI{#>m01UozpF|l_Uk~baq5b-s>;@=LsY&m zJua^ifQVCiNLNoqSI>gH7z)o;ry3sy5Qx_bC^=QfM{WnG0Lj@3Kr2@=0EI%KoV%m^ zAzC#-)g}#Kri!+w$sJ8@^2OiSf(oK|31w$30Q~5SZMT+k%hmD)cUyp3K@nv-CnPz} zY)!Q)*0M}_J98CZ1uL8eu#{ENAi;bF%%&EMfjLx_OLQfGqNi#E*kbyNgR**HV4!mB z5{bmmf_~CCua<s|#;0rT%~Z{HG4IXe35TQs~Cf}&r$ zZhTMF8w9}`U@`EM=XF$igQ_pw65RnHYVA&?QuE6Go}QlZ-$t*kSJ=nY+fhJuuje`& zqg8ZpaIo2^6zdGu&brkQAd?La11||2aozZaiRIY${ceM7Lo4N2fvm!}8d?XF$&SlW zysC=t2L}~-4dHaci7%g0z|hc8o88p>Bd`dSj}wWG?e!WGRkZ;`B&;(ozMtE!@DXs; z5`C<+)fJnxycGLE&H?u!d~&t!JekU_Y=GxMhhx;kxd?MBJpeoZ~oG zLR*#smr*v{`s<%dnN0Ais@8N+6HQgEY&Q2o>)f`%5_t}_mrX_v)3oL3boyQ_`wKyy zFS&B4^oz&|C=6ScHBu-P3^Xsm4ijQng~&Qe^+VvKF@;T?ot?kb<7lYDXEM2^BHF9) zcq4e=f)U-3blsEF0cZ5rES*k!Sh4kju0U}R;(!h01abyBgOR?@&W=kn$$MwpzahEi U&aUeA)&Kwi07*qoM6N<$f)&9^6aWAK literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..eb2cbb46c00a699fc20749d7bfdfedab44d6941a GIT binary patch literal 2702 zcmV;93UT#`P)-~a#$KuJVFRCt{2TYZciWf}iHv$xl~a@PYX2laM#cCS4Gp(QE>fz%UF z0}?18B=QlY0wSP@@@3Ef6(RB=g^<(&u?Mh5z1{iP>ru)_ zKeX4~+4tukcWq~8XJ>Zr_AW;I`){82_k7GV@6NpM^Sle}$A0X`|1)GNoD6Kc!Gh)IC7#titR7)i918`9UO%eFBh^&R;Mkesj7T{yo zb$7UJZI#wisgrE!0#ufQ!vQ%#z^?&luVs+HIt}V7!!X{RNc)t%e8iN%=ivOZUxX?MWEbi7(KU&h-%b!!wDd%S(beVAvXtx z6o3^i3Heznm2w)jTMssF{IIjVedIa-PoH*icX#*BMr<~e0Fs(%7FR)d zeqd-wX*j1>*WYNw-gx0SPRgzD8C1V;-zt|zPU`FH+g`6Ntr5qjU0hss^McpG%KWLi zc>qYIQcglcKY&$%q0c8<+g6cG)N8Bm8IZTEZwlo}zcL?Fs&ZvEn;ogwPBTGLEX%o( zz+Ld%3xRvGhW_JvY}Azi%d+Mx$~pjT9`O@KI`yr|Se-SByy^TWZfpVymc1Orr5@3cCOkHsP7l=+TrQVu?dB2uYGVPIfjTC%lm4S*B(Nx8vD>t7TRx0YUH0!-6fKxpecB2vkT*=*|d zdVl)_#t>3lw+mI~z=jQ{2V;ByeZoHy;oBxAo=y}i935OSwiM&Op=;o$>n>C`k@aGZXC z3p}E-K;0G>glU=w%{=7L7a+Vkj$1DTxXrYj-xiC->9J&0eh31~Bbhl;Dt)&Wy=DSL z;l@A|4;zLt809;c%e4a9vjDyl8))M=uk5PF<7PrOn;jwOe^8X`YOM`Ijpg(C!vLJ- z5tWr&z9Y&pN$Ke9T1ucliZ?-=Td`PnqMm|ne>IF7ngB^8E(EYQV*;${ z?d|;_%Bf{J7Xi3DF1U$8fLl$o79y?fRP~$of-D7N&jvYF2_Vqv zb0YF-OcYc0@(b~uieUs}?+g-R6HuwJW{quZRTfsQof;_7+HNT6bjP-w0K0NxpU{1 zyqvHZ;H#*TJTNATV$ArYL4e2vkn9SGb_6+92~dC;FjMvB^asIQ)c9nAlt|y2*4i5o z6{3@11;=q}er~ea><9#p#>d-ah&&Qik{|m-pWzcKSsUb4 zC7`>zd#3=ed1Yl4Fcd&J*>XF8ZP5`o4+7W;@%I6OuxZ!^-2K3D7jI!f3a5kM=18n>R=9_zXjT zK!BH`IE^E8hObPgQ^B5~UyIa0`Zj4oc`S?@nt*gVJp^L4M>H+DyButX`ye8&QttTx z-jCun1_@riPUT(^*N!ty=K}bfFvEtCS{=r%T@@DjWkB$~!NDOT%5gTE{Zyb%M^lrq z7weT313H%fx z+t50(l_Ixf^qz<7=|UHa#hGPSy$kO#8uErrCVgKmotP$rz81hrKVN%haB%R@xL`!Y zH4Oc3x15{<$}#}|j??jAn*euJ+|rzEI`vRJH=oPpTFYhiJNRxM?`++=rDk6csH1$d zY143bOVWJ@p!cT#QZ9|0(%09wJ5GNOipApea#@`Q4d;@WC!0O@4yI`>BjietsH`+Bh&#DbSN$rVca9g0YvDZ+CRkzUsmmvFK*F}|_K}eh z)kq@4P_V44L0Re(5|?K(`tms4x(j%w>0C_EcjAJ;Bmdg5?V3iPRSg5VR9#d``psVl12_JMuB9DX*!D_Sd6e9BxQ+V^xRbMc_J?+c39f7`Zdba01gfr z{)FIj8now1rCqBVO~&Zqs)PC!)R_XD1t4r0UIuYhJ#YJ3m~b0sQ?aPGRMZ0?z7aty z1AG;ty#mGem6APeR;EAS{ljsTby zK^KS_8139_1GrrvwgNUnxKSftO{dfE{WqLN-jDs*kN;i#2fG{o)WkB`5dZ)H07*qo IM6N<$f?zfMod5s; literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..f78c15360f84f414dee6911d6bc2a82d4261c236 GIT binary patch literal 1336 zcmV-81;_e{P)-~a#w>PbXFR9J=Oms@O9RTPH5wP!jYB;_JT1S-&gDFjReB>{q>(AJ7T zDLEQaBK86yCi-B4f)FPS3iZVVMU>hWjq<|uqHQS90n)yJ1ZzXULSifzORF&uFp9LD z*~^ESDQ9|b@s0I#_S)q zw=!71|Cj$&K)RE+AZ$&cpwABy_bj5@f@LKq?n}UOXVVz5_H$re)YYa?ZO|iOq}gY} zZ5^So^_meA!)m9ANE)yjm>P|*v7O|es4D(r$O6)xycyO?6)-D8EdJ1qNeAlc3PSyf z_WS+j)P?J>0v`a$z%^s-s$-R<=LRicSyoQ6!E**-g24Blk^jDS0XUf|J1qF5}z8Ff}Vb z86n>q`z^2>&|Wi;x;FP|FlT{3)tH&b14XxEbAG?yoIc<3u8O=5jO=5@{|LNSTVDLB zo5XP(-z_`l9FPL62$mPu#O6#~zA(E1RApy(@>3VCe;rL_U*rIz751dA&EMxVX5|Ey?=`n?6z|C=-nG5@lxoMez4z~GLpt{D9=bye=9IB6nP0O~PodI}Jh0;t-f zZaiZ=ZvY8{pzdy?)oV7!X$$Ky0IR&vLjbBt5p{Yw4n|oq4Dtw}@UnYs)Y}Xoksi`b zfJB@Loj!LN36axmxHi>2koJTa_T(sbd=+#zzuzwd#SCDc0kGZRavdOKLK9=2f`S4o zaP>X}TyqcFAG#C8*4Eeo=iURq0f;a?4nnA5xTf*%CZNete@o1FPk^B=`jqZ|DJHlqj+) z%39e&K(MN`72zbpgmE`)z8mz$c=HZWGnj)&A}Rul=T6?~_NQiTTp4Y0KL-O}cHIr) zcDS{&6+i@kMs{{$%->K{)Oqt^lL@+q{y#?uW!G5G?RD-h>Nt)MVRuBJZo`$!xH7qX z@u$}0S@UKJEYwiK?Dem#JXBv_uK;Zg4Yv7We3x7O^r9Fr_BEjAx&V3N5dOt%$j#Q>Cu(vuUx6`w}2u{@1B2W!_L@>=5+t%J0wmy$4L7NtA9vs zr|H~K7x?P;zBmT;W3tT2U1+Q+1fCsCJkW^Pt--R=+JORx^lSEF=H_W36Ur1L%SAOw uBW=|Kv;ZxlT90@tYs-r+4F&hXw*LV4fZDKt8Qnqv0000-~a#$=}AOERCt{2TYYd;)fNApyPHiS=0m}+20t*!Ktrq&w8qlNN3s}& zU^cu~v1lNh2wL0Xv`%HFuCdy&9|9wzXxKnRqivT22COk(c2g7_h0r1d7&S!2)K*DC zKp^{e-{~JA@b>N7w{MeOrqlA9*+1U7zkAMk=iPVTz2}|<&f`4J>^}$^PJkeBFy#X;85hD)3tRm-SWW}>YxYvNDFz_xhybL}d$npt; zdSo$hEEyE=1&~4{(m*s0j0r@X3#I}9$>9_-u+0Km+E}-C-$?u)Q2=I3Wj8AdZ3b|K zwvB;f0NxZtTLXcCw^}!CI1-KSTxnVIs6hWrf|v{9B0U=bP61flT<3m$ST}$X1R&p0 zwt$G%0Z0sSis(6;&HBt=UR%>UT>WZDl4R>s(#iom4&YL4I{{DUPR@9|va(W%R(I3^ zaJgJ!`@Zg{!2Fn|NdaS>6{u{ecOQ;cuNf2-ElxRM6^{_%=KwBLw=rn5UnDH_dR{ml zjn1e7;BvXd_74x&g6M9ImTo~@+~}!(KN@|*MWMqv)=$`k&8Hqy5Uo9YTmN0+l*&}pRn|$051VB(M%rzyTSBa zx~1yV6rcK?x#?|QwJ{&4+-k_UzH!K!qIv1yXq)h^DDTvcdsZB#-Z0u=Jvfk0=d9 zWElBqzzo;+eP8@(&YX%1B60nx{ucp!c1A!L!zYp+2*(fq3NU^VETETK>(_T08J8r< z<{OYV1DF-b(Wt?g?@J79aJgKDudTPH<`kGT4~id=BuRI)>nfWrm0k|!+f^c2k@=|z zE>d40?Rfxs5qQG}gG#pV?T$DK(=C0k0Q`|kl+mlC=j(BG1CXF3EI{!5@OJAK_rHvc z7L+*e1;H7~xsih(pXDgmy_q3+Je~lUJZc$%@7Lpo8BRPms58+PBZH^k&1Z}_v4kLA z5pGBifkV;DLk$p6fR%%4ZoqWXyAgD)e zT0c^Aw7if2@JZV(0BkDJ-&;IYpJ{nRkR-{%#6OAbb8NwcpBlASR#qxt1U)!~MM$19 z^c7$+S$#=_ZAONAIqmxZE-~W73E2fD4_s$NAaJnnj4UljCjgkFzEl+YD1@Un!kBN= z9#1d=C58kN8sB-6mJ%8O;%kBhis82(;5cW2!-EJR@3a~|lC{2%({l8_0x3a8fCzhi zI+v4QFc@PE+ed}?o}#5h41iz`n`1k@D$~o>o+}szz*|!@06@JHv`Lbrp5S!@5VS@1 z3lVk$($)qMM#s4UAz`E{LYybYu^<9-$gmlL*IVf)z;J~aS12&dK2I+#O$1<7iF_W9 z$EW6mt^)>7YR_H+=|)DF@kL}$;{zh&09bmgX&TWnEhjVpz^B1hLT64*`(DHL_`=wB zqH=A}HKR*Q(OU=XS6>pyaIpcVdc*cOf>;>ZCKf@yGjKr52?>B;1RXXqFip!*Lr#^O z07P{f6C-@uSYNfhhqyu6%11H zE|*I%Xikuj;nng&0&x0lZHHRsCygQvtit~!fTM;E#}=O-r<9dOgm*sd&Oy)`h5G$H z89TK+-ETMnn(ePrWMr(tv;Hflh#8|;V)+iw%9BO}5?Y`6Exq)(ZU9(TY5}N@nrUXC zw8(JB=l^=_Dgcc}oY;U~X|8kE8ZlfhmmntXChcWCu5JLDx2)?XLX%3AC@WU&ad;5C z-b%k5@ZZfqJP%3VlT+jhL^zJyv9J3csLmk>_)yNqS}n&! z-pw_A%z-=N6oj3MjJqNo$4Qc8W9DD0Wz4)X-04u*05or`ew#RGGPGF;Pek&vwSIl4 zKj6OwAl--$3(S8!E>iL$C1wGjS4piv@V2)n+0Sdj@r^bztOzU*7SVln$!WL;2L?xi zeB@hqg6Nm5v-~s-#@7HXZLY6g5NXl_fa&*Cj3LmkG&+8>Wy`v-J{V?JJ3HFDGQXXZ z3E(@YMFd9Sxa+38cIaUHH%5KCy4sY^j`nxQPrSLBNVyO|7GQe!c9eisY!N?b*|_#y zGaV#JvdMDdR?ykB7Xf>E#)z_i?%EZ$b|~WMu)TQ6rEKx<0pl{2c)RsP^2~;Y)dOan z0|ry)r;?Q01*3$4Yz$_Rht3VZ0;n6z?Ig&PMt!Z?U0Wm+lsMM_SfUciLh!UmWjm${ zB=Q~3TZrI=sv?X*>ssp8Ix&I*iCk$}a{6(<5=|iWV4q+9ATvL&mJ!3*RPU~i)Yo*8 zRDq*xA&7!1E*Pk~NF04Q+NTvmkiEqDFas;0n$L)^s%fKpnHdG9YlJ%Y@7|M{m2&}r z@0~FOKk2qcb$mF^N~W5BwNO$TVDdO9KjE=Q9hEfsH>~ZRLx*i>8y0> zTaLl4Fk(IViPRWTv9#S$md8Z( z07i%UgkA!+0@!LvKG_s)FeFK`^#s!M1o2z|^8n~A!)0PDH8b0X!-&h}?ei90$yUoM z01gA1Oh6kG{>n@TElS{HR=6i&RMK&U`U3;LloY~18U@5SL72cyxgeSiaH@gM4@h8X zlgGVlB>u0k|oax&d?o zSRtqQtD`N@G(z0|G&Q@VJd1%+1{VRCFdQ8Oe5rum6s)|Qn?3fO;rt)KgpK&aK5x;L zN`hqufwBN)BACVjNCS|H!IPV#0Qv#?9N+^C9AFV>YxS((kN<*N^Z4Jze*l02 V>VUGh1^NI0002ovPDHLkV1jUnL5u(Z literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..6d9c9801cf0b6ff3649e3eb4b6e641719ecadd20 GIT binary patch literal 1232 zcmV;>1TXuEP)-~a#wf=NU{R9J=OmtBa|Wf;YO=biB@sWc?4T&pGfSSkf|R*60|QPOmG zYukt-K@_EnE`mx++M+VM39QhHAOx?>c2>>p0}8zeon6f~NQ%JFR<{fUCDUx?JzdP~ zIOEQ)JJy}&X81q<=RN1VU;pPBxYVI)lBc)3CXu7j@*ImA%mhIIjv#uBb}2_X)2yHW zR|7NCPDOhyFl&gUT{&r0SChW_PX?xL_La$G+yHv45bDL=?hrmxj)TJ^y?-Z(j*OSM zL5g!h4Z!sU_6~xUWE%8))dps6^-VG7ZNP0nuTbmAv3#_1ma>CRsnsDhg-2z-2GmL% zj@F{ihtxe}1Jky+HW8cw#sOOysV6h@b#hSQ^YB22M;t#B*MpW|P6g}k-Obv6K?C(2 zzJfE}4b*|xWxB&NyrNi*coDYh+gXXd2I$FJseKQtw=^Z$Z_wZIT~M9P_RjD7i%)NN zO^9(R(tONBAYu-Ic4XnhG6BgMdu=N1TA`&$c@y>=Bv)L4)D}-uaF^kaTvn6zwdh3g zWvfH|6rRU^2^d*<#+;J$!k#AHDHW;P?BSOu-3{DI)PhX2I{My)((y|84S-<1+E09P z+*nx3%HsLyj5c03BOTXc7bkb1MQ4Rx%qx0r>ARwVsh{{7%>BUelR4fm<*lF0YS0sy zA;D-xeLGK=#`ZLk27UzYNTs>6pMhjxAt2-(2U>KtFFtLHYr(4vGaNdiU%zXsuPr`H zmc0!iI5zb&fa87npYVApPa+YY0)|x~T@YmSKapi+o)o?Sur#~B0aQ~M_)8g)wV-P8 zq6a@%`W(c;JSP(>7{~{MICqWmho$yn4cLWGasgvU6u8B8eFrgA7~ICQZFfWxH^Cr%f+kM@1wN(}f{00(X?qmVneNQm;WxpUju(-$im zu)|J(;5e_0MBzQ)Vrs$Jm<%75JBo7)YG3y=Ff7S-0HXy{-*@raWg2w=`R!`eEv@NX zq;ogQ7HAPbR7m$T@J)k`0$&5;hF#6lQnKu^@EoFwt?n9*2=tDx7K&~ioW>1<@zUkOpV}m489#%;WZPp;jz*xTDRH5t$dwP(5eBeAwa4v zw@K)6U~8sZ51n6*r?vU^1aSq{e8fb+hC{-i<`QAU-Uj_tz8F@0I&J_h2Xg*2B4%Co5ve^lMk6V4_A_E}b1H^Yh%YeTeb#G_0_MV?NV0}xq`DWp5z%9TLORblUVdGGm(iu}| zcD^Z{1oX&i*z>Tyt&~1!ft`}}m=TU2fF3D?dTehGiSSu2%fV!%_w+F0s2t;SaD51I zp7U*a-v{T*nAPI07X3Dm#*iv}s?9Tn*8=wpCEsGd(8^4czPwOwRe#N9q)Uv^_~14G0000|r literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..63476a0752671e91713c24391dd98aa7bfd80b56 GIT binary patch literal 2656 zcmV-m3ZM0fP)-~a#$5=lfsRCt{2TWgRM)fqkK&djcZEQt6>N+^RdmaYLzaG70#E10BI zf-Jj>8y}_OBPu4w#3UwKrHe+5#t4>G2DO5vB9&xdcK|I>tHiYs*BX12};HXK;Tsa!OK%?}?$2 z){d0H@f42{a0q}w03rak?ftzc=ncTUjwqJ*PT@P1)>g3qj7#a8j}|%Q<+vkC4nShDj+A5XCU|}T%>q~fs!P_aHxc|(8Eml@+YbVqodz{A zV6Y5E2sjQ<1Ard_hzIywZY^i5n#R{k(O*&k8d4f-r9}X~o}+j>s3$4&xCNf-ZQ;j7 z`A#bCL~t5u&jL6lPaC^LUeeplzxGEzP(lF4cIZ4%4-u&Li=uRIwA$S9!eoBZU;l2@ zCRJ4v#ZLg;1mFmNxuDy6Up6=4X4+zX7axFjnZzi2E6D48C05Wwl)1U5m79w8TL8Yd zST$*jYbpI2z(7x-uqf{Eg0431D8^@T0ce*=jJERup5rUoY{=%7&Fn48Uq6xP&@dRK z`~$9tb*$!uo=MzRs4r7g!zbC9IXd5+5l`MYPQ=Z@S@%pJ{ndxGyr2eHI&fH0FH8*d*fSq zYS+cwRgBR3PMu(dW*R#R;xGWi05||Pk=i6{)+&b1qSpWt6Dd0v;KeTM9*Pa!ty~*a zH8cQ;PG>H_OI)VS(Fp5SG;wnw+G>-ks)=C+q$>d&Uq~Gh>kN4B@HFNvXrog|oim?Q z^~XE4jKnyXd2M_M6I~OT$yYBh0EteG2ejO+4dS?-R(2O6YHUhVX>}KfV+-Nuz)J#u z)!V{lg^&}AbtD|U3gEDPHiFl5xA5M4b@C5_5&`|eXPjS1=f^ytSR&=zM=4c8=KfgoeZp*HVaA zg>ego$o9l&{e8?54G81Lx8Z&g@3~Be4fqUKS=sCsPWpQs?vM3 zNWk~Qg!Ti|qG>%Eb|>@=%=G+Gg09UsH^}L%E~&2pIKyR1D{5{HlqYdu)ZPc6F_2dZ zh}Oht8+sQGPh%c{w_K*9HW>UM7dK}BB2k=&zOAZ#4KM3y;s-&ECKlm*f|rGfD;>P4 zexY)9W*-)`(IK?JQ_I+ka&dD8K+stpgXNN-2FEPX07!QPamoo9%?h3F8spQ3)|Yd#RRpvq-> zX-ym7^YixM?4%-A`gy42GK11JfrOiBDS7@lDSMwXD*y)gwx<$36QL|@jNudlhX;zO z3`Qmv>RUksOXJZl+7tbp>@h(01P{TQx3V~Hy6m(-nU#b=Yfy2-z^9!j_&M1DAiv?h zv_RmyA7Z6)dZyjT?D1(AM))~d0gy$FkML=r2JY9v&yQh2g$I9@rM9$Vk6EZ1)B{z6~?x~5|{0QX9;sx~S20G}fOz7--Z@@{xcm;jT@$9_btR0r9Q z0I=PC?Y|@3*t^aSoFP^ifxFKW9!52QsLQnH^)~Ktb8-xV@a(ACzEj*F{41oqk_ZgI z&Os z{kw?{<$c|BUCdpS9uAdTW=MQ6a7(^j2H<3GC3N{|SpnF4wzkq!kC^P|xe;^BEdaI# zDlRWJMjXrzBGiq-7
  • +v0~}wV#(~KY*T96rm|WjV*8EhX8|jjLHe}hLvsH8ALI# z9?gQD%C$Y7GXSv&=A$pEVQ*!ec1lu#E57&;+ymn2K;h*8HLqtX<_B`xWk7lsX|(2% zT-2NaSkc7I0-pJzGEkk4TK{pl2VE1H+1+<=`evZG($F3M)Lb5R99KUY=fZmk^L~8j zm;G@g?=)8ApFG##PserW=%9vQYUZbo;6UG<5Ff%H5&Ru;Oh1djM*?T`G@J9n20Z{6vqXnc@*LqqynRIz^J)lO z$#plg3)DOhUrHqw>&P%MT@#t%kB zHkXx>AkmOi{E&gL#RM{szNX1WU`pfpgM14wUO1cw3r3b^!5^p)$!C(4w%llE@PiER>#*RXhp{^HDS61J^+W=?9 zw_W)h*I+T1+&u zCyG2Czz7n9B@9B}$<0>ueKxld(0bCW7x8>g6W;hL-~a#wx=BPqR9J=Oms@OXTH)Zcp)u`i*jv1u~DORx9Ed6B#?ky zG*&}2VhD6gVGEj|pv1KSvA#gMU0QZ+Vn}$hi49ahNi^`JrMosf*kDW`U};N)CK>^| z?9TCFyUW-6Mc??peP_-&|NqQ4Gv^H4>5%a_`zj91w5jA8QCWg86JZ95LAi`b2f}Gb zZBt8R>u>+70B?Dy1f?2yag148MRjLuWb60;NkDN~ zYtm$6HG#*9ons73)v_94c3=AAPAav&rD5BZaSK>jabTWF+M|d*3UrAOobtf6FHcof zB}bf6FlfBp1#f`t0WAbB8CZ2DQh9dF0=%2{6=HK*fN8)HCzrQdYAgR5k$3>+1wwgK zd#OWM4_rrhHg>SGZBzk^0-^ho34RnPQnV)S>3NT;DmxzX+fecOLpv1N3v{TaO5)LX zyWAc*14B~1gheOkAb^}neug2K8!~LwQiE4(qQi7{DQN< z0?-w)$kyYTG2@Q5qMre%>h6K$-tPQEeM>nUIlvSVYP|kX9cXrP?Tu9lfsgv;T1LfO(=`^PTm^5|) zSxj*fY;+r}G2f+g%HqKSU?zYga={&>%8Ch)ry=^X`!kp1c>skOg9K!ZMsB%|kqS^a zaRHetIgP86oJ{VAG8@qh3UVX(iHzzq5)@~Y-0n@tWq^b@o~%>)61q5H0mvoy*S*$w z(z@u(TyVE%r}8_1vCJKi9@SF-BC^aK4tU~H;skbt&upi|Py zra|w9ez`R7{qg+@ZH!I7y4!8>ZVImyC<1lBMV6Pfj-~a#$rb$FWRCt{2TYGR+)fxYN_wH_BlL%xHgVK@MmeE+4A-fAwH6q&4 zTEz#h^)V<>*iC>e!c<$GsY|SOv}y>uVB828L8h&lQKveJOtqoZB4h)W`oQrKA2g6k z!Xpy0+1>N?k09K8_wK!SlU=6M^80VU^E==9o$sDK_dLD}oW^OK#{VN6Wr zkC1J>$z!RMJR(^Pwv8f2nP8ek;29wN1i(lG;aef3nzm;be=r>V!wP_>Iy?=GR{)IH zDeeXEIuTwaS=zK?_2TYqe9u@~KXTxxZ59F7fiOEm8~p(8jzxpN&tCl?h8zI5KXN+} zuLDq!CW<*6m+g=JvvJ|Uq54;%+!t~<$CNA}qK6n5mquWEG&cUgL#V40+4{~t0HKiN z-aqyc0zaTB5ky!gB~iD1O>l44el6hQyB{x(+nmcl{0jg@n&MabWO?p~PcQm58=u() zAQX~3`^Ihr@vSO5qZ1Ntj6Dgp`bzkv`$>k{y`2JrX=()t8h_!``lv z<=V~@@Gc|eIaQqpfbDC7d+p9-B?B8ZMN`E9Z}jjQ8lPK;)nbZA8Hh|cy+f41Vs(qCX&AmS0=tpG-x zwDJqFXzUVK?=b5(yf zLMs-oxIjwEHy&RaPXJ>Ah*ALd5{bP+&`w#8U|MbINwSg0K13~p4eTwp{3=Pl$8oU zs0|m4PT*}YeylL>EGq4u-db0e%v8^C5_J0;E>U$JU?F3U)y}*9ksF+2TpuvF0oFSY z08^RqTt`V)tfD$H%Swe$Bf+?w6gL4lpfFeT?sF|Ps%J0)m^^{VUjbaAu)PqAE}3g4 z#_f;VLH!K`GHl#3i0fi!^*n54p`$Y&92n?}Pu#uXzN32lj3dCiAW{ic=aGPv3YiI* zT=Vo8qWBv*>pTE3g*^LRe{}n!PBUuJK=CsGzEYUR+MSL-CVs{Mu!Q^621H|x%RV=1 zyxbRZ6o}L-0Io0-It1KI=wFXe$nbC5+FaF71kHnzmStKS=sNQ*TwMy_YK18w3-O4t zKBhvKYc;@?#=K#GXpVco%XAb@>@MBFz$YiFfzSEO)peyFS2qA6mAoB_MG^sTZ(nn7 zmrjeQ?D5cqWCh+LMh*v+)>gs&xp`I{$Lvb z<)|Ii;o9%k^3noO;B;IBz;V(-@3lAG`<0gW9elnQWg-O4HRl?<#IU%oP5`WWaLnoF zlsbO_=|>vFR-<-0TwRxfai*b|{9y9*z{(#Q5t!B5iE*KplNJDGzCiUG;u9@LQ{iUA z@;oBR(j235iJ{g`xFC(AH4tH<%D`m!?guEZr@)3S6Q}*BRj}K%+RL<*^btTPRy87# z$zK1IPJSv7Fu|z2u+OR0UaaM$&jG9^Nz9qg*alZ+dZ)Fg1Z)z3*5-L}0Lq=9qudvA zC^>rT0M!O5DT#~+9y15)XLYQWW7vo5Ku>(HiokN(u=x(h_t}Ok#JqxGc=|kZUULBe zo5D2kVN2bBl9N6O0;&^L7ChQS#J^01<_lyTfMd49qco;oEhl{v1bwM$LrR}H)#dcQ zQF&g$#%;4~J5O!E7g~T$gphzq0-KTJz7qB07z0@HZrRY zMbc1otY|ZUtZrj+0>+o^O^bFJQ#9IjMod}&`efP$KzaXOF@1hGEdASJIseu5B_QsM@)>$q}X$ia-?sEkA_GTjbk3_x2n_%;CL zWayBRV!5fx#$}%;AOUD8z`z+M5EFUa#f8ki+S6 zZ3g4A6Gp~vMuEpDuh29AQ>q)sIXJN!z*&k~e?Mf$tWP7sxD|20;L*86@vA{RhnXe= zI0rzxdW5iAE~9m+hFB<))0#Zms;^)IY+27wrTg-?yH?3x>#X$+nvtJ@fBCRwy%A2 zpH*MEK)EmEIQP=sQ5u}6PdrEh-YhEZuKHrj7E3vUSsiDU9UT84gI-n{8JB?^ZEk;L zayGt(gDKUGXNO*%q!EILG8Yim_5uQNg9)KH>elYnhh@X<}RG&@4 zq7i0>Lbl$0CG$Yi@(g#7^<_P!_gl>;Qes%i(%wKrB|~}%fJ>+NAb?i^yed1eIon{A z`$7)qXjdi4xQ+#`2SINco&c!E%50wr!%mm?E?oURPNf=BflbKLRn$}fvy#PG`hBv3aL7#&~ebK-fYqL$zH1wJ) zM_PCnth!K0JdeP$0ZbaAoBd$CP9&ahD?RwPp?nWuhEwv{-0^whaxh;A(D@*g0T_kB z|G14ohlz0n#9tF(j}X{nBW&3ot^Me~As6{HPUAHGckv$_YsOT-~a#vrb$FWR9J=OmrrOMRT#j3-<#|vT9b&Dn3~ zpNE}YlWfvt*^QTem-+bSoA>*@VcyIexYa{iX}(&iBx8X+Vv+rVCQ%Xy2Bm`F3tTjY zsbn&l@2J4M=j}F@N#L=q^ebF8$jRa1#CL58%+1a9J5Kxqgy*7CRbd*@vnnzlc6C*6 z3qu=*;h?IMQqcnfKTv+fU3YL*G+sZBEik1Rn-(d z?^#iK6UZQxZ6Jp;nZyrU7ATcU8O2-zb_#s4wDk82qobpL+zh-n^7(vsth?uZl;gmk zsM(uJ4PDt(AfM0o#o|5R17iyBrrgAhe5*K%!Y7DylA5*`^4Bpg#6c{XuMc5B!g@R=`$j$JpR@5glhoG`3u; zzhnLrP~+9QY}& zOQp&??MSGql*|5Wio60`GwAaxXAc`}$!hySE&+ETe13aR_pyP2fyGwfxm+%OM{oaW z;AP;35q-pU-I=w0>&`BjOkNEg*#rEH^3;vL{+TTny%$xrYcsH_no`MsW=C&-E`s~0 zvv)l>Y_csc6bg4@oDT(gIx6|7OpC}_2-~a#!9!W$&RCt{2TYZciWgUKgGq-zpa32upQL`Vjd)I49T1+gb5z|GqNt8fMO~9&Dp-Kz68@A+?@_xJwhnP=Xaedm3D3(R94^Z0*;%*IKE4;@+% zo2;y);1Uh8M1j2k&J#!%Kpntw0LKX_0z9BW{zg{zXEK?QsI^6AK(SctQ_$8zaS(zJ z&M?ggC@*T7`gtmqdP77Qsz`)v07)rW)|H~L0l=y-a|6gxxb^MBho2f47_h@i8kzxx zg0%|5EdU0>${7qP5ZIJSC!PpnL^N$cKA*ox(_;?+_~H~{ioowhWG@tlsN)|kz|l&j za-!1KR*jd-on%Wlpt2M!2IMjUKMA0{Rzd>%HK_H5VZ7Ol{-zAbmr5Ve6m|jlKtS^e zfxJL+cT0=BluRbyZX|c9RBEqQC>CzrX)@y}7hTPHdJ&H~B7J@G4jxn5~Nk zfMhah=^9o7*y(BdP%PfIlcZj6uDVCSNU`{Np*-#G%pFQqZ_Q@26ZPf^6C|ZrwC*Bs z9~{?0U`y6WeWRWnbs11B76%k%KY%s|{gjbT-WbK~tWk`Z*4G5w=Hvu&lVK#En6B@% zkAP)a7bwauI4)j**QhG%=EB7TKqj4d2$Y{WIf9QC3S-Ns>pQIh6~!$85)Nuiglpcf zVIKq$p>3a958w|DIu5BkO0s3DzEc`tn&t`+H#;a&$>-AP^jH&mBSC+E|D>wg*8n*3 z9xKa>MeDYy`qeamq!9Y|J@n3OHu-8ZLZd`)Z|_@#Y<6-4?j9c>Ketw&ng$dsYbC%H z4$2m&Z-t;US}6NR5ELEEg%joSmurRBG(Z&YaufKmVHo-56-J9}HakJkeWNIM)S4Rv z8Za_4vJk+h9F(mp_PwF0j2M|z>PZ5_4k}S7l|B&^8)$&&`t<<*>zDv9_xAR_6|T(a zAR<*EpK)EqXT32#0|<0F zk45BPA?un=c(r$W1Ew{gT4h6PY;y^jOlA^5#X-e$xt#L_?>9iaizG45iEsX>5Ht}w z;XKfl<{LI=3krooD*)$uKzZ4+Wo2hf&fQG7Tvr*iOB4-uo(M}-ejqw@K-roKS z0LT8jEVnEx8G*h?K~e*7m5Wre*Bj?Epr@zjqyVotIa_%WodqbBN|(aDqkKG*Nxb2W z3tSH%;rfaaa4=kX(L+IVX(srRh*Z3Bfd*(AcjEMJ@4LOP7(R4pLD(Xr0!a8JipS?#>S+FZft=;(zI-0dRC?=4xfz&8bc7gO#HX0xfi0G@QmYtQHN`HPwn8U=E> zT->(RvvAfB5q~*yWNvyA@Y^UxEFiqgCl0?egQVPRbXE%rd^vzB#zYR z7722>T)d;J`w>TG0kOuDrl4yaOr=tPZ6x1Jaq!@H zPfM)wOZdN3-=wOn$Y!&3FXYaoP*OL|(hnfw9bz_t?NvLrdC{VUha1gX4^EfQ;;RsB z1aQ8qQSf5bE??Kz*LSRuoXwQV-U7jP05MO~Ndga4$`e}~DOj8eBwI|=S_{D@xa*b9 z1jtsyNNf<1YNNTEE0!)6S89~!09+8z{0_n08noTz@~J(Invu)p;+>u6uT)U01-KeO z&@|izu|AVYJvI~lKnUgX2S-O!Emid(h-;<@vjOgdXupNx-<6Vss#T80DwUJva=F^p z*4C+%>L&FpH7o|zWdgYpKv%7V1YSQ=F8{}7^oRI|iPEPjxL<%v!pd0#V}yJslTQ3} zCPUtfu>UfnnWl9$1setUaG1FP7AQn0FMi#q<|p^hct3uI-Nc+ iSITkcF^_rtZ{j~8dkHBG8NM9=0000VP)-~a#v$4Nv%R9J=Omr+PvWgNhN|L^Ku^TBN)%u3lNE4HW}S_}$SEA^TT zr!x)_LN;v{L@z<$=;0tm6M8DfVooh0pRQL+YqooJTwfN$LPjfu$VOeYhz*Te>b>{- z_i(Rvz1KM}UVGX9>74KUzyI&|9nLx5|G=Fdl1;L&_IRoF6{wT~C4do_Qiz~B zisbc&0%w2BsX&#}d@ycJyP!|6v+fw8CqunmBO4N^a9XyBwI2d6B!^}c1`RqCM<%@{ zKC>8$+dQ+SIIecLi1>h7U{^B#yp7T{GSK;Z)&f;d^ImIZ0N9@ZiyOOs??>TqTWl?9 z*LBUMt5eSd?*L`MFUH!V7y7%etXrVG{&<8*OcEHXC?qeP4ZZtBSk}M2wn) z7y3G8QWH%2jM#j^=>(j?4Z;C5*w@vL(g~DUV?QNr(JM|WpKE#y%oy;88gu`!zhiC# z@a1qE$2)7cT>3Zki=kq)H{wPg4Ezcp!k*0%$VbZ(EFw!|{|Okv$)l>x5>PQd z0K{C(6j;>3q}`DNEiL(*z!yc1CaL`y0-=HKX@rXiMLVwBmvc?8tUpnc+~mFw`Ohu) z1}okIYo!%H1h=}Op)gl)$8o#}rvL;!3FxWchc6*B7Z5GXWm+8ZeFuA?gFX=ttHV70}_myXk*y_@o%?ctn0_5+-Z8;Skn$Xxt@Gr9I>sT z-tOS-60`a>d$#V?-7yoZ6C)L(TB?a{)dNI;h^UStp8jB>>oR22RKi0C P00000NkvXXu0mjf={WJf literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..61cd48ffe12c5da696c0634928382744f01838ad GIT binary patch literal 2277 zcmV-~a#!mq|oHRCt{2TWxF<#~FU!xewc+{%9eg$j}C?ASk9Pm{v7KV8EQ~ zs+jm-)sPBed{F`UqefQbtW@lz+=72GbVGRGzppm#qp;CHx zP}&y?;@OfhgMeuOXMiXT5;hP500JPs0ErG3)Gi1|{XXxy`;L@!5WpmT z9RrsEye^0ig~R=Cv^MO$6i@D4Wkbria9{~REC+Fs(LDh40a({u=Y4fp4}b&=$aj}L zNJKRNk|IPAz2J1(fA^O^ZSNUwel-+DarVme3II<5xJO@4z?R(X%%`fVs${&m<2JzK z@rYw*yPgK~MqQNzqs9(YHPw4B#+x@56cw#Yy=oVa5#ezFUsBgG=wL`V*0lLvx)M*$ zxD4=kJmT2<7x#nc0bQ0ZL0o*;SN(Q8`G$)^clqQHp#hN{?z{HnYk5uk_XlFlWsB#= z&hhtEf#^{keL}EUdbrN}K|Hwh-FY4$$!PJn_`f7D=ta;4B#r6}S&W_U!Su^Kc1yMe3v}OXP_aP;@v;A~S zEO}yj1(vN`HxCd;0VJ#Fea&^=wXk4z7BBMM<-Z`pb83zW549Zd?j7n{F;u|P;a(~JEw2sar2 zzR3|V*E#-Qk3_pJngK-N@Nae8{+4?0iA022iPlE%XAEpnbIf?swPww@!LAw9fMrU> zLJ%!bQ9;RJj|n<0MJO$_1Hgq_1YrVSP5#MX@q@Pj#xJ!5z1&*AyE9>h7Nf1Uwhv6Y zABrDS6vc4JH#8tmDfudxzptW#GRRMxrqW_$*m_?9_(K(y*&{RZjbaTAa7f34&`y%x zY;E*@W}-$*;q&>zVDhOs0zYIFJIE`*%QY7hHJT-Eq(CI}ntx#Q8blayqsN@D<|NT; z=E}1kx!IFWf}n1-=>eqW=;I;`;A_tB0&uFRzqj~yUeL#lc2reWNiZ}&oMaKPP8s0=BGz)W>fO8PJ&=1u_#opzq74~aB@_+Bj`NB!787zQY) z*FIGrV>Ak+stW{+__w}k7#E>ERUa~>0fITMHMY@&w%Xc$03j9SR1`(s!5bQ&StJPw zF)F_KtwMwW#JH>pV2)@ucM9@KN|FGm*8>K8KHq>kCUPEdeW&(z8OX3kp7pSG+tYQ_ zWqnMf0l+63f+Bm)I|fN|nx@P+uMaVr2Xv^51iH^;StABwq0!F3Iekoo0fM2~Y-C`8 zKITq=VAg6UoQa6h69abVaR9gW-wBvo=q{gZg+MFe@puG-eyAZCZTh$f18(fC9anQ9 z(j~eB@YefXIneAVQy|ox`Hnu$a6Nzk-RG|?GF9COfP`K%ztPrK71GBU8o)uhAAoAB znU)kPrFWaE&_Z}T9zjg2bo3shSVIGv8*93V;8#&eL21`-hmTquKijn$z>J$^0zM61 z%Jdt>4!SDL;6JL%1b%dhyX@xSMPmbS-rtE*Fl z1NDW4KhqzM`mdr_rf&mbk%|hE;EJIRRSs!@zhTGcEO9@8eic1Gcvs&`7@@PqL&3GG z;t>E3t2ttt$0Xcm#dEwW-HSe|aXHH#>M|q-9 z6vdf2bNK94tVEXY+h zq@>ErKV`;75WcLfTw=0#EpSzPS6MgnDt8yKEs7)dLtGsR=y<90G92mU7J>uNjJ> zIJ?6c3kC6V04o3(O~Zr4Snsd*Ru4x%V8SrwT2VTM?Y8FuxTAyx2{^)pzcSMYHW~hi zC3ic$?og96^+H2KJMCgS>G>aGv{MFii!J4j>KJcW%A_ z5CG_(0H0&v9E-~a#vg-Jv~R9J=OmrZD#RTPGw_h!-`p|zEwDK@kQt(uL2)Jd}Nr=_%1 zX_J~55vhfuxNs*3DK4TY8gQi)MG-{NO=vS|qNx@v=|b9RtfdP>L5QG}MiG>1wLi>v zUl%h;lTMN*Wa6f0b3e{^zVkl!e)s2GxYp<~b%EN~HZmyY|^?CR^jVx$AFjqaXG#R+K2fkSPz|O)0rCr zGz@qpmwf`L1;3L$8(!iy#rcR&n5~9hIaM7Lqf?%SK%xM?i#FV@t3t076x}s>6eb?(4|#1$9tHmVJFm6F?Yden0H81*G9Cu*GpZY36%!+n z3hV@g{AJn20VK=r0|<`0$KBU{f#aivCVW+P@uEeAuK_G=DFr~)g@&IN3m}LQ0L;2+ z01D0^##kgRa0aA_j<`SCqw5`cdJaNw@R0!W~y z_?R2_O#s+o5Fj{iUn~F=w-wcnl>k(x=m#)*y#51MmR;NyXcs_K$dmwl+pP1zF0Vw2y#Sm~Rp^+KU9PxNuH5ZWb9HU zad|>j0_#JF+g&Kj$2Xj#F|WNt?fP{ljX7OR(miex?gAd3OT5Jyp^ofs9lcTPysl=A z8EN=y*uToM_Xz`Q*L1?LUb}W2TWN63_qu002ovPDHLkV1fm_ By{Z5J literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0f12c860be431b46ed6351643e9ba8a3c39aa854 GIT binary patch literal 2127 zcmV-V2(b5wP)-~a#!0ZBwbRCt{2TYYd;)g3+O?j~WY0SkV#qZx`$84ML$AZ$Vr!D+|J z0C5vc)ecH^sKwTq*0FSOMgy(bYAdLJNLxQDD$|*T%?9a!I#UUQd~8C-)={Bj>jyBY zS_2)`bSXTd%K(LX5Yr7&6(Lh-tV6Kd*`0__P+b>y$=}1FoyB}3=YIeu88Wq z(`A@RYcG?*1d106I0wK;0098U&iwWZ+6$OB5ybZP`Fy9;+Dc}?^tdibTe}G4d;pXB zl|*<4Mq8{kPj@t64@mi|(r*JK*2QtPg_Z)C?PqENuM1q2`X`?2yp2g8^ZJ8uOtWG1 zAcU!Y<;;P11uk!o;2A&eh@uS$Z`1`!+lL5#rx%(9ume<^tl4J*_`6a#Y%PwD0MaK7 zD$9UTG8iXdJfJ!N-vkiqCFgc)xujzO-zY|ZQ3lk-HO)$`0KS-|_&BJ|l-Xo~7up;6 zuYz(%6-ozi6=~-IoS)+y-6C&kkMIxu(GL`1z_gfd1oaew3a=xseaVMp_0G#bA6k0=RE^KS!i9&J~W8oy^cfhn3jiFI1T#ZM2=%`sd z7#a@%i3U6Z==aVTp~q`un%r02J`Eu3g8(jcgt~$OM%up1?!u*(2&6`jFiRxtbVSQV zJw9uzg1uGk)qrq|W&pg!5fa449rf%gMsF#wWe!g<$OZt19O22`M{s*@^>P~^5zsF@ z!F7p7?k+-SNs*}M2M|{}V}kCP^rFtnRVSwbb#crDFvAf_rmbl%US??#I)>kn*zX9P z`?-&BTP}W111$6t=P{+)IZ@9K{1jPAtZ!nP(0XT##@?Kbo7Dh8 z^IQST=Y3N*P%y@$nRBxJ4KfTk(_>C|#!_kg(Pw!j$L?3r0l<0JjyhO|DPCTN0Tus2 zEr4=I=+B)^-0$TLdaR(OIP0Sf?Ui0m zh5@9TWQl_2*aj2Y7U2|tlp|DL9hI|#&tiaQl7tq6;+?-#$ovZc$DPOCJ7Oqd*3+l} z;G7RQ{bmzSJ2_c8LAYjAZOZknJzvS#0Et49*Y%VQ09H&FfxHh5?}zb^&m%zfTUwbdmq^ zN{nV1fOB0jq0LLnFyPGE+Adc;Vy>4r*ikbHQ{Y}vJ{B5{Jzidp`2f1!q6p3RS6=C1 zU|pI8z0fwBsZ3rLlm)O3J)0WNRK`_TM0K9;DocfC8ITK{AzHIG8#Su|JL=gb;H6J0 z0~N`j^)81GTGU>S8vsmjgx(L0`LsPwp#mZxEt`=YXhIJ*qr16_l+!(|3*a`AJo43Q#vwq)8-EEJNAG%CQlL7j@{s}in8;gQ1;mS?b2vBG zW6z6%c8OJ`&D{jz?(^ZwU`iczt-7p`T*Y8|i_WhM>Q5Ps2i`aZUY~E{fqrb1ye_K1 zfuQ}BK<_P<1hggqvvOwxKP)tFKB$W-ln&yDgq8vLyr+0eD#aT*n|QR4oc-S_8`rIr z)&MB;6rG^-kV0lvAsZHZ!>p|eb|1zfQOn`puLJ-Pv}$b1EM4EkbfLM6>cwkfnrWyO z0AsQg9|5!pGMf;>ONE+I9aZ^AgPAgR9>974*@odskxSYme6m0K0Ux%@*R-n2SUn7& zp%+>b#5P%OrNLh%{7nXjD}p$YG)S8hsI=u6r8LHY7*E(bfLEjElbT$@J47x?MA%u3 ze&3$swQ*e|=>Y(x?hLym{%mX-PxR-O_rl+SOtZ|iNvJo}G66Nd<_6vdxGHoMPx`q> zv1B8;nhlz0j9ql*V~6qmO!GdV%~ob@$7^_{Ki>oNg#j7L*0idM7PF1)M3EB!j3Y5h z!btS2+#E&EXLAPt?IX=T5!({=*gIIZ;|^mO!}#CCe*qR9)Kii#ABX?|002ovPDHLk FV1k>4>5TvY literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..37c09a6d81e007bcf678f7a835755cb928a6933a GIT binary patch literal 1027 zcmV+e1pNDnP)-~a#vwMj%lR9J=OmtAO^RT#&A&w2ZSQ|D|4i`cSRs$xNrHO=(GuQ@hE zwob5!$eawl+I#9YR>9Sb7uoQ#}nl>G-1;uSP z%X=O#l743GTAF&Z|K;;O=lp-q;XUU(2X1!BYLe@kyDP1m*)J-)5GoNWPz=f#B1wdE zj@sVA=+R#b3gB%D`%pT7r&c&?TvU(6qes7A6F_Za^bV2fkAN3*p%h5JDreMjNA+Km zD&AnMrtw&@+l*niTIvzD=BEF~aot0MC)+Nr8en^KceTmbK13e?QX&Lz-7@*fKq!=1 zwxnRtcqhtV067j?1^jMc-}z|k&npJ-9{HdOTQmr42EKAiczLj^_3vek7pXcBF5NUu z55ghfGQwjQK5iYlA;6A6cw;8bj{-G{ewgq~y+J5sS7SaWl{$a8U6FTzq^j#n#9mL$ z&oGOJxYI-gYJmQ=nFEN%qpckxoCGS2IG=+qD0%^a&)?-mIDqh{YUzQsna@F7o}6p} zMih2>{o!Yp1hAs-0jTObiJ1SdwVP)(d@7U{cq<3gF@F_i0csmN??QPRn7TSO6)lwc zjN;KiFE9c;=<|0ylm{S~y?~&6J$x#ZE;Im$qS^;wMW4$9K;%gPMZPV(c~;h#@3JVe zGampd0UVLv)(fD7%qW0DMIOLR(8#q^{?NkcQn52L_uVr;V%|CMzbW|kLI8m=fV4QC z_42&k8V`WN_{jhx0xm5rH$=TT4R~-Nlkv;1MVAu_y@IxMeTO|De zs`_kgW3;&N_9|9oAAqrLZyvxV}_q6=8 z8ta;dV970IZ&W&DJk-(VXLur z4`S+b-7vseah!wko|cKFJXZ8D@%bZ-~a#!iAh93RCt{2TWxSu)fs-?b9XneBz$BM6V%b5WiV7`V6#xvMzD6I z9l>I|R_&;OBq2anV5}XS(MwvX^(!X3UXD$^O$5vDkROl!kX3n3frPz5@EfRssy zmCs-#+1>N@M-cAE?q+XtH-GsCPhXksS?0TbVZArwgptdEzTU<4r zh+Y6tU{}m|VBjd2S2V2+yk^IU=yd|7%&)vUs)&~f_(c+#B;Y*|*Gnl51F=sXM5m_t9!VduqPGWoyq$q7%xA>#p`0rH$3Kj$>gRvDrZk*;e z0NaVMjTEtS|LVmjt;C+Xv|@1QSB^Ugmt}m(QTQTw0B7JprmJyeCFJ zOW@^(7DhBg?;ced(E0 zUEgjWfys+jd1Am;=x!eSGdqSB^@p1WfbiO~Du91) zpx1eeS54}!Z?_4M5%~gvuen4pnqy9yUB7Ye1?yJR1>!R-eb#G-X-56Vxfh6F_@czJL~Db%3GgjkodaNohKeXsK5LiB zbmNATIj=MD@i*55zUEU;>s|4*aT6e8(TAW}BoXj#L+z4Q+nuHfb#?d0h)}2H1oNZu zv~d$apqU2dPj;E>E3lMC&p(d$7?=`pamKt=%Sn#CZLhubqbc`vBLMBF9d^WX!fVu- z5|H6`eGh=^GDH7pTD#OFeR0g@eabkGfcUO~*kh})J_NJgJ2A!^HKqhG z^UbA0U)ZOT={<0rPah+2k16QqC)nIcm8xCUIN;50#;1J z=1Re|IU6$oX!ip;57w1;YBlCb5YX+YvgG0Ev6p^)?KnHkK(!e)=1CCrx%QfbdFH%Q zz=~sxp1@I~Ce9?thqRXje8*;AeFh1s^Uj3BMvXZEBy@+3%(_jHD+&yQccu@G8dCz= z71|3xd;UIY%KYH9w!2F=R8y0u~0=mxDXs?!wDs+!g*Wcl59^r-lMETs% zQ76MjUHmOE*1ts&@hn^2^#z2`d1hc|eR+A*B#YNK=Az92E*~{B?wmL`c$M8A(*{)) z4E#(>5qMKPY1{-{-1pz5p)wSw={UUK!q@6~5WqMMbs{t8)UJ5iguB87eo0TzqKS)E zU2luSG$P-xx|s1B9ZB>`yx|WdNkC&w;9UUP$fk`=r*mJNQaM3jtc7XQ?!mvYnJl zWLm;Ij*s@u_#B|wm*ZpN=z_-F;bSK6`p?1LF^isU0+YAc69AzK`i-2*a82O3M7^{~ zxkjityz{_l?+iDHZqv|Sr`uhaJLv~+w>0f)Pc@bu$oH$R>%V`XhPo!|OE*uzJDE8r z=N{d?JEfXIOI2cdr*ofT&=wuZxC7*B^cIJ1u@b8{n6RLFlsnt=7l0l!G<_85h&_<# zH$NUMKf`|io63<9EiZy-si7%Cgz64BR~}eX`i0fFsbK2Tioubu9E(9%4q$|?k+6eh z#)D03OU_z}+2cv9pd|Ddz|{bphNkl%epzu+g_VNEWSFL^j<%NUIUun@SFdy#6?vy} zo~*08-|}44t6AJvQd!6lZvpVcX+8~L8-Q(!3%jf)Bj2yO+`~PEq+ljX+zUdyWq1Uj z(r``L`X1N^U_-gQZ{h0eI2Nk}a9-hWsW<*@`yDSR3jGLzp9hfM$*`*~`PX?Tb834s ze*rT=$IfAPf$9JN002ovPDHLkV1g&4NI3ui literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2f51f062442018b2ea3b0558b1ccf442d73ea8 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!h_Q zaSVxQeS7^NCxZeH%RvRPw1-V=J%T*mIM{yN`P+u$jCq=hneDMJ65D^T)Z)H0Ym2;= nzPmj$P%8rbHQw~*mfvr&ebvJI4IWK?4wCV7^>bP0l+XkK$X+dA literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c35b4653240feb15e25c4b840b598c5b47628e69 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+DEP?J z#WAE}&f5zcc@G&#us%$0^Jt$kGeS{Rcq6N^>%v6t;D!|oHqCW@v`_1(e#JhQOZM7} z|0l%eFP{=KNyYSerCnV0z3o;#e?F>I+NOCK?UldwdEdn!4Cjy6{CZbieb-!4enFb&$!U{x hO})QYduDxLIBF|n@^JC@e4uX`JYD@<);T3K0RUPtY-j)g literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..013ac4578b12fc76571f47db420fcb2653a4eca8 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i6U zaSVxQeS3W)FHkjWpb1~vVU~3VW~i-s#-?=S)4D&LC$j|?rtCUXI&=TKz{LqOPX3Kr oFY}iNs1*S&%?}j5IdkqJz8mbEiW90kE`p>yUHx3vIVCg!0A|-O3jhEB literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f713dd4d046c76717979a0d47a57ccaba9631404 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+DEQpd z#WAE}&fD1=1rHgB9GxerBy7ldob7^vAg^+P&jFK_n_4wFVy$j>STA`c{$Hr}tDno0 z`I?LCH`vePU;1p8%GM{J_S~1V{T_X@_fN&7HOGBCmz_@pawX*y-Y0K+7Wdn?M)`n$ zGDB3uF@`M+y^I-*Qp^{aOxPB%X7D(0Uyx`JTVTkb>p&d^X@3^4Ou0F$`t5cj8wX!M k&u1#1t;+9;3uZoK)lpY65SZum8R%sOPgg&ebxsLQ0LA!e!~g&Q literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0d425889d977a6a6b0b92786dea52168791861 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!h_Q zaSVxQeS7^NCs4IpVt3i6TSt5acFf%3xU8h+{g37kv7!r8cHJr2x%XY*;)EF||3;i2$GG2Tq=QOY;Ro<8_|B-z)nqK~kQselF{r5}E)KBQksd literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5ca39b1eb7ece9a93e3d76627ae2efb2746bfc GIT binary patch literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+DEQdZ z#WAE}&f5zc1)CfsSRa0mX4x9St}78aF*cyRR3MU7V!=$e@(t&9#Frf8-E-UJlKtwv z^#${;6`rlST^Dx!cSP{{-)sG<>ufyZ`Xwjvyl?-y=YH0AhMRJqU*36LH(8nKj|uYy z<_xw4>=$?(_!mev$T=7@*fyjwR56@o_`)!Y@dYE56u7fg)L4GsbwA}lgLmvIqwv&o gLDS!TS6z8fxRpswC%yKlBhb4Hp00i_>zopr0EZ53egFUf literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..e414c0c52bc0b10c01ee74448217e6a44a5e11dd GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i6U zaSVxQeS7^NCs4IpVz*mS!?wct&p2b&@)|9DTzy==<^3uS)!^uL+y0dHOR*mId3U|) n>5FurRs@*vzh~B)D}IjbmRmWWTCU~w14((h`njxgN@xNAbG|PO literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e8af20f3502fff80898ec36910768e740fe2bc GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+DEQ3N z#WAE}&f7~HIS)B7xIK(-KcS}gh)eUxvBaDv?;Rb{ONzQT8zd;2-HV;~;J3nr0}Jcr zJXQW~_I+=EL-yQnmCK(h_Qd*KpY}XExBB0YB(0MHlN8sBXIJj?`p$5=d(YkNR`J=r z`VW>%Hpn>`GuSqyF;p>}W%$A{i}3}c3G)T!47LUA7kC`_7f?q*wDN(!hig}V4h`c7 lIHvOXvsUu&&y&9FWp}@;q#_>9c?;-c22WQ%mvv4FO#tN~ar*!O literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..140846d759a7ff963856278443400398aa1f48f3 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twqr zaSVxQeS3MMAcKH_%f+PvQHmJ5x}0@A|go`|ln5H$a2qhfZ%xnu3a+e&T!<1B9`mF))V1%egs zn|Yu8EcBkN=~?bD-&Qx$_{-m~|0K5^yD}1oiT1CndMrt=2plGx_$HnmzkII~(sf_;m6TwdE?0jq>?6n4e|LIyvFV z-G!%Dc^RooR()q+_}3o4K=RImPo41()c1o8V_>lU$apmdKI;Vst E0D?74^#A|> literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..9aac0365ad51127f595ecece819298531ad89ab9 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twkp zaSVxQeS29^h(UmX_2Sc@RgW0-Ua_R5OgEaO74&WCeY4sLDz#$gJaTyz>{oq@OlIux iZ@Sc~KSAZ?ZrbzwOt!-M)CthZK9)tmo=weB-F$S4Me4TAEqdsO&y<~KWnxSpkG#DmF6^Jx@8O~hTDAIaJ>1Wz}tL?8GCW+|04ZJnOVQ=-+R(Vwd1_M)@1sYF}6+GQ-3d| zwm7JLtv3V1|HJwhBY-u#u}w+f$e62$d%^>bP0l+XkKMWjqS literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..96e2689ff5f7f4f5c69ec2c9bd5ecac9ee60c346 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i3T zaSVxQeS3W)FM|RPvm>{mM6+_L=oB8IHUruJwQI7KCtf_+HCgoBu`MiXQ}239y#s1O i0y`?_PpsOX_~#DmMODtf5}}U*L6V-XelF{r5}E*#Nh#d` literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5944e44c9550998d5b4ce1b448b1fffd79e0042e GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D0s=! z#WAE}&f5zcc@H^=xEwTfwQw%--SVKL>qXNnoyiwkIUQUkR86?iski&D{>oMLW-I!q zKP@{o!Fy85>B?Ds;Ts<-*!fPn{xNydM_Hx<#(BrFRL3 p1Jf*>ukl1~PEE63^=iE>1BWhOkY>*31fcI2JYD@<);T3K0RYeYVg3LB literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..941e14509d5b8c58c484db94925f6f6d09a4be09 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i3T zaSVxQeS3W)FM|RPvtzSFkD72wYftBts}hGw{(RrKuGhtF;?;>)&mA-3y}jpp2|G{| k0vtH|tEa6b&hg({rn|3M)-CcZyAP7|boFyt=akR{0I2jYC;$Ke literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e44a33be6c9523e88a75557fda60da7c348e4a9d GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D0tP= z#WAE}&fD9Df`=R!STFJ_E#hG1;alJ+$SWivvOrB#&&lycQ2NZo_|m(7Z~s#`X)nE| z`}^_Fi8FRGonfB-{O>n|vNt{6jMI+yANawWc!B9d<)2%X!D$Wi0~o3s)-rr!h-Q4l zxQ*!sa}MhU_8VLY{2N3M$R%hu*d7R@ih{GhO<31&{d{c;gYldO&Kc8+C*{23-91?_ V;Q90Il|TrR`%Jnb#fO-(1 hVfJ@P-ns65{ku0^W~-4%Zmk2!dAj4E2hPUl??0jD6WE{#D4I pVvVSNwQlL|X;IZl)=H1A#AR>@`&qj^xdikbgQu&X%Q~loCIDF{Vz~eS literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..38004682a2a882747f0036f792655109c96123b5 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6!i3T zaSVxQeS6)JmqCGtW1D*&P;jZ~j%!%vUw)TGO|t%xqfbjc0q8Spzj8 ifxLU^CM9x~cJG+_4zUU(O6{8nlJs=-b6Mw<&;$VK5h;xT literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d4b88c0476bb5b540ddf5108a02b52fe26618d8f GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D0suu z#WAE}&f7~HeGdmnxLuTQ`=F*XNi;}7s%>HCCKs{9?vR{BE}f+v8MR7JT865IFp8xoGuHjHe9y%e(QjP*xBA-R+Y_J6 a{L6GQPta?wk_;$B7(8A5T-G@yGywq8ENHg? literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..b503c8093ee49c71fae9ae15d78c6163cf10a41d GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twnq zaSVxQeS3DJAcKGa>qUP>4cA54#!-eMMM?|52>o7kHjIhkLHWaDG1VtRYPVhU_Vb;z g=)3>}!-KaBQD*Ec(+?_%0gYksboFyt=akR{0Qp@f2 zO2X&z_qkfhlb*HNrO(>D^!={u>GIc(-mJHquaf(!=lBMh2Z^T`xAAyRd%b#2-nm&1 f-w8pqG936?7d4fabP0l+XkK<;*7; literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8e54cfa8ec05ee3ff66c6ba131919b7a70974f1b GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C|Kp` z;uumf=k0}!xrY)&S}(p&@91bWVoYkjP@yzy%>*-E?ns@7TPDUft6D7IQ+2dvuU>!q{P(xLeGXszho7sK_FXNVo6lBZKAUmc#gMz@ nFFpkH#!-txB?u+~!3iG3ngG4-C{an^LB{Ts5a*s); literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..fcdfc0f21835c0e22d2a6f1010ca2e3f0bd0e37e GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twho zaSVxQeS3DHD1!h4!^LFHP{RgS-v_oggXS&i>iYfiR-=mNes1-kXyz0B>uRq>Fg%*P eP{s4oQMS}QtSl!j`+fioVeoYIb6Mw<&;$VZm?^IS literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..51b0839655f68fea36835f3b18acb7857ec06bdd GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+C|K_4 z;uumf=k0}!yoVeFSPs~}U<~9cRj^Vha(&k{LGHzoMeG$pU;27gZG_k9-MGyH)B*%I znqDr!-4m;41WKFIJE4aH-dybUHx3vIVCg!0M{u;7XSbN literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..9d6f84d51ff46471d0aa34652ecbde506cefddb4 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6twYl zaSVxQeS20>ltGc4_CP>KB)z4*}Q$iB}!j4Aq literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..3a95111e51595aa94007fbb3345f2e1c6f2d3a15 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6qNFG taSVxQeS46R5y)#&_`g2S!vVy6&nBS2!067npaaNZ@O1TaS?83{1ONs!7CQg{ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4b952259520cacaeb5fac54556987170b3bc70 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D5&n~ w;uumf=j}m8ULfz#g75yheC7*)Ok~hd&g|g8z}WxkWFSb`)78&qol`;+0769>1poj5 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..3a95111e51595aa94007fbb3345f2e1c6f2d3a15 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6qNFG taSVxQeS46R5y)#&_`g2S!vVy6&nBS2!067npaaNZ@O1TaS?83{1ONs!7CQg{ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4b952259520cacaeb5fac54556987170b3bc70 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D5&n~ w;uumf=j}m8ULfz#g75yheC7*)Ok~hd&g|g8z}WxkWFSb`)78&qol`;+0769>1poj5 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..3a95111e51595aa94007fbb3345f2e1c6f2d3a15 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6qNFG taSVxQeS46R5y)#&_`g2S!vVy6&nBS2!067npaaNZ@O1TaS?83{1ONs!7CQg{ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4b952259520cacaeb5fac54556987170b3bc70 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D5&n~ w;uumf=j}m8ULfz#g75yheC7*)Ok~hd&g|g8z}WxkWFSb`)78&qol`;+0769>1poj5 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..3a95111e51595aa94007fbb3345f2e1c6f2d3a15 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?2QUl3+Y?_qoZ6qNFG taSVxQeS46R5y)#&_`g2S!vVy6&nBS2!067npaaNZ@O1TaS?83{1ONs!7CQg{ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4b952259520cacaeb5fac54556987170b3bc70 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Drz97t)-oy9+D5&n~ w;uumf=j}m8ULfz#g75yheC7*)Ok~hd&g|g8z}WxkWFSb`)78&qol`;+0769>1poj5 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png new file mode 100644 index 0000000000000000000000000000000000000000..0115ca3f32bedff8b25115c025f0de5a19c4c658 GIT binary patch literal 714 zcmV;*0yX`KP)-~a#ud`Uz>R9J=WmrHWfKomvKb20$75LqqFU<+)40gwQJkc#th6)YfC ztbt)>3?Rh$J0TQRtbsMa2)85yI{*g6k3r-h>tjhSGlCvjue$F!erj7S_}7OFKUn+a zrpn-jz*UrIp4WUkO^~(GJi>F}r_gw6%-n}jfgt(_T#qjYD!SymZg(2+UKl