/* Bluefish HTML Editor
 * callbacks.c - contains all callbacks
 *
 * Copyright (C) 1998 Olivier Sessink and Chris Mazuc
 * 
 * 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 Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <unistd.h>
#include "bluefish.h"
#include "coloursel.h"
#include "callbacks.h"
#include "widgets.h"
#include "interface.h"
#include "config.h"
#include "network.h"
#include "init.h"

extern void add_to_statusbar (gchar *);
extern void create_buttons();
extern int closed;
extern int sockfd;

/* this struct is used for the project editor */
struct EditProject
  {
    GtkWidget *window;
    GtkWidget *base_entry;
    GtkWidget *web_entry;
  }
EditProject;

extern void create_dialog (int, int, gchar *);

void exit_modal_loop (GtkWidget * button, gpointer data);
void warn_close_dialog (gchar * filename);
void file_close_ok (GtkWidget * button, gpointer windowname);
void file_close_save (GtkWidget * button, gpointer windowname);
void file_close_save_as (void);
void file_close_save_ok (GtkWidget * w, GtkFileSelection * fs);
void file_open_ok (GtkWidget * w, GtkFileSelection * fs);
void file_insert_ok (GtkWidget * w, GtkFileSelection * fs);
void file_to_textbox (gchar * filename);
void file_save_as_ok (GtkWidget * w, GtkFileSelection * fs);
void textbox_to_file (gchar * filename);

/* project editor functions */
void project_edit_ok (GtkWidget * widget, struct EditProject *data);
void project_edit_cancel (GtkWidget * widget, struct EditProject *data);
void project_save_as_ok (GtkWidget * w, GtkFileSelection * fs);
void project_open_ok (GtkWidget * w, GtkFileSelection * fs);


/* ---------------------------------------------------
   * These functions are declared in callbacks.h --> all functions 
   * that use callbacks.h know them 
   * ------------------------------------------------------ */

void
file_save (GtkWidget * widget, gpointer data)
{
  /* This is the callback function for a save button */
#ifdef DEBUG
  g_print ("file_save, file save started\n");
#endif
  if (current_document->modified)
    {
      if (current_document->filename == NULL)
	{
#ifdef DEBUG
	  g_print ("file_save, No filename known --> save as..\n");
#endif
	  file_save_as (widget, data);
	}
      else
	{
#ifdef DEBUG
	  g_print ("file_save, Saving to %s\n", current_document->filename);
#endif
	  change_dir (current_document->filename);
	  textbox_to_file (current_document->filename);
	}
    }
}

void
file_save_as (GtkWidget * widget, gpointer data)
{
  GtkWidget *filew;
  gint sigid;

  /* This is the callback function for a save as button */
  filew = gtk_file_selection_new ("Save file as..");
  sigid = gtk_signal_connect (GTK_OBJECT (filew), "delete_event",
			      GTK_SIGNAL_FUNC (exit_modal_loop), NULL);

  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (file_save_as_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (exit_modal_loop), NULL);
  gtk_file_selection_set_filename (GTK_FILE_SELECTION (filew),
				   "index.html");
  gtk_widget_show (filew);
  /* this is needed, because this function can be used in file_save all(), 
     * and then all processes have to stop till this file is saved or cancelled */
#ifdef DEBUG
  g_print ("file_save_as, a new gtk_main_started\n");
#endif
  gtk_main ();
#ifdef DEBUG
  g_print ("file_save_as, the new gtk_main_stopped\n");
#endif
  gtk_signal_disconnect (GTK_OBJECT (filew), sigid);
  gtk_grab_remove (filew);
  gtk_object_destroy ((GtkObject *) filew);
}

void
file_open (GtkWidget * widget, gpointer data)
{
  GtkWidget *filew;

  /* This is the callback function for a file open button */
  filew = gtk_file_selection_new ("Open file");
  gtk_grab_add (filew);
  gtk_signal_connect (GTK_OBJECT (filew), "delete_event", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);
  gtk_signal_connect (GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);

  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (file_open_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (filew));

  gtk_file_selection_set_filename (GTK_FILE_SELECTION (filew),
				   "index.html");

  gtk_widget_show (filew);
}

void
file_insert (GtkWidget * widget, gpointer data)
{
  GtkWidget *filew;

  /* This is the callback function for a file open button */
  filew = gtk_file_selection_new ("Insert file");
  gtk_grab_add (filew);
  gtk_signal_connect (GTK_OBJECT (filew), "delete_event", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);
  gtk_signal_connect (GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);
  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (file_insert_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (filew));
  gtk_widget_show (filew);
}

void
file_new (GtkWidget * widget, gpointer data)
{

  /* This is the callback function for a file new button */
#ifdef DEBUG
  g_print ("file_new, started\n");
#endif
  current_document = new_document ();
  gtk_label_set (GTK_LABEL (current_document->tab_label), "Untitled");
#ifdef DEBUG
  g_print ("file_new, end\n");
#endif
}

