Send by email

This commit is contained in:
Jakub Melka 2019-12-22 18:03:19 +01:00
parent 1fafd3835c
commit 38748340fa
10 changed files with 285 additions and 11 deletions

View File

@ -36,6 +36,7 @@ SOURCES += \
main.cpp \ main.cpp \
pdfaboutdialog.cpp \ pdfaboutdialog.cpp \
pdfdocumentpropertiesdialog.cpp \ pdfdocumentpropertiesdialog.cpp \
pdfsendmail.cpp \
pdfsidebarwidget.cpp \ pdfsidebarwidget.cpp \
pdfviewermainwindow.cpp \ pdfviewermainwindow.cpp \
pdfviewersettings.cpp \ pdfviewersettings.cpp \
@ -45,6 +46,7 @@ SOURCES += \
HEADERS += \ HEADERS += \
pdfaboutdialog.h \ pdfaboutdialog.h \
pdfdocumentpropertiesdialog.h \ pdfdocumentpropertiesdialog.h \
pdfsendmail.h \
pdfsidebarwidget.h \ pdfsidebarwidget.h \
pdfviewermainwindow.h \ pdfviewermainwindow.h \
pdfviewersettings.h \ pdfviewersettings.h \

View File

@ -41,6 +41,7 @@ namespace pdfviewer
struct PDFFileInfo struct PDFFileInfo
{ {
QString originalFileName;
QString fileName; QString fileName;
QString path; QString path;
pdf::PDFInteger fileSize = 0; pdf::PDFInteger fileSize = 0;

View File

@ -25,5 +25,6 @@
<file>resources/cache.svg</file> <file>resources/cache.svg</file>
<file>resources/shortcuts.svg</file> <file>resources/shortcuts.svg</file>
<file>resources/info.svg</file> <file>resources/info.svg</file>
<file>resources/send-mail.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,94 @@
// Copyright (C) 2019 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#include "pdfsendmail.h"
#include <QDir>
#include <QWidget>
#include <QFileInfo>
#ifdef Q_OS_WIN
#include <Windows.h>
#include <MAPI.h>
#include <string>
#endif
namespace pdfviewer
{
bool PDFSendMail::sendMail(QWidget* parent, QString subject, QString fileName)
{
#ifdef Q_OS_WIN
QFileInfo fileInfo(fileName);
std::wstring subjectString = subject.toStdWString();
std::wstring fileNameString = fileInfo.fileName().toStdWString();
std::wstring filePathString = QDir::toNativeSeparators(fileInfo.absoluteFilePath()).toStdWString();
HMODULE mapiLib = ::LoadLibrary(L"MAPI32.DLL");
if (!mapiLib)
{
return false;
}
LPMAPISENDMAILW SendMail;
SendMail = (LPMAPISENDMAILW)GetProcAddress(mapiLib, "MAPISendMailW");
if (!SendMail)
{
::FreeLibrary(mapiLib);
return false;
}
// Jakub Melka: now, we have function for mail sending, we can use it!
// First, we must fill the info structures.
MapiFileDescW fileDesc;
::ZeroMemory(&fileDesc, sizeof(fileDesc));
fileDesc.nPosition = ULONG(-1);
fileDesc.lpszFileName = const_cast<PWSTR>(fileNameString.c_str());
fileDesc.lpszPathName = const_cast<PWSTR>(filePathString.c_str());
MapiMessageW message;
::ZeroMemory(&message, sizeof(message));
message.lpszSubject = const_cast<PWSTR>(subjectString.c_str());
message.nFileCount = 1;
message.lpFiles = &fileDesc;
const int returnCode = SendMail(0, parent->winId(), &message, MAPI_LOGON_UI | MAPI_DIALOG, 0);
::FreeLibrary(mapiLib);
switch (returnCode)
{
case SUCCESS_SUCCESS:
case MAPI_USER_ABORT:
case MAPI_E_LOGIN_FAILURE:
return true;
default:
return false;
}
return false;
#else
static_assert(false, "Implement this for another OS!");
return false;
#endif
}
} // namespace pdfviewer

View File

@ -0,0 +1,38 @@
// Copyright (C) 2019 Jakub Melka
//
// This file is part of PdfForQt.
//
// PdfForQt is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// PdfForQt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFSENDMAIL_H
#define PDFSENDMAIL_H
#include <QString>
class QWidget;
namespace pdfviewer
{
class PDFSendMail
{
public:
PDFSendMail() = delete;
static bool sendMail(QWidget* parent, QString subject, QString fileName);
};
} // namespace pdfviewer
#endif // PDFSENDMAIL_H

View File

@ -32,6 +32,7 @@
#include "pdffont.h" #include "pdffont.h"
#include "pdfitemmodels.h" #include "pdfitemmodels.h"
#include "pdfutils.h" #include "pdfutils.h"
#include "pdfsendmail.h"
#include <QSettings> #include <QSettings>
#include <QFileDialog> #include <QFileDialog>
@ -665,6 +666,7 @@ void PDFViewerMainWindow::updateUI(bool fullUpdate)
} }
ui->actionProperties->setEnabled(m_pdfDocument); ui->actionProperties->setEnabled(m_pdfDocument);
ui->actionSend_by_E_Mail->setEnabled(m_pdfDocument);
} }
else else
{ {
@ -714,6 +716,7 @@ void PDFViewerMainWindow::openDocument(const QString& fileName)
closeDocument(); closeDocument();
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
m_fileInfo.originalFileName = fileName;
m_fileInfo.fileName = fileInfo.fileName(); m_fileInfo.fileName = fileInfo.fileName();
m_fileInfo.path = fileInfo.path(); m_fileInfo.path = fileInfo.path();
m_fileInfo.fileSize = fileInfo.size(); m_fileInfo.fileSize = fileInfo.size();
@ -932,4 +935,20 @@ void PDFViewerMainWindow::on_actionAbout_triggered()
dialog.exec(); dialog.exec();
} }
void PDFViewerMainWindow::on_actionSend_by_E_Mail_triggered()
{
Q_ASSERT(m_pdfDocument);
QString subject = m_pdfDocument->getInfo()->title;
if (subject.isEmpty())
{
subject = m_fileInfo.fileName;
}
if (!PDFSendMail::sendMail(this, subject, m_fileInfo.originalFileName))
{
QMessageBox::critical(this, tr("Error"), tr("Error while starting email client occured!"));
}
}
} // namespace pdfviewer } // namespace pdfviewer

