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

callbacks.c

/*
 *  Copyright (C) 2006 Giuseppe Torelli - <colossus73@gmail.com>
 *  Copyright (C) 2006 Benedikt Meurer - <benny@xfce.org>
 *
 *  This program 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "callbacks.h"
#include "string_utils.h"
#include "interface.h"
#include "support.h"
#include "main.h"

extern GList *ArchiveType;
extern GList *ArchiveSuffix;
extern gboolean cli;
extern gboolean stop_flag;

#ifndef HAVE_STRCASESTR
/*
 * case-insensitive version of strstr()
 */
const char *strcasestr(const char *haystack, const char *needle)
{
      const char *h;
      const char *n;

      h = haystack;
      n = needle;
      while (*haystack)
      {
            if (tolower((unsigned char) *h) == tolower((unsigned char) *n))
            {
                  h++;
                  n++;
                  if (!*n)
                        return haystack;
            } else {
                  h = ++haystack;
                  n = needle;
            }
      }
      return NULL;
}
#endif /* !HAVE_STRCASESTR */

gchar *CurrentFolder = NULL;
GList *Suffix , *Name;
gint current_archive_suffix = 0;

void xa_watch_child ( GPid pid, gint status, gpointer data)
{
      XArchive *archive = data;
      gboolean new      = FALSE;
      gboolean open     = FALSE;
      gboolean add      = FALSE;
      gboolean extract= FALSE;
      gboolean select   = FALSE;
      gboolean check    = FALSE;
      gboolean info     = FALSE;
      
      gtk_widget_set_sensitive (close1,TRUE);

      if ( archive->type == XARCHIVETYPE_BZIP2 || archive->type == XARCHIVETYPE_GZIP )
      {
            new = open = TRUE;
            info = FALSE;
      }     
      else if (archive->type == XARCHIVETYPE_RPM)
      {
            new = open = extract = select = TRUE;
            info = FALSE;
      }
      else if (archive->type == XARCHIVETYPE_TAR_BZ2 || archive->type == XARCHIVETYPE_TAR_GZ || archive->type == XARCHIVETYPE_TAR )
      {
            new = open = add = extract = select = info = TRUE;
            check = FALSE;
      }
      else
      {
            check = TRUE;
            new = open = add = extract = select = info = TRUE;
      }
      gtk_widget_set_sensitive ( check_menu , check);
      gtk_widget_set_sensitive ( properties , info);
      xa_set_button_state (new,open,add,extract,select);

      if ( WIFSIGNALED (status) )
      {
            Update_StatusBar ( _("Operation canceled."));
            if (archive->status == XA_ARCHIVESTATUS_EXTRACT)
            {
                  gchar *msg = g_strdup_printf(_("Please check \"%s\" since some files could have been already extracted."),archive->extraction_path);

            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_INFO,     GTK_BUTTONS_OK,"",msg );
            g_free (msg);
            }
            else if (archive->status == XA_ARCHIVESTATUS_OPEN)
            {
                  xa_set_button_state (1,1,0,0,0);
                  gtk_widget_set_sensitive ( check_menu , FALSE );
            }
            archive->status = XA_ARCHIVESTATUS_IDLE;
            return;
      }
      OffTooltipPadlock();

      if ( WIFEXITED (status) )
      {
            if ( WEXITSTATUS (status) )
            {
                  response = ShowGtkMessageDialog (GTK_WINDOW     (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("An error occurred while accessing the archive."),_("Do you want to open the error messages window?") );
                  if (response == GTK_RESPONSE_YES)
                        ShowShellOutput (NULL);
                  /* In case the user supplies a wrong password we reset it so he can try again */
                  if (archive->status == XA_ARCHIVESTATUS_TEST && archive->passwd != NULL)
                  {
                        g_free (archive->passwd);
                        archive->passwd = NULL;
                  }
                  archive->status = XA_ARCHIVESTATUS_IDLE;
                  Update_StatusBar ( _("Operation failed."));
                  return;
            }
      }
      if (archive->status == XA_ARCHIVESTATUS_TEST)
            ShowShellOutput (NULL);

      if ( ! cli )
      {
            /* This to automatically reload the content of the archive after adding or deleting */
            if (archive->status == XA_ARCHIVESTATUS_DELETE || archive->status == XA_ARCHIVESTATUS_ADD)
            {
                if (archive->type == XARCHIVETYPE_BZIP2 || archive->type == XARCHIVETYPE_GZIP)
                        Update_StatusBar ( _("Operation completed."));
                  else
                  {
                        Update_StatusBar ( _("Please wait while the content of the archive is being updated..."));
                        RemoveColumnsListStore();
                  }
                  switch ( archive->type )
                  {
                        case XARCHIVETYPE_RAR:
                      OpenRar ( archive );
                        break;

                        case XARCHIVETYPE_TAR:
                        OpenTar ( archive );
                        break;

                        case XARCHIVETYPE_TAR_BZ2:
                        OpenBzip2 ( archive );
                        break;

                        case XARCHIVETYPE_TAR_GZ:
                        OpenGzip ( archive );
                        break;

                        case XARCHIVETYPE_ZIP:
                        OpenZip ( archive );
                        break;

                        case XARCHIVETYPE_7ZIP:
                        Open7Zip ( archive );
                        break;

                        case XARCHIVETYPE_ARJ:
                        OpenArj ( archive );
                        break;
            
                        default:
                        break;
                  }
            }
      }

      if ( archive->status != XA_ARCHIVESTATUS_EXTRACT && archive->type != XARCHIVETYPE_BZIP2 && archive->type != XARCHIVETYPE_GZIP)
      {
            gtk_tree_view_set_model (GTK_TREE_VIEW(treeview1), model);
            g_object_unref (model);
      }
      gtk_widget_grab_focus (treeview1);
      gtk_window_set_title ( GTK_WINDOW (MainWindow) , archive->path );
      archive->status = XA_ARCHIVESTATUS_IDLE;
    Update_StatusBar ( _("Operation completed."));
}

void xa_new_archive (GtkMenuItem *menuitem, gpointer user_data)
{
      archive = xa_init_archive_structure (archive);
      if (user_data != NULL)
            archive->tmp = g_path_get_basename ( user_data);
      gchar *path = Show_File_Dialog ( 1 , "new" );
      g_free (archive->tmp);
      archive->tmp = NULL;
      if (path == NULL)
            return;
      if ( g_file_test ( path , G_FILE_TEST_EXISTS ) )
      {
            gchar *utf8_path;
            gchar  *msg;

            utf8_path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
            msg = g_strdup_printf (_("The archive \"%s\" already exists!"), utf8_path);
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),
                                    GTK_DIALOG_MODAL,
                                    GTK_MESSAGE_QUESTION,
                                    GTK_BUTTONS_YES_NO,
                                    msg,
                                    _("Do you want to overwrite it?")
                                    );
            g_free (utf8_path);
            g_free (msg);           
            if (response != GTK_RESPONSE_YES)
            {
                  g_free (path);
            return;
            }
        /* The following to avoid to update the archive instead of adding to it since the filename exists */
        unlink ( path );
      }
      xa_set_button_state (1,1,1,0,0 );
      archive->path = g_strdup (path);
      g_free (path);
    archive->escaped_path = EscapeBadChars (archive->path , "$\'`\"\\!?* ()&|@#:;");
    EmptyTextBuffer();
    archive->has_passwd = FALSE;
    gtk_widget_set_sensitive ( iso_info , FALSE );
    gtk_widget_set_sensitive ( view_shell_output1 , TRUE );
    gtk_widget_set_sensitive ( check_menu , FALSE);
    gtk_widget_set_sensitive ( properties , FALSE );
    /* Let's off the delete and view buttons and the menu entries to avoid strange behaviours */
    OffDeleteandViewButtons ();

      if ( liststore != NULL )
            RemoveColumnsListStore();
      
      if (archive->type == XARCHIVETYPE_BZIP2 || archive->type == XARCHIVETYPE_GZIP)
      {
            Update_StatusBar ( _("Choose Add File to create the compressed file."));
            xa_set_button_state (1,1,1,0,0 );
      }
      else
            Update_StatusBar ( _("Choose Add to begin creating the archive."));

    gtk_tooltips_disable ( pad_tooltip );
    gtk_widget_hide ( pad_image );
    
    archive->passwd = NULL;
    archive->dummy_size = 0;
    archive->nr_of_files = 0;
    archive->nr_of_dirs = 0;
      gtk_window_set_title ( GTK_WINDOW (MainWindow) , archive->path );
}

int ShowGtkMessageDialog ( GtkWindow *window, int mode,int type,int button, const gchar *message1,const gchar *message2)
{
      dialog = gtk_message_dialog_new (window, mode, type, button,message1);
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), message2);
      response = gtk_dialog_run (GTK_DIALOG (dialog) );
      gtk_widget_destroy (GTK_WIDGET (dialog) );
      return response;
}

