Fixed ID Details Dialog with Reputation

This commit is contained in:
defnax 2015-10-13 02:18:41 +02:00
parent 58bd186c23
commit 791f5fe886
3 changed files with 245 additions and 270 deletions

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
*****/
@ -52,18 +54,9 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
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->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);
@ -72,10 +65,6 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
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);
@ -83,10 +72,8 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
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);
@ -98,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();
}
@ -141,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!");
@ -242,81 +227,110 @@ 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);
@ -342,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) {
@ -359,6 +399,10 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r
insertIdDetails(req.mToken);
break;
case IDDETAILSDIALOG_REPLIST:
insertRepList(req.mToken);
break;
default:
std::cerr << "IdDetailsDialog::loadRequest() ERROR";
std::cerr << std::endl;

View File

@ -46,10 +46,16 @@ 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;
TokenQueue *mIdQueue;

View File

@ -200,25 +200,8 @@
</property>
</widget>
</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">
@ -233,7 +216,90 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<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>
@ -242,164 +308,23 @@
</font>
</property>
<property name="text">
<string>Overall</string>
<string>Overall:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="line_RatingOverall">
<property name="readOnly">
<bool>true</bool>
</property>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Implicit</string>
</property>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="line_RatingImplicit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</layout>
</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>
@ -412,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>