Feature #531

Add 'Save as' context menu for vcard photo

Added by Remko Tronçon 1637 days ago. Updated 344 days ago.

Status:Rejected Start:
Priority:Normal Due date:
Assigned to:Dmitriy Erlih % Done:

0%

Category:UserInterface
Target version:0.14
Operating System:

All

Reported in:

0.10


Description

Add 'Save as' context menu for vcard photo.


Related issues

blocks Bug #764 Patch review (META TASK) New

History

Updated by - duryodhan 903 days ago

A context menu (right click menu) to the image would involve subclassing qlabel and creating something like QClickableLabel, which would cause a significant churn. A simpler and cleaner alternative is a button in the ui called save image. This should be pretty easy to implement. What do you think?

Updated by zet _ 903 days ago

for example, patch from dion ( http://bombus-im.org/zet/psi/patches/psi-vcard-save.diff ):

Index: trunk/src/infodlg.cpp =================================================================== --- trunk.orig/src/infodlg.cpp 2007-11-22 20:25:31.000000000 +0200 +++ trunk/src/infodlg.cpp 2007-11-22 20:26:08.000000000 +0200 @@ -95,6 +95,7 @@ connect(ui_.pb_refresh, SIGNAL(clicked()), this, SLOT(updateStatus())); connect(ui_.te_desc, SIGNAL(textChanged()), this, SLOT(textChanged())); connect(ui_.pb_open, SIGNAL(clicked()), this, SLOT(selectPhoto())); + connect(ui_.pb_save, SIGNAL(clicked()), this, SLOT(savePhoto())); connect(ui_.pb_clear, SIGNAL(clicked()), this, SLOT(clearPhoto())); connect(ui_.pb_close, SIGNAL(clicked()), this, SLOT(close())); @@ -273,6 +274,7 @@ img_scaled = img; } ui_.label_photo->setPixmap(QPixmap(img_scaled)); + ui_.pb_save->show(); } void InfoDlg::fieldsEnable(bool x) @@ -517,6 +519,26 @@ } /** + * Opens a file browser dialog, and if selected, save photo from vcard +*/ +void InfoDlg::savePhoto() +{ + if (!d->photo.isEmpty()) { + if (PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString().isEmpty()) + PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString() = QDir::homeDirPath(); + QString str=QFileDialog::getSaveFileName(this, tr("Save photo"), PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString(), tr("Images (*.png *.xpm *.jpg *.PNG *.XPM *.JPG")); + if (!str.isEmpty()) + { + QFileInfo fi(str); + PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString()=fi.dirPath(); + // Convert imge if required + QImage img(d->photo); + img.save(str); + } + } +} + +/** * Loads the image from the requested URL, and inserts the resized image into the preview box. * \param path image file to load */ @@ -546,6 +568,7 @@ // the picture changed, so notify there are some changes done d->te_edited = true; + ui_.pb_save->hide(); } /** Index: trunk/src/infodlg.h =================================================================== --- trunk.orig/src/infodlg.h 2007-11-22 20:25:11.000000000 +0200 +++ trunk/src/infodlg.h 2007-11-22 20:26:08.000000000 +0200 @@ -63,6 +63,7 @@ void doSubmit(); void textChanged(); void selectPhoto(); + void savePhoto(); void clearPhoto(); private: Index: trunk/src/info.ui =================================================================== --- trunk.orig/src/info.ui 2007-11-22 20:25:11.000000000 +0200 +++ trunk/src/info.ui 2007-11-22 20:26:08.000000000 +0200 @@ -160,6 +160,30 @@ </widget> </item> <item> + <widget class="QPushButton" name="pb_save" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>&amp;Save...</string> + </property> + <property name="shortcut" > + <string>Alt+S</string> + </property> + <property name="autoDefault" > + <bool>false</bool> + </property> + <property name="flat" > + <bool>false</bool> + </property> + </widget> + </item> + <item> <widget class="QPushButton" name="pb_clear" > <property name="sizePolicy" > <sizepolicy> @@ -503,6 +527,7 @@ <tabstop>le_homepage</tabstop> <tabstop>le_email</tabstop> <tabstop>pb_open</tabstop> + <tabstop>pb_save</tabstop> <tabstop>pb_clear</tabstop> <tabstop>pb_submit</tabstop> <tabstop>pb_refresh</tabstop>

Updated by - duryodhan 902 days ago

I haven't applied this patch, but looking at the source, it seems that there is the possibility of the button being active when there is no image and then clicking on the button will give nothing. (based on +void InfoDlg::savePhoto()
+{
+ if (!d->photo.isEmpty()) {)

...

maybe you could change that so that the button is disabled when the image isn't present.

Updated by - duryodhan 901 days ago

I found somewhere a class called MLabel (somewhere as in inside Psi , mainwin_p.cpp), maybe that could be used to implement the image , then the context menu could have the save as ...

Updated by Dmitriy Erlih 882 days ago

I've added popup menu with "Save avatar" action, which is activeting on photo label's context menu event.
I think, photo label should have shape QFrame::Box and shadow QFrame::Plain for good looking.
This is the svn diff output:

Index: src/infodlg.cpp ===================================================================
--- src/infodlg.cpp (revision 1069)
+++ src/infodlg.cpp (working copy)
@ -46,12 +46,22 @
#include "psioptions.h"
#include "fileutil.h"

+#include <QMenu>
+#include "iconaction.h"
+
using namespace XMPP; - Private() {}
+ Private() : saveAvatarMenu(new QMenu),
+ action(new IconAction(saveAvatarMenu,"save avatar action"))
+ {
+ action->setPsiIcon("psi/save");
+ action->setText(QObject::tr("Save avatar"));
+ saveAvatarMenu->addAction(action);
+ }
+ ~Private() { delete saveAvatarMenu; } @ -64,6 +74,9 @
bool cacheVCard;
QByteArray photo;
QList<QString> infoRequested;
+
+ QMenu* saveAvatarMenu;
+ IconAction *action;
}; @ -99,6 +112,12 @
connect(ui_.pb_clear, SIGNAL), this, SLOT));
connect(ui_.pb_close, SIGNAL), this, SLOT));