void xa_open_archive (GtkMenuItem *menuitem, gpointer data)
{
      path = (gchar *)data;
      if ( path == NULL)
    {
            path = Show_File_Dialog ( 1 , "open" );
            if (path == NULL)
                  return;
      }
      if ( liststore != NULL )
      {
            RemoveColumnsListStore();
            EmptyTextBuffer ();
      }
      archive = xa_init_archive_structure(archive);
      archive->path = g_strdup (path);
      g_free (path);
      archive->escaped_path = EscapeBadChars ( archive->path , "$\'`\"\\!?* ()&|@#:;" );
    
      OffDeleteandViewButtons();
    gtk_widget_set_sensitive ( iso_info , FALSE );
    gtk_widget_set_sensitive ( view_shell_output1 , TRUE );

    archive->type = DetectArchiveType ( archive->path );
    if ( archive->type == -2 )
            return;
    if ( archive->type == -1 )
    {
            gchar *utf8_path,*msg;
            utf8_path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
            msg = g_strdup_printf (_("Can't open file \"%s\":"), utf8_path);
        gtk_window_set_title ( GTK_WINDOW (MainWindow) , "Xarchiver " VERSION );
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,msg,
            _("Archive format is not recognized!"));
            xa_set_button_state ( 1,1,0,0,0);
            gtk_widget_set_sensitive ( check_menu , FALSE );
            gtk_widget_set_sensitive ( properties , FALSE );
            g_free (utf8_path);
            g_free (msg);
        return;
      }
    EmptyTextBuffer();
    
    //Does the user open an archive from the command line whose archiver is not installed ?
    gchar *ext = NULL;
    if ( archive->type == XARCHIVETYPE_RAR )
            ext = ".rar";
      else if ( archive->type == XARCHIVETYPE_7ZIP )
            ext = ".7z";
    else if ( archive->type == XARCHIVETYPE_ARJ )
            ext = ".arj";
    if ( ext != NULL )
        if ( ! g_list_find ( ArchiveType , ext ) )
        {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,_("Sorry, this archive format is not supported:"),_("the proper archiver is not installed!") );
            return;
        }

    gtk_widget_set_sensitive (Stop_button,TRUE);
    gtk_widget_show ( viewport2 );
    if ( archive->type == XARCHIVETYPE_ISO )
            Update_StatusBar ( _("Please wait while the content of the ISO image is being read..."));
    else
            Update_StatusBar ( _("Please wait while the content of the archive is being read..."));
      archive->status = XA_ARCHIVESTATUS_OPEN;
      switch ( archive->type )
      {
            case XARCHIVETYPE_ARJ:
            OpenArj (archive);
            break;

            case XARCHIVETYPE_BZIP2:
            OpenBzip2 (archive);
            break;

            case XARCHIVETYPE_GZIP:
            OpenGzip ( archive );
            break;

            
        case XARCHIVETYPE_ISO:
        OpenISO (archive);
            break;

            case XARCHIVETYPE_RAR:
            OpenRar (archive);
            break;

            case XARCHIVETYPE_RPM:
        OpenRPM (archive);
        break;

            case XARCHIVETYPE_TAR:
            OpenTar (archive);
            break;

            case XARCHIVETYPE_ZIP:
            OpenZip (archive);
            break;

        case XARCHIVETYPE_7ZIP:
        Open7Zip (archive);
        break;
        
        default:
        break;
      }
      if (archive->passwd != NULL)
            g_free (archive->passwd);
      archive->passwd = NULL;
}

void xa_test_archive (GtkMenuItem *menuitem, gpointer user_data)
{
    gchar *command;
      if ( archive->has_passwd )
      {
            if ( archive->passwd == NULL)
            {
                  archive->passwd = password_dialog ();
                  if ( archive->passwd == NULL)
                        return;
            }
      }
    Update_StatusBar ( _("Testing archive integrity, please wait..."));
    gtk_widget_set_sensitive (Stop_button,TRUE);
    gtk_widget_set_sensitive ( check_menu , FALSE );
    xa_set_button_state (0,0,0,0,0);
    switch ( archive->type )
      {
            case XARCHIVETYPE_RAR:
            if (archive->passwd != NULL)
                  command = g_strconcat ("rar t -idp -p" , archive->passwd ," " , archive->escaped_path, NULL);
            else
                  command = g_strconcat ("rar t -idp " , archive->escaped_path, NULL);
        break;

        case XARCHIVETYPE_ZIP:
        if (archive->passwd != NULL)
                  command = g_strconcat ("unzip -P ", archive->passwd, " -t " , archive->escaped_path, NULL);
        else
                  command = g_strconcat ("unzip -t " , archive->escaped_path, NULL);
        break;

        case XARCHIVETYPE_7ZIP:
        if (archive->passwd != NULL)
                  command = g_strconcat ( "7za t -p" , archive->passwd , " " , archive->escaped_path, NULL);
            else
                  command = g_strconcat ("7za t " , archive->escaped_path, NULL);
            break;

            case XARCHIVETYPE_ARJ:
        if (archive->passwd != NULL)
                  command = g_strconcat ("arj t -g" , archive->passwd , " -i " , archive->escaped_path, NULL);
            else
                  command = g_strconcat ("arj t -i " , archive->escaped_path, NULL);
            break;
            
            default:
            command = NULL;
      }
      archive->status = XA_ARCHIVESTATUS_TEST;
    xa_run_command ( command , 1);
    g_free (command);
}

void xa_close_archive (GtkMenuItem *menuitem, gpointer user_data)
{
      if (archive == NULL)
            return;
      
      RemoveColumnsListStore();
      EmptyTextBuffer();
      gtk_widget_set_sensitive (close1,FALSE);
      gtk_widget_set_sensitive (properties,FALSE);
      gtk_widget_set_sensitive (check_menu,FALSE);
      xa_set_button_state (1,1,0,0,0);
      xa_clean_archive_structure (archive);
      archive = NULL;
}

void xa_quit_application (GtkMenuItem *menuitem, gpointer user_data)
{
      if (archive != NULL)
      {
            if ( archive->status != XA_ARCHIVESTATUS_IDLE )
            {
                  Update_StatusBar ( _("Please hit the Stop button first!"));
                  return;
            }
            g_list_free ( Suffix );
            g_list_free ( Name );
      
            if ( destination_path != NULL )
            g_free (destination_path);
            
            xa_clean_archive_structure (archive);
      }
      gtk_main_quit();
}

void xa_delete_archive (GtkMenuItem *menuitem, gpointer user_data)
{
      gchar *command = NULL;
      gchar *tar;
      gint x;

      GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview1) );
      names = g_string_new ( " " );
      gtk_tree_selection_selected_foreach (selection, (GtkTreeSelectionForeachFunc) ConcatenateFileNames, names );
      
      x = gtk_tree_selection_count_selected_rows (selection);
      gchar *msg = g_strdup_printf(_("You are about to delete %d file(s) from the archive."),x);
      response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,msg,_( "Are you sure you want to do this?") );
      g_free (msg);
      
      if ( response == GTK_RESPONSE_NO)
            return;
      
      Update_StatusBar ( _("Deleting files from the archive, please wait..."));
      archive->status = XA_ARCHIVESTATUS_DELETE;

      tar = g_find_program_in_path ("gtar");
      if (tar == NULL)
            tar = g_strdup ("tar");

      switch (archive->type)
      {
            case XARCHIVETYPE_RAR:
            command = g_strconcat ( "rar d " , archive->escaped_path , names->str , NULL );
            break;

        case XARCHIVETYPE_TAR:
            command = g_strconcat (tar, " --delete -vf " , archive->escaped_path , names->str , NULL );
            break;

        case XARCHIVETYPE_TAR_BZ2:
        xa_add_delete_tar_bzip2_gzip ( names , archive , 0 , 0 );
        break;

        case XARCHIVETYPE_TAR_GZ:
        xa_add_delete_tar_bzip2_gzip ( names , archive , 1 , 0 );
            break;
            
        case XARCHIVETYPE_ZIP:
            command = g_strconcat ( "zip -d " , archive->escaped_path , names->str , NULL );
            break;

        case XARCHIVETYPE_7ZIP:
        command = g_strconcat ( "7za d " , archive->escaped_path , names->str , NULL );
        break;

        case XARCHIVETYPE_ARJ:
        command = g_strconcat ( "arj d " , archive->escaped_path , names->str, NULL);
        break;
        
        default:
        break;
      }
      if (command != NULL)
    {
        xa_run_command ( command , 1);
        g_free (command);
    }
    g_string_free (names , TRUE );
    g_free (tar);
}

void xa_add_files_archive ( GtkMenuItem *menuitem, gpointer data )
{
      gchar *command = NULL;
      
      add_window = xa_create_add_dialog (archive);
      command = xa_parse_add_dialog_options ( archive, add_window );
      gtk_widget_destroy ( add_window->dialog1 );
      if (command != NULL)
      {
            xa_run_command (command , 1);
            g_free (command);
      }
      g_free ( add_window );
      add_window = NULL;
}

