merged with latest trunk

This commit is contained in:
csoler 2016-01-01 15:15:19 -05:00
commit 6ecd2991e7
2342 changed files with 29868 additions and 19573 deletions

View file

@ -364,7 +364,7 @@ Changes for 0.5.5a
* Bug fixes
- Fixed proper display of crypto params for UDP connections
- Added missing location from cert when addign new friend
- Added missing location from cert when adding new friend
- Added missing IndicateConfigChanged to p3PeerMgrIMPL::setDynDNS
- Fixed crash when closing the main window without the setting "Minimize to Tray Icon"
- Renamed the setting "Do not Minimize to Tray Icon" to "Minimize to Tray
@ -1189,7 +1189,7 @@ Changes for v0.5.3b
- Added BSD specific changes - data directory and #including <sys/params.h>
- improved plugin management to allow services to be used, and config pages to be added
- Improvement to plugin system:
- made config page system more automatic, to allow addign config pages from plugins
- made config page system more automatic, to allow adding config pages from plugins
- added (disabled) checkbox and function to allow all plugins for development
- added config page methods to RsPlugin class
- Mark local existing files in SearchDialog with red text color.
@ -1202,7 +1202,7 @@ Changes for v0.5.3b
- Added Cache system for GPG Certificates.
- This should reduce gpg calls by 90+%.
- Added translation for "[ ... Missing Message ... ]".
- removed cache adding strategy to DL queue that was O(n^2). Now addign cache at the end of the queue
- removed cache adding strategy to DL queue that was O(n^2). Now adding cache at the end of the queue
- The channel message (in channels) is set to read when the user clicks on the show more button.
- The forum/channel news feed is removed when the user reads the message in forums/channels.
- The standard font is now used for new chat lobbies.

View file

@ -235,7 +235,7 @@ static bool trimAnonIds(std::list<RsGxsId>& lst)
RsIdentityDetails idd ;
for(std::list<RsGxsId>::iterator it = lst.begin();it!=lst.end();)
if(!rsIdentity->getIdDetails(*it,idd) || !idd.mPgpLinked)
if(!rsIdentity->getIdDetails(*it,idd) || !(idd.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
it = lst.erase(it) ;
removed= true ;
@ -269,7 +269,7 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint)
{
QTreeWidgetItem *item = ui.lobbyTreeWidget->currentItem();
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
//ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
ChatLobbyFlags flags(item->data(COLUMN_DATA, ROLE_FLAGS).toUInt());
bool removed = false ;
@ -376,7 +376,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
+QObject::tr("Id:")+" "+QString::number(id,16) ;
if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
tooltipstr += QObject::tr("\nSecurity: no anonymous ids") ;
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
item->setToolTip(0,tooltipstr) ;
}
@ -725,7 +725,7 @@ void ChatLobbyWidget::subscribeChatLobbyAs()
return ;
RsGxsId gxs_id(action->data().toString().toStdString());
uint32_t error_code ;
//uint32_t error_code ;
if(rsMsgs->joinVisibleChatLobby(id,gxs_id))
ChatDialog::chatFriend(ChatId(id),true) ;
@ -795,7 +795,7 @@ void ChatLobbyWidget::subscribeChatLobbyAtItem(QTreeWidgetItem *item)
if(!rsIdentity->getIdDetails(gxs_id,idd))
return ;
if(flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
if( (flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) && !(idd.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
QMessageBox::warning(NULL,tr("Default identity is anonymous"),tr("You cannot join this lobby with your default identity, since it is anonymous and the lobby forbids it.")) ;
return ;
@ -839,16 +839,18 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
ui.lobbyid_lineEdit->setText( QString::number((*it).lobby_id,16) );
ui.lobbytopic_lineEdit->setText( RsHtml::plainText(it->lobby_topic) );
ui.lobbytype_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)?tr("Public"):tr("Private")) );
ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous ids accepted")) );
ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous IDs accepted")) );
ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) );
QString text = tr("You're not subscribed to this lobby; Double click-it to enter and chat.") ;
if(my_ids.empty())
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
text += "\n\n"+tr("You will need to create a non anonymous identity in order to join this chat lobby.") ;
else
text += "\n\n"+tr("You will need to create an identity in order to join chat lobbies.") ;
if(my_ids.empty())
{
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
text += "\n\n"+tr("You will need to create a non anonymous identity in order to join this chat lobby.") ;
else
text += "\n\n"+tr("You will need to create an identity in order to join chat lobbies.") ;
}
ui.lobbyInfoLabel->setText(text);
return ;

View file

@ -717,9 +717,9 @@ void TransfersDialog::downloadListCustomPopupMenu( QPoint /*point*/ )
}// for (int i = 0; i < lst.count(); ++i)
}// if (!items.empty())
if (atLeastOne_Downloading) {
if (atLeastOne_Waiting || atLeastOne_Downloading || atLeastOne_Queued || atLeastOne_Paused) {
contextMnu.addMenu( &prioritySpeedMenu) ;
}//if (atLeastOne_Downloading)
}
if (atLeastOne_Queued) {
contextMnu.addMenu( &priorityQueueMenu) ;
}//if (atLeastOne_Queued)
@ -1076,6 +1076,7 @@ int TransfersDialog::addItem(int row, const FileInfo &fileInfo)
}
return row;
}
int TransfersDialog::addPeerToItem(QStandardItem *dlItem, const QString& name, const QString& coreID, double dlspeed, uint32_t status, const FileProgressInfo& peerInfo)
@ -1401,6 +1402,13 @@ void TransfersDialog::insertTransfers()
}
ui.uploadsList->setSortingEnabled(true);
downloads = tr("Downloads") + " (" + QString::number(DLListModel->rowCount()) + ")";
uploads = tr("Uploads") + " (" + QString::number(ULListModel->rowCount()) + ")" ;
ui.tabWidget->setTabText(0, downloads);
ui.tabWidget_2->setTabText(0, uploads);
}
QString TransfersDialog::getPeerName(const RsPeerId& id) const

View file

@ -239,6 +239,9 @@ private:
/** Adds a new action to the toolbar. */
void addAction(QAction *action, const char *slot = 0);
QString downloads;
QString uploads;
/** Qt Designer generated object */
Ui::TransfersDialog ui;

View file

@ -72,8 +72,8 @@ class MyFilter: public QObject
void GenCertDialog::grabMouse()
{
static int last_x = 0 ;
static int last_y = 0 ;
static uint32_t last_x = 0 ;
static uint32_t last_y = 0 ;
static uint32_t count = 0 ;
uint32_t x = QCursor::pos().x() ;
@ -165,7 +165,7 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent)
#if QT_VERSION >= 0x040700
ui.email_input->setPlaceholderText(tr("[Optional] Visible to your friends, and friends of friends.")) ;
ui.node_input->setPlaceholderText(tr("[Required] Examples: Home, Laptop,...")) ;
ui.hiddenaddr_input->setPlaceholderText(tr("[Required] Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor)")) ;
ui.hiddenaddr_input->setPlaceholderText(tr("[Required] Tor/I2P address - Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor)")) ;
ui.name_input->setPlaceholderText(tr("[Required] Visible to your friends, and friends of friends."));
ui.password_input->setPlaceholderText(tr("[Required] This password protects your private PGP key."));
ui.password_input_2->setPlaceholderText(tr("[Required] Type the same password again here."));
@ -458,7 +458,7 @@ void GenCertDialog::genPerson()
/* Message Dialog */
QMessageBox::warning(this,
tr("Invalid hidden node"),
tr("Please enter a valid address of the form: 31769173498.onion:7800"),
tr("Please enter a valid address of the form: 31769173498.onion:7800 or [52 characters].b32.i2p"),
QMessageBox::Ok);
return;
}
@ -555,6 +555,7 @@ void GenCertDialog::genPerson()
RsPeerId sslId;
std::cerr << "GenCertDialog::genPerson() Generating SSL cert with gpg id : " << PGPId << std::endl;
std::string err;
this->hide();//To show dialog asking password PGP Key.
bool okGen = RsAccounts::GenerateSSLCertificate(PGPId, "", genLoc, "", isHiddenLoc, sslPasswd, sslId, err);
if (okGen)

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>853</width>
<height>592</height>
<height>711</height>
</rect>
</property>
<property name="windowTitle">
@ -111,7 +111,7 @@
</property>
<property name="text">
<string>You can create a new profile with this form.
Alternatively you can use an existing profile. Just uncheck "Create a new profile"</string>
Alternatively you can use an existing profile. Just uncheck &quot;Create a new profile&quot;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -431,7 +431,7 @@ Alternatively you can use an existing profile. Just uncheck "Create a new profil
<item>
<widget class="QLabel" name="hiddenaddr_label">
<property name="text">
<string>Tor address</string>
<string>hidden address</string>
</property>
</widget>
</item>
@ -593,7 +593,7 @@ anonymous, you can use a fake email.</string>
<item>
<widget class="QLabel" name="label_hiddenaddr2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This is a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion &lt;/p&gt;&lt;p&gt;In order to get one, you must configure Tor to create a new hidden service. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&amp;gt;Server-&amp;gt;Tor configuration panel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This can be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion &lt;br/&gt;or an I2P address in the form: [52 characters].b32.i2p &lt;/p&gt;&lt;p&gt;In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&amp;gt;Server-&amp;gt;Hidden Service configuration panel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -761,6 +761,7 @@ anonymous, you can use a fake email.</string>
</spacer>
</item>
</layout>
<zorder>no_node_label</zorder>
<zorder>genButton2</zorder>
<zorder>header_label</zorder>
<zorder>genprofileinfo_label</zorder>
@ -772,17 +773,17 @@ anonymous, you can use a fake email.</string>
<zorder>label_hiddenaddr2</zorder>
</widget>
<customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget>
<class>HeaderFrame</class>
<extends>QFrame</extends>
<header>gui/common/HeaderFrame.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="images.qrc"/>

View file

@ -198,9 +198,9 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;When your friends send you a their invitations, Click to open the Add Friends window.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;When your friends send you their invitations, click to open the Add Friends window.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Cut and Paste your Friend's &amp;quot;ID Certificates&amp;quot; into the window and add them as friends.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Paste your Friend's &amp;quot;ID Certificates&amp;quot; into the window and add them as friends.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -283,7 +283,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Be Online at the same time, and RetroShare will automatically connect you!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Be Online at the same time as your friends, and RetroShare will automatically connect you!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Your client needs to find the RetroShare Network before it can make connections.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;This takes 5-30 minutes the first time you start up RetroShare&lt;/span&gt;&lt;/p&gt;
@ -368,12 +368,12 @@ p, li { white-space: pre-wrap; }
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;You can improve your Retroshare performance by opening an External Port. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;This will speed up connections and allow more people to connect with you &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;This will speed up connections and allow more people to connect with you. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;The easiest way to do this is by enabling UPnP on your Wireless Box or Router.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;As each router is different, you need to find out your Router Model and Google for instructions.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;As each router is different, you will need to find out your Router Model and search the Internet for instructions.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;If none of this makes sense, don't worry about it Retroshare will still work.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;If none of this makes sense to you, don't worry about it Retroshare will still work.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
@ -417,11 +417,11 @@ p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Having trouble getting started with RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;1) look at the FAQ Wiki. This is a bit old, we trying to bring it up to date.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;1) Look at the FAQ Wiki. This is a bit old, we are trying to bring it up to date.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;2) check out the Online Forums. Ask questions and discuss features.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;2) Check out the Online Forums. Ask questions and discuss features.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;3) try the Internal RetroShare Forums &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;3) Try the Internal RetroShare Forums &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt; - These come online once you are connected to friends.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;4) If you are still stuck. Email us.&lt;/span&gt;&lt;/p&gt;

View file

