#include "News.h" #define VIEWER_CREATE_FAIL(nv, msg) \ { \ news_util_message_error_show(msg); \ news_viewer_destroy(nv); \ return 0; \ } static int _dialog_create(News_Viewer *nv); static void _dialog_destroy(News_Viewer *nv); static void _dialog_geometry_update(News_Viewer *nv); static int _dialog_content_create(News_Viewer *nv); static void _dialog_content_destroy(News_Viewer *nv); static void _dialog_cb_feed_selected(void *data); static void _dialog_cb_article_selected(void *data); static void _dialog_cb_del(void *obj); static void _dialog_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event); static void _vfeeds_buttons_state_refresh(News_Viewer *nv); static void _vfeeds_cb_button_feed(void *data, void *data2); static void _vfeeds_cb_button_refresh(void *data, void *data2); static void _vfeeds_cb_button_setasread(void *data, void *data2); static void _varticles_refresh(News_Viewer *nv); static void _vcontent_text_set(News_Viewer *nv, char *text); static void _vcontent_feed_infos_set(News_Viewer *nv); static void _vcontent_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); static Evas_Object *_article_icon_get(News_Feed_Article *art, Evas *evas); static Evas_List *_sort_feedrefs_unreadfirst_list_get(News_Item *ni); static Evas_List *_sort_articles_unreadfirst_list_get(News_Feed *f); static Evas_List *_sort_articles_unreadfirst(Evas_List *articles); static Evas_List *_sort_articles_date_list_get(News_Feed *f); static int _sort_articles_date_list_cb(void *d1, void *d2); static Evas_List *_viewers; /* * Public functions */ int news_viewer_init(void) { _viewers = NULL; return 1; } void news_viewer_shutdown(void) { News_Viewer *nv; while (_viewers) { nv = _viewers->data; news_viewer_destroy(nv); _viewers = evas_list_remove_list(_viewers, _viewers); } } void news_viewer_all_refresh(int force, int recreate) { News_Viewer *nv; int pos, count, counter; pos = 0; counter = 0; count = evas_list_count(_viewers); while (counter < count) { nv = evas_list_nth(_viewers, pos); if (force) { NEWS_ITEM_FEEDS_FOREACH_BEG(nv->item); if (!_feed->doc) continue; _feed->doc->ui_needrefresh = 1; NEWS_ITEM_FEEDS_FOREACH_END(); } if (recreate) { News_Item *ni; ni = nv->item; news_viewer_destroy(nv); news_viewer_create(ni); } else { news_viewer_refresh(nv); pos++; } counter++; } } int news_viewer_create(News_Item *ni) { News_Viewer *nv; if (ni->viewer) return 0; nv = E_NEW(News_Viewer, 1); nv->item = ni; if (!_dialog_create(nv)) VIEWER_CREATE_FAIL(nv, "Could not create viewer dialog"); if (!_dialog_content_create(nv)) VIEWER_CREATE_FAIL(nv, "Could not create viewer dialog content"); _dialog_geometry_update(nv); e_win_raise(nv->dialog.dia->win); ni->viewer = nv; _viewers = evas_list_append(_viewers, nv); news_viewer_refresh(nv); return 1; } void news_viewer_destroy(News_Viewer *nv) { _dialog_content_destroy(nv); _dialog_destroy(nv); nv->item->viewer = NULL; _viewers = evas_list_remove(_viewers, nv); free(nv); } void news_viewer_refresh(News_Viewer *nv) { Evas_Object *ilist; Evas_List *feed_refs; int feed_refs_own = 0; int pos, toselect_pos; if (!nv) return; ilist = nv->vfeeds.ilist; e_widget_ilist_freeze(ilist); e_widget_ilist_clear(ilist); if (!evas_list_count(nv->item->config->feed_refs)) { nv->vfeeds.selected = NULL; nv->varticles.selected = NULL; e_widget_button_icon_set(nv->vfeeds.button_feed, NULL); e_widget_ilist_clear(nv->varticles.ilist); _vcontent_text_set(nv, ""); } if (news->config->viewer.vfeeds.unread_first) { feed_refs = _sort_feedrefs_unreadfirst_list_get(nv->item); feed_refs_own = 1; } else feed_refs = nv->item->config->feed_refs; DD(("feed_refs_own = %d", feed_refs_own)); /* refresh the list of feeds */ pos = 0; toselect_pos = -1; NEWS_ITEM_FEEDS_FOREACH_BEG_LIST(feed_refs); { Evas_Object *ic = NULL; char buf[4096]; if (!_feed->doc) continue; DD(("UI NEED REFRESH = %d (%s)", _feed->doc->ui_needrefresh, _feed->name)); /* add the ui item in the feeds list */ if (_feed->icon && _feed->icon[0]) { ic = e_icon_add(evas_object_evas_get(ilist)); e_icon_file_set(ic, _feed->icon); } if (_feed->doc && _feed->doc->unread_count) snprintf(buf, sizeof(buf), "[UNREAD] %s", _feed->name); else snprintf(buf, sizeof(buf), "%s", _feed->name); e_widget_ilist_append(ilist, ic, buf, _dialog_cb_feed_selected, _feed, NULL); if (nv->vfeeds.selected == _feed) toselect_pos = pos; pos++; } NEWS_ITEM_FEEDS_FOREACH_END(); e_widget_ilist_go(ilist); e_widget_ilist_thaw(ilist); /* select a feed */ if (toselect_pos != -1) { e_widget_ilist_selected_set(ilist, toselect_pos); } /* ilist size */ if (pos == -1) e_widget_min_size_set(ilist, 100, 70); else { int wmw; e_widget_min_size_get(ilist, &wmw, NULL); e_widget_min_size_set(ilist, wmw, 110); } if (nv->vfeeds.list_own) { if (nv->vfeeds.list) { DD(("LIST OWN free !!")); evas_list_free(nv->vfeeds.list); nv->vfeeds.list = NULL; } nv->vfeeds.list_own = 0; } nv->vfeeds.list = feed_refs; nv->vfeeds.list_own = feed_refs_own; _vfeeds_buttons_state_refresh(nv); } int news_viewer_feed_select(News_Viewer *nv, News_Feed *feed) { int pos; int found; if (nv->vfeeds.selected == feed) return 1; pos = 0; found = 0; NEWS_ITEM_FEEDS_FOREACH_BEG_LIST(nv->vfeeds.list); if (feed == _feed) { found = 1; break; } pos++; NEWS_ITEM_FEEDS_FOREACH_END(); if (!found) return 0; e_widget_ilist_selected_set(nv->vfeeds.ilist, pos); _dialog_cb_feed_selected(feed); return 1; } void news_viewer_feed_selected_infos_refresh(News_Viewer *nv) { if (!nv->varticles.selected) _vcontent_feed_infos_set(nv); } void news_viewer_article_state_refresh(News_Viewer *nv, News_Feed_Article *art) { Evas_List *l; News_Feed *f; News_Feed_Article *a; int pos; f = art->doc->feed; if (nv->vfeeds.selected != f) return; pos = 0; for (l=nv->varticles.list; l; l=evas_list_next(l)) { a = l->data; if (art == a) break; pos++; } if (!l) return; e_widget_ilist_nth_icon_set(nv->varticles.ilist, pos, _article_icon_get(art,evas_object_evas_get(nv->varticles.ilist))); } /* * Private functions */ static int _dialog_create(News_Viewer *nv) { Evas_Modifier_Mask mask; E_Dialog *dia; char buf[4096]; snprintf(buf, sizeof(buf), "_e_mod_news_viewer_%d", nv->item->gcc->id); dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", buf); if (!dia) return 0; dia->data = nv; e_object_del_attach_func_set(E_OBJECT(dia), _dialog_cb_del); e_dialog_title_set(dia, "News Viewer"); e_dialog_resizable_set(dia, 1); e_win_sticky_set(dia->win, 1); //e_win_layer_set(dia->win, ECORE_X_WINDOW_LAYER_ABOVE); mask = 0; evas_object_key_grab(dia->event_object, "Escape", mask, ~mask, 0); evas_object_event_callback_add(dia->event_object, EVAS_CALLBACK_KEY_DOWN, _dialog_cb_key_down, nv); nv->dialog.dia = dia; return 1; } static void _dialog_destroy(News_Viewer *nv) { if (nv->dialog.dia) { nv->dialog.dia->data = NULL; e_object_del(E_OBJECT(nv->dialog.dia)); nv->dialog.dia = NULL; } } static void _dialog_geometry_update(News_Viewer *nv) { int dia_x, dia_y; int tab_w, tab_h; int canvas_w, canvas_h; if (!nv->dialog.dia) return; /* dialog position : compute dia_x and dia_y */ e_widget_min_size_get(nv->dialog.tab, &tab_w, &tab_h); news_util_ecanvas_geometry_get(&canvas_w, &canvas_h); dia_x = (canvas_w - tab_w) / 2; dia_y = (canvas_h - tab_h) / 2; DVIEWER(("diax: %d diay : %d", dia_x, dia_y)); /* apply ! */ e_win_move(nv->dialog.dia->win, dia_x, dia_y); nv->dialog.x = dia_x; nv->dialog.y = dia_y; e_dialog_show(nv->dialog.dia); e_dialog_border_icon_set(nv->dialog.dia, news_theme_file_get(NEWS_THEME_CAT_ICON)); } static int _dialog_content_create(News_Viewer *nv) { Evas_Textblock_Style *tb_style; Evas *evas; Evas_Object *o, *o2, *ob, *of, *icon; char buf[4096]; char buf2[1024] = ""; int w, h; evas = evas_object_evas_get(nv->dialog.dia->bg_object); o = e_widget_list_add(evas, 0, 0); o2 = e_widget_list_add(evas, 0, 1); nv->dialog.tab = o; of = e_widget_frametable_add(evas, D_("Feeds in this gadget"), 0); nv->dialog.ftab_feeds = of; ob = e_widget_button_add(evas, "", NULL, _vfeeds_cb_button_feed, nv, NULL); e_widget_min_size_set(ob, 60, 60); nv->vfeeds.button_feed = ob; e_widget_frametable_object_append(of, ob, 0, 0, 1, 2, 0, 0, 0, 0); ob = e_widget_button_add(evas, "Update", "", _vfeeds_cb_button_refresh, nv, NULL); icon = e_icon_add(evas); news_theme_icon_set(icon, NEWS_THEME_ICON_UPDATE); e_icon_fill_inside_set(icon, 1); e_widget_button_icon_set(ob, icon); nv->vfeeds.button_refresh = ob; e_widget_frametable_object_append(of, ob, 1, 0, 1, 1, 0, 0, 0, 0); ob = e_widget_button_add(evas, "Set as read", "", _vfeeds_cb_button_setasread, nv, NULL); icon = e_icon_add(evas); news_theme_icon_set(icon, NEWS_THEME_ICON_SETASREAD); e_icon_fill_inside_set(icon, 1); e_widget_button_icon_set(ob, icon); nv->vfeeds.button_setasread = ob; e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 0, 0, 0, 0); ob = e_widget_ilist_add(evas, 16, 16, NULL); e_widget_ilist_selector_set(ob, 1); nv->vfeeds.ilist = ob; news_viewer_refresh(nv); e_widget_frametable_object_append(of, ob, 0, 2, 2, 1, 1, 1, 1, 1); e_widget_list_object_append(o2, of, 1, 0, 0.0); ob = evas_object_textblock_add(evas_object_evas_get(nv->dialog.dia->bg_object)); tb_style = evas_textblock_style_new(); if (news->config->viewer.vcontent.font_shadow) { snprintf(buf2, sizeof(buf2), " style=soft_shadow shadow_color=%s", news->config->viewer.vcontent.font_shadow_color); } snprintf(buf, sizeof(buf), "DEFAULT='font=Vera font_size=%d align=left color=%s%s wrap=word'" "br='\n'" "hilight='+ font=Vera-Bold font_size=%d'" "small='+ font_size=%d'" "italic='+ font=Vera-Italic'", news->config->viewer.vcontent.font_size, news->config->viewer.vcontent.font_color, buf2, news->config->viewer.vcontent.font_size + 1, news->config->viewer.vcontent.font_size - 1); evas_textblock_style_set(tb_style, buf); evas_object_textblock_style_set(ob, tb_style); evas_textblock_style_free(tb_style); evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _vcontent_cb_mouse_down, nv); nv->vcontent.tb = ob; ob = e_widget_scrollframe_simple_add(evas, nv->vcontent.tb); e_widget_min_size_set(ob, 290, 200); evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _vcontent_cb_mouse_down, nv); nv->vcontent.scrollframe = ob; e_widget_list_object_append(o2, ob, 1, 1, 0.5); e_widget_list_object_append(o, o2, 1, 1, 0.5); of = e_widget_framelist_add(evas, D_("Articles in selected feed"), 0); nv->dialog.ftab_articles = of; ob = e_widget_ilist_add(evas, 16, 16, NULL); e_widget_ilist_selector_set(ob, 1); e_widget_min_size_set(ob, 250, 140); nv->varticles.ilist = ob; e_widget_framelist_object_append(of, ob); e_widget_list_object_append(o, of, 1, 1, 1.0); /* apply */ e_widget_min_size_get(o, &w, &h); e_dialog_content_set(nv->dialog.dia, o, w, h); return 1; } static void _dialog_content_destroy(News_Viewer *nv) { if (nv->dialog.tab) { evas_object_del(nv->dialog.tab); nv->dialog.tab = NULL; } if (nv->dialog.ftab_feeds) { evas_object_del(nv->dialog.ftab_feeds); nv->dialog.ftab_feeds = NULL; } if (nv->dialog.ftab_articles) { evas_object_del(nv->dialog.ftab_articles); nv->dialog.ftab_articles = NULL; } if (nv->vfeeds.list_own && nv->vfeeds.list) { evas_list_free(nv->vfeeds.list); nv->vfeeds.list = NULL; } if (nv->vfeeds.ilist) { evas_object_del(nv->vfeeds.ilist); nv->vfeeds.ilist = NULL; nv->vfeeds.selected = NULL; } if (nv->vfeeds.button_feed) { evas_object_del(nv->vfeeds.button_feed); nv->vfeeds.button_feed = NULL; } if (nv->vfeeds.button_feed_icon) { evas_object_del(nv->vfeeds.button_feed_icon); nv->vfeeds.button_feed_icon = NULL; } if (nv->vfeeds.button_refresh) { evas_object_del(nv->vfeeds.button_refresh); nv->vfeeds.button_refresh = NULL; } if (nv->vfeeds.button_setasread) { evas_object_del(nv->vfeeds.button_setasread); nv->vfeeds.button_setasread = NULL; } if (nv->varticles.list_own && nv->varticles.list) { evas_list_free(nv->varticles.list); nv->varticles.list = NULL; nv->varticles.list_own = 0; } if (nv->varticles.ilist) { evas_object_del(nv->varticles.ilist); nv->varticles.ilist = NULL; nv->varticles.selected = NULL; } if (nv->vcontent.tb) { evas_object_del(nv->vcontent.tb); nv->vcontent.tb = NULL; } if (nv->vcontent.scrollframe) { evas_object_del(nv->vcontent.scrollframe); nv->vcontent.scrollframe = NULL; } } static void _dialog_cb_feed_selected(void *data) { News_Viewer *nv; News_Feed *feed; int changed = 0; feed = data; if (!feed) return; nv = feed->item->viewer; DD(("TRIGGERED cb feed ilist (%s)", feed->name)); if ((nv->vfeeds.selected == feed) && !feed->doc->ui_needrefresh) { /* show feed infos in vcontent */ _vcontent_feed_infos_set(nv); _vfeeds_buttons_state_refresh(nv); if (nv->varticles.selected) { e_widget_ilist_unselect(nv->varticles.ilist); nv->varticles.selected = NULL; } return; } if (nv->vfeeds.selected != feed) { changed = 1; nv->vfeeds.selected = feed; } if (feed->icon && feed->icon[0]) { Evas_Object *ic; ic = e_icon_add(evas_object_evas_get(nv->vfeeds.ilist)); e_icon_file_set(ic, feed->icon); e_icon_fill_inside_set(ic, 1); if (nv->vfeeds.button_feed_icon) evas_object_del(nv->vfeeds.button_feed_icon); e_widget_button_icon_set(nv->vfeeds.button_feed, ic); nv->vfeeds.button_feed_icon = ic; } _vfeeds_buttons_state_refresh(nv); if (changed) nv->varticles.selected = NULL; _varticles_refresh(nv); } static void _dialog_cb_article_selected(void *data) { News_Viewer *nv; News_Feed_Article *art; char buf[4096]; char buf_date[4096] = "Not dated"; art = data; if (!art) return; nv = art->doc->feed->item->viewer; DD(("TRIGGERED cb article ilist (%s)", art->title)); nv->varticles.selected = art; if (art->date.tm_year != 0) strftime(buf_date, sizeof(buf_date), "%Y-%m-%d %H:%M:%S", &art->date); snprintf(buf, sizeof(buf), "%s
" "%s

