sfx2: introduce a new .uno:SignPDF

It's similar to File -> Open, but the file picker only offers PDF files
in this case, and the import is read-only -- i.e. it's the import
equivalent of .uno:ExportToPDF.

Change-Id: I7be9d6711e0ea93643e538575c0604d41cff9b26
diff --git a/include/sfx2/app.hxx b/include/sfx2/app.hxx
index 942d1ba..17dbba1 100644
--- a/include/sfx2/app.hxx
+++ b/include/sfx2/app.hxx
@@ -213,6 +213,7 @@ public:
    SAL_DLLPRIVATE void         NewDocExec_Impl(SfxRequest &);
    SAL_DLLPRIVATE void         OpenDocExec_Impl(SfxRequest &);
    SAL_DLLPRIVATE void         OpenRemoteExec_Impl(SfxRequest &);
    SAL_DLLPRIVATE void         SignPDFExec_Impl(SfxRequest&);
    SAL_DLLPRIVATE void         MiscExec_Impl(SfxRequest &);
    SAL_DLLPRIVATE void         MiscState_Impl(SfxItemSet &);
    SAL_DLLPRIVATE static void  PropExec_Impl(SfxRequest &);
diff --git a/include/sfx2/filedlghelper.hxx b/include/sfx2/filedlghelper.hxx
index 0c6ac8c..a56b0b0 100644
--- a/include/sfx2/filedlghelper.hxx
+++ b/include/sfx2/filedlghelper.hxx
@@ -65,10 +65,12 @@ enum class FileDialogFlags {
    Export            = 0x02,    // turn Save into Export dialog
    SaveACopy         = 0x04,    // turn Save into Save a Copy dialog
    MultiSelection    = 0x08,
    Graphic           = 0x10     // register graphic formats
    Graphic           = 0x10,    // register graphic formats
    /// Sign existing PDF.
    SignPDF           = 0x20
};
namespace o3tl {
    template<> struct typed_flags<FileDialogFlags> : is_typed_flags<FileDialogFlags, 0x1f> {};
    template<> struct typed_flags<FileDialogFlags> : is_typed_flags<FileDialogFlags, 0x3f> {};
}

#define FILEDIALOG_FILTER_ALL   "*.*"
diff --git a/include/sfx2/sfx.hrc b/include/sfx2/sfx.hrc
index 251dd22..020f82b 100644
--- a/include/sfx2/sfx.hrc
+++ b/include/sfx2/sfx.hrc
@@ -125,6 +125,7 @@
#define STR_READONLY                        (RID_SFX_START+105)

#define STR_SFX_FILTERNAME_ALL              (RID_SFX_START+106)
#define STR_SFX_FILTERNAME_PDF              (RID_SFX_START+107)
#define STR_EDIT                            (RID_SFX_START+108)

#define STR_BYTES                           (RID_SFX_START+111)
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index 8520a25..0685df6 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -103,6 +103,7 @@
#define SID_SAVEASDOC                       (SID_SFX_START + 502)
#define SID_SAVEASREMOTE                    (SID_SFX_START + 516)
#define SID_SAVESIMPLE                      (SID_SFX_START + 518)
#define SID_SIGNPDF                         (SID_SFX_START + 519)
#define SID_SAVEACOPY                       (SID_SFX_START + 999)
#define SID_SAVEACOPYITEM                   (SID_SFX_START + 998)
#define SID_CLOSING                         (SID_SFX_START +1539)
diff --git a/sfx2/sdi/docslots.sdi b/sfx2/sdi/docslots.sdi
index 8a54a6c..18bd741 100644
--- a/sfx2/sdi/docslots.sdi
+++ b/sfx2/sdi/docslots.sdi
@@ -30,6 +30,10 @@ interface Documents
    [
        ExecMethod = OpenRemoteExec_Impl ;
    ]
    SID_SIGNPDF
    [
        ExecMethod = SignPDFExec_Impl ;
    ]
    SID_OPENHYPERLINK // ole(no) api(final/play/rec)
    [
        ExecMethod = OpenDocExec_Impl ;
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index e45cf6d..dda5c78 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -2826,6 +2826,24 @@ SfxObjectItem OpenRemote SID_OPENREMOTE
    GroupId = GID_APPLICATION;
]

SfxObjectItem SignPDF SID_SIGNPDF
(SfxStringItem URL SID_FILE_NAME,SfxStringItem FilterName SID_FILTER_NAME,SfxStringItem OpenFlags SID_OPTIONS,SfxStringItem Password SID_PASSWORD,SfxStringItem FilterOptions SID_FILE_FILTEROPTIONS,SfxInt16Item Version SID_VERSION,SfxStringItem Referer SID_REFERER,SfxStringItem SuggestedSaveAsDir SID_DEFAULTFILEPATH,SfxStringItem SuggestedSaveAsName SID_DEFAULTFILENAME)
[
    AutoUpdate = FALSE,
    FastCall = FALSE,
    ReadOnlyDoc = TRUE,
    Toggle = FALSE,
    Container = TRUE,
    RecordAbsolute = FALSE,
    RecordPerSet;
    Asynchron;

    AccelConfig = TRUE,
    MenuConfig = TRUE,
    ToolBoxConfig = TRUE,
    GroupId = GID_APPLICATION;
]