@ -26,9 +26,11 @@
#include "gui/common/UIStateHelper.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsreputations.h>
// Data Requests.
#define IDDETAILSDIALOG_IDDETAILS 1
#define IDDETAILSDIALOG_REPLIST 2
/******
* #define ID_DEBUG 1
*****/
@ -51,39 +53,27 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->toolButton_Reputation);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repModButton);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Accept);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Ban);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Negative);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Positive);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Custom);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_spinBox);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->ownOpinion_CB);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->overallOpinion_TF);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_KeyId);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_KeyId);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->setActive(IDDETAILSDIALOG_REPLIST, false);
/* Create token queue */
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
@ -95,9 +85,7 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
//connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(changeGroup()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
// Hiding Rep Btn until that part is finished.
ui->toolButton_Reputation->setVisible(false);
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation()));
requestIdDetails();
}
@ -111,6 +99,24 @@ IdDetailsDialog::~IdDetailsDialog()
delete(mIdQueue);
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
return QString(QObject::tr("%1 seconds ago")).arg(seconds) ;
else if(seconds < 120)
return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ;
else if(seconds < 3600)
return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ;
else if(seconds < 7200)
return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ;
else if(seconds < 24*3600)
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
else if(seconds < 2*24*3600)
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
else
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
}
void IdDetailsDialog::insertIdDetails(uint32_t token)
{
mStateHelper->setLoading(IDDETAILSDIALOG_IDDETAILS, false);
@ -120,7 +126,7 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
if (!rsIdentity->getGroupData(token, datavector))
{
mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDETAILSDIALOG_IDDETAILS);
mStateHelper->clear(IDDETAILSDIALOG_REPLIST);
ui->lineEdit_KeyId->setText("ERROR GETTING KEY!");
@ -153,6 +159,9 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
time_t now = time(NULL) ;
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
QPixmap pixmap;
if(data.mImage.mSize > 0 && pixmap.loadFromData(data.mImage.mData, data.mImage.mSize, "PNG"))
@ -217,82 +226,111 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
}
else
ui->lineEdit_Type->setText(tr("Anonymous identity")) ;
// if (isOwnId)
// {
// ui->radioButton_IdYourself->setChecked(true);
// }
// else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
// {
// if (data.mPgpKnown)
// {
// if (rsPeers->isGPGAccepted(data.mPgpId))
// {
// ui->radioButton_IdFriend->setChecked(true);
// }
// else
// {
// ui->radioButton_IdFOF->setChecked(true);
// }
// }
// else
// {
// ui->radioButton_IdOther->setChecked(true);
// }
// }
// else
// {
// ui->radioButton_IdPseudo->setChecked(true);
// }
if (isOwnId)
{
//mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false);
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
}
else
{
// No Reputation yet!
//mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false);
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
}
/* now fill in the reputation information */
ui->line_RatingOverall->setText("Overall Rating TODO");
ui->line_RatingOwn->setText("Own Rating TODO");
/* now fill in the reputation information */
#ifdef SUSPENDED
if (data.mPgpKnown)
{
ui->line_RatingImplicit->setText("+50 Known PGP");
ui->line_RatingImplicit->setText(tr("+50 Known PGP"));
}
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
{
ui->line_RatingImplicit->setText("+10 UnKnown PGP");
ui->line_RatingImplicit->setText(tr("+10 UnKnown PGP"));
}
else
{
ui->line_RatingImplicit->setText("+5 Anon Id");
ui->line_RatingImplicit->setText(tr("+5 Anon Id"));
}
{
QString rating = QString::number(data.mReputation.mOverallScore);
ui->line_RatingOverall->setText(rating);
}
{
QString rating = QString::number(data.mReputation.mIdScore);
ui->line_RatingImplicit->setText(rating);
}
{
QString rating = QString::number(data.mReputation.mOwnOpinion);
ui->line_RatingOwn->setText(rating);
}
#endif
RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ;
ui->neighborNodesOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f));
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f) +" ("+
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ;
switch(info.mOwnOpinion)
{
QString rating = QString::number(data.mReputation.mPeerOpinion);
ui->line_RatingPeers->setText(rating);
case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ;
case RsReputations::OPINION_NEUTRAL : ui->ownOpinion_CB->setCurrentIndex(1); break ;
case RsReputations::OPINION_POSITIVE: ui->ownOpinion_CB->setCurrentIndex(2); break ;
default:
std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl;
}
}
void IdDetailsDialog::modifyReputation()
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation()";
std::cerr << std::endl;
#endif
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
RsReputations::Opinion op ;
switch(ui->ownOpinion_CB->currentIndex())
{
case 0: op = RsReputations::OPINION_NEGATIVE ; break ;
case 1: op = RsReputations::OPINION_NEUTRAL ; break ;
case 2: op = RsReputations::OPINION_POSITIVE ; break ;
default:
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
}
rsReputations->setOwnOpinion(id,op) ;
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod;
std::cerr << std::endl;
#endif
#ifdef SUSPENDED
// Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not
// very efficient because of this.
uint32_t token;
if (!rsIdentity->submitOpinion(token, id, false, op))
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() Error submitting Opinion";
std::cerr << std::endl;
#endif
}
#endif
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token;
std::cerr << std::endl;
#endif
// trigger refresh when finished.
// basic / anstype are not needed.
requestIdDetails();
return;
}
void IdDetailsDialog::requestIdDetails()
{
mIdQueue->cancelActiveRequestTokens(IDDETAILSDIALOG_IDDETAILS);
@ -318,6 +356,32 @@ void IdDetailsDialog::requestIdDetails()
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDETAILSDIALOG_IDDETAILS);
}
void IdDetailsDialog::requestRepList()
{
// Removing this for the moment.
return;
mStateHelper->setLoading(IDDETAILSDIALOG_REPLIST, true);
mIdQueue->cancelActiveRequestTokens(IDDETAILSDIALOG_REPLIST);
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(mId);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
uint32_t token;
mIdQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDETAILSDIALOG_REPLIST);
}
void IdDetailsDialog::insertRepList(uint32_t token)
{
Q_UNUSED(token)
mStateHelper->setLoading(IDDETAILSDIALOG_REPLIST, false);
mStateHelper->setActive(IDDETAILSDIALOG_REPLIST, true);
}
void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
if (queue != mIdQueue) {
@ -334,7 +398,11 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r
case IDDETAILSDIALOG_IDDETAILS:
insertIdDetails(req.mToken);
break;
case IDDETAILSDIALOG_REPLIST:
insertRepList(req.mToken);
break;
default:
std::cerr << "IdDetailsDialog::loadRequest() ERROR";
std::cerr << std::endl;

View file

@ -46,9 +46,15 @@ public:
/* TokenResponse */
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
private:
private slots:
void modifyReputation();
private :
void requestIdDetails();
void insertIdDetails(uint32_t token);
void requestRepList();
void insertRepList(uint32_t token);
private:
RsGxsGroupId mId;

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>698</width>
<height>446</height>
<height>472</height>
</rect>
</property>
<property name="windowTitle">
@ -134,7 +134,7 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="8" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -147,6 +147,23 @@
</property>
</spacer>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
@ -183,206 +200,131 @@
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reputation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Neighbor nodes:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="ownOpinion_CB">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself,&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; S = own_opinion * a + friends_opinion * (1-a)&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The factor 'a' depends on the type of ID. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- anonymous IDs: &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- PGP-signed IDs by unknown PGP keys: a=&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; -0.5: Posts are not stored, nor forwarded &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; 0.2: Posts are hidden, but still transmitted&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; 0.0: &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset>
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reputation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="line_RatingOverall">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Implicit</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="line_RatingImplicit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Opinion</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="line_RatingOwn">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Peers</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="line_RatingPeers">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QToolButton" name="toolButton_Reputation">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Edit Reputation</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/edit_24.png</normaloff>:/images/edit_24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="tweakGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Tweak Opinion</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="repMod_Accept">
<property name="text">
<string>Accept (+100)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="repMod_Positive">
<property name="text">
<string>Positive (+10)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="repMod_Negative">
<property name="text">
<string>Negative (-10)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="repMod_Ban">
<property name="text">
<string>Ban (-100)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="repMod_Custom">
<property name="text">
<string>Custom</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="repMod_spinBox">
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="repModButton">
<property name="text">
<string>Modify</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -395,7 +337,7 @@
</property>
</spacer>
</item>
<item row="4" column="0">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin">
<number>9</number>

View file

@ -33,8 +33,11 @@
#include "gui/settings/rsharesettings.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/RetroShareLink.h"
#include "util/QtVersion.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsreputations.h>
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsmsgs.h"
#include <iostream>
@ -68,8 +71,8 @@
#define RSID_COL_NICKNAME 0
#define RSID_COL_KEYID 1
#define RSID_COL_LASTUSED 2
#define RSID_COL_IDTYPE 3
#define RSID_COL_IDTYPE 2
#define RSID_COL_VOTES 3
#define RSIDREP_COL_NAME 0
#define RSIDREP_COL_OPINION 1
@ -93,6 +96,13 @@ IdDialog::IdDialog(QWidget *parent) :
ui->setupUi(this);
mIdQueue = NULL;
allItem = new QTreeWidgetItem();
allItem->setText(0, tr("All"));
contactsItem = new QTreeWidgetItem();
contactsItem->setText(0, tr("Contacts"));
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -106,19 +116,10 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repModButton);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Accept);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Ban);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Negative);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Positive);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Custom);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_spinBox);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
@ -127,23 +128,16 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
//mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
// mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingPeers);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
//mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList);
//mStateHelper->addLoadPlaceholder(IDDIALOG_REPLIST, ui->treeWidget_RepList);
@ -161,9 +155,9 @@ IdDialog::IdDialog(QWidget *parent) :
connect(ui->filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged()));
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
connect(ui->repModButton, SIGNAL(clicked()), this, SLOT(modifyReputation()));
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation()));
connect(ui->messageButton, SIGNAL(clicked()), this, SLOT(sendMsg()));
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
ui->avlabel->setPixmap(QPixmap(":/images/user/friends64.png"));
@ -191,38 +185,36 @@ IdDialog::IdDialog(QWidget *parent) :
QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem();
QString headerText = headerItem->text(RSID_COL_NICKNAME);
ui->filterLineEdit->addFilter(QIcon(), headerText, RSID_COL_NICKNAME, QString("%1 %2").arg(tr("Search"), headerText));
headerText = headerItem->text(RSID_COL_KEYID);
ui->filterLineEdit->addFilter(QIcon(), headerItem->text(RSID_COL_KEYID), RSID_COL_KEYID, QString("%1 %2").arg(tr("Search"), headerText));
/* Set initial section sizes */
QHeaderView * circlesheader = ui->treeWidget_membership->header () ;
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 280);
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
/* Setup tree */
ui->idTreeWidget->sortByColumn(RSID_COL_NICKNAME, Qt::AscendingOrder);
ui->idTreeWidget->enableColumnCustomize(true);
ui->idTreeWidget->setColumnCustomizable(RSID_COL_NICKNAME, false);
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
ui->idTreeWidget->setColumnHidden(RSID_COL_LASTUSED, true);
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true);
/* Set initial column width */
int fontWidth = QFontMetricsF(ui->idTreeWidget->font()).width("W");
ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 18 * fontWidth);
ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 25 * fontWidth);
ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 14 * fontWidth);
ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 20 * fontWidth);
ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth);
ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 7 * fontWidth);
//QHeaderView_setSectionResizeMode(ui->idTreeWidget->header(), QHeaderView::ResizeToContents);
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setActive(IDDIALOG_REPLIST, false);
// Hiding RepList until that part is finished.
//ui->treeWidget_RepList->setVisible(false);
ui->toolButton_Reputation->setVisible(false);
QString hlp_str = tr(
" <h1><img width=\"32\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Identities</h1> \
<p>In this tab you can create/edit pseudo-anonymous identities.</p> \
@ -239,10 +231,6 @@ IdDialog::IdDialog(QWidget *parent) :
// load settings
processSettings(true);
// hide reputation sice it's currently unused
ui->reputationGroupBox->hide();
ui->tweakGroupBox->hide();
// circles stuff
connect(ui->pushButton_extCircle, SIGNAL(clicked()), this, SLOT(createExternalCircle()));
@ -508,14 +496,6 @@ IdDialog::~IdDialog()
delete(mIdQueue);
}
void IdDialog::todo()
{
QMessageBox::information(this, "Todo",
"<b>Open points:</b><ul>"
"<li>Reputation"
"</ul>");
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
@ -557,6 +537,10 @@ void IdDialog::processSettings(bool load)
// state of splitter
Settings->setValue("splitter", ui->splitter->saveState());
//save expanding
Settings->setValue("ExpandAll", allItem->isExpanded());
Settings->setValue("ExpandContacts", contactsItem->isExpanded());
}
Settings->endGroup();
@ -588,6 +572,24 @@ void IdDialog::updateSelection()
}
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
return QString(QObject::tr("%1 seconds ago")).arg(seconds) ;
else if(seconds < 120)
return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ;
else if(seconds < 3600)
return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ;
else if(seconds < 7200)
return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ;
else if(seconds < 24*3600)
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
else if(seconds < 2*24*3600)
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
else
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
}
void IdDialog::requestIdList()
{
//Disable by default, will be enable by insertIdDetails()
@ -654,6 +656,9 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
if (!item)
item = new QTreeWidgetItem();
RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ;
item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
@ -663,7 +668,8 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setData(RSID_COL_LASTUSED, Qt::UserRole, QString::number(now - data.mLastUsageTS));
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight);
item->setData(RSID_COL_VOTES,Qt::DisplayRole, QString::number(info.mOverallReputationScore - 1.0f,'f',3));
if(isOwnId)
{
@ -727,10 +733,11 @@ void IdDialog::insertIdList(uint32_t token)
mStateHelper->setLoading(IDDIALOG_IDLIST, false);
int accept = ui->filterComboBox->itemData(ui->filterComboBox->currentIndex()).toInt();
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
std::vector<RsGxsIdGroup>::iterator vit;
if (!rsIdentity->getGroupData(token, datavector))
{
#ifdef ID_DEBUG
@ -743,50 +750,78 @@ void IdDialog::insertIdList(uint32_t token)
return;
}
// turn that vector into a std::set, to avoid a linear search
std::map<RsGxsGroupId,RsGxsIdGroup> ids_set ;
for(uint32_t i=0;i<datavector.size();++i)
ids_set[datavector[i].mMeta.mGroupId] = datavector[i] ;
mStateHelper->setActive(IDDIALOG_IDLIST, true);
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
/* Update existing and remove not existing items */
// Update existing and remove not existing items
// Also remove items that do not have the correct parent
QTreeWidgetItemIterator itemIterator(ui->idTreeWidget);
QTreeWidgetItem *item = NULL;
while ((item = *itemIterator) != NULL) {
while ((item = *itemIterator) != NULL)
{
++itemIterator;
std::map<RsGxsGroupId,RsGxsIdGroup>::iterator it = ids_set.find(RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString())) ;
for (vit = datavector.begin(); vit != datavector.end(); ++vit)
if(it == ids_set.end())
{
if (vit->mMeta.mGroupId == RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString()))
{
break;
}
}
if (vit == datavector.end())
{
delete(item);
} else {
if (!fillIdListItem(*vit, item, ownPgpId, accept))
{
if(item != allItem && item != contactsItem)
delete(item);
}
datavector.erase(vit);
}
continue ;
}
QTreeWidgetItem *parent_item = item->parent() ;
if( (parent_item == allItem && it->second.mIsAContact) || (parent_item == contactsItem && !it->second.mIsAContact))
{
delete item ; // do not remove from the list, so that it is added again in the correct place.
continue ;
}
if (!fillIdListItem(it->second, item, ownPgpId, accept))
delete(item);
ids_set.erase(it); // erase, so it is not considered to be a new item
}
/* Insert new items */
for (vit = datavector.begin(); vit != datavector.end(); ++vit)
for (std::map<RsGxsGroupId,RsGxsIdGroup>::const_iterator vit = ids_set.begin(); vit != ids_set.end(); ++vit)
{
data = (*vit);
data = vit->second ;
item = NULL;
if (fillIdListItem(*vit, item, ownPgpId, accept))
{
ui->idTreeWidget->addTopLevelItem(item);
}
ui->idTreeWidget->insertTopLevelItem(0, contactsItem );
ui->idTreeWidget->insertTopLevelItem(0, allItem);
Settings->beginGroup("IdDialog");
allItem->setExpanded(Settings->value("ExpandAll", QVariant(true)).toBool());
contactsItem->setExpanded(Settings->value("ExpandContacts", QVariant(true)).toBool());
Settings->endGroup();
if (fillIdListItem(vit->second, item, ownPgpId, accept))
if(vit->second.mIsAContact)
contactsItem->addChild(item);
else
allItem->addChild(item);
}
/* count items */
int itemCount = contactsItem->childCount() + allItem->childCount();
ui->label_count->setText( "(" + QString::number( itemCount ) + ")" );
filterIds();
updateSelection();
}
@ -929,55 +964,27 @@ void IdDialog::insertIdDetails(uint32_t token)
else
ui->lineEdit_Type->setText(tr("Anonymous identity")) ;
// if (isOwnId)
// {
// ui->radioButton_IdYourself->setChecked(true);
// }
// else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
// {
// if (data.mPgpKnown)
// {
// if (rsPeers->isGPGAccepted(data.mPgpId))
// {
// ui->radioButton_IdFriend->setChecked(true);
// }
// else
// {
// ui->radioButton_IdFOF->setChecked(true);
// }
// }
// else
// {
// ui->radioButton_IdOther->setChecked(true);
// }
// }
// else
// {
// ui->radioButton_IdPseudo->setChecked(true);
// }
if (isOwnId)
{
mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false);
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
ui->editIdentity->setEnabled(true);
ui->removeIdentity->setEnabled(true);
ui->chatIdentity->setEnabled(false);
ui->messageButton->setEnabled(false);
ui->inviteButton->setEnabled(false);
}
else
{
// No Reputation yet!
mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false);
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
ui->editIdentity->setEnabled(false);
ui->removeIdentity->setEnabled(false);
ui->chatIdentity->setEnabled(true);
ui->messageButton->setEnabled(true);
ui->inviteButton->setEnabled(true);
}
/* now fill in the reputation information */
ui->line_RatingOverall->setText("Overall Rating TODO");
ui->line_RatingOwn->setText("Own Rating TODO");
#ifdef SUSPENDED
if (data.mPgpKnown)
{
ui->line_RatingImplicit->setText(tr("+50 Known PGP"));
@ -990,25 +997,28 @@ void IdDialog::insertIdDetails(uint32_t token)
{
ui->line_RatingImplicit->setText(tr("+5 Anon Id"));
}
{
QString rating = QString::number(data.mReputation.mOverallScore);
ui->line_RatingOverall->setText(rating);
}
{
QString rating = QString::number(data.mReputation.mIdScore);
ui->line_RatingImplicit->setText(rating);
}
{
QString rating = QString::number(data.mReputation.mOwnOpinion);
ui->line_RatingOwn->setText(rating);
}
#endif
RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ;
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverage - 1.0f));
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore - 1.0f) +" ("+
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ;
switch(info.mOwnOpinion)
{
QString rating = QString::number(data.mReputation.mPeerOpinion);
ui->line_RatingPeers->setText(rating);
case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ;
case RsReputations::OPINION_NEUTRAL : ui->ownOpinion_CB->setCurrentIndex(1); break ;
case RsReputations::OPINION_POSITIVE: ui->ownOpinion_CB->setCurrentIndex(2); break ;
default:
std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl;
}
}
@ -1020,47 +1030,38 @@ void IdDialog::modifyReputation()
#endif
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
RsReputations::Opinion op ;
int mod = 0;
if (ui->repMod_Accept->isChecked())
{
mod += 100;
}
else if (ui->repMod_Positive->isChecked())
{
mod += 10;
}
else if (ui->repMod_Negative->isChecked())
{
mod += -10;
}
else if (ui->repMod_Ban->isChecked())
{
mod += -100;
}
else if (ui->repMod_Custom->isChecked())
{
mod += ui->repMod_spinBox->value();
}
else
{
// invalid
return;
}
switch(ui->ownOpinion_CB->currentIndex())
{
case 0: op = RsReputations::OPINION_NEGATIVE ; break ;
case 1: op = RsReputations::OPINION_NEUTRAL ; break ;
case 2: op = RsReputations::OPINION_POSITIVE ; break ;
default:
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
}
rsReputations->setOwnOpinion(id,op) ;
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod;
std::cerr << std::endl;
#endif
#ifdef SUSPENDED
// Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not
// very efficient because of this.
uint32_t token;
if (!rsIdentity->submitOpinion(token, id, false, mod))
if (!rsIdentity->submitOpinion(token, id, false, op))
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() Error submitting Opinion";
std::cerr << std::endl;
#endif
}
#endif
#ifdef ID_DEBUG
std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token;
@ -1069,7 +1070,8 @@ void IdDialog::modifyReputation()
// trigger refresh when finished.
// basic / anstype are not needed.
mIdQueue->queueRequest(token, 0, 0, IDDIALOG_REFRESH);
requestIdDetails();
requestIdList();
return;
}
@ -1248,7 +1250,8 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
rsIdentity->getOwnIds(own_identities) ;
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (item) {
if(item != allItem && item != contactsItem) {
uint32_t item_flags = item->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ;
if(!(item_flags & RSID_FILTER_OWNED_BY_YOU))
@ -1282,13 +1285,59 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
}
contextMnu.addAction(QIcon(":/images/mail_new.png"), tr("Send message to this person"), this, SLOT(sendMsg()));
contextMnu.addSeparator();
RsIdentityDetails details;
std::string keyId = item->text(RSID_COL_KEYID).toStdString();
rsIdentity->getIdDetails(RsGxsId(keyId), details);
QAction *addContact = contextMnu.addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts()));
QAction *removeContact = contextMnu.addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts()));
if(details.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT)
{
addContact->setVisible(false);
removeContact->setVisible(true);
}
else
{
addContact->setVisible(true);
removeContact->setVisible(false);
}
contextMnu.addSeparator();
RsReputations::ReputationInfo info ;
std::string Id = item->text(RSID_COL_KEYID).toStdString();
rsReputations->getReputationInfo(RsGxsId(Id),info) ;
QAction *banaction = contextMnu.addAction(QIcon(":/images/denied16.png"), tr("Ban this person"), this, SLOT(banPerson()));
QAction *unbanaction = contextMnu.addAction(QIcon(), tr("Unban this person"), this, SLOT(unbanPerson()));
if(info.mAssessment == RsReputations::ASSESSMENT_BAD)
{
banaction->setVisible(false);
unbanaction->setVisible(true);
}
else
{
banaction->setVisible(true);
unbanaction->setVisible(false);
}
}
contextMnu.addSeparator();
contextMnu.addAction(ui->editIdentity);
contextMnu.addAction(ui->removeIdentity);
}
contextMnu.addSeparator();
contextMnu.addAction(ui->editIdentity);
contextMnu.addAction(ui->removeIdentity);
contextMnu.addSeparator();
@ -1313,8 +1362,9 @@ void IdDialog::chatIdentity()
RsGxsId from_gxs_id(action->data().toString().toStdString());
uint32_t error_code ;
DistantChatPeerId did ;
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, error_code))
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, did, error_code))
QMessageBox::information(NULL, tr("Distant chat cannot work"), QString("%1 %2: %3").arg(tr("Distant chat refused with this person.")).arg(tr("Error code")).arg(error_code)) ;
}
@ -1340,3 +1390,102 @@ void IdDialog::sendMsg()
/* window will destroy itself! */
}
QString IdDialog::inviteMessage()
{
return tr("Hi,<br>I want to be friends with you on RetroShare.<br>");
}
void IdDialog::sendInvite()
{
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (!item)
{
return;
}
/* create a message */
MessageComposer *composer = MessageComposer::newMsg();
composer->setTitleText(tr("You have a friend invite"));
RsPeerId ownId = rsPeers->getOwnId();
RetroShareLink link;
link.createCertificate(ownId);
std::string keyId = item->text(RSID_COL_KEYID).toStdString();
QString sMsgText = inviteMessage();
sMsgText += "<br><br>";
sMsgText += tr("Respond now:") + "<br>";
sMsgText += link.toHtml() + "<br>";
sMsgText += "<br>";
sMsgText += tr("Thanks, <br>") + QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str());
composer->setMsgText(sMsgText);
composer->addRecipient(MessageComposer::TO, RsGxsId(keyId));
composer->show();
}
void IdDialog::banPerson()
{
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (!item)
{
return;
}
std::string Id = item->text(RSID_COL_KEYID).toStdString();
rsReputations->setOwnOpinion(RsGxsId(Id),RsReputations::OPINION_NEGATIVE) ;
requestIdDetails();
requestIdList();
}
void IdDialog::unbanPerson()
{
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (!item)
{
return;
}
std::string Id = item->text(RSID_COL_KEYID).toStdString();
rsReputations->setOwnOpinion(RsGxsId(Id),RsReputations::OPINION_POSITIVE) ;
requestIdDetails();
requestIdList();
}
void IdDialog::addtoContacts()
{
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (!item)
{
return;
}
std::string Id = item->text(RSID_COL_KEYID).toStdString();
rsIdentity->setAsRegularContact(RsGxsId(Id),true);
requestIdList();
}
void IdDialog::removefromContacts()
{
QTreeWidgetItem *item = ui->idTreeWidget->currentItem();
if (!item)
{
return;
}
std::string Id = item->text(RSID_COL_KEYID).toStdString();
rsIdentity->setAsRegularContact(RsGxsId(Id),false);
requestIdList();
}

