Merge pull request #594 from luco5826/master

Workaround on Export extension
presentation
andreasb242 7 years ago committed by GitHub
commit d552237335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      src/control/Control.cpp
  2. 4
      src/control/Control.h
  3. 39
      src/control/jobs/BaseExportJob.cpp
  4. 11
      src/control/jobs/BaseExportJob.h
  5. 60
      src/control/jobs/CustomExportJob.cpp
  6. 8
      src/control/jobs/CustomExportJob.h
  7. 29
      src/control/jobs/PdfExportJob.cpp
  8. 1
      src/control/jobs/PdfExportJob.h
  9. 1
      src/control/jobs/SaveJob.cpp
  10. 6
      src/control/settings/Settings.cpp
  11. 36
      src/model/Document.cpp
  12. 15
      src/util/Util.cpp
  13. 1
      src/util/Util.h

@ -2376,10 +2376,23 @@ bool Control::showSaveDialog()
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), true);
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->getWindow()->getWindow()));
if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
while (true)
{
gtk_widget_destroy(dialog);
return false;
if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
{
gtk_widget_destroy(dialog);
return false;
}
path filenameTmp = path(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))).replace_extension(".xopp");
path currentFolder(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)));
// Since we add the extension after the OK button, we have to check manually on existing files
if (checkExistingFile(currentFolder, filenameTmp))
{
break;
}
}
char* name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@ -2598,6 +2611,19 @@ bool Control::close(bool destroy)
return true;
}
bool Control::checkExistingFile(path& folder, path& filename)
{
XOJ_CHECK_TYPE(Control);
if (boost::filesystem::exists(filename))
{
string msg = FS(FORMAT_STR("The file {1} already exists! Do you want to replace it?") % filename.filename().string() );
int res = Util::replaceFileQuestion(getGtkWindow(), msg);
return res != 1; // res != 1 when user clicks on Replace
}
return true;
}
void Control::resetShapeRecognizer()
{
XOJ_CHECK_TYPE(Control);

@ -76,6 +76,10 @@ public:
void quit();
bool close(bool destroy = false);
// Asks user to replace an existing file when saving / exporting, since we add the extension
// after the OK, we need to check manually
bool checkExistingFile(path& folder, path& filename);
void resetShapeRecognizer();
// Menu edit

@ -3,6 +3,8 @@
#include "control/Control.h"
#include <i18n.h>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
#include <boost/algorithm/string.hpp>
namespace ba = boost::algorithm;
@ -38,18 +40,35 @@ void BaseExportJob::addFileFilterToDialog(string name, string pattern)
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
}
string BaseExportJob::getFilterName()
void BaseExportJob::clearExtensions(path& filename)
{
XOJ_CHECK_TYPE(BaseExportJob);
while (filename.has_extension())
{
filename.replace_extension();
}
}
bool BaseExportJob::checkOverwriteBackgroundPDF(path& filename)
{
XOJ_CHECK_TYPE(BaseExportJob);
GtkFileFilter* filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
return gtk_file_filter_get_name(filter);
// If the new file name (with the selected extension) is the prevoiusly selected pdf, warn the user
if (boost::iequals(filename.string(), control->getDocument()->getPdfFilename().string()))
{
string msg = _("Do not overwrite the background PDF! This will cause errors!");
Util::showErrorToUser(control->getGtkWindow(), msg);
return false;
}
return true;
}
void BaseExportJob::prepareSavePath(path& path)
string BaseExportJob::getFilterName()
{
XOJ_CHECK_TYPE(BaseExportJob);
// Nothing to do here, but will be overwritten
GtkFileFilter* filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
return gtk_file_filter_get_name(filter);
}
bool BaseExportJob::showFilechooser()
@ -66,13 +85,9 @@ bool BaseExportJob::showFilechooser()
path name = doc->createSaveFilename(Document::PDF, settings->getDefaultSaveName());
doc->unlock();
prepareSavePath(name);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), PATH_TO_CSTR(folder));
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), PATH_TO_CSTR(name));
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), true);
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->control->getWindow()->getWindow()));
while (true)
@ -84,9 +99,11 @@ bool BaseExportJob::showFilechooser()
}
string uri(gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog)));
this->filename = path(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
this->filename = path(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))).replace_extension();
path currentFolder(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)));
if (isUriValid(uri))
// Since we add the extension after the OK button, we have to check manually on existing files
if (isUriValid(uri) && control->checkExistingFile(currentFolder, filename))
{
break;
}