SfxObjectItem WebHtml SID_WEBHTML
()
[
diff --git a/sfx2/source/appl/app.src b/sfx2/source/appl/app.src
index 3384f4a..21c5f91 100644
--- a/sfx2/source/appl/app.src
+++ b/sfx2/source/appl/app.src
@@ -333,6 +333,10 @@ String STR_SFX_FILTERNAME_ALL
{
    Text [ en-US ] = "All files" ;
};
String STR_SFX_FILTERNAME_PDF
{
    Text [ en-US ] = "PDF files" ;
};
String RID_SVXSTR_EDITGRFLINK
{
    Text [ en-US ] = "Link Image" ;
diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx
index 5b0fddd..caec98f 100644
--- a/sfx2/source/appl/appopen.cxx
+++ b/sfx2/source/appl/appopen.cxx
@@ -624,6 +624,15 @@ void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
        if ( pRemoteDialogItem && pRemoteDialogItem->GetValue())
            nDialog = SFX2_IMPL_DIALOG_REMOTE;

        sal_Int16 nDialogType = ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION;
        FileDialogFlags eDialogFlags = FileDialogFlags::MultiSelection;
        const SfxBoolItem* pSignPDFItem = rReq.GetArg<SfxBoolItem>(SID_SIGNPDF);
        if (pSignPDFItem && pSignPDFItem->GetValue())
        {
            eDialogFlags |= FileDialogFlags::SignPDF;
            nDialogType = ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
        }

        OUString sStandardDir;

        const SfxStringItem* pStandardDirItem = rReq.GetArg<SfxStringItem>(SID_STANDARD_DIR);
@@ -638,8 +647,8 @@ void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )


        sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl(
                ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
                FileDialogFlags::MultiSelection, OUString(), aURLList,
                nDialogType,
                eDialogFlags, OUString(), aURLList,
                aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList );

        if ( nErr == ERRCODE_ABORT )
@@ -1127,4 +1136,10 @@ void SfxApplication::OpenRemoteExec_Impl( SfxRequest& rReq )
    GetDispatcher_Impl()->Execute( SID_OPENDOC, SfxCallMode::SYNCHRON, *rReq.GetArgs() );
}

void SfxApplication::SignPDFExec_Impl(SfxRequest& rReq)
{
    rReq.AppendItem(SfxBoolItem(SID_SIGNPDF, true));
    GetDispatcher_Impl()->Execute(SID_OPENDOC, SfxCallMode::SYNCHRON, *rReq.GetArgs());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 7771124..c54a0df 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -2593,16 +2593,24 @@ ErrCode FileOpenDialog_Impl( sal_Int16 nDialogType,
                             const css::uno::Sequence< OUString >& rBlackList )
{
    ErrCode nRet;
    FileDialogHelper aDialog( nDialogType, nFlags,
            rFact, nDialog, SfxFilterFlags::NONE, SfxFilterFlags::NONE, rStandardDir, rBlackList );
    std::unique_ptr<FileDialogHelper> pDialog;
    // Sign existing PDF: only works with PDF files and they are opened
    // read-only to discourage editing (which would invalidate existing
    // signatures).
    if (nFlags & FileDialogFlags::SignPDF)
        pDialog.reset(new FileDialogHelper(nDialogType, nFlags, SfxResId(STR_SFX_FILTERNAME_PDF).toString(), "pdf", rStandardDir, rBlackList));
    else
        pDialog.reset(new FileDialogHelper(nDialogType, nFlags, rFact, nDialog, SfxFilterFlags::NONE, SfxFilterFlags::NONE, rStandardDir, rBlackList));

    OUString aPath;
    if ( pPath )
        aPath = *pPath;

    nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath );
    nRet = pDialog->Execute(rpURLList, rpSet, rFilter, aPath);
    DBG_ASSERT( rFilter.indexOf(": ") == -1, "Old filter name used!");

    if (rpSet && nFlags & FileDialogFlags::SignPDF)
        rpSet->Put(SfxBoolItem(SID_DOC_READONLY, true));
    return nRet;
}

diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 40f19ea..0a4f02e 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3502,7 +3502,10 @@ bool SfxMedium::SignContents_Impl( bool bScriptingContent, const OUString& aODFV
                comphelper::getProcessComponentContext(), aODFVersion, bHasValidDocumentSignature ) );

        uno::Reference< embed::XStorage > xWriteableZipStor;
        if ( !IsReadOnly() )
        // Signing is not modification of the document, as seen by the user
        // ("only a saved document can be signed"). So allow signing in the
        // "opened read-only, but not physically-read-only" case.
        if (!IsOriginallyReadOnly())
        {
            // we can reuse the temporary file if there is one already
            CreateTempFile( false );