View file

@ -73,14 +73,22 @@ private slots:
void updateSelection();
void todo();
void modifyReputation();
/** Create the context popup menu and it's submenus */
void IdListCustomPopupMenu( QPoint point );
void CircleListCustomPopupMenu( QPoint point);
void circle_selected();
void CircleListCustomPopupMenu(QPoint point) ;
void circle_selected() ;
void addtoContacts();
void removefromContacts();
void banPerson();
void unbanPerson();
static QString inviteMessage();
void sendInvite();
private:
void processSettings(bool load);
@ -104,6 +112,9 @@ private:
TokenQueue *mCircleQueue;
UIStateHelper *mStateHelper;
QTreeWidgetItem *contactsItem;
QTreeWidgetItem *allItem;
RsGxsGroupId mId;
/* UI - Designer */

View file

@ -7,7 +7,11 @@
<x>0</x>
<y>0</y>
<width>826</width>
<<<<<<< HEAD
<height>579</height>
=======
<height>630</height>
>>>>>>> upstream/master
</rect>
</property>
<property name="sizePolicy">
@ -19,8 +23,25 @@
<property name="windowTitle">
<string/>
</property>
<<<<<<< HEAD
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
=======
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
>>>>>>> upstream/master
<widget class="QFrame" name="titleBarFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@ -35,7 +56,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -70,6 +100,13 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_count">
<property name="text">
<string>()</string>
</property>
</widget>
</item>
<item>
<spacer name="titleBarSpacer">
<property name="orientation">
@ -119,7 +156,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -177,6 +223,18 @@
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="indentation">
<number>24</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
@ -185,7 +243,7 @@
</attribute>
<column>
<property name="text">
<string>Identity name</string>
<string>Persons</string>
</property>
</column>
<column>
@ -203,6 +261,14 @@
<string>Owned by</string>
</property>
</column>
<column>
<property name="text">
<string>Reputation</string>
</property>
<property name="textAlignment">
<set>AlignLeading|AlignVCenter</set>
</property>
</column>
</widget>
</item>
</layout>
@ -232,6 +298,7 @@
</property>
</widget>
</item>
<<<<<<< HEAD
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -723,6 +790,332 @@
<zorder>detailsGroupBox</zorder>
<zorder>headerFrame</zorder>
</widget>
=======
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="detailsGroupBox">
<property name="title">
<string>Identity info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Identity ID :</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="PgpId_LB">
<property name="text">
<string>Owner node ID :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="PgpName_LB">
<property name="text">
<string>Owner node name :</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string extracomment="Click here to change your avatar">Your Avatar</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="inviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reputation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="2" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Neighbor nodes:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="ownOpinion_CB">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself,&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; S = own_opinion * a + friends_opinion * (1-a)&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The factor 'a' depends on the type of ID. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- anonymous IDs: &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;- PGP-signed IDs by unknown PGP keys: a=&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; -0.5: Posts are not stored, nor forwarded &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; 0.2: Posts are hidden, but still transmitted&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; 0.0: &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset>
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
>>>>>>> upstream/master
</widget>
</widget>
</item>
@ -785,6 +1178,13 @@
</customwidgets>
<tabstops>
<tabstop>idTreeWidget</tabstop>
<<<<<<< HEAD
=======
<tabstop>lineEdit_Nickname</tabstop>
<tabstop>lineEdit_KeyId</tabstop>
<tabstop>lineEdit_GpgId</tabstop>
<tabstop>lineEdit_GpgName</tabstop>
>>>>>>> upstream/master
</tabstops>
<resources>
<include location="../images.qrc"/>

View file

@ -113,10 +113,16 @@ void IdEditDialog::changeAvatar()
}
}
void IdEditDialog::setupNewId(bool pseudo)
void IdEditDialog::setupNewId(bool pseudo,bool enable_anon)
{
setWindowTitle(tr("New identity"));
if(pseudo && !enable_anon)
{
std::cerr << "IdEditDialog::setupNewId: Error. Cannot init with pseudo-anonymous id when anon ids are disabled." << std::endl;
pseudo = false ;
}
mIsNew = true;
mGroupId.clear();
@ -139,7 +145,11 @@ void IdEditDialog::setupNewId(bool pseudo)
ui->frame_Tags->setHidden(true);
ui->radioButton_GpgId->setEnabled(true);
ui->radioButton_Pseudo->setEnabled(true);
if(enable_anon)
ui->radioButton_Pseudo->setEnabled(true);
else
ui->radioButton_Pseudo->setEnabled(false);
setAvatar(QPixmap());

View file

@ -45,7 +45,7 @@ public:
IdEditDialog(QWidget *parent = 0);
~IdEditDialog();
void setupNewId(bool pseudo);
void setupNewId(bool pseudo, bool enable_anon = true);
void setupExistingId(const RsGxsGroupId &keyId);
void enforceNoAnonIds() ;

View file

@ -401,7 +401,7 @@ void MainWindow::initStackedPage()
else
icon = QIcon(":images/extension_48.png") ;
std::cerr << " Addign widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
std::cerr << " Adding widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
pluginPage->setIconPixmap(icon);
pluginPage->setPageName(QString::fromUtf8(rsPlugins->plugin(i)->getPluginName().c_str()));
addPage(pluginPage, grp, &notify);
@ -677,12 +677,20 @@ void MainWindow::updateTrayCombine()
updateFriends();
}
void MainWindow::toggleStatusToolTip(bool toggle){
if(!toggle)return;
QString tray = "RetroShare\n";
tray += "\n" + nameAndLocation;
trayIcon->setToolTip(tray);
}
void MainWindow::updateStatus()
{
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
if(RsAutoUpdatePage::eventsLocked())
return;
if(Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool())
return;
float downKb = 0;
float upKb = 0;
rsConfig->GetCurrentDataRates(downKb, upKb);

View file

@ -184,6 +184,7 @@ public slots:
void setNewPage(int page);
void setCompactStatusMode(bool compact);
void toggleStatusToolTip(bool toggle);
protected:
/** Default Constructor */
MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);

View file

@ -1237,8 +1237,16 @@ void MessagesDialog::insertMessages()
else if(it->msgflags & RS_MSG_DISTANT)
{
item->setIcon(COLUMN_SIGNATURE, QIcon(":/images/blue_lock_open.png")) ;
item->setToolTip(COLUMN_SIGNATURE, tr("This message comes from a distant person.")) ;
item->setIcon(COLUMN_SUBJECT, QIcon(":/images/message-mail-read.png")) ;
if (msgbox == RS_MSG_INBOX )
{
item->setToolTip(COLUMN_SIGNATURE, tr("This message comes from a distant person.")) ;
}
else if (msgbox == RS_MSG_OUTBOX)
{
item->setToolTip(COLUMN_SIGNATURE, tr("This message goes to a distant person.")) ;
}
if(it->msgflags & RS_MSG_SIGNED)
{

View file

@ -393,6 +393,8 @@ void NetworkDialog::insertConnect()
/* get a link to the table */
QTreeWidget *connectWidget = ui.connectTreeWidget;
/* disable sorting while editing the table */
connectWidget->setSortingEnabled(false);
//remove items
int index = 0;
@ -560,7 +562,10 @@ void NetworkDialog::insertConnect()
}
connectWidget->addTopLevelItem(self_item);
connectWidget->update(); /* update display */
/* enable sorting */
connectWidget->setSortingEnabled(true);
/* update display */
connectWidget->update();
if (ui.filterLineEdit->text().isEmpty() == false) {
filterItems(ui.filterLineEdit->text());

View file

@ -183,11 +183,26 @@ void QuickStartWizard::on_pushButtonSharesExit_clicked()
close();
}
void QuickStartWizard::on_pushButtonSystemBack_clicked()
void QuickStartWizard::on_pushButtonStyleBack_clicked()
{
ui.pagesWizard->setCurrentIndex(2);
}
void QuickStartWizard::on_pushButtonStyleNext_clicked()
{
ui.pagesWizard->setCurrentIndex(4);
}
void QuickStartWizard::on_pushButtonStyleExit_clicked()
{
close();
}
void QuickStartWizard::on_pushButtonSystemBack_clicked()
{
ui.pagesWizard->setCurrentIndex(3);
}
void QuickStartWizard::on_pushButtonSystemFinish_clicked()
{
Settings->setStartMinimized(ui.checkBoxStartMinimized->isChecked());
@ -390,6 +405,9 @@ QuickStartWizard::loadGeneral()
ui.checkBoxStartMinimized->setChecked(Settings->getStartMinimized());
ui.checkBoxQuit->setChecked(Settings->value("doQuit", false).toBool());
ui.rbtPageOnToolBar->setChecked(Settings->getPageButtonLoc());
ui.rbtPageOnListItem->setChecked(!Settings->getPageButtonLoc());
//ui.checkBoxQuickWizard->setChecked(settings.value(QString::fromUtf8("FirstRun"), false).toBool());
}
@ -419,6 +437,12 @@ void QuickStartWizard::loadNetwork()
case RS_NETMODE_UDP:
netIndex = 1;
break;
case RS_NETMODE_HIDDEN:
ui.netModeLabel->hide();
ui.netModeComboBox->hide();
ui.discoveryLabel->hide();
ui.discoveryComboBox->hide();
break;
default:
case RS_NETMODE_UPNP:
netIndex = 0;
@ -472,6 +496,8 @@ void QuickStartWizard::saveChanges()
//bool saveAddr = false;
Settings->setPageButtonLoc(ui.rbtPageOnToolBar->isChecked());
RsPeerDetails detail;
RsPeerId ownId = rsPeers->getOwnId();

View file

@ -60,6 +60,9 @@ private Q_SLOTS:
void on_pushButtonSharesExit_clicked();
void on_pushButtonSharesNext_clicked();
void on_pushButtonSharesBack_clicked();
void on_pushButtonStyleExit_clicked();
void on_pushButtonStyleNext_clicked();
void on_pushButtonStyleBack_clicked();
void on_pushButtonWelcomeExit_clicked();
void on_pushButtonWelcomeNext_clicked();
void on_pushButtonConnectionExit_clicked();

View file

@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>445</width>
<width>457</width>
<height>370</height>
</rect>
</property>
@ -36,7 +36,16 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -48,11 +57,20 @@
<item row="1" column="0">
<widget class="QStackedWidget" name="pagesWizard">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="pageWelcome">
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -73,7 +91,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<property name="spacing">
@ -188,7 +215,16 @@ p, li { white-space: pre-wrap; }
</widget>
<widget class="QWidget" name="pageConnection">
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -291,7 +327,7 @@ p, li { white-space: pre-wrap; }
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<widget class="QLabel" name="netModeLabel">
<property name="text">
<string>Connection :</string>
</property>
@ -317,7 +353,7 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="discoveryLabel">
<property name="text">
<string>Discovery :</string>
</property>
@ -443,7 +479,16 @@ p, li { white-space: pre-wrap; }
</widget>
<widget class="QWidget" name="pageShares">
<layout class="QGridLayout" name="gridLayout_7">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -674,9 +719,137 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<widget class="QWidget" name="pageStyle">
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QGroupBox" name="grpToolBar">
<property name="minimumSize">
<size>
<width>0</width>
<height>228</height>
</size>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="title">
<string>RetroShare Page Display Style</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="labelPageToolBar">
<property name="text">
<string>Where do you want to have the buttons for the page?</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="rbtPageOnToolBar">
<property name="text">
<string>ToolBar View</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rbtPageOnListItem">
<property name="text">
<string>List View</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>204</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="topMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonStyleBack">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&lt; Back</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonStyleNext">
<property name="text">
<string>Next &gt;</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonStyleExit">
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageSystem">
<layout class="QGridLayout" name="gridLayout_16">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -697,8 +870,17 @@ p, li { white-space: pre-wrap; }
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout_15">
<property name="margin">
<number>4</number>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<property name="spacing">
<number>4</number>

View file

@ -590,7 +590,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const
QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::SizeHintRole)
/*if (role == Qt::SizeHintRole)
{
int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ;
int defh = QFontMetricsF(QWidget().font()).height();
@ -600,7 +600,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int
defw = 200/16.0*defh;
}
return QSize(defw, defh);
}
}*/
if (role != Qt::DisplayRole)
return QVariant();
@ -636,7 +636,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int
}
QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::SizeHintRole)
/*if (role == Qt::SizeHintRole)
{
int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ;
int defh = QFontMetricsF(QWidget().font()).height();
@ -646,7 +646,7 @@ QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int
defw = defh*200/16.0;
}
return QSize(defw, defh);
}
}*/
if (role != Qt::DisplayRole)
return QVariant();
@ -1341,7 +1341,7 @@ void FlatStyle_RDM::updateRefs()
if(details->type == DIR_TYPE_FILE) // only push files, not directories nor persons.
_ref_entries.push_back(std::pair<void*,QString>(ref,computeDirectoryPath(*details)));
#ifdef RDM_DEBUG
std::cerr << "FlatStyle_RDM::postMods(): addign ref " << ref << std::endl;
std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl;
#endif
for(std::list<DirStub>::const_iterator it = details->children.begin(); it != details->children.end(); ++it)
_ref_stack.push_back(it->ref) ;

View file

@ -195,7 +195,9 @@ void RetroShareLink::fromUrl(const QUrl& url)
if (url.scheme() != RSLINK_SCHEME) {
/* No RetroShare-Link */
#ifdef DEBUG_RSLINK
std::cerr << "Not a RS link: scheme=" << url.scheme().toStdString() << std::endl;
#endif
return;
}
@ -1333,7 +1335,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
if(!gxs_id.isNull() && rsIdentity->getIdDetails(gxs_id,gxs_details))
{
if(gxs_details.mIsOwnId)
if(gxs_details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID)
{
QMessageBox::warning(NULL,QString("Cannot send message to yourself"),QString("This identity is owned by you. You wouldn't want to send yourself a message right?"));
break ;

View file

@ -244,6 +244,9 @@ void SearchDialog::processSettings(bool bLoad)
// state of splitter
ui.splitter->restoreState(Settings->value("Splitter").toByteArray());
ui._max_results_SB->setValue(Settings->value("MaxResults").toInt());
} else {
// save settings
@ -252,6 +255,8 @@ void SearchDialog::processSettings(bool bLoad)
// state of splitter
Settings->setValue("Splitter", ui.splitter->saveState());
Settings->setValue("MaxResults", ui._max_results_SB->value());
}
Settings->endGroup();
@ -295,16 +300,16 @@ void SearchDialog::initialiseFileTypeMappings()
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_AUDIO,
"aac aif flac iff m3u m4a mid midi mp3 mpa ogg ra ram wav wma");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_ARCHIVE,
"7z bz2 gz pkg rar sea sit sitx tar zip");
"7z bz2 gz pkg rar sea sit sitx tar zip tgz");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_CDIMAGE,
"iso nrg mdf");
"iso nrg mdf bin");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_DOCUMENT,
"doc odt ott rtf pdf ps txt log msg wpd wps" );
"doc odt ott rtf pdf ps txt log msg wpd wps ods xls epub" );
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PICTURE,
"3dm 3dmf ai bmp drw dxf eps gif ico indd jpe jpeg jpg mng pcx pcc pct pgm "
"pix png psd psp qxd qxprgb sgi svg tga tif tiff xbm xcf");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PROGRAM,
"app bat cgi com bin exe js pif py pl sh vb ws ");
"app bat cgi com bin exe js pif py pl sh vb ws bash");
SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_VIDEO,
"3gp asf asx avi mov mp4 mkv flv mpeg mpg qt rm swf vob wmv");
SearchDialog::initialised = true;

View file

@ -79,7 +79,7 @@
/** Constructor */
WikiDialog::WikiDialog(QWidget *parent)
: MainPage(parent)
: RsGxsUpdateBroadcastPage(rsWiki, parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
@ -103,11 +103,6 @@ WikiDialog::WikiDialog(QWidget *parent)
connect(ui.groupTreeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT(groupListCustomPopupMenu(QPoint)));
connect(ui.groupTreeWidget, SIGNAL(treeItemActivated(QString)), this, SLOT(wikiGroupChanged(QString)));
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
timer->start(1000);
/* setup TokenQueue */
mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this);
@ -118,8 +113,6 @@ WikiDialog::WikiDialog(QWidget *parent)
mPopularGroups = ui.groupTreeWidget->addCategoryItem(tr("Popular Groups"), QIcon(IMAGE_FOLDERGREEN), false);
mOtherGroups = ui.groupTreeWidget->addCategoryItem(tr("Other Groups"), QIcon(IMAGE_FOLDERYELLOW), false);
//Auto refresh seems not to work, temporary solution at start
insertWikiGroups();
}
WikiDialog::~WikiDialog()
@ -127,20 +120,6 @@ WikiDialog::~WikiDialog()
delete(mWikiQueue);
}
void WikiDialog::checkUpdate()
{
/* update */
if (!rsWiki)
return;
if (rsWiki->updated())
{
insertWikiGroups();
}
return;
}
void WikiDialog::OpenOrShowAddPageDialog()
{
RsGxsGroupId groupId = getSelectedGroup();
@ -362,11 +341,6 @@ const RsGxsGroupId& WikiDialog::getSelectedGroup()
/************************** Request / Response *************************/
/*** Loading Main Index ***/
void WikiDialog::insertWikiGroups()
{
requestGroupMeta();
}
void WikiDialog::requestGroupMeta()
{
std::cerr << "WikiDialog::requestGroupMeta()";
@ -528,7 +502,7 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
#define GXSGROUP_NEWGROUPID 1
case GXSGROUP_NEWGROUPID:
insertWikiGroups();
requestGroupMeta();
break;
default:
std::cerr << "WikiDialog::loadRequest() ERROR: INVALID TYPE";
@ -716,3 +690,20 @@ void WikiDialog::todo()
"<li>Auto update Group trees"
"</ul>");
}
void WikiDialog::updateDisplay(bool complete)
{
if (complete || !getGrpIds().empty() || !getGrpIdsMeta().empty()) {
/* Update group list */
requestGroupMeta();
} else {
/* Update all groups of changed messages */
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgIds;
getAllMsgIds(msgIds);
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator msgIt;
for (msgIt = msgIds.begin(); msgIt != msgIds.end(); ++msgIt) {
wikiGroupChanged(QString::fromStdString(msgIt->first.toStdString()));
}
}
}