@ -39,7 +39,8 @@ protected:
void initDialog();
virtual void addFilterToDialog() = 0;
void addFileFilterToDialog(string name, string pattern);
virtual void prepareSavePath(path& path);
void clearExtensions(path& filename);
bool checkOverwriteBackgroundPDF(path& filename);
virtual bool isUriValid(string& uri);
private:
@ -51,4 +52,12 @@ protected:
path filename;
string errorMsg;
class ExportType
{
public:
string extension;
bool withoutBackground;
ExportType(string ext, bool hideBg) : extension(ext), withoutBackground(hideBg){}
};
};

@ -21,12 +21,12 @@ CustomExportJob::CustomExportJob(Control* control)
{
XOJ_INIT_TYPE(CustomExportJob);
// Static vars are not translated, they are loaded before the translation is ready
EXPORT_PDF = _("PDF files");
EXPORT_PDF_NOBG = _("PDF with plain background");
EXPORT_PNG = _("PNG graphics");
EXPORT_PNG_NOBG = _("PNG with transparent background");
EXPORT_XOJ = _("Xournal (Compatibility)");
// Supported filters
filters[_("PDF files")] = new ExportType(".pdf", false);
filters[_("PDF with plain background")] = new ExportType(".pdf", true);
filters[_("PNG graphics")] = new ExportType(".png", false);
filters[_("PNG with transparent background")] = new ExportType(".png", true);
filters[_("Xournal (Compatibility)")] = new ExportType(".xoj", false);
}
CustomExportJob::~CustomExportJob()
@ -39,6 +39,11 @@ CustomExportJob::~CustomExportJob()
}
exportRange.clear();
for(auto& filter : filters)
{
delete filter.second;
}
XOJ_RELEASE_TYPE(CustomExportJob);
}
@ -47,11 +52,11 @@ void CustomExportJob::addFilterToDialog()
{
XOJ_CHECK_TYPE(CustomExportJob);
addFileFilterToDialog(EXPORT_PDF, "*.pdf");
addFileFilterToDialog(EXPORT_PDF_NOBG, "*.pdf");
addFileFilterToDialog(EXPORT_PNG, "*.png");
addFileFilterToDialog(EXPORT_PNG_NOBG, "*.png");
addFileFilterToDialog(EXPORT_XOJ, "*.xoj");
// Runs on every filter inside the filters map
for (auto& filter : filters)
{
addFileFilterToDialog(filter.first, "*" + filter.second->extension); // Adds * for the pattern
}
}
bool CustomExportJob::isUriValid(string& uri)
@ -63,17 +68,14 @@ bool CustomExportJob::isUriValid(string& uri)
return false;
}
// Extract the file filter selected
this->chosenFilterName = BaseExportJob::getFilterName();
// Remove any pre-existing extension and adds the chosen one
clearExtensions(filename);
filename.replace_extension(filters[this->chosenFilterName]->extension);
string ext = filename.extension().string();
if (ext != ".pdf" && ext != ".png" && ext != ".xoj")
{
string msg = _("File name needs to end with .pdf, .png or .xoj");
Util::showErrorToUser(control->getGtkWindow(), msg);
return false;
}
return true;
return checkOverwriteBackgroundPDF(filename);
}
bool CustomExportJob::showFilechooser()
@ -189,14 +191,9 @@ void CustomExportJob::exportPngPage(int pageId, int id, double zoom, DocumentVie
PdfView::drawPage(NULL, popplerPage, cr, zoom, page->getWidth(), page->getHeight());
}
if (this->chosenFilterName == EXPORT_PNG_NOBG)
{
view.drawPage(page, this->cr, true, true);
}
else
{
view.drawPage(page, this->cr, true);
}
bool hideBackground = filters[this->chosenFilterName]->withoutBackground;
view.drawPage(page, this->cr, true, hideBackground);
if (!freeSurface(id))
{
@ -287,12 +284,9 @@ void CustomExportJob::run()
Document* doc = control->getDocument();
XojPdfExport* pdfe = XojPdfExportFactory::createExport(doc, control);
if (this->chosenFilterName == EXPORT_PDF_NOBG)
{
pdfe->setNoBackgroundExport(true);
}
pdfe->setNoBackgroundExport(filters[this->chosenFilterName]->withoutBackground);
if (!pdfe->createPdf(this->filename, exportRange))
{
this->errorMsg = pdfe->getLastError();

@ -17,6 +17,7 @@
#include <PageRange.h>
#include <i18n.h>
#include <map>
class CustomExportJob : public BaseExportJob
{
@ -75,10 +76,5 @@ private:
string chosenFilterName;
// Cannot be full static, because of translation
string EXPORT_PDF;
string EXPORT_PDF_NOBG;
string EXPORT_PNG;
string EXPORT_PNG_NOBG;
string EXPORT_XOJ;
std::map<string, ExportType*> filters;
};

@ -26,16 +26,6 @@ void PdfExportJob::addFilterToDialog()
addFileFilterToDialog(_("PDF files"), "*.pdf");
}
void PdfExportJob::prepareSavePath(path& path)
{
XOJ_CHECK_TYPE(PdfExportJob);
if (path.extension() != ".pdf")
{
path += ".pdf";
}
}
bool PdfExportJob::isUriValid(string& uri)
{
XOJ_CHECK_TYPE(PdfExportJob);
@ -45,22 +35,11 @@ bool PdfExportJob::isUriValid(string& uri)
return false;
}
string ext = filename.extension().string();
if (ext != ".pdf")
{
string msg = _("File name needs to end with .pdf");
Util::showErrorToUser(control->getGtkWindow(), msg);
return false;
}
if (boost::iequals(filename.string(), control->getDocument()->getPdfFilename().string()))
{
string msg = _("Do not overwrite the background PDF! This will cause errors!");
Util::showErrorToUser(control->getGtkWindow(), msg);
return false;
}
// Remove any pre-existing extension and adds .pdf
clearExtensions(filename);
filename += ".pdf";
return true;
return checkOverwriteBackgroundPDF(filename);
}

