[vlc-devel] [PATCH 04/10][RFC][WIP] dialog: add new dialog that spawns a browsers if the user allows

Diogo Silva dbtdsilva at gmail.com
Thu Aug 17 03:08:12 CEST 2017


This function invokes a question dialog in order to warn the user
that a browser is required and then, if allowed, spawns the user's
default browser
---
 include/vlc/libvlc_dialog.h         |  8 ++++++++
 include/vlc_dialog.h                | 36 ++++++++++++++++++++++++++++++++++++
 lib/dialog.c                        |  9 +++++++++
 modules/gui/qt/dialogs/external.cpp | 18 +++++++++++++++++-
 modules/gui/qt/dialogs/external.hpp |  3 +++
 src/interface/dialog.c              | 37 +++++++++++++++++++++++++++++++++++++
 src/libvlccore.sym                  |  2 ++
 7 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/include/vlc/libvlc_dialog.h b/include/vlc/libvlc_dialog.h
index b176b93621..75002e94ae 100644
--- a/include/vlc/libvlc_dialog.h
+++ b/include/vlc/libvlc_dialog.h
@@ -152,6 +152,14 @@ typedef struct libvlc_dialog_cbs
      */
     void (*pf_update_progress)(void *p_data, libvlc_dialog_id *p_id,
                                float f_position, const char *psz_text);