void xa_extract_archive ( GtkMenuItem *menuitem , gpointer user_data )
{
      gchar *command = NULL;

      GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview1) );
      gint selected = gtk_tree_selection_count_selected_rows ( selection );
    extract_window = xa_create_extract_dialog (selected , archive);
      if (archive->extraction_path != NULL)
            gtk_entry_set_text (GTK_ENTRY(extract_window->destination_path_entry),archive->extraction_path);
    command = xa_parse_extract_dialog_options ( archive , extract_window, selection );
      if (extract_window->dialog1 != NULL)
      {
            gtk_widget_destroy ( extract_window->dialog1 );
            extract_window->dialog1 = NULL;
      }

      if (command != NULL)
      {
            xa_run_command (command , 1);
            g_free (command);
      }
      g_free (extract_window);
      extract_window = NULL;
}

void xa_about (GtkMenuItem *menuitem, gpointer user_data)
{
    static GtkWidget *about = NULL;
    const char *authors[] = {"\nDevelopers:\nGiuseppe Torelli - Colossus <colossus73@gmail.com>\nSalvatore Santagati for the ISO support. <salvatore.santagati@gmail.com>\n",NULL};
    const char *documenters[] = {"\nSpecial thanks to Bjoern Martensen for discovering\nmany bugs in the Xarchiver development code.\n\nThanks to:\nBenedikt Meurer\nStephan Arts\nEnrico Troeger\nUracile for the stunning logo\nThe people of gtk-app-devel-list.", NULL};
      if (about != NULL)
      {
            gtk_window_present (GTK_WINDOW (about));
            return;
      }
      about = gtk_about_dialog_new ();
      gtk_about_dialog_set_email_hook (xa_about_activate_link, NULL, NULL);
      gtk_about_dialog_set_url_hook (xa_about_activate_link, NULL, NULL);
      g_object_set (about,
                  "name",  "Xarchiver",
                  "version", PACKAGE_VERSION,
                  "copyright", "Copyright \xC2\xA9 2005-2006 Giuseppe Torelli",
                  "comments", "A lightweight GTK+2 archive manager",
                  "authors", authors,
              "documenters",documenters,
                  "translator_credits", _("translator-credits"),
                  "logo_icon_name", "xarchiver",
                  "website", "http://xarchiver.xfce.org",
                  "license",    "Copyright (C)2005-2006 Giuseppe Torelli - Colossus <colossus73@gmail.com>\n\n"
                                    "This is free software; you can redistribute it and/or\n"
                              "modify it under the terms of the GNU Library General Public License as\n"
                              "published by the Free Software Foundation; either version 2 of the\n"
                              "License, or (at your option) any later version.\n"
                              "\n"
                              "This software is distributed in the hope that it will be useful,\n"
                              "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
                              "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
                              "Library General Public License for more details.\n"
                              "\n"
                              "You should have received a copy of the GNU Library General Public\n"
                              "License along with the Gnome Library; see the file COPYING.LIB.  If not,\n"
                              "write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
                              "Boston, MA 02111-1307, USA.\n",
                  NULL);
      gtk_window_set_destroy_with_parent (GTK_WINDOW (about), TRUE);
      g_signal_connect (G_OBJECT (about), "destroy",  G_CALLBACK (gtk_widget_destroyed), &about);
      gtk_window_set_position (GTK_WINDOW (about), GTK_WIN_POS_CENTER);
      gtk_dialog_run ( GTK_DIALOG(about) );
      gtk_widget_destroy (about);
}

GSList *Add_File_Dialog ( gchar *mode )
{
      GSList *list = NULL;
      int flag;
      if ( mode == "file" )
      {
            title = _("Select the files to be added to the current archive; use SHIFT to multiple select");
            flag = GTK_FILE_CHOOSER_ACTION_OPEN;
      }
      else
      {
            if (archive->type == XARCHIVETYPE_ARJ)
                  title = _("Select the folder to be added to the current archive");
        else
                  title = _("Select the folders to be added to the current archive; use SHIFT to multiple select");
            flag = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
      }
      File_Selector = gtk_file_chooser_dialog_new ( title,
                                          GTK_WINDOW (MainWindow),
                                          flag,
                                          GTK_STOCK_CANCEL,
                                          GTK_RESPONSE_CANCEL,
                                          GTK_STOCK_ADD,
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);
    /* We set gtk_file_chooser_set_select_multiple to FALSE because a bug in ARJ prevents adding more of two directories */
    if (archive->type == XARCHIVETYPE_BZIP2 || archive->type == XARCHIVETYPE_GZIP || ( archive->type == XARCHIVETYPE_ARJ && mode == "folder" ) )
            gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER (File_Selector) , FALSE );
    else
            gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER (File_Selector) , TRUE );
      if (CurrentFolder != NULL)
            gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER (File_Selector) , CurrentFolder );
      response = gtk_dialog_run (GTK_DIALOG (File_Selector) );
      if (response == GTK_RESPONSE_ACCEPT)
            list = gtk_file_chooser_get_filenames ( GTK_FILE_CHOOSER (File_Selector) );
      gtk_widget_destroy (File_Selector);
      return list;
}

gchar *Show_File_Dialog ( int dummy , gpointer mode )
{
      GtkWidget *hbox = NULL;
      GtkWidget *combo_box = NULL;
      GtkWidget *check_button = NULL;
      GtkFileFilter *filter;
      GtkTooltips *FilterToolTip ;
      gchar *path = NULL;
    gchar *dummy_path = NULL;
      const gchar *flag2 = NULL;
      unsigned short int flag = 0;

      if ( mode == "new" )
      {
            title = _("Create a new archive");
            flag = GTK_FILE_CHOOSER_ACTION_SAVE;
            flag2 = _("Cr_eate");
      }
      else if ( mode == "open" )
      {
            title = _("Open an archive");
            flag = GTK_FILE_CHOOSER_ACTION_OPEN;
            flag2 = "gtk-open";
      }

      else if (mode == "extract" )
      {
            title = _("Choose the destination folder where to extract the current archive");
            File_Selector = gtk_file_chooser_dialog_new ( title,
            GTK_WINDOW (MainWindow),
            GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
            GTK_STOCK_CANCEL,
            GTK_RESPONSE_CANCEL,
            GTK_STOCK_OPEN,
            GTK_RESPONSE_ACCEPT,
            NULL );
        if (destination_path != NULL)
                  gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER (File_Selector) , destination_path );
        response = gtk_dialog_run (GTK_DIALOG (File_Selector));
            if (response == GTK_RESPONSE_ACCEPT)
                  gtk_entry_set_text (GTK_ENTRY(extract_window->destination_path_entry),gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER (File_Selector) ) );
            gtk_widget_destroy (File_Selector);
            return NULL;
      }

      File_Selector = gtk_file_chooser_dialog_new ( title,
                                          GTK_WINDOW (MainWindow),
                                          flag,
                                          GTK_STOCK_CANCEL,
                                          GTK_RESPONSE_CANCEL,
                                          flag2,
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);
      if (CurrentFolder != NULL)
            gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER (File_Selector) , CurrentFolder );
      gtk_dialog_set_default_response (GTK_DIALOG (File_Selector), GTK_RESPONSE_ACCEPT);

      filter = gtk_file_filter_new ();
      gtk_file_filter_set_name ( filter , _("All files") );
      gtk_file_filter_add_pattern ( filter, "*" );
      gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (File_Selector), filter);

      filter = gtk_file_filter_new ();
      gtk_file_filter_set_name ( filter , _("Only archives") );

      Suffix = g_list_first ( ArchiveSuffix );

      while ( Suffix != NULL )
      {
            gtk_file_filter_add_pattern (filter, Suffix->data);
            Suffix = g_list_next ( Suffix );
      }
      gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (File_Selector), filter);

      Suffix = g_list_first ( ArchiveSuffix );

      while ( Suffix != NULL )
      {
            if ( Suffix->data != "" )     /* To avoid double filtering when opening the archive */
            {
                  filter = gtk_file_filter_new ();
                  gtk_file_filter_set_name (filter, Suffix->data );
                  gtk_file_filter_add_pattern (filter, Suffix->data );
                  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (File_Selector), filter);
            }

            Suffix = g_list_next ( Suffix );
      }
      //current_archive_suffix = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
      if ( mode == "new" )
      {
            hbox = gtk_hbox_new (FALSE, 12);
            gtk_box_pack_start (GTK_BOX (hbox),gtk_label_new (_("Archive type:")),FALSE, FALSE, 0);
            combo_box = gtk_combo_box_new_text ();
            FilterToolTip = gtk_tooltips_new();
            gtk_tooltips_set_tip (FilterToolTip,combo_box, _("Choose the archive type to create") , NULL);
            Name = g_list_first ( ArchiveType );
            while ( Name != NULL )
            {
                  if (Name->data != ".tgz" && Name->data != ".rpm" && Name->data != ".iso" && Name->data != ".gz" && Name->data != ".bz2" )
                        gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), Name->data );
                  Name = g_list_next ( Name );
            }
            gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box) , current_archive_suffix );
            gtk_box_pack_start (GTK_BOX (hbox), combo_box, TRUE, TRUE, 0);
            check_button = gtk_check_button_new_with_label (_("Add the archive extension to the filename"));
            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check_button),TRUE);
            gtk_box_pack_start (GTK_BOX (hbox), check_button, TRUE, TRUE, 0);
            gtk_widget_show_all (hbox);
            gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (File_Selector), hbox);
            if (archive->tmp != NULL)
                  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (File_Selector),archive->tmp);
      }

      gtk_window_set_modal (GTK_WINDOW (File_Selector),TRUE);
      response = gtk_dialog_run (GTK_DIALOG (File_Selector));
      CurrentFolder = gtk_file_chooser_get_current_folder ( GTK_FILE_CHOOSER (File_Selector) );
      if (response == GTK_RESPONSE_ACCEPT)
      {
            path = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER (File_Selector) );
            if ( mode == "new")
            {
                  ComboArchiveType = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo_box));
                  current_archive_suffix = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
            if (strcmp ( ComboArchiveType,".arj") == 0) archive->type = XARCHIVETYPE_ARJ;
                else if (strcmp ( ComboArchiveType,".rar") == 0) archive->type = XARCHIVETYPE_RAR;
                else if (strcmp ( ComboArchiveType,".tar") == 0) archive->type = XARCHIVETYPE_TAR;
                else if (strcmp ( ComboArchiveType,".tar.bz2") == 0) archive->type = XARCHIVETYPE_TAR_BZ2;
                else if (strcmp ( ComboArchiveType,".tar.gz") == 0) archive->type = XARCHIVETYPE_TAR_GZ;
                else if (strcmp ( ComboArchiveType,".jar") == 0 || strcmp ( ComboArchiveType,".zip") == 0 ) archive->type = XARCHIVETYPE_ZIP;
                else if (strcmp ( ComboArchiveType,".rpm") == 0) archive->type = XARCHIVETYPE_RPM;
                else if (strcmp ( ComboArchiveType,".7z") == 0) archive->type = XARCHIVETYPE_7ZIP;
                  if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(check_button) ) )
                  {
                        if ( ! g_str_has_suffix ( path , ComboArchiveType ) )
                        {
                              dummy_path = g_strconcat ( path, ComboArchiveType , NULL);
                              g_free ( path );
                              path = dummy_path;
                        }
                  }
            }
            gtk_widget_destroy (File_Selector);
      }
      else if ( (response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT) )
      {
            gtk_widget_destroy (File_Selector);
            path = NULL;
      }
      return path;
}