void
file_close (GtkWidget * widget, gpointer data)
{
  /* This is the callback function for a file close button */
#ifdef DEBUG
  g_print ("file_close, begin\n");
#endif

  if (current_document != NULL)
    {
      if (!current_document->modified)
	{
#ifdef DEBUG
	  g_print ("file_close, destroy it\n");
#endif
	  if (!(current_document->filename == NULL &&
		current_document->modified ==
		FALSE && g_list_length (documentlist) == 2))
	    {
#ifdef DEBUG
	      g_print
		       ("file_close, not closing last unmodified, untitled document\n");
#endif
	      destroy_current_document ();
	    }
	}
      else
	{
#ifdef DEBUG
	  g_print ("file_close, warning dialog\n");
#endif
	  warn_close_dialog (current_document->filename);
	}
    }
  else
    {
#ifdef DEBUG
      g_print ("file_close, cannot close NULL document\n");
#endif
    }

  if (current_document == NULL)
    {
      file_new (NULL, NULL);
    }
}

void
file_close_all (GtkWidget * widget, gpointer data)
{

  gint count;

  count = g_list_length (documentlist) - 1;
  while (count > 0)
    {
      current_document = NULL;
      current_document = g_list_nth_data (documentlist, count);
      if (current_document != NULL)
	{
	  if (!current_document->modified)
	    {
#ifdef DEBUG
	      g_print ("file_close_all, destroy count=%d\n", count);
#endif
	      destroy_current_document ();
	    }
	  else
	    {
#ifdef DEBUG
	      g_print ("file_close_all, warning dialog for count=%d\n", count);
#endif
	      warn_close_dialog (current_document->filename);
	    }
	}
      else
	{
#ifdef DEBUG
	  g_print ("file_close_all, current_document==NULL, count=%d\n", count);
#endif
	}
      count--;
#ifdef DEBUG
      g_print ("file_close_all, count=%d\n", count);
#endif
    }
  if (data == NULL)
    {
      /* File close all, keep one document open */
      file_new (NULL, NULL);
    }
}


void
file_save_all (GtkWidget * widget, gpointer data)
{

  gint count;

  count = g_list_length (documentlist) - 1;
  while (count > 0)
    {
      current_document = NULL;
      current_document = g_list_nth_data (documentlist, count);
      if (current_document != NULL)
	{
	  if (current_document->modified)
	    {
	      if (current_document->filename == NULL)
		{
#ifdef DEBUG
		  g_print
		    ("file_save_all, No filename known --> save as..\n");
#endif
		  file_save_as (widget, data);
		}
	      else
		{
#ifdef DEBUG
		  g_print ("file_save_all, Saving to %s\n", current_document->filename);
#endif
		  textbox_to_file (current_document->filename);
		}
	    }
	}
      else
	{
#ifdef DEBUG
	  g_print ("file_save_all, current_document==NULL, count=%d\n", count);
#endif
	}
      count--;
    }
}

void
project_open (GtkWidget * widget, gpointer data)
{
  GtkWidget *filew;

  /* This is the callback function for a file open button */
  filew = gtk_file_selection_new ("Open project");
  gtk_grab_add (filew);
  gtk_signal_connect (GTK_OBJECT (filew), "delete_event", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);
  gtk_signal_connect (GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), &filew);
  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (project_open_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (filew));
  gtk_file_selection_set_filename (GTK_FILE_SELECTION (filew), current_project.filename);
  gtk_widget_show (filew);
}

void
project_save (GtkWidget * widget, gpointer data)
{

  if (current_project.filename == NULL)
    {
      project_save_as (NULL, NULL);
    }
  else
    {
      project_to_file ();
    }
}

void
project_save_as (GtkWidget * widget, gpointer data)
{
  GtkWidget *filew;


  /* This is the callback function for a save as button */
  filew = gtk_file_selection_new ("Save file as..");
  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (project_save_as_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (filew));
  gtk_file_selection_set_filename (GTK_FILE_SELECTION (filew), current_project.filename);
  gtk_widget_show (filew);
}

/***************************************************** 
 *
 *           project edit functions
 *
 *****************************************************/

void
project_edit (GtkWidget * widget, gpointer data)
{
  GtkWidget *vbox, *hbox, *vbox2, *frame, *ok_b, *cancel_b;
  gint count;
  struct EditProject *editproject;
  struct thefilestruct *tmp;

  editproject = g_malloc (sizeof (EditProject));
  editproject->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/*   gtk_widget_set_usize (editproject->window, 350, 300);
  gtk_window_set_policy( GTK_WINDOW(editproject->window), TRUE, TRUE, TRUE ); */
  gtk_container_border_width (GTK_CONTAINER (editproject->window), 10);
  gtk_window_set_title (GTK_WINDOW (editproject->window), current_project.filename);
  gtk_signal_connect (GTK_OBJECT (editproject->window), "destroy",
		      GTK_SIGNAL_FUNC (project_edit_cancel), editproject);
  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (editproject->window), vbox);
  gtk_widget_show (vbox);
  label = gtk_label_new ("Basedir");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);
  editproject->base_entry = gtk_entry_new_with_max_length (1023);
  gtk_box_pack_start (GTK_BOX (vbox), editproject->base_entry, FALSE, FALSE, 0);
  gtk_entry_set_text (GTK_ENTRY (editproject->base_entry), current_project.basedir);
  gtk_widget_show (editproject->base_entry);
  label = gtk_label_new ("Webdir");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);
  editproject->web_entry = gtk_entry_new_with_max_length (1023);
  gtk_box_pack_start (GTK_BOX (vbox), editproject->web_entry, FALSE, FALSE, 0);
  gtk_entry_set_text (GTK_ENTRY (editproject->web_entry), current_project.webdir);
  gtk_widget_show (editproject->web_entry);

  /* print the filenames */
  frame = gtk_frame_new ("Files");
  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
