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

static gint inkscape_autosave ( gpointer   ) [static]

static gint inkscape_autosave(gpointer);

Callback passed to g_timeout_add_seconds() Responsible for autosaving all open documents

Definition at line 293 of file inkscape.cpp.

References Inkscape::XML::Node::document(), Inkscape::Preferences::get(), Inkscape::Preferences::getInt(), and Inkscape::Preferences::getString().

{
    if (inkscape->document_set.empty()) { // nothing to autosave
        return TRUE;
    }
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    // Use UID for separating autosave-documents between users if directory is multiuser
    uid_t uid = getuid();

    Glib::ustring autosave_dir;
    {
        Glib::ustring tmp = prefs->getString("/options/autosave/path");
        if (!tmp.empty()) {
            autosave_dir = tmp;
        } else {
            autosave_dir = Glib::get_tmp_dir();
        }
    }

    GDir *autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL);
    if( !autosave_dir_ptr ){
        g_warning("Cannot open autosave directory!");
        return TRUE;
    }

    time_t sptime = time(NULL);
    struct tm *sptm = localtime(&sptime);
    gchar sptstr[256];
    strftime(sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm);

    gint autosave_max = prefs->getInt("/options/autosave/max", 10);

    gint docnum = 0;

    SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents..."));
    for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
          iter != inkscape->document_set.end();
          ++iter) {

        SPDocument *doc = iter->first;

        ++docnum;

        Inkscape::XML::Node *repr = sp_document_repr_root(doc);
        // g_debug("Document %d: \"%s\" %s", docnum, doc ? doc->name : "(null)", doc ? (doc->isModifiedSinceSave() ? "(dirty)" : "(clean)") : "(null)");

        if (doc->isModifiedSinceSave()) {
            gchar *oldest_autosave = 0;
            const gchar  *filename = 0;
            struct stat sb;
            time_t min_time = 0;
            gint count = 0;

            // Look for previous autosaves
            gchar* baseName = g_strdup_printf( "inkscape-autosave-%d", uid );
            g_dir_rewind(autosave_dir_ptr);
            while( (filename = g_dir_read_name(autosave_dir_ptr)) != NULL ){
                if ( strncmp(filename, baseName, strlen(baseName)) == 0 ){
                    gchar* full_path = g_build_filename( autosave_dir.c_str(), filename, NULL );
                    if ( g_stat(full_path, &sb) != -1 ) {
                        if ( difftime(sb.st_ctime, min_time) < 0 || min_time == 0 ){
                            min_time = sb.st_ctime;
                            if ( oldest_autosave ) {
                                g_free(oldest_autosave);
                            }
                            oldest_autosave = g_strdup(full_path);
                        }
                        count ++;
                    }
                    g_free(full_path);
                }
            }

            // g_debug("%d previous autosaves exists. Max = %d", count, autosave_max);

            // Have we reached the limit for number of autosaves?
            if ( count >= autosave_max ){
                // Remove the oldest file
                if ( oldest_autosave ) {
                    unlink(oldest_autosave);
                }
            }

            if ( oldest_autosave ) {
                g_free(oldest_autosave);
                oldest_autosave = 0;
            }


            // Set the filename we will actually save to
            g_free(baseName);
            baseName = g_strdup_printf("inkscape-autosave-%d-%s-%03d.svg", uid, sptstr, docnum);
            gchar* full_path = g_build_filename(autosave_dir.c_str(), baseName, NULL);
            g_free(baseName);
            baseName = 0;

            // g_debug("Filename: %s", full_path);

            // Try to save the file
            FILE *file = Inkscape::IO::fopen_utf8name(full_path, "w");
            gchar *errortext = 0;
            if (file) {
                try{
                    sp_repr_save_stream(repr->document(), file, SP_SVG_NS_URI);
                } catch (Inkscape::Extension::Output::no_extension_found &e) {
                    errortext = g_strdup(_("Autosave failed! Could not find inkscape extension to save document."));
                } catch (Inkscape::Extension::Output::save_failed &e) {
                    gchar *safeUri = Inkscape::IO::sanitizeString(full_path);
                    errortext = g_strdup_printf(_("Autosave failed! File %s could not be saved."), safeUri);
                    g_free(safeUri);
                }
                fclose(file);
            }
            else {
                gchar *safeUri = Inkscape::IO::sanitizeString(full_path);
                errortext = g_strdup_printf(_("Autosave failed! File %s could not be saved."), safeUri);
                g_free(safeUri);
            }

            if (errortext) {
                SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, errortext);
                g_warning("%s", errortext);
                g_free(errortext);
            }

            g_free(full_path);
        }
    }
    g_dir_close(autosave_dir_ptr);

    SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosave complete."));

    return TRUE;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index