gboolean isISO ( FILE *ptr )
{
      int offset_image;
      if ((offset_image = DetectImage(ptr)) > 0 )
      {
            fseek ( ptr , offset_image, SEEK_SET );
            fread ( &ipd, 1, sizeof(ipd), ptr );
            system_id = g_strndup ( ipd.system_id, 30);
            volume_id = g_strndup ( ipd.volume_id, 30);
            application_id = g_strndup ( ipd.application_id, 126);
            publisher_id = g_strndup ( ipd.publisher_id, 126);
            preparer_id = g_strndup ( ipd.preparer_id, 126);

            creation_date = g_strdup_printf ("%4.4s %2.2s %2.2s %2.2s:%2.2s:%2.2s.%2.2s",&ipd.creation_date[0],&ipd.creation_date[4],&ipd.creation_date[6],&ipd.creation_date[8],&ipd.creation_date[10],&ipd.creation_date[12],&ipd.creation_date[14]);
            
            modified_date = g_strdup_printf ("%4.4s %2.2s %2.2s %2.2s:%2.2s:%2.2s.%2.2s",&ipd.modification_date[0],&ipd.modification_date[4],&ipd.modification_date[6],&ipd.modification_date[8],&ipd.modification_date[10],&ipd.modification_date[12],&ipd.modification_date[14]);
            
            expiration_date = g_strdup_printf ("%4.4s %2.2s %2.2s %2.2s:%2.2s:%2.2s.%2.2s",&ipd.expiration_date[0],&ipd.expiration_date[4],&ipd.expiration_date[6],&ipd.expiration_date[8],&ipd.expiration_date[10],&ipd.expiration_date[12],&ipd.expiration_date[14]);
            
            effective_date = g_strdup_printf ("%4.4s %2.2s %2.2s %2.2s:%2.2s:%2.2s.%2.2s",&ipd.effective_date[0],&ipd.effective_date[4],&ipd.effective_date[6],&ipd.effective_date[8],&ipd.effective_date[10],&ipd.effective_date[12],&ipd.effective_date[14]);
        return TRUE;
      }
    else
            return FALSE;
}

gboolean isTar ( FILE *ptr )
{
      unsigned char magic[7];
      fseek ( ptr, 0 , SEEK_SET );
    if ( fseek ( ptr , 257 , SEEK_CUR) < 0 )
            return FALSE;
    if ( fread ( magic, 1, 7, ptr ) == 0 )
            return FALSE;
    if ( memcmp ( magic,"\x75\x73\x74\x61\x72\x00\x30",7 ) == 0 || memcmp (magic,"\x75\x73\x74\x61\x72\x20\x20",7 ) == 0)
            return TRUE;
    else
            return FALSE;
}

int DetectArchiveType ( gchar *filename )
{
      FILE *dummy_ptr = NULL;
    int xx = -1;
      unsigned char magic[12];
      dummy_ptr = fopen ( filename , "r" );
      
      if (dummy_ptr == NULL)
      {
            if ( !cli )
            {
                  gchar *utf8_path,*msg;
                  utf8_path = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
                  msg = g_strdup_printf (_("Can't open archive \"%s\":") , utf8_path );
                  response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow) , GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,
                  msg,g_strerror (errno));
                  g_free (msg);
                  g_free (utf8_path);
                  return -2;
            }
            else
                  return -2;
       }
      if ( fread ( magic, 1, 12, dummy_ptr ) == 0 )
      {
            fclose ( dummy_ptr);
            return -2;
      }

      if ( memcmp ( magic,"\x50\x4b\x03\x04",4 ) == 0 || memcmp ( magic,"\x50\x4b\x05\x06",4 ) == 0 )
    {
        if ( ! cli)
                  archive->has_passwd = DetectPasswordProtectedArchive ( XARCHIVETYPE_ZIP , dummy_ptr , magic );
        xx = XARCHIVETYPE_ZIP;
    }
      else if ( memcmp ( magic,"\x60\xea",2 ) == 0 )
    {
            if (! cli)
                  archive->has_passwd = DetectPasswordProtectedArchive ( XARCHIVETYPE_ARJ , dummy_ptr , magic );
        xx = XARCHIVETYPE_ARJ;
    }
      else if ( memcmp ( magic,"\x52\x61\x72\x21",4 ) == 0 ) xx = XARCHIVETYPE_RAR;
    else if ( memcmp ( magic,"\x42\x5a\x68",3 ) == 0 ) xx = XARCHIVETYPE_BZIP2;
      else if ( memcmp ( magic,"\x1f\x8b",2) == 0 || memcmp ( magic,"\x1f\x9d",2 ) == 0 )  xx = XARCHIVETYPE_GZIP;
    else if ( memcmp ( magic,"\xed\xab\xee\xdb",4 ) == 0) xx = XARCHIVETYPE_RPM;
    else if ( memcmp ( magic,"\x37\x7a\xbc\xaf\x27\x1c",6 ) == 0 ) xx = XARCHIVETYPE_7ZIP;
    else if ( isTar ( dummy_ptr ) ) xx = XARCHIVETYPE_TAR;
    else if ( isISO ( dummy_ptr ) ) xx = XARCHIVETYPE_ISO;
      else if ( memcmp (magic,"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00",12) == 0 ) xx = XARCHIVETYPE_BIN;
      fclose ( dummy_ptr );
      return xx;
}