+
+    /**
+     * Called when a browser requires to be spawned
+     *
+     * @param p_data opaque pointer for the callback
+     * @param psz_url spawns the default browser in the following url
+     */
+    void (*pf_spawn_browser)(void *p_data, const char *psz_url);
 } libvlc_dialog_cbs;

 /**
diff --git a/include/vlc_dialog.h b/include/vlc_dialog.h
index 23df3cb9ea..7385716251 100644
--- a/include/vlc_dialog.h
+++ b/include/vlc_dialog.h
@@ -238,6 +238,34 @@ vlc_dialog_update_progress_text_va(vlc_object_t *p_obj, vlc_dialog_id *p_id,
                                    float f_position, const char *psz_fmt,
                                    va_list ap);

+/**
+ * This functions spawns the default webbrowser. Before spawning a
+ * webbrowser, it warns the user that a webbrowser is going to be opened. That
+ * warning dialog can be skipped if psz_title is equals to NULL
+ *
+ * @param p_obj the VLC object emitting the browser
+ * @param psz_url spawns the default browser in the following url
+ * @param psz_title (optional) title of the warning dialog
+ * @param psz_fmt format string for the warning message
+ * @return < 0 on error, 0 if the user cancelled to open browser, 1 if browser
+ * was opened
+ */
+VLC_API int
+vlc_spawn_browser(vlc_object_t *p_obj, const char *psz_url,
+                  const char *dialog_title, const char *psz_fmt, ...)
+                  VLC_FORMAT(4, 5);
+#define vlc_spawn_browser(a, b, c, d, ...) \
+    vlc_spawn_browser(VLC_OBJECT(a), b, c, d, ##__VA_ARGS__)
+
+/**
+ * This functions spawns the default webbrowser with a warning dialog.
+ *
+ * Equivalent to vlc_spawn_browser() expect that it's called with a va_list.
+ */
+VLC_API int
+vlc_spawn_browser_va(vlc_object_t *p_obj, const char *psz_url,
+                  const char *dialog_title, const char *psz_fmt, va_list ap);
+
 /**
  * Release the dialog id returned by vlc_dialog_display_progress()
  *
@@ -377,6 +405,14 @@ typedef struct vlc_dialog_cbs
      */
     void (*pf_update_progress)(void *p_data, vlc_dialog_id *p_id,
                                float f_position, const char *psz_text);
+
+    /**
+     * Called when a browser requires to be spawned
+     *
+     * @param p_data opaque pointer for the callback
+     * @param psz_url spawns the default browser in the following url
+     */
+    void (*pf_spawn_browser)(void *p_data, const char *psz_url);
 } vlc_dialog_cbs;

 /**
diff --git a/lib/dialog.c b/lib/dialog.c
index 2fd936b2e4..6c24353edf 100644
--- a/lib/dialog.c
+++ b/lib/dialog.c
@@ -115,6 +115,13 @@ update_progress_cb(void *p_data, vlc_dialog_id *p_id, float f_position,
                                               f_position, psz_text);
 }

+static void
+spawn_browser_cb(void *p_data, const char *psz_url)
+{
+    libvlc_instance_t *p_instance = p_data;
+    p_instance->dialog.cbs.pf_spawn_browser(p_instance->dialog.data, psz_url);
+}
+
 void
 libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
                             const libvlc_dialog_cbs *p_cbs, void *p_data)
@@ -136,6 +143,8 @@ libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
             .pf_cancel = p_cbs->pf_cancel != NULL ? cancel_cb : NULL,
             .pf_update_progress = p_cbs->pf_update_progress != NULL ?
                                   update_progress_cb : NULL,
+            .pf_spawn_browser = p_cbs->pf_spawn_browser != NULL ?
+                                spawn_browser_cb : NULL,
         };

         p_instance->dialog.cbs = *p_cbs;
diff --git a/modules/gui/qt/dialogs/external.cpp b/modules/gui/qt/dialogs/external.cpp
index b85de56a8f..a744f3a0b3 100644
--- a/modules/gui/qt/dialogs/external.cpp
+++ b/modules/gui/qt/dialogs/external.cpp
@@ -29,6 +29,7 @@
 #include <assert.h>

 #include <QCheckBox>
+#include <QDesktopServices>
 #include <QDialogButtonBox>
 #include <QLabel>
 #include <QLineEdit>
@@ -45,7 +46,8 @@ DialogHandler::DialogHandler (intf_thread_t *p_intf, QObject *_parent)
         displayQuestionCb,
         displayProgressCb,
         cancelCb,
-        updateProgressCb
+        updateProgressCb,
+        spawnBrowserCb
     };
     vlc_dialog_provider_set_callbacks(p_intf, &cbs, this);

@@ -73,6 +75,9 @@ DialogHandler::DialogHandler (intf_thread_t *p_intf, QObject *_parent)

     CONNECT(this, progressUpdated(vlc_dialog_id *, float, const QString &),
             this, updateProgress(vlc_dialog_id *, float, const QString &));
+
+    CONNECT(this, browserSpawned(const QString &),
+            this, spawnBrowser(const QString &));
 }

 DialogHandler::~DialogHandler()
@@ -156,6 +161,12 @@ void DialogHandler::updateProgressCb(void *p_data, vlc_dialog_id *p_id,
     emit self->progressUpdated(p_id, f_value, qfu(psz_text));
 }

+void DialogHandler::spawnBrowserCb(void *p_data, const char *psz_url)
+{
+    DialogHandler *self =  static_cast<DialogHandler *>(p_data);
+    emit self->browserSpawned(qfu(psz_url));
+}
+
 void DialogHandler::cancel(vlc_dialog_id *p_id)
 {
     DialogWrapper *p_wrapper =
@@ -177,6 +188,11 @@ void DialogHandler::updateProgress(vlc_dialog_id *p_id, float f_value,
         p_progress_wrapper->updateProgress(f_value, text);
 }

+void DialogHandler::spawnBrowser(const QString &url)
+{
+    QDesktopServices::openUrl(QUrl(url));
+}
+
 void DialogHandler::displayError(const QString &title, const QString &text)
 {
     ErrorsDialog::getInstance (p_intf)->addError(title, text);
diff --git a/modules/gui/qt/dialogs/external.hpp b/modules/gui/qt/dialogs/external.hpp
index 64696e4597..d34cb34cca 100644
--- a/modules/gui/qt/dialogs/external.hpp
+++ b/modules/gui/qt/dialogs/external.hpp
@@ -59,6 +59,7 @@ signals:
                            float f_position, const QString &cancel);
     void cancelled(vlc_dialog_id *p_id);
     void progressUpdated(vlc_dialog_id *p_id, float f_value, const QString &text);
+    void browserSpawned(const QString& url);

 private slots:
     void displayError(const QString &title, const QString &text);
@@ -74,6 +75,7 @@ private slots:
                          float f_position, const QString &cancel);
     void cancel(vlc_dialog_id *p_id);
     void updateProgress(vlc_dialog_id *p_id, float f_value, const QString &text);
+    void spawnBrowser(const QString &url);

 private:
     intf_thread_t *p_intf;
@@ -88,6 +90,7 @@ private:
                                   const char *, bool, float, const char *);
     static void cancelCb(void *, vlc_dialog_id *);
     static void updateProgressCb(void *, vlc_dialog_id *, float, const char *);
+    static void spawnBrowserCb(void *, const char *);
 };

 class DialogWrapper : public QObject
diff --git a/src/interface/dialog.c b/src/interface/dialog.c
index 38ec83b0db..14ffbbb80f 100644
--- a/src/interface/dialog.c
+++ b/src/interface/dialog.c
@@ -697,6 +697,43 @@ vlc_dialog_update_progress_text(vlc_object_t *p_obj, vlc_dialog_id *p_id,
     return i_ret;
 }

+#undef vlc_spawn_browser
+int
+vlc_spawn_browser(vlc_object_t *p_obj, const char *psz_url,
+                  const char *dialog_title, const char *psz_fmt, ...)
+{
+    assert(psz_fmt != NULL);
+    va_list ap;
+    va_start(ap, psz_fmt);
+    int i_ret = vlc_spawn_browser_va(p_obj, psz_url, dialog_title, psz_fmt, ap);
+    va_end(ap);
+
+    return i_ret;
+}
+
+int
+vlc_spawn_browser_va(vlc_object_t *p_obj, const char *psz_url,
+                  const char *dialog_title, const char *psz_fmt, va_list ap)
+{
+    assert(psz_url != NULL);
+
+    if (dialog_title != NULL)
+    {
+        int ret = vlc_dialog_wait_question_va(p_obj,
+                VLC_DIALOG_QUESTION_WARNING, "Cancel", "Open", NULL,
+                dialog_title, psz_fmt, ap);
+        if (ret <= 0)
+            return ret;
+    }
+
+    vlc_dialog_provider *p_provider = get_dialog_provider(p_obj, false);
+    if (p_provider->cbs.pf_spawn_browser == NULL)
+        return VLC_EGENERIC;
+
+    p_provider->cbs.pf_spawn_browser(p_provider->p_cbs_data, psz_url);
+    return 1;
+}
+
 #undef vlc_dialog_release
 void
 vlc_dialog_release(vlc_object_t *p_obj, vlc_dialog_id *p_id)
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index ab9cb15890..f78a11e65c 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -559,6 +559,8 @@ vlc_sem_init
 vlc_sem_destroy
 vlc_sem_post
 vlc_sem_wait
+vlc_spawn_browser
+vlc_spawn_browser_va
 vlc_control_cancel
 vlc_GetCPUCount
 vlc_CPU
--
2.14.1


More information about the vlc-devel mailing list