Exemplo n.º 1
0
/* Finish up the user's Release command by choosing a location to store the
project. This is a callback and the GDK lock is held when entering this
 function. */
void
i7_story_save_compiler_output(I7Story *story, const gchar *dialog_title)
{
    I7_STORY_USE_PRIVATE(story, priv);

    GFile *file = NULL;
    if(priv->copy_blorb_dest_file == NULL) {
        /* ask the user for a release file name if cBlorb didn't provide one */

        /* Create a file chooser */
        GtkFileFilter *filter = gtk_file_filter_new();
        if(i7_story_get_story_format(story) == I7_STORY_FORMAT_GLULX) {
            gtk_file_filter_set_name(filter, _("Glulx games (.ulx,.gblorb)"));
            gtk_file_filter_add_pattern(filter, "*.ulx");
            gtk_file_filter_add_pattern(filter, "*.gblorb");
        } else {
            gtk_file_filter_set_name(filter, _("Z-code games (.z?,.zblorb)"));
            gtk_file_filter_add_pattern(filter, "*.z?");
            gtk_file_filter_add_pattern(filter, "*.zblorb");
        }
        GtkWidget *dialog = gtk_file_chooser_dialog_new(dialog_title,
                            GTK_WINDOW(story), GTK_FILE_CHOOSER_ACTION_SAVE,
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                            GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                            NULL);
        gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
        char *curfilename = g_file_get_basename(priv->compiler_output_file);
        gchar *title = i7_document_get_display_name(I7_DOCUMENT(story));
        char *extension = strrchr(curfilename, '.'); /* not allocated */
        char *suggestname;
        if(title != NULL) {
            *(strrchr(title, '.')) = '\0';
            suggestname = g_strconcat(title, extension, NULL);
            g_free(title);
        } else {
            suggestname = g_strconcat("Untitled", extension, NULL);
        }
        g_free(curfilename);
        gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), suggestname);
        g_free(suggestname);
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

        if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
            file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog));

        gtk_widget_destroy(dialog);
    } else {
        file = g_object_ref(priv->copy_blorb_dest_file);
    }

    if(file) {
        /* Move the finished file to the release location */
        GError *err = NULL;
        if(!g_file_move(priv->compiler_output_file, file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &err)) {
            IO_ERROR_DIALOG(GTK_WINDOW(story), file, err, _("copying compiler output"));
        }
        g_object_unref(file);
    }
}
Exemplo n.º 2
0
/* Search the documentation pages for the string 'text', building the index
  if necessary */
