From ed228485d04c194d0673f3e46a86e2f6ed20fb89 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 18 Jan 2021 23:39:00 +0100 Subject: [PATCH] Added Stickers to load in Avatars Dialog to use a Avatar * Added function to load stickers in Avatars Dialog to use a Avatars * Added ZoomableLabel with crop image feature from PR #2236 --- .../src/gui/common/AvatarDialog.cpp | 235 +++++++++++++++++- retroshare-gui/src/gui/common/AvatarDialog.h | 10 + retroshare-gui/src/gui/common/AvatarDialog.ui | 158 +++++++----- 3 files changed, 332 insertions(+), 71 deletions(-) diff --git a/retroshare-gui/src/gui/common/AvatarDialog.cpp b/retroshare-gui/src/gui/common/AvatarDialog.cpp index 2a5d92cac..e1efb191a 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.cpp +++ b/retroshare-gui/src/gui/common/AvatarDialog.cpp @@ -19,12 +19,36 @@ *******************************************************************************/ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include "AvatarDialog.h" #include "ui_AvatarDialog.h" #include "AvatarDefs.h" #include "util/misc.h" #include "gui/common/FilesDefs.h" +#include "util/HandleRichText.h" +#include "retroshare/rsinit.h" + +#define ICONNAME "groupicon.png" + +static QStringList filters; +static QStringList stickerFolders; +static QHash tooltipcache; +static QHash iconcache; /** Constructor */ AvatarDialog::AvatarDialog(QWidget *parent) : @@ -44,6 +68,8 @@ AvatarDialog::AvatarDialog(QWidget *parent) : connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); updateInterface(); + loadFolders(); + loadAvatarWidget(); } const int AvatarDialog::RS_AVATAR_DEFAULT_IMAGE_W = 96; @@ -56,18 +82,25 @@ AvatarDialog::~AvatarDialog() void AvatarDialog::changeAvatar() { - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Avatar"), RS_AVATAR_DEFAULT_IMAGE_W,RS_AVATAR_DEFAULT_IMAGE_H); + QString image_filename ; - if (img.isNull()) - return; + if(!misc::getOpenFileName(this,RshareSettings::LASTDIR_IMAGES,tr("Import image"), tr("Image files (*.jpg *.png);;All files (*)"),image_filename)) + return; - ui->avatarLabel->setPixmap(img); + QImage img(image_filename); + + ui->avatarLabel->setPicture(QPixmap::fromImage(img)); + ui->avatarLabel->setEnableZoom(true); + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + + // shows the tooltip for a while + QToolTip::showText( ui->avatarLabel->mapToGlobal( QPoint( 0, 0 ) ), ui->avatarLabel->toolTip() ); updateInterface(); } void AvatarDialog::removeAvatar() { - ui->avatarLabel->setPixmap(QPixmap()); + ui->avatarLabel->setPicture(QPixmap()); updateInterface(); } @@ -83,7 +116,7 @@ void AvatarDialog::updateInterface() void AvatarDialog::setAvatar(const QPixmap &avatar) { - ui->avatarLabel->setPixmap(avatar); + ui->avatarLabel->setPicture(avatar); updateInterface(); } @@ -111,3 +144,193 @@ void AvatarDialog::getAvatar(QByteArray &avatar) buffer.open(QIODevice::WriteOnly); pixmap->save(&buffer, "PNG"); // writes image into ba in PNG format } + +void AvatarDialog::loadFolders() +{ + filters << "*.png" << "*.jpg" << "*.gif"; + 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 AvatarDialog::loadAvatarWidget() +{ + QVector stickerTabs; + refreshStickerTabs(stickerTabs); + + if(stickerTabs.count() == 0) { + ui->nostickersLabel->setText(""); + QString message = "No stickers installed.\nYou can install them by putting images into one of these folders:\n" + stickerFolders.join('\n'); + ui->nostickersLabel->setText(message); + } else { + ui->infoframe->hide(); + } + + bool bOnlyOneGroup = (stickerTabs.count() == 1); + + QTabWidget *avatarTab = nullptr; + if (! bOnlyOneGroup) + { + avatarTab = new QTabWidget(ui->avatarWidget); + QGridLayout *avatarGLayout = new QGridLayout(ui->avatarWidget); + avatarGLayout->setContentsMargins(0,0,0,0); + avatarGLayout->addWidget(avatarTab); + } + + const int buttonWidth = QFontMetricsF(ui->avatarWidget->font()).height()*5; + const int buttonHeight = QFontMetricsF(ui->avatarWidget->font()).height()*5; + int maxRowCount = 0; + int maxCountPerLine = 0; + + QVectorIterator grp(stickerTabs); + while(grp.hasNext()) + { + QDir groupDir = QDir(grp.next()); + QString groupName = groupDir.dirName(); + groupDir.setNameFilters(filters); + + QWidget *tabGrpWidget = nullptr; + if (! bOnlyOneGroup) + { + //Lazy load tooltips for the current tab + QObject::connect(avatarTab, &QTabWidget::currentChanged, [=](int index){ + QWidget* current = avatarTab->widget(index); + loadToolTips(current); + }); + + tabGrpWidget = new QWidget(avatarTab); + + // (Cyril) Never use an absolute size. It needs to be scaled to the actual font size on the screen. + // + QFontMetricsF fm(font()) ; + avatarTab->setIconSize(QSize(28*fm.height()/14.0,28*fm.height()/14.0)); + avatarTab->setMinimumWidth(200); + //avatarTab->setTabPosition(QTabWidget::West); + avatarTab->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 = avatarTab->addTab( tabGrpWidget, FilesDefs::getIconFromQtResourcePath(groupDir.absoluteFilePath(ICONNAME)), ""); + else + index = avatarTab->addTab( tabGrpWidget, FilesDefs::getIconFromQtResourcePath(groupDir.entryInfoList(QDir::Files)[0].canonicalFilePath()), ""); + avatarTab->setTabToolTip(index, groupName); + } else { + tabGrpWidget = ui->avatarWidget; + } + + 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)); + if(!iconcache.contains(fi.absoluteFilePath())) + { + iconcache.insert(fi.absoluteFilePath(), FilesDefs::getPixmapFromQtResourcePath(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;}"); + button->setFlat(true); + tabGLayout->addWidget(button,col,lin); + ++lin; + if(lin >= countPerLine) + { + lin = 0; + ++col; + } + QObject::connect(button, SIGNAL(clicked()), this, SLOT(addAvatar())); + } + + } + + //Load tooltips for the first page + QWidget * firstpage; + if(bOnlyOneGroup) { + firstpage = ui->avatarWidget; + } else { + firstpage = avatarTab->currentWidget(); + } + loadToolTips(firstpage); + + //Get widget's size + QSize sizeWidget = ui->avatarWidget->sizeHint(); + +} + +QString AvatarDialog::importedStickerPath() +{ + QDir dir(stickerFolders[0]); + return dir.absoluteFilePath("imported"); +} + +void AvatarDialog::loadToolTips(QWidget *container) +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + QList children = container->findChildren(); + for(int i = 0; i < children.length(); ++i) { + if(!children[i]->toolTip().contains('<')) { + if(tooltipcache.contains(children[i]->statusTip())) { + children[i]->setToolTip(tooltipcache[children[i]->statusTip()]); + } else { + QString tooltip; + if(RsHtml::makeEmbeddedImage(children[i]->statusTip(), tooltip, 300*300)) { + tooltipcache.insert(children[i]->statusTip(), tooltip); + children[i]->setToolTip(tooltip); + } + + } + + } + } + QApplication::restoreOverrideCursor(); +} + +void AvatarDialog::refreshStickerTabs(QVector& stickerTabs) +{ + for(int i = 0; i < stickerFolders.count(); ++i) + refreshStickerTabs(stickerTabs, stickerFolders[i]); +} + +void AvatarDialog::refreshStickerTabs(QVector& stickerTabs, 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) + stickerTabs.append(foldername); + + //Check subfolders + QFileInfoList subfolders = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); + for(int i = 0; i(sender())->statusTip(); + QPixmap pixmap(sticker); + + ui->avatarLabel->setPixmap(pixmap); + updateInterface(); +} diff --git a/retroshare-gui/src/gui/common/AvatarDialog.h b/retroshare-gui/src/gui/common/AvatarDialog.h index 407e95604..df168b72c 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.h +++ b/retroshare-gui/src/gui/common/AvatarDialog.h @@ -46,9 +46,19 @@ public: void getAvatar(QPixmap &avatar); void getAvatar(QByteArray &avatar); + static QString importedStickerPath(); + private slots: void changeAvatar(); void removeAvatar(); + void addAvatar(); + + void loadFolders(); + void loadAvatarWidget(); + + void loadToolTips(QWidget *container); + void refreshStickerTabs(QVector& stickerTabs, QString foldername); + void refreshStickerTabs(QVector& stickerTabs); private: void updateInterface(); diff --git a/retroshare-gui/src/gui/common/AvatarDialog.ui b/retroshare-gui/src/gui/common/AvatarDialog.ui index bdf59252a..dcce126e3 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.ui +++ b/retroshare-gui/src/gui/common/AvatarDialog.ui @@ -6,21 +6,27 @@ 0 0 - 374 - 252 + 589 + 468 Change Avatar - - + + 0 - + 0 - + + 0 + + + 0 + + QFrame::StyledPanel @@ -30,7 +36,7 @@ - + QFrame::StyledPanel @@ -39,10 +45,16 @@ QFrame::Raised - - + + 3 + + + 0 + + + - + 128 @@ -70,73 +82,84 @@ - - - - - Add Avatar - - - - - - - false - - - Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + Browse... + + + + + + + false + + + Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + - - - - Qt::Horizontal + + + + QFrame::StyledPanel - - - 61 - 98 - + + QFrame::Raised - + + + + + TextLabel + + + Qt::AlignCenter + + + + + - - - - Qt::Vertical + + + + + 0 + 0 + - - - 218 - 88 - - - + - + - + + 9 + + + 9 + + + 9 + + 9 @@ -175,6 +198,11 @@
gui/common/HeaderFrame.h
1 + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+