" "%s

" "%s", (art->title && art->title[0]) ? art->title : "No title", buf_date, (art->description && art->description[0])? art->description : "No description text", (art->url) ? "||click on the text to open article in a browser||" : ""); _vcontent_text_set(nv, buf); if (art->unread) news_feed_article_unread_set(art, 0); } static void _dialog_cb_del(void *obj) { E_Dialog *dia; News_Viewer *nv; dia = obj; nv = dia->data; if (!nv) return; nv->dialog.dia = NULL; news_viewer_destroy(nv); } static void _dialog_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event) { Evas_Event_Key_Down *ev; News_Viewer *nv; ev = event; nv = data; if (!strcmp(ev->keyname, "Escape")) { news_viewer_destroy(nv); } } static void _vfeeds_buttons_state_refresh(News_Viewer *nv) { News_Feed *f; f = nv->vfeeds.selected; if (nv->vfeeds.button_feed) { if (f && f->url_home && f->url_home[0]) e_widget_disabled_set(nv->vfeeds.button_feed, 0); else e_widget_disabled_set(nv->vfeeds.button_feed, 1); } if (nv->vfeeds.button_refresh) { if (f) e_widget_disabled_set(nv->vfeeds.button_refresh, 0); else e_widget_disabled_set(nv->vfeeds.button_refresh, 1); } if (nv->vfeeds.button_setasread) { if (f && f->doc && f->doc->unread_count) e_widget_disabled_set(nv->vfeeds.button_setasread, 0); else e_widget_disabled_set(nv->vfeeds.button_setasread, 1); } } static void _vfeeds_cb_button_feed(void *data, void *data2) { News_Viewer *nv; nv = data; if (!nv->vfeeds.selected) return; if (nv->vfeeds.selected->config_dialog) return; news_util_browser_open(nv->vfeeds.selected->url_home); } static void _vfeeds_cb_button_refresh(void *data, void *data2) { News_Viewer *nv; News_Feed *f; nv = data; f = nv->vfeeds.selected; if (!f || !f->doc) return; news_feed_update(f); } static void _vfeeds_cb_button_setasread(void *data, void *data2) { News_Viewer *nv; News_Feed *f; nv = data; f = nv->vfeeds.selected; if (!f || !f->doc) return; news_feed_read_set(f); } static void _varticles_refresh(News_Viewer *nv) { News_Feed *feed; Evas_Object *ilist; Evas_List *articles, *l; int articles_own = 0; int pos, toselect_pos; ilist = nv->varticles.ilist; e_widget_ilist_clear(ilist); feed = nv->vfeeds.selected; if (!feed || !feed->doc) return; e_widget_ilist_freeze(ilist); if (news->config->viewer.varticles.unread_first) { if (news->config->viewer.varticles.sort_date) { Evas_List *tmp; tmp = _sort_articles_date_list_get(feed); articles = _sort_articles_unreadfirst(tmp); evas_list_free(tmp); } else articles = _sort_articles_unreadfirst_list_get(feed); articles_own = 1; } else if (news->config->viewer.varticles.sort_date) { articles = _sort_articles_date_list_get(feed); articles_own = 1; } else articles = feed->doc->articles; pos = 0; toselect_pos = -1; if (evas_list_count(articles)) { for (l=articles; l; l=evas_list_next(l)) { News_Feed_Article *art; char label[4096]; char buf_date[4096] = ""; art = l->data; /* append the article to the article ilist */ if (art->date.tm_year) strftime(buf_date, sizeof(buf_date), "%d %H:%M", &art->date); snprintf(label, sizeof(label), "%s %s", buf_date, art->title); e_widget_ilist_append(ilist, _article_icon_get(art, evas_object_evas_get(ilist)), label, _dialog_cb_article_selected, art, NULL); if (nv->varticles.selected == art) toselect_pos = pos; pos++; } } e_widget_ilist_go(ilist); e_widget_ilist_thaw(ilist); /* select a feed, of if no articles are selected show feed informations in vcontent */ if (toselect_pos != -1) { e_widget_ilist_selected_set(ilist, toselect_pos); _dialog_cb_article_selected(nv->varticles.selected); } else if (!nv->varticles.selected) _vcontent_feed_infos_set(nv); if (nv->varticles.list_own) { evas_list_free(nv->varticles.list); nv->varticles.list = NULL; nv->varticles.list_own = 0; } nv->varticles.list = articles; nv->varticles.list_own = articles_own; feed->doc->ui_needrefresh = 0; } static void _vcontent_text_set(News_Viewer *nv, char *text) { int w, h, sw, sh; evas_object_geometry_get(nv->vcontent.scrollframe, NULL, NULL, &sw, &sh); evas_object_resize(nv->vcontent.tb, sw-20, sh-20); evas_object_textblock_clear(nv->vcontent.tb); if (text) evas_object_textblock_text_markup_set(nv->vcontent.tb, text); evas_object_textblock_size_formatted_get(nv->vcontent.tb, &w, &h); if (h < sh - 20) h = sh - 20; if (w > sw - 20) w = sw - 20; evas_object_resize(nv->vcontent.tb, w, h); } static void _vcontent_feed_infos_set(News_Viewer *nv) { News_Feed *f; char buf_error[1024] = ""; char buf_infos[1024] = ""; char buf_conn[200] = ""; char buf_unread[1024] = "No unread articles"; char buf[4096]; evas_object_textblock_clear(nv->vcontent.tb); f = nv->vfeeds.selected; if (!f) return; if (f->doc) { switch(f->doc->parse.error) { case NEWS_PARSE_ERROR_NO: case NEWS_PARSE_ERROR_NOT_IMPLEMENTED: break; case NEWS_PARSE_ERROR_BROKEN_FEED: case NEWS_PARSE_ERROR_TYPE_UNKNOWN: snprintf(buf_error, sizeof(buf_error), "
An error happend during the parse of this feed !
" "You can report error at ooookiwi@gmail.com to get it fixed

