utils.c 7.85 KB
Newer Older
1 2 3 4 5 6 7
/* See LICENSE file for license and copyright information */

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
8
#include <gtk/gtk.h>
9
#include <girara/datastructures.h>
10
#include <girara/session.h>
11
#include <girara/settings.h>
12
#include <girara/utils.h>
13

14
#include "links.h"
15 16
#include "utils.h"
#include "zathura.h"
17
#include "internal.h"
18
#include "document.h"
19 20
#include "page.h"
#include "plugin.h"
21
#include "content-type.h"
22

23
double
24
zathura_correct_zoom_value(girara_session_t* session, const double zoom)
25 26
{
  if (session == NULL) {
27
    return zoom;
28 29 30 31 32 33 34 35 36 37 38
  }

  /* zoom limitations */
  int zoom_min_int = 10;
  int zoom_max_int = 1000;
  girara_setting_get(session, "zoom-min", &zoom_min_int);
  girara_setting_get(session, "zoom-max", &zoom_max_int);

  const double zoom_min = zoom_min_int * 0.01;
  const double zoom_max = zoom_max_int * 0.01;

39
  if (zoom < zoom_min) {
40
    return zoom_min;
41
  } else if (zoom > zoom_max) {
42 43
    return zoom_max;
  } else {
44
    return zoom;
45 46 47
  }
}

48 49 50
bool
file_valid_extension(zathura_t* zathura, const char* path)
{
51
  if (zathura == NULL || path == NULL || zathura->plugins.manager == NULL) {
52 53 54
    return false;
  }

55
  char* content_type = zathura_content_type_guess(zathura->content_type_context, path);
56 57 58 59
  if (content_type == NULL) {
    return false;
  }

60
  zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
61
  g_free(content_type);
62 63

  return (plugin == NULL) ? false : true;
64 65 66 67
}

void
document_index_build(GtkTreeModel* model, GtkTreeIter* parent,
68
                     girara_tree_node_t* tree)
69
{
70 71
  girara_list_t* list = girara_node_get_children(tree);

72
  GIRARA_LIST_FOREACH_BODY(list, girara_tree_node_t*, node,
73 74 75 76 77 78 79 80 81 82 83 84 85 86
    zathura_index_element_t* index_element = (zathura_index_element_t*)girara_node_get_data(node);

    zathura_link_type_t type     = zathura_link_get_type(index_element->link);
    zathura_link_target_t target = zathura_link_get_target(index_element->link);

    gchar* description = NULL;
    if (type == ZATHURA_LINK_GOTO_DEST) {
      description = g_strdup_printf("Page %d", target.page_number + 1);
    } else {
      description = g_strdup(target.value);
    }

    GtkTreeIter tree_iter;
    gtk_tree_store_append(GTK_TREE_STORE(model), &tree_iter, parent);
87 88 89
    gchar* markup = g_markup_escape_text(index_element->title, -1);
    gtk_tree_store_set(GTK_TREE_STORE(model), &tree_iter, 0, markup, 1, description, 2, index_element, -1);
    g_free(markup);
90 91 92 93 94 95
    g_object_weak_ref(G_OBJECT(model), (GWeakNotify) zathura_index_element_free, index_element);
    g_free(description);

    if (girara_node_get_num_children(node) > 0) {
      document_index_build(model, &tree_iter, node);
    }
96
  );
97 98
}

99 100
zathura_rectangle_t
rotate_rectangle(zathura_rectangle_t rectangle, unsigned int degree, double height, double width)
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
{
  zathura_rectangle_t tmp;
  switch (degree) {
    case 90:
      tmp.x1 = height - rectangle.y2;
      tmp.x2 = height - rectangle.y1;
      tmp.y1 = rectangle.x1;
      tmp.y2 = rectangle.x2;
      break;
    case 180:
      tmp.x1 = width - rectangle.x2;
      tmp.x2 = width - rectangle.x1;
      tmp.y1 = height - rectangle.y2;
      tmp.y2 = height - rectangle.y1;
      break;
    case 270:
      tmp.x1 = rectangle.y1;
      tmp.x2 = rectangle.y2;
      tmp.y1 = width - rectangle.x2;
      tmp.y2 = width - rectangle.x1;
      break;
    default:
      tmp.x1 = rectangle.x1;
      tmp.x2 = rectangle.x2;
      tmp.y1 = rectangle.y1;
      tmp.y2 = rectangle.y2;
  }

  return tmp;
}

