Example #1
0
static void motFileDlgCallback(Widget w, Ihandle* ih, XmFileSelectionBoxCallbackStruct* call_data)
{
  (void)w;
  if (call_data->reason == XmCR_OK)
  {
    int dialogtype = iupAttribGetInt(ih, "_IUPDLG_DIALOGTYPE");
    char* filename;
    XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename);
    iupAttribStoreStr(ih, "VALUE", filename);
    XtFree(filename);

    if (!motFileDlgCheckValue(ih, w))
      return;

    if (dialogtype == IUP_DIALOGDIR)
    {
      iupAttribSetStr(ih, "STATUS", "0");
      iupAttribSetStr(ih, "FILEEXIST", NULL);
    }
    else
    {
      IFnss file_cb = (IFnss)IupGetCallback(ih, "FILE_CB");
      if (file_cb && file_cb(ih, iupAttribGet(ih, "VALUE"), "OK") == IUP_IGNORE)
        return;

      if (iupdrvIsFile(iupAttribGet(ih, "VALUE")))  /* check if file exists */
      {
        iupAttribSetStr(ih, "FILEEXIST", "YES");
        iupAttribSetStr(ih, "STATUS", "0");
      }
      else
      {
        iupAttribSetStr(ih, "FILEEXIST", "NO");
        iupAttribSetStr(ih, "STATUS", "1");
      }
    }

    if (!iupAttribGetInt(ih, "NOCHANGEDIR"))  /* do change the current directory */
    {
      /* XmFileSelection does not change the current directory */
      XmString xm_dir;
      char* dir;
      XtVaGetValues(w, XmNdirectory, &xm_dir, NULL);
      XmStringGetLtoR(xm_dir, XmSTRING_DEFAULT_CHARSET, &dir);
      iupdrvSetCurrentDirectory(dir);
      XtFree(dir);
    }
  }
  else if (call_data->reason == XmCR_CANCEL)
  {
    iupAttribSetStr(ih, "VALUE", NULL);
    iupAttribSetStr(ih, "FILEEXIST", NULL);
    iupAttribSetStr(ih, "STATUS", "-1");
  }
}
int probe_main (probe_ctx *ctx, void *mutex)
{
        SEXP_t *path, *filename, *behaviors;
        SEXP_t *filepath, *attribute_, *probe_in;
	int err;
        struct cbargs cbargs;
	OVAL_FTS    *ofts;
	OVAL_FTSENT *ofts_ent;

        if (mutex == NULL)
                return PROBE_EINIT;

        _A(mutex == &__file_probe_mutex);

        probe_in  = probe_ctx_getobject(ctx);

        path       = probe_obj_getent (probe_in, "path",      1);
        filename   = probe_obj_getent (probe_in, "filename",  1);
        behaviors  = probe_obj_getent (probe_in, "behaviors", 1);
        filepath   = probe_obj_getent (probe_in, "filepath", 1);
        attribute_ = probe_obj_getent (probe_in, "attribute_name", 1);

	/* we want either path+filename or filepath */
        if (((path == NULL || filename == NULL) && filepath == NULL)
            || attribute_ == NULL)
        {
                SEXP_free (behaviors);
                SEXP_free (path);
                SEXP_free (filename);
                SEXP_free (filepath);
                SEXP_free (attribute_);

                return PROBE_ENOELM;
        }

	probe_filebehaviors_canonicalize(&behaviors);

        switch (pthread_mutex_lock (&__file_probe_mutex)) {
        case 0:
                break;
        default:
                dI("Can't lock mutex(%p): %u, %s.", &__file_probe_mutex, errno, strerror (errno));

		SEXP_free(path);
		SEXP_free(filename);
		SEXP_free(filepath);
		SEXP_free(behaviors);
                SEXP_free(attribute_);

                return PROBE_EFATAL;
        }

        cbargs.ctx      = ctx;
	cbargs.error    = 0;
        cbargs.attr_ent = attribute_;

	if ((ofts = oval_fts_open(path, filename, filepath, behaviors)) != NULL) {
		while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
			file_cb(ofts_ent->path, ofts_ent->file, &cbargs);
			oval_ftsent_free(ofts_ent);
		}
		oval_fts_close(ofts);
	}

	err = 0;

	SEXP_free(path);
	SEXP_free(filename);
	SEXP_free(filepath);
	SEXP_free(behaviors);
        SEXP_free(attribute_);

        switch (pthread_mutex_unlock (&__file_probe_mutex)) {
        case 0:
                break;
        default:
                dI("Can't unlock mutex(%p): %u, %s.", &__file_probe_mutex, errno, strerror (errno));

                return PROBE_EFATAL;
        }

        return err;
}
Example #3
0
static int motFileDlgPopup(Ihandle* ih, int x, int y)
{
  InativeHandle* parent = iupDialogGetNativeParent(ih);
  Widget filebox, dialog;
  int dialogtype, style = XmDIALOG_FULL_APPLICATION_MODAL;
  IFnss file_cb = NULL;
  Widget preview_canvas = NULL;
  char* value;

  iupAttribSetInt(ih, "_IUPDLG_X", x);   /* used in iupDialogUpdatePosition */
  iupAttribSetInt(ih, "_IUPDLG_Y", y);

  value = iupAttribGetStr(ih, "DIALOGTYPE");
  if (iupStrEqualNoCase(value, "SAVE"))
    dialogtype = IUP_DIALOGSAVE;
  else if (iupStrEqualNoCase(value, "DIR"))
    dialogtype = IUP_DIALOGDIR;
  else
    dialogtype = IUP_DIALOGOPEN;
  iupAttribSetInt(ih, "_IUPDLG_DIALOGTYPE", dialogtype);

  if (parent)
  {
    filebox = XmCreateFileSelectionDialog(parent, "filedialog", NULL, 0);
    dialog = XtParent(filebox);
  }
  else
  {
    dialog = XtAppCreateShell(NULL, "filedialog", topLevelShellWidgetClass, iupmot_display, NULL, 0);
    filebox = XmCreateFileSelectionBox(dialog, "filebox", NULL, 0);
    style = XmDIALOG_MODELESS;
    XtVaSetValues(dialog,
      XmNmwmInputMode, MWM_INPUT_FULL_APPLICATION_MODAL,
      XmNmappedWhenManaged, False,
      XmNsaveUnder, True,
      NULL);
  }
  if (!filebox)
    return IUP_NOERROR;

  if (!iupAttribGetBoolean(ih, "SHOWHIDDEN"))
    XtVaSetValues(filebox, XmNfileFilterStyle, XmFILTER_HIDDEN_FILES, NULL);

  value = iupAttribGet(ih, "TITLE");
  if (!value)
  {
    if (dialogtype == IUP_DIALOGSAVE)
      value = "IUP_SAVEAS";
    else if (dialogtype == IUP_DIALOGOPEN)
      value = "IUP_OPEN";
    else
      value = "IUP_SELECTDIR";
    iupAttribSetStr(ih, "TITLE", iupStrMessageGet(value));
  }
  iupmotSetString(filebox, XmNdialogTitle, value);

  XtVaSetValues(filebox,
                XmNdialogStyle, style,
                XmNautoUnmanage, False,
                XmNresizePolicy, XmRESIZE_GROW,
                NULL);

  if (dialogtype == IUP_DIALOGDIR)
    XtVaSetValues(filebox, XmNfileTypeMask, XmFILE_DIRECTORY, NULL);

  /* just check for the path inside FILE */
  value = iupAttribGet(ih, "FILE");
  if (value && value[0] == '/')
  {
    char* dir = iupStrFileGetPath(value);
    iupAttribStoreStr(ih, "DIRECTORY", dir);
    free(dir);
  }

  /* set XmNdirectory before XmNpattern and before XmNdirSpec */

  value = iupAttribGet(ih, "DIRECTORY");
  if (value)
    iupmotSetString(filebox, XmNdirectory, value);

  value = iupAttribGet(ih, "FILTER");
  if (value)
  {
    char *filter = value;
    char *p = strchr(value, ';');
    if (p) 
    {
      /* Use only the first filter */
      int size = p-value;
      filter = (char*)malloc(size+1);
      memcpy(filter, value, size);
      filter[size] = 0;
    }

    iupmotSetString(filebox, XmNpattern, filter);

    if (filter != value) 
      free(filter);
  }

  value = iupAttribGet(ih, "FILE");
  if (value)
  {
    char* file = value;

    if (value[0] != '/')  /* if does not contains a full path, then add the directory */
    {
      char* cur_dir = NULL;
      char* dir = iupAttribGet(ih, "DIRECTORY");
      if (!dir)
      {
        cur_dir = iupdrvGetCurrentDirectory();
        dir = cur_dir;
      }

      file = iupStrFileMakeFileName(dir, value);

      if (cur_dir)
        free(cur_dir);
    }

  /* clear value before setting. Do not know why we have to do this, 
     but if not cleared it will fail to set the XmNdirSpec value. */
    iupmotSetString(filebox, XmNdirSpec, "");
    iupmotSetString(filebox, XmNdirSpec, file);

    if (file != value)
      free(file);
  }

  if (!IupGetCallback(ih, "HELP_CB"))
    XtUnmanageChild(XmFileSelectionBoxGetChild(filebox, XmDIALOG_HELP_BUTTON));

  XtAddCallback(filebox, XmNokCallback, (XtCallbackProc)motFileDlgCallback, (XtPointer)ih);
  XtAddCallback(filebox, XmNcancelCallback, (XtCallbackProc)motFileDlgCallback, (XtPointer)ih);
  XtAddCallback(filebox, XmNhelpCallback, (XtCallbackProc)motFileDlgHelpCallback, (XtPointer)ih);

  if (dialogtype == IUP_DIALOGDIR)
  {
    Widget new_folder = XtVaCreateManagedWidget("new_folder", xmPushButtonWidgetClass, filebox, 
                                                XmNlabelType, XmSTRING, 
                                                NULL);
    iupmotSetString(new_folder, XmNlabelString, iupStrMessageGet("IUP_CREATEFOLDER"));
    XtAddCallback(new_folder, XmNactivateCallback, (XtCallbackProc)motFileDlgNewFolderCallback, (XtPointer)filebox);
  }
  else
  {
    file_cb = (IFnss)IupGetCallback(ih, "FILE_CB");
    if (file_cb)
    {
      Widget list = XmFileSelectionBoxGetChild(filebox, XmDIALOG_LIST);
      XtAddCallback(list, XmNbrowseSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih);
      list = XmFileSelectionBoxGetChild(filebox, XmDIALOG_DIR_LIST);
      XtAddCallback(list, XmNbrowseSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih);

      if (iupAttribGetBoolean(ih, "SHOWPREVIEW"))
      {
        Widget frame = XtVaCreateManagedWidget("preview_canvas", xmFrameWidgetClass, filebox, 
                                                        XmNshadowType, XmSHADOW_ETCHED_IN,
                                                        NULL);

        preview_canvas = XtVaCreateManagedWidget("preview_canvas", xmDrawingAreaWidgetClass, frame, 
                                                        XmNwidth, 180, 
                                                        XmNheight, 150,
                                                        XmNresizePolicy, XmRESIZE_GROW,
                                                        NULL);

        XtAddCallback(preview_canvas, XmNexposeCallback, (XtCallbackProc)motFileDlgPreviewCanvasExposeCallback, (XtPointer)ih);
        XtAddCallback(preview_canvas, XmNresizeCallback, (XtCallbackProc)motFileDlgPreviewCanvasResizeCallback,  (XtPointer)ih);

        iupAttribSetStr(ih, "_IUPDLG_FILEBOX", (char*)filebox);
      }
    }

    if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
    {
      Widget wList = XmFileSelectionBoxGetChild(filebox, XmDIALOG_LIST);
      XtVaSetValues(wList, XmNselectionPolicy, XmEXTENDED_SELECT, NULL);

      if (file_cb)
        XtAddCallback(wList, XmNextendedSelectionCallback, (XtCallbackProc)motFileDlgBrowseSelectionCallback, (XtPointer)ih);
    }
  }

  XmAddWMProtocolCallback(dialog, iupmot_wm_deletewindow, motFileDlgCBclose, (XtPointer)ih);
  XtManageChild(filebox);

  XtRealizeWidget(dialog);
  ih->handle = dialog;
  iupDialogUpdatePosition(ih);
  ih->handle = NULL;  /* reset handle */

  if (file_cb)
  {
    if (preview_canvas)
      motFileDlgPreviewCanvasInit(ih, preview_canvas);

    file_cb(ih, NULL, "INIT");
  }

  if (ih->userwidth && ih->userheight)
  {
    XtVaSetValues(dialog,
      XmNwidth, (XtArgVal)(ih->userwidth),
      XmNheight, (XtArgVal)(ih->userheight),
      NULL);
  }

  if (style == XmDIALOG_MODELESS)
    XtPopup(dialog, XtGrabExclusive);

  /* while the user hasn't provided an answer, simulate main loop.
  ** The answer changes as soon as the user selects one of the
  ** buttons and the callback routine changes its value. */
  iupAttribSetStr(ih, "STATUS", NULL);
  while (iupAttribGet(ih, "STATUS") == NULL)
    XtAppProcessEvent(iupmot_appcontext, XtIMAll);

  if (file_cb)
  {
    if (preview_canvas)
      XFreeGC(iupmot_display, (GC)iupAttribGet(ih, "PREVIEWDC"));

    file_cb(ih, NULL, "FINISH");
  }

  if (!iupAttribGet(ih, "_IUP_WM_DELETE"))
  {
    XtUnmanageChild(filebox);

    if (style == XmDIALOG_MODELESS)
    {
      XtPopdown(dialog);
      XtDestroyWidget(dialog);
    }
  }

  return IUP_NOERROR;
}
Example #4
0
static void motFileDlgCallback(Widget w, Ihandle* ih, XmFileSelectionBoxCallbackStruct* call_data)
{
  (void)w;
  if (call_data->reason == XmCR_OK)
  {
    int dialogtype = iupAttribGetInt(ih, "_IUPDLG_DIALOGTYPE");
    char* filename;
    XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename);
    iupAttribStoreStr(ih, "VALUE", filename);
    XtFree(filename);

    if (!motFileDlgCheckValue(ih, w))
      return;

    if (dialogtype == IUP_DIALOGDIR)
    {
      iupAttribSetStr(ih, "STATUS", "0");
      iupAttribSetStr(ih, "FILEEXIST", NULL);
    }
    else if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
    {
      Widget wList = XmFileSelectionBoxGetChild(w, XmDIALOG_LIST);

      /* VALUE obtained above contains exactly the DIRECTORY */
      char* dir = iupAttribGet(ih, "VALUE");
      int len = strlen(dir);
      if (dir[len-1]=='/') dir[len-1] = 0;  /* remove last '/' */
      iupAttribStoreStr(ih, "DIRECTORY", dir);

      if (!motFileDlgGetMultipleFiles(ih, iupAttribGet(ih, "DIRECTORY"), wList))
      {
        iupStrMessageShowError(ih, "IUP_FILENOTEXIST");
        return;
      }

      iupAttribSetStr(ih, "STATUS", "0");
      iupAttribSetStr(ih, "FILEEXIST", "YES");
    }
    else
    {
      IFnss file_cb = (IFnss)IupGetCallback(ih, "FILE_CB");
      filename = iupAttribGet(ih, "VALUE");
      if (file_cb && file_cb(ih, filename, "OK") == IUP_IGNORE)
        return;

      if (iupdrvIsFile(filename))  /* check if file exists */
      {
        char* dir = iupStrFileGetPath(filename);
        iupAttribStoreStr(ih, "DIRECTORY", dir);
        free(dir);

        iupAttribSetStr(ih, "FILEEXIST", "YES");
        iupAttribSetStr(ih, "STATUS", "0");
      }
      else
      {
        iupAttribSetStr(ih, "FILEEXIST", "NO");
        iupAttribSetStr(ih, "STATUS", "1");
      }
    }

    if (!iupAttribGetBoolean(ih, "NOCHANGEDIR"))  /* do change the current directory */
    {
      /* XmFileSelection does not change the current directory */
      XmString xm_dir;
      char* dir;
      XtVaGetValues(w, XmNdirectory, &xm_dir, NULL);
      XmStringGetLtoR(xm_dir, XmSTRING_DEFAULT_CHARSET, &dir);
      iupdrvSetCurrentDirectory(dir);
      XtFree(dir);
    }
  }
  else if (call_data->reason == XmCR_CANCEL)
  {
    iupAttribSetStr(ih, "VALUE", NULL);
    iupAttribSetStr(ih, "FILEEXIST", NULL);
    iupAttribSetStr(ih, "STATUS", "-1");
  }
}
Example #5
0
static int gtkFileDlgPopup(Ihandle* ih, int x, int y)
{
  InativeHandle* parent = iupDialogGetNativeParent(ih);
  GtkWidget* dialog;
  GtkWidget* preview_canvas = NULL;
  GtkFileChooserAction action;
  IFnss file_cb;
  char* value;
  int response, filter_count = 0;

  iupAttribSetInt(ih, "_IUPDLG_X", x);   /* used in iupDialogUpdatePosition */
  iupAttribSetInt(ih, "_IUPDLG_Y", y);

  value = iupAttribGetStr(ih, "DIALOGTYPE");
  if (iupStrEqualNoCase(value, "SAVE"))
    action = GTK_FILE_CHOOSER_ACTION_SAVE;
  else if (iupStrEqualNoCase(value, "DIR"))
    action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
  else
    action = GTK_FILE_CHOOSER_ACTION_OPEN;

  value = iupAttribGet(ih, "TITLE");
  if (!value)
  {
    GtkStockItem item;

    if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
      value = GTK_STOCK_SAVE_AS;
    else
      value = GTK_STOCK_OPEN;

    gtk_stock_lookup(value, &item);
    value = item.label;

    iupAttribStoreStr(ih, "TITLE", iupgtkStrConvertFromUTF8(value));
    value = iupAttribGet(ih, "TITLE");
    iupStrRemoveChar(value, '_');
  }

  dialog = gtk_file_chooser_dialog_new(iupgtkStrConvertToUTF8(value), (GtkWindow*)parent, action, 
                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 
                                       NULL);
  if (!dialog)
    return IUP_ERROR;

  if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
    gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, GTK_RESPONSE_OK);
  else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
    gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OPEN, GTK_RESPONSE_OK);
  else
    gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);

  if (IupGetCallback(ih, "HELP_CB"))
    gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP);

