Logo Search packages:      
Sourcecode: parcellite version File versions  Download package

history.c

/* Copyright (C) 2007-2008 by Xyhthyx <xyhthyx@gmail.com>
 *
 * This file is part of Parcellite.
 *
 * Parcellite 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.
 *
 * Parcellite 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, see <http://www.gnu.org/licenses/>.
 */

#include <gtk/gtk.h>
#include "main.h"
#include "utils.h"

GSList* history = NULL;

/* Reads history from ~/.local/share/parcellite/history */
void h_read()
{
      /* Open the file for reading */
      gchar* history_path = g_build_filename(g_get_home_dir(),
                                             ".local/share/parcellite/history", NULL);
      
      FILE* history_file = fopen(history_path, "rb");
      g_free(history_path);
      /* Check that it opened and begin read */
      if (history_file)
      {
            /* Read the size of the first item */
            gint size;
            fread(&size, 4, 1, history_file); 
            /* Continue reading until size is 0 */
            while (size != 0)
            {
                  /* Malloc according to the size of the item */
                  gchar* item = (gchar*)g_malloc(size + 1);
                  /* Read item and add ending character */
                  fread(item, size, 1, history_file);
                  item[size] = '\0';
                  /* Prepend item and read next size */
                  history = g_slist_prepend(history, item);
                  fread(&size, 4, 1, history_file);
            }
            /* Close file and reverse the history since every item
             * was prepended instead of appended (prepend is faster)
             */
            fclose(history_file);
            history = g_slist_reverse(history);
      }
}

/* Saves history to ~/.local/share/parcellite/history */
void h_save()
{
      /* Check that the directory is available */
      u_check_directories();
      /* Open the file for writing */
      gchar* history_path = g_build_filename(g_get_home_dir(),
                                             ".local/share/parcellite/history", NULL);
      
      FILE* history_file = fopen(history_path, "wb");
      g_free(history_path);
      /* Check that it opened and begin write */
      if (history_file)
      {
            GSList* element;
            /* Write each element to a binary file */
            for (element = history; element != NULL; element = element->next)
            {
                  /* Create new GString from element data, write its length (size)
                   * to file followed by the element data itself
                   */
                  GString* item = g_string_new((gchar*)element->data);
                  fwrite(&(item->len), 4, 1, history_file);
                  fputs(item->str, history_file);
                  g_string_free(item, TRUE);
            }
            /* Write 0 to indicate end of file */
            gint end = 0;
            fwrite(&end, 4, 1, history_file);
            fclose(history_file);
      }
}

/* Adds item to the end of history */
void h_append(gchar* item)
{
      if (item)
      {
            /* Reverse and prepend new item then reverse again when finished
             * This is faster than g_slist_append()
             */
            history = g_slist_reverse(history);
            history = g_slist_prepend(history, g_strdup(item));
            /* Shorten history if necessary */
            GSList* last_possible_element = g_slist_nth(history, history_limit - 1);
            if (last_possible_element)
            {
                  /* Free last posible element and subsequent elements */
                  g_slist_free(last_possible_element->next);
                  last_possible_element->next = NULL;
            }
            /* Return history to normal */
            history = g_slist_reverse(history);
            /* Save changes */
            if (save_history)
                  h_save();
      }
}

/* Truncates history to history_limit items */
void h_truncate()
{
      if (history)
      {
            /* Reverse history list */
            history = g_slist_reverse(history);
            /* Shorten history if necessary */
            GSList* last_possible_element = g_slist_nth(history, history_limit - 1);
            if (last_possible_element)
            {
                  /* Free last posible element and subsequent elements */
                  g_slist_free(last_possible_element->next);
                  last_possible_element->next = NULL;
            }
            /* Return history to normal */
            history = g_slist_reverse(history);
            /* Save changes */
            if (save_history)
                  h_save();
      }
}

/* Returns pointer to last item in history */
gpointer h_get_last()
{
      if (history)
      {
            /* Reverse history to have last element first */
            history = g_slist_reverse(history);
            if (history->data)
            {
                  /* Get the last element and return history to normal */
                  gpointer last_item = history->data;
                  history = g_slist_reverse(history);
                  return last_item;
            }
            else
            {
                  /* Return history to normal */
                  history = g_slist_reverse(history);
                  return NULL;
            }
      }
      else
            return NULL;
}

Generated by  Doxygen 1.6.0   Back to index