From 6b5c4517ca2b340e06a2d8cc7dca56029ab9ed3f Mon Sep 17 00:00:00 2001 From: Anshudhar Date: Fri, 5 Mar 2021 23:39:38 +0530 Subject: [PATCH 1/2] Added dialog for batch export conflicts Added options skip, overwrite, add suffix to batch export --- src/ui/dialog/export.cpp | 44 ++++++++++++++++++++++++ src/ui/dialog/export.h | 4 +++ src/ui/interface.cpp | 74 ++++++++++++++++++++++++++++++++++++++++ src/ui/interface.h | 5 +++ 4 files changed, 127 insertions(+) diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 2b2fcc82a5..4dfba70255 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -1028,6 +1028,42 @@ void Export::onExport () gint export_count = 0; auto itemlist= desktop->getSelection()->items(); + + //Get set of items which have existing filename + std::set conflicting_paths; + for(auto i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i) + { + SPItem *item = *i; + std::string path; + const gchar *filename = item->getRepr()->attribute("inkscape:export-filename"); + if (!filename) + { + auto id = item->getId(); + if (!id) + { + g_warning("object has no id"); + continue; + } + path = create_filepath_from_id(id, filename_entry.get_text()); + } + else + { + path = absolutize_path_from_document_location(doc, filename); + } + if (Inkscape::IO::file_test(path.c_str(), G_FILE_TEST_EXISTS)) + { + conflicting_paths.insert(path); + } + } + + //get a common suffix for all conflicting path + //should every conflicting file have its own suffix? + std::string suffix = sp_ui_overwrite_file_batch(conflicting_paths); + + //If export is cancelled by user set interrupt + if(suffix == "CANCEL") + interrupted = true; + for(auto i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i){ SPItem *item = *i; @@ -1049,6 +1085,10 @@ void Export::onExport () path = absolutize_path_from_document_location(doc, filename); } + //if skip is choosed + if(conflicting_paths.count(path) && suffix == "SKIP") + continue; + // retrieve export dpi hints const gchar *dpi_hint = item->getRepr()->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now gdouble dpi = 0.0; @@ -1074,6 +1114,10 @@ void Export::onExport () _("Exporting file %s..."), safeFile), desktop); std::vector x; std::vector selected(desktop->getSelection()->items().begin(), desktop->getSelection()->items().end()); + + if(conflicting_paths.count(path) && suffix != "OVERWRITE") + path = path + suffix; //buggy part as suffix is added after extension. + if (!sp_export_png_file (doc, path.c_str(), *area, width, height, pHYs, pHYs, nv->pagecolor, diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 0e138243a9..1c856dba9b 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -24,6 +24,10 @@ #include "ui/dialog/dialog-base.h" #include "ui/widget/scrollprotected.h" +//For set<> in batch export +#include +#include + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 089327c7ac..b74822964a 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -221,6 +221,80 @@ sp_ui_overwrite_file(gchar const *filename) return return_value; } +std::string +sp_ui_overwrite_file_batch(std::set& conflicting_paths) +{ + //0 means no conflicting paths hence take no action. + if(conflicting_paths.size()<1) + return "NO_CONFLICTING_PATHS"; + + //get space separated list of paths for printing in dialog + std::string path_list = ""; + for(auto& path:conflicting_paths) + path_list = path_list + path + " "; + + //get suffix if want copy. suffix also act as return value. + std::string suffix; + + bool suffix_found; + std::string temp_path = ""; + //To prevent infinite loop if happens. Currently only 100 iterations allowed + for(int i=0;i<100;i++) + { + suffix_found = true; + suffix = "_" + std::to_string(i); + for(auto& path: conflicting_paths) + { + temp_path = path + suffix; + if (Inkscape::IO::file_test(temp_path.c_str(), G_FILE_TEST_EXISTS)) + { + suffix_found = false; + break; + } + } + if(suffix_found) + break; + } + + if(!suffix_found) + suffix = "NO_SUFFIX_FOUND"; + + + //dialog creation. reference taken from sp_ui_overwrite_file + Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); + GtkWidget* dialog = gtk_message_dialog_new_with_markup( window->gobj(), + (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _( "Files already exists.\n\n" + "Files: \"%s\"\n" + "Replacing files will overwrite their contents. You can also skip these files.\n" + "Click add suffix to add \"%s\" as suffix to the file names." ), + path_list.c_str(), + suffix.c_str() + ); + + gtk_dialog_add_buttons( GTK_DIALOG(dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("Overwrite"), GTK_RESPONSE_YES, + _("SKIP FILES"), GTK_RESPONSE_OK, + _("ADD SUFFIX"), GTK_RESPONSE_APPLY, + NULL ); + gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_YES ); + + auto stat = gtk_dialog_run( GTK_DIALOG(dialog) ); + + if ( stat == GTK_RESPONSE_YES ) { + suffix = "OVERWRITE"; + } else if( stat == GTK_RESPONSE_OK ) { + suffix = "SKIP"; + } else if( stat == GTK_RESPONSE_CANCEL ) { + suffix = "CANCEL"; + } + gtk_widget_destroy(dialog); + return suffix; +} + /* Local Variables: mode:c++ diff --git a/src/ui/interface.h b/src/ui/interface.h index 4fa80dab13..b34e5f6357 100644 --- a/src/ui/interface.h +++ b/src/ui/interface.h @@ -20,6 +20,10 @@ #include +//Added for sp_ui_overwrite_file_batch +#include +#include + typedef struct _GtkWidget GtkWidget; namespace Inkscape { @@ -59,6 +63,7 @@ Glib::ustring getLayoutPrefPath( Inkscape::UI::View::View *view ); */ void sp_ui_error_dialog (char const* message); bool sp_ui_overwrite_file (char const* filename); +std::string sp_ui_overwrite_file_batch(std::set &conflicting_paths); #endif // SEEN_SP_INTERFACE_H -- GitLab From 4573edef6cf487ce58de5e19fa24c74e4f64dab3 Mon Sep 17 00:00:00 2001 From: Anshudhar Date: Sun, 7 Mar 2021 00:39:10 +0530 Subject: [PATCH 2/2] suffix before extention Separate function to minimise intereference with extension. Also refactored code to gtkmm --- src/ui/dialog/export.cpp | 82 ++++++++++++++++++++++++++++---------- src/ui/dialog/export.h | 1 - src/ui/interface.cpp | 85 ++++++++++++---------------------------- src/ui/interface.h | 4 +- 4 files changed, 87 insertions(+), 85 deletions(-) diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 4dfba70255..bb6102cb9a 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -578,6 +578,23 @@ Glib::RefPtr Export::createSpinbutton( gchar const * /*key*/, } // end of createSpinbutton() +//moved up because there was no declaration in header file. Should we add? +static std::string absolutize_path_from_document_location(SPDocument *doc, const std::string &filename) +{ + std::string path; + //Make relative paths go from the document location, if possible: + if (!Glib::path_is_absolute(filename) && doc->getDocumentURI()) { + auto dirname = Glib::path_get_dirname(doc->getDocumentURI()); + if (!dirname.empty()) { + path = Glib::build_filename(dirname, filename); + } + } + if (path.empty()) { + path = filename; + } + return path; +} + std::string create_filepath_from_id(Glib::ustring id, const Glib::ustring &file_entry_text) { if (id.empty()) @@ -606,6 +623,39 @@ std::string create_filepath_from_id(Glib::ustring id, const Glib::ustring &file_ return Glib::build_filename(directory, Glib::filename_from_utf8(id) + ".png"); } +std::string +create_filepath_from_id_with_suffix(gchar const* id, const Glib::ustring &file_entry_text,const gchar *filename,SPDocument *doc) +{ + + std::string path = ""; + std::string temp_id; + std::string temp_filename; + for(int i=0;i<100;i++) + { + if (!filename) { + if (!id) { + g_warning("object has no id"); + path = ""; + return path; + } + temp_id = id; + path = create_filepath_from_id(temp_id + "_" + std::to_string(i), file_entry_text); + } else { + temp_filename = filename; + path = absolutize_path_from_document_location(doc, temp_filename + "_" + std::to_string(i)); + } + + if (!Inkscape::IO::file_test(path.c_str(), G_FILE_TEST_EXISTS)) + { + return path; + } + } + + //if not found return empty path + path = ""; + return path; +} + void Export::onBatchClicked () { if (batch_export.get_active()) { @@ -959,22 +1009,6 @@ Export::create_progress_dialog(Glib::ustring progress_text) return dlg; } -static std::string absolutize_path_from_document_location(SPDocument *doc, const std::string &filename) -{ - std::string path; - //Make relative paths go from the document location, if possible: - if (!Glib::path_is_absolute(filename) && doc->getDocumentURI()) { - auto dirname = Glib::path_get_dirname(doc->getDocumentURI()); - if (!dirname.empty()) { - path = Glib::build_filename(dirname, filename); - } - } - if (path.empty()) { - path = filename; - } - return path; -} - // Called when unit is changed void Export::onUnitChanged() { @@ -1058,10 +1092,10 @@ void Export::onExport () //get a common suffix for all conflicting path //should every conflicting file have its own suffix? - std::string suffix = sp_ui_overwrite_file_batch(conflicting_paths); + auto conflict_response = sp_ui_overwrite_file_batch(conflicting_paths); //If export is cancelled by user set interrupt - if(suffix == "CANCEL") + if(conflict_response == -1) interrupted = true; for(auto i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i){ @@ -1086,7 +1120,7 @@ void Export::onExport () } //if skip is choosed - if(conflicting_paths.count(path) && suffix == "SKIP") + if(conflicting_paths.count(path) && conflict_response == 0) continue; // retrieve export dpi hints @@ -1115,8 +1149,14 @@ void Export::onExport () std::vector x; std::vector selected(desktop->getSelection()->items().begin(), desktop->getSelection()->items().end()); - if(conflicting_paths.count(path) && suffix != "OVERWRITE") - path = path + suffix; //buggy part as suffix is added after extension. + //if response was add suffix + if(conflicting_paths.count(path) && conflict_response == 2) + { + path = create_filepath_from_id_with_suffix(item->getId(), filename_entry.get_text(),filename,doc); + if(path.empty()) + continue; + } + if (!sp_export_png_file (doc, path.c_str(), *area, width, height, pHYs, pHYs, diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 1c856dba9b..e573172cd1 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -25,7 +25,6 @@ #include "ui/widget/scrollprotected.h" //For set<> in batch export -#include #include namespace Inkscape { diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index b74822964a..68bf3ab0cd 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -221,78 +221,41 @@ sp_ui_overwrite_file(gchar const *filename) return return_value; } -std::string +int sp_ui_overwrite_file_batch(std::set& conflicting_paths) { //0 means no conflicting paths hence take no action. if(conflicting_paths.size()<1) - return "NO_CONFLICTING_PATHS"; + return 1; //get space separated list of paths for printing in dialog - std::string path_list = ""; + Glib::ustring sec_message = "These files already exists:\n"; for(auto& path:conflicting_paths) - path_list = path_list + path + " "; - - //get suffix if want copy. suffix also act as return value. - std::string suffix; - - bool suffix_found; - std::string temp_path = ""; - //To prevent infinite loop if happens. Currently only 100 iterations allowed - for(int i=0;i<100;i++) - { - suffix_found = true; - suffix = "_" + std::to_string(i); - for(auto& path: conflicting_paths) - { - temp_path = path + suffix; - if (Inkscape::IO::file_test(temp_path.c_str(), G_FILE_TEST_EXISTS)) - { - suffix_found = false; - break; - } - } - if(suffix_found) - break; - } - - if(!suffix_found) - suffix = "NO_SUFFIX_FOUND"; - + sec_message = sec_message + "- " + path + "\n"; + sec_message = sec_message + "You can also skip these files or make a copy with suitable suffix"; //dialog creation. reference taken from sp_ui_overwrite_file Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); - GtkWidget* dialog = gtk_message_dialog_new_with_markup( window->gobj(), - (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _( "Files already exists.\n\n" - "Files: \"%s\"\n" - "Replacing files will overwrite their contents. You can also skip these files.\n" - "Click add suffix to add \"%s\" as suffix to the file names." ), - path_list.c_str(), - suffix.c_str() - ); - - gtk_dialog_add_buttons( GTK_DIALOG(dialog), - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("Overwrite"), GTK_RESPONSE_YES, - _("SKIP FILES"), GTK_RESPONSE_OK, - _("ADD SUFFIX"), GTK_RESPONSE_APPLY, - NULL ); - gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_YES ); - - auto stat = gtk_dialog_run( GTK_DIALOG(dialog) ); - if ( stat == GTK_RESPONSE_YES ) { - suffix = "OVERWRITE"; - } else if( stat == GTK_RESPONSE_OK ) { - suffix = "SKIP"; - } else if( stat == GTK_RESPONSE_CANCEL ) { - suffix = "CANCEL"; - } - gtk_widget_destroy(dialog); - return suffix; + Gtk::MessageDialog *dialog = new Gtk::MessageDialog(*window, + "", + true, + Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_NONE, + true + ); + + dialog->set_message("Files already exists. Do you want to overwrite them?"); + dialog->set_secondary_text(sec_message); + dialog->add_button(_("_Cancel"), -1); + dialog->add_button(_("Skip"), 0); + dialog->add_button(_("Overwrite"), 1); + dialog->add_button(_("Add Suffix"), 2); + dialog->set_default_response(1); + auto response = dialog->run(); + + delete dialog; + return response; } /* diff --git a/src/ui/interface.h b/src/ui/interface.h index b34e5f6357..14fa2723e1 100644 --- a/src/ui/interface.h +++ b/src/ui/interface.h @@ -21,8 +21,8 @@ #include //Added for sp_ui_overwrite_file_batch -#include #include +#include typedef struct _GtkWidget GtkWidget; @@ -63,7 +63,7 @@ Glib::ustring getLayoutPrefPath( Inkscape::UI::View::View *view ); */ void sp_ui_error_dialog (char const* message); bool sp_ui_overwrite_file (char const* filename); -std::string sp_ui_overwrite_file_batch(std::set &conflicting_paths); +int sp_ui_overwrite_file_batch(std::set &conflicting_paths); #endif // SEEN_SP_INTERFACE_H -- GitLab