summaryrefslogtreecommitdiff
path: root/src/editor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editor.c')
-rw-r--r--src/editor.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/editor.c b/src/editor.c
new file mode 100644
index 00000000..ccef61aa
--- /dev/null
+++ b/src/editor.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2010-2013 Stefan Bolte <portix@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+#include "dwb.h"
+#include "editor.h"
+#include "util.h"
+#include "dom.h"
+
+typedef struct _EditorInfo {
+ char *filename;
+ char *id;
+ GList *gl;
+ WebKitDOMElement *element;
+ char *tagname;
+} EditorInfo;
+
+/* dwb_editor_watch (GChildWatchFunc) {{{*/
+static void
+editor_watch(GPid pid, int status, EditorInfo *info)
+{
+ gsize length;
+ WebKitDOMElement *e = NULL;
+ WebKitWebView *wv;
+
+ char *content = util_get_file_content(info->filename, &length);
+
+ if (content == NULL)
+ goto clean;
+
+ if (!info->gl || !g_list_find(dwb.state.views, info->gl->data))
+ {
+ if (info->id == NULL)
+ goto clean;
+ else
+ wv = CURRENT_WEBVIEW();
+ }
+ else
+ wv = WEBVIEW(info->gl);
+ if (info->id != NULL)
+ {
+ WebKitDOMDocument *doc = webkit_web_view_get_dom_document(wv);
+ e = webkit_dom_document_get_element_by_id(doc, info->id);
+
+ if (e == NULL && (e = info->element) == NULL )
+ goto clean;
+ }
+ else if (info->element)
+ e = info->element;
+ else
+ goto clean;
+
+ /* g_file_get_contents adds an additional newline */
+ if (length > 0 && content[length-1] == '\n')
+ content[length-1] = 0;
+
+ if (!strcasecmp(info->tagname, "INPUT"))
+ webkit_dom_html_input_element_set_value(WEBKIT_DOM_HTML_INPUT_ELEMENT(e), content);
+ else if (!strcasecmp(info->tagname, "TEXTAREA"))
+ webkit_dom_html_text_area_element_set_value(WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT(e), content);
+
+clean:
+ unlink(info->filename);
+ g_free(info->filename);
+ g_free(info->id);
+ g_free(info);
+}/*}}}*/
+
+static gboolean
+navigation_cb(WebKitWebView *web, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *action,
+ WebKitWebPolicyDecision *policy, EditorInfo *info)
+{
+ if (frame == webkit_web_view_get_main_frame(web))
+ {
+ info->element = NULL;
+ g_free(info->id);
+ info->id = NULL;
+ g_signal_handler_disconnect(web, VIEW(info->gl)->status->signals[SIG_EDITOR_NAVIGATION]);
+ }
+ return false;
+}
+
+/* dwb_open_in_editor(void) ret: gboolean success {{{*/
+DwbStatus
+editor_open(void)
+{
+ DwbStatus ret = STATUS_OK;
+ char **commands = NULL;
+ char *commandstring = NULL, *tagname, *path;
+ char *value = NULL;
+ GPid pid;
+ gboolean success;
+
+ char *editor = GET_CHAR("editor");
+
+ if (editor == NULL)
+ return STATUS_ERROR;
+
+ WebKitDOMDocument *doc = webkit_web_view_get_dom_document(CURRENT_WEBVIEW());
+ WebKitDOMElement *active = dom_get_active_element(doc);
+
+ if (active == NULL)
+ return STATUS_ERROR;
+
+ tagname = webkit_dom_element_get_tag_name(active);
+ if (tagname == NULL)
+ {
+ ret = STATUS_ERROR;
+ goto clean;
+ }
+ if (! strcasecmp(tagname, "INPUT"))
+ value = webkit_dom_html_input_element_get_value(WEBKIT_DOM_HTML_INPUT_ELEMENT(active));
+ else if (! strcasecmp(tagname, "TEXTAREA"))
+ value = webkit_dom_html_text_area_element_get_value(WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT(active));
+
+ if (value == NULL)
+ {
+ ret = STATUS_ERROR;
+ goto clean;
+ }
+
+ path = util_get_temp_filename("edit");
+
+ commandstring = util_string_replace(editor, "dwb_uri", path);
+ if (commandstring == NULL)
+ {
+ ret = STATUS_ERROR;
+ goto clean;
+ }
+
+ g_file_set_contents(path, value, -1, NULL);
+ commands = g_strsplit(commandstring, " ", -1);
+ g_free(commandstring);
+
+ success = g_spawn_async(NULL, commands, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL);
+ g_strfreev(commands);
+ if (!success)
+ {
+ ret = STATUS_ERROR;
+ goto clean;
+ }
+
+ EditorInfo *info = dwb_malloc(sizeof(EditorInfo));
+ char *id = webkit_dom_html_element_get_id(WEBKIT_DOM_HTML_ELEMENT(active));
+ if (id != NULL && strlen(id) > 0) {
+ info->id = id;
+ }
+ else {
+ info->id = NULL;
+ }
+ info->tagname = tagname;
+ info->element = active;
+ info->filename = path;
+ info->gl = dwb.state.fview;
+ g_child_watch_add(pid, (GChildWatchFunc)editor_watch, info);
+ VIEW(dwb.state.fview)->status->signals[SIG_EDITOR_NAVIGATION] =
+ g_signal_connect(CURRENT_WEBVIEW(), "navigation-policy-decision-requested", G_CALLBACK(navigation_cb), info);
+clean:
+ g_free(value);
+
+ return ret;
+}/*}}}*/