From 179726de7e87c87e60db35ef00d42b961a296e18 Mon Sep 17 00:00:00 2001 From: bdilly Date: Thu, 9 Aug 2007 06:39:57 +0000 Subject: [PATCH] changes export to ocal dialog --- src/file.cpp | 9 +- src/ui/dialog/filedialog.cpp | 21 +- src/ui/dialog/filedialog.h | 64 ++++++ src/ui/dialog/filedialogimpl-gtkmm.cpp | 305 +++++++++++++++++++++++++ src/ui/dialog/filedialogimpl-gtkmm.h | 124 ++++++++++ 5 files changed, 516 insertions(+), 7 deletions(-) diff --git a/src/file.cpp b/src/file.cpp index 92df59065..ebeef462e 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1213,7 +1213,6 @@ sp_file_export_dialog(void *widget) bool sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow) { - //# temp hack for 'doc' until we can switch to this dialog if (!SP_ACTIVE_DOCUMENT) return false; @@ -1227,7 +1226,7 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow) bool success = false; - static Inkscape::UI::Dialog::FileExportDialog *exportDialogInstance = NULL; + static Inkscape::UI::Dialog::FileExportToOCALDialog *exportDialogInstance = NULL; Inkscape::XML::Node *repr = sp_document_repr_root(doc); // Verify whether the document is saved, so save this as temporary @@ -1270,11 +1269,9 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow) export_path = export_path_local; //# Show the Export To OCAL dialog - // MADE A CHANGE TO SUBMIT CHANGES. IN THE FUTURE WILL CALL FileExportToOCALDialog if (!exportDialogInstance) - exportDialogInstance = Inkscape::UI::Dialog::FileExportDialog::create( + exportDialogInstance = Inkscape::UI::Dialog::FileExportToOCALDialog::create( parentWindow, - export_path, Inkscape::UI::Dialog::EXPORT_TYPES, (char const *) _("Select file to export to"), default_extension @@ -1325,7 +1322,7 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow) uri.append(Glib::path_get_basename(fileName)); // Save as a remote file using the dav protocol. success = file_save_remote(doc, uri, selectionType, FALSE, FALSE); - //remove(fileName.c_str()); + remove(fileName.c_str()); if (!success) g_warning( "Error exporting the document." ); diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index 2b4dc699b..63bb98b4b 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -65,7 +65,7 @@ FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow, /** * Public factory method. Used in file.cpp */ -FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow, + FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow, const Glib::ustring &path, FileDialogType fileTypes, const Glib::ustring &title, @@ -76,6 +76,25 @@ FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow, } +//######################################################################## +//# F I L E E X P O R T T O O C A L +//######################################################################## + + +/** + * Public factory method. Used in file.cpp + */ + + FileExportToOCALDialog *FileExportToOCALDialog::create(Gtk::Window& parentWindow, + FileDialogType fileTypes, + const Glib::ustring &title, + const Glib::ustring &default_key) +{ + FileExportToOCALDialog *dialog = new FileExportToOCALDialogImpl(parentWindow, fileTypes, title, default_key); + return dialog; +} + + } //namespace Dialog } //namespace UI diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 8551b0eb2..06d68fa72 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -35,6 +35,7 @@ namespace Dialog { + /** * Used for setting filters and options, and * reading them back from user selections. @@ -328,6 +329,69 @@ public: }; //FileExportDialog +/** + * This class provides an implementation-independent API for + * file "ExportToOCAL" dialogs. + */ +class FileExportToOCALDialog +{ +public: + + /** + * Constructor. Do not call directly . Use the factory. + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + * @param key a list of file types from which the user can select + */ + FileExportToOCALDialog () + {}; + + /** + * Factory. + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + * @param key a list of file types from which the user can select + */ + static FileExportToOCALDialog *create(Gtk::Window& parentWindow, + FileDialogType fileTypes, + const Glib::ustring &title, + const Glib::ustring &default_key); + + + /** + * Destructor. + * Perform any necessary cleanups. + */ + virtual ~FileExportToOCALDialog() {}; + + + /** + * Show an SaveAs file selector. + * @return the selected path if user selected one, else NULL + */ + virtual bool show() =0; + + /** + * Return the 'key' (filetype) of the selection, if any + * @return a pointer to a string if successful (which must + * be later freed with g_free(), else NULL. + */ + virtual Inkscape::Extension::Extension * getSelectionType() = 0; + + virtual void setSelectionType( Inkscape::Extension::Extension * key ) = 0; + + virtual Glib::ustring getFilename () =0; + + /** + * Change the window title. + */ + virtual void change_title(const Glib::ustring& title) =0; + + +}; //FileExportToOCAL + + + } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 6ed56cefd..b76772c40 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -1612,6 +1612,311 @@ FileExportDialogImpl::getFilename() return myFilename; } + + + +//######################################################################## +//# F I L E E X P O R T T O O C A L +//######################################################################## + + + +/** + * Callback for fileNameEntry widget + */ +void FileExportToOCALDialogImpl::fileNameEntryChangedCallback() +{ + if (!fileNameEntry) + return; + + Glib::ustring fileName = fileNameEntry->get_text(); + if (!Glib::get_charset()) //If we are not utf8 + fileName = Glib::filename_to_utf8(fileName); + + //g_message("User hit return. Text is '%s'\n", fileName.c_str()); + + myFilename = fileName; + response(Gtk::RESPONSE_OK); +} + + + +/** + * Callback for fileNameEntry widget + */ +void FileExportToOCALDialogImpl::fileTypeChangedCallback() +{ + int sel = fileTypeComboBox.get_active_row_number(); + if (sel<0 || sel >= (int)fileTypes.size()) + return; + FileType type = fileTypes[sel]; + + extension = type.extension; + updateNameAndExtension(); +} + + + +void FileExportToOCALDialogImpl::createFileTypeMenu() +{ + Inkscape::Extension::DB::OutputList extension_list; + Inkscape::Extension::db.get_output_list(extension_list); + knownExtensions.clear(); + + for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin(); + current_item != extension_list.end(); current_item++) + { + Inkscape::Extension::Output * omod = *current_item; + + // FIXME: would be nice to grey them out instead of not listing them + if (omod->deactivated()) continue; + + FileType type; + type.name = (_(omod->get_filetypename())); + type.pattern = "*"; + Glib::ustring extension = omod->get_extension(); + knownExtensions.insert( extension.casefold() ); + fileDialogExtensionToPattern (type.pattern, extension); + type.extension= omod; + fileTypeComboBox.append_text(type.name); + fileTypes.push_back(type); + } + + //#Let user choose + FileType guessType; + guessType.name = _("Guess from extension"); + guessType.pattern = "*"; + guessType.extension = NULL; + fileTypeComboBox.append_text(guessType.name); + fileTypes.push_back(guessType); + + + fileTypeComboBox.set_active(0); + fileTypeChangedCallback(); //call at least once to set the filter +} + + + +/** + * Constructor + */ +FileExportToOCALDialogImpl::FileExportToOCALDialogImpl(Gtk::Window &parentWindow, + FileDialogType fileTypes, + const Glib::ustring &title, + const Glib::ustring &default_key) : + FileDialogExportBase(title) +{ + /* + * Start Taking the vertical Box and putting a Label + * and a Entry to take the filename + * Later put the extension selection and checkbox (?) + */ + /* Initalize to Autodetect */ + extension = NULL; + /* No filename to start out with */ + myFilename = ""; + + /* Set our dialog type (save, export, etc...)*/ + dialogType = fileTypes; + Gtk::VBox *vbox = get_vbox(); + //Gtk::HBox fileBox; + + Gtk::Label *fileLabel = new Gtk::Label(_("File")); + + fileNameEntry = new Gtk::Entry(); + fileNameEntry->set_text(myFilename); + fileNameEntry->set_max_length(252); // I am giving the extension approach. + fileBox.pack_start(*fileLabel); + fileBox.pack_start(*fileNameEntry, Gtk::PACK_EXPAND_WIDGET, 3); + vbox->pack_start(fileBox); + + //###### Do we want the .xxx extension automatically added? + fileTypeCheckbox.set_label(Glib::ustring(_("Append filename extension automatically"))); + fileTypeCheckbox.set_active( (bool)prefs_get_int_attribute("dialogs.export", + "append_extension", 1) ); + + createFileTypeMenu(); + + fileTypeComboBox.set_size_request(200,40); + fileTypeComboBox.signal_changed().connect( + sigc::mem_fun(*this, &FileExportToOCALDialogImpl::fileTypeChangedCallback) ); + + checksBox.pack_start( fileTypeCheckbox ); + vbox->pack_start( checksBox ); + + vbox->pack_end( fileTypeComboBox ); + + //Let's do some customization + fileNameEntry = NULL; + Gtk::Container *cont = get_toplevel(); + std::vector entries; + findEntryWidgets(cont, entries); + //g_message("Found %d entry widgets\n", entries.size()); + if (entries.size() >=1 ) + { + //Catch when user hits [return] on the text field + fileNameEntry = entries[0]; + fileNameEntry->signal_activate().connect( + sigc::mem_fun(*this, &FileExportToOCALDialogImpl::fileNameEntryChangedCallback) ); + } + + //Let's do more customization + std::vector expanders; + findExpanderWidgets(cont, expanders); + //g_message("Found %d expander widgets\n", expanders.size()); + if (expanders.size() >=1 ) + { + //Always show the file list + Gtk::Expander *expander = expanders[0]; + expander->set_expanded(true); + } + + + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + set_default(*add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK)); + + show_all_children(); +} + + + +/** + * Destructor + */ +FileExportToOCALDialogImpl::~FileExportToOCALDialogImpl() +{ +} + + + +/** + * Show this dialog modally. Return true if user hits [OK] + */ +bool +FileExportToOCALDialogImpl::show() +{ + set_modal (TRUE); //Window + sp_transientize((GtkWidget *)gobj()); //Make transient + gint b = run(); //Dialog + hide(); + + if (b == Gtk::RESPONSE_OK) + { + updateNameAndExtension(); + + return TRUE; + } + else + { + return FALSE; + } +} + + +/** + * Get the file extension type that was selected by the user. Valid after an [OK] + */ +Inkscape::Extension::Extension * +FileExportToOCALDialogImpl::getSelectionType() +{ + return extension; +} + +void FileExportToOCALDialogImpl::setSelectionType( Inkscape::Extension::Extension * key ) +{ + // If no pointer to extension is passed in, look up based on filename extension. + if ( !key ) { + // Not quite UTF-8 here. + gchar *filenameLower = g_ascii_strdown(myFilename.c_str(), -1); + for ( int i = 0; !key && (i < (int)fileTypes.size()); i++ ) { + Inkscape::Extension::Output *ext = dynamic_cast(fileTypes[i].extension); + if ( ext && ext->get_extension() ) { + gchar *extensionLower = g_ascii_strdown( ext->get_extension(), -1 ); + if ( g_str_has_suffix(filenameLower, extensionLower) ) { + key = fileTypes[i].extension; + } + g_free(extensionLower); + } + } + g_free(filenameLower); + } + + // Ensure the proper entry in the combo box is selected. + if ( key ) { + extension = key; + gchar const * extensionID = extension->get_id(); + if ( extensionID ) { + for ( int i = 0; i < (int)fileTypes.size(); i++ ) { + Inkscape::Extension::Extension *ext = fileTypes[i].extension; + if ( ext ) { + gchar const * id = ext->get_id(); + if ( id && ( strcmp(extensionID, id) == 0) ) { + int oldSel = fileTypeComboBox.get_active_row_number(); + if ( i != oldSel ) { + fileTypeComboBox.set_active(i); + } + break; + } + } + } + } + } +} + + +/** + * Get the file name chosen by the user. Valid after an [OK] + */ +Glib::ustring +FileExportToOCALDialogImpl::getFilename() +{ + myFilename = fileNameEntry->get_text(); + updateNameAndExtension(); + return myFilename; +} + + +void +FileExportToOCALDialogImpl::change_title(const Glib::ustring& title) +{ + this->set_title(title); +} + +void FileExportToOCALDialogImpl::updateNameAndExtension() +{ + // Pick up any changes the user has typed in. + Glib::ustring tmp = myFilename; // get_filename(); + + Inkscape::Extension::Output* newOut = extension ? dynamic_cast(extension) : 0; + if ( fileTypeCheckbox.get_active() && newOut ) { + try { + bool appendExtension = true; + Glib::ustring utf8Name = Glib::filename_to_utf8( myFilename ); + Glib::ustring::size_type pos = utf8Name.rfind('.'); + if ( pos != Glib::ustring::npos ) { + Glib::ustring trail = utf8Name.substr( pos ); + Glib::ustring foldedTrail = trail.casefold(); + if ( (trail == ".") + | (foldedTrail != Glib::ustring( newOut->get_extension() ).casefold() + && ( knownExtensions.find(foldedTrail) != knownExtensions.end() ) ) ) { + utf8Name = utf8Name.erase( pos ); + } else { + appendExtension = false; + } + } + + if (appendExtension) { + utf8Name = utf8Name + newOut->get_extension(); + myFilename = Glib::filename_from_utf8( utf8Name ); + + } + } catch ( Glib::ConvertError& e ) { + // ignore + } + } +} + + } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h index cd9523036..fa8edda85 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.h +++ b/src/ui/dialog/filedialogimpl-gtkmm.h @@ -562,6 +562,130 @@ private: Glib::ustring myFilename; }; + + +/*######################################################################### +### F I L E D I A L O G E X P O R T B A S E C L A S S +#########################################################################*/ + +/** + * This class is the base implementation for export to OCAL. + */ +class FileDialogExportBase : public Gtk::Dialog +{ +public: + + /** + * + */ + FileDialogExportBase(const Glib::ustring &title) : Gtk::Dialog(title,true) + {} + /* + * + */ + virtual ~FileDialogExportBase() + {} + +protected: + void cleanup( bool showConfirmed ); + + //Glib::ustring preferenceBase; + /** + * What type of 'open' are we? (open, import, place, etc) + */ + FileDialogType dialogType; +}; + + + + +//######################################################################## +//# F I L E E X P O R T T O O C A L +//######################################################################## + + + +/** + * Our implementation of the FileExportToOCALDialog interface. + */ +class FileExportToOCALDialogImpl : public FileExportToOCALDialog, public FileDialogExportBase +{ + +public: + FileExportToOCALDialogImpl(Gtk::Window& parentWindow, + FileDialogType fileTypes, + const Glib::ustring &title, + const Glib::ustring &default_key); + + virtual ~FileExportToOCALDialogImpl(); + + bool show(); + + Inkscape::Extension::Extension *getSelectionType(); + virtual void setSelectionType( Inkscape::Extension::Extension * key ); + + Glib::ustring getFilename(); + + Glib::ustring myFilename; + + void change_title(const Glib::ustring& title); + void updateNameAndExtension(); + +private: + + /** + * Fix to allow the user to type the file name + */ + Gtk::Entry *fileNameEntry; + + + /** + * Allow the specification of the output file type + */ + Gtk::ComboBoxText fileTypeComboBox; + + + /** + * Data mirror of the combo box + */ + std::vector fileTypes; + + //# Child widgets + Gtk::HBox childBox; + Gtk::VBox checksBox; + Gtk::HBox fileBox; + + Gtk::CheckButton fileTypeCheckbox; + + /** + * Callback for user input into fileNameEntry + */ + void fileTypeChangedCallback(); + + /** + * Create a filter menu for this type of dialog + */ + void createFileTypeMenu(); + + + /** + * The extension to use to write this file + */ + Inkscape::Extension::Extension *extension; + + /** + * Callback for user input into fileNameEntry + */ + void fileNameEntryChangedCallback(); + + /** + * List of known file extensions. + */ + std::set knownExtensions; +}; + + + } } } -- 2.30.2