/*   gtk_container_border_width (GTK_CONTAINER (frame), 10); */
  gtk_widget_show (frame);
  vbox2 = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (frame), vbox2);
  gtk_widget_show (vbox2);
  for (count = g_list_length (documentlist) - 1; count > 0; count--)
    {
#ifdef DEBUG
      g_print ("project_edit, count =%d\n", count);
#endif
      tmp = g_list_nth_data (documentlist, count);
      if (tmp->filename != NULL)
	{
	  label = gtk_label_new (tmp->filename);
	  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	  gtk_widget_show (label);
	}
    }

  hbox = gtk_hbox_new (TRUE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  ok_b = gtk_button_new_with_label ("Ok");
  cancel_b = gtk_button_new_with_label ("Cancel");
  GTK_WIDGET_SET_FLAGS (ok_b, GTK_CAN_DEFAULT);
  GTK_WIDGET_SET_FLAGS (cancel_b, GTK_CAN_DEFAULT);
  gtk_window_set_default(GTK_WINDOW(editproject->window), ok_b);
  gtk_box_pack_start (GTK_BOX (hbox), ok_b, TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (hbox), cancel_b, TRUE, TRUE, 0);
  gtk_signal_connect (GTK_OBJECT (cancel_b), "clicked",
		      GTK_SIGNAL_FUNC (project_edit_cancel), editproject);
  gtk_signal_connect (GTK_OBJECT (ok_b), "clicked",
		      GTK_SIGNAL_FUNC (project_edit_ok), editproject);
  gtk_widget_show (ok_b);
  gtk_widget_show (cancel_b);

  gtk_widget_show (editproject->window);
}

void
project_edit_ok (GtkWidget * widget, struct EditProject *data)
{

  strncpy (current_project.basedir, gtk_entry_get_text (GTK_ENTRY
	   (data->base_entry)), 1023);
  strncpy (current_project.webdir, gtk_entry_get_text (GTK_ENTRY
	   (data->web_entry)), 1023);
#ifdef DEBUG
  g_print ("project_edit_ok, current_project.basedir(%p)=%s\n",
	   current_project.basedir, current_project.basedir);
  g_print ("project_edit_ok, current_project.webdir(%p)=%s\n",
	   current_project.webdir, current_project.webdir);
#endif
  project_edit_cancel (widget, data);
}

void
project_edit_cancel (GtkWidget * widget, struct EditProject *data)
{
#ifdef DEBUG
  g_print ("project_edit_cancel, started\n");
#endif
  gtk_signal_handlers_destroy (GTK_OBJECT (data->window));
  gtk_widget_destroy (data->window);
  g_free (data);
#ifdef DEBUG
  g_print ("project_edit_cancel, finished\n");
#endif
}

/*******************************************
 *    
 *        other project functions
 *
 ********************************************/