gboolean DetectPasswordProtectedArchive ( int type , FILE *stream , unsigned char magic[6] )
{
    unsigned int fseek_offset;
    unsigned short int password_flag;
    unsigned int compressed_size;
    unsigned int uncompressed_size;
    unsigned short int file_length;
    unsigned short int extra_length;

      unsigned char sig[2];
      unsigned short int basic_header_size;
      unsigned short int extended_header_size;
      unsigned int basic_header_CRC;
      unsigned int extended_header_CRC;
      unsigned char arj_flag;

      fseek ( stream, 0 , SEEK_SET );
      fseek ( stream, 6 , SEEK_SET );
      if ( type == XARCHIVETYPE_ZIP )
      {
            while ( memcmp ( magic,"\x50\x4b\x03\x04",4 ) == 0  || memcmp ( magic,"\x50\x4b\x05\x06",4 ) == 0 )
            {
            fread ( &password_flag, 1, 2, stream );
            if (( password_flag & ( 1<<0) ) > 0)
                        return TRUE;
            fseek (stream,10,SEEK_CUR);
            fread (&compressed_size,1,4,stream);
            fread (&uncompressed_size,1,4,stream);
            fread (&file_length,1,2,stream);
            /* If the zip archive is empty (no files) it should return here */
            if (fread (&extra_length,1,2,stream) < 2 )
                        return FALSE;
            fseek_offset = compressed_size + file_length + extra_length;
            fseek (stream , fseek_offset , SEEK_CUR);
            fread (magic , 1 , 4 , stream);
            fseek ( stream , 2 , SEEK_CUR);
        }
    }
    else if ( type == XARCHIVETYPE_ARJ)
    {
        fseek (stream , magic[2]+magic[3] , SEEK_CUR);
        fseek (stream , 2 , SEEK_CUR);
        fread (&extended_header_size,1,2,stream);
        if (extended_header_size != 0) fread (&extended_header_CRC,1,4,stream);
        fread (&sig,1,2,stream);
        while ( memcmp (sig,"\x60\xea",2) == 0)
        {
            fread ( &basic_header_size , 1 , 2 , stream );
            if ( basic_header_size == 0 )
                        break;
            fseek ( stream , 4 , SEEK_CUR);
            fread (&arj_flag,1,1,stream);
            if ((arj_flag & ( 1<<0) ) > 0)
                        return TRUE;
            fseek ( stream , 7 , SEEK_CUR);
            fread (&compressed_size,1,4,stream);
            fseek ( stream , basic_header_size - 16 , SEEK_CUR);
            fread (&basic_header_CRC,1,4,stream);
            fread (&extended_header_size,1,2,stream);
            if (extended_header_size != 0) fread (&extended_header_CRC,1,4,stream);
            fseek ( stream , compressed_size , SEEK_CUR);
            fread (&sig,1,2,stream);
        }
    }
    return FALSE;
}

void RemoveColumnsListStore()
{
      gtk_window_set_title ( GTK_WINDOW (MainWindow) , "Xarchiver " VERSION );
      GList *columns = gtk_tree_view_get_columns ( GTK_TREE_VIEW (treeview1) );
      while (columns != NULL)
      {
            gtk_tree_view_remove_column (GTK_TREE_VIEW (treeview1) , columns->data);
            columns = columns->next;
      }
      g_list_free (columns);
}

void EmptyTextBuffer ()
{
      if (textbuf != NULL)
      {
            gtk_text_buffer_get_start_iter (textbuf,&start);
            gtk_text_buffer_get_end_iter (textbuf,&end);
            gtk_text_buffer_delete (textbuf,&start,&end);
            gtk_text_buffer_get_start_iter(textbuf, &enditer);
      }
}

void xa_create_liststore ( unsigned short int nc, gchar *columns_names[] , GType columns_types[])
{
      unsigned short int x;

      liststore = gtk_list_store_newv ( nc , (GType *)columns_types);
      gtk_tree_view_set_model ( GTK_TREE_VIEW (treeview1), GTK_TREE_MODEL (liststore) );
      gtk_tree_view_set_rules_hint ( GTK_TREE_VIEW (treeview1) , TRUE );
    gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (treeview1),(GtkTreeViewSearchEqualFunc) treeview_select_search, NULL, NULL);
      GtkTreeSelection *sel = gtk_tree_view_get_selection( GTK_TREE_VIEW (treeview1) );
      gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
      g_signal_connect ((gpointer) sel, "changed", G_CALLBACK (Activate_buttons), NULL);
    
      model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview1));
      g_object_ref(model);
      gtk_tree_view_set_model(GTK_TREE_VIEW(treeview1), NULL);

      for (x = 0; x <= nc-1; x++)
      {
            renderer = gtk_cell_renderer_text_new ();
            column = gtk_tree_view_column_new_with_attributes ( columns_names[x],renderer,"text",x,NULL);
            gtk_tree_view_column_set_resizable (column, TRUE);
            gtk_tree_view_column_set_sort_column_id (column, x);
            gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column);
      }
}

gboolean treeview_select_search (GtkTreeModel *model,gint column,const gchar *key,GtkTreeIter *iter,gpointer search_data)
{
    char *filename;
    gboolean result;

    gtk_tree_model_get (model, iter, 0, &filename, -1);
    if ( strcasestr (filename, key) ) result = FALSE;
        else result = TRUE;
    g_free (filename);
    return result;
}

void ShowShellOutput ( GtkMenuItem *menuitem )
{
      if (OutputWindow != NULL)
      {
            gtk_window_set_title (GTK_WINDOW (OutputWindow), _("Archiver Output Window") );
            gtk_window_present ( GTK_WINDOW (OutputWindow) );
            return;
      }
      OutputWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_position (GTK_WINDOW (OutputWindow), GTK_WIN_POS_CENTER);
      gtk_window_set_default_size(GTK_WINDOW(OutputWindow), 380, 250);
      gtk_window_set_destroy_with_parent (GTK_WINDOW (OutputWindow), TRUE);
      g_signal_connect (G_OBJECT (OutputWindow), "delete-event",  G_CALLBACK (gtk_widget_hide), &OutputWindow);

      vbox = gtk_vbox_new ( FALSE, 2 );
      scrollwin = gtk_scrolled_window_new ( NULL,NULL );
      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW( scrollwin ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

      textview = gtk_text_view_new();
      gtk_text_view_set_editable (GTK_TEXT_VIEW(textview), FALSE);
      gtk_container_add (GTK_CONTAINER(scrollwin), textview);
      gtk_box_pack_start (GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
      gtk_container_add (GTK_CONTAINER(OutputWindow), vbox);
      textbuf = gtk_text_view_get_buffer ( GTK_TEXT_VIEW(textview) );
      gtk_text_buffer_get_start_iter (textbuf, &enditer);
      //gtk_text_buffer_create_tag (textbuf, "red_foreground","foreground", "red", NULL);

      gtk_widget_show (vbox);
      gtk_widget_show (scrollwin);
      gtk_widget_show (textview);
}

void xa_cancel_archive ( GtkMenuItem *menuitem , gpointer data )
{
      if (archive->status == XA_ARCHIVESTATUS_ADD)
      {
            response = ShowGtkMessageDialog (GTK_WINDOW     (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("Doing so will probably corrupt your archive!"),_("Do you really want to cancel?") );
            if (response == GTK_RESPONSE_NO)
                  return;
      }
      gtk_widget_set_sensitive ( Stop_button , FALSE );
    Update_StatusBar (_("Waiting for the process to abort..."));
      stop_flag = TRUE;
      if (archive->type != XARCHIVETYPE_ISO)
      {
            if ( kill ( archive->child_pid , SIGABRT ) < 0 )
          {
                response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("An error occurred while trying to kill the process:"),g_strerror(errno));
                  return;
          }
      }
    /* This in case the user cancels the opening of a password protected archive */
    if (archive->status != XA_ARCHIVESTATUS_ADD || archive->status != XA_ARCHIVESTATUS_DELETE)
            if (archive->has_passwd)
                  archive->has_passwd = FALSE;
}

void xa_view_file_inside_archive ( GtkMenuItem *menuitem , gpointer user_data )
{
      GIOChannel *ioc_view = NULL;
      gchar *line = NULL;
      gchar *filename = NULL;
      GError *error = NULL;
      gchar *string = NULL;
      gchar *command = NULL;
      GtkTreeSelection *selection;
      GtkTreeModel *model;
      GtkTreeIter iter;
      gchar *dir;
      gchar *dummy_name;
      unsigned short int COL_NAME;
      gboolean is_dir = FALSE;
      gboolean tofree = FALSE;
      gboolean result = FALSE;
      GList *row_list = NULL;

      if ( archive->has_passwd )
      {
            if ( archive->passwd == NULL)
            {
                  archive->passwd = password_dialog ();
                  if ( archive->passwd == NULL)
                        return;
            }
      }
      selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview1) );

      /* if no or more than one rows selected, do nothing, just for sanity */
      if ( gtk_tree_selection_count_selected_rows (selection) != 1)
            return;

      row_list = gtk_tree_selection_get_selected_rows (selection, &model);
      if ( row_list == NULL )
            return;

      gtk_tree_model_get_iter(model, &iter, row_list->data);

      gtk_tree_path_free(row_list->data);
      g_list_free (row_list);

      switch (archive->type)
      {
            case XARCHIVETYPE_RAR:
            case XARCHIVETYPE_ARJ:
            COL_NAME = 6;
            break;

            case XARCHIVETYPE_ZIP:
            COL_NAME = 0;
            break;

            case XARCHIVETYPE_7ZIP:
            COL_NAME = 3;
            break;

            default:
            COL_NAME = 1;
      }
      gtk_tree_model_get (model, &iter, COL_NAME, &dir, -1);
      if (archive->type == XARCHIVETYPE_ZIP)
      {
            if ( g_str_has_suffix (dir,"/") == TRUE )
                  is_dir = TRUE;
      }
      else if ( strstr ( dir , "d" ) || strstr ( dir , "D" ) ) is_dir = TRUE;
      if (is_dir)
      {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,"Can't perform the action:",_("Please select a file, not a directory!") );
            g_free ( dir );
            return;
      }
      g_free ( dir );
      
      full_path = archive->full_path;
      overwrite = archive->overwrite;
            
      archive->full_path = 0;
      archive->overwrite = 1;

      names = g_string_new (" ");
      gtk_tree_model_get (model, &iter, 0, &dummy_name, -1);
      archive->status = XA_ARCHIVESTATUS_EXTRACT;
      ConcatenateFileNames2 ( dummy_name , names );
      
      if (archive->type == XARCHIVETYPE_ISO)
      {
            gtk_tree_model_get (model, &iter,
                  0, &dummy_name,
                  1, &permissions,
                  2, &file_size,
                  4, &file_offset,
                  -1);
            xa_extract_iso_file (archive, permissions, "/tmp/", dummy_name , file_size, file_offset );
            g_free (permissions);
      }
      else if (archive->type == XARCHIVETYPE_TAR || archive->type == XARCHIVETYPE_TAR_BZ2 || archive->type == XARCHIVETYPE_TAR_GZ)
      {
            gchar *option = NULL;
            gchar *digit;
            digit = g_strdup_printf ("%d", CountCharacter (names->str , '/') );
            if (archive->type == XARCHIVETYPE_TAR)
                  option = " -xvf ";
            else if (archive->type == XARCHIVETYPE_TAR_BZ2)
                  option = " -xvjf ";
            else if (archive->type == XARCHIVETYPE_TAR_GZ)
                  option = " -xvzf ";
            command = g_strconcat ("tar --strip-components=",digit,option,archive->escaped_path," -C /tmp",names->str,NULL);
            g_free (digit);
      }
      else
            command = xa_extract_single_files ( archive , names, "/tmp");

      g_string_free (names,TRUE);
      archive->full_path = full_path;
      archive->overwrite = overwrite;
      EmptyTextBuffer();
      if (command != NULL)
      {
            result = xa_run_command (command , 0);
            g_free (command);
            if ( result == 0 )
            {
                  unlink (dummy_name);
                  g_free (dummy_name);
                  return;
            }
      }

      string = StripPathFromFilename ( dummy_name, "/" );
      if (  string == NULL )
            filename = g_strconcat ( "/tmp/" , dummy_name, NULL );
      else
      {
            if ( strchr ( string , ' ' ) )
            {
                  string = RemoveBackSlashes ( string );
                  tofree = TRUE;
            }
            filename = g_strconcat ( "/tmp" , string , NULL );
            if ( tofree )
                  g_free ( string );
      }
      g_free (dummy_name);
      view_window = view_win();
      ioc_view = g_io_channel_new_file ( filename , "r" , &error );
      archive->status = XA_ARCHIVESTATUS_IDLE;
      if (error == NULL)
      {
            g_io_channel_set_encoding (ioc_view, locale , NULL);
            g_io_channel_set_flags ( ioc_view , G_IO_FLAG_NONBLOCK , NULL );
            g_io_channel_read_to_end ( ioc_view , &line , NULL, NULL );
            gtk_text_buffer_get_end_iter ( viewtextbuf, &viewenditer );
            if (line != NULL)
            {
                  gtk_text_buffer_insert (viewtextbuf, &viewenditer, line, strlen ( line ) );
                  g_free ( line );
            }
            g_io_channel_shutdown ( ioc_view , TRUE , NULL );
            g_io_channel_unref (ioc_view);
      }
      else
      {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,"An error occurred while extracting the file to be viewed:",error->message);
            g_error_free (error);
            unlink ( filename );
            Update_StatusBar ( _("Operation failed."));
            return;
      }
      unlink ( filename );
      gtk_widget_show (view_window);
      g_free (filename);
      OffTooltipPadlock();
      Update_StatusBar (_("Operation completed."));
}

