summaryrefslogtreecommitdiff
path: root/libreofficekit
diff options
context:
space:
mode:
authorPranav Kant <pranavk@collabora.co.uk>2016-01-27 16:56:14 +0530
committerCaolán McNamara <caolanm@redhat.com>2016-02-02 12:29:51 +0000
commit18fbddcca569c109ca2f46f7d791187e672d4d83 (patch)
tree8ef9c30e4f48156c30319b0c3b54a87d97b972fd /libreofficekit
parent59aee037e3cf33b253b6f5ebafe3872e420d3408 (diff)
lokdocview: Handle password protected documents
Change-Id: I606a1112c8eb4c1cc4596d6947ce1223543cc87c Reviewed-on: https://gerrit.libreoffice.org/21861 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'libreofficekit')
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx50
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx109
2 files changed, 154 insertions, 5 deletions
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 45ac17e1f134..c29443087fae 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 825a72fb05de..17104a00b838 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)
{