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

View File

@ -242,7 +242,7 @@ void GenCertDialog::initKeyList()
RsAccounts::GetPGPLoginDetails(*it, name, email); RsAccounts::GetPGPLoginDetails(*it, name, email);
std::cerr << "Adding PGPUser: " << name << " id: " << *it << std::endl; std::cerr << "Adding PGPUser: " << name << " id: " << *it << std::endl;
QString gid = QString::fromStdString( (*it).toStdString()).right(8) ; 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; haveGPGKeys = true;
} }
} }
@ -294,7 +294,8 @@ void GenCertDialog::setupState()
ui.reuse_existing_node_CB->setEnabled(adv_state) ; ui.reuse_existing_node_CB->setEnabled(adv_state) ;
ui.importIdentity_PB->setVisible(adv_state && !generate_new) ; 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) ; ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ;
@ -317,6 +318,11 @@ void GenCertDialog::setupState()
ui.password_input->setVisible(true); ui.password_input->setVisible(true);
ui.password_label->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_check_LB->setVisible(generate_new);
ui.password2_input->setVisible(generate_new); ui.password2_input->setVisible(generate_new);
ui.password2_label->setVisible(generate_new); ui.password2_label->setVisible(generate_new);
@ -468,7 +474,10 @@ bool GenCertDialog::importIdentity()
RsAccounts::GetPGPLoginDetails(gpg_id, name, email); RsAccounts::GetPGPLoginDetails(gpg_id, name, email);
std::cerr << "Adding PGPUser: " << name << " id: " << gpg_id << std::endl; 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 ; return true ;
} }

View File

@ -62,6 +62,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos
ui->hashBox->setAutoHide(true); ui->hashBox->setAutoHide(true);
ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING); ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING);
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>))); 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 */ /* fill in the available OwnIds for signing */
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
@ -189,7 +190,7 @@ void PostedCreatePostDialog::addPicture()
} }
QImage opt; 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)); ui->imageLabel->setPixmap(QPixmap::fromImage(opt));
} else { } else {
imagefilename = ""; imagefilename = "";

View File

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

View File

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

View File

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

View File

@ -389,7 +389,7 @@ border-image: url(:/images/closepressed.png)
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../icons.qrc"> <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>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -981,6 +981,15 @@ border-image: url(:/images/closepressed.png)
<string>Save image</string> <string>Save image</string>
</property> </property>
</action> </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"> <action name="actionSendAsPlainText">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>

View File

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

View File

@ -306,11 +306,15 @@ QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail,bo
infotext += "<UL>" ; infotext += "<UL>" ;
if(use_short_format) if(use_short_format)
{
infotext += "<li> a <b>Profile fingerprint</b>"; infotext += "<li> a <b>Profile fingerprint</b>";
infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.fpr.toStdString().c_str()+") " ;
}
else else
infotext += "<li> a <b>Profile key</b>"; {
infotext += "<li> a <b>Profile public key</b>";
infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ; infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ;
}
if(signatures_included && !use_short_format) if(signatures_included && !use_short_format)
infotext += tr("with")+" "+QString::number(detail.gpgSigners.size()-1)+" "+tr("external signatures</li>") ; 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/bandwidth.png</file>
<file>icons/png/options2.png</file> <file>icons/png/options2.png</file>
<file>icons/png/exit2.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/bold.png</file>
<file>icons/textedit/bullet-list.png</file> <file>icons/textedit/bullet-list.png</file>
<file>icons/textedit/italic.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"> <item row="0" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">
@ -541,7 +541,7 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QPlainTextEdit" name="certplainTextEdit"> <widget class="QPlainTextEdit" name="certplainTextEdit">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -569,6 +569,9 @@
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QCheckBox" name="_includeSignatures_CB"> <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"> <property name="text">
<string>Include signatures</string> <string>Include signatures</string>
</property> </property>
@ -576,6 +579,9 @@
</item> </item>
<item> <item>
<widget class="QCheckBox" name="_shortFormat_CB"> <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"> <property name="text">
<string>Short format</string> <string>Short format</string>
</property> </property>
@ -601,7 +607,7 @@
<item> <item>
<widget class="QPushButton" name="saveButton"> <widget class="QPushButton" name="saveButton">
<property name="toolTip"> <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>
<property name="text"> <property name="text">
<string>Save certificate to file</string> <string>Save certificate to file</string>

View File

@ -37,7 +37,7 @@
ImageUtil::ImageUtil() {} 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::Left, QTextCursor::MoveAnchor, 1);
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2); cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
@ -52,13 +52,13 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
QImage image = QImage::fromData(ba); QImage image = QImage::fromData(ba);
if(!image.isNull()) if(!image.isNull())
{ {
QString file;
success = true; 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, nullptr, 100))
if(!image.save(file + ".png", 0, 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")); 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 //nothing to do if it fits into the limits
optimized = original; optimized = original;
if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) { 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; return true;
} }
} }
QVector<QRgb> ct;
quantization(original, ct);
//Downscale the image to fit into maxPixels //Downscale the image to fit into maxPixels
double whratio = (qreal)original.width() / (qreal)original.height(); double whratio = (qreal)original.width() / (qreal)original.height();
int maxwidth; int maxwidth;
@ -98,6 +96,9 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original,
return true; return true;
} }
QVector<QRgb> ct;
quantization(original, ct);
//Use binary search to find a suitable image size + linear regression to guess the file size //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)); double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither));
if(maxsize <= maxBytes) return true; //success if(maxsize <= maxBytes) return true; //success
@ -141,6 +142,7 @@ bool ImageUtil::optimizeSizeHtml(QString &html, const QImage& original, QImage &
QByteArray bytearray; QByteArray bytearray;
if(maxBytes > 0){ if(maxBytes > 0){
maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff
if(maxBytes < 1) maxBytes = 1;
} }
if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes)) if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes))

View File

@ -31,7 +31,7 @@ class ImageUtil
public: public:
ImageUtil(); 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 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); static bool optimizeSizeBytes(QByteArray &bytearray, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);