void
project_from_file (void)
{
  FILE *fd;
  gchar *errmessage, tmpbuf[1024];
  gint count;

  if (current_project.filename == NULL)
    {
#ifdef DEBUG
      g_print ("project_from_file, no filename known\n");
#endif
    }
  else
    {
      fd = fopen (current_project.filename, "r");
      if (fd == NULL)
	{
#ifdef DEBUG
	  g_print ("project_from_file, cannot open file %s\n", current_project.filename);
#endif
	  errmessage = g_malloc (1024);
	  strncat (strcpy (errmessage, "Could not open file:\n"),
		   current_project.filename, 1023);
	  error_dialog (((strlen (current_project.filename) * 5) + 120),
			100, "Error", errmessage);
	  g_free (errmessage);
	  return;
	}
      else
	{
	  current_project.basedir = g_malloc (1024);
	  fgets (current_project.basedir, 1023, fd);
	  for (count = 0; count <= strlen (current_project.basedir);
	    count++)
	    {
	      /* replace the \n with a string end */
	      if (current_project.basedir[count] == '\n')
		current_project.basedir[count] = '\0';
	    }

#ifdef DEBUG
	  g_print ("project_from_file, basedir (%p)=%s\n",
		   current_project.basedir, current_project.basedir);
#endif
	  current_project.webdir = g_malloc (1024);
	  fgets (current_project.webdir, 1023, fd);
	  for (count = 0; count <= strlen (current_project.webdir); count++)
	    {
	      /* replace the \n with a string end */
	      if (current_project.webdir[count] == '\n')
		{
		  current_project.webdir[count] = '\0';
#ifdef DEBUG
		  g_print ("project_from_file, placed \\0 on count=%d\n", count);
#endif
		}
	    }
#ifdef DEBUG
	  g_print ("project_from_file, webdir(%p)=%s\n",
		   current_project.webdir, current_project.webdir);
#endif
	  while (fgets (tmpbuf, 1023, fd) != NULL)
	    {
	      for (count = 0; count <= strlen (tmpbuf); count++)
		{
		  if (tmpbuf[count] == '\n')
		    {
		      tmpbuf[count] = '\0';
#ifdef DEBUG
		      g_print
			       ("project_from_file, placed \\0 on count=%d\n", count);
#endif
		    }
		}
	      if (file_exists_and_readable (tmpbuf))
		{
#ifdef DEBUG
		  g_print
		    ("project_from_file, opening file=%s (it's readable)\n", tmpbuf);
#endif

		  current_document = new_document ();
		  gtk_label_set (GTK_LABEL (current_document->tab_label),
				 strip_filename (tmpbuf));
		  current_document->filename = g_malloc (strlen (tmpbuf)
							 + 2);
		  strncpy (current_document->filename, tmpbuf,
			   strlen (tmpbuf) + 1);
#ifdef DEBUG
		  g_print
		    ("project_from_file, current_document->filename=%s \n", current_document->filename);
#endif
		  file_to_textbox (tmpbuf);
		}
	      else
		{
#ifdef DEBUG
		  g_print ("project_from_file, file `%s` does not exist\n", tmpbuf);
#endif
		}
	    }
	  fclose (fd);
	}
    }
}
void
project_to_file (void)
{
  gchar *errmessage;
  gint count;
  FILE *fd;

  if (current_project.filename == NULL)
    {
#ifdef DEBUG
      g_print ("project_to_file, no filename known\n");
#endif
    }
  else
    {
      fd = fopen (current_project.filename, "w");
      if (fd == NULL)
	{
#ifdef DEBUG
	  g_print ("project_to_file, cannot open file %s\n", current_project.filename);
#endif
	  errmessage = g_malloc (1024);
	  strncat (strcpy (errmessage, "Could not open file:\n"),
		   current_project.filename, 1023);
	  error_dialog (((strlen (current_project.filename) * 5) + 120),
			100, "Error", errmessage);
	  g_free (errmessage);
	  return;
	}
      else
	{
#ifdef DEBUG
	  g_print ("project_to_file, file should be opened succesful\n");
	  g_print ("project_to_file, fd=%p\n", fd);
	  g_print ("project_to_file, current_project.filename=%s\n", current_project.filename);
#endif
	  if (current_project.basedir == NULL)
	    {
#ifdef DEBUG
	      g_print ("project_to_file, unknown basedir\n");
#endif
	    }
	  else
	    {
	      fputs (current_project.basedir, fd);
	    }
	  fputc (10, fd);
	  if (current_project.webdir == NULL)
	    {
#ifdef DEBUG
	      g_print ("project_to_file, unknown webdir\n");
#endif
	    }
	  else
	    {
	      fputs (current_project.webdir, fd);
	    }
	  fputc (10, fd);
#ifdef DEBUG
	  g_print ("project_to_file, saved both base- and webdir\n");
#endif
	  count = g_list_length (documentlist) - 1;
	  while (count > 0)
	    {
	      current_document = NULL;
	      current_document = g_list_nth_data (documentlist, count);
	      if (current_document != NULL)
		{
		  if (current_document->filename != NULL)
		    {
		      fputs (current_document->filename, fd);
		      fputc (10, fd);
		    }
		}
	      else
		{
#ifdef DEBUG
		  g_print
		    ("project_to_file, current_document==NULL, count=%d\n", count);
#endif
		}
	      count--;
	    }
	  fclose (fd);
	}
    }
}

void
view_in_netscape (GtkWidget * widget, gpointer data)
{
  gchar command[COMMAND_MAX];
  gint rcode;
  gchar *browser, *url, *url2;

  if (strlen (current_project.basedir) > 1 && strlen
      (current_project.webdir) > 1)
    {
      /* convert the local filename to an URL (in the project)
         so it works with dynamic content */
      url = strip_common_path (current_document->filename, current_project.basedir);
#ifdef DEBUG
      g_print ("view_in_netscape, url=%s\n", url);
#endif
      url2 = g_malloc (strlen (url) + strlen (current_project.webdir) + 1);
      strcpy (url2, current_project.webdir);
      strcat (url2, url);
    }
  else
    {
      url2 = g_malloc (strlen (current_document->filename) + 1);
      strcpy (url2, current_document->filename);
    }
#ifdef DEBUG
  g_print ("view_in_netscape, url2=%s\n", url2);
#endif
  if (cfg_browser_cline == 0)
    {
      browser = DEFAULT_BROWSER;
    }
  else
    {
      browser = cfg_browser_cline;
    }

  snprintf (command, COMMAND_MAX, browser, url2);
  rcode = system (command);
#ifdef DEBUG
  g_print ("view_in_netscape, rcode = %d\n", rcode);
#endif
  if (rcode == 0)
    {
      return;
      /*everything was ok */
    }
  else
    {
      snprintf (command, COMMAND_MAX, "netscape %s &",
		url2);
      system (command);
    }
  g_free (url2);
}


/* ---------------------------------------------------------------
 * the functions below are only declared in this file, so they are NOT known if you use callbacks.h 
 * ---------------------------------------------------------------- */

/* close a dialog box wich has it's own gtk_main() */
void
exit_modal_loop (GtkWidget * button, gpointer data)
{
  gtk_main_quit ();
}

void
error_dialog (gint xsize, gint ysize, gchar * window_title, gchar * error_string)
{

  dialog = gtk_dialog_new ();
  gtk_window_set_title (GTK_WINDOW (dialog), window_title);
  gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
  gtk_widget_set_usize (dialog, xsize, ysize);

  okbutton = gtk_button_new_with_label ("OK");
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
		      okbutton, TRUE, TRUE, 0);
  GTK_WIDGET_SET_FLAGS (okbutton, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (okbutton);
  gtk_signal_connect_object (GTK_OBJECT (okbutton), "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (dialog));
  gtk_widget_show (okbutton);

  label = gtk_label_new (error_string);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, TRUE,
		      TRUE, 0);
  gtk_widget_show (label);
  gtk_widget_show (dialog);
}

