//#define DEBUGON 1
-
#ifdef DEBUGON
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
#else
static Evas_Object *image_provider(void *images, Evas_Object *entry, const char *item);
static void entry_deleted(void *images, Evas *e, Evas_Object *entry, void *unused);
-
static Eina_Bool targets_converter(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
static Eina_Bool text_converter(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
static Eina_Bool html_converter(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
static Paste_Image *pasteimage_alloc(const char *file, int pathlen);
static Eina_Bool pasteimage_append(Paste_Image *pi, Evas_Object *entry);
static void pasteimage_free(Paste_Image *pi);
+static void entry_insert_filter(Evas_Object* entry, char* str);
/* Optimisation: Turn this into a 256 byte table:
* then can lookup in one index, not N checks */
static const Escape escapes[] = {
- { "<br>", '\n' },
- { "<\t>", '\t' },
- { "gt;", '>' },
- { "lt;", '<' },
- { "amp;", '&' },
- { "quot;", '\'' },
- { "dquot;", '"' }
+ { "<br>", '\n' },
+ { "<ps>", '\n' },
+ { "<\t>", '\t' },
+ { "gt;", '>' },
+ { "lt;", '<' },
+ { "amp;", '&' },
+ { "quot;", '\'' },
+ { "dquot;", '"' }
};
#define N_ESCAPES ((int)(sizeof(escapes) / sizeof(escapes[0])))
},
[CNP_ATOM_XELM] = {
"application/x-elementary-markup",
- ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
+ ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
edje_converter,
NULL,
notify_handler_edje,
/* Stringshared, so I can just compare pointers later */
static const char *text_uri;
-
/* For convert EFL to HTML */
#define TAGPOS_START 0x00000001
{"underline", "del", 0},
{"strikethrough", "ins", 0},
{"br", "br", 1},
+ {"ps", "br", 1},
{"b", "b", 1},
{"item", "img", 1}
};
_new_tag_node(char *tag, char *tag_str, char* str, char *pos_in_ori_str)
{
PTagNode newNode = calloc(1, sizeof(TagNode));
+ if (tag)
+ eina_str_tolower(&tag);
newNode->tag = tag;
+ if (tag_str)
+ eina_str_tolower(&tag_str);
newNode->tag_str = tag_str;
newNode->str = str;
newNode->pos_in_ori_str = pos_in_ori_str;
char *valueEnd = strchr(value, '\0');
int i;
- for (i = 0; i < spCnt; i++)
+ int start = 0;
+ if ((!strncmp(tag_str, "<item", 5) && !strcmp(tag_name, "href")) // EFL img tag
+ || (!strncmp(tag_str, "<img", 4) && !strcmp(tag_name, "src"))) // HTML img tag
+ start = 1;
+
+ for (i = start; i < spCnt; i++)
{
if (spArray[i] && spArray[i] < valueEnd)
valueEnd = spArray[i];
if (path)
{
char *modify = malloc(sizeof(char) * (strlen(value) + 1));
- strncpy(modify, "file://", 7);
- modify[7] = '\0';
+ strncpy(modify, "file://", 8);
path += 7;
while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
{
strcat(modify, path);
data->href = modify;
cnp_debug("image href ---%s---\n", data->href);
+ free(value);
}
else
freeAndAssign(data->href, value);
- free(value);
}
value = _get_tag_value(tag_str, "absize");
if (path)
{
char *modify = malloc(sizeof(char) * (strlen(value) + 1));
- strncpy(modify, "file://", 7);
- modify[7] = '\0';
+ strncpy(modify, "file://", 8);
path += 7;
while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
{
strcat(modify, path);
data->href = modify;
cnp_debug("image src ---%s---\n", data->href);
+ free(value);
}
else
freeAndAssign(data->href, value);
- free(value);
}
value = _get_tag_value(tag_str, "width");
}
switch(trail->tagPosType)
{
+ /* closed tag does not need in HTML
case TAGPOS_ALONE:
eina_strbuf_append(html, " />");
- break;
+ break;*/
default:
eina_strbuf_append(html, ">");
break;
else if (!strcmp(_HTMLtoEFLConvertTable[j].src, "img"))
{
PItemTagData data = trail->tagData;
- char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT; if (data->width)
+ char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
+ if (data->width)
width = data->width;
if (data->height)
height = data->height;
}
switch(trail->tagPosType)
{
+ /* not support in efl
case TAGPOS_ALONE:
eina_strbuf_append(html, " />");
break;
+ */
default:
eina_strbuf_append(html, ">");
break;
return ret;
}
+
Eina_Bool
elm_selection_set(Elm_Sel_Type selection, Evas_Object *widget, Elm_Sel_Format format, const char *selbuf)
{
#ifdef HAVE_ELEMENTARY_X
+ Evas_Object *top = elm_widget_top_get(widget);
+ Ecore_X_Window xwin;
Cnp_Selection *sel;
+ if (top) xwin = elm_win_xwindow_get(top);
+ else xwin = elm_win_xwindow_get(widget);
+ if (!xwin) return EINA_FALSE;
if ((unsigned int)selection >= (unsigned int)ELM_SEL_MAX) return EINA_FALSE;
if (!_elm_cnp_init_count) _elm_cnp_init();
if ((!selbuf) && (format != ELM_SEL_FORMAT_IMAGE))
sel->active = 1;
sel->widget = widget;
- sel->set(elm_win_xwindow_get(widget),&selection,sizeof(Elm_Sel_Type));
+ sel->set(xwin, &selection, sizeof(Elm_Sel_Type));
sel->format = format;
sel->selbuf = selbuf ? strdup(selbuf) : NULL;
Cnp_Selection *sel;
if (!data_ret) return EINA_FALSE;
+ if (!data || (*((unsigned int *)data) >= ELM_SEL_MAX))
+ return EINA_FALSE;
sel = selections + *((int *)data);
return EINA_TRUE;
}
+
+static Eina_Bool
+is_uri_type_data(Cnp_Selection *sel __UNUSED__, Ecore_X_Event_Selection_Notify *notify)
+{
+ Ecore_X_Selection_Data *data;
+ char *p;
+
+ data = notify->data;
+ cnp_debug("data->format is %d %p %p\n", data->format, notify, data);
+ if (data->content == ECORE_X_SELECTION_CONTENT_FILES) return EINA_TRUE;
+ else p = (char *)data->data;
+
+ if (!p) return EINA_TRUE;
+ cnp_debug("Got %s\n", p);
+ if (strncmp(p, "file://", 7))
+ {
+ if (*p != '/') return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
/*
* Callback to handle a targets response on a selection request:
* So pick the format we'd like; and then request it.
{
Ecore_X_Selection_Data_Targets *targets;
Ecore_X_Atom *atomlist;
+ Evas_Object *top;
int i, j;
targets = notify->data;
{
if ((atoms[j].atom == atomlist[i]) && (atoms[j].notify))
{
+#if 0
+ if ((j == CNP_ATOM_text_uri) ||
+ (j == CNP_ATOM_text_urilist))
+ {
+ if(!is_uri_type_data(sel, notify)) continue;
+ }
+#endif
cnp_debug("Atom %s matches\n",atoms[j].name);
goto done;
}
return ECORE_CALLBACK_PASS_ON;
done:
- cnp_debug("Sending request for %s\n",atoms[j].name);
- sel->request(elm_win_xwindow_get(sel->requestwidget), atoms[j].name);
+ top = elm_widget_top_get(sel->requestwidget);
+ if (!top) top = sel->requestwidget;
+ cnp_debug("Sending request for %s\n", atoms[j].name);
+ sel->request(elm_win_xwindow_get(top), atoms[j].name);
return ECORE_CALLBACK_PASS_ON;
}
return 0;
}
+static void
+entry_insert_filter(Evas_Object* entry, char* str)
+{
+ if (!entry || !str)
+ return;
+
+ char *insertStr = str;
+ // if entry has text only set then remove item tags
+ if (elm_entry_cnp_textonly_get(entry))
+ {
+ while (EINA_TRUE)
+ {
+ char *startTag = NULL;
+ char *endTag = NULL;
+
+ startTag = strstr(insertStr, "<item");
+ if (!startTag)
+ startTag = strstr(insertStr, "</item");
+ if (startTag)
+ endTag = strstr(startTag, ">");
+ else
+ break;
+ if (!endTag || startTag > endTag)
+ {
+ cnp_debug("Broken tag: %s\n", str);
+ break;
+ }
+
+ size_t sindex = startTag - insertStr;
+ size_t eindex = endTag - insertStr + 1;
+
+ Eina_Strbuf *buf = eina_strbuf_new();
+ if (buf)
+ {
+ eina_strbuf_append(buf, insertStr);
+ eina_strbuf_remove(buf, sindex, eindex);
+ insertStr = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ }
+ }
+ }
+ cnp_debug("remove item tag: %s\n", insertStr);
+
+ // if entry has single line set then remove <br> & <ps> tags
+ if (elm_entry_single_line_get(entry))
+ {
+ Eina_Strbuf *buf = eina_strbuf_new();
+ if (buf)
+ {
+ eina_strbuf_append(buf, insertStr);
+ eina_strbuf_replace_all(buf, "<br>", "");
+ eina_strbuf_replace_all(buf, "<ps>", "");
+ insertStr = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ }
+ }
+ cnp_debug("remove break tag: %s\n", insertStr);
+
+ elm_entry_entry_insert(entry, insertStr);
+
+ if (insertStr != str)
+ free(insertStr);
+}
static int
notify_handler_text(Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *notify)
if (sel->datacb)
{
Elm_Selection_Data ddata;
-
- str = mark_up((char *)data->data, data->length, NULL);
+
+ str = strdup(data->data);
ddata.x = ddata.y = 0;
ddata.format = ELM_SEL_FORMAT_TEXT;
ddata.data = str;
free(str);
return 0;
}
-
+
cnp_debug("Notify handler text %d %d %p\n", data->format,data->length, data->data);
str = mark_up((char *)data->data, data->length, NULL);
cnp_debug("String is %s (from %s)\n", str, data->data);
- elm_entry_entry_insert(sel->requestwidget, str);
+ entry_insert_filter(sel->requestwidget, str);
+ //elm_entry_entry_insert(sel->requestwidget, str);
free(str);
return 0;
}
Ecore_X_Selection_Data *data;
Ecore_X_Selection_Data_Files *files;
Paste_Image *pi;
- char *p;
+ char *p, *stripstr;
data = notify->data;
cnp_debug("data->format is %d %p %p\n", data->format, notify, data);
cnp_debug("more then one file: Bailing\n");
return 0;
}
- p = files->files[0];
+ stripstr = p = strdup(files->files[0]);
}
else
{
- p = (char *)data->data;
+ stripstr = p = strndup((char *)data->data, data->length);
}
if (!p)
if (sel->datacb)
{
Elm_Selection_Data ddata;
-
+
ddata.x = ddata.y = 0;
ddata.format = ELM_SEL_FORMAT_MARKUP;
ddata.data = p;
ddata.len = data->length;
sel->datacb(sel->udata, sel->widget, &ddata);
+ free(p);
return 0;
}
if (strncmp(p, "file://", 7))
{
/* Try and continue if it looks sane */
- if (*p != '/') return 0;
+ if (*p != '/')
+ {
+ free(p);
+ return 0;
+ }
}
else
{
pasteimage_append(pi, sel->requestwidget);
savedtypes.pi = NULL;
}
+ free(stripstr);
return 0;
}
sel->datacb(sel->udata, sel->widget, &ddata);
}
else
- elm_entry_entry_insert(sel->requestwidget, stripstr);
+ entry_insert_filter(sel->requestwidget, stripstr);
+ //elm_entry_entry_insert(sel->requestwidget, stripstr);
cnp_debug("String is %s (%d bytes)\n", stripstr, data->length);
free(stripstr);
return 0;
}
+
/**
* Warning: Generic text/html can';t handle it sanely.
* Firefox sends ucs2 (i think).
sel->datacb(sel->udata, sel->widget, &ddata);
}
else
- elm_entry_entry_insert(sel->requestwidget, stripstr);
+ entry_insert_filter(sel->requestwidget, stripstr);
+ //elm_entry_entry_insert(sel->requestwidget, stripstr);
cnp_debug("String is %s (%d bytes)\n", stripstr, data->length);
free(stripstr);
if (size_ret) *size_ret = strlen(sel->selbuf);*/
char *edje = NULL;
- if (data_ret && (sel->format & ELM_SEL_FORMAT_HTML))
+ if (data_ret && (sel->format == ELM_SEL_FORMAT_TEXT))
+ {
+ if (sel->selbuf && sel->selbuf[0] != '\0')
+ edje = mark_up(sel->selbuf, strlen(sel->selbuf), NULL);
+ }
+ else if (data_ret && ((sel->format & ELM_SEL_FORMAT_HTML)))
{
Eina_List *nodeList = NULL;
Eina_List *trail;
if (edje)
*data_ret = edje;
else
- *data_ret = strdup(sel->selbuf);
+ if (sel->selbuf)
+ *data_ret = strdup(sel->selbuf);
+ else
+ *data_ret = strdup("");
}
if (size_ret)
{
if (edje)
*size_ret = strlen(edje);
else
- *size_ret = strlen(sel->selbuf);
+ if (sel->selbuf)
+ *size_ret = strlen(sel->selbuf);
+ else
+ *size_ret = 0;
}
return EINA_TRUE;
sel = selections + *(int *)data;
char *html = NULL;
- if (data_ret && (sel->format & ELM_SEL_FORMAT_MARKUP))
+ char *convert_target = sel->selbuf;
+ Eina_Bool convert_edje = EINA_FALSE;
+
+ if (data_ret && (sel->format == ELM_SEL_FORMAT_TEXT))
+ {
+ if (sel->selbuf && sel->selbuf[0] != '\0')
+ {
+ convert_target = mark_up(sel->selbuf, strlen(sel->selbuf), NULL);
+ convert_edje = EINA_TRUE;
+ }
+ }
+
+ if (data_ret && ((sel->format & ELM_SEL_FORMAT_MARKUP) || convert_edje))
{
Eina_List *nodeList = NULL;
Eina_List *trail;
PTagNode nodeData;
- nodeData = _get_start_node(sel->selbuf);
+ nodeData = _get_start_node(convert_target);
while (nodeData)
{
if (html)
*data_ret = html;
else
- *data_ret = strdup(sel->selbuf);
+ if (sel->selbuf)
+ *data_ret = strdup(sel->selbuf);
+ else
+ *data_ret = strdup("");
}
if (size_ret)
if (html)
*size_ret = strlen(html);
else
- *size_ret = strlen(sel->selbuf);
+ if (sel->selbuf)
+ *size_ret = strlen(sel->selbuf);
+ else
+ *size_ret = 0;
}
+ if (convert_target != sel->selbuf)
+ free(convert_target);
return EINA_TRUE;
}
if (!pi) return EINA_FALSE;
if (!entry) return EINA_FALSE;
+ if (elm_entry_cnp_textonly_get(entry)) return EINA_FALSE;
pasteimage_provider_set(entry);
q = ret = malloc(l + 1);
/* Second pass: Change characters */
- for (p = start; *p; )
+ for (p = start; ((!endp) || (p < endp)) && (*p); )
{
for (i = 0; i < N_ESCAPES; i++)
{
/* Request it, so we know what it is */
cnp_debug("Sending uri request\n");
savedtypes.textreq = 1;
+ if (savedtypes.pi) pasteimage_free(savedtypes.pi);
savedtypes.pi = NULL; /* FIXME: Free? */
ecore_x_selection_xdnd_request(enter->win, text_uri);
}
cnp_debug("Insert %s\n", (char *)ddata.data);
dropable->dropcb(dropable->cbdata, dropable->obj, &ddata);
ecore_x_dnd_send_finished();
+
+ if (savedtypes.pi) pasteimage_free(savedtypes.pi);
+ savedtypes.pi = NULL;
return EINA_TRUE;
}
else if (dropable->types & ELM_SEL_FORMAT_IMAGE)
dropable->dropcb(dropable->cbdata, dropable->obj, &ddata);
ecore_x_dnd_send_finished();
- pasteimage_free(savedtypes.pi);
+ if (savedtypes.pi) pasteimage_free(savedtypes.pi);
savedtypes.pi = NULL;
return EINA_TRUE;
tmppath = getenv("TMP");
if (!tmppath) tmppath = P_tmpdir;
- if (!tmppath) tmppath = "/tmp";
len = snprintf(NULL, 0, "%s/%sXXXXXX", tmppath, "elmcnpitem-");
if (len < 0)
{
return info;
}
+ eina_mmap_safety_enabled_set(EINA_TRUE);
+
info->map = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, info->fd, 0);
if (info->map == MAP_FAILED)
{