void
i7_search_window_search_documentation(I7SearchWindow *self)
{
	GError *err;

	if(doc_index == NULL) { /* documentation index hasn't been built yet */
		GFile *doc_file = i7_app_get_data_file_va(i7_app_get(), "Documentation", NULL);

		GFileEnumerator *docdir;
		if((docdir = g_file_enumerate_children(doc_file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, &err)) == NULL) {
			IO_ERROR_DIALOG(GTK_WINDOW(self), doc_file, err, _("opening documentation directory"));
			g_object_unref(doc_file);
			return;
		}

		start_spinner(self);

		GFileInfo *info;
		while((info = g_file_enumerator_next_file(docdir, NULL, &err)) != NULL) {
			const char *basename = g_file_info_get_name(info);
			const char *displayname = g_file_info_get_display_name(info);

			if(!g_str_has_suffix(basename, ".html") ||
			   (!g_str_has_prefix(basename, "doc") && !g_str_has_prefix(basename, "Rdoc")))
				continue;

			char *label = g_strdup_printf(_("Please be patient, indexing %s..."), displayname);
			gtk_label_set_text(GTK_LABEL(self->search_text), label);
			g_free(label);

			while(gtk_events_pending())
				gtk_main_iteration();

			GFile *file = g_file_get_child(doc_file, basename);
			GSList *doctexts = html_to_ascii(file, g_str_has_prefix(basename, "R"));
			g_object_unref(file);
			if(doctexts != NULL) {
				GSList *iter;
				/* Append the entries to the documentation index and search them
				right now while we're at it */
				for(iter = doctexts; iter != NULL; iter = g_slist_next(iter)) {
					doc_index = g_list_prepend(doc_index, iter->data);
					search_documentation(iter->data, self);
				}
				g_slist_free(doctexts);
			}
		}
		g_object_unref(doc_file);

		stop_spinner(self);
		update_label(self);
	} else {
		start_spinner(self);
		g_list_foreach(doc_index, (GFunc)search_documentation, self);
		stop_spinner(self);
	}
	return;
}
Exemplo n.º 3
0
/* Release->Open Materials Folder */
void
action_open_materials_folder(GtkAction *action, I7Story *story)
{
	GError *error = NULL;
	gchar *uri;
	GFile *materials_file = i7_story_get_materials_file(story);

	/* Prompt the user to create the folder if it doesn't exist */
	if(!g_file_query_exists(materials_file, NULL)) {
		/* TRANSLATORS: Release->Open Materials Folder */
		GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(story),
			GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
			GTK_BUTTONS_OK_CANCEL, _("Could not find Materials folder"));
		gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
			_("At the moment, this project has no Materials folder - a "
			"convenient place to put figures, sounds, manuals, hints or other "
			"matter to be packaged up with a release.\n\nWould you like to "
			"create one?"));
		gint response = gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);
		if(response == GTK_RESPONSE_OK) {
			if(!g_file_make_directory_with_parents(materials_file, NULL, &error)) {
				/* shouldn't already exist, so don't ignore G_IO_ERROR_EXISTS */
				IO_ERROR_DIALOG(GTK_WINDOW(story), materials_file, error, _("creating Materials folder"));
				goto finally;
			}
			file_set_custom_icon(materials_file, "application-x-inform-materials");
		} else
			goto finally;
	}

	if(g_file_query_file_type(materials_file, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY) {
		/* Odd; the Materials folder is a file. We open the containing path so
		 the user can see this and correct it if they like. */
		GFile *parent = g_file_get_parent(materials_file);
		uri = g_file_get_uri(parent);
		g_object_unref(parent);
	} else {
		uri = g_file_get_uri(materials_file);
	}

	/* TRANSLATORS: this string is used in error messages and should fit in the
	pattern "We couldn't open a program to show ___" */
	show_uri_externally(uri, GTK_WINDOW(story), _("the Materials folder"));

	g_free(uri);
finally:
	g_object_unref(materials_file);
}
Exemplo n.º 4
0
/* Set everything up for using the NI compiler. Called from the main thread. */
static void
prepare_ni_compiler(CompilerData *data)
{
    I7_STORY_USE_PRIVATE(data->story, priv);
    GError *err = NULL;

    /* Clear the previous compile output */
    gtk_text_buffer_set_text(priv->progress, "", -1);
    html_load_blank(WEBKIT_WEB_VIEW(data->story->panel[LEFT]->results_tabs[I7_RESULTS_TAB_REPORT]));
    html_load_blank(WEBKIT_WEB_VIEW(data->story->panel[RIGHT]->results_tabs[I7_RESULTS_TAB_REPORT]));

    /* Create the UUID file if needed */
    GFile *uuid_file = g_file_get_child(data->input_file, "uuid.txt");
    if(!g_file_query_exists(uuid_file, NULL)) {
#ifdef E2FS_UUID /* code for e2fsprogs uuid */
        uuid_t uuid;
        gchar uuid_string[37];

        uuid_generate_time(uuid);
        uuid_unparse(uuid, uuid_string);
#else /* code for OSSP UUID */
        gchar *uuid_string = NULL; /* a new buffer is allocated if NULL */
        uuid_t *uuid;

        if(!((uuid_create(&uuid) == UUID_RC_OK)
                && (uuid_make(uuid, UUID_MAKE_V1) == UUID_RC_OK)
                && (uuid_export(uuid, UUID_FMT_STR, (void **)&uuid_string, NULL) == UUID_RC_OK)
                && (uuid_destroy(uuid) == UUID_RC_OK))) {
            error_dialog(GTK_WINDOW(data->story), NULL, _("Error creating UUID."));
            g_object_unref(uuid_file);
            return;
        }
#endif /* UUID conditional */
        if(!g_file_replace_contents(uuid_file, uuid_string, strlen(uuid_string), NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &err)) {
            IO_ERROR_DIALOG(GTK_WINDOW(data->story), uuid_file, err, _("creating UUID file"));
            g_object_unref(uuid_file);
            return;
        }
#ifndef E2FS_UUID /* Only OSSP UUID */
        free(uuid_string);
#endif /* !OSSP_UUID */
    }
    g_object_unref(uuid_file);

    /* Display status message */
    i7_document_display_status_message(I7_DOCUMENT(data->story), _("Compiling Inform 7 to Inform 6"), COMPILE_OPERATIONS);
}
Exemplo n.º 5
0
void
on_extensions_view_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selectiondata, guint info, guint time)
{
	GFile *file;
	GFileInfo *file_info;
	gchar *type_name = NULL;

	/* Check that we got data from source */
	if(selectiondata == NULL || gtk_selection_data_get_length(selectiondata) < 0)
		goto fail;

	/* Check that we got the format we can use */
	type_name = gdk_atom_name(gtk_selection_data_get_data_type(selectiondata));
	if(strcmp(type_name, "text/uri-list") != 0)
		goto fail;

	/* Do stuff with the data */
	char **extension_files = g_uri_list_extract_uris((char *)gtk_selection_data_get_data(selectiondata));
	int foo;
	/* Get a list of URIs to the dropped files */
	for(foo = 0; extension_files[foo] != NULL; foo++) {
		GError *err = NULL;
		file = g_file_new_for_uri(extension_files[foo]);
		file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &err);
		if(!file_info) {
			IO_ERROR_DIALOG(NULL, file, err, _("accessing a URI"));
			goto fail2;
		}

		/* Check whether a directory was dropped. if so, install contents */
		/* NOTE: not recursive (that would be kind of silly anyway) */
		if(g_file_info_get_file_type(file_info) == G_FILE_TYPE_DIRECTORY) {

			GFileEnumerator *dir = g_file_enumerate_children(file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, &err);
			if(!dir) {
				IO_ERROR_DIALOG(NULL, file, err, _("opening a directory"));
				goto fail3;
			}

			GFileInfo *entry_info;
			while((entry_info = g_file_enumerator_next_file(dir, NULL, &err)) != NULL) {
				if(g_file_info_get_file_type(entry_info) != G_FILE_TYPE_DIRECTORY) {
					GFile *extension_file = g_file_get_child(file, g_file_info_get_name(entry_info));
					i7_app_install_extension(i7_app_get(), extension_file);
					g_object_unref(extension_file);
				}
				g_object_unref(entry_info);
			}
			g_file_enumerator_close(dir, NULL, &err);
			g_object_unref(dir);

			if(err) {
				IO_ERROR_DIALOG(NULL, file, err, _("reading a directory"));
				goto fail3;
			}

		} else {
			/* just install it */
			i7_app_install_extension(i7_app_get(), file);
		}

		g_object_unref(file_info);
		g_object_unref(file);
	}

	g_strfreev(extension_files);
	g_free(type_name);
	gtk_drag_finish(drag_context, TRUE, FALSE, time);
	return;