@ -26,7 +26,6 @@ public:
protected:
virtual void addFilterToDialog();
virtual void prepareSavePath(path& path);
virtual bool isUriValid(string& uri);
private:

@ -127,6 +127,7 @@ bool SaveJob::save()
doc->lock();
h.prepareSave(doc);
path filename = doc->getFilename();
filename.replace_extension(".xopp");
doc->unlock();
if (doc->shouldCreateBackupOnSave())

@ -1026,12 +1026,6 @@ string Settings::getDefaultSaveName()
{
XOJ_CHECK_TYPE(Settings);
if (ba::ends_with(defaultSaveName, ".xoj"))
{
defaultSaveName = defaultSaveName.substr(0, defaultSaveName.size() - 4);
defaultSaveName += ".xopp";
}
return this->defaultSaveName;
}

@ -187,45 +187,21 @@ path Document::createSaveFilename(DocumentType type, string defaultSaveName)
{
if (!filename.empty())
{
//This can be any extension
return filename.filename();
//This can be any extension
return filename.stem();
}
else if (!pdfFilename.empty())
{
path extension;
if (type == Document::XOPP)
{
extension = path(".pdf.xopp");
}
else if (type == Document::PDF)
{
extension = path(".xopp.pdf");
}
else
{
extension = path("");
}
return pdfFilename.filename().replace_extension(extension);
return pdfFilename.stem();
}
else
{
time_t curtime = time(NULL);
char stime[128];
strftime(stime, sizeof(stime), defaultSaveName.c_str(), localtime(&curtime));
path automaticName = path(stime);
if (type == Document::XOPP)
{
automaticName.replace_extension(".xopp");
}
else if (type == Document::XOJ)
{
automaticName.replace_extension(".xoj");
}
else if (type == Document::PDF)
{
automaticName.replace_extension(".pdf");
}
return automaticName.c_str();
// Remove the extension, file format is handled by the filter combo box
return path(stime).replace_extension();
}
}

@ -58,6 +58,21 @@ void Util::showErrorToUser(GtkWindow* win, string msg)
gtk_widget_destroy(dialog);
}
int Util::replaceFileQuestion(GtkWindow* win, string msg)
{
GtkWidget* dialog = gtk_message_dialog_new(win, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
"%s", msg.c_str());
if (win != NULL)
{
gtk_window_set_transient_for(GTK_WINDOW(dialog), win);
}
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Select another name"), 1);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Replace"), 2);
int res = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return res;
}
void Util::cairo_set_source_rgbi(cairo_t* cr, int c)
{
double r = ((c >> 16) & 0xff) / 255.0;

@ -38,6 +38,7 @@ private:
public:
static void showErrorToUser(GtkWindow* win, string msg);
static int replaceFileQuestion(GtkWindow* win, string msg);
static void cairo_set_source_rgbi(cairo_t* cr, int color);

Loading…
Cancel
Save