InfoDlg::InfoDlg(int type, const Jid &j, const VCard &vcard, PsiAccount *pa, QWidget *parent, bool cacheVCard)

+ d->action->setStatusTip(QObject::tr("Save %1's avatar").arg(d->vcard.nickName()));
+ ui_.label_photo->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui_.label_photo, SIGNAL),
+ SLOT));
+ connect(d->action,SIGNAL),SLOT));
+
if(d->type == Self) {
connect(ui_.pb_submit, SIGNAL), this, SLOT));
}
@ -632,3 +651,44 @
updateStatus();
}
}
+
+/**
+ * Save avatar slots
+ */
+void InfoDlg::saveAvatarMenu(const QPoint & point)
+{
+ QAction *saveAvatarAction = d->saveAvatarMenu->actions().first();
+ if(d->photo.isEmpty())
+ saveAvatarAction->setEnabled(false);
+ else
+ saveAvatarAction->setEnabled(true);
+
+ d->saveAvatarMenu->popup(ui_.label_photo->mapToGlobal(point));
+}
+
+void InfoDlg::openSaveAvatarDialog()
+{
+ QString filePath = PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString();
+ if(filePath.isEmpty())
+ filePath = QDir::homeDirPath();
+
+ QString fileName = QFileDialog::getSaveFileName(this, QString(),
+ filePath + "/" + d->vcard.nickName() + ".png",
+ tr("Images (*.png *.xpm *.jpg *.PNG *.XPM *.JPG"));
+
+ if(fileName.isEmpty())
+ return;
+
+ QFileInfo lastPath(fileName);
+ PsiOptions::instance()->getOption("options.ui.last-used-open-path").toString() = lastPath.dirPath();
+
+ QImage avatar;
+ if(!avatar.loadFromData(d->photo))
+ {
+ qDebug("Warning: Can't load data to QImage");
+ return;
+ }
+
+ if(!avatar.save(fileName))
+ QMessageBox::warning(this,tr("Unsupported file format"),tr("Can't save %1 (UNSUPPORTED FILE FORMAT)").arg(fileName));
+}
Index: src/infodlg.h ===================================================================
--- src/infodlg.h (revision 1069)
+++ src/infodlg.h (working copy)
@ -53,6 +53,9 @
void closeEvent ( QCloseEvent * e );
void setStatusVisibility(bool visible);

+ void saveAvatarMenu(const QPoint &);
+ void openSaveAvatarDialog();
+
private slots:
void contactAvailable(const Jid &, const Resource &);
void contactUnavailable(const Jid &, const Resource &);

Updated by Justin Karneges 345 days ago

  • Target version set to 0.14

Updated by Justin Karneges 344 days ago

  • Status changed from New to Rejected

#1029 added this feature

Also available in: Atom PDF