root / trunk / client / gui / info.c @ 1859
History | View | Annotate | Download (32 KB)
| 1 |
/*
|
|---|---|
| 2 |
Copyright (C) 2005-2010 Erik van Pienbroek |
| 3 |
|
| 4 |
This program is free software; you can redistribute it and/or modify |
| 5 |
it under the terms of the GNU General Public License as published by |
| 6 |
the Free Software Foundation; either version 2 of the License, or |
| 7 |
(at your option) any later version. |
| 8 |
|
| 9 |
This program is distributed in the hope that it will be useful, |
| 10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 |
GNU General Public License for more details. |
| 13 |
|
| 14 |
You should have received a copy of the GNU General Public License |
| 15 |
along with this program; if not, write to the Free Software |
| 16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 |
*/ |
| 18 |
|
| 19 |
#include "gui.h" |
| 20 |
#include |
| 21 |
#ifdef HAVE_SOUP
|
| 22 |
#include |
| 23 |
#ifdef HAVE_SOUP_GNOME
|
| 24 |
#include |
| 25 |
#endif
|
| 26 |
#else
|
| 27 |
#include |
| 28 |
#include |
| 29 |
#include |
| 30 |
#endif
|
| 31 |
#include |
| 32 |
#ifdef WIN32
|
| 33 |
#include |
| 34 |
#endif
|
| 35 |
|
| 36 |
#if defined(WIN32) && !defined(__MINGW64__)
|
| 37 |
/* Win32 likes to add a extra _ to external variables. Workaround this */
|
| 38 |
#define __BUILD_SVN_REV _BUILD_SVN_REV
|
| 39 |
#define __BUILD_DATE _BUILD_DATE
|
| 40 |
#define __BUILD_NUMBER _BUILD_NUMBER
|
| 41 |
#endif
|
| 42 |
|
| 43 |
#ifdef DARWIN
|
| 44 |
#define GET_BUILD_SVN_REV __BUILD_SVN_REV
|
| 45 |
#define GET_BUILD_DATE __BUILD_DATE
|
| 46 |
#define GET_BUILD_NUMBER __BUILD_NUMBER
|
| 47 |
#else
|
| 48 |
extern char __BUILD_SVN_REV; |
| 49 |
extern char __BUILD_DATE; |
| 50 |
extern char __BUILD_NUMBER; |
| 51 |
#define GET_BUILD_SVN_REV &__BUILD_SVN_REV
|
| 52 |
#define GET_BUILD_DATE &__BUILD_DATE
|
| 53 |
#define GET_BUILD_NUMBER &__BUILD_NUMBER
|
| 54 |
#endif
|
| 55 |
|
| 56 |
#ifndef HAVE_SOUP
|
| 57 |
static size_t
|
| 58 |
curl_write_function(void *buffer, size_t size, size_t nmemb, void *stream) |
| 59 |
{
|
| 60 |
char *buf;
|
| 61 |
GString *data = (GString *) stream; |
| 62 |
|
| 63 |
g_assert(data); |
| 64 |
|
| 65 |
/* The buffer isn't \0 terminated. Solve this by
|
| 66 |
using a temporary buffer */ |
| 67 |
buf = (char *) g_slice_alloc((int) (size * nmemb) + 1); |
| 68 |
memcpy(buf, buffer, size * nmemb); |
| 69 |
buf[size * nmemb] = '\0';
|
| 70 |
data = g_string_append(data, buf); |
| 71 |
g_slice_free1((size * nmemb) + 1, buf);
|
| 72 |
|
| 73 |
return (int) (size * nmemb); |
| 74 |
} |
| 75 |
#endif
|
| 76 |
|
| 77 |
static gboolean
|
| 78 |
open_uri (GtkWidget *embed, const char *url_unquoted, gpointer data) |
| 79 |
{
|
| 80 |
if (strstr(url_unquoted, "https://")) { |
| 81 |
char *url = g_shell_quote(url_unquoted);
|
| 82 |
#ifdef WIN32
|
| 83 |
GtkWidget *windowMain = nntpgrab_gui_base_get_widget("windowMain");
|
| 84 |
ShellExecuteA(GDK_WINDOW_HWND(windowMain->window), "open", url_unquoted, NULL, NULL, SW_SHOW); |
| 85 |
#elif defined(DARWIN)
|
| 86 |
GError *error = NULL;
|
| 87 |
char cmd[1024]; |
| 88 |
|
| 89 |
snprintf(cmd, sizeof(cmd), "open %s", url); |
| 90 |
g_spawn_command_line_async(cmd, &error); |
| 91 |
if (error) {
|
| 92 |
g_print("%s: %s\n", error->message, cmd);
|
| 93 |
} |
| 94 |
#else
|
| 95 |
GError *error = NULL;
|
| 96 |
char cmd[1024]; |
| 97 |
|
| 98 |
if (g_find_program_in_path("xdg-open")) { |
| 99 |
// We hebben de desktop-onafhankelijke methode om programma's te openen
|
| 100 |
snprintf(cmd, sizeof(cmd), "xdg-open %s", url); |
| 101 |
} else if (g_getenv("GNOME_DESKTOP_SESSION_ID") && g_find_program_in_path("gnome-open")) { |
| 102 |
// We draaien Gnome
|
| 103 |
snprintf(cmd, sizeof(cmd), "gnome-open %s", url); |
| 104 |
} else if (g_getenv("KDE_FULL_SESSION") && g_find_program_in_path("kfmclient")) { |
| 105 |
// We draaien KDE
|
| 106 |
snprintf(cmd, sizeof(cmd), "kfmclient openURL %s", url); |
| 107 |
} else if (g_getenv("BROWSER")) { |
| 108 |
// XFCE4 gebruikt de environment variabele BROWSER om de standaardbrowser te bepalen.
|
| 109 |
snprintf(cmd, sizeof(cmd), "%s %s", g_getenv("BROWSER"), url); |
| 110 |
} else {
|
| 111 |
// Window manager onbekend..probeer firefox, mozilla of konqueror te lanceren indien aanwezig
|
| 112 |
if (g_find_program_in_path("firefox")) { |
| 113 |
snprintf(cmd, sizeof(cmd), "firefox %s", url); |
| 114 |
} else if (g_find_program_in_path("mozilla")) { |
| 115 |
snprintf(cmd, sizeof(cmd), "mozilla %s", url); |
| 116 |
} else if (g_find_program_in_path("konqueror")) { |
| 117 |
snprintf(cmd, sizeof(cmd), "konqueror %s", url); |
| 118 |
} else {
|
| 119 |
GtkWidget *windowMain = nntpgrab_gui_base_get_widget("windowMain");
|
| 120 |
nntpgrab_gui_base_dialog_show(windowMain, _("Unable to find a external webbrowser"), GTK_MESSAGE_ERROR, GTK_BUTTONS_OK);
|
| 121 |
g_free(url); |
| 122 |
return FALSE;
|
| 123 |
} |
| 124 |
} |
| 125 |
|
| 126 |
g_spawn_command_line_async(cmd, &error); |
| 127 |
if (error) {
|
| 128 |
g_print("%s: %s\n", error->message, cmd);
|
| 129 |
} |
| 130 |
#endif
|
| 131 |
|
| 132 |
g_free(url); |
| 133 |
|
| 134 |
return FALSE;
|
| 135 |
} |
| 136 |
|
| 137 |
return TRUE;
|
| 138 |
} |
| 139 |
|
| 140 |
#ifndef HAVE_SOUP
|
| 141 |
static char * |
| 142 |
retrieve_website_info(void)
|
| 143 |
{
|
| 144 |
char *ret;
|
| 145 |
CURL *curl = NULL;
|
| 146 |
CURLcode curl_retval; |
| 147 |
GString *serverOutput; |
| 148 |
char *user_agent;
|
| 149 |
|
| 150 |
curl_global_init(CURL_GLOBAL_WIN32); |
| 151 |
|
| 152 |
curl = curl_easy_init(); |
| 153 |
if(!curl) {
|
| 154 |
g_warning(_("retrieve_website_info(): curl_easy_init() failed\n"));
|
| 155 |
return NULL; |
| 156 |
} |
| 157 |
|
| 158 |
serverOutput = g_string_new("");
|
| 159 |
|
| 160 |
curl_easy_setopt(curl, CURLOPT_URL, "https://www.nntpgrab.nl/info.php");
|
| 161 |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_function); |
| 162 |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, serverOutput); |
| 163 |
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, TRUE); |
| 164 |
curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip");
|
| 165 |
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20);
|
| 166 |
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); |
| 167 |
//curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
|
| 168 |
|
| 169 |
user_agent = g_strdup("NNTPGrab version " VERSION " (" OS ")"); |
| 170 |
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent); |
| 171 |
|
| 172 |
#if 0
|
| 173 |
if (core->config->proxyHost && core->config->proxyPort) {
|
| 174 |
curl_easy_setopt(curl, CURLOPT_PROXY, ftd_string_value(core->config->proxyHost)); |
| 175 |
curl_easy_setopt(curl, CURLOPT_PROXYPORT, atoi(ftd_string_value(core->config->proxyPort))); |
| 176 |
|
| 177 |
if (core->config->proxyUser && core->config->proxyPassword) {
|
| 178 |
int len = ftd_string_length(core->config->proxyUser) + ftd_string_length(core->config->proxyPassword) + 2; |
| 179 |
proxyUserPw = g_malloc (len); |
| 180 |
snprintf(proxyUserPw, len, "%s:%s", ftd_string_value(core->config->proxyUser), ftd_string_value(core->config->proxyPassword)); |
| 181 |
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxyUserPw); |
| 182 |
} |
| 183 |
} |
| 184 |
#endif |
| 185 |
|
| 186 |
curl_retval = curl_easy_perform(curl); |
| 187 |
if (curl_retval == 0) { |
| 188 |
ret = g_strdup(serverOutput->str); |
| 189 |
} else {
|
| 190 |
ret = NULL;
|
| 191 |
} |
| 192 |
|
| 193 |
g_free(user_agent); |
| 194 |
g_string_free(serverOutput, TRUE); |
| 195 |
|
| 196 |
curl_easy_cleanup(curl); |
| 197 |
curl_global_cleanup(); |
| 198 |
|
| 199 |
return ret;
|
| 200 |
} |
| 201 |
#endif
|
| 202 |
|
| 203 |
typedef struct _changelog |
| 204 |
{
|
| 205 |
int major_version;
|
| 206 |
int minor_version;
|
| 207 |
int micro_version;
|
| 208 |
GList *entries; |
| 209 |
} ChangeLog; |
| 210 |
|
| 211 |
typedef struct _update_info |
| 212 |
{
|
| 213 |
int stable_major_version;
|
| 214 |
int stable_minor_version;
|
| 215 |
int stable_micro_version;
|
| 216 |
time_t date_latest_stable_version; |
| 217 |
char date_latest_stable_version_str[128]; |
| 218 |
|
| 219 |
int unstable_major_version;
|
| 220 |
int unstable_minor_version;
|
| 221 |
int unstable_micro_version;
|
| 222 |
time_t date_latest_unstable_version; |
| 223 |
char date_latest_unstable_version_str[128]; |
| 224 |
|
| 225 |
GList *changelogs; |
| 226 |
} UpdateInfo; |
| 227 |
|
| 228 |
static char *xml_parser_errmsg = NULL; |
| 229 |
|
| 230 |
static void |
| 231 |
xml_parser_error_func (void *ctx, const char *msg, ...) |
| 232 |
{
|
| 233 |
va_list args; |
| 234 |
char *orig = xml_parser_errmsg;
|
| 235 |
char *tmp;
|
| 236 |
|
| 237 |
va_start(args, msg); |
| 238 |
|
| 239 |
tmp = g_strdup_vprintf(msg, args); |
| 240 |
if (orig) {
|
| 241 |
xml_parser_errmsg = g_strdup_printf("%s %s", orig, tmp);
|
| 242 |
g_free(orig); |
| 243 |
g_free(tmp); |
| 244 |
} else {
|
| 245 |
xml_parser_errmsg = tmp; |
| 246 |
} |
| 247 |
|
| 248 |
va_end(args); |
| 249 |
} |
| 250 |
|
| 251 |
static void |
| 252 |
parse_changelog(xmlDocPtr doc, xmlNodePtr cur, ChangeLog *changelog) |
| 253 |
{
|
| 254 |
gboolean translated_entry_seen = FALSE; |
| 255 |
const char * const *langs = g_get_language_names(); |
| 256 |
int i = 0; |
| 257 |
const char *lang_requested = NULL; |
| 258 |
|
| 259 |
while(cur != NULL) { |
| 260 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "VersionMajor")) { |
| 261 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 262 |
changelog->major_version = atoi((const gchar *) version);
|
| 263 |
xmlFree(version); |
| 264 |
} |
| 265 |
|
| 266 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "VersionMinor")) { |
| 267 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 268 |
changelog->minor_version = atoi((const gchar *) version);
|
| 269 |
xmlFree(version); |
| 270 |
} |
| 271 |
|
| 272 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "VersionMicro")) { |
| 273 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 274 |
changelog->micro_version = atoi((const gchar *) version);
|
| 275 |
xmlFree(version); |
| 276 |
} |
| 277 |
|
| 278 |
if (!translated_entry_seen && !xmlStrcmp(cur->name, (const xmlChar *) "Entry")) { |
| 279 |
xmlChar *entry = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 280 |
changelog->entries = g_list_append(changelog->entries, g_strdup((const char *) entry)); |
| 281 |
xmlFree(entry); |
| 282 |
} |
| 283 |
|
| 284 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "Entry-i18n")) { |
| 285 |
xmlChar *prop = xmlNodeGetLang(cur); |
| 286 |
xmlChar *entry; |
| 287 |
if (!prop) {
|
| 288 |
cur = cur->next; |
| 289 |
continue;
|
| 290 |
} |
| 291 |
|
| 292 |
if (!lang_requested) {
|
| 293 |
i = 0;
|
| 294 |
|
| 295 |
while (langs[i]) {
|
| 296 |
if (!strcmp((const char *) prop, langs[i])) { |
| 297 |
break;
|
| 298 |
} |
| 299 |
i++; |
| 300 |
} |
| 301 |
|
| 302 |
/* Did we find a match? */
|
| 303 |
if (langs[i]) {
|
| 304 |
lang_requested = langs[i]; |
| 305 |
} else {
|
| 306 |
/* Nope, ignore the entry */
|
| 307 |
xmlFree(prop); |
| 308 |
cur = cur->next; |
| 309 |
continue;
|
| 310 |
} |
| 311 |
} else if (strcmp((const char *) prop, lang_requested)) { |
| 312 |
/* Other language found, ignore */
|
| 313 |
xmlFree(prop); |
| 314 |
cur = cur->next; |
| 315 |
continue;
|
| 316 |
} |
| 317 |
|
| 318 |
translated_entry_seen = TRUE; |
| 319 |
|
| 320 |
entry = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 321 |
changelog->entries = g_list_append(changelog->entries, g_strdup((const char *) entry)); |
| 322 |
xmlFree(entry); |
| 323 |
xmlFree(prop); |
| 324 |
} |
| 325 |
|
| 326 |
cur = cur->next; |
| 327 |
} |
| 328 |
} |
| 329 |
|
| 330 |
static void |
| 331 |
parse_changelogs(xmlDocPtr doc, xmlNodePtr cur, UpdateInfo *info) |
| 332 |
{
|
| 333 |
while(cur != NULL) { |
| 334 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "Version")) { |
| 335 |
ChangeLog *changelog = g_slice_new0(ChangeLog); |
| 336 |
|
| 337 |
info->changelogs = g_list_append(info->changelogs, changelog); |
| 338 |
|
| 339 |
parse_changelog(doc, cur->xmlChildrenNode, changelog); |
| 340 |
} |
| 341 |
|
| 342 |
cur = cur->next; |
| 343 |
} |
| 344 |
} |
| 345 |
|
| 346 |
static void |
| 347 |
parse_info(xmlDocPtr doc, xmlNodePtr cur, UpdateInfo *info) |
| 348 |
{
|
| 349 |
while(cur != NULL) { |
| 350 |
// stable
|
| 351 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestStableMajor")) { |
| 352 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 353 |
info->stable_major_version = atoi((const gchar *) version);
|
| 354 |
xmlFree(version); |
| 355 |
} |
| 356 |
|
| 357 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestStableMinor")) { |
| 358 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 359 |
info->stable_minor_version = atoi((const gchar *) version);
|
| 360 |
xmlFree(version); |
| 361 |
} |
| 362 |
|
| 363 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestStableMicro")) { |
| 364 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 365 |
info->stable_micro_version = atoi((const gchar *) version);
|
| 366 |
xmlFree(version); |
| 367 |
} |
| 368 |
|
| 369 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "DateLatestVersion")) { |
| 370 |
struct tm *now;
|
| 371 |
|
| 372 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 373 |
info->date_latest_stable_version = atoi((const gchar *) version);
|
| 374 |
xmlFree(version); |
| 375 |
|
| 376 |
if ((now = localtime(&info->date_latest_stable_version)) != NULL) { |
| 377 |
strftime(info->date_latest_stable_version_str, sizeof(info->date_latest_stable_version_str), "%x", now); |
| 378 |
} |
| 379 |
} |
| 380 |
|
| 381 |
// unstable
|
| 382 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestUnstableMajor")) { |
| 383 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 384 |
info->unstable_major_version = atoi((const gchar *) version);
|
| 385 |
xmlFree(version); |
| 386 |
} |
| 387 |
|
| 388 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestUnstableMinor")) { |
| 389 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 390 |
info->unstable_minor_version = atoi((const gchar *) version);
|
| 391 |
xmlFree(version); |
| 392 |
} |
| 393 |
|
| 394 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "LatestUnstableMicro")) { |
| 395 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 396 |
info->unstable_micro_version = atoi((const gchar *) version);
|
| 397 |
xmlFree(version); |
| 398 |
} |
| 399 |
|
| 400 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "DateLatestUnstable")) { |
| 401 |
struct tm *now;
|
| 402 |
|
| 403 |
xmlChar *version = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
| 404 |
info->date_latest_unstable_version = atoi((const gchar *) version);
|
| 405 |
xmlFree(version); |
| 406 |
|
| 407 |
if ((now = localtime(&info->date_latest_unstable_version)) != NULL) { |
| 408 |
strftime(info->date_latest_unstable_version_str, sizeof(info->date_latest_unstable_version_str), "%x", now); |
| 409 |
} |
| 410 |
} |
| 411 |
cur = cur->next; |
| 412 |
} |
| 413 |
} |
| 414 |
|
| 415 |
static UpdateInfo *
|
| 416 |
parse_version_info(const char *contents, char **errmsg) |
| 417 |
{
|
| 418 |
xmlDocPtr doc; |
| 419 |
xmlNodePtr cur; |
| 420 |
UpdateInfo *info = NULL;
|
| 421 |
|
| 422 |
xmlSetGenericErrorFunc(NULL, xml_parser_error_func);
|
| 423 |
|
| 424 |
if (xml_parser_errmsg) {
|
| 425 |
g_free(xml_parser_errmsg); |
| 426 |
xml_parser_errmsg = NULL;
|
| 427 |
} |
| 428 |
|
| 429 |
doc = xmlParseMemory(contents, strlen(contents)); |
| 430 |
cur = xmlDocGetRootElement(doc); |
| 431 |
if (cur == NULL) { |
| 432 |
if (errmsg) {
|
| 433 |
*errmsg = g_strdup(xml_parser_errmsg); |
| 434 |
} |
| 435 |
|
| 436 |
g_free(xml_parser_errmsg); |
| 437 |
xml_parser_errmsg = NULL;
|
| 438 |
|
| 439 |
xmlFreeDoc(doc); |
| 440 |
return NULL; |
| 441 |
} |
| 442 |
|
| 443 |
if (xmlStrcmp(cur->name, (const xmlChar *) "NNTPGrab")) { |
| 444 |
if (errmsg) {
|
| 445 |
*errmsg = g_strdup("parse_version_info: document of the wrong type, root node != NNTPGrab");
|
| 446 |
} |
| 447 |
|
| 448 |
xmlFreeDoc(doc); |
| 449 |
|
| 450 |
return FALSE;
|
| 451 |
} |
| 452 |
|
| 453 |
cur = cur->xmlChildrenNode; |
| 454 |
if (!cur) {
|
| 455 |
if (errmsg) {
|
| 456 |
*errmsg = g_strdup("parse_version_info: no children of root-node!");
|
| 457 |
} |
| 458 |
|
| 459 |
xmlFreeDoc(doc); |
| 460 |
|
| 461 |
return FALSE;
|
| 462 |
} |
| 463 |
|
| 464 |
info = g_slice_new0(UpdateInfo); |
| 465 |
|
| 466 |
do {
|
| 467 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "VersionInfo")) { |
| 468 |
parse_info(doc, cur->xmlChildrenNode, info); |
| 469 |
} |
| 470 |
|
| 471 |
if (!xmlStrcmp(cur->name, (const xmlChar *) "ChangeLog")) { |
| 472 |
parse_changelogs(doc, cur->xmlChildrenNode, info); |
| 473 |
} |
| 474 |
} while ((cur=cur->next));
|
| 475 |
|
| 476 |
xmlFreeDoc(doc); |
| 477 |
|
| 478 |
return info;
|
| 479 |
} |
| 480 |
|
| 481 |
static void |
| 482 |
insert_link(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text) |
| 483 |
{
|
| 484 |
GtkTextTag *tag; |
| 485 |
|
| 486 |
tag = gtk_text_buffer_create_tag (buffer, NULL, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, "justification", GTK_JUSTIFY_CENTER, NULL); |
| 487 |
g_object_set_data (G_OBJECT (tag), "is_link", GINT_TO_POINTER (1)); |
| 488 |
gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL); |
| 489 |
} |
| 490 |
|
| 491 |
static void |
| 492 |
follow_if_link(GtkWidget *text_view, GtkTextIter *iter) |
| 493 |
{
|
| 494 |
GSList *tags = NULL, *tagp = NULL; |
| 495 |
|
| 496 |
tags = gtk_text_iter_get_tags (iter); |
| 497 |
for (tagp = tags; tagp != NULL; tagp = tagp->next) { |
| 498 |
GtkTextTag *tag = tagp->data; |
| 499 |
gboolean is_link = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "is_link"));
|
| 500 |
|
| 501 |
if (is_link) {
|
| 502 |
open_uri(NULL, "https://www.nntpgrab.nl", NULL); |
| 503 |
break;
|
| 504 |
} |
| 505 |
} |
| 506 |
|
| 507 |
if (tags) {
|
| 508 |
g_slist_free (tags); |
| 509 |
} |
| 510 |
} |
| 511 |
|
| 512 |
static gboolean
|
| 513 |
event_after(GtkWidget *text_view, GdkEvent *ev) |
| 514 |
{
|
| 515 |
GtkTextIter start, end, iter; |
| 516 |
GtkTextBuffer *buffer; |
| 517 |
GdkEventButton *event; |
| 518 |
gint x, y; |
| 519 |
|
| 520 |
if (ev->type != GDK_BUTTON_RELEASE) {
|
| 521 |
return FALSE;
|
| 522 |
} |
| 523 |
|
| 524 |
event = (GdkEventButton *)ev; |
| 525 |
|
| 526 |
if (event->button != 1) { |
| 527 |
return FALSE;
|
| 528 |
} |
| 529 |
|
| 530 |
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); |
| 531 |
|
| 532 |
/* we shouldn't follow a link if the user has selected something */
|
| 533 |
gtk_text_buffer_get_selection_bounds (buffer, &start, &end); |
| 534 |
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) {
|
| 535 |
return FALSE;
|
| 536 |
} |
| 537 |
|
| 538 |
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, event->x, event->y, &x, &y); |
| 539 |
|
| 540 |
gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y); |
| 541 |
|
| 542 |
follow_if_link (text_view, &iter); |
| 543 |
|
| 544 |
return FALSE;
|
| 545 |
} |
| 546 |
|
| 547 |
static gboolean hovering_over_link = FALSE;
|
| 548 |
static GdkCursor *hand_cursor = NULL; |
| 549 |
static GdkCursor *regular_cursor = NULL; |
| 550 |
|
| 551 |
/* Looks at all tags covering the position (x, y) in the text view,
|
| 552 |
* and if one of them is a link, change the cursor to the "hands" cursor |
| 553 |
* typically used by web browsers. |
| 554 |
*/ |
| 555 |
static void |
| 556 |
set_cursor_if_appropriate(GtkTextView *text_view, gint x, gint y) |
| 557 |
{
|
| 558 |
GSList *tags = NULL, *tagp = NULL; |
| 559 |
GtkTextIter iter; |
| 560 |
gboolean hovering = FALSE; |
| 561 |
|
| 562 |
gtk_text_view_get_iter_at_location (text_view, &iter, x, y); |
| 563 |
|
| 564 |
tags = gtk_text_iter_get_tags (&iter); |
| 565 |
for (tagp = tags; tagp != NULL; tagp = tagp->next) { |
| 566 |
GtkTextTag *tag = tagp->data; |
| 567 |
gboolean is_link = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "is_link"));
|
| 568 |
|
| 569 |
if (is_link != 0) { |
| 570 |
hovering = TRUE; |
| 571 |
break;
|
| 572 |
} |
| 573 |
} |
| 574 |
|
| 575 |
if (hovering != hovering_over_link) {
|
| 576 |
hovering_over_link = hovering; |
| 577 |
|
| 578 |
if (hovering_over_link) {
|
| 579 |
gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor); |
| 580 |
} else {
|
| 581 |
gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor); |
| 582 |
} |
| 583 |
} |
| 584 |
|
| 585 |
if (tags) {
|
| 586 |
g_slist_free (tags); |
| 587 |
} |
| 588 |
} |
| 589 |
|
| 590 |
/* Update the cursor image if the pointer moved.
|
| 591 |
*/ |
| 592 |
static gboolean
|
| 593 |
motion_notify_event (GtkWidget *text_view, GdkEventMotion *event) |
| 594 |
{
|
| 595 |
gint x, y; |
| 596 |
|
| 597 |
gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, event->x, event->y, &x, &y); |
| 598 |
|
| 599 |
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y); |
| 600 |
|
| 601 |
#if GTK_CHECK_VERSION(2,14,0) |
| 602 |
gdk_window_get_pointer (gtk_widget_get_window(text_view), NULL, NULL, NULL); |
| 603 |
#else
|
| 604 |
gdk_window_get_pointer (text_view->window, NULL, NULL, NULL); |
| 605 |
#endif
|
| 606 |
|
| 607 |
return FALSE;
|
| 608 |
} |
| 609 |
|
| 610 |
/* Also update the cursor image if the window becomes visible
|
| 611 |
* (e.g. when a window covering it got iconified). |
| 612 |
*/ |
| 613 |
static gboolean
|
| 614 |
visibility_notify_event (GtkWidget *text_view, GdkEventVisibility *event) |
| 615 |
{
|
| 616 |
gint wx, wy, bx, by; |
| 617 |
|
| 618 |
#if GTK_CHECK_VERSION(2,14,0) |
| 619 |
gdk_window_get_pointer (gtk_widget_get_window(text_view), &wx, &wy, NULL);
|
| 620 |
#else
|
| 621 |
gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
|
| 622 |
#endif
|
| 623 |
|
| 624 |
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, wx, wy, &bx, &by); |
| 625 |
|
| 626 |
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by); |
| 627 |
|
| 628 |
return FALSE;
|
| 629 |
} |
| 630 |
|
| 631 |
#define CHECK_VERSION_IS_OLDER(major,minor,micro) \
|
| 632 |
(MAJOR_VERSION < (major) || \ |
| 633 |
(MAJOR_VERSION == (major) && MINOR_VERSION < (minor)) || \ |
| 634 |
(MAJOR_VERSION == (major) && MINOR_VERSION == (minor) && \ |
| 635 |
MICRO_VERSION < (micro))) |
| 636 |
|
| 637 |
#define CHECK_IS_VERSION(major,minor,micro) \
|
| 638 |
(MAJOR_VERSION == (major) && MINOR_VERSION == (minor) && MICRO_VERSION == (micro)) |
| 639 |
|
| 640 |
static GtkWidget *
|
| 641 |
generate_version_table(UpdateInfo *info) |
| 642 |
{
|
| 643 |
GtkWidget *table; |
| 644 |
GtkWidget *label; |
| 645 |
char tmp[64]; |
| 646 |
gboolean unstable_available; |
| 647 |
|
| 648 |
if (info->unstable_major_version > 0 || |
| 649 |
info->unstable_minor_version > 0 ||
|
| 650 |
info->unstable_micro_version > 0) {
|
| 651 |
|
| 652 |
table = gtk_table_new(3, 2, FALSE); |
| 653 |
unstable_available = TRUE; |
| 654 |
} else {
|
| 655 |
table = gtk_table_new(2, 2, FALSE); |
| 656 |
unstable_available = FALSE; |
| 657 |
} |
| 658 |
|
| 659 |
/* Active version */
|
| 660 |
label = gtk_label_new(_("You are using version:"));
|
| 661 |
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 662 |
|
| 663 |
memset(&tmp, 0, sizeof(tmp)); |
| 664 |
snprintf(tmp, sizeof(tmp) - 1, "%i.%i.%i", MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION); |
| 665 |
label = gtk_label_new(tmp); |
| 666 |
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 667 |
|
| 668 |
/* Latest available stable */
|
| 669 |
if (unstable_available) {
|
| 670 |
label = gtk_label_new(_("The latest available stable version is:"));
|
| 671 |
} else {
|
| 672 |
label = gtk_label_new(_("The latest available version is:"));
|
| 673 |
} |
| 674 |
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 675 |
|
| 676 |
memset(&tmp, 0, sizeof(tmp)); |
| 677 |
snprintf(tmp, sizeof(tmp) - 1, "%i.%i.%i", info->stable_major_version, info->stable_minor_version, info->stable_micro_version); |
| 678 |
label = gtk_label_new(tmp); |
| 679 |
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 680 |
|
| 681 |
/* Latest available unstable */
|
| 682 |
if (unstable_available) {
|
| 683 |
label = gtk_label_new(_("The latest available unstable version is:"));
|
| 684 |
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 685 |
|
| 686 |
memset(&tmp, 0, sizeof(tmp)); |
| 687 |
snprintf(tmp, sizeof(tmp) - 1, "%i.%i.%i", info->unstable_major_version, info->unstable_minor_version, info->unstable_micro_version); |
| 688 |
label = gtk_label_new(tmp); |
| 689 |
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 5, 1); |
| 690 |
} |
| 691 |
|
| 692 |
gtk_widget_show_all(table); |
| 693 |
|
| 694 |
return table;
|
| 695 |
} |
| 696 |
|
| 697 |
#pragma GCC diagnostic push
|
| 698 |
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" |
| 699 |
static void |
| 700 |
generate_html(UpdateInfo *info) |
| 701 |
{
|
| 702 |
GtkWidget *textview; |
| 703 |
GtkTextBuffer *buffer; |
| 704 |
GtkTextIter iter; |
| 705 |
GtkTextIter iter2; |
| 706 |
GtkWidget *table; |
| 707 |
GtkTextChildAnchor *anchor; |
| 708 |
char *data;
|
| 709 |
|
| 710 |
textview = nntpgrab_gui_base_get_widget("htmlInformation");
|
| 711 |
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); |
| 712 |
|
| 713 |
gtk_text_buffer_get_end_iter(buffer, &iter); |
| 714 |
|
| 715 |
table = generate_version_table(info); |
| 716 |
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter); |
| 717 |
gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(textview), table, anchor); |
| 718 |
iter2 = iter; |
| 719 |
gtk_text_iter_backward_char(&iter2); |
| 720 |
gtk_text_buffer_apply_tag_by_name(buffer, "center", &iter2, &iter);
|
| 721 |
|
| 722 |
gtk_text_buffer_insert(buffer, &iter, "\n\n", -1); |
| 723 |
|
| 724 |
if (info->unstable_major_version < 0 && CHECK_IS_VERSION(info->stable_major_version, info->stable_minor_version, info->stable_micro_version)) { |
| 725 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("You are using the latest version of NNTPGrab"), -1, "center", NULL); |
| 726 |
gtk_text_buffer_insert(buffer, &iter, "\n", -1); |
| 727 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("For more information, go to our website "), -1, "center", NULL); |
| 728 |
insert_link(buffer, &iter, "https://www.nntpgrab.nl");
|
| 729 |
} else if (CHECK_IS_VERSION(info->unstable_major_version, info->unstable_minor_version, info->unstable_micro_version)) { |
| 730 |
data = g_strdup_printf("%s\n%s\n\n", _("You are using the latest unstable version of NNTPGrab"), _("If you find any bugs with this version, please report these")); |
| 731 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, data, -1, "center", NULL); |
| 732 |
g_free(data); |
| 733 |
|
| 734 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("For more information, go to our website "), -1, "center", NULL); |
| 735 |
insert_link(buffer, &iter, "https://www.nntpgrab.nl");
|
| 736 |
} else if ((info->unstable_major_version < 0 && !(CHECK_VERSION_IS_OLDER(info->stable_major_version, info->stable_minor_version, info->stable_micro_version))) || |
| 737 |
(info->unstable_major_version >=0 && !(CHECK_VERSION_IS_OLDER(info->unstable_major_version, info->unstable_minor_version, info->unstable_micro_version)))) {
|
| 738 |
|
| 739 |
data = g_strdup_printf("%s\n%s %"G_GUINT64_FORMAT" (%s %"G_GUINT64_FORMAT") %s %"G_GUINT64_FORMAT"\n\n", _("You are using a snapshot version of NNTPGrab"), _("This is subversion revision"), (guint64) GET_BUILD_SVN_REV, _("build"), (guint64) GET_BUILD_NUMBER, _("which was built on "), (guint64) GET_BUILD_DATE); |
| 740 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, data, -1, "center", NULL); |
| 741 |
g_free(data); |
| 742 |
|
| 743 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("For more information, go to our website "), -1, "center", NULL); |
| 744 |
insert_link(buffer, &iter, "https://www.nntpgrab.nl");
|
| 745 |
} else {
|
| 746 |
GList *list; |
| 747 |
GList *list2; |
| 748 |
|
| 749 |
if (info->unstable_major_version >= 0) { |
| 750 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("A new unstable version of NNTPGrab is available!"), -1, "center", "x-large", "bold", NULL); |
| 751 |
data = g_strdup_printf("\n\n%s %i.%i.%i %s %s %s\n\n", _("Version"), info->unstable_major_version, info->unstable_minor_version, info->unstable_micro_version, _("is released on"), info->date_latest_unstable_version_str, _("and contains the following changes :")); |
| 752 |
} else {
|
| 753 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("A new version of NNTPGrab is available!"), -1, "center", "x-large", "bold", NULL); |
| 754 |
data = g_strdup_printf("\n\n%s %i.%i.%i %s %s %s\n\n", _("Version"), info->stable_major_version, info->stable_minor_version, info->stable_micro_version, _("is released on"), info->date_latest_stable_version_str, _("and contains the following changes :")); |
| 755 |
} |
| 756 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, data, -1, "center", NULL); |
| 757 |
g_free(data); |
| 758 |
|
| 759 |
list = info->changelogs; |
| 760 |
while (list) {
|
| 761 |
ChangeLog *changelog = list->data; |
| 762 |
|
| 763 |
if (!CHECK_VERSION_IS_OLDER(changelog->major_version, changelog->minor_version, changelog->micro_version)) {
|
| 764 |
list = g_list_next(list); |
| 765 |
continue;
|
| 766 |
} |
| 767 |
|
| 768 |
data = g_strdup_printf("%s %i.%i.%i:\n\n", _("Changes in version"), changelog->major_version, changelog->minor_version, changelog->micro_version); |
| 769 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, data, -1, "underline", "bold", NULL); |
| 770 |
g_free(data); |
| 771 |
|
| 772 |
list2 = changelog->entries; |
| 773 |
while (list2) {
|
| 774 |
char *entry = list2->data;
|
| 775 |
|
| 776 |
data = g_strdup_printf("• %s\n", entry);
|
| 777 |
gtk_text_buffer_insert(buffer, &iter, data, -1);
|
| 778 |
g_free(data); |
| 779 |
|
| 780 |
list2 = g_list_next(list2); |
| 781 |
} |
| 782 |
|
| 783 |
gtk_text_buffer_insert(buffer, &iter, "\n", -1); |
| 784 |
|
| 785 |
list = g_list_next(list); |
| 786 |
} |
| 787 |
gtk_text_buffer_insert(buffer, &iter, "\n", -1); |
| 788 |
|
| 789 |
if (info->unstable_major_version >= 0) { |
| 790 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("Please note that the unstable version may still contain bugs, so only use the unstable version when you want to help out testing"), -1, "center", "bold", NULL); |
| 791 |
gtk_text_buffer_insert(buffer, &iter, "\n\n", -1); |
| 792 |
} |
| 793 |
|
| 794 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("To retrieve the latest version and for more information, go to our website "), -1, "center", NULL); |
| 795 |
insert_link(buffer, &iter, "https://www.nntpgrab.nl");
|
| 796 |
} |
| 797 |
} |
| 798 |
#pragma GCC diagnostic pop
|
| 799 |
|
| 800 |
static gboolean
|
| 801 |
process_update_info(gpointer data) |
| 802 |
{
|
| 803 |
UpdateInfo *info; |
| 804 |
GList *list; |
| 805 |
char *errmsg = NULL; |
| 806 |
char *contents = (char*) data; |
| 807 |
|
| 808 |
if (!contents) {
|
| 809 |
// Update check failed
|
| 810 |
GtkWidget *windowMain = nntpgrab_gui_base_get_widget("windowMain");
|
| 811 |
nntpgrab_gui_base_dialog_show(windowMain, _("Update check failed"), GTK_MESSAGE_ERROR, GTK_BUTTONS_OK);
|
| 812 |
return FALSE;
|
| 813 |
} |
| 814 |
|
| 815 |
info = parse_version_info(contents, &errmsg); |
| 816 |
|
| 817 |
g_free(contents); |
| 818 |
|
| 819 |
if (!info) {
|
| 820 |
// Invalid data received
|
| 821 |
char *msg;
|
| 822 |
GtkWidget *windowMain = nntpgrab_gui_base_get_widget("windowMain");
|
| 823 |
|
| 824 |
msg = g_strdup_printf(_("Update check failed due to invalid data:\n%s"), errmsg);
|
| 825 |
nntpgrab_gui_base_dialog_show(windowMain, msg, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK); |
| 826 |
|
| 827 |
g_free(msg); |
| 828 |
g_free(errmsg); |
| 829 |
|
| 830 |
return FALSE;
|
| 831 |
} |
| 832 |
|
| 833 |
generate_html(info); |
| 834 |
|
| 835 |
list = info->changelogs; |
| 836 |
while (list) {
|
| 837 |
ChangeLog *changelog = list->data; |
| 838 |
GList *list2; |
| 839 |
|
| 840 |
list2 = changelog->entries; |
| 841 |
while (list2) {
|
| 842 |
g_free(list2->data); |
| 843 |
list2 = g_list_next(list2); |
| 844 |
} |
| 845 |
g_list_free(changelog->entries); |
| 846 |
|
| 847 |
g_slice_free(ChangeLog, list->data); |
| 848 |
list = g_list_next(list); |
| 849 |
} |
| 850 |
g_list_free(info->changelogs); |
| 851 |
g_slice_free(UpdateInfo, info); |
| 852 |
|
| 853 |
return FALSE;
|
| 854 |
} |
| 855 |
|
| 856 |
#ifdef HAVE_SOUP
|
| 857 |
static void |
| 858 |
update_info_received(SoupSession *session, SoupMessage *msg, gpointer data) |
| 859 |
{
|
| 860 |
if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
|
| 861 |
process_update_info(NULL);
|
| 862 |
//g_object_unref(session);
|
| 863 |
return;
|
| 864 |
} |
| 865 |
|
| 866 |
process_update_info(g_strdup(msg->response_body->data)); |
| 867 |
|
| 868 |
//g_object_unref(session);
|
| 869 |
} |
| 870 |
|
| 871 |
#else
|
| 872 |
static gpointer
|
| 873 |
check_for_updates(gpointer data) |
| 874 |
{
|
| 875 |
char *contents;
|
| 876 |
|
| 877 |
contents = retrieve_website_info(); |
| 878 |
|
| 879 |
g_idle_add(process_update_info, contents); |
| 880 |
|
| 881 |
return NULL; |
| 882 |
} |
| 883 |
#endif
|
| 884 |
|
| 885 |
void
|
| 886 |
info_initialize() |
| 887 |
{
|
| 888 |
GtkWidget *textview; |
| 889 |
GtkTextBuffer *buffer; |
| 890 |
GtkTextIter iter; |
| 891 |
|
| 892 |
textview = nntpgrab_gui_base_get_widget("htmlInformation");
|
| 893 |
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); |
| 894 |
|
| 895 |
gtk_text_buffer_create_tag (buffer, "extra_top_margin", "pixels-above-lines", 5, "pixels-above-lines-set", TRUE, NULL); |
| 896 |
gtk_text_buffer_create_tag (buffer, "underline", "underline", PANGO_UNDERLINE_SINGLE, "underline_set", TRUE, NULL); |
| 897 |
gtk_text_buffer_create_tag (buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); |
| 898 |
gtk_text_buffer_create_tag (buffer, "center", "justification", GTK_JUSTIFY_CENTER, NULL); |
| 899 |
gtk_text_buffer_create_tag (buffer, "x-large", "scale", PANGO_SCALE_X_LARGE, NULL); |
| 900 |
gtk_text_buffer_create_tag (buffer, "xx-large", "scale", PANGO_SCALE_XX_LARGE, NULL); |
| 901 |
|
| 902 |
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
| 903 |
|
| 904 |
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, _("Welcome to NNTPGrab"), -1, "extra_top_margin", "center", "xx-large", "bold", NULL); |
| 905 |
gtk_text_buffer_insert(buffer, &iter, "\n\n", -1); |
| 906 |
|
| 907 |
g_signal_connect (textview, "event-after", G_CALLBACK (event_after), NULL); |
| 908 |
g_signal_connect (textview, "motion-notify-event", G_CALLBACK (motion_notify_event), NULL); |
| 909 |
g_signal_connect (textview, "visibility-notify-event", G_CALLBACK (visibility_notify_event), NULL); |
| 910 |
|
| 911 |
hand_cursor = gdk_cursor_new (GDK_HAND2); |
| 912 |
regular_cursor = gdk_cursor_new (GDK_XTERM); |
| 913 |
|
| 914 |
#ifndef HAVE_SOUP
|
| 915 |
/* cURL doesn't support async transfers so we spawn a seperate thread for it */
|
| 916 |
g_thread_create(check_for_updates, NULL, TRUE, NULL); |
| 917 |
#else
|
| 918 |
SoupSession *session = soup_session_sync_new(); |
| 919 |
SoupMessage *msg; |
| 920 |
char *user_agent;
|
| 921 |
|
| 922 |
#if 0
|
| 923 |
SoupLogger *logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1); |
| 924 |
soup_session_add_feature(session, SOUP_SESSION_FEATURE(logger)); |
| 925 |
g_object_unref(logger); |
| 926 |
#endif |
| 927 |
|
| 928 |
#ifdef HAVE_SOUP_GNOME
|
| 929 |
/* Enable proxy support when using GNOME 2.26.0 or higher */
|
| 930 |
soup_session_add_feature_by_type(session, SOUP_TYPE_GNOME_FEATURES_2_26); |
| 931 |
#endif
|
| 932 |
|
| 933 |
#ifdef HAVE_SOUP_GZIP
|
| 934 |
/* Enable gzip compression */
|
| 935 |
soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER); |
| 936 |
#endif
|
| 937 |
|
| 938 |
msg = soup_message_new ("GET", "https://www.nntpgrab.nl/info.php"); |
| 939 |
|
| 940 |
user_agent = g_strdup("NNTPGrab version " VERSION " (" OS ")"); |
| 941 |
soup_message_headers_append(msg->request_headers, "User-Agent", user_agent);
|
| 942 |
g_free(user_agent); |
| 943 |
|
| 944 |
soup_message_headers_append(msg->request_headers, "Keep-Alive", "30"); |
| 945 |
soup_message_headers_append(msg->request_headers, "Connection", "Keep-alive"); |
| 946 |
|
| 947 |
soup_session_queue_message(session, msg, update_info_received, NULL);
|
| 948 |
#endif
|
| 949 |
} |
| 950 |
|
| 951 |
G_MODULE_EXPORT void
|
| 952 |
on_btnDonate_clicked(GtkWidget *caller, gpointer data) |
| 953 |
{
|
| 954 |
open_uri(NULL, "https://www.nntpgrab.nl/donate.php", NULL); |
| 955 |
} |
NNTPGrab