View file

@ -26,7 +26,7 @@
#include <QMessageBox>
#include "retroshare-gui/mainpage.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "ui_WikiDialog.h"
#include <retroshare/rswiki.h>
@ -40,7 +40,7 @@
class WikiAddDialog;
class WikiEditDialog;
class WikiDialog : public MainPage, public TokenResponse
class WikiDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
{
Q_OBJECT
@ -52,12 +52,13 @@ public:
virtual QString pageName() const { return tr("Wiki Pages") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
public:
virtual void updateDisplay(bool complete);
private slots:
void checkUpdate();
void OpenOrShowAddPageDialog();
void OpenOrShowAddGroupDialog();
void OpenOrShowEditDialog();
@ -69,8 +70,6 @@ private slots:
void showGroupDetails();
void editGroupDetails();
void insertWikiGroups();
// GroupTreeWidget stuff.
void groupListCustomPopupMenu(QPoint point);
void subscribeToGroup();

View file

@ -733,7 +733,7 @@ void WikiEditDialog::loadBaseHistory(const uint32_t &token)
modItem->setText(WET_COL_DATE, text);
modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort);
}
modItem->setId(page.mMeta.mAuthorId, WET_COL_AUTHORID);
modItem->setId(page.mMeta.mAuthorId, WET_COL_AUTHORID, false);
modItem->setText(WET_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId.toStdString()));
ui.treeWidget_History->addTopLevelItem(modItem);
@ -847,7 +847,7 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token)
modItem->setText(WET_COL_DATE, text);
modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort);
}
modItem->setId(snapshot.mMeta.mAuthorId, WET_COL_AUTHORID);
modItem->setId(snapshot.mMeta.mAuthorId, WET_COL_AUTHORID, false);
modItem->setText(WET_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId.toStdString()));
/* find the parent */

View file

@ -96,7 +96,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if (cd == NULL) {
if(id.isGxsId())
if(id.isDistantChatId())
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat
if (chatflags & RS_CHAT_OPEN) {
@ -104,12 +104,16 @@ void ChatDialog::init(ChatId id, const QString &title)
ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId());
cld->init();
cd = cld;
} else if(id.isGxsId()) {
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog();
QString peer_name = pdcd->getPeerName(id) ;
pdcd->init(id.toGxsId(), tr("Talking to")+" "+peer_name) ;
}
else if(id.isDistantChatId())
{
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
pdcd->init(id.toDistantChatId());
cd = pdcd;
} else {
}
else
{
RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(id.toPeerId(), sslDetails)) {
PopupChatDialog* pcd = new PopupChatDialog();
@ -168,7 +172,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if(msg.chat_id.isBroadcast())
return; // broadcast is not handled by a chat dialog
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId()))
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isDistantChatId()))
// play sound when recv a message
SoundManager::play(SOUND_NEW_CHAT_MESSAGE);
@ -334,8 +338,8 @@ void ChatDialog::setPeerStatus(uint32_t status)
RsPeerId vpid;
if(mChatId.isPeerId())
vpid = mChatId.toPeerId();
if(mChatId.isGxsId())
vpid = RsPeerId(mChatId.toGxsId());
if(mChatId.isDistantChatId())
vpid = RsPeerId(mChatId.toDistantChatId());
cw->updateStatus(QString::fromStdString(vpid.toStdString()), status);
}
}

View file

@ -34,6 +34,7 @@
#include "gui/settings/RsharePeerSettings.h"
#include "gui/MainWindow.h"
#include "gui/FriendsDialog.h"
#include "gui/msgs/MessageComposer.h"
#include <gui/common/html.h>
#include "gui/common/RSTreeWidgetItem.h"
#include "gui/common/FriendSelectionDialog.h"
@ -52,6 +53,10 @@
#define COLUMN_ID 3
#define COLUMN_COUNT 4
#define ROLE_SORT Qt::UserRole + 1
const static uint32_t timeToInactivity = 60 * 10; // in seconds
/** Default constructor */
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
: ChatDialog(parent, flags), lobbyId(lid)
@ -66,18 +71,35 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(ui.participantsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(participantsTreeWidgetDoubleClicked(QTreeWidgetItem*,int)));
int S = QFontMetricsF(font()).height() ;
ui.participantsList->setIconSize(QSize(S,S));
ui.participantsList->setIconSize(QSize(1.3*S,1.3*S));
ui.participantsList->setColumnCount(COLUMN_COUNT);
ui.participantsList->setColumnWidth(COLUMN_ICON, 1.25*S);
ui.participantsList->setColumnWidth(COLUMN_ICON, 1.4*S);
ui.participantsList->setColumnHidden(COLUMN_ACTIVITY,true);
ui.participantsList->setColumnHidden(COLUMN_ID,true);
muteAct = new QAction(QIcon(), tr("Mute participant"), this);
distantChatAct = new QAction(QIcon(), tr("Start private chat"), this);
muteAct = new QAction(QIcon(), tr("Mute participant"), this);
distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this);
sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this);
QActionGroup *sortgrp = new QActionGroup(this);
actionSortByName = new QAction(QIcon(), tr("Sort by Name"), this);
actionSortByName->setCheckable(true);
actionSortByName->setChecked(true);
actionSortByName->setActionGroup(sortgrp);
actionSortByActivity = new QAction(QIcon(), tr("Sort by Activity"), this);
actionSortByActivity->setCheckable(true);
actionSortByActivity->setChecked(false);
actionSortByActivity->setActionGroup(sortgrp);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage()));
connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants()));
connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants()));
// Add a button to invite friends.
//
@ -89,7 +111,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
inviteFriendsButton->setToolTip(tr("Invite friends to this lobby"));
mParticipantCompareRole = new RSTreeWidgetItemCompareRole;
mParticipantCompareRole->setRole(0, Qt::UserRole);
mParticipantCompareRole->setRole(COLUMN_ACTIVITY, ROLE_SORT);
{
QIcon icon ;
@ -170,12 +192,18 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
QMenu contextMnu(this);
contextMnu.addAction(muteAct);
contextMnu.addAction(distantChatAct);
contextMnu.addAction(sendMessageAct);
contextMnu.addSeparator();
contextMnu.addAction(muteAct);
contextMnu.addSeparator();
contextMnu.addAction(actionSortByActivity);
contextMnu.addAction(actionSortByName);
muteAct->setCheckable(true);
muteAct->setEnabled(false);
muteAct->setChecked(false);
muteAct->setChecked(false);
if (selectedItems.size())
{
@ -292,11 +320,20 @@ void ChatLobbyDialog::processSettings(bool load)
// state of splitter
ui.splitter->restoreState(Settings->value("splitter").toByteArray());
// load sorting
actionSortByActivity->setChecked(Settings->value("sortbyActivity", QVariant(false)).toBool());
actionSortByName->setChecked(Settings->value("sortbyName", QVariant(true)).toBool());
} else {
// save settings
// state of splitter
Settings->setValue("splitter", ui.splitter->saveState());
//save sorting
Settings->setValue("sortbyActivity", actionSortByActivity->isChecked());
Settings->setValue("sortbyName", actionSortByName->isChecked());
}
Settings->endGroup();
@ -362,7 +399,7 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
else
name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ;
ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
ui.chatWidget->addChatMsg(msg.incoming, name, gxs_id, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
emit messageReceived(msg.incoming, id(), sendTime, name, message) ;
// This is a trick to translate HTML into text.
@ -425,7 +462,8 @@ void ChatLobbyDialog::updateParticipantsList()
widgetitem = new GxsIdRSTreeWidgetItem(mParticipantCompareRole,GxsIdDetails::ICON_TYPE_AVATAR);
widgetitem->setId(it2->first,COLUMN_NAME, true) ;
//widgetitem->setText(COLUMN_NAME, participant);
widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL)));
// set activity time to the oast so that the peer is marked as inactive
widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL) - timeToInactivity));
widgetitem->setText(COLUMN_ID,QString::fromStdString(it2->first.toStdString()));
ui.participantsList->addTopLevelItem(widgetitem);
@ -441,18 +479,21 @@ void ChatLobbyDialog::updateParticipantsList()
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
time_t now = time(NULL);
widgetitem->setSizeHint(COLUMN_ICON, QSize(20,20));
if(isParticipantMuted(it2->first))
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_64.png"));
else if (tLastAct<now-60*30)
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_grey_64.png"));
else
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_green_64.png"));
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_128.png"));
else if (tLastAct + timeToInactivity < now)
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_grey_128.png"));
else
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_green_128.png"));
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_64.png"));
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_128.png"));
QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct);
widgetitem->setToolTip(COLUMN_ICON,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>")
@ -463,7 +504,7 @@ void ChatLobbyDialog::updateParticipantsList()
}
}
ui.participantsList->setSortingEnabled(true);
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
sortParcipants();
}
/**
@ -553,8 +594,9 @@ void ChatLobbyDialog::distantChatParticipant()
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
uint32_t error_code ;
DistantChatPeerId tunnel_id;
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,error_code))
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code))
{
QString error_str ;
switch(error_code)
@ -571,6 +613,36 @@ void ChatLobbyDialog::distantChatParticipant()
}
}
void ChatLobbyDialog::sendMessage()
{
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
if (selectedItems.isEmpty())
return;
QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
RsGxsId gxs_id ;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxs_id) ;
MessageComposer *nMsgDialog = MessageComposer::newMsg();
if (nMsgDialog == NULL) {
return;
}
nMsgDialog->addRecipient(MessageComposer::TO, RsGxsId(gxs_id));
nMsgDialog->show();
nMsgDialog->activateWindow();
/* window will destroy itself! */
}
}
void ChatLobbyDialog::muteParticipant(const RsGxsId& nickname)
{
@ -722,3 +794,14 @@ void ChatLobbyDialog::showDialog(uint chatflags)
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->setCurrentChatPage(this) ;
}
}
void ChatLobbyDialog::sortParcipants()
{
if (actionSortByActivity->isChecked()) {
ui.participantsList->sortItems(COLUMN_ACTIVITY, Qt::DescendingOrder);
} else if (actionSortByName->isChecked()) {
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
}
}

View file

@ -47,6 +47,7 @@ public:
void setIdentity(const RsGxsId& gxs_id);
bool isParticipantMuted(const RsGxsId &participant);
ChatLobbyId id() const { return lobbyId ;}
void sortParcipants();
private slots:
void participantsTreeWidgetCustomPopupMenu( QPoint point );
@ -77,6 +78,7 @@ protected slots:
void changePartipationState();
void distantChatParticipant();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
void sendMessage();
private:
void updateParticipantsList();
@ -101,9 +103,12 @@ private:
/** Ignored Users in Chatlobby by nickname until we had implemented Peer Ids in ver 0.6 */
std::set<RsGxsId> mutedParticipants;
QAction *muteAct;
QAction *muteAct;
QAction *distantChatAct;
QAction *actionSortByName;
QAction *actionSortByActivity;
QWidgetAction *checkableAction;
QAction *sendMessageAct;
GxsIdChooser *ownIdChooser ;
};

View file