void
open_from_web ()
{
  create_dialog (450, 80, "Open from Web");
  dialogtable = gtk_table_new (1, 10, 0);
  gtk_container_border_width (GTK_CONTAINER (vbox), 0);
  gtk_box_pack_start (GTK_BOX (vbox), dialogtable, FALSE, FALSE, 0);
  gtk_widget_show (dialogtable);

  label = gtk_label_new ("URL:");
  combo1 = GTK_COMBO (gtk_combo_new ());
  gtk_combo_set_popdown_strings (combo1, urllist);
  gtk_table_attach_defaults (GTK_TABLE (dialogtable), label, 0, 1, 0, 1);
  gtk_table_attach_defaults (GTK_TABLE (dialogtable), GTK_WIDGET (combo1),
			     1, 10,
			     0, 1);
  gtk_widget_show (label);
  gtk_widget_show (GTK_WIDGET (combo1));

  create_buttons ();
  gtk_signal_connect (GTK_OBJECT (okbutton), "clicked", GTK_SIGNAL_FUNC
		      (open_from_web_callback), NULL);
}

void
open_from_web_callback ()
{
  gint return_code;
  gint signal_code;
  gchar *url_string;

  url_string = g_malloc0 (256);

  add_to_list (urllist, gtk_entry_get_text (GTK_ENTRY (combo1->entry)));
  sprintf (url_string, "%s", gtk_entry_get_text (GTK_ENTRY (combo1->entry)));
  gtk_widget_destroy (dialog);

  /* Bind escape key to cancel d/l */

  signal_code = gtk_signal_connect (GTK_OBJECT (main_window),
				    "key_press_event",
				    GTK_SIGNAL_FUNC (key_press_callback), NULL);

  return_code = open_web (url_string);
  switch (return_code)
    {
    case 0:
      break;
    case 1:
      error_dialog (240, 160, "Error",
		    "That looks like a secure server,\nBluefish doesn't support them");
      break;
    case 2:
      error_dialog (240, 160, "Error", "Invalid address");
      break;
    case 3:
      error_dialog (240, 160, "Error", "Host name lookup failure");
      break;
    case 4:
      error_dialog (240, 160, "Error", "Couldn't create socket");
      break;
    case 5:
      error_dialog (240, 160, "Error", "The network is unreachable");
      break;
    case 6:
      error_dialog (240, 160, "Error", "Can't send data");
      break;
    case 7:
      error_dialog (240, 160, "Error", "Didn't send all the data");
      break;
    case 8:
      error_dialog (240, 160, "Error", "Can't open file");
      break;
    case 9:
/* The used cancelled the d/l, do nothing */
      break;
    default:
      error_dialog (240, 160, "Error", "Unknown error");
      break;
    }

  add_to_statusbar ("");
  g_free (url_string);
#ifdef DEBUG
  g_print ("open_from_web_callback, disconnecting key_press_callback()\n");
#endif
  gtk_signal_disconnect (GTK_OBJECT (main_window), signal_code);
}

void
key_press_callback (GtkWidget * widget, GdkEventKey * event, gpointer data)
{
#ifdef DEBUG
  g_print ("key_press_callback, Value is .%d.\n", event->keyval);
#endif
  /* Escape? */
  if (event->keyval == 65307)
    {
      closed = 1;
      close (sockfd);
      gtk_text_thaw ((GtkText *) current_document->textbox);
#ifdef DEBUG
      g_print ("key_press_callback, socket closed and document thawed\n");
#endif
    }
}


/* warn if you really want to close a changed file */
void
warn_close_dialog (gchar * filename)
{
  GtkWidget *dialog, *label1, *button_ok, *button_cancel, *button_save;
  gint sigid;

  dialog = gtk_dialog_new ();
  gtk_window_set_title (GTK_WINDOW (dialog), "Confirmation");
  gtk_container_border_width (GTK_CONTAINER (dialog), 10);
  gtk_grab_add (dialog);
  sigid = gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
			      GTK_SIGNAL_FUNC (exit_modal_loop),
			      NULL);
  gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
  button_ok = gtk_button_new_with_label ("Close");
  button_save = gtk_button_new_with_label ("Save & close");
  button_cancel = gtk_button_new_with_label ("Cancel");
  GTK_WIDGET_SET_FLAGS (button_ok, GTK_CAN_DEFAULT);
  GTK_WIDGET_SET_FLAGS (button_save, GTK_CAN_DEFAULT);
  GTK_WIDGET_SET_FLAGS (button_cancel, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button_save,
		      TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button_ok,
		      TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button_cancel,
		      TRUE, TRUE, 0);
  gtk_widget_show (button_ok);
  gtk_widget_show (button_save);
  gtk_widget_show (button_cancel);
  gtk_signal_connect_object (GTK_OBJECT (button_cancel), "clicked",
			     GTK_SIGNAL_FUNC (exit_modal_loop),
			     (gpointer) dialog);
  gtk_signal_connect_object (GTK_OBJECT (button_save), "clicked",
			     GTK_SIGNAL_FUNC (file_close_save),
			     (gpointer) dialog);
  gtk_signal_connect_object (GTK_OBJECT (button_ok), "clicked",
			     GTK_SIGNAL_FUNC (file_close_ok),
			     (gpointer) dialog);
  if (filename != NULL) {
     label1 = gtk_label_new(filename);
     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label1, TRUE,
		      TRUE, 0);
     gtk_widget_show (label1);
  }
  label1 = gtk_label_new
    ("This file is modified, are you sure you want to close it?");
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label1, TRUE,
		      TRUE, 0);
  gtk_widget_show (label1);
  gtk_widget_show (dialog);
  gtk_window_set_default(GTK_WINDOW(dialog), button_save);
  /* we want to wait until the button is chosen and all stuff is done */