zathura_rectangle_t
recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle)
{
135 136
  if (page == NULL) {
    goto error_ret;
137 138
  }

139 140 141 142 143 144 145 146 147 148
  zathura_document_t* document = zathura_page_get_document(page);

  if (document == NULL) {
    goto error_ret;
  }

  double page_height = zathura_page_get_height(page);
  double page_width  = zathura_page_get_width(page);
  double scale       = zathura_document_get_scale(document);

149 150 151 152 153
  zathura_rectangle_t tmp = rotate_rectangle(rectangle, zathura_document_get_rotation(document), page_height, page_width);
  tmp.x1 *= scale;
  tmp.x2 *= scale;
  tmp.y1 *= scale;
  tmp.y2 *= scale;
154 155

  return tmp;
156 157 158 159

error_ret:

  return rectangle;
160 161
}

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
GtkWidget*
zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page)
{
  if (zathura == NULL || page == NULL || zathura->pages == NULL) {
    return NULL;
  }

  unsigned int page_number = zathura_page_get_index(page);

  return zathura->pages[page_number];
}

void
document_draw_search_results(zathura_t* zathura, bool value)
{
  if (zathura == NULL || zathura->document == NULL || zathura->pages == NULL) {
    return;
  }

  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    g_object_set(zathura->pages[page_id], "draw-search-results", (value == true) ? TRUE : FALSE, NULL);
184 185
  }
}
186 187 188 189

char*
zathura_get_version_string(zathura_t* zathura, bool markup)
{
190 191 192
  if (zathura == NULL) {
    return NULL;
  }
193 194 195 196

  GString* string = g_string_new(NULL);

  /* zathura version */
197 198
  g_string_append(string, "zathura " ZATHURA_VERSION);
  g_string_append_printf(string, "\ngirara " GIRARA_VERSION " (runtime: %s)", girara_version());
199

200
  const char* format = (markup == true) ? "\n<i>(plugin)</i> %s (%d.%d.%d) <i>(%s)</i>" : "\n(plugin) %s (%d.%d.%d) (%s)";
201 202 203 204

  /* plugin information */
  girara_list_t* plugins = zathura_plugin_manager_get_plugins(zathura->plugins.manager);
  if (plugins != NULL) {
205
    GIRARA_LIST_FOREACH_BODY(plugins, zathura_plugin_t*, plugin,
206
      const char* name = zathura_plugin_get_name(plugin);
207
      zathura_plugin_version_t version = zathura_plugin_get_version(plugin);
208 209 210 211 212 213
      g_string_append_printf(string, format,
                             (name == NULL) ? "-" : name,
                             version.major,
                             version.minor,
                             version.rev,
                             zathura_plugin_get_path(plugin));
214
    );
215 216
  }

217 218
  char* version = string->str;
  g_string_free(string, FALSE);
219

220
  return version;
221 222
}

223 224
GdkAtom*
get_selection(zathura_t* zathura)
225
{
226
  g_return_val_if_fail(zathura != NULL, NULL);
227

228
  char* value = NULL;
229
  girara_setting_get(zathura->ui.session, "selection-clipboard", &value);
230 231 232
  if (value == NULL) {
    return NULL;
  }
233

234 235
  GdkAtom* selection = g_try_malloc(sizeof(GdkAtom));
  if (selection == NULL) {
236
    g_free(selection);
237 238
    return NULL;
  }
239

240 241 242 243 244 245 246 247
  if (strcmp(value, "primary") == 0) {
    *selection = GDK_SELECTION_PRIMARY;
  } else if (strcmp(value, "clipboard") == 0) {
    *selection = GDK_SELECTION_CLIPBOARD;
  } else {
    girara_error("Invalid value for the selection-clipboard setting");
    g_free(value);
    g_free(selection);
248

249 250
    return NULL;
  }
251

252
  g_free(value);
253

254
  return selection;
255
}
256 257 258 259 260 261 262

unsigned int
find_first_page_column(const char* first_page_column_list,
                       const unsigned int pages_per_row)
{
  /* sanity checks */
  unsigned int first_page_column = 1;
263 264 265
  g_return_val_if_fail(first_page_column_list != NULL,  first_page_column);
  g_return_val_if_fail(*first_page_column_list != '\0', first_page_column);
  g_return_val_if_fail(pages_per_row > 0,               first_page_column);
266 267

  /* split settings list */
268
  char** settings = g_strsplit(first_page_column_list, ":", pages_per_row + 1);
269 270 271 272
  const size_t settings_size = g_strv_length(settings);

  /* read setting value corresponding to the specified pages per row */
  unsigned int index = pages_per_row - 1;
273
  if (index < settings_size && *settings[index] != '\0') {
274
    first_page_column = atoi(settings[index]);
275 276
  } else if (*settings[settings_size - 1] != '\0') {
    first_page_column = atoi(settings[settings_size - 1]);
277 278 279 280 281 282 283
  }

  /* free buffers */
  g_strfreev(settings);

  return first_page_column;
}
284 285 286 287 288 289 290 291 292 293

bool
parse_color(GdkRGBA* color, const char* str)
{
  if (gdk_rgba_parse(color, str) == FALSE) {
    girara_warning("Failed to parse color string '%s'.", str);
    return false;
  }
  return true;
}