"); break; } if (f->doc->parse.last_time) { char buf_mtime[200]; char *type; switch (f->doc->parse.type) { case NEWS_FEED_TYPE_RSS: type = "RSS"; break; case NEWS_FEED_TYPE_ATOM: type = "ATOM (not supported for now)"; break; default: type = "UNKNOWN"; } snprintf(buf_mtime, sizeof(buf_mtime), "Last check of the feed : %s", ctime(&f->doc->parse.last_time)); buf_mtime[strlen(buf_mtime)-1] = '\0'; snprintf(buf_infos, sizeof(buf_infos), "%s
Type: %s, Version %.2f
", buf_mtime, type, f->doc->parse.version); } if (f->doc->server.conn) { if (f->doc->server.nb_tries > 1) snprintf(buf_conn, sizeof(buf_conn), "Trying to update the feed ... (%d)
", f->doc->server.nb_tries); else snprintf(buf_conn, sizeof(buf_conn), "Trying to update the feed ...
"); } if (f->doc->unread_count) { snprintf(buf_unread, sizeof(buf_unread), "%d unread articles%s", f->doc->unread_count, (f->doc->unread_count >= NEWS_FEED_UNREAD_COUNT_MAX) ? "
" "Its the maximum number of articles a feed can have.
" "The oldest articles you didn't red are not keeped anymore." : ""); } } snprintf(buf, sizeof(buf), "%s in %s

