diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp
index 5f29b2a20..bb7352ffd 100644
--- a/retroshare-gui/src/gui/chat/ChatWidget.cpp
+++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp
@@ -94,6 +94,8 @@ ChatWidget::ChatWidget(QWidget *parent)
//Resize Tool buttons
ui->emoteiconButton->setFixedSize(buttonSize);
ui->emoteiconButton->setIconSize(iconSize);
+ ui->stickerButton->setFixedSize(buttonSize);
+ ui->stickerButton->setIconSize(iconSize);
ui->attachPictureButton->setFixedSize(buttonSize);
ui->attachPictureButton->setIconSize(iconSize);
ui->addFileButton->setFixedSize(buttonSize);
@@ -145,6 +147,7 @@ ChatWidget::ChatWidget(QWidget *parent)
ui->markButton->setToolTip(tr("Mark this selected text
Ctrl+M"));
connect(ui->emoteiconButton, SIGNAL(clicked()), this, SLOT(smileyWidget()));
+ connect(ui->stickerButton, SIGNAL(clicked()), this, SLOT(stickerWidget()));
connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture()));
connect(ui->addFileButton, SIGNAL(clicked()), this , SLOT(addExtraFile()));
connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendChat()));
@@ -1545,6 +1548,22 @@ void ChatWidget::addSmiley()
ui->chatTextEdit->textCursor().insertText(smiley);
}
+void ChatWidget::stickerWidget()
+{
+ Emoticons::showStickerWidget(this, ui->stickerButton, SLOT(sendSticker()), true);
+}
+
+void ChatWidget::sendSticker()
+{
+ QString sticker = qobject_cast(sender())->statusTip();
+ QString encodedImage;
+ if (RsHtml::makeEmbeddedImage(sticker, encodedImage, 640*480, maxMessageSize() - 200)) { //-200 for the html stuff
+ RsHtml::optimizeHtml(encodedImage, 0);
+ std::string msg = encodedImage.toUtf8().constData();
+ rsMsgs->sendChat(chatId, msg);
+ }
+}
+
void ChatWidget::clearChatHistory()
{
ui->textBrowser->clear();
diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h
index d8f949503..b1b0a23db 100644
--- a/retroshare-gui/src/gui/chat/ChatWidget.h
+++ b/retroshare-gui/src/gui/chat/ChatWidget.h
@@ -159,6 +159,8 @@ private slots:
void smileyWidget();
void addSmiley();
+ void stickerWidget();
+ void sendSticker();
void addExtraFile();
void addExtraPicture();
diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui
index 16a411eb5..a937bf247 100644
--- a/retroshare-gui/src/gui/chat/ChatWidget.ui
+++ b/retroshare-gui/src/gui/chat/ChatWidget.ui
@@ -343,6 +343,32 @@ border-image: url(:/images/closepressed.png)
+ -
+
+
+ Qt::NoFocus
+
+
+ Insert sticker
+
+
+
+
+
+
+ :/icons/png/new.png:/icons/png/new.png
+
+
+
+ 28
+ 28
+
+
+
+ true
+
+
+
-
diff --git a/retroshare-gui/src/gui/common/Emoticons.cpp b/retroshare-gui/src/gui/common/Emoticons.cpp
index 4c7250746..667fa9e06 100644
--- a/retroshare-gui/src/gui/common/Emoticons.cpp
+++ b/retroshare-gui/src/gui/common/Emoticons.cpp
@@ -21,23 +21,39 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include "Emoticons.h"
#include "util/HandleRichText.h"
+#include "retroshare/rsinit.h"
+
+#define ICONNAME "groupicon.png"
static QHash, QHash > > Smileys;
static QVector grpOrdered;
+static QVector StickerGroups;
+static QStringList filters;
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
+}
+
+void Emoticons::loadSmiley()
{
QString sm_AllLines;
bool internalFiles = true;
@@ -267,3 +283,149 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s
smWidget->move(x, y) ;
smWidget->show() ;
}
+
+void Emoticons::loadSticker(QString foldername)
+{
+ QDir dir(foldername);
+ if(!dir.exists()) return;
+
+ //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);
+
+ //Check subfolders
+ QFileInfoList subfolders = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ for(int i = 0; isetAttribute(Qt::WA_DeleteOnClose) ;
+ smWidget->setWindowTitle("Stickers") ;
+
+ if(StickerGroups.count() == 0) {
+ QMessageBox::warning(parent, "Stickers", "No stickers installed");
+ return;
+ }
+ bool bOnlyOneGroup = (StickerGroups.count() == 1);
+
+ QTabWidget *smTab = nullptr;
+ if (! bOnlyOneGroup)
+ {
+ smTab = new QTabWidget(smWidget);
+ QGridLayout *smGLayout = new QGridLayout(smWidget);
+ smGLayout->setContentsMargins(0,0,0,0);
+ smGLayout->addWidget(smTab);
+ }
+
+ const int buttonWidth = QFontMetricsF(smWidget->font()).height()*2.6;
+ const int buttonHeight = QFontMetricsF(smWidget->font()).height()*2.6;
+ int maxRowCount = 0;
+ int maxCountPerLine = 0;
+
+ QVectorIterator grp(StickerGroups);
+ while(grp.hasNext())
+ {
+ QDir groupDir = QDir(grp.next());
+ QString groupName = groupDir.dirName();
+ groupDir.setNameFilters(filters);
+
+ QWidget *tabGrpWidget = nullptr;
+ if (! bOnlyOneGroup)
+ {
+ tabGrpWidget = new QWidget(smTab);
+
+ // (Cyril) Never use an absolute size. It needs to be scaled to the actual font size on the screen.
+ //
+ QFontMetricsF fm(parent->font()) ;
+ smTab->setIconSize(QSize(28*fm.height()/14.0,28*fm.height()/14.0));
+ smTab->setMinimumWidth(400);
+ smTab->setTabPosition(QTabWidget::South);
+ smTab->setStyleSheet("QTabBar::tab { height: 44px; width: 44px; }");
+
+ int index;
+ if (groupDir.exists(ICONNAME)) //use groupicon.png if exists, else the first png as a group icon
+ index = smTab->addTab( tabGrpWidget, QIcon(groupDir.absoluteFilePath(ICONNAME)), "");
+ else
+ index = smTab->addTab( tabGrpWidget, QIcon(groupDir.entryInfoList(QDir::Files)[0].canonicalFilePath()), "");
+ smTab->setTabToolTip(index, groupName);
+ } else {
+ tabGrpWidget = smWidget;
+ }
+
+ QGridLayout *tabGLayout = new QGridLayout(tabGrpWidget);
+ tabGLayout->setContentsMargins(0,0,0,0);
+ tabGLayout->setSpacing(0);
+
+ QFileInfoList group = groupDir.entryInfoList(QDir::Files, QDir::Name);
+ int rowCount = (int)sqrt((double)group.size());
+ int countPerLine = (group.size()/rowCount) + ((group.size() % rowCount) ? 1 : 0);
+ maxRowCount = qMax(maxRowCount, rowCount);
+ maxCountPerLine = qMax(maxCountPerLine, countPerLine);
+
+ int lin = 0;
+ int col = 0;
+ for(int i = 0; i < group.length(); ++i)
+ {
+ QFileInfo fi = group[i];
+ if(fi.fileName().compare(ICONNAME, Qt::CaseInsensitive) == 0)
+ continue;
+ QPushButton *button = new QPushButton("", tabGrpWidget);
+ button->setIconSize(QSize(buttonWidth, buttonHeight));
+ button->setFixedSize(QSize(buttonWidth, buttonHeight));
+ button->setIcon(QPixmap(fi.absoluteFilePath()));
+ button->setToolTip(fi.fileName());
+ button->setStatusTip(fi.absoluteFilePath());
+ button->setStyleSheet("QPushButton:hover {border: 3px solid #0099cc; border-radius: 3px;}");
+ button->setFlat(true);
+ tabGLayout->addWidget(button,col,lin);
+ ++lin;
+ if(lin >= countPerLine)
+ {
+ lin = 0;
+ ++col;
+ }
+ QObject::connect(button, SIGNAL(clicked()), parent, slotAddMethod);
+ QObject::connect(button, SIGNAL(clicked()), smWidget, SLOT(close()));
+ }
+
+ }
+
+ //Get left up pos of button
+ QPoint butTopLeft = button->mapToGlobal(QPoint(0,0));
+ //Get widget's size
+ QSize sizeWidget = smWidget->sizeHint();
+ //Get screen's size
+ QSize sizeScreen = QApplication::desktop()->size();
+
+ //Calculate left distance to screen start
+ int distToScreenLeft = butTopLeft.x();
+ //Calculate right distance to screen end
+ int distToRightScreen = sizeScreen.width() - (butTopLeft.x() + button->width());
+
+ //Calculate left position
+ int x;
+ if (distToScreenLeft >= distToRightScreen) //More distance in left than right in screen
+ x = butTopLeft.x() - sizeWidget.width(); //Place widget on left of button
+ else
+ x = butTopLeft.x() + button->width(); //Place widget on right of button
+
+ //Calculate top position
+ int y;
+ if (above) //Widget must be above the button
+ y = butTopLeft.y() + button->height() - sizeWidget.height();
+ else
+ y = butTopLeft.y() + button->height()/2 - sizeWidget.height()/2; //Centered on button height
+
+ if (y + sizeWidget.height() > sizeScreen.height()) //Widget will be too low
+ y = sizeScreen.height() - sizeWidget.height(); //Place widget bottom at screen bottom
+
+ if (y < 0) //Widget will be too high
+ y = 0; //Place widget top at screen top
+
+ smWidget->move(x, y) ;
+ smWidget->show() ;
+}
diff --git a/retroshare-gui/src/gui/common/Emoticons.h b/retroshare-gui/src/gui/common/Emoticons.h
index 2b04fdd6d..360ddf880 100644
--- a/retroshare-gui/src/gui/common/Emoticons.h
+++ b/retroshare-gui/src/gui/common/Emoticons.h
@@ -28,8 +28,11 @@ 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 void formatText(QString &text);
};