fail3:
	g_object_unref(file_info);
fail2:
	g_object_unref(file);
	g_strfreev(extension_files);
fail:
	g_free(type_name);
	gtk_drag_finish(drag_context, FALSE, FALSE, time);
}
Exemplo n.º 6
0
/* Finish up the user's Export iFiction Record command. This is a callback and
 the GDK lock is held when entering this function. */
void
i7_story_save_ifiction(I7Story *story)
{
    /* Work out where the file should be */
    GFile *project_file = i7_document_get_file(I7_DOCUMENT(story));
    if(project_file == NULL) {
        g_warning("Tried to save iFiction record of story without associated file");
        return; /* This shouldn't happen because the file is saved before compilation */
    }
    GFile *ifiction_file = g_file_get_child(project_file, "Metadata.iFiction");

    /* Prompt user to save iFiction file if it exists */
    if(g_file_query_exists(ifiction_file, NULL))
    {
        /* Make a file filter */
        GtkFileFilter *filter = gtk_file_filter_new();
        gtk_file_filter_set_name(filter, _("iFiction records (.iFiction)"));
        gtk_file_filter_add_pattern(filter, "*.iFiction");

        /* Make up a default file name */
        gchar *name = i7_document_get_display_name(I7_DOCUMENT(story));
        /* project_file is not NULL so neither is name */
        *(strrchr(name, '.')) = '\0';
        gchar *filename = g_strconcat(name, ".iFiction", NULL);
        g_free(name);

        /* Create a file chooser */
        GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Save iFiction record"),
                            GTK_WINDOW(story), GTK_FILE_CHOOSER_ACTION_SAVE,
                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                            GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                            NULL);
        gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
        gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
        g_free(filename);

        GFile *parent_file = g_file_get_parent(project_file);
        /* Ignore error */
        gtk_file_chooser_set_current_folder_file(GTK_FILE_CHOOSER(dialog), parent_file, NULL);
        g_object_unref(parent_file);

        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

        /* Copy the finished file to the chosen location */
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
            GFile *dest_file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog));
            GError *error = NULL;

            if(!g_file_copy(ifiction_file, dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
                IO_ERROR_DIALOG(GTK_WINDOW(story), dest_file, error, _("copying iFiction record"));
            }

            g_object_unref(dest_file);
        }
        gtk_widget_destroy(dialog);
    }
    else
        error_dialog(GTK_WINDOW(story), NULL,
                     _("The compiler failed to create an iFiction record; check the "
                       "results page to see why."));

    g_object_unref(ifiction_file);
    g_object_unref(project_file);
}