#ifdef DEBUG
  g_print ("warn_close_dialog, a new gtk_main_started\n");
#endif
  gtk_main ();
#ifdef DEBUG
  g_print ("warn_close_dialog, the new gtk_main_stopped\n");
#endif
  gtk_signal_disconnect (GTK_OBJECT (dialog), sigid);
  gtk_grab_remove (dialog);
  gtk_object_destroy ((GtkObject *) dialog);
}

/* close the file even if it's modified */
void
file_close_ok (GtkWidget * button, gpointer windowname)
{
#ifdef DEBUG
  g_print ("file_close_ok, begin\n");
#endif
  destroy_current_document ();
  exit_modal_loop (button, windowname);
#ifdef DEBUG
  g_print ("file_close_ok, end\n");
#endif
}

/* close the file even if it's modified, but save it first */
void
file_close_save (GtkWidget * button, gpointer windowname)
{

  if (current_document->filename == NULL)
    {
#ifdef DEBUG
      g_print ("file_close_save, No filename known --> save as..\n");
#endif
      file_close_save_as ();
    }
  else
    {
#ifdef DEBUG
      g_print ("file_close_save, Saving to %s\n", current_document->filename);
#endif
      change_dir (current_document->filename);
      textbox_to_file (current_document->filename);
      destroy_current_document ();
    }
  exit_modal_loop (button, windowname);
}

void
file_close_save_as (void)
{
  GtkWidget *filew;

  /* This is the callback function for a save as button */
  filew = gtk_file_selection_new ("Save file as..");
  gtk_grab_add (filew);
  gtk_signal_connect (GTK_OBJECT (filew), "delete_event", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), filew);
  gtk_signal_connect (GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC
		      (gtk_widget_destroy), filew);
  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
		      "clicked", GTK_SIGNAL_FUNC (file_close_save_ok), filew);
  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION
					 (filew)->cancel_button),
			     "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (filew));
  gtk_file_selection_set_filename (GTK_FILE_SELECTION (filew),
				   "index.html");
  gtk_widget_show (filew);
}

/* File can be saved and closed now */
void
file_close_save_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is a callback for file_selection for saving */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
#ifdef DEBUG
  g_print ("file_close_save_ok, save to: %s\n", filename);
#endif
  g_free (current_document->filename);
  current_document->filename = g_malloc (strlen (filename) + 2);
  strncpy (current_document->filename, filename, strlen (filename) + 1);
#ifdef DEBUG
  g_print ("file_close_save_ok,current_document->filename=%s\n", current_document->filename);
#endif
  file_close_save (w, fs);
}

void
file_open_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is the callback function for a file_selection for file_open */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
#ifdef DEBUG
  g_print ("file_open_ok, open from: %s\n", filename);
#endif

  if (!(current_document->filename == NULL &&
	current_document->modified ==
	FALSE && g_list_length (documentlist) == 2))
    {
      current_document = new_document ();
    }
  gtk_label_set (GTK_LABEL (current_document->tab_label), strip_filename (filename));
  current_document->filename = g_malloc (strlen (filename) + 2);
  strncpy (current_document->filename, filename, strlen (filename) + 1);
#ifdef DEBUG
  g_print ("file_open_ok, current_document->filename=%s\n", current_document->filename);
#endif
  change_dir (current_document->filename);
  file_to_textbox (filename);
  gtk_grab_remove (GTK_WIDGET (fs));
  gtk_widget_destroy (GTK_WIDGET (fs));
  flush_queue ();
}

void
file_insert_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is the callback function for a file_selection for file_open */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
#ifdef DEBUG
  g_print ("file_insert_ok, open from: %s\n", filename);
#endif
  file_to_textbox (filename);
  gtk_grab_remove (GTK_WIDGET (fs));
  gtk_widget_destroy (GTK_WIDGET (fs));
}

void
file_to_textbox (gchar * filename)
{
  FILE *fd;
  gchar *errmessage, line[512];

/*      guint point; */

  /* This opens the contents of a file to a textbox */
  change_dir (filename);
  fd = fopen (filename, "r");
  if (fd == NULL)
    {
#ifdef DEBUG
      g_print ("file_to_textbox, cannot open file %s\n", filename);
#endif
      errmessage = g_malloc (1024);
      strncat (strcpy (errmessage, "Could not open file:\n"), filename, 1023);
      error_dialog (((strlen (filename) * 5) + 120), 100, "Error", errmessage);		/* 7 */
      g_free (errmessage);
      return;
    }
  else
    {

/*      point =gtk_text_get_point((GtkText *)current_document->textbox);
 *    gtk_text_set_point((GtkText *)current_document->textbox, point); */

      gtk_text_freeze ((GtkText *) current_document->textbox);
      while (fgets (line, 512, fd) != NULL)
	{
	  gtk_text_insert ((GtkText *) current_document->textbox, NULL, NULL,
			   NULL, line, -1);
	}
      gtk_text_thaw ((GtkText *) current_document->textbox);
      fclose (fd);
      current_document->modified = FALSE;
    }
}

void
file_save_as_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is a callback for file_selection for saving */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
#ifdef DEBUG
  g_print ("file_save_as_ok, save to: %s\n", filename);
