See this page for instructions on how to use Flyspray: http://psi-im.org/wiki/Flyspray
Please Note!
Please do not create tasks here without discussing your bug or feature request on the forums or groupchat psi@conference.psi-im.org, *and* getting explicit confirmation by a developer to add it to flyspray.
Please Note!
Please do not create tasks here without discussing your bug or feature request on the forums or groupchat psi@conference.psi-im.org, *and* getting explicit confirmation by a developer to add it to flyspray.
FS#531 - Add 'Save as' context menu for vcard photo
Attached to Project:
Psi Jabber Client
Opened by Remko Tronçon (spike) - Sunday, 05 February 2006, 13:44 GMT-5
Opened by Remko Tronçon (spike) - Sunday, 05 February 2006, 13:44 GMT-5
|
DetailsAdd 'Save as' context menu for vcard photo.
|
This task blocks these from closing
FS#764 - Patch review (META TASK)
FS#772 - bite sized tasks (META TASK)
FS#764 - Patch review (META TASK)
FS#772 - bite sized tasks (META TASK)
<code>
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>&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>
</code>
+{
+ if (!d->photo.isEmpty()) {)
...
maybe you could change that so that the button is disabled when the image isn't present.
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;
class InfoDlg::Private
{
public:
- 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; }
int type;
Jid jid;
@@ -64,6 +74,9 @@
bool cacheVCard;
QByteArray photo;
QList<QString> infoRequested;
+
+ QMenu* saveAvatarMenu;
+ IconAction *action;
};
InfoDlg::InfoDlg(int type, const Jid &j, const VCard &vcard, PsiAccount *pa, QWidget *parent, bool cacheVCard)
@@ -99,6 +112,12 @@
connect(ui_.pb_clear, SIGNAL(clicked()), this, SLOT(clearPhoto()));
connect(ui_.pb_close, SIGNAL(clicked()), this, SLOT(close()));
+ d->action->setStatusTip(QObject::tr("Save %1's avatar").arg(d->vcard.nickName()));
+ ui_.label_photo->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui_.label_photo, SIGNAL(customContextMenuRequested(const QPoint&)),
+ SLOT(saveAvatarMenu(const QPoint &)));
+ connect(d->action,SIGNAL(triggered()),SLOT(openSaveAvatarDialog()));
+
if(d->type == Self) {
connect(ui_.pb_submit, SIGNAL(clicked()), this, SLOT(doSubmit()));
}
@@ -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 &);