void xa_iso_properties ( GtkMenuItem *menuitem , gpointer user_data )
{
      gchar *utf8_string, *text, *measure;
      unsigned long long int file_size;
      GtkWidget *iso_properties_win;

      stat ( archive->path , &my_stat );
      file_size = my_stat.st_size;
      iso_properties_win = create_iso_properties_window();
      //Name
      text = StripPathFromFilename ( archive->path, "/" );
      if (text != NULL)
      {
          text++; //This to avoid the / char in the string
          utf8_string = g_filename_display_name (text);
      }
      else
            utf8_string = g_filename_display_name (archive->path);
      gtk_entry_set_text ( GTK_ENTRY (filename_entry), utf8_string );
      g_free (utf8_string);
    //Size
      if (file_size > 1024*1024*1024 )
      {
            content_size = (double)file_size / (1024*1024*1024);
            measure = " GB";
      }
      else if (file_size > 1024*1024 )
      {
            content_size = (double)file_size / (1024*1024);
            measure = " MB";
      }

    else if (file_size > 1024 )
      {
            content_size = (double)file_size / 1024;
            measure = " KB";
      }
      else
      {
            measure = " Bytes";
            content_size = file_size;
      }

    text = g_strdup_printf ("%.1f %s", content_size,measure);
    gtk_entry_set_text ( GTK_ENTRY (size_entry), text );
    g_free (text);
      /* Image type */
      gtk_entry_set_text ( GTK_ENTRY (image_type_entry),archive->tmp);
      /* System ID */
      gtk_entry_set_text ( GTK_ENTRY (system_id_entry),system_id);
      /* Volume ID */
      gtk_entry_set_text ( GTK_ENTRY (volume_id_entry),volume_id);
      /* Application ID */
      gtk_entry_set_text ( GTK_ENTRY (application_entry),application_id);
      /* Publisher ID */
      gtk_entry_set_text ( GTK_ENTRY (publisher_entry),publisher_id);
      gtk_widget_show (iso_properties_win);
      /* Preparer ID */
      gtk_entry_set_text ( GTK_ENTRY (preparer_entry),preparer_id);
      gtk_widget_show (iso_properties_win);
      /* Creation Date */
      gtk_entry_set_text ( GTK_ENTRY (creation_date_entry),creation_date);
      /* Modified Date */
      gtk_entry_set_text ( GTK_ENTRY (modified_date_entry),modified_date);
      gtk_widget_show (iso_properties_win);
      /* Expiration Date */
      gtk_entry_set_text ( GTK_ENTRY (expiration_date_entry),expiration_date);
      /* Effective Date */
      gtk_entry_set_text ( GTK_ENTRY (effective_date_entry),effective_date);
      gtk_widget_show (iso_properties_win);
}

void xa_archive_properties ( GtkMenuItem *menuitem , gpointer user_data )
{
    gchar *utf8_string , *measure, *text, *dummy_string;
    char date[64];
    gchar *t;
    unsigned long long int file_size;

    stat ( archive->path , &my_stat );
    file_size = my_stat.st_size;
    archive_properties_win = create_archive_properties_window();
    //Name
    text = StripPathFromFilename ( archive->path, "/" );
    if (text != NULL)
    {
        text++; //This to avoid the / char in the string
        utf8_string = g_filename_display_name (text);
    }
    else
            utf8_string = g_filename_display_name (archive->path);
    gtk_entry_set_text ( GTK_ENTRY (name_data), utf8_string );
    g_free (utf8_string);
    //Path
    dummy_string = remove_level_from_path (archive->path);
    if ( strlen(dummy_string) != 0)
            utf8_string = g_filename_display_name (dummy_string);
    else
            utf8_string = g_filename_display_name ( g_get_current_dir () );
    gtk_entry_set_text ( GTK_ENTRY (path_data), utf8_string );
    g_free ( utf8_string );
    g_free ( dummy_string );
      //Type
      gtk_entry_set_text ( GTK_ENTRY (type_data), archive->format );
    //Modified Date
    strftime (date, 64, "%c", localtime (&my_stat.st_mtime) );
    t = g_locale_to_utf8 ( date, -1, 0, 0, 0);
    gtk_entry_set_text ( GTK_ENTRY (modified_data), t);
    g_free (t);
    //Archive Size
      if (file_size > 1024*1024*1024 )
      {
            content_size = (double)file_size / (1024*1024*1024);
            measure = " GB";
      }
      else if (file_size > 1024*1024 )
      {
            content_size = (double)file_size / (1024*1024);
            measure = " MB";
      }

    else if (file_size > 1024 )
      {
            content_size = (double)file_size / 1024;
            measure = " KB";
      }
      else
      {
            measure = " Bytes";
            content_size = file_size;
      }

    t = g_strdup_printf ("%.1f %s", content_size,measure);
    gtk_entry_set_text ( GTK_ENTRY (size_data), t );
    g_free (t);
    //content_size
    if (archive->dummy_size > 1024*1024*1024 )
    {
        content_size = (double)archive->dummy_size / (1024*1024*1024);
        measure = " GB";
    }
        else if (archive->dummy_size > 1024*1024 )
        {
            content_size = (double)archive->dummy_size / (1024*1024);
            measure = " MB";
        }

        else if (archive->dummy_size > 1024 )
        {
            content_size = (double)archive->dummy_size / 1024;
            measure = " KB";
        }
        else
        {
            measure = " Bytes";
            content_size = archive->dummy_size;
        }
    t = g_strdup_printf ( "%.1f %s", content_size,measure);
    gtk_entry_set_text ( GTK_ENTRY (content_data), t );
    g_free (t);
    //Compression_ratio
    if (content_size != 0)
            content_size = (double)archive->dummy_size / file_size;
    else
            content_size = 0.0;
    t = g_strdup_printf ( "%.2f", content_size);
    gtk_entry_set_text ( GTK_ENTRY (compression_data), t );
    g_free (t);
    //Number of files
    t = g_strdup_printf ( "%d", archive->nr_of_files);
    gtk_entry_set_text ( GTK_ENTRY (number_of_files_data), t );
    g_free (t);
    //Number of dirs
    t = g_strdup_printf ( "%d", archive->nr_of_dirs);
    gtk_entry_set_text ( GTK_ENTRY (number_of_dirs_data), t );
    g_free (t);
    gtk_widget_show ( archive_properties_win );
}