#endif
  g_free (current_document->filename);
  current_document->filename = g_malloc (strlen (filename) + 2);
  strncpy (current_document->filename, filename, strlen (filename) + 1);
#ifdef DEBUG
  g_print ("file_save_as_ok, current_document->filename=%s\n", current_document->filename);
#endif
  gtk_label_set (GTK_LABEL (current_document->tab_label), strip_filename (filename));
  textbox_to_file (filename);
  exit_modal_loop (NULL, NULL);
}

void
textbox_to_file (gchar * filename)
{
  FILE *fd;
  gchar *tmpchar, *errmessage;

  /* This writes the contents of a textbox to a file */
  change_dir (filename);
  fd = fopen (filename, "w");
  if (fd == NULL)
    {
#ifdef DEBUG
      g_print ("textbox_to_file, cannot open file %s\n", filename);
#endif
      errmessage = g_malloc (1024);
      strncat (strcpy (errmessage, "Could not open file:\n"), filename, 1023);
      error_dialog (((strlen (filename) * 5) + 120), 100, "Error", errmessage);
      g_free (errmessage);
      return;
    }
  else
    {
#ifdef DEBUG
      g_print ("textbox_to_file, lenght=%d\n",
	       gtk_text_get_length (GTK_TEXT (current_document->textbox)));
      g_print ("textbox_to_file, fd=%p\n", fd);
      g_print ("textbox_to_file, filename=%s\n", filename);
#endif
      tmpchar = gtk_editable_get_chars (GTK_EDITABLE (current_document->textbox),
					0, gtk_text_get_length (GTK_TEXT (current_document->textbox)));
      fputs (tmpchar, fd);
      g_free (tmpchar);
      fclose (fd);
      current_document->modified = 0;
#ifdef DEBUG
      g_print ("textbox_to file, text saved to: %s\n", filename);
#endif
/*      strncat(stuff, "Done", 1023);
   gtk_statusbar_push(GTK_STATUSBAR(statusbar), 1, stuff); */
    }
}



void
project_save_as_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is a callback for file_selection for saving */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
  strncpy (current_project.filename, filename, 1023);
  project_to_file ();
  gtk_grab_remove (GTK_WIDGET (fs));
  gtk_widget_destroy (GTK_WIDGET (fs));
}

void
project_open_ok (GtkWidget * w, GtkFileSelection * fs)
{
  gchar filename[255];

  /* This is the callback function for a file_selection for file_open */
  strncpy (filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION
						      (fs)), 255);
  g_free (current_project.filename);
  current_project.filename = g_malloc (strlen (filename) + 2);
  strncpy (current_project.filename, filename, strlen (filename) + 1);
  project_from_file ();
  gtk_grab_remove (GTK_WIDGET (fs));
  gtk_widget_destroy (GTK_WIDGET (fs));

}


void
re_check (GtkWidget * widget, GtkWidget * window)
{
  gtk_widget_destroy (window);
  run_weblint (NULL, NULL);
}

static void
scrollbar_update (GtkText * txt, gint tl, gint ln)
{
  gfloat value;

  if (tl < 3 || ln > tl)
    return;

  value = (ln * GTK_ADJUSTMENT (txt->vadj)->upper) /
    tl - GTK_ADJUSTMENT (txt->vadj)->page_increment;

  gtk_adjustment_set_value (GTK_ADJUSTMENT (txt->vadj), value);
}

static void
go_to_line (gint linenum)
{

/* Thanks to Andy Kahn for the amazing non-leaking go to line function
   It dances, it does tricks, AND you have memory left after... :) */

  gchar *buf, *haystack, *needle;
  gint numlines;
  gint a, b, len;

  numlines = 1;

  len = gtk_text_get_length (GTK_TEXT (current_document->textbox));
  buf = gtk_editable_get_chars (GTK_EDITABLE (current_document->textbox),
				1, len);

/*  If index is past the end, or 0 (Usually because line number is -) */

  if ((linenum > (len - 1)) || (linenum == 0))
    return;

  a = 1;
  b = len;
  haystack = buf;
  do
    {
      needle = strchr (haystack, '\n');
      if (needle)
	{
	  haystack = needle + 1;
	  if (linenum == numlines)
	    b = needle - buf + 1;
	  numlines++;
	  if (linenum == numlines)
	    a = needle - buf + 1;
	}
    }
  while (needle != NULL);

  g_free (buf);
  gtk_editable_select_region (GTK_EDITABLE (current_document->textbox),
			      a, b);
  scrollbar_update (GTK_TEXT (current_document->textbox), numlines, linenum);
  gtk_editable_insert_text (GTK_EDITABLE ((GtkText *)
					  current_document->textbox),
			    " ", 1, &b);
  gtk_editable_delete_text (GTK_EDITABLE ((GtkText *)
					  current_document->textbox), b -
			    1, b);
}


void
selection_made (GtkWidget * clist, gint row, gint column,
		GdkEventButton * event, gpointer data)
{

/*  Every time a list item is selected or unselected this checks
   if it was also a double or triple click, if so goToLine is called */

  gchar *text;
  gchar *bracket_ptr;
  gint line_number;
  gtk_clist_get_text (GTK_CLIST (clist), row, column, &text);

  if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
    {

/*  Find first bracket, increment, atoi rest of string, atoi will
   stop at second bracket (we hope) */

      bracket_ptr = strchr (text, '(');
      bracket_ptr++;

/* Mark that in the record books, Neil uses a pointer increment! */

      line_number = atoi (bracket_ptr);
      go_to_line (line_number);
    }
}

