[Libreoffice-commits] core.git: include/LibreOfficeKit libreofficekit/qa libreofficekit/source

Pranav Kant pranavk at collabora.co.uk
Tue Feb 2 12:30:32 UTC 2016


 include/LibreOfficeKit/LibreOfficeKitGtk.h          |   12 ++
 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx |   50 +++++++++
 libreofficekit/source/gtk/lokdocview.cxx            |  109 +++++++++++++++++++-
 3 files changed, 166 insertions(+), 5 deletions(-)

New commits:
commit 18fbddcca569c109ca2f46f7d791187e672d4d83
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Wed Jan 27 16:56:14 2016 +0530

    lokdocview: Handle password protected documents
    
    Change-Id: I606a1112c8eb4c1cc4596d6947ce1223543cc87c
    Reviewed-on: https://gerrit.libreoffice.org/21861
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index c3e4b28..229bac0 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -286,6 +286,18 @@ gboolean                        lok_doc_view_paste                 (LOKDocView*
                                                                     gsize nSize);
 
 /**
+ * lok_doc_view_set_document_password:
+ * @pDocView: The #LOKDocView instance
+ * @pUrl: the URL of the document to set password for, as sent with signal `password-required`
+ * @pPassword: (nullable): the password, NULL for no password
+ *
+ * Set the password for password protected documents
+ */
+void                            lok_doc_view_set_document_password (LOKDocView* pDocView,
+                                                                    const gchar* pURL,
+                                                                    const gchar* pPassword);
+
+/**
  * lok_doc_view_pixel_to_twip:
  * @pDocView: The #LOKDocView instance
  * @fInput: The value in pixels to convert to twips
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 45ac17e..c294430 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -486,10 +486,20 @@ static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/)
     }
 }
 
+static void
+setLOKFeatures (GtkWidget* pDocView)
+{
+    g_object_set(G_OBJECT(pDocView),
+                 "doc-password", TRUE,
+                 "doc-password-to-modify", TRUE,
+                 nullptr);
+}
+
 /// Common initialization, regardless if it's just a new view or a full init.
 static TiledWindow& setupWidgetAndCreateWindow(GtkWidget* pDocView)
 {
     setupDocView(pDocView);
+    setLOKFeatures(pDocView);
     TiledWindow aWindow;
     aWindow.m_pDocView = pDocView;
     GtkWidget* pWindow = createWindow(aWindow);
@@ -861,6 +871,45 @@ static void formulaChanged(LOKDocView* pLOKDocView, char* pPayload, gpointer /*p
     gtk_entry_set_text(GTK_ENTRY(rWindow.m_pFormulabarEntry), pPayload);
 }
 
+/// LOKDocView password is requried to open the document
+static void passwordRequired(LOKDocView* pLOKDocView, gchar* pUrl, gboolean bModify, gpointer /*pData*/)
+{
+    GtkWidget* pPasswordDialog = gtk_dialog_new_with_buttons ("Password required",
+                                                              GTK_WINDOW (gtk_widget_get_toplevel(GTK_WIDGET(pLOKDocView))),
+                                                              GTK_DIALOG_MODAL,
+                                                              "OK",
+                                                              GTK_RESPONSE_OK,
+                                                              nullptr);
+    g_object_set(G_OBJECT(pPasswordDialog), "resizable", FALSE, nullptr);
+    GtkWidget* pDialogMessageArea = gtk_dialog_get_content_area (GTK_DIALOG (pPasswordDialog));
+    GtkWidget* pPasswordEntry = gtk_entry_new ();
+    gtk_entry_set_visibility (GTK_ENTRY(pPasswordEntry), FALSE);
+    gtk_entry_set_invisible_char (GTK_ENTRY(pPasswordEntry), '*');
+    gtk_box_pack_end(GTK_BOX(pDialogMessageArea), pPasswordEntry, TRUE, TRUE, 2);
+    if (bModify)
+    {
+        GtkWidget* pSecondaryLabel = gtk_label_new ("Document requires password to edit");
+        gtk_box_pack_end(GTK_BOX(pDialogMessageArea), pSecondaryLabel, TRUE, TRUE, 2);
+        gtk_dialog_add_button (GTK_DIALOG (pPasswordDialog), "Open as read-only", GTK_RESPONSE_ACCEPT);
+    }
+    gtk_widget_show_all(pPasswordDialog);
+
+    gint res = gtk_dialog_run (GTK_DIALOG(pPasswordDialog));
+    switch (res)
+    {
+    case GTK_RESPONSE_OK:
+        lok_doc_view_set_document_password (pLOKDocView, pUrl, gtk_entry_get_text(GTK_ENTRY(pPasswordEntry)));
+        break;
+    case GTK_RESPONSE_ACCEPT:
+        // User accepts to open this document as read-only
+    case GTK_RESPONSE_DELETE_EVENT:
+        lok_doc_view_set_document_password (pLOKDocView, pUrl, nullptr);
+        break;
+    }
+
+    gtk_widget_destroy(pPasswordDialog);
+}
+
 static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/)
 {
     TiledWindow& rWindow = lcl_getTiledWindow(pWidget);
@@ -1353,6 +1402,7 @@ static void setupDocView(GtkWidget* pDocView)
     g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), nullptr);
     g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), nullptr);
     g_signal_connect(pDocView, "formula-changed", G_CALLBACK(formulaChanged), nullptr);
+    g_signal_connect(pDocView, "password-required", G_CALLBACK(passwordRequired), nullptr);
 }
 
 int main( int argc, char* argv[] )
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 825a72f..17104a0 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -65,6 +65,8 @@ struct LOKDocViewPrivateImpl
     glong m_nDocumentHeightTwips;
     /// View or edit mode.
     gboolean m_bEdit;
+    /// LOK Features
+    guint64 m_nLOKFeatures;
     /// Position and size of the visible cursor.
     GdkRectangle m_aVisibleCursor;
     /// Cursor overlay is visible or hidden (for blinking).
@@ -147,6 +149,7 @@ struct LOKDocViewPrivateImpl
         m_nDocumentWidthTwips(0),
         m_nDocumentHeightTwips(0),
         m_bEdit(FALSE),
+        m_nLOKFeatures(0),
         m_aVisibleCursor({0, 0, 0, 0}),
         m_bCursorOverlayVisible(false),
         m_bCursorVisible(true),
@@ -204,6 +207,7 @@ enum
     COMMAND_RESULT,
     FORMULA_CHANGED,
     TEXT_SELECTION,
+    PASSWORD_REQUIRED,
 
     LAST_SIGNAL
 };
@@ -224,6 +228,8 @@ enum
     PROP_DOC_HEIGHT,
     PROP_CAN_ZOOM_IN,
     PROP_CAN_ZOOM_OUT,
+    PROP_DOC_PASSWORD,
+    PROP_DOC_PASSWORD_TO_MODIFY,
 
     PROP_LAST
 };
@@ -323,6 +329,10 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_SET_PART";
     case LOK_CALLBACK_SEARCH_RESULT_SELECTION:
         return "LOK_CALLBACK_SEARCH_RESULT_SELECTION";
+    case LOK_CALLBACK_DOCUMENT_PASSWORD:
+        return "LOK_CALLBACK_DOCUMENT_PASSWORD";
+    case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY:
+        return "LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY";
     }
     return nullptr;
 }
@@ -831,6 +841,7 @@ globalCallback (gpointer pData)
 {
     CallbackData* pCallback = static_cast<CallbackData*>(pData);
     LOKDocViewPrivate& priv = getPrivate(pCallback->m_pDocView);
+    gboolean bModify = false;
 
     switch (pCallback->m_nType)
     {
@@ -852,12 +863,12 @@ globalCallback (gpointer pData)
         g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 1.0);
     }
     break;
-    case LOK_CALLBACK_DOCUMENT_PASSWORD:
     case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY:
+        bModify = true;
+    case LOK_CALLBACK_DOCUMENT_PASSWORD:
     {
         char const*const pURL(pCallback->m_aPayload.c_str());
-        // TODO maybe allow more passwords
-        priv->m_pOffice->pClass->setDocumentPassword(priv->m_pOffice, pURL, "1");
+        g_signal_emit (pCallback->m_pDocView, doc_view_signals[PASSWORD_REQUIRED], 0, pURL, bModify);
     }
     break;
     default:
@@ -1960,6 +1971,8 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal
 {
     LOKDocView* pDocView = LOK_DOC_VIEW (object);
     LOKDocViewPrivate& priv = getPrivate(pDocView);
+    gboolean bDocPasswordEnabled = priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD;
+    gboolean bDocPasswordToModifyEnabled = priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY;
 
     switch (propId)
     {
@@ -1987,6 +2000,20 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal
     case PROP_DOC_HEIGHT:
         priv->m_nDocumentHeightTwips = g_value_get_long (value);
         break;
+    case PROP_DOC_PASSWORD:
+        if (g_value_get_boolean (value) != bDocPasswordEnabled)
+        {
+            priv->m_nLOKFeatures = priv->m_nLOKFeatures ^ LOK_FEATURE_DOCUMENT_PASSWORD;
+            priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, priv->m_nLOKFeatures);
+        }
+        break;
+    case PROP_DOC_PASSWORD_TO_MODIFY:
+        if ( g_value_get_boolean (value) != bDocPasswordToModifyEnabled)
+        {
+            priv->m_nLOKFeatures = priv->m_nLOKFeatures ^ LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY;
+            priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, priv->m_nLOKFeatures);
+        }
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec);
     }
@@ -2035,6 +2062,12 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va
     case PROP_CAN_ZOOM_OUT:
         g_value_set_boolean (value, priv->m_bCanZoomOut);
         break;
+    case PROP_DOC_PASSWORD:
+        g_value_set_boolean (value, priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD);
+        break;
+    case PROP_DOC_PASSWORD_TO_MODIFY:
+        g_value_set_boolean (value, priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec);
     }
@@ -2084,8 +2117,6 @@ static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* /
         return FALSE;
     }
 
-//    priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, LOK_FEATURE_DOCUMENT_PASSWORD|LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY);
-
     return TRUE;
 }
 
@@ -2273,6 +2304,33 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
                              static_cast<GParamFlags>(G_PARAM_READABLE
                                                       | G_PARAM_STATIC_STRINGS));
 
+    /**
+     * LOKDocView:doc-password:
+     *
+     * Set it to true if client supports providing password for viewing
+     * password protected documents
+     */
+    properties[PROP_DOC_PASSWORD] =
+        g_param_spec_boolean("doc-password",
+                             "Document password capability",
+                             "Whether client supports providing document passwords",
+                             FALSE,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE
+                                                      | G_PARAM_STATIC_STRINGS));
+
+    /**
+     * LOKDocView:doc-password-to-modify:
+     *
+     * Set it to true if client supports providing password for edit-protected documents
+     */
+    properties[PROP_DOC_PASSWORD_TO_MODIFY] =
+        g_param_spec_boolean("doc-password-to-modify",
+                             "Edit document password capability",
+                             "Whether the client supports providing passwords to edit documents",
+                             FALSE,
+                             static_cast<GParamFlags>(G_PARAM_READWRITE
+                                                      | G_PARAM_STATIC_STRINGS));
+
     g_object_class_install_properties(pGObjectClass, PROP_LAST, properties);
 
     /**
@@ -2459,6 +2517,37 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
                      g_cclosure_marshal_VOID__BOOLEAN,
                      G_TYPE_NONE, 1,
                      G_TYPE_BOOLEAN);
+
+    /**
+     * LOKDocView::password-required:
+     * @pDocView: the #LOKDocView on which the signal is emitted
+     * @pUrl: URL of the document for which password is required
+     * @bModify: whether password id required to modify the document
+     * This is true when password is required to edit the document,
+     * while it can still be viewed without password. In such cases, provide a NULL
+     * password for read-only access to the document.
+     * If false, password is required for opening the document, and document
+     * cannot be opened without providing a valid password.
+     *
+     * Password must be provided by calling lok_doc_view_set_document_password
+     * function with pUrl as provided by the callback.
+     *
+     * Upon entering a invalid password, another `password-required` signal is
+     * emitted.
+     * Upon entering a valid password, document starts to load.
+     * Upon entering a NULL password: if bModify is %TRUE, document starts to
+     * open in view-only mode, else loading of document is aborted.
+     */
+    doc_view_signals[PASSWORD_REQUIRED] =
+        g_signal_new("password-required",
+                     G_TYPE_FROM_CLASS(pGObjectClass),
+                     G_SIGNAL_RUN_FIRST,
+                     0,
+                     nullptr, nullptr,
+                     g_cclosure_marshal_generic,
+                     G_TYPE_NONE, 2,
+                     G_TYPE_STRING,
+                     G_TYPE_BOOLEAN);
 }
 
 SAL_DLLPUBLIC_EXPORT GtkWidget*
@@ -2859,6 +2948,16 @@ lok_doc_view_paste (LOKDocView* pDocView,
     return ret;
 }
 
+SAL_DLLPUBLIC_EXPORT void
+lok_doc_view_set_document_password (LOKDocView* pDocView,
+                                    const gchar* pURL,
+                                    const gchar* pPassword)
+{
+    LOKDocViewPrivate& priv = getPrivate(pDocView);
+
+    priv->m_pOffice->pClass->setDocumentPassword(priv->m_pOffice, pURL, pPassword);
+}
+
 SAL_DLLPUBLIC_EXPORT gfloat
 lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput)
 {


More information about the Libreoffice-commits mailing list