void Activate_buttons ()
{
      if ( ! GTK_WIDGET_VISIBLE (Extract_button) )
            return;
      
      GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview1) );
      gint selected = gtk_tree_selection_count_selected_rows ( selection );
      if (selected == 0 )
            OffDeleteandViewButtons();
      else
      {
            if ( archive->type != XARCHIVETYPE_RPM && archive->type != XARCHIVETYPE_ISO )
            {
                  gtk_widget_set_sensitive ( delete_menu , TRUE );
                  gtk_widget_set_sensitive ( Delete_button , TRUE );
            }
            if (selected > 1 )
            {
                  gtk_widget_set_sensitive ( View_button , FALSE);
                  gtk_widget_set_sensitive ( view_menu, FALSE );
            }
            else
            {
                  gtk_widget_set_sensitive ( View_button , TRUE );
                  gtk_widget_set_sensitive ( view_menu, TRUE );
            }
      }
}

void ConcatenateFileNames2 (gchar *filename , GString *data)
{
      gchar *esc_filename = NULL;
      gchar *escaped = NULL;
      gchar *escaped2 = NULL;
                  
      if ( strstr (filename, "[") || strstr (filename, "]"))
      {
            if (archive->type == XARCHIVETYPE_ZIP)
            {
                  if (archive->status == XA_ARCHIVESTATUS_ADD)
                        esc_filename = EscapeBadChars ( filename ,"$\'`\"\\!?* ()[]&|@#:;" );
                  else
                  {
                        escaped = EscapeBadChars ( filename ,"$\'`\"\\!?* ()[]&|@#:;");
                        escaped2 = escape_str_common (escaped , "*?[]", '\\', 0);
                        g_free (escaped);
                        esc_filename = escaped2;
                  }
            }
            else if ( archive->type == XARCHIVETYPE_TAR_BZ2 || archive->type == XARCHIVETYPE_TAR_GZ || archive->type == XARCHIVETYPE_TAR )
            {
                  if (archive->status == XA_ARCHIVESTATUS_ADD)
                        esc_filename = EscapeBadChars ( filename ,"$\'`\"\\!?* ()[]&|@#:;" );
                  else
                  {
                        escaped = EscapeBadChars ( filename ,"?*\\'& !|()@#:;");
                        escaped2 = escape_str_common ( escaped , "[]", '[', ']');
                        g_free (escaped);
                        esc_filename = escaped2;
                  }
            }
      }
      esc_filename = EscapeBadChars ( filename , "$\'`\"\\!?* ()[]&|@#:;" );
      
      g_string_prepend (data, esc_filename);
      g_string_prepend_c (data, ' ');
      g_free (esc_filename);
}

void ConcatenateFileNames (GtkTreeModel *model, GtkTreePath *treepath, GtkTreeIter *iter, GString *data)
{
      gchar *filename = NULL;
      
      gtk_tree_model_get (model, iter, 0, &filename, -1);
      ConcatenateFileNames2 ( filename , data );
      g_free (filename);
}

void xa_cat_filenames (GtkTreeModel *model, GtkTreePath *treepath, GtkTreeIter *iter, GString *data)
{
      gchar *fullname;
      gchar *name;

      gtk_tree_model_get (model, iter, 1, &fullname, -1);
      name = g_path_get_basename ( fullname );
      g_free (fullname);
      ConcatenateFileNames2 ( name , data );
      g_free (name);
}

gboolean xa_run_command ( gchar *command , gboolean watch_child_flag )
{
      int status;
      gboolean waiting = TRUE;
      int ps;
      
      if (watch_child_flag)
            EmptyTextBuffer ();
      archive->parse_output = 0;
      SpawnAsyncProcess ( archive , command , 0, 1);
      if ( archive->child_pid == 0 )
            return FALSE;

      gtk_widget_show (viewport2);
      while (waiting)
      {
            ps = waitpid ( archive->child_pid, &status, WNOHANG);
            if (ps < 0)
                  waiting = FALSE;
            else
                  while (gtk_events_pending())
                        gtk_main_iteration();
      }
      if (watch_child_flag)
      {
            xa_watch_child (archive->child_pid, status, archive);
            return TRUE;
      }
      else
      {
            if ( WIFEXITED (status) )
            {
                  if ( WEXITSTATUS (status) )
                  {
                        gtk_tooltips_disable ( pad_tooltip );
                        gtk_widget_hide ( pad_image );
                        gtk_widget_hide ( viewport2 );
                        gtk_window_set_title ( GTK_WINDOW (MainWindow) , "Xarchiver " VERSION );
                        response = ShowGtkMessageDialog (GTK_WINDOW     (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("An error occurred while accessing the archive."),_("Do you want to open the error messages window?") );
                        if (response == GTK_RESPONSE_YES)
                              ShowShellOutput (NULL);
                        archive->status = XA_ARCHIVESTATUS_IDLE;
                        gtk_widget_set_sensitive (Stop_button,FALSE);
                        Update_StatusBar ( _("Operation failed."));
                        return FALSE;
                  }
            }
      }
      return TRUE;
}

void Update_StatusBar ( gchar *msg)
{
    gtk_label_set_text (GTK_LABEL (info_label), msg);
}

gboolean xa_report_child_stderr (GIOChannel *ioc, GIOCondition cond, gpointer data)
{
      GIOStatus status;
      gchar     buffer[4096];
      gsize     bytes_read;

      if (cond & (G_IO_IN | G_IO_PRI))
      {
            do
          {
                  status = g_io_channel_read_chars (ioc, buffer, sizeof (buffer), &bytes_read, NULL);
                  if (bytes_read > 0)
                        gtk_text_buffer_insert (textbuf, &enditer, buffer, bytes_read);
          }
            while (status == G_IO_STATUS_NORMAL);
          if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
                  goto done;
      }
      else if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) )
      {
            done:
                  g_io_channel_shutdown (ioc, TRUE, NULL);
                  g_io_channel_unref (ioc);
                  return FALSE;
      }
      return TRUE;
}

void OffDeleteandViewButtons()
{
    gtk_widget_set_sensitive ( Delete_button, FALSE);
    gtk_widget_set_sensitive ( delete_menu, FALSE);
    gtk_widget_set_sensitive ( View_button, FALSE);
    gtk_widget_set_sensitive ( view_menu, FALSE);
}

void OffTooltipPadlock()
{
    gtk_widget_set_sensitive ( Stop_button , FALSE );
    gtk_widget_hide (viewport2);
    if ( archive->has_passwd == FALSE && archive->passwd == NULL)
    {
        gtk_tooltips_disable ( pad_tooltip );
        gtk_widget_hide ( pad_image );
    }
      else
    {
        gtk_widget_show ( pad_image );
        gtk_tooltips_enable ( pad_tooltip );
    }
}

void drag_begin (GtkWidget *treeview1,GdkDragContext *context, gpointer data)
{
    GtkTreeSelection *selection;
    GtkTreeIter       iter;
    gchar            *name;
    GList            *row_list;

      //gtk_drag_source_set_icon_name (treeview1, DATADIR "/pixmaps/xarchiver.png" );
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1));

      row_list = gtk_tree_selection_get_selected_rows (selection, NULL);
      if ( row_list == NULL )
            return;

      gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) (row_list->data) );
      gtk_tree_model_get (model, &iter, 0, &name, -1);
      gchar *no_slashes = StripPathFromFilename ( name, "/" );
      if (no_slashes != NULL)
            no_slashes++;
      gdk_property_change (context->source_window,
                           gdk_atom_intern ("XdndDirectSave0", FALSE),
                             gdk_atom_intern ("text/plain", FALSE), 8,
                               GDK_PROP_MODE_REPLACE,
                                 (const guchar *) no_slashes != NULL ? no_slashes : name, no_slashes != NULL ? strlen (no_slashes) : strlen (name) );

      g_list_foreach (row_list, (GFunc) gtk_tree_path_free, NULL);
      g_list_free (row_list);
      g_free (name);
}

