Merge pull request #43 from hunbernd/New-Posted-Card-View

New posted card view
This commit is contained in:
defnax 2020-01-05 21:09:10 +01:00 committed by GitHub
commit 99aca410a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 193 additions and 47 deletions

View File

@ -65,12 +65,14 @@ class Reputation
{
public:
Reputation() :
mOwnOpinion(static_cast<int32_t>(RsOpinion::NEUTRAL)), mOwnOpinionTs(0),
mOwnOpinion(static_cast<int32_t>(RsOpinion::NEUTRAL)),
mOwnOpinionTs(0),
mFriendAverage(1.0f),
/* G10h4ck: TODO shouln't this be initialized with
* RsReputation::NEUTRAL or UNKOWN? */
mReputationScore(static_cast<float>(RsOpinion::NEUTRAL)),
mIdentityFlags(0) {}
mFriendsPositive(0),
mFriendsNegative(0),
mReputationScore(1.0f),
mIdentityFlags(0),
mLastUsedTS(0) {}
void updateReputation();

View File

@ -242,7 +242,7 @@ void GenCertDialog::initKeyList()
RsAccounts::GetPGPLoginDetails(*it, name, email);
std::cerr << "Adding PGPUser: " << name << " id: " << *it << std::endl;
QString gid = QString::fromStdString( (*it).toStdString()).right(8) ;
ui.genPGPuser->addItem(QString::fromUtf8(name.c_str()) + " <" + QString::fromUtf8(email.c_str()) + "> (" + gid + ")", userData);
ui.genPGPuser->addItem(QString::fromUtf8(name.c_str()) + " (" + gid + ")", userData);
haveGPGKeys = true;
}
}
@ -294,7 +294,8 @@ void GenCertDialog::setupState()
ui.reuse_existing_node_CB->setEnabled(adv_state) ;
ui.importIdentity_PB->setVisible(adv_state && !generate_new) ;
ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ;
//ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ;
ui.exportIdentity_PB->setVisible(false); // not useful, and probably confusing
ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ;
@ -317,6 +318,11 @@ void GenCertDialog::setupState()
ui.password_input->setVisible(true);
ui.password_label->setVisible(true);
if(generate_new)
ui.password_input->setToolTip(tr("<html><p>Put a strong password here. This password will be required to start your Retroshare node and protects all your data.</p></html>"));
else
ui.password_input->setToolTip(tr("<html><p>Please supply the existing password for the selected profile above.</p></html>"));
ui.password2_check_LB->setVisible(generate_new);
ui.password2_input->setVisible(generate_new);
ui.password2_label->setVisible(generate_new);
@ -468,7 +474,10 @@ bool GenCertDialog::importIdentity()
RsAccounts::GetPGPLoginDetails(gpg_id, name, email);
std::cerr << "Adding PGPUser: " << name << " id: " << gpg_id << std::endl;
QMessageBox::information(this,tr("New profile imported"),tr("Your profile was imported successfully:")+" \n"+"\nName :"+QString::fromStdString(name)+"\nemail: " + QString::fromStdString(email)+"\nKey ID: "+QString::fromStdString(gpg_id.toStdString())+"\n\n"+tr("You can use it now to create a new node.")) ;
QMessageBox::information(this,tr("New profile imported"),tr("Your profile was imported successfully:")+" \n"+"\nName :"+QString::fromStdString(name)+"\nKey ID: "+QString::fromStdString(gpg_id.toStdString())+"\n\n"+tr("You can use it now to create a new node.")) ;
initKeyList();
setupState();
return true ;
}

View File