void
run_weblint (GtkWidget * widget, gpointer data)
{

  gint rcode, row, unlink_code;
  GtkWidget *ext_window, *list, *close_button, *recheck_button;
  GtkWidget *scrolwin;
  gchar temp[1024], line[1024], html_file[1024], output_file[1024];
  gchar text[1][50];
  gchar *texts[1];
  gchar *command;
  FILE *fd;

  sprintf (output_file, "%s", "weblint.out");

/* Current HTML file saved to filename 'untitled' */

  sprintf (html_file, "%s", "untitled");

  add_to_statusbar ("Running Weblint");

/* Main Window */

  ext_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (ext_window), "destroy",
		      NULL, &ext_window);
  gtk_signal_connect (GTK_OBJECT (ext_window), "delete_event",
		      NULL, &ext_window);
  gtk_window_set_title (GTK_WINDOW (ext_window), "Weblint output");
  gtk_container_border_width (GTK_CONTAINER (ext_window), 10);
  gtk_window_set_policy( GTK_WINDOW(ext_window), TRUE, TRUE, FALSE );
  gtk_widget_set_usize (ext_window, 550, 350);

  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (ext_window), vbox);
  
  /* since GTK 1.2 one should use a scrolledwindow for a clist */
  scrolwin = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolwin),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (vbox), scrolwin, TRUE, TRUE, 0);
  gtk_widget_show (scrolwin);
  list = gtk_clist_new (1);
  gtk_clist_set_shadow_type (GTK_CLIST (list), GTK_SHADOW_OUT);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolwin), list);
  gtk_widget_show (list);
  gtk_widget_show (vbox);
  flush_queue ();

  gtk_signal_connect (GTK_OBJECT (list), "select_row",
		      GTK_SIGNAL_FUNC (selection_made), NULL);

  gtk_signal_connect (GTK_OBJECT (list), "unselect_row", GTK_SIGNAL_FUNC
		      (selection_made), NULL);

/*      Button box */

  hbox = gtk_hbox_new (TRUE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  recheck_button = gtk_button_new_with_label ("Recheck");
  gtk_box_pack_start (GTK_BOX (hbox), recheck_button, TRUE, TRUE, 0);
  gtk_widget_show (recheck_button);

  gtk_signal_connect (GTK_OBJECT (recheck_button), "clicked",
		      GTK_SIGNAL_FUNC (re_check), GTK_OBJECT (ext_window));

  close_button = gtk_button_new_with_label ("Close");
  gtk_box_pack_start (GTK_BOX (hbox), close_button, TRUE, TRUE, 0);

/*  GTK_WIDGET_SET_FLAGS (close_button, GTK_CAN_DEFAULT);
   gtk_widget_grab_default (close_button); */

  gtk_widget_show (close_button);

  gtk_signal_connect_object (GTK_OBJECT (close_button), "clicked",
			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
			     GTK_OBJECT (ext_window));

  if (cfg_weblint_cline == NULL)
    {
      command = DEFAULT_WEBLINT;
    }
  else
    {
      command = cfg_weblint_cline;
    }

  /* Exec Weblint */

  textbox_to_file (html_file);
  sprintf (temp, "%s %s > %s 2>/dev/null", command, html_file, output_file);
  flush_queue ();

  rcode = system (temp);
  flush_queue ();

/* if return code == 0 then no errors, confirm with dialog */

  if (rcode == 0)
    {
      gtk_widget_destroy (ext_window);
      error_dialog (240, 160, "Weblint", "No errors in this document");
      unlink_code = unlink ("weblint.out");
      if (unlink_code == -1)
	{
#ifdef DEBUG
	  printf ("Cannot delete file weblint.out\n");
#endif
	}
      unlink_code = unlink (html_file);
      if (unlink_code == -1)
	{
#ifdef DEBUG
	  printf ("Cannot delete file %s\n", html_file);
#endif
	}
    }
  else if (rcode == 32512 || rcode == 32256)
    {

/*  return code == 32512, seems to be 'no weblint.' Tell user to
   install brainModule */
      gtk_widget_destroy (ext_window);
      error_dialog (380, 140, "Weblint",
		    "You don't appear to have weblint installed \nTo use this option you will need to download weblint from:\nhttp://www.cre.canon.co.uk/~neilb/weblint/");

    }
  else
    {
      fd = fopen (output_file, "r");
      if (fd != NULL)
	{

	  texts[0] = text[0];
	  gtk_clist_freeze (GTK_CLIST (list));

	  while (fgets (line, 512, fd) != NULL)
	    {
	      line[(strlen (line) - 1)] = '\0';
	      sprintf (text[0], "%s", line);
	      row = gtk_clist_append (GTK_CLIST (list), texts);
	    }
	  fclose (fd);
	  unlink_code = unlink ("weblint.out");
	  if (unlink_code == -1)
	    {
#ifdef DEBUG
	      printf ("Cannot delete file weblint.out\n");
#endif
	    }
	  unlink_code = unlink (html_file);
	  if (unlink_code == -1)
	    {
#ifdef DEBUG
	      printf ("Cannot delete file %s\n", html_file);
#endif
	    }
	  gtk_clist_thaw (GTK_CLIST (list));
	  flush_queue ();

	}
      gtk_widget_show (ext_window);
    }

  add_to_statusbar ("");
}