void drag_end (GtkWidget *treeview1,GdkDragContext *context, gpointer data)
{
   /* Nothing to do */
}

void drag_data_get (GtkWidget *widget, GdkDragContext *dc, GtkSelectionData *selection_data, guint info, guint t, gpointer data)
{
      GtkTreeSelection *selection;
      GtkTreeIter iter;
      guchar *fm_path;
      int fm_path_len;
      gchar *command , *no_uri_path , *name;
      gchar *to_send = "E";
      GList *row_list, *_row_list;

      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1));
      row_list = _row_list = gtk_tree_selection_get_selected_rows (selection, NULL);
      if ( row_list == NULL)
            return;
      if ( archive->status == XA_ARCHIVESTATUS_EXTRACT )
      {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't perform another extraction:"),_("Please wait until the completion of the current one!") );
            return;
      }
      if ( gdk_property_get (dc->source_window,
                                          gdk_atom_intern ("XdndDirectSave0", FALSE),
                                          gdk_atom_intern ("text/plain", FALSE),
                                          0, 1024, FALSE, NULL, NULL, &fm_path_len, &fm_path)
                                          && fm_path != NULL)
      {
            /*  Zero-Terminate the string */
            fm_path = g_realloc (fm_path, fm_path_len + 1);
            fm_path[fm_path_len] = '\0';
            no_uri_path = g_filename_from_uri ( (gchar*)fm_path, NULL, NULL );
            /* g_message ("%s - %s",fm_path,no_uri_path); */
            g_free ( fm_path );
            if (no_uri_path == NULL)
            {
                  gtk_drag_finish (dc, FALSE, FALSE, t);
                  return;
            }

            gtk_tree_model_get_iter(model, &iter, (GtkTreePath*)(_row_list->data));
            gtk_tree_model_get (model, &iter, 0, &name, -1);

            archive->extraction_path = extract_local_path ( no_uri_path , name );
            g_free (name);
            g_free ( no_uri_path );
            if (archive->extraction_path != NULL)
                  to_send = "S";

            names = g_string_new ("");
            gtk_tree_selection_selected_foreach (selection, (GtkTreeSelectionForeachFunc) ConcatenateFileNames, names );
            full_path = archive->full_path;
            overwrite = archive->overwrite;
            archive->full_path = 0;
            archive->overwrite = 1;
            command = xa_extract_single_files ( archive , names, archive->extraction_path );
            g_string_free (names, TRUE);
            if ( command != NULL )
            {
                  archive->status = XA_ARCHIVESTATUS_EXTRACT;
                  xa_run_command ( command , 1);
                  g_free (command);
            }
            archive->full_path = full_path;
            archive->overwrite = overwrite;
            gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar*)to_send, 1);
      }

      if (archive->extraction_path != NULL)
      {
            g_free (archive->extraction_path);
            archive->extraction_path = NULL;
      }
      g_list_foreach (row_list, (GFunc) gtk_tree_path_free, NULL);
      g_list_free (row_list);
      archive->status = XA_ARCHIVESTATUS_IDLE;
}

void on_drag_data_received (GtkWidget *widget,GdkDragContext *context, int x,int y,GtkSelectionData *data, unsigned int info, unsigned int time, gpointer user_data)
{
      gchar **array = NULL;
      gchar *filename = NULL;
      gchar *command = NULL;
      gchar *name = NULL;
      gchar *_current_dir = NULL;
      gchar *current_dir = NULL;
      gboolean one_file;
      unsigned int len = 0;

      array = gtk_selection_data_get_uris ( data );
      if (array == NULL)
      {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,"",_("Sorry, I could not perform the operation!") );
            gtk_drag_finish (context, FALSE, FALSE, time);
            return;
      }
      gtk_drag_finish (context, TRUE, FALSE, time);
      one_file = (array[1] == NULL);

      if (one_file)
      {
            filename = g_filename_from_uri ( array[0] , NULL, NULL );
            if ( filename == NULL)
                  return;
            else if ( DetectArchiveType ( filename ) > 0 )
            {
                  xa_open_archive ( NULL, filename );
                  g_strfreev ( array );
                  return;
            }
    }

      if (archive == NULL)
      {
            xa_new_archive ( NULL , filename );
            if (archive->path == NULL)
                  return;
      }
      if ( (archive->type == XARCHIVETYPE_BZIP2 || archive->type == XARCHIVETYPE_GZIP) && ! one_file)
      {
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Bzip2 or gzip cannot compress more than one file!"),_("Please choose another archive format!") );
            gtk_window_set_title ( GTK_WINDOW (MainWindow) , "Xarchiver " VERSION );
            Update_StatusBar ( _("Operation failed."));
            return;
      }
      GString *names = g_string_new (" ");
      _current_dir = g_path_get_dirname ( array[0] );
      current_dir = g_filename_from_uri ( _current_dir, NULL, NULL );
      g_free (_current_dir);
      chdir ( current_dir );
      g_free (current_dir);
      archive->status = XA_ARCHIVESTATUS_ADD;

      while (array[len])
      {
            filename = g_filename_from_uri ( array[len] , NULL, NULL );
            name = g_path_get_basename ( filename );
            g_free (filename);
            ConcatenateFileNames2 ( name, names );
            g_free (name);
            len++;
      }
      
      full_path = archive->full_path;
      add_recurse = archive->add_recurse;
      archive->full_path = 0;
      archive->add_recurse = 1;
      command = xa_add_single_files ( archive, names, NULL );
      if (command != NULL)
      {
            xa_run_command (command , 1);
            g_free (command);
      }
      g_string_free (names, TRUE);
      g_strfreev ( array );
      archive->full_path = full_path;
      archive->add_recurse = add_recurse;
}

gboolean key_press_function (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
    if (event == NULL) return FALSE;
      switch (event->keyval)
    {
          case GDK_Escape:
          if ( GTK_WIDGET_VISIBLE (viewport2) )
                  xa_cancel_archive (NULL, NULL);
          break;

          case GDK_Delete:
        if ( GTK_WIDGET_STATE (Delete_button) != GTK_STATE_INSENSITIVE )
                  xa_delete_archive ( NULL , NULL );
            break;
    }
      return FALSE;
}

void xa_select_all ( GtkMenuItem *menuitem , gpointer user_data )
{

      gtk_tree_selection_select_all ( gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1) ) );
      gtk_widget_set_sensitive (select_all,FALSE);
      gtk_widget_set_sensitive (deselect_all,TRUE);
}

void xa_deselect_all ( GtkMenuItem *menuitem , gpointer user_data )
{
      gtk_tree_selection_unselect_all ( gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1) ) );
      gtk_widget_set_sensitive (select_all,TRUE);
      gtk_widget_set_sensitive (deselect_all,FALSE);
}

void xa_append_rows ( XArchive *archive , unsigned short int nc )
{
      unsigned short int i = 0;
      
      if (archive->row == NULL)
            return;
      archive->row = g_list_reverse ( archive->row );

      gtk_list_store_append (liststore, &iter);
      while ( archive->row )
      {
            if ( i == nc )
            {
                  gtk_list_store_append (liststore, &iter);
                  i = 0;
            }
            else
            {
                  gtk_list_store_set_value(liststore, &iter, i, archive->row->data);
                  archive->row = archive->row->next;
                  i++;
            }
      }
      while ( gtk_events_pending() )
            gtk_main_iteration();

      g_list_foreach(archive->row, (GFunc)g_value_unset, NULL);
      g_list_foreach(archive->row, (GFunc)g_free, NULL);
      g_list_free(archive->row);
      archive->row = NULL;
}

void xa_about_activate_link (GtkAboutDialog *about, const gchar *link, gpointer data)
{
      GdkScreen *screen;
      GtkWidget *message;
      GError *error = NULL;
      gchar *argv[3];
      gchar *exo_path;

      exo_path = g_find_program_in_path ("exo-open");
      if ( exo_path == NULL)
            argv[0] = "firefox";
      else
      {
            argv[0] = "exo-open";
            g_free (exo_path);
      }
      argv[1] = (gchar *) link;
      argv[2] = NULL;

      screen = gtk_widget_get_screen (GTK_WIDGET (about));

      if (!gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error))
      {
            message = gtk_message_dialog_new (GTK_WINDOW (about),
                                                            GTK_DIALOG_MODAL
                                                            | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                            GTK_MESSAGE_ERROR,
                                                            GTK_BUTTONS_CLOSE,
                                                            _("Failed to open link."));
            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.", error->message);
            gtk_dialog_run (GTK_DIALOG (message));
            gtk_widget_destroy (message);
            g_error_free (error);
      }
}



Generated by  Doxygen 1.6.0   Back to index