#if GTK_CHECK_VERSION(2, 6, 0)
  if (iupAttribGetBoolean(ih, "SHOWHIDDEN"))
    gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), TRUE);
#endif

  if (iupAttribGetBoolean(ih, "MULTIPLEFILES") && action == GTK_FILE_CHOOSER_ACTION_OPEN)
    gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);

#if GTK_CHECK_VERSION(2, 8, 0)
  if (!iupAttribGetBoolean(ih, "NOOVERWRITEPROMPT") && action == GTK_FILE_CHOOSER_ACTION_SAVE)
    gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
#endif

  /* just check for the path inside FILE */
  value = iupAttribGet(ih, "FILE");
  if (value && (value[0] == '/' || value[1] == ':'))
  {
    char* dir = iupStrFileGetPath(value);
    int len = strlen(dir);
    iupAttribStoreStr(ih, "DIRECTORY", dir);
    free(dir);
    iupAttribStoreStr(ih, "FILE", value+len);
  }

  value = iupAttribGet(ih, "DIRECTORY");
  if (value)
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), iupgtkStrConvertToFilename(value));

  value = iupAttribGet(ih, "FILE");
  if (value)
  {
    if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
      gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), iupgtkStrConvertToFilename(value));
    else
    {
      if (iupdrvIsFile(value))  /* check if file exists */
        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), iupgtkStrConvertToFilename(value));
    }
  }

  value = iupAttribGet(ih, "EXTFILTER");
  if (value)
  {
    char *name, *pattern, *filters = iupStrDup(value), *p;
    char atrib[30];
    int i;
    int filter_index = iupAttribGetInt(ih, "FILTERUSED");
    if (!filter_index)
      filter_index = 1;

    filter_count = iupStrReplace(filters, '|', 0) / 2;

    p = filters;
    for (i=0; i<filter_count; i++)
    {
      GtkFileFilter *filter = gtk_file_filter_new();

      gtkFileDlgGetNextFilter(&p, &name, &pattern);

      gtk_file_filter_set_name(filter, iupgtkStrConvertToUTF8(name));
      gtk_file_filter_add_pattern(filter, pattern);
      gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

      sprintf(atrib, "_IUPDLG_FILTER%d", i+1);
      iupAttribSetStr(ih, atrib, (char*)filter);

      if (i+1 == filter_index)
        gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
    }

    free(filters);
  }
  else 
  {
    value = iupAttribGet(ih, "FILTER");
    if (value)
    {
      GtkFileFilter *filter = gtk_file_filter_new();
      char* info = iupAttribGet(ih, "FILTERINFO");
      if (!info)
        info = value;

      gtk_file_filter_set_name(filter, iupgtkStrConvertToUTF8(info));
      gtk_file_filter_add_pattern(filter, value);
      gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
    }
  }

  file_cb = (IFnss)IupGetCallback(ih, "FILE_CB");
  if (file_cb && action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
  {
    g_signal_connect(GTK_FILE_CHOOSER(dialog), "update-preview", G_CALLBACK(gtkFileDlgUpdatePreview), ih);
    g_signal_connect(dialog, "realize", G_CALLBACK(gtkFileDlgRealize), ih);

    if (iupAttribGetBoolean(ih, "SHOWPREVIEW"))
    {
      GtkWidget* frame = gtk_frame_new(NULL);
      gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
      gtk_widget_set_size_request(frame, 180, 150);

      preview_canvas = gtk_drawing_area_new();
      gtk_widget_set_double_buffered(preview_canvas, FALSE);
      gtk_container_add(GTK_CONTAINER(frame), preview_canvas);
      gtk_widget_show(preview_canvas);

      g_signal_connect(preview_canvas, "configure-event", G_CALLBACK(gtkFileDlgPreviewConfigureEvent), ih);
      g_signal_connect(preview_canvas, "expose-event", G_CALLBACK(gtkFileDlgPreviewExposeEvent), ih);
      g_signal_connect(preview_canvas, "realize", G_CALLBACK(gtkFileDlgPreviewRealize), ih);

      iupAttribSetStr(ih, "_IUPDLG_FILE_CHOOSER", (char*)dialog);

      gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), frame);
    }
  }
  
  /* initialize the widget */
  gtk_widget_realize(GTK_WIDGET(dialog));
  
  ih->handle = GTK_WIDGET(dialog);
  iupDialogUpdatePosition(ih);
  ih->handle = NULL;  /* reset handle */

  do 
  {
    response = gtk_dialog_run(GTK_DIALOG(dialog));

    if (response == GTK_RESPONSE_HELP)
    {
      Icallback cb = IupGetCallback(ih, "HELP_CB");
      if (cb && cb(ih) == IUP_CLOSE)
        response = GTK_RESPONSE_CANCEL;
    }
    else if (response == GTK_RESPONSE_OK)
    {
      char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
      int file_exist = iupdrvIsFile(filename);
      int dir_exist = iupdrvIsDirectory(filename);
      g_free(filename);

      if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
      {
        if (!dir_exist)
        {
          iupStrMessageShowError(ih, "IUP_INVALIDDIR");
          response = GTK_RESPONSE_HELP; /* to leave the dialog open */
          continue;
        }
      }
      else if (!iupAttribGetBoolean(ih, "MULTIPLEFILES"))
      {
        if (dir_exist)
        {
          iupStrMessageShowError(ih, "IUP_FILEISDIR");
          response = GTK_RESPONSE_HELP; /* to leave the dialog open */
          continue;
        }

        if (!file_exist)  /* if do not exist check ALLOWNEW */
        {
          value = iupAttribGet(ih, "ALLOWNEW");
          if (!value)
          {
            if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
              value = "YES";
            else
              value = "NO";
          }

          if (!iupStrBoolean(value))
          {
            iupStrMessageShowError(ih, "IUP_FILENOTEXIST");
            response = GTK_RESPONSE_HELP; /* to leave the dialog open */
            continue;
          }
        }

        if (file_cb)
        {
          char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
          int ret = file_cb(ih, iupgtkStrConvertFromFilename(filename), "OK");
          g_free(filename);
          
          if (ret == IUP_IGNORE)
          {
            response = GTK_RESPONSE_HELP; /* to leave the dialog open */
            continue;
          }
        }
      }
    }
  } while (response == GTK_RESPONSE_HELP);

  if (file_cb)
  {
    if (iupAttribGetBoolean(ih, "SHOWPREVIEW"))
      iupgtkReleaseNativeGraphicsContext(preview_canvas, (void*)iupAttribGet(ih, "PREVIEWDC"));

    file_cb(ih, NULL, "FINISH");
  }

  if (response == GTK_RESPONSE_OK)
  {
    int file_exist, dir_exist;

    if (filter_count)
    {
      int i;
      char atrib[30];
      GtkFileFilter* filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));

      for (i=0; i<filter_count; i++)
      {
        sprintf(atrib, "_IUPDLG_FILTER%d", i+1);
        if (filter == (GtkFileFilter*)iupAttribGet(ih, atrib))
          iupAttribSetInt(ih, "FILTERUSED", i+1);
      }
    }

    if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
    {
      GSList* file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));

      if (file_list->next) /* if more than one file */
        gtkFileDlgGetMultipleFiles(ih, file_list);
      else
      {
        char* filename = (char*)file_list->data;
        iupAttribStoreStr(ih, "VALUE", iupgtkStrConvertFromFilename(filename));
        g_free(filename);
      }

      g_slist_free(file_list);
      file_exist = 1;
      dir_exist = 0;
    }
    else
    {
      char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
      iupAttribStoreStr(ih, "VALUE", iupgtkStrConvertFromFilename(filename));
      file_exist = iupdrvIsFile(filename);
      dir_exist = iupdrvIsDirectory(filename);
      g_free(filename);
    }

    if (dir_exist)
    {
      iupAttribSetStr(ih, "FILEEXIST", NULL);
      iupAttribSetStr(ih, "STATUS", "0");
    }
    else
    {
      if (file_exist)  /* check if file exists */
      {
        iupAttribSetStr(ih, "FILEEXIST", "YES");
        iupAttribSetStr(ih, "STATUS", "0");
      }
      else
      {
        iupAttribSetStr(ih, "FILEEXIST", "NO");
        iupAttribSetStr(ih, "STATUS", "1");
      }
    }

    if (action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && !iupAttribGetBoolean(ih, "NOCHANGEDIR"))  /* do change the current directory */
    {
      /* GtkFileChooser does not change the current directory */
      char* dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
      if (dir) iupdrvSetCurrentDirectory(dir);
      g_free(dir);
    }
  }
  else
  {
    iupAttribSetStr(ih, "FILTERUSED", NULL);
    iupAttribSetStr(ih, "VALUE", NULL);
    iupAttribSetStr(ih, "FILEEXIST", NULL);
    iupAttribSetStr(ih, "STATUS", "-1");
  }

  gtk_widget_destroy(GTK_WIDGET(dialog));  

  return IUP_NOERROR;
}