@ -267,10 +267,12 @@ static QString getStyle(const QDir &styleDir, const QString &styleVariant, enumG
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag)
{
bool me = false;
QDomDocument doc ;
QString styleOptimized ;
QString errorMsg ; int errorLine ; int errorColumn ;
QString messageBody = message ;
me = me || message.trimmed().startsWith("/me ");
if (doc.setContent(messageBody, &errorMsg, &errorLine, &errorColumn)) {
QDomElement body = doc.documentElement();
if (!body.isNull()){
@ -279,6 +281,12 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
for (int curs = 0; curs < count; ++curs){
QDomNode it = body.childNodes().item(curs);
if (it.nodeName().toLower() != "style") {
//find out if the message starts with /me
if(it.isText()){
me = me || it.toText().data().trimmed().startsWith("/me ");
}else if(it.isElement()){
me = me || it.toElement().text().trimmed().startsWith("/me ");
}
QString str;
QTextStream stream(&str);
it.toElement().save(stream, -1);
@ -351,11 +359,29 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
Q_UNUSED(flag);
#endif
QString formatMsg = style.replace("%name%", RsHtml::plainText(name))
.replace("%date%", DateTime::formatDate(timestamp.date()))
.replace("%time%", DateTime::formatTime(timestamp.time()))
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("<a name=\"date\">")).append(QString("</a>"));
QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("<a name=\"time\">")).append(QString("</a>"));
int bi = name.lastIndexOf(QRegExp(" \\(.*\\)")); //trim location from the end
QString strShortName = RsHtml::plainText(name.left(bi)).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
//handle /me
//%nome% and %me% for including formatting conditionally
//meName class for modifying the style of the name in the palce of /me
if(me){
messageBody = messageBody.replace(messageBody.indexOf("/me "), 3, strShortName.prepend(QString("<span class=\"meName\">")).append(QString("</span>"))); //replace only the first /me
style = style.remove(QRegExp("%nome%.*%/nome%")).remove("%me%").remove("%/me%");
} else {
style = style.remove(QRegExp("%me%.*%/me%")).remove("%nome%").remove("%/nome%");
}
QString formatMsg = style.replace("%name%", strName)
.replace("%shortname%", strShortName)
.replace("%date%", strDate)
.replace("%time%", strTime)
#ifdef COLORED_NICKNAMES
.replace("%color%", color.name())
.replace("%color%", color.name())
#endif
.replace("%message%", messageBody ) ;
if ( !styleOptimized.isEmpty() ) {

View file

@ -109,7 +109,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
if(!msg.chat_id.isBroadcast()
&&( ChatDialog::getExistingChat(msg.chat_id)
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|| msg.chat_id.isGxsId()))
|| msg.chat_id.isDistantChatId()))
{
ChatDialog::chatMessageReceived(msg);
}

View file

@ -51,6 +51,7 @@
#include "util/HandleRichText.h"
#include "gui/chat/ChatUserNotify.h"//For BradCast
#include "util/DateTime.h"
#include "util/imageutil.h"
#include <retroshare/rsstatus.h>
#include <retroshare/rsidentity.h>
@ -125,6 +126,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
connect(ui->actionChooseFont, SIGNAL(triggered()), this, SLOT(chooseFont()));
connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor()));
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
@ -214,7 +217,7 @@ void ChatWidget::setDefaultExtraFileFlags(TransferRequestFlags fl)
void ChatWidget::addChatHorizontalWidget(QWidget *w)
{
ui->verticalLayout_2->addWidget(w) ;
ui->vl_Plugins->addWidget(w) ;
update() ;
}
@ -223,9 +226,15 @@ void ChatWidget::addChatBarWidget(QWidget *w)
ui->pluginButtonFrame->layout()->addWidget(w) ;
}
void ChatWidget::addVOIPBarWidget(QWidget *w)
void ChatWidget::addTitleBarWidget(QWidget *w)
{
ui->titleBarFrame->layout()->addWidget(w) ;
ui->pluginTitleFrame->layout()->addWidget(w) ;
}
void ChatWidget::hideChatText(bool hidden)
{
ui->frame_ChatText->setHidden(hidden); ;
ui->searchframe->setVisible(ui->actionSearch_History->isChecked() && !hidden); ;
}
RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser()
@ -249,7 +258,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
RsPeerId ownId = rsPeers->getOwnId();
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
if(chatId.isPeerId() || chatId.isGxsId())
if(chatId.isPeerId() || chatId.isDistantChatId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
if(chatId.isBroadcast() || chatId.isLobbyId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
@ -328,7 +337,8 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
continue;
QString name;
if (chatId.isLobbyId() || chatId.isGxsId()) {
if (chatId.isLobbyId() || chatId.isDistantChatId())
{
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());
@ -360,7 +370,7 @@ ChatWidget::ChatType ChatWidget::chatType()
// but maybe it is good to have separate types in libretroshare and gui
if(chatId.isPeerId())
return CHATTYPE_PRIVATE;
if(chatId.isGxsId())
if(chatId.isDistantChatId())
return CHATTYPE_DISTANT;
if(chatId.isLobbyId())
return CHATTYPE_LOBBY;
@ -488,10 +498,10 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent) {
if (notify && keyEvent->key() == Qt::Key_Delete) {
if (keyEvent->key() == Qt::Key_Delete) {
// Delete key pressed
if (ui->textBrowser->textCursor().selectedText().length() > 0) {
if (chatType() == CHATTYPE_LOBBY) {
if (notify && chatType() == CHATTYPE_LOBBY) {
QRegExp rx("<a name=\"(.*)\"",Qt::CaseSensitive, QRegExp::RegExp2);
rx.setMinimal(true);
QString sel=ui->textBrowser->textCursor().selection().toHtml();
@ -839,6 +849,13 @@ void ChatWidget::setWelcomeMessage(QString &text)
}
void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType)
{
addChatMsg(incoming, name, RsGxsId(), sendTime, recvTime, message, chatType);
}
void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gxsId
, const QDateTime &sendTime, const QDateTime &recvTime
, const QString &message, MsgType chatType)
{
#ifdef CHAT_DEBUG
std::cout << "ChatWidget::addChatMsg message : " << message.toStdString() << std::endl;
@ -870,6 +887,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime
if (!Settings->valueFromGroup("Chat", "EnableCustomFontSize", true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_SIZE;
}
int desiredMinimumFontSize = Settings->valueFromGroup("Chat", "MinimumFontSize", 10).toInt();
if (!Settings->valueFromGroup("Chat", "EnableBold", true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT;
}
@ -893,13 +911,20 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime
formatFlag |= CHAT_FORMATMSG_SYSTEM;
}
QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast);
QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast, desiredMinimumFontSize);
QDateTime dtTimestamp=incoming ? sendTime : recvTime;
QString formatMsg = chatStyle.formatMessage(type, name, dtTimestamp, formattedMessage, formatFlag);
QString timeStamp = dtTimestamp.toString(Qt::ISODate);
formatMsg.prepend(QString("<a name=\"%1\"/>").arg(timeStamp));
//To call this anchor do: ui->textBrowser->scrollToAnchor(QString("%1_%2").arg(timeStamp).arg(name));
//replace Date and Time anchors
formatMsg.replace(QString("<a name=\"date\">"),QString("<a name=\"%1\">").arg(timeStamp));
formatMsg.replace(QString("<a name=\"time\">"),QString("<a name=\"%1\">").arg(timeStamp));
//replace Name anchors with GXS Id
QString strGxsId = "";
if (!gxsId.isNull())
strGxsId = QString::fromStdString(gxsId.toStdString());
formatMsg.replace(QString("<a name=\"name\">"),QString("<a name=\"%1\">").arg(strGxsId));
QTextCursor textCursor = QTextCursor(ui->textBrowser->textCursor());
textCursor.movePosition(QTextCursor::End);
textCursor.setBlockFormat(QTextBlockFormat ());
@ -953,6 +978,14 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addSeparator();
contextMnu->addAction(ui->actionClearChatHistory);
contextMnu->addAction(ui->actionQuote);
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
if(ImageUtil::checkImage(cursor))
{
ui->actionSave_image->setData(point);
contextMnu->addAction(ui->actionSave_image);
}
contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point));
delete(contextMnu);
@ -1501,77 +1534,83 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
// make virtual peer id from gxs id in case of distant chat
RsPeerId vpid;
if(chatId.isGxsId())
vpid = RsPeerId(chatId.toGxsId());
if(chatId.isDistantChatId())
vpid = RsPeerId(chatId.toDistantChatId());
else
vpid = chatId.toPeerId();
/* set font size for status */
if (peer_id.toStdString() == vpid.toStdString()) {
// the peers status has changed
if (peer_id.toStdString() == vpid.toStdString())
{
// the peers status has changed
QString peerName ;
if(chatId.isGxsId())
{
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(chatId.toGxsId(),details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
QString peerName ;
if(chatId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
RsIdentityDetails details ;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
if(rsMsgs->getDistantChatStatus(chatId.toDistantChatId(),dcpinfo))
if(rsIdentity->getIdDetails(dcpinfo.to_id,details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(dcpinfo.to_id.toStdString()) ;
else
peerName = QString::fromStdString(chatId.toDistantChatId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->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;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->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_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
peerStatus = status;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
peerStatus = status;
emit infoChanged(this);
emit statusChanged(status);
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
emit infoChanged(this);
emit statusChanged(status);
return;
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
return;
}
// ignore status change
}
@ -1640,3 +1679,21 @@ bool ChatWidget::setStyle()
return false;
}
void ChatWidget::quote()
{
QString text = ui->textBrowser->textCursor().selection().toPlainText();
if(text.length() > 0)
{
QStringList sl = text.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
text = sl.join("\n>");
emit ui->chatTextEdit->append(QString(">") + text);
}
}
void ChatWidget::saveImage()
{
QPoint point = ui->actionSave_image->data().toPoint();
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
ImageUtil::extractImage(window(), cursor);
}

View file

@ -94,6 +94,7 @@ public:
void setWelcomeMessage(QString &text);
void addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType);
void addChatMsg(bool incoming, const QString &name, const RsGxsId gxsId, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType);
void updateStatusString(const QString &statusMask, const QString &statusString, bool permanent = false);
void addToolsAction(QAction *action);
@ -108,9 +109,8 @@ public:
// Adds one widget in the chat bar. Used to add e.g. new buttons. The widget should be
// small enough in size.
void addChatBarWidget(QWidget *w) ;
void addVOIPBarWidget(QWidget *w);
void addTitleBarWidget(QWidget *w);
void hideChatText(bool hidden);
RSButtonOnText* getNewButtonOnTextBrowser();
RSButtonOnText* getNewButtonOnTextBrowser(QString text);
@ -185,6 +185,9 @@ private slots:
bool fileSave();
bool fileSaveAs();
void quote();
void saveImage();
private:
bool findText(const QString& qsStringToFind);
bool findText(const QString& qsStringToFind, bool bBackWard, bool bForceMove);

File diff suppressed because it is too large Load diff

View file

@ -110,7 +110,7 @@ void CreateLobbyDialog::checkTextFields()
rsIdentity->getIdDetails(id,idd) ;
if( (!idd.mPgpKnown) && ui->pgp_signed_CB->isChecked())
if( (!(idd.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN)) && ui->pgp_signed_CB->isChecked())
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false) ;
}

View file

@ -43,11 +43,16 @@ PopupDistantChatDialog::~PopupDistantChatDialog()
delete _update_timer ;
}
PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags flags)
PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_id,QWidget *parent, Qt::WindowFlags flags)
: PopupChatDialog(parent,flags)
{
_status_label = new QLabel ;
_tunnel_id = tunnel_id ;
_status_label = new QToolButton ;
_update_timer = new QTimer ;
_status_label->setAutoRaise(true);
_status_label->setIconSize(QSize(24,24));
_update_timer->setInterval(1000) ;
QObject::connect(_update_timer,SIGNAL(timeout()),this,SLOT(updateDisplay())) ;
@ -58,97 +63,98 @@ PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags
updateDisplay() ;
}
void PopupDistantChatDialog::init(const RsGxsId &gxs_id,const QString & title)
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
{
_pid = gxs_id ;
PopupChatDialog::init(ChatId(gxs_id), title) ;
_tunnel_id = peer_id;
DistantChatPeerInfo tinfo;
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
return ;
RsIdentityDetails iddetails ;
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
else
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
RsGxsId own_gxs_id ;
uint32_t status ;
// do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// it will not be transmitted.
if(rsMsgs->getDistantChatStatus(gxs_id,status,&own_gxs_id))
ui.ownAvatarWidget->setId(ChatId(own_gxs_id));
ui.ownAvatarWidget->setOwnId() ; // sets the flag
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
}
void PopupDistantChatDialog::updateDisplay()
{
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(!isVisible())
return ;
if(!isVisible())
return ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
ui.avatarWidget->setId(ChatId(_pid));
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
ui.avatarWidget->setId(ChatId(_tunnel_id));
QString msg;
switch(status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ;
msg = tr("Hash Error. No tunnel.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
switch(tinfo.status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
msg = tr("Chat remotely closed. Please close this window.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: //std::cerr << "Tunnel is ok. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_YEL_LED)) ;
msg = QObject::tr("Secured tunnel established. Waiting for ACK...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
}
void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
{
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
DistantChatPeerInfo tinfo ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
if(tinfo.status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
{
QString msg = tr("Closing this window will end the conversation, notify the peer and remove the encrypted tunnel.") ;
if(QMessageBox::Ok == QMessageBox::critical(NULL,tr("Kill the tunnel?"),msg, QMessageBox::Ok | QMessageBox::Cancel))
rsMsgs->closeDistantChatConnexion(_pid) ;
rsMsgs->closeDistantChatConnexion(_tunnel_id) ;
else
{
e->ignore() ;
@ -163,23 +169,26 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
QString PopupDistantChatDialog::getPeerName(const ChatId &id) const
{
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(id.toGxsId(),details))
if(rsIdentity->getIdDetails(tinfo.to_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(id.toGxsId().toStdString()) ;
return QString::fromStdString(tinfo.to_id.toStdString()) ;
}
QString PopupDistantChatDialog::getOwnName() const
{
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
RsGxsId from_gxs_id ;
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_pid,status,&from_gxs_id) ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(from_gxs_id,details))
if(rsIdentity->getIdDetails(tinfo.own_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(from_gxs_id.toStdString()) ;
return QString::fromStdString(tinfo.own_id.toStdString()) ;
}

View file

@ -22,6 +22,7 @@
#pragma once
#include <retroshare/rsgxstunnel.h>
#include "PopupChatDialog.h"
class QTimer ;
@ -33,11 +34,11 @@ class PopupDistantChatDialog: public PopupChatDialog
protected:
/** Default constructor */
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
PopupDistantChatDialog(const DistantChatPeerId &tunnel_id, QWidget *parent = 0, Qt::WindowFlags flags = 0);
/** Default destructor */
virtual ~PopupDistantChatDialog();
virtual void init(const RsGxsId &gxs_id, const QString &title);
virtual void init(const DistantChatPeerId& peer_id);
virtual void closeEvent(QCloseEvent *e) ;
virtual QString getPeerName(const ChatId &id) const ;
@ -48,8 +49,8 @@ class PopupDistantChatDialog: public PopupChatDialog
private:
QTimer *_update_timer ;
RsGxsId _pid ;
QLabel *_status_label ;
DistantChatPeerId _tunnel_id ;
QToolButton *_status_label ;
friend class ChatDialog;
};

View file

@ -124,24 +124,33 @@ void AvatarWidget::setFrameType(FrameType type)
void AvatarWidget::setId(const ChatId &id)
{
mId = id;
// mPgpId = rsPeers->getGPGId(id) ;
// mFlag.isGpg = false ;
mGxsId.clear();
setPixmap(QPixmap());
if (id.isNotSet()) {
setEnabled(false);
}
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setGxsId(const RsGxsId &id)
{
mId = ChatId();
mGxsId = id;
setPixmap(QPixmap());
if (id.isNull()) {
setEnabled(false);
}
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setOwnId(const RsGxsId& own_gxs_id)
{
mFlag.isOwnId = true;
setId(ChatId(own_gxs_id));
}
void AvatarWidget::setOwnId()
{
mFlag.isOwnId = true;
@ -181,7 +190,7 @@ void AvatarWidget::refreshStatus()
rsStatus->getOwnStatus(statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
else if(mId.isDistantChatId())
status = RS_STATUS_ONLINE ;
else
{
@ -198,11 +207,15 @@ void AvatarWidget::refreshStatus()
rsStatus->getStatus(mId.toPeerId(), statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
{
if(!rsMsgs->getDistantChatStatus(mId.toGxsId(),status))
status = RS_STATUS_OFFLINE ;
}
else if(mId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
status = dcpinfo.status ;
else
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
}
else
{
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;
@ -235,13 +248,22 @@ void AvatarWidget::updateStatus(int status)
void AvatarWidget::updateAvatar(const QString &peerId)
{
if(mId.isPeerId() && mId.toPeerId() == RsPeerId(peerId.toStdString()))
refreshAvatarImage() ;
if(mId.isGxsId() && mId.toGxsId() == RsGxsId(peerId.toStdString()))
refreshAvatarImage() ;
refreshAvatarImage() ;
else if(mId.isDistantChatId() && mId.toDistantChatId() == DistantChatPeerId(peerId.toStdString()))
refreshAvatarImage() ;
else
std::cerr << "(EE) cannot update avatar. mId has unhandled type." << std::endl;
}
void AvatarWidget::refreshAvatarImage()
{
if (mGxsId.isNull()==false)
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mGxsId, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
if (mId.isNotSet())
{
QPixmap avatar(defaultAvatar);
@ -262,12 +284,21 @@ void AvatarWidget::refreshAvatarImage()
setPixmap(avatar);
return;
}
else if (mId.isGxsId())
else if (mId.isDistantChatId())
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
setPixmap(avatar);
return;
QPixmap avatar;
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
{
if(mFlag.isOwnId)
AvatarDefs::getAvatarFromGxsId(dcpinfo.own_id, avatar, defaultAvatar);
else
AvatarDefs::getAvatarFromGxsId(dcpinfo.to_id, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
}
else
std::cerr << "WARNING: unhandled situation in AvatarWidget::refreshAvatarImage()" << std::endl;

View file

@ -50,8 +50,8 @@ public:
QString frameState();
void setFrameType(FrameType type);
void setId(const ChatId& id) ;
void setGxsId(const RsGxsId& id) ;
void setOwnId();
void setOwnId(const RsGxsId&);
void setDefaultAvatar(const QString &avatar_file_name);
protected:
@ -71,6 +71,7 @@ private:
Ui::AvatarWidget *ui;
ChatId mId;
RsGxsId mGxsId;
struct {
bool isOwnId : 1;

View file

@ -221,5 +221,7 @@ void ElidedLabel::mousePressEvent(QMouseEvent *ev)
{
if (mElided && (ev->buttons()==Qt::LeftButton) && (mRectElision.contains(ev->pos()))){
QToolTip::showText(mapToGlobal(QPoint(0, 0)),QString("<FONT>") + mContent + QString("</FONT>"));
return; // eat event
}
QLabel::mousePressEvent(ev);
}

View file

@ -29,7 +29,7 @@
#include <QPushButton>
#include <iostream>
#include <math.h>
#include "Emoticons.h"
#include "util/HandleRichText.h"
@ -48,7 +48,7 @@ void Emoticons::load()
internalEmoticons = false;
} else {
// then embedded emotions
sm_file.setFileName(":/smileys/emotes.acs");
sm_file.setFileName(":/emojione/emotes.acs");
if(!sm_file.open(QIODevice::ReadOnly))
{
std::cout << "error opening ressource file" << std::endl ;
@ -56,7 +56,7 @@ void Emoticons::load()
}
}
#else
QFile sm_file(QString(":/smileys/emotes.acs"));
QFile sm_file(QString(":/emojione/emotes.acs"));
if(!sm_file.open(QIODevice::ReadOnly))
{
std::cout << "error opening ressource file" << std::endl ;
@ -128,9 +128,9 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s
const int buttonWidth = 26;
const int buttonHeight = 26;
const int countPerLine = 9;
int rowCount = (Smileys.size()/countPerLine) + ((Smileys.size() % countPerLine) ? 1 : 0);
int rowCount = (int)sqrt((double)Smileys.size());
int countPerLine = (Smileys.size()/rowCount) + ((Smileys.size() % rowCount) ? 1 : 0);
smWidget->setAttribute( Qt::WA_DeleteOnClose);
smWidget->setWindowTitle("Emoticons");

View file

@ -284,6 +284,10 @@ void FriendSelectionWidget::secured_fillList()
std::set<RsGxsId> gxsIdsSelected;
if (mShowTypes & SHOW_GXS)
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
std::set<RsGxsId> gxsIdsSelected2;
if (mShowTypes & SHOW_CONTACTS)
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected2,true);
// remove old items
ui->friendList->clear();
@ -525,6 +529,7 @@ void FriendSelectionWidget::secured_fillList()
// iterate through gpg ids
for (std::vector<RsGxsGroupId>::const_iterator gxsIt = gxsIds.begin(); gxsIt != gxsIds.end(); ++gxsIt)
{
// we fill the not assigned gpg ids
if (std::find(filledIds.begin(), filledIds.end(), (*gxsIt).toStdString()) != filledIds.end())
continue;
@ -570,6 +575,61 @@ void FriendSelectionWidget::secured_fillList()
setSelected(mListModus, gxsItem, true);
}
}
if(mShowTypes & SHOW_CONTACTS)
{
// iterate through gpg ids
for (std::vector<RsGxsGroupId>::const_iterator gxsIt = gxsIds.begin(); gxsIt != gxsIds.end(); ++gxsIt)
{
// we fill the not assigned gpg ids
if (std::find(filledIds.begin(), filledIds.end(), (*gxsIt).toStdString()) != filledIds.end())
continue;
// add equal too, its no problem
filledIds.push_back((*gxsIt).toStdString());
RsIdentityDetails detail;
if (!rsIdentity->getIdDetails(RsGxsId(*gxsIt), detail))
continue; /* BAD */
QList<QIcon> icons ;
GxsIdDetails::getIcons(detail,icons,GxsIdDetails::ICON_TYPE_AVATAR) ;
QIcon identicon = icons.front() ;
if(detail.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT)
{
// make a widget per friend
gxsItem = new RSTreeWidgetItem(mCompareRole, IDTYPE_GXS);
QString name = QString::fromUtf8(detail.mNickname.c_str());
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
gxsItem->setIcon(COLUMN_NAME, identicon);
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
gxsItem->setData(COLUMN_NAME, ROLE_SORT_GROUP, 1);
gxsItem->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, 0);
//TODO: online state for gxs items
gxsItem->setData(COLUMN_NAME, ROLE_SORT_STATE, 1);
gxsItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name);
if (mListModus == MODUS_CHECK)
gxsItem->setCheckState(0, Qt::Unchecked);
ui->friendList->addTopLevelItem(gxsItem);
gxsItem->setExpanded(true);
emit itemAdded(IDTYPE_GXS, QString::fromStdString(detail.mId.toStdString()), gxsItem);
if (std::find(gxsIdsSelected.begin(), gxsIdsSelected.end(), detail.mId) != gxsIdsSelected.end())
setSelected(mListModus, gxsItem, true);
}
}
}
if (groupIt != groupInfoList.end()) {
++groupIt;
} else {

View file

@ -65,7 +65,8 @@ public:
SHOW_GPG = 2,
SHOW_SSL = 4,
SHOW_NON_FRIEND_GPG = 8,
SHOW_GXS =16
SHOW_GXS =16,
SHOW_CONTACTS =32
};
Q_DECLARE_FLAGS(ShowTypes, ShowType)

View file

@ -46,7 +46,7 @@ void GroupSelectionBox::selectedGroupIds(std::list<std::string> &groupIds) const
QListWidgetItem *listItem = item(i);
if (listItem->checkState() == Qt::Checked) {
groupIds.push_back(item(i)->data(ROLE_ID).toString().toStdString());
std::cerr << "Addign selected item " << groupIds.back() << std::endl;
std::cerr << "Adding selected item " << groupIds.back() << std::endl;
}
}
}
@ -74,7 +74,7 @@ void GroupSelectionBox::selectedGroupNames(QList<QString> &groupNames) const
QListWidgetItem *listItem = item(i);
if (listItem->checkState() == Qt::Checked) {
groupNames.push_back(item(i)->text());
std::cerr << "Addign selected item " << groupNames.back().toUtf8().constData() << std::endl;
std::cerr << "Adding selected item " << groupNames.back().toUtf8().constData() << std::endl;
}
}
}

View file

@ -46,10 +46,11 @@
#define ROLE_DESCRIPTION Qt::UserRole + 2
#define ROLE_POPULARITY Qt::UserRole + 3
#define ROLE_LASTPOST Qt::UserRole + 4
#define ROLE_SEARCH_SCORE Qt::UserRole + 5
#define ROLE_SUBSCRIBE_FLAGS Qt::UserRole + 6
#define ROLE_COLOR Qt::UserRole + 7
#define ROLE_SAVED_ICON Qt::UserRole + 8
#define ROLE_POSTS Qt::UserRole + 5
#define ROLE_SEARCH_SCORE Qt::UserRole + 6
#define ROLE_SUBSCRIBE_FLAGS Qt::UserRole + 7
#define ROLE_COLOR Qt::UserRole + 8
#define ROLE_SAVED_ICON Qt::UserRole + 9
#define FILTER_NAME_INDEX 0
#define FILTER_DESC_INDEX 1
@ -65,6 +66,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
actionSortByName = NULL;
actionSortByPopularity = NULL;
actionSortByLastPost = NULL;
actionSortByPosts = NULL;
compareRole = new RSTreeWidgetItemCompareRole;
compareRole->setRole(COLUMN_DATA, ROLE_NAME);
@ -96,7 +98,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
QHeaderView_setSectionResizeModeColumn(header, COLUMN_NAME, QHeaderView::Stretch);
header->resizeSection(COLUMN_NAME, 10*S);
QHeaderView_setSectionResizeModeColumn(header, COLUMN_POPULARITY, QHeaderView::Fixed);
header->resizeSection(COLUMN_POPULARITY, 1.5*S);
header->resizeSection(COLUMN_POPULARITY, 2*S);
/* add filter actions */
ui->filterLineEdit->addFilter(QIcon(), tr("Title"), FILTER_NAME_INDEX , tr("Search Title"));
@ -106,7 +108,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
/* Initialize display button */
initDisplayMenu(ui->displayButton);
ui->treeWidget->setIconSize(QSize(S*1.2,S*1.2)) ;
ui->treeWidget->setIconSize(QSize(S*1.6,S*1.6)) ;
}
GroupTreeWidget::~GroupTreeWidget()
@ -153,6 +155,7 @@ void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
const int SORTBY_NAME = 1;
const int SORTBY_POPULRITY = 2;
const int SORTBY_LASTPOST = 3;
const int SORTBY_POSTS = 4;
if (load) {
// load settings
@ -175,6 +178,11 @@ void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
actionSortByLastPost->setChecked(true);
}
break;
case SORTBY_POSTS:
if (actionSortByPosts) {
actionSortByPosts->setChecked(true);
}
break;
}
} else {
// save settings
@ -221,6 +229,10 @@ void GroupTreeWidget::initDisplayMenu(QToolButton *toolButton)
actionSortByLastPost = displayMenu->addAction(QIcon(), tr("Sort by Last Post"), this, SLOT(sort()));
actionSortByLastPost->setCheckable(true);
actionSortByLastPost->setActionGroup(actionGroup);
actionSortByPosts = displayMenu->addAction(QIcon(), tr("Sort by Posts"), this, SLOT(sort()));
actionSortByPosts->setCheckable(true);
actionSortByPosts->setActionGroup(actionGroup);
toolButton->setMenu(displayMenu);
}
@ -359,6 +371,9 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
/* Set last post */
qlonglong lastPost = itemInfo.lastpost.toTime_t();
item->setData(COLUMN_DATA, ROLE_LASTPOST, -lastPost); // negative for correct sorting
/* Set visible posts */
item->setData(COLUMN_DATA, ROLE_POSTS, -itemInfo.max_visible_posts);// negative for correct sorting
/* Set icon */
if (ui->treeWidget->itemWidget(item, COLUMN_NAME)) {
@ -623,6 +638,8 @@ void GroupTreeWidget::resort(QTreeWidgetItem *categoryItem)
compareRole->setRole(COLUMN_DATA, ROLE_POPULARITY);
} else if (actionSortByLastPost && actionSortByLastPost->isChecked()) {
compareRole->setRole(COLUMN_DATA, ROLE_LASTPOST);
} else if (actionSortByPosts && actionSortByPosts->isChecked()) {
compareRole->setRole(COLUMN_DATA, ROLE_POSTS);
}
if (categoryItem) {

View file

@ -137,6 +137,7 @@ private:
QAction *actionSortByName;
QAction *actionSortByPopularity;
QAction *actionSortByLastPost;
QAction *actionSortByPosts;
RSTreeWidgetItemCompareRole *compareRole;

View file

@ -41,6 +41,7 @@ MimeTextEdit::MimeTextEdit(QWidget *parent)
mCompleterKeyModifiers = Qt::ControlModifier;
mCompleterKey = Qt::Key_Space;
mForceCompleterShowNextKeyEvent = false;
highliter = new RsSyntaxHighlighter(this);
}
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
@ -231,6 +232,8 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e)
/* Add actions for pasting links */
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler()));
spoilerAction->setToolTip(tr("Select text to hide, then push this button"));
contextMenu->addSeparator();
QAction *pasteLinkAction = contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
@ -268,3 +271,8 @@ void MimeTextEdit::pastePlainText()
{
insertPlainText(QApplication::clipboard()->text());
}
void MimeTextEdit::spoiler()
{
RsHtml::insertSpoilerText(this->textCursor());
}

View file

@ -24,11 +24,14 @@
#include <QCompleter>
#include "RSTextEdit.h"
#include "util/RsSyntaxHighlighter.h"
class MimeTextEdit : public RSTextEdit
{
Q_OBJECT
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
public:
MimeTextEdit(QWidget *parent = 0);
@ -44,6 +47,11 @@ public:
// Add QAction to context menu (action won't be deleted)
void addContextMenuAction(QAction *action);
QColor textColorQuote() const { return highliter->textColorQuote();}
public slots:
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
signals:
void calculateContextMenuActions();
@ -59,6 +67,8 @@ private slots:
void pasteLink();
void pasteOwnCertificateLink();
void pastePlainText();
void spoiler();
private:
QString textUnderCursor() const;
@ -69,6 +79,7 @@ private:
bool mForceCompleterShowNextKeyEvent;
QString mCompleterStartString;
QList<QAction*> mContextMenuActions;
RsSyntaxHighlighter *highliter;
};
#endif // MIMETEXTEDIT_H

View file

@ -113,7 +113,7 @@ QString RSGraphSource::legend(int i,float v) const
return displayName(i) + " (" + displayValue(v) + " )";
}
void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts) const
void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts,float filter_factor) const
{
pts.clear() ;
qint64 now = getTime() ;
@ -126,8 +126,15 @@ void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts) const
if(n != index)
return ;
float last_value = it->second.empty()?0.0f:(it->second.begin()->second) ;
for(std::list<std::pair<qint64,float> >::const_iterator it2=it->second.begin();it2!=it->second.end();++it2)
pts.push_back(QPointF( (now - (*it2).first)/1000.0f,(*it2).second)) ;
{
float val = (1-filter_factor)*(*it2).second + filter_factor*last_value;
last_value = val ;
pts.push_back(QPointF( (now - (*it2).first)/1000.0f, val)) ;
}
}
void RSGraphWidget::setShowEntry(uint32_t entry,bool b)
@ -231,6 +238,7 @@ RSGraphWidget::RSGraphWidget(QWidget *parent)
_opacity = 0.6 ;
_flags = 0;
_time_scale = 5.0f ; // in pixels per second.
_time_filter = 1.0f ;
_timer = new QTimer ;
QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ;
@ -370,7 +378,8 @@ void RSGraphWidget::paintData()
if( _masked_entries.find(source.displayName(i).toStdString()) == _masked_entries.end() )
{
std::vector<QPointF> values ;
source.getDataPoints(i,values) ;
//std::cerr << "time filter = " << _time_filter << ", factor=" << 1./_time_scale*_time_filter/(1+_time_filter/_time_scale) << std::endl;
source.getDataPoints(i,values,1./_time_scale*_time_filter/(1.0f+_time_filter/_time_scale)) ;
QVector<QPointF> points ;
pointsFromData(values,points) ;
@ -394,79 +403,79 @@ void RSGraphWidget::paintData()
* of rsdht or alldht values. */
void RSGraphWidget::pointsFromData(const std::vector<QPointF>& values,QVector<QPointF>& points)
{
points.clear();
points.clear();
int x = _rec.width();
int y = _rec.height();
int x = _rec.width();
int y = _rec.height();
float time_step = 1.0f ; // number of seconds per pixel
float time_step = 1.0f ; // number of seconds per pixel
/* Translate all data points to points on the graph frame */
/* Translate all data points to points on the graph frame */
// take 0 as the origin, otherwise the different curves are not aligned properly
float last = 0;//values.back().x();
// take 0 as the origin, otherwise the different curves are not aligned properly
float last = 0;//values.back().x();
//std::cerr << "Got " << values.size() << " values for index 0" << std::endl;
//std::cerr << "Got " << values.size() << " values for index 0" << std::endl;
float FS = QFontMetricsF(font()).height();
float fact = FS/14.0 ;
float FS = QFontMetricsF(font()).height();
float fact = FS/14.0 ;
float last_px = SCALE_WIDTH*fact ;
float last_py = 0.0f ;
float last_px = SCALE_WIDTH*fact ;
float last_py = 0.0f ;
// float min_x_no_data_threshold = 1.5 ; // 1.5 sec.
// float min_x_no_data_threshold = 1.5 ; // 1.5 sec.
for (uint i = 0; i < values.size(); ++i)
{
//std::cerr << "Value: (" << values[i].x() << " , " << values[i].y() << ")" << std::endl;
for (uint i = 0; i < values.size(); ++i)
{
//std::cerr << "Value: (" << values[i].x() << " , " << values[i].y() << ")" << std::endl;
// compute point in pixels
// compute point in pixels
qreal px = x - (values[i].x()-last)*_time_scale ;
qreal py = y - valueToPixels(values[i].y()) ;
qreal px = x - (values[i].x()-last)*_time_scale ;
qreal py = y - valueToPixels(values[i].y()) ;
if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact)
{
float alpha = (SCALE_WIDTH*fact - last_px)/(px - last_px) ;
float ipx = SCALE_WIDTH*fact ;
float ipy = (1-alpha)*last_py + alpha*py ;
if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact)
{
float alpha = (SCALE_WIDTH*fact - last_px)/(px - last_px) ;
float ipx = SCALE_WIDTH*fact ;
float ipy = (1-alpha)*last_py + alpha*py ;
points << QPointF(ipx,y) ;
points << QPointF(ipx,ipy) ;
}
else if(i==0)
{
if(px < SCALE_WIDTH*fact)
points << QPointF(SCALE_WIDTH*fact,py) ;
else
points << QPointF(px,y) ;
}
points << QPointF(ipx,y) ;
points << QPointF(ipx,ipy) ;
}
else if(i==0)
{
if(px < SCALE_WIDTH*fact)
points << QPointF(SCALE_WIDTH*fact,py) ;
else
points << QPointF(px,y) ;
}
if(px < SCALE_WIDTH*fact)
continue ;
if(px < SCALE_WIDTH*fact)
continue ;
_maxValue = std::max(_maxValue,values[i].y()) ;
_maxValue = std::max(_maxValue,values[i].y()) ;
// remove midle point when 3 consecutive points have the same value.
// remove midle point when 3 consecutive points have the same value.
if(points.size() > 1 && points[points.size()-2].y() == points.back().y() && points.back().y() == py)
points.pop_back() ;
if(points.size() > 1 && points[points.size()-2].y() == points.back().y() && points.back().y() == py)
points.pop_back() ;
// if(fabs(px - last_px)/_time_scale > min_x_no_data_threshold)
// {
// points << QPointF(last_px,y) ;
// points << QPointF(px,y) ;
// }
// if(fabs(px - last_px)/_time_scale > min_x_no_data_threshold)
// {
// points << QPointF(last_px,y) ;
// points << QPointF(px,y) ;
// }
points << QPointF(px,py) ;
points << QPointF(px,py) ;
if(i==values.size()-1)
points << QPointF(px,y) ;
if(i==values.size()-1)
points << QPointF(px,y) ;
last_px = px ;
last_py = py ;
last_px = px ;
last_py = py ;
}
}
}
qreal RSGraphWidget::valueToPixels(qreal val)
@ -601,12 +610,18 @@ void RSGraphWidget::paintScale2()
void RSGraphWidget::wheelEvent(QWheelEvent *e)
{
if(e->delta() > 0)
_time_scale *= 1.1 ;
else
_time_scale /= 1.1 ;
if(e->modifiers() & Qt::ShiftModifier)
if(e->delta() > 0)
_time_filter *= 1.1 ;
else
_time_filter /= 1.1 ;
else
if(e->delta() > 0)
_time_scale *= 1.1 ;
else
_time_scale /= 1.1 ;
update() ;
update() ;
}
void RSGraphWidget::paintLegend()