" "%s" "%s

" "%s%s
" "%s
", f->name, f->category->name, buf_error, (f->description && f->description[0]) ? f->description : "No description for this feed", buf_infos, buf_conn, buf_unread); _vcontent_text_set(nv, buf); } static void _vcontent_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { News_Viewer *nv; Evas_Event_Mouse_Down *ev; nv = data; ev = event_info; if (nv->varticles.selected) { if (nv->varticles.selected->url) news_util_browser_open(nv->varticles.selected->url); } else if (nv->vfeeds.selected) { if (nv->vfeeds.selected->url_home) news_util_browser_open(nv->vfeeds.selected->url_home); } } static Evas_Object * _article_icon_get(News_Feed_Article *art, Evas *evas) { Evas_Object *ic; ic = e_icon_add(evas); e_icon_fill_inside_set(ic, 1); if (art->unread) news_theme_icon_set(ic, NEWS_THEME_ICON_ARTICLE_UNREAD); else news_theme_icon_set(ic, NEWS_THEME_ICON_ARTICLE_READ); return ic; } static Evas_List * _sort_feedrefs_unreadfirst_list_get(News_Item *ni) { Evas_List *list, *reads, *l; News_Feed_Ref *ref; list = NULL; reads = NULL; NEWS_ITEM_FEEDS_FOREACH_BEG(ni); if (_feed->doc && _feed->doc->unread_count) list = evas_list_append(list, _ref); else reads = evas_list_append(reads, _ref); NEWS_ITEM_FEEDS_FOREACH_END(); for (l=reads; l; l=evas_list_next(l)) { ref = l->data; list = evas_list_append(list, ref); } evas_list_free(reads); return list; } static Evas_List * _sort_articles_unreadfirst_list_get(News_Feed *f) { Evas_List *list; if (!f->doc) return NULL; list = _sort_articles_unreadfirst(f->doc->articles); return list; } static Evas_List * _sort_articles_unreadfirst(Evas_List *articles) { Evas_List *list, *reads, *l; News_Feed_Article *art; list = NULL; reads = NULL; for (l=articles; l; l=evas_list_next(l)) { art = l->data; if (art->unread) list = evas_list_append(list, art); else reads = evas_list_append(reads, art); } for (l=reads; l; l=evas_list_next(l)) { art = l->data; list = evas_list_append(list, art); } evas_list_free(reads); return list; } static Evas_List * _sort_articles_date_list_get(News_Feed *f) { Evas_List *list, *l; News_Feed_Article *art; if (!f->doc) return NULL; list = NULL; for (l=f->doc->articles; l; l=evas_list_next(l)) { art = l->data; list = evas_list_append(list, art); } list = evas_list_sort(list, evas_list_count(list), _sort_articles_date_list_cb); return list; } static int _sort_articles_date_list_cb(void *d1, void *d2) { News_Feed_Article *a1, *a2; a1 = d1; a2 = d2; /* sort reverse order : more recent (greater) first */ return - (news_util_datecmp(&a1->date, &a2->date)); }