@ -62,6 +62,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos
ui->hashBox->setAutoHide(true);
ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING);
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
ui->sizeWarningLabel->setText(QString("Post size is limited to %1 KB, pictures will be downscaled.").arg(MAXMESSAGESIZE / 1024));
/* fill in the available OwnIds for signing */
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
@ -189,7 +190,7 @@ void PostedCreatePostDialog::addPicture()
}
QImage opt;
if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 1000)) { //Leave space for other stuff
if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff
ui->imageLabel->setPixmap(QPixmap::fromImage(opt));
} else {
imagefilename = "";

View File

@ -47,7 +47,7 @@ public:
private:
QString imagefilename;
QByteArray imagebytes;
const int MAXMESSAGESIZE = 32000;
const int MAXMESSAGESIZE = 199000;
private slots:
void createPost();

View File

@ -187,7 +187,7 @@
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<widget class="QLabel" name="sizeWarningLabel">
<property name="text">
<string>Post size is limited to 32 KB, pictures will be downscaled.</string>
</property>

View File

@ -32,6 +32,7 @@
#include <QTextStream>
#include <QTimer>
#include <QToolTip>
#include <QInputDialog>
#include "ChatWidget.h"
#include "ui_ChatWidget.h"
@ -163,6 +164,7 @@ ChatWidget::ChatWidget(QWidget *parent)
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
connect(ui->actionDropPlacemark, SIGNAL(triggered()), this, SLOT(dropPlacemark()));
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
connect(ui->actionImport_sticker, SIGNAL(triggered()), this, SLOT(saveSticker()));
connect(ui->actionShow_Hidden_Images, SIGNAL(triggered()), ui->textBrowser, SLOT(showImages()));
ui->actionShow_Hidden_Images->setIcon(ui->textBrowser->getBlockedImage());
@ -438,6 +440,7 @@ void ChatWidget::blockSending(QString msg)
#ifndef RS_ASYNC_CHAT
// sendingBlocked = true;
// ui->sendButton->setEnabled(false);
// ui->stickerButton->setEnabled(false);
#endif
ui->sendButton->setToolTip(msg);
}
@ -445,6 +448,7 @@ void ChatWidget::blockSending(QString msg)
void ChatWidget::unblockSending()
{
sendingBlocked = false;
ui->stickerButton->setEnabled(true);
updateLenOfChatTextEdit();
}
@ -1128,7 +1132,9 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addAction(ui->actionShow_Hidden_Images);
ui->actionSave_image->setData(point);
ui->actionImport_sticker->setData(point);
contextMnu->addAction(ui->actionSave_image);
contextMnu->addAction(ui->actionImport_sticker);
}
QString anchor = ui->textBrowser->anchorForPosition(point);
@ -1556,6 +1562,7 @@ void ChatWidget::stickerWidget()
void ChatWidget::sendSticker()
{
if(sendingBlocked) return;
QString sticker = qobject_cast<QPushButton*>(sender())->statusTip();
QString encodedImage;
if (RsHtml::makeEmbeddedImage(sticker, encodedImage, 640*480, maxMessageSize() - 200)) { //-200 for the html stuff
@ -1910,3 +1917,13 @@ void ChatWidget::saveImage()
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
ImageUtil::extractImage(window(), cursor);
}
void ChatWidget::saveSticker()
{
QPoint point = ui->actionImport_sticker->data().toPoint();
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
QString filename = QInputDialog::getText(window(), "Import sticker", "Sticker name");
if(filename.isEmpty()) return;
filename = Emoticons::importedStickerPath() + "/" + filename + ".png";
ImageUtil::extractImage(window(), cursor, filename);
}

View File

@ -194,6 +194,7 @@ private slots:
void quote();
void dropPlacemark();
void saveImage();
void saveSticker();
private:
bool findText(const QString& qsStringToFind);

View File

@ -389,7 +389,7 @@ border-image: url(:/images/closepressed.png)
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/new.png</normaloff>:/icons/png/new.png</iconset>
<normaloff>:/icons/png/addstickers.png</normaloff>:/icons/png/addstickers.png</iconset>
</property>
<property name="iconSize">
<size>
@ -981,6 +981,15 @@ border-image: url(:/images/closepressed.png)
<string>Save image</string>
</property>
</action>
<action name="actionImport_sticker">
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/icons/png/addstickers.png</normaloff>:/icons/png/addstickers.png</iconset>
</property>
<property name="text">
<string>Import sticker</string>
</property>
</action>
<action name="actionSendAsPlainText">
<property name="checkable">
<bool>true</bool>

View File

@ -29,6 +29,7 @@
#include <QTabWidget>
#include <QWidget>
#include <QMessageBox>
#include <QDir>
#include <iostream>
#include <math.h>
@ -41,17 +42,21 @@
static QHash<QString, QPair<QVector<QString>, QHash<QString, QString> > > Smileys;
static QVector<QString> grpOrdered;
static QVector<QString > StickerGroups;
static QStringList filters;
static QStringList stickerFolders;
static QHash<QString, QString> tooltipcache;
static QHash<QString, QPixmap> iconcache;
void Emoticons::load()
{
loadSmiley();
filters << "*.png" << "*.jpg" << "*.gif";
loadSticker(QString::fromStdString(RsAccounts::ConfigDirectory()) + "/stickers"); //under .retroshare, shared between users
loadSticker(QString::fromStdString(RsAccounts::AccountDirectory()) + "/stickers"); //under account, unique for user
loadSticker(QString::fromStdString(RsAccounts::systemDataDirectory()) + "/stickers"); //exe's folder, shipped with RS
stickerFolders << (QString::fromStdString(RsAccounts::AccountDirectory()) + "/stickers"); //under account, unique for user
stickerFolders << (QString::fromStdString(RsAccounts::ConfigDirectory()) + "/stickers"); //under .retroshare, shared between users
stickerFolders << (QString::fromStdString(RsAccounts::systemDataDirectory()) + "/stickers"); //exe's folder, shipped with RS
QDir dir(QString::fromStdString(RsAccounts::AccountDirectory()));
dir.mkpath("stickers/imported");
}
void Emoticons::loadSmiley()
@ -285,7 +290,13 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s
smWidget->show() ;
}
void Emoticons::loadSticker(QString foldername)
void Emoticons::refreshStickerTabs(QVector<QString>& stickerTabs)
{
for(int i = 0; i < stickerFolders.count(); ++i)
refreshStickerTabs(stickerTabs, stickerFolders[i]);
}
void Emoticons::refreshStickerTabs(QVector<QString>& stickerTabs, QString foldername)
{
QDir dir(foldername);
if(!dir.exists()) return;
@ -293,25 +304,30 @@ void Emoticons::loadSticker(QString foldername)
//If it contains at a least one png then add it as a group
QStringList files = dir.entryList(filters, QDir::Files);
if(files.count() > 0)
StickerGroups.append(foldername);
stickerTabs.append(foldername);
//Check subfolders
QFileInfoList subfolders = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
for(int i = 0; i<subfolders.length(); i++)
loadSticker(subfolders[i].filePath());
refreshStickerTabs(stickerTabs, subfolders[i].filePath());
}
void Emoticons::showStickerWidget(QWidget *parent, QWidget *button, const char *slotAddMethod, bool above)
{
QVector<QString> stickerTabs;
refreshStickerTabs(stickerTabs);
if(stickerTabs.count() == 0) {
QString message = "No stickers installed.\nYou can install them by putting images into one of these folders:\n" + stickerFolders.join('\n');
QMessageBox::warning(parent, "Stickers", message);
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
QWidget *smWidget = new QWidget(parent, Qt::Popup) ;
smWidget->setAttribute(Qt::WA_DeleteOnClose) ;
smWidget->setWindowTitle("Stickers") ;
if(StickerGroups.count() == 0) {
QMessageBox::warning(parent, "Stickers", "No stickers installed");
return;
}
bool bOnlyOneGroup = (StickerGroups.count() == 1);
bool bOnlyOneGroup = (stickerTabs.count() == 1);
QTabWidget *smTab = nullptr;
if (! bOnlyOneGroup)
@ -327,7 +343,7 @@ void Emoticons::showStickerWidget(QWidget *parent, QWidget *button, const char *
int maxRowCount = 0;
int maxCountPerLine = 0;
QVectorIterator<QString> grp(StickerGroups);
QVectorIterator<QString> grp(stickerTabs);
while(grp.hasNext())
{
QDir groupDir = QDir(grp.next());
@ -383,7 +399,11 @@ void Emoticons::showStickerWidget(QWidget *parent, QWidget *button, const char *
QPushButton *button = new QPushButton("", tabGrpWidget);
button->setIconSize(QSize(buttonWidth, buttonHeight));
button->setFixedSize(QSize(buttonWidth, buttonHeight));
button->setIcon(QPixmap(fi.absoluteFilePath()));
if(!iconcache.contains(fi.absoluteFilePath()))
{
iconcache.insert(fi.absoluteFilePath(), QPixmap(fi.absoluteFilePath()).scaled(buttonWidth, buttonHeight, Qt::KeepAspectRatio));
}
button->setIcon(iconcache[fi.absoluteFilePath()]);
button->setToolTip(fi.fileName());
button->setStatusTip(fi.absoluteFilePath());
button->setStyleSheet("QPushButton:hover {border: 3px solid #0099cc; border-radius: 3px;}");
@ -444,10 +464,18 @@ void Emoticons::showStickerWidget(QWidget *parent, QWidget *button, const char *
smWidget->move(x, y);
smWidget->show();
QApplication::restoreOverrideCursor();
}
QString Emoticons::importedStickerPath()
{
QDir dir(stickerFolders[0]);
return dir.absoluteFilePath("imported");
}
void Emoticons::loadToolTips(QWidget *container)
{
QApplication::setOverrideCursor(Qt::WaitCursor);
QList<QPushButton *> children = container->findChildren<QPushButton *>();
for(int i = 0; i < children.length(); ++i) {
if(!children[i]->toolTip().contains('<')) {
@ -464,4 +492,5 @@ void Emoticons::loadToolTips(QWidget *container)
}
}
QApplication::restoreOverrideCursor();
}

View File

@ -21,6 +21,8 @@
#ifndef _EMOTICONS_H
#define _EMOTICONS_H
#include <QVector>
class QWidget;
class QString;
@ -28,14 +30,15 @@ class Emoticons
{
public:
static void load();
static void loadSmiley();
static void loadSticker(QString foldername);
static void showSmileyWidget(QWidget *parent, QWidget *button, const char *slotAddMethod, bool above);
static void showStickerWidget(QWidget *parent, QWidget *button, const char *slotAddMethod, bool above);
static QString importedStickerPath();
private:
static void loadToolTips(QWidget *container);
static void loadSmiley();
static void refreshStickerTabs(QVector<QString>& stickerTabs, QString foldername);
static void refreshStickerTabs(QVector<QString>& stickerTabs);
};
#endif

View File

@ -306,11 +306,15 @@ QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail,bo
infotext += "<UL>" ;
if(use_short_format)
{
infotext += "<li> a <b>Profile fingerprint</b>";
infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.fpr.toStdString().c_str()+") " ;
}
else
infotext += "<li> a <b>Profile key</b>";
infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ;
{
infotext += "<li> a <b>Profile public key</b>";
infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ;
}
if(signatures_included && !use_short_format)
infotext += tr("with")+" "+QString::number(detail.gpgSigners.size()-1)+" "+tr("external signatures</li>") ;

View File

@ -290,6 +290,8 @@
<file>icons/png/bandwidth.png</file>
<file>icons/png/options2.png</file>
<file>icons/png/exit2.png</file>
<file>icons/svg/addstickers.svg</file>
<file>icons/png/addstickers.png</file>
<file>icons/textedit/bold.png</file>
<file>icons/textedit/bullet-list.png</file>
<file>icons/textedit/italic.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4155"
version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
xml:space="preserve"
width="128"
height="128"
viewBox="0 0 128 128"
sodipodi:docname="addstickers.svg"><metadata
id="metadata4161"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs4159" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1152"
inkscape:window-height="801"
id="namedview4157"
showgrid="false"
inkscape:zoom="3.6195028"
inkscape:cx="53.669069"
inkscape:cy="71.112562"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g4163" /><g
id="g4163"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,0,128)"><path
inkscape:connector-curvature="0"
id="path4167"
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60304987"
d="m 102.81622,51.518623 c 0,-28.330702 -22.966895,-51.29759817 -51.297597,-51.29759817 -28.330702,0 -51.29759817,22.96689617 -51.29759817,51.29759817 0,28.330702 22.96689617,51.297597 51.29759817,51.297597 28.330702,0 51.297597,-22.966895 51.297597,-51.297597" /><g
id="g835"
transform="matrix(0.16426573,0,0,-0.1695986,9.5806414,96.195902)"><g
id="g833"><g
id="g831"><path
d="m 511.653,195.545 h 0.018 C 500.227,149.939 477.629,109.379 443.689,76.275 V 76.178 C 394.902,27.098 329.298,0.021 259.891,0.021 190.485,0.021 125.202,27.026 76.122,76.107 27.043,125.186 0,190.427 0,259.834 c 0,69.407 27.474,134.654 76.554,183.735 33.107,33.106 74.409,56.647 120.015,68.089 v -0.017 c 0,0.22 1.288,0.338 2.158,0.338 2.776,0 5.26,-1.09 7.275,-3.107 L 509,205.71 c 2.647,-2.648 3.575,-6.983 2.653,-10.165 z m -331.684,243.559 -0.021,-0.051 c -21.899,-9.701 -41.643,-23.277 -58.851,-40.485 -76.502,-76.501 -76.502,-200.981 0,-277.483 38.255,-38.256 88.49,-57.377 138.742,-57.377 50.239,0 100.495,19.13 138.741,57.377 17.209,17.209 30.783,36.953 40.485,58.852 l 0.072,0.021 c -68.393,0.168 -134.341,27.402 -183.049,76.118 -48.713,48.703 -75.946,114.652 -76.119,183.028 z m 24.612,40.963 c -1.461,-8.557 -2.461,-17.209 -2.983,-25.878 -4.137,-68.081 21.19,-134.824 69.491,-183.115 44.875,-44.884 105.674,-69.928 168.688,-69.928 4.797,0 9.615,0.145 14.433,0.439 8.665,0.523 17.315,1.522 25.873,2.984 z M 462.426,180.93 c -10.888,-28.139 -27.292,-53.294 -48.845,-74.847 -84.775,-84.774 -222.71,-84.771 -307.483,0 -84.772,84.773 -84.772,222.709 0,307.482 21.554,21.552 46.709,37.957 74.848,48.846 0.695,7.955 1.75,15.883 3.17,23.732 C 149.239,474.489 117.347,454.814 91.096,428.561 46.021,383.49 21.198,323.564 21.198,259.822 c 0,-63.742 24.823,-123.667 69.896,-168.741 45.074,-45.074 105,-69.897 168.741,-69.897 63.742,0 123.669,24.823 168.742,69.896 26.251,26.251 45.926,58.144 57.582,93.02 -7.851,-1.421 -15.779,-2.476 -23.733,-3.17 z"
data-original="#000000"
class="active-path"
data-old_color="#000000"
id="path829"
inkscape:connector-curvature="0"
style="fill:#fffcfc" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -14,7 +14,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -541,7 +541,7 @@
<item row="0" column="0">
<widget class="QPlainTextEdit" name="certplainTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -569,6 +569,9 @@
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="_includeSignatures_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option includes all signatures of your profile key. Signatures are not mandatory, but only a way to express your trust in some particular profile.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Include signatures</string>
</property>
@ -576,6 +579,9 @@
</item>
<item>
<widget class="QCheckBox" name="_shortFormat_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The short format only contains the profile fingerprint, and authentication is based on the node ID (ID of the SSL key). If you choose the old (long) format, the certificate includes the full profile public key. There is no fundamental difference between making friends with either method, because the public profile keys will be exchanged and checked w.r.t. the fingerprint after connection.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Short format</string>
</property>
@ -601,7 +607,7 @@
<item>
<widget class="QPushButton" name="saveButton">
<property name="toolTip">
<string>Save Key into a file</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Saves your profile key pair into a file. This allows you to create a new node for the same profile, by importing this key pair on a different computer. Friends who already accept connections from you will automatically accept connections from that new node after you add them yourself. Your key is exported encrypted and you will need your login password to create a new profile.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Save certificate to file</string>

View File

@ -37,7 +37,7 @@
ImageUtil::ImageUtil() {}
void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file)
{
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
@ -52,13 +52,13 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
QImage image = QImage::fromData(ba);
if(!image.isNull())
{
QString file;
success = true;
if(misc::getSaveFileName(window, RshareSettings::LASTDIR_IMAGES, "Save Picture File", "Pictures (*.png *.xpm *.jpg)", file))
if(!file.isEmpty() || misc::getSaveFileName(window, RshareSettings::LASTDIR_IMAGES, "Save Picture File", "Pictures (*.png *.xpm *.jpg)", file))
{
if(!image.save(file, 0, 100))
if(!image.save(file + ".png", 0, 100))
QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Cannot save the image, invalid filename"));
if(!image.save(file, nullptr, 100))
if(!image.save(file + ".png", nullptr, 100))
QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Cannot save the image, invalid filename")
+ "\n" + file);
}
}
}
@ -73,14 +73,12 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original,
//nothing to do if it fits into the limits
optimized = original;
if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) {
if(checkSize(bytearray, optimized) <= maxBytes) {
int s = checkSize(bytearray, optimized);
if((maxBytes <= 0) || (s <= maxBytes)) {
return true;
}
}
QVector<QRgb> ct;
quantization(original, ct);
//Downscale the image to fit into maxPixels
double whratio = (qreal)original.width() / (qreal)original.height();
int maxwidth;
@ -98,6 +96,9 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original,
return true;
}
QVector<QRgb> ct;
quantization(original, ct);
//Use binary search to find a suitable image size + linear regression to guess the file size
double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither));
if(maxsize <= maxBytes) return true; //success
@ -141,6 +142,7 @@ bool ImageUtil::optimizeSizeHtml(QString &html, const QImage& original, QImage &
QByteArray bytearray;
if(maxBytes > 0){
maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff
if(maxBytes < 1) maxBytes = 1;
}
if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes))
@ -169,7 +171,7 @@ int ImageUtil::checkSize(QByteArray &bytearray, const QImage &img)
} else {
std::cerr << "ImageUtil: image can't be saved to buffer" << std::endl;
}
buffer.close();
buffer.close();
} else {
std::cerr << "ImageUtil: buffer can't be opened" << std::endl;
}

View File

@ -31,7 +31,7 @@ class ImageUtil
public:
ImageUtil();
static void extractImage(QWidget *window, QTextCursor cursor);
static void extractImage(QWidget *window, QTextCursor cursor, QString file = "");
static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);
static bool optimizeSizeBytes(QByteArray &bytearray, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);