View file

@ -73,7 +73,7 @@ public:
virtual QString legend(int i,float v) const ;
// Returns the n^th interpolated value at the given time in floating point seconds backward.
virtual void getDataPoints(int index, std::vector<QPointF>& pts) const ;
virtual void getDataPoints(int index, std::vector<QPointF>& pts, float filter_factor=0.0f) const ;
// returns the name to give to the nth entry in the graph
virtual QString displayName(int index) const ;
@ -113,108 +113,109 @@ class RSGraphWidget: public QFrame
{
Q_OBJECT
public:
static const uint32_t RSGRAPH_FLAGS_AUTO_SCALE_Y = 0x0001 ;// automatically adjust Y scale
static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y
static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style
static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes
public:
static const uint32_t RSGRAPH_FLAGS_AUTO_SCALE_Y = 0x0001 ;// automatically adjust Y scale
static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y
static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style
static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes
/** Bandwidth graph style. */
enum GraphStyle
{
SolidLine = 0, /**< Plot bandwidth as solid lines. */
AreaGraph = 1 /**< Plot bandwidth as alpha blended area graphs. */
};
/** Bandwidth graph style. */
enum GraphStyle
{
SolidLine = 0, /**< Plot bandwidth as solid lines. */
AreaGraph = 1 /**< Plot bandwidth as alpha blended area graphs. */
};
/** Default Constructor */
RSGraphWidget(QWidget *parent = 0);
/** Default Destructor */
~RSGraphWidget();
/** Default Constructor */
RSGraphWidget(QWidget *parent = 0);
/** Default Destructor */
~RSGraphWidget();
// sets the update interval period.
//
void setTimerPeriod(int miliseconds) ;
void setSource(RSGraphSource *gs) ;
void setTimeScale(float pixels_per_second) ;
// sets the update interval period.
//
void setTimerPeriod(int miliseconds) ;
void setSource(RSGraphSource *gs) ;
void setTimeScale(float pixels_per_second) ;
/** Add data points. */
//void addPoints(qreal rsDHT, qreal allDHT);
/** Clears the graph. */
void resetGraph();
/** Toggles display of data counters. */
//void setShowCounters(bool showRSDHT, bool showALLDHT);
/** Add data points. */
//void addPoints(qreal rsDHT, qreal allDHT);
/** Clears the graph. */
void resetGraph();
/** Toggles display of data counters. */
//void setShowCounters(bool showRSDHT, bool showALLDHT);
void setShowEntry(uint32_t entry, bool show) ;
void setCurvesOpacity(float f) ;
void setShowEntry(uint32_t entry, bool show) ;
void setCurvesOpacity(float f) ;
void setFlags(uint32_t flag) { _flags |= flag ; }
void resetFlags(uint32_t flag) { _flags &= ~flag ; }
protected:
/** Overloaded QWidget::paintEvent() */
void paintEvent(QPaintEvent *event);
void setFlags(uint32_t flag) { _flags |= flag ; }
void resetFlags(uint32_t flag) { _flags &= ~flag ; }
protected:
/** Overloaded QWidget::paintEvent() */
void paintEvent(QPaintEvent *event);
virtual QSizeF sizeHint( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
virtual QSizeF sizeHint( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
protected slots:
void updateIfPossible() ;
protected slots:
void updateIfPossible() ;
virtual void wheelEvent(QWheelEvent *e);
private:
/** Gets the width of the desktop, the max # of points. */
int getNumPoints();
virtual void wheelEvent(QWheelEvent *e);
private:
/** Gets the width of the desktop, the max # of points. */
int getNumPoints();
/** Paints an integral and an outline of that integral for each data set
/** Paints an integral and an outline of that integral for each data set
* (rsdht and/or alldht) that is to be displayed. */
void paintData();
/** Paints the rsdht/alldht totals. */
void paintTotals();
/** Paints the scale in the graph. */
void paintLegend();
/** Paints the scale in the graph. */
void paintScale1();
void paintScale2();
void paintData();
/** Paints the rsdht/alldht totals. */
void paintTotals();
/** Paints the scale in the graph. */
void paintLegend();
/** Paints the scale in the graph. */
void paintScale1();
void paintScale2();
QColor getColor(int i) ;
QColor getColor(int i) ;
/** Returns a formatted string representation of total. */
QString totalToStr(qreal total);
/** Returns a list of points on the bandwidth graph based on the supplied set
/** Returns a formatted string representation of total. */
QString totalToStr(qreal total);
/** Returns a list of points on the bandwidth graph based on the supplied set
* of rsdht or alldht values. */
void pointsFromData(const std::vector<QPointF>& values, QVector<QPointF> &points ) ;
void pointsFromData(const std::vector<QPointF>& values, QVector<QPointF> &points ) ;
/** Paints a line with the data in <b>points</b>. */
void paintLine(const QVector<QPointF>& points, QColor color,
Qt::PenStyle lineStyle = Qt::SolidLine);
/** Paints an integral using the supplied data. */
void paintIntegral(const QVector<QPointF>& points, QColor color, qreal alpha = 1.0);
/** Paints a line with the data in <b>points</b>. */
void paintLine(const QVector<QPointF>& points, QColor color,
Qt::PenStyle lineStyle = Qt::SolidLine);
/** Paints an integral using the supplied data. */
void paintIntegral(const QVector<QPointF>& points, QColor color, qreal alpha = 1.0);
/** A QPainter object that handles drawing the various graph elements. */
QPainter* _painter;
/** The current dimensions of the graph. */
QRect _rec;
/** The maximum data value plotted. */
qreal _maxValue;
/** The maximum number of points to store. */
qreal _y_scale ;
qreal _opacity ;
/** A QPainter object that handles drawing the various graph elements. */
QPainter* _painter;
/** The current dimensions of the graph. */
QRect _rec;
/** The maximum data value plotted. */
qreal _maxValue;
/** The maximum number of points to store. */
qreal _y_scale ;
qreal _opacity ;
qreal pixelsToValue(qreal) ;
qreal valueToPixels(qreal) ;
int _maxPoints;
qreal pixelsToValue(qreal) ;
qreal valueToPixels(qreal) ;
int _maxPoints;
std::set<std::string> _masked_entries ;
std::set<std::string> _masked_entries ;
qreal _time_scale ; // horizontal scale in pixels per sec.
qreal _time_scale ; // horizontal scale in pixels per sec.
qreal _time_filter ; // time filter. Goes from 0 to infinity. Will be converted into 1-1/(1+f)
/** Show the respective lines and counters. */
//bool _showRSDHT;
//bool _showALLDHT;
/** Show the respective lines and counters. */
//bool _showRSDHT;
//bool _showALLDHT;
uint32_t _flags ;
QTimer *_timer ;
uint32_t _flags ;
QTimer *_timer ;
RSGraphSource *_source ;
RSGraphSource *_source ;
};

View file

@ -14,6 +14,8 @@ RSTextBrowser::RSTextBrowser(QWidget *parent) :
mImageBlockWidget = NULL;
mLinkClickActive = true;
highliter = new RsSyntaxHighlighter(this);
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
}

View file

@ -2,6 +2,7 @@
#define RSTEXTBROWSER_H
#include <QTextBrowser>
#include "util/RsSyntaxHighlighter.h"
class RSImageBlockWidget;
@ -9,6 +10,8 @@ class RSTextBrowser : public QTextBrowser
{
Q_OBJECT
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
public:
explicit RSTextBrowser(QWidget *parent = 0);
@ -20,8 +23,11 @@ public:
virtual QVariant loadResource(int type, const QUrl &name);
QColor textColorQuote() const { return highliter->textColorQuote();}
public slots:
void showImages();
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
private slots:
void linkClicked(const QUrl &url);
@ -35,6 +41,7 @@ private:
bool mShowImages;
RSImageBlockWidget *mImageBlockWidget;
bool mLinkClickActive;
RsSyntaxHighlighter *highliter;
};
#endif // RSTEXTBROWSER_H

View file

@ -182,6 +182,10 @@ QString StatusDefs::connectStateString(RsPeerDetails &details)
stateString = qApp->translate("StatusDefs", "Connected: Tor");
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_I2P:
stateString = qApp->translate("StatusDefs", "Connected: I2P");
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN:
stateString = qApp->translate("StatusDefs", "Connected: Unknown");
isConnected = true;
@ -231,6 +235,7 @@ QString StatusDefs::connectStateWithoutTransportTypeString(RsPeerDetails &detail
case RS_PEER_CONNECTSTATE_CONNECTED_TCP:
case RS_PEER_CONNECTSTATE_CONNECTED_UDP:
case RS_PEER_CONNECTSTATE_CONNECTED_TOR:
case RS_PEER_CONNECTSTATE_CONNECTED_I2P:
case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN:
stateString = qApp->translate("StatusDefs", "Connected");
break;
@ -258,6 +263,9 @@ QString StatusDefs::connectStateIpString(RsPeerDetails &details)
case RS_PEER_CONNECTSTATE_CONNECTED_TOR:
stateString += QString(details.actAsServer ? qApp->translate("StatusDefs", "Tor-in") : qApp->translate("StatusDefs", "Tor-out"));
break;
case RS_PEER_CONNECTSTATE_CONNECTED_I2P:
stateString += QString(details.actAsServer ? qApp->translate("StatusDefs", "I2P-in") : qApp->translate("StatusDefs", "I2P-out"));
break;
case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN:
stateString += qApp->translate("StatusDefs", "unkown");
break;

View file

@ -103,7 +103,21 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) :
ui->requestinfolabel->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))) ;
connect(ui->addKeyToKeyring_CB,SIGNAL(toggled(bool)), ui->acceptNoSignGPGCheckBox,SLOT(setChecked(bool))) ;
connect(ui->gmailButton, SIGNAL(clicked()), this, SLOT(inviteGmail()));
connect(ui->yahooButton, SIGNAL(clicked()), this, SLOT(inviteYahoo()));
connect(ui->outlookButton, SIGNAL(clicked()), this, SLOT(inviteOutlook()));
connect(ui->aolButton, SIGNAL(clicked()), this, SLOT(inviteAol()));
connect(ui->yandexButton, SIGNAL(clicked()), this, SLOT(inviteYandex()));
connect(ui->emailButton, SIGNAL(clicked()), this, SLOT(runEmailClient2()));
subject = tr("RetroShare Invitation");
body = GetStartedDialog::GetInviteText();
body += "\n" + GetStartedDialog::GetCutBelowText();
body += "\n\n" + QString::fromUtf8(rsPeers->GetRetroshareInvite(false).c_str());
updateStylesheet();
}
@ -351,13 +365,23 @@ void ConnectFriendWizard::initializePage(int id)
case Page_Rsid:
ui->RsidPage->registerField("friendRSID*", ui->friendRsidEdit);
break;
case Page_WebMail:
case Page_Email:
{
ui->EmailPage->registerField("addressEdit*", ui->addressEdit);
ui->EmailPage->registerField("subjectEdit*", ui->subjectEdit);
ui->subjectEdit->setText(tr("RetroShare Invitation"));
ui->inviteTextEdit->setPlainText(GetStartedDialog::GetInviteText());
QString body = ui->inviteTextEdit->toPlainText();
body += "\n" + GetStartedDialog::GetCutBelowText();
body += "\n\n" + QString::fromUtf8(rsPeers->GetRetroshareInvite(false).c_str());
ui->inviteTextEdit->setPlainText(body);
}
break;
case Page_ErrorMessage:
break;
@ -488,6 +512,7 @@ void ConnectFriendWizard::initializePage(int id)
}
ui->nodeEdit->setText(loc);
ui->ipEdit->setText(QString::fromStdString(peerDetails.isHiddenNode ? peerDetails.hiddenNodeAddress : peerDetails.extAddr));
ui->signersEdit->setPlainText(ts);
fillGroups(this, ui->groupComboBox, groupId);
@ -730,6 +755,7 @@ int ConnectFriendWizard::nextId() const
if (ui->certRadioButton->isChecked()) return Page_Cert;
if (ui->foffRadioButton->isChecked()) return Page_Foff;
if (ui->rsidRadioButton->isChecked()) return Page_Rsid;
if (ui->webmailRadioButton->isChecked()) return Page_WebMail;
if (ui->emailRadioButton->isChecked()) return Page_Email;
if (ui->friendRecommendationsRadioButton->isChecked()) return Page_FriendRecommendations;
return ConnectFriendWizard::Page_Foff;
@ -738,6 +764,7 @@ int ConnectFriendWizard::nextId() const
case Page_Rsid:
return error ? ConnectFriendWizard::Page_Conclusion : ConnectFriendWizard::Page_ErrorMessage;
case Page_Foff:
case Page_WebMail:
case Page_Email:
case Page_ErrorMessage:
case Page_Conclusion:
@ -1205,4 +1232,34 @@ void ConnectFriendWizard::groupCurrentIndexChanged(int index)
}
}
//========================== WebMailPage ==================================
void ConnectFriendWizard::inviteGmail()
{
QDesktopServices::openUrl(QUrl("https://mail.google.com/mail/?view=cm&fs=1&su=" + subject + "&body=" + body , QUrl::TolerantMode));
}
void ConnectFriendWizard::inviteYahoo()
{
QDesktopServices::openUrl(QUrl("http://compose.mail.yahoo.com/?&subject=" + subject + "&body=" + body, QUrl::TolerantMode));
}
void ConnectFriendWizard::inviteOutlook()
{
QDesktopServices::openUrl(QUrl("http://mail.live.com/mail/EditMessageLight.aspx?n=&subject=" + subject + "&body=" + body, QUrl::TolerantMode));
}
void ConnectFriendWizard::inviteAol()
{
QDesktopServices::openUrl(QUrl("http://webmail.aol.com/Mail/ComposeMessage.aspx?&subject=" + subject + "&body=" + body, QUrl::TolerantMode));
}
void ConnectFriendWizard::inviteYandex()
{
QDesktopServices::openUrl(QUrl("https://mail.yandex.com/neo2/#compose/subject=" + subject + "&body=" + body, QUrl::TolerantMode));
}
void ConnectFriendWizard::runEmailClient2()
{
sendMail("", subject, body );
}

View file

@ -30,7 +30,7 @@ class ConnectFriendWizard : public QWizard
Q_PROPERTY(QString titleColor READ titleColor WRITE setTitleColor)
public:
enum Page { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion, Page_Foff, Page_Rsid, Page_Email, Page_FriendRequest, Page_FriendRecommendations };
enum Page { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion, Page_Foff, Page_Rsid, Page_WebMail, Page_Email, Page_FriendRequest, Page_FriendRecommendations };
ConnectFriendWizard(QWidget *parent = 0);
~ConnectFriendWizard();
@ -62,6 +62,7 @@ private slots:
void toggleSignatureState(bool doUpdate = true);
void toggleFormatState(bool doUpdate = true);
void runEmailClient();
void runEmailClient2();
void showHelpUserCert();
void copyCert();
void pasteCert();
@ -81,6 +82,14 @@ private slots:
/* ConclusionPage */
void groupCurrentIndexChanged(int index);
/* WebMailPage */
void inviteGmail();
void inviteYahoo();
void inviteOutlook();
void inviteAol();
void inviteYandex();
private:
// returns the translated error string for the error code (to be found in rspeers.h)
@ -109,6 +118,10 @@ private:
/* ConclusionPage */
QString groupId;
/* WebMailPage */
QString subject;
QString body;
Ui::ConnectFriendWizard *ui;
};

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>691</width>
<height>650</height>
<height>644</height>
</rect>
</property>
<property name="windowTitle">
@ -22,7 +22,7 @@
<string>Add a new Friend</string>
</property>
<property name="subTitle">
<string>This wizard will help you to connect to your friend(s) to RetroShare network.&lt;br&gt;These ways are possible to do this:</string>
<string>This wizard will help you to connect to your friend(s) to RetroShare network.&lt;br&gt;Select how you would like to add a friend:</string>
</property>
<attribute name="pageId">
<string notr="true">ConnectFriendWizard::Page_Intro</string>
@ -31,7 +31,7 @@
<item>
<widget class="QRadioButton" name="textRadioButton">
<property name="text">
<string>&amp;Enter the certificate manually</string>
<string>Enter the certificate manually</string>
</property>
</widget>
</item>
@ -52,7 +52,14 @@
<item>
<widget class="QRadioButton" name="rsidRadioButton">
<property name="text">
<string>&amp;Enter RetroShare ID manually</string>
<string>Enter RetroShare ID manually</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="webmailRadioButton">
<property name="text">
<string>&amp;Send an Invitation by Web Mail Providers</string>
</property>
</widget>
</item>
@ -60,14 +67,14 @@
<widget class="QRadioButton" name="emailRadioButton">
<property name="text">
<string>&amp;Send an Invitation by Email
(She/He receives an email with instructions how to to download RetroShare)</string>
(Your friend will receive an email with instructions how to to download RetroShare)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="friendRecommendationsRadioButton">
<property name="text">
<string>Recommend many friends to each others</string>
<string>Recommend many friends to each other</string>
</property>
</widget>
</item>
@ -271,7 +278,7 @@
<item>
<widget class="QLabel" name="friendCertLabel">
<property name="text">
<string>Please, paste your friends PGP certificate into the box below</string>
<string>Please, paste your friend's PGP certificate into the box below</string>
</property>
</widget>
</item>
@ -504,6 +511,227 @@
</item>
</layout>
</widget>
<widget class="QWizardPage" name="WebmalPage">
<property name="title">
<string>RetroShare is better with Friends </string>
</property>
<property name="subTitle">
<string>Invite your Friends from other Networks to RetroShare.</string>
</property>
<attribute name="pageId">
<string notr="true">ConnectFriendWizard::Page_WebMail</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="gmailButton">
<property name="text">
<string>GMail</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/gmail.png</normaloff>:/icons/gmail.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="yahooButton">
<property name="text">
<string>Yahoo</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/yahoo.png</normaloff>:/icons/yahoo.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="outlookButton">
<property name="text">
<string>Outlook</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/outlook.png</normaloff>:/icons/outlook.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aolButton">
<property name="text">
<string>AOL</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/aol.png</normaloff>:/icons/aol.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="yandexButton">
<property name="text">
<string>Yandex</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/yandex.png</normaloff>:/icons/yandex.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="emailButton">
<property name="text">
<string>Email</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/mail_128.png</normaloff>:/icons/mail_128.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>444</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="ConnectFriendPage" name="EmailPage">
<property name="title">
<string>Invite Friends by Email</string>
@ -883,7 +1111,8 @@
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string>Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add to many friends. You can add as many friends as you like, but more than 40 will probably require too much resources.</string>
<string>Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add too many friends. You can add as many friends as you like, but more than 40 will probably require too much
resources.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -1038,21 +1267,21 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="signersLabel">
<property name="text">
<string>Signers</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QPlainTextEdit" name="signersEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="alreadyRegisteredLabel">
<property name="text">
<string>This peer is already on your friend list. Adding it might just set it's ip address.</string>
@ -1062,6 +1291,20 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="ipLabel">
<property name="text">
<string>IP-Addr:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="ipEdit">
<property name="text">
<string>IP-Address</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -1338,6 +1581,7 @@
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -0,0 +1,559 @@
<RCC>
<qresource prefix="/">
<file>emojione/00A9.png</file>
<file>emojione/00AE.png</file>
<file>emojione/1F525.png</file>
<file>emojione/1F004.png</file>
<file>emojione/1F4AA.png</file>
<file>emojione/1F4AB.png</file>
<file>emojione/1F4AC.png</file>
<file>emojione/1F4AD.png</file>
<file>emojione/1F4AE.png</file>
<file>emojione/1F4AF.png</file>
<file>emojione/1F4A1.png</file>
<file>emojione/1F4A2.png</file>
<file>emojione/1F4A3.png</file>
<file>emojione/1F4A4.png</file>
<file>emojione/1F4A5.png</file>
<file>emojione/1F4A6.png</file>
<file>emojione/1F4A7.png</file>
<file>emojione/1F4A8.png</file>
<file>emojione/1F4A9.png</file>
<file>emojione/1F4C0.png</file>
<file>emojione/1F4C1.png</file>
<file>emojione/1F4C2.png</file>
<file>emojione/1F4C3.png</file>
<file>emojione/1F4C4.png</file>
<file>emojione/1F4C5.png</file>
<file>emojione/1F4C6.png</file>
<file>emojione/1F4C7.png</file>
<file>emojione/1F4C8.png</file>
<file>emojione/1F4C9.png</file>
<file>emojione/1F4CA.png</file>
<file>emojione/1F4CB.png</file>
<file>emojione/1F4CC.png</file>
<file>emojione/1F4CD.png</file>
<file>emojione/1F4CE.png</file>
<file>emojione/1F4CF.png</file>
<file>emojione/1F4D0.png</file>
<file>emojione/1F4D1.png</file>
<file>emojione/1F4D2.png</file>
<file>emojione/1F4D3.png</file>
<file>emojione/1F4D4.png</file>
<file>emojione/1F4D5.png</file>
<file>emojione/1F4D6.png</file>
<file>emojione/1F4D7.png</file>
<file>emojione/1F4D8.png</file>
<file>emojione/1F4D9.png</file>
<file>emojione/1F4DA.png</file>
<file>emojione/1F4DB.png</file>
<file>emojione/1F4DC.png</file>
<file>emojione/1F4DD.png</file>
<file>emojione/1F4DE.png</file>
<file>emojione/1F4DF.png</file>
<file>emojione/1F4E0.png</file>
<file>emojione/1F4E1.png</file>
<file>emojione/1F4E2.png</file>
<file>emojione/1F4E3.png</file>
<file>emojione/1F4E4.png</file>
<file>emojione/1F4E5.png</file>
<file>emojione/1F4E6.png</file>
<file>emojione/1F4E7.png</file>
<file>emojione/1F4E8.png</file>
<file>emojione/1F4E9.png</file>
<file>emojione/1F4EA.png</file>
<file>emojione/1F4EB.png</file>
<file>emojione/1F4EC.png</file>
<file>emojione/1F4ED.png</file>
<file>emojione/1F4EE.png</file>
<file>emojione/1F4EF.png</file>
<file>emojione/1F4F0.png</file>
<file>emojione/1F4F1.png</file>
<file>emojione/1F4F2.png</file>
<file>emojione/1F4F3.png</file>
<file>emojione/1F4F4.png</file>
<file>emojione/1F4F5.png</file>
<file>emojione/1F4F6.png</file>
<file>emojione/1F4F7.png</file>
<file>emojione/1F4F8.png</file>
<file>emojione/1F4F9.png</file>
<file>emojione/1F4FA.png</file>
<file>emojione/1F4FB.png</file>
<file>emojione/1F4FC.png</file>
<file>emojione/1F4FD.png</file>
<file>emojione/1F4FE.png</file>
<file>emojione/1F5E2.png</file>
<file>emojione/1F17E.png</file>
<file>emojione/1F17F.png</file>
<file>emojione/1F18E.png</file>
<file>emojione/1F19A.png</file>
<file>emojione/1F21A.png</file>
<file>emojione/1F22F.png</file>
<file>emojione/1F23A.png</file>
<file>emojione/1F32A.png</file>
<file>emojione/1F32B.png</file>
<file>emojione/1F32C.png</file>
<file>emojione/1F36A.png</file>
<file>emojione/1F37A.png</file>
<file>emojione/1F37B.png</file>
<file>emojione/1F43A.png</file>
<file>emojione/1F43B.png</file>
<file>emojione/1F43C.png</file>
<file>emojione/1F43D.png</file>
<file>emojione/1F43E.png</file>
<file>emojione/1F43F.png</file>
<file>emojione/1F44A.png</file>
<file>emojione/1F44B.png</file>
<file>emojione/1F44C.png</file>
<file>emojione/1F44D.png</file>
<file>emojione/1F44E.png</file>
<file>emojione/1F44F.png</file>
<file>emojione/1F46A.png</file>
<file>emojione/1F46B.png</file>
<file>emojione/1F46C.png</file>
<file>emojione/1F46D.png</file>
<file>emojione/1F46E.png</file>
<file>emojione/1F46F.png</file>
<file>emojione/1F47A.png</file>
<file>emojione/1F47B.png</file>
<file>emojione/1F47C.png</file>
<file>emojione/1F47D.png</file>
<file>emojione/1F47E.png</file>
<file>emojione/1F47F.png</file>
<file>emojione/1F48A.png</file>
<file>emojione/1F48B.png</file>
<file>emojione/1F48C.png</file>
<file>emojione/1F48D.png</file>
<file>emojione/1F48E.png</file>
<file>emojione/1F48F.png</file>
<file>emojione/1F49A.png</file>
<file>emojione/1F49B.png</file>
<file>emojione/1F49C.png</file>
<file>emojione/1F49D.png</file>
<file>emojione/1F49E.png</file>
<file>emojione/1F49F.png</file>
<file>emojione/1F54A.png</file>
<file>emojione/1F60A.png</file>
<file>emojione/1F60B.png</file>
<file>emojione/1F60C.png</file>
<file>emojione/1F60D.png</file>
<file>emojione/1F60E.png</file>
<file>emojione/1F60F.png</file>
<file>emojione/1F61A.png</file>
<file>emojione/1F61B.png</file>
<file>emojione/1F61C.png</file>
<file>emojione/1F61D.png</file>
<file>emojione/1F61E.png</file>
<file>emojione/1F61F.png</file>
<file>emojione/1F62A.png</file>
<file>emojione/1F62B.png</file>
<file>emojione/1F62C.png</file>
<file>emojione/1F62D.png</file>
<file>emojione/1F62E.png</file>
<file>emojione/1F62F.png</file>
<file>emojione/1F63A.png</file>
<file>emojione/1F63B.png</file>
<file>emojione/1F63C.png</file>
<file>emojione/1F63D.png</file>
<file>emojione/1F63E.png</file>
<file>emojione/1F63F.png</file>
<file>emojione/1F64A.png</file>
<file>emojione/1F64B.png</file>
<file>emojione/1F64C.png</file>
<file>emojione/1F64D.png</file>
<file>emojione/1F64E.png</file>
<file>emojione/1F64F.png</file>
<file>emojione/1F68A.png</file>
<file>emojione/1F68B.png</file>
<file>emojione/1F68C.png</file>
<file>emojione/1F68D.png</file>
<file>emojione/1F68E.png</file>
<file>emojione/1F68F.png</file>
<file>emojione/1F69A.png</file>
<file>emojione/1F69B.png</file>
<file>emojione/1F69C.png</file>
<file>emojione/1F69D.png</file>
<file>emojione/1F69E.png</file>
<file>emojione/1F69F.png</file>
<file>emojione/1F170.png</file>
<file>emojione/1F171.png</file>
<file>emojione/1F191.png</file>
<file>emojione/1F192.png</file>
<file>emojione/1F193.png</file>
<file>emojione/1F194.png</file>
<file>emojione/1F195.png</file>
<file>emojione/1F196.png</file>
<file>emojione/1F197.png</file>
<file>emojione/1F198.png</file>
<file>emojione/1F199.png</file>
<file>emojione/1F201.png</file>
<file>emojione/1F202.png</file>
<file>emojione/1F232.png</file>
<file>emojione/1F233.png</file>
<file>emojione/1F234.png</file>
<file>emojione/1F235.png</file>
<file>emojione/1F236.png</file>
<file>emojione/1F237.png</file>
<file>emojione/1F238.png</file>
<file>emojione/1F239.png</file>
<file>emojione/1F250.png</file>
<file>emojione/1F251.png</file>
<file>emojione/1F300.png</file>
<file>emojione/1F301.png</file>
<file>emojione/1F302.png</file>
<file>emojione/1F303.png</file>
<file>emojione/1F304.png</file>
<file>emojione/1F305.png</file>
<file>emojione/1F306.png</file>
<file>emojione/1F307.png</file>
<file>emojione/1F308.png</file>
<file>emojione/1F309.png</file>
<file>emojione/1F310.png</file>
<file>emojione/1F311.png</file>
<file>emojione/1F312.png</file>
<file>emojione/1F313.png</file>
<file>emojione/1F314.png</file>
<file>emojione/1F315.png</file>
<file>emojione/1F316.png</file>
<file>emojione/1F317.png</file>
<file>emojione/1F318.png</file>
<file>emojione/1F319.png</file>
<file>emojione/1F320.png</file>
<file>emojione/1F321.png</file>
<file>emojione/1F327.png</file>
<file>emojione/1F328.png</file>
<file>emojione/1F329.png</file>
<file>emojione/1F330.png</file>
<file>emojione/1F331.png</file>
<file>emojione/1F332.png</file>
<file>emojione/1F333.png</file>
<file>emojione/1F334.png</file>
<file>emojione/1F335.png</file>
<file>emojione/1F336.png</file>
<file>emojione/1F337.png</file>
<file>emojione/1F338.png</file>
<file>emojione/1F339.png</file>
<file>emojione/1F340.png</file>
<file>emojione/1F341.png</file>
<file>emojione/1F342.png</file>
<file>emojione/1F343.png</file>
<file>emojione/1F344.png</file>
<file>emojione/1F345.png</file>
<file>emojione/1F346.png</file>
<file>emojione/1F347.png</file>
<file>emojione/1F348.png</file>
<file>emojione/1F349.png</file>
<file>emojione/1F350.png</file>
<file>emojione/1F351.png</file>
<file>emojione/1F352.png</file>
<file>emojione/1F353.png</file>
<file>emojione/1F354.png</file>
<file>emojione/1F355.png</file>
<file>emojione/1F356.png</file>
<file>emojione/1F357.png</file>
<file>emojione/1F358.png</file>
<file>emojione/1F359.png</file>
<file>emojione/1F360.png</file>
<file>emojione/1F361.png</file>
<file>emojione/1F362.png</file>
<file>emojione/1F363.png</file>
<file>emojione/1F364.png</file>
<file>emojione/1F365.png</file>
<file>emojione/1F366.png</file>
<file>emojione/1F367.png</file>
<file>emojione/1F368.png</file>
<file>emojione/1F369.png</file>
<file>emojione/1F370.png</file>
<file>emojione/1F371.png</file>
<file>emojione/1F372.png</file>
<file>emojione/1F373.png</file>
<file>emojione/1F374.png</file>
<file>emojione/1F375.png</file>
<file>emojione/1F376.png</file>
<file>emojione/1F377.png</file>
<file>emojione/1F378.png</file>
<file>emojione/1F379.png</file>
<file>emojione/1F380.png</file>
<file>emojione/1F381.png</file>
<file>emojione/1F382.png</file>
<file>emojione/1F383.png</file>
<file>emojione/1F384.png</file>
<file>emojione/1F385.png</file>
<file>emojione/1F386.png</file>
<file>emojione/1F387.png</file>
<file>emojione/1F388.png</file>
<file>emojione/1F389.png</file>
<file>emojione/1F390.png</file>
<file>emojione/1F391.png</file>
<file>emojione/1F392.png</file>
<file>emojione/1F393.png</file>
<file>emojione/1F394.png</file>
<file>emojione/1F395.png</file>
<file>emojione/1F396.png</file>
<file>emojione/1F397.png</file>
<file>emojione/1F398.png</file>
<file>emojione/1F399.png</file>
<file>emojione/1F400.png</file>
<file>emojione/1F401.png</file>
<file>emojione/1F402.png</file>
<file>emojione/1F403.png</file>
<file>emojione/1F404.png</file>
<file>emojione/1F405.png</file>
<file>emojione/1F406.png</file>
<file>emojione/1F407.png</file>
<file>emojione/1F408.png</file>
<file>emojione/1F409.png</file>
<file>emojione/1F410.png</file>
<file>emojione/1F411.png</file>
<file>emojione/1F412.png</file>
<file>emojione/1F413.png</file>
<file>emojione/1F414.png</file>
<file>emojione/1F415.png</file>
<file>emojione/1F416.png</file>
<file>emojione/1F417.png</file>
<file>emojione/1F418.png</file>
<file>emojione/1F419.png</file>
<file>emojione/1F420.png</file>
<file>emojione/1F421.png</file>
<file>emojione/1F422.png</file>
<file>emojione/1F423.png</file>
<file>emojione/1F424.png</file>
<file>emojione/1F425.png</file>
<file>emojione/1F426.png</file>
<file>emojione/1F427.png</file>
<file>emojione/1F428.png</file>
<file>emojione/1F429.png</file>
<file>emojione/1F430.png</file>
<file>emojione/1F431.png</file>
<file>emojione/1F432.png</file>
<file>emojione/1F433.png</file>
<file>emojione/1F434.png</file>
<file>emojione/1F435.png</file>
<file>emojione/1F436.png</file>
<file>emojione/1F437.png</file>
<file>emojione/1F438.png</file>
<file>emojione/1F439.png</file>
<file>emojione/1F440.png</file>
<file>emojione/1F441.png</file>
<file>emojione/1F442.png</file>
<file>emojione/1F443.png</file>
<file>emojione/1F444.png</file>
<file>emojione/1F445.png</file>
<file>emojione/1F446.png</file>
<file>emojione/1F447.png</file>
<file>emojione/1F448.png</file>
<file>emojione/1F449.png</file>
<file>emojione/1F450.png</file>
<file>emojione/1F451.png</file>
<file>emojione/1F452.png</file>
<file>emojione/1F453.png</file>
<file>emojione/1F454.png</file>
<file>emojione/1F455.png</file>
<file>emojione/1F456.png</file>
<file>emojione/1F457.png</file>
<file>emojione/1F458.png</file>
<file>emojione/1F459.png</file>
<file>emojione/1F460.png</file>
<file>emojione/1F461.png</file>
<file>emojione/1F462.png</file>
<file>emojione/1F463.png</file>
<file>emojione/1F464.png</file>
<file>emojione/1F465.png</file>
<file>emojione/1F466.png</file>
<file>emojione/1F467.png</file>
<file>emojione/1F468.png</file>
<file>emojione/1F469.png</file>
<file>emojione/1F470.png</file>
<file>emojione/1F471.png</file>
<file>emojione/1F472.png</file>
<file>emojione/1F473.png</file>
<file>emojione/1F474.png</file>
<file>emojione/1F475.png</file>
<file>emojione/1F476.png</file>
<file>emojione/1F477.png</file>
<file>emojione/1F478.png</file>
<file>emojione/1F479.png</file>
<file>emojione/1F480.png</file>
<file>emojione/1F481.png</file>
<file>emojione/1F482.png</file>
<file>emojione/1F483.png</file>
<file>emojione/1F484.png</file>
<file>emojione/1F485.png</file>
<file>emojione/1F486.png</file>
<file>emojione/1F487.png</file>
<file>emojione/1F488.png</file>
<file>emojione/1F489.png</file>
<file>emojione/1F490.png</file>
<file>emojione/1F491.png</file>
<file>emojione/1F492.png</file>
<file>emojione/1F493.png</file>
<file>emojione/1F494.png</file>
<file>emojione/1F495.png</file>
<file>emojione/1F496.png</file>
<file>emojione/1F497.png</file>
<file>emojione/1F498.png</file>
<file>emojione/1F499.png</file>
<file>emojione/1F574.png</file>
<file>emojione/1F575.png</file>
<file>emojione/1F595.png</file>
<file>emojione/1F596.png</file>
<file>emojione/1F597.png</file>
<file>emojione/1F598.png</file>
<file>emojione/1F599.png</file>
<file>emojione/1F600.png</file>
<file>emojione/1F601.png</file>
<file>emojione/1F602.png</file>
<file>emojione/1F603.png</file>
<file>emojione/1F604.png</file>
<file>emojione/1F605.png</file>
<file>emojione/1F606.png</file>
<file>emojione/1F607.png</file>
<file>emojione/1F608.png</file>
<file>emojione/1F609.png</file>
<file>emojione/1F610.png</file>
<file>emojione/1F611.png</file>
<file>emojione/1F612.png</file>
<file>emojione/1F613.png</file>
<file>emojione/1F614.png</file>
<file>emojione/1F615.png</file>
<file>emojione/1F616.png</file>
<file>emojione/1F617.png</file>
<file>emojione/1F618.png</file>
<file>emojione/1F619.png</file>
<file>emojione/1F620.png</file>
<file>emojione/1F621.png</file>
<file>emojione/1F622.png</file>
<file>emojione/1F623.png</file>
<file>emojione/1F624.png</file>
<file>emojione/1F625.png</file>
<file>emojione/1F626.png</file>
<file>emojione/1F627.png</file>
<file>emojione/1F628.png</file>
<file>emojione/1F629.png</file>
<file>emojione/1F630.png</file>
<file>emojione/1F631.png</file>
<file>emojione/1F632.png</file>
<file>emojione/1F633.png</file>
<file>emojione/1F634.png</file>
<file>emojione/1F635.png</file>
<file>emojione/1F636.png</file>
<file>emojione/1F637.png</file>
<file>emojione/1F638.png</file>
<file>emojione/1F639.png</file>
<file>emojione/1F640.png</file>
<file>emojione/1F641.png</file>
<file>emojione/1F642.png</file>
<file>emojione/1F645.png</file>
<file>emojione/1F646.png</file>
<file>emojione/1F647.png</file>
<file>emojione/1F648.png</file>
<file>emojione/1F649.png</file>
<file>emojione/1F680.png</file>
<file>emojione/1F681.png</file>
<file>emojione/1F682.png</file>
<file>emojione/1F683.png</file>
<file>emojione/1F684.png</file>
<file>emojione/1F685.png</file>
<file>emojione/1F686.png</file>
<file>emojione/1F687.png</file>
<file>emojione/1F688.png</file>
<file>emojione/1F689.png</file>
<file>emojione/1F690.png</file>
<file>emojione/1F691.png</file>
<file>emojione/1F692.png</file>
<file>emojione/1F693.png</file>
<file>emojione/1F694.png</file>
<file>emojione/1F695.png</file>
<file>emojione/1F696.png</file>
<file>emojione/1F697.png</file>
<file>emojione/1F698.png</file>
<file>emojione/1F699.png</file>
<file>emojione/2B1B.png</file>
<file>emojione/2B1C.png</file>
<file>emojione/2B05.png</file>
<file>emojione/2B06.png</file>
<file>emojione/2B07.png</file>
<file>emojione/2B50.png</file>
<file>emojione/2B55.png</file>
<file>emojione/21A9.png</file>
<file>emojione/21AA.png</file>
<file>emojione/23E9.png</file>
<file>emojione/23EA.png</file>
<file>emojione/23EB.png</file>
<file>emojione/23EC.png</file>
<file>emojione/23F0.png</file>
<file>emojione/23F3.png</file>
<file>emojione/24C2.png</file>
<file>emojione/25AA.png</file>
<file>emojione/25AB.png</file>
<file>emojione/25B6.png</file>
<file>emojione/25C0.png</file>
<file>emojione/25FB.png</file>
<file>emojione/25FC.png</file>
<file>emojione/25FD.png</file>
<file>emojione/25FE.png</file>
<file>emojione/26A0.png</file>
<file>emojione/26A1.png</file>
<file>emojione/26AA.png</file>
<file>emojione/26AB.png</file>
<file>emojione/26BD.png</file>
<file>emojione/26BE.png</file>
<file>emojione/26C4.png</file>
<file>emojione/26C5.png</file>
<file>emojione/26CE.png</file>
<file>emojione/26D4.png</file>
<file>emojione/26EA.png</file>
<file>emojione/26F2.png</file>
<file>emojione/26F3.png</file>
<file>emojione/26F5.png</file>
<file>emojione/26FA.png</file>
<file>emojione/26FD.png</file>
<file>emojione/27A1.png</file>
<file>emojione/27B0.png</file>
<file>emojione/27BF.png</file>
<file>emojione/203C.png</file>
<file>emojione/231A.png</file>
<file>emojione/231B.png</file>
<file>emojione/260E.png</file>
<file>emojione/261D.png</file>
<file>emojione/263A.png</file>
<file>emojione/264A.png</file>
<file>emojione/264B.png</file>
<file>emojione/264C.png</file>
<file>emojione/264D.png</file>
<file>emojione/264E.png</file>
<file>emojione/264F.png</file>
<file>emojione/267B.png</file>
<file>emojione/267F.png</file>
<file>emojione/270A.png</file>
<file>emojione/270B.png</file>
<file>emojione/270C.png</file>
<file>emojione/270F.png</file>
<file>emojione/274C.png</file>
<file>emojione/274E.png</file>
<file>emojione/303D.png</file>
<file>emojione/2049.png</file>
<file>emojione/2600.png</file>
<file>emojione/2601.png</file>
<file>emojione/2611.png</file>
<file>emojione/2614.png</file>
<file>emojione/2615.png</file>
<file>emojione/2708.png</file>
<file>emojione/2744.png</file>
<file>emojione/2764.png</file>
<file>emojione/2934.png</file>
<file>emojione/2935.png</file>
<file>emojione/3030.png</file>
<file>emojione/3297.png</file>
<file>emojione/3299.png</file>
<file>emojione/1f910.png</file>
<file>emojione/1f911.png</file>
<file>emojione/1f912.png</file>
<file>emojione/1f913.png</file>
<file>emojione/1f914.png</file>
<file>emojione/1f915.png</file>
<file>emojione/1f916.png</file>
<file>emojione/1f643.png</file>
<file>emojione/emotes.acs</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show more