View File

@ -79,6 +79,8 @@ private slots:
void on_actionProperties_triggered(); void on_actionProperties_triggered();
void on_actionSend_by_E_Mail_triggered();
private: private:
void onActionOpenTriggered(); void onActionOpenTriggered();
void onActionCloseTriggered(); void onActionCloseTriggered();

View File

@ -30,6 +30,8 @@
<addaction name="actionOpen"/> <addaction name="actionOpen"/>
<addaction name="actionClose"/> <addaction name="actionClose"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionSend_by_E_Mail"/>
<addaction name="separator"/>
<addaction name="actionProperties"/> <addaction name="actionProperties"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
@ -305,6 +307,15 @@
<string>Properties</string> <string>Properties</string>
</property> </property>
</action> </action>
<action name="actionSend_by_E_Mail">
<property name="icon">
<iconset resource="pdfforqtviewer.qrc">
<normaloff>:/resources/send-mail.svg</normaloff>:/resources/send-mail.svg</iconset>
</property>
<property name="text">
<string>Send by E-Mail</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

View File

@ -25,9 +25,9 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="5.6" inkscape:zoom="11.2"
inkscape:cx="20.721345" inkscape:cx="61.228354"
inkscape:cy="52.467845" inkscape:cy="24.722037"
inkscape:document-units="mm" inkscape:document-units="mm"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="false" showgrid="false"
@ -44,7 +44,7 @@
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title> <dc:title />
<dc:creator> <dc:creator>
<cc:Agent> <cc:Agent>
<dc:title>Jakub Melka</dc:title> <dc:title>Jakub Melka</dc:title>
@ -76,7 +76,7 @@
id="layer1" id="layer1"
transform="translate(0,-267)"> transform="translate(0,-267)">
<rect <rect
style="fill:#f0f0f0;fill-opacity:1;stroke:#000000;stroke-width:0.28757221;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5901" id="rect5901"
width="23.147377" width="23.147377"
height="20.895622" height="20.895622"
@ -84,16 +84,20 @@
y="274.57504" y="274.57504"
ry="0" /> ry="0" />
<rect <rect
style="fill:#f0f0f0;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5903" id="rect5903"
width="5.1026788" width="5.1026788"
height="2.0788691" height="2.0788691"
x="2.3151042" x="2.3151042"
y="272.50241" /> y="272.50241" />
<path <rect
style="fill:#f0f0f0;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.44556388;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 2.3151042,295.46448 4.5169729,-18.9106 22.8181359,-0.3842 -2.128821,19.2948 z" id="rect5901-2"
id="path5907" width="23.204285"
inkscape:connector-curvature="0" /> height="16.552702"
x="46.932369"
y="282.22354"
ry="0"
transform="matrix(1,0,-0.14834045,0.98893635,0,0)" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,102 @@
<?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"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg5291"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="send-mail.svg">
<defs
id="defs5285" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="30.416613"
inkscape:cy="-20.999376"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5288">
<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>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<rect
style="fill:#c8c8c8;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect831"
width="26.647322"
height="19.135044"
x="1.7008928"
y="272.33707"
ry="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 1.7008928,272.33707 15.308036,284.45591 28.348215,272.33707"
id="path833"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 1.7008928,291.47211 12.425967,281.85733"
id="path837"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 28.348215,291.47211 -10.299852,-9.6384"
id="path839"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB