From 17702c3e7d673070205000a6359403bb920e10aa Mon Sep 17 00:00:00 2001 From: joelholdsworth Date: Sun, 19 Aug 2007 00:29:36 +0000 Subject: [PATCH] Separated the OCAL import and export dialogs into their own source file - ocaldialogs.cpp and ocaldialogs.h --- src/ui/dialog/Makefile_insert | 6 +- src/ui/dialog/filedialog.cpp | 35 -- src/ui/dialog/filedialog.h | 117 ---- src/ui/dialog/filedialogimpl-gtkmm.cpp | 695 +----------------------- src/ui/dialog/filedialogimpl-gtkmm.h | 252 ++------- src/ui/dialog/ocaldialogs.cpp | 704 +++++++++++++++++++++++++ src/ui/dialog/ocaldialogs.h | 251 +++++++++ 7 files changed, 997 insertions(+), 1063 deletions(-) create mode 100644 src/ui/dialog/ocaldialogs.cpp create mode 100644 src/ui/dialog/ocaldialogs.h diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 11011d0c5..d3bb8b62c 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -55,7 +55,9 @@ ui_dialog_libuidialog_a_SOURCES = \ $(inkboard_dialogs) \ ui/dialog/xml-editor.cpp \ ui/dialog/xml-editor.h \ - ui/dialog/aboutbox.cpp \ - ui/dialog/aboutbox.h + ui/dialog/aboutbox.cpp \ + ui/dialog/aboutbox.h \ + ui/dialog/ocaldialogs.cpp \ + ui/dialog/ocaldialogs.h ui/dialog/aboutbox.$(OBJEXT): inkscape_version.h diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index 88ba32679..c3ca49c99 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -76,41 +76,6 @@ FileSaveDialog *FileSaveDialog::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; -} - -//######################################################################### -//### F I L E I M P O R T F R O M O C A L -//######################################################################### - -/** - * Public factory. Called by file.cpp. - */ -FileImportFromOCALDialog *FileImportFromOCALDialog::create(Gtk::Window &parentWindow, - const Glib::ustring &path, - FileDialogType fileTypes, - const Glib::ustring &title) -{ - FileImportFromOCALDialog *dialog = new FileImportFromOCALDialogImplGtk(parentWindow, path, fileTypes, title); - return dialog; -} - - } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index d98c37a28..75c6f0080 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -59,7 +59,6 @@ typedef enum { */ typedef struct FileOpenNativeData_def FileOpenNativeData; - /** * This class provides an implementation-independent API for * file "Open" dialogs. Using a standard interface obviates the need @@ -329,122 +328,6 @@ 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 - - -/** - * This class provides an implementation-independent API for - * file "ImportFromOCAL" dialogs. - */ -class FileImportFromOCALDialog -{ -public: - - - /** - * Constructor .. do not call directly - * @param path the directory where to start searching - * @param fileTypes one of FileDialogTypes - * @param title the title of the dialog - */ - FileImportFromOCALDialog() - {}; - - /** - * Factory. - * @param path the directory where to start searching - * @param fileTypes one of FileDialogTypes - * @param title the title of the dialog - */ - static FileImportFromOCALDialog *create(Gtk::Window& parentWindow, - const Glib::ustring &path, - FileDialogType fileTypes, - const Glib::ustring &title); - - - /** - * Destructor. - * Perform any necessary cleanups. - */ - virtual ~FileImportFromOCALDialog() {}; - - /** - * Show an OpenFile 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 Glib::ustring getFilename () =0; - -}; //FileImportFromOCALDialog - - } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index db6914354..d3016e0f3 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -52,18 +52,7 @@ namespace Dialog //### U T I L I T Y //######################################################################## -/** - \brief A quick function to turn a standard extension into a searchable - pattern for the file dialogs - \param pattern The patter that the extension should be written to - \param in_file_extension The C string that represents the extension - - This function just goes through the string, and takes all characters - and puts a [] so that both are searched and shown in - the file dialog. This function edits the pattern string to make - this happen. -*/ -static void +void fileDialogExtensionToPattern(Glib::ustring &pattern, Glib::ustring &extension) { @@ -84,11 +73,7 @@ fileDialogExtensionToPattern(Glib::ustring &pattern, } } - -/** - * Hack: Find all entry widgets in a container - */ -static void + void findEntryWidgets(Gtk::Container *parent, std::vector &result) { @@ -107,13 +92,7 @@ findEntryWidgets(Gtk::Container *parent, } - - - -/** - * Hack: Find all expander widgets in a container - */ -static void +void findExpanderWidgets(Gtk::Container *parent, std::vector &result) { @@ -1618,673 +1597,7 @@ 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); - - 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) : - FileDialogOCALBase(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::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 - } - } -} - -//######################################################################### -//### F I L E I M P O R T F R O M O C A L -//######################################################################### - -/* - * Callback for row activated - */ -void FileListViewText::on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) -{ - // create file path - myFilename = Glib::get_tmp_dir(); - myFilename.append(G_DIR_SEPARATOR_S); - std::vector posArray(1); - posArray = path.get_indices(); - myFilename.append(get_text(posArray[0], 2)); - -#ifdef WITH_GNOME_VFS - gnome_vfs_init(); - GnomeVFSHandle *from_handle = NULL; - GnomeVFSHandle *to_handle = NULL; - GnomeVFSFileSize bytes_read; - GnomeVFSFileSize bytes_written; - GnomeVFSResult result; - guint8 buffer[8192]; - - //get file url - Glib::ustring fileUrl = get_text(posArray[0], 1); //http url - - //Glib::ustring fileUrl = "dav://"; //dav url - //fileUrl.append(prefs_get_string_attribute("options.ocalurl", "str")); - //fileUrl.append("/dav/"); - //fileUrl.append(get_text(posArray[0], 3)); //author dir - //fileUrl.append("/"); - //fileUrl.append(get_text(posArray[0], 2)); //filename - - if (!Glib::get_charset()) //If we are not utf8 - fileUrl = Glib::filename_to_utf8(fileUrl); - - // verifies if the file wasn't previously downloaded - if(gnome_vfs_open(&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_READ) == GNOME_VFS_ERROR_NOT_FOUND) - { - // open the temp file to receive - result = gnome_vfs_open (&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_WRITE); - if (result == GNOME_VFS_ERROR_NOT_FOUND){ - result = gnome_vfs_create (&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_WRITE, FALSE, GNOME_VFS_PERM_USER_ALL); - } - if (result != GNOME_VFS_OK) { - g_warning("Error creating temp file: %s", gnome_vfs_result_to_string(result)); - return; - } - result = gnome_vfs_open (&from_handle, fileUrl.c_str(), GNOME_VFS_OPEN_READ); - if (result != GNOME_VFS_OK) { - g_warning("Could not find the file in Open Clip Art Library."); - return; - } - // copy the file - while (1) { - result = gnome_vfs_read (from_handle, buffer, 8192, &bytes_read); - if ((result == GNOME_VFS_ERROR_EOF) &&(!bytes_read)){ - result = gnome_vfs_close (from_handle); - result = gnome_vfs_close (to_handle); - break; - } - if (result != GNOME_VFS_OK) { - g_warning("%s", gnome_vfs_result_to_string(result)); - return; - } - result = gnome_vfs_write (to_handle, buffer, bytes_read, &bytes_written); - if (result != GNOME_VFS_OK) { - g_warning("%s", gnome_vfs_result_to_string(result)); - return; - } - if (bytes_read != bytes_written){ - g_warning("Bytes read not equal to bytes written"); - return; - } - } - } - else - { - gnome_vfs_close(to_handle); - } - myPreview->showImage(myFilename); -#endif -} - - -/* - * Returns the selected filename - */ -Glib::ustring FileListViewText::getFilename() -{ - return myFilename; -} - -/** - * Callback for user input into searchTagEntry - */ -void FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback() -{ - if (!searchTagEntry) - return; - - notFoundLabel->hide(); - - Glib::ustring searchTag = searchTagEntry->get_text(); - // create the ocal uri to get rss feed - Glib::ustring uri = "http://www."; - uri.append(prefs_get_string_attribute("options.ocalurl", "str")); - uri.append("/media/feed/rss/"); - uri.append(searchTag); - if (!Glib::get_charset()) //If we are not utf8 - uri = Glib::filename_to_utf8(uri); - -#ifdef WITH_GNOME_VFS - - // get the rss feed - gnome_vfs_init(); - GnomeVFSHandle *from_handle = NULL; - GnomeVFSHandle *to_handle = NULL; - GnomeVFSFileSize bytes_read; - GnomeVFSFileSize bytes_written; - GnomeVFSResult result; - guint8 buffer[8192]; - - // create the temp file name - Glib::ustring fileName = Glib::get_tmp_dir (); - fileName.append(G_DIR_SEPARATOR_S); - fileName.append("ocalfeed.xml"); - - // open the temp file to receive - result = gnome_vfs_open (&to_handle, fileName.c_str(), GNOME_VFS_OPEN_WRITE); - if (result == GNOME_VFS_ERROR_NOT_FOUND){ - result = gnome_vfs_create (&to_handle, fileName.c_str(), GNOME_VFS_OPEN_WRITE, FALSE, GNOME_VFS_PERM_USER_ALL); - } - if (result != GNOME_VFS_OK) { - g_warning("Error creating temp file: %s", gnome_vfs_result_to_string(result)); - return; - } - - // open the rss feed - result = gnome_vfs_open (&from_handle, uri.c_str(), GNOME_VFS_OPEN_READ); - if (result != GNOME_VFS_OK) { - sp_ui_error_dialog(_("Failed to receive the Open Clip Art Library RSS feed. Verify if the URL is correct in Configuration->Misc (e.g.: openclipart.org)")); - //g_warning("Could not find the Open Clip Art Library rss feed. Verify if the OCAL url is correct in Configuration"); - return; - } - - // copy the file - while (1) { - - result = gnome_vfs_read (from_handle, buffer, 8192, &bytes_read); - - if ((result == GNOME_VFS_ERROR_EOF) &&(!bytes_read)){ - result = gnome_vfs_close (from_handle); - result = gnome_vfs_close (to_handle); - break; - } - - if (result != GNOME_VFS_OK) { - g_warning("%s", gnome_vfs_result_to_string(result)); - return; - } - result = gnome_vfs_write (to_handle, buffer, bytes_read, &bytes_written); - if (result != GNOME_VFS_OK) { - g_warning("%s", gnome_vfs_result_to_string(result)); - return; - } - - if (bytes_read != bytes_written){ - g_warning("Bytes read not equal to bytes written"); - return; - } - - } - - // create the resulting xml document tree - // this initialize the library and test mistakes between compiled and shared library used - LIBXML_TEST_VERSION - xmlDoc *doc = NULL; - xmlNode *root_element = NULL; - doc = xmlReadFile(fileName.c_str(), NULL, 0); - if (doc == NULL) { - g_warning("Failed to parse %s\n", fileName.c_str()); - return; - } - - // get the root element node - root_element = xmlDocGetRootElement(doc); - - // clear the fileslist - filesList->clear_items(); - filesList->set_sensitive(false); - - // print all xml the element names - print_xml_element_names(root_element); - - if (filesList->size() == 0) - { - notFoundLabel->show(); - filesList->set_sensitive(false); - } - else - filesList->set_sensitive(true); - - // free the document - xmlFreeDoc(doc); - // free the global variables that may have been allocated by the parser - xmlCleanupParser(); - return; -#endif -} - -/** - * Prints the names of the all the xml elements - * that are siblings or children of a given xml node - */ -void FileImportFromOCALDialogImplGtk::print_xml_element_names(xmlNode * a_node) -{ - xmlNode *cur_node = NULL; - guint row_num = 0; - for (cur_node = a_node; cur_node; cur_node = cur_node->next) { - // get itens information - if (strcmp((const char*)cur_node->name, "rss")) //avoid the root - if (cur_node->type == XML_ELEMENT_NODE && !strcmp((const char*)cur_node->parent->name, "item")) - { - if (!strcmp((const char*)cur_node->name, "title")) - { - xmlChar *title = xmlNodeGetContent(cur_node); - row_num = filesList->append_text((const char*)title); - xmlFree(title); - } -#ifdef WITH_GNOME_VFS - else if (!strcmp((const char*)cur_node->name, "enclosure")) - { - xmlChar *urlattribute = xmlGetProp(cur_node, (xmlChar*)"url"); - filesList->set_text(row_num, 1, (const char*)urlattribute); - gchar *tmp_file; - tmp_file = gnome_vfs_uri_extract_short_path_name(gnome_vfs_uri_new((const char*)urlattribute)); - filesList->set_text(row_num, 2, (const char*)tmp_file); - xmlFree(urlattribute); - } - else if (!strcmp((const char*)cur_node->name, "creator")) - { - filesList->set_text(row_num, 3, (const char*)xmlNodeGetContent(cur_node)); - } -#endif - } - print_xml_element_names(cur_node->children); - } -} - -/** - * Constructor. Not called directly. Use the factory. - */ -FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title) : - FileDialogOCALBase(title) -{ - - // Initalize to Autodetect - extension = NULL; - // No filename to start out with - Glib::ustring searchTag = ""; - - dialogType = fileTypes; - Gtk::VBox *vbox = get_vbox(); - Gtk::Label *tagLabel = new Gtk::Label(_("Search Tag")); - notFoundLabel = new Gtk::Label(_("No files matched your search")); - messageBox.pack_start(*notFoundLabel); - searchTagEntry = new Gtk::Entry(); - searchTagEntry->set_text(searchTag); - searchTagEntry->set_max_length(252); // I am giving the extension approach. - tagBox.pack_start(*tagLabel); - tagBox.pack_start(*searchTagEntry, Gtk::PACK_EXPAND_WIDGET, 3); - filesPreview = new SVGPreview(); - filesPreview->showNoPreview(); - filesList = new FileListViewText(4, *filesPreview); - filesList->set_sensitive(false); - // add the listview inside a ScrolledWindow - listScrolledWindow.add(*filesList); - // only show the scrollbars when they are necessary: - listScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - filesList->set_column_title(0, _("Files Found")); - listScrolledWindow.set_size_request(200, 180); - filesList->get_column(1)->set_visible(false); // file url - filesList->get_column(2)->set_visible(false); // tmp file path - filesList->get_column(3)->set_visible(false); // author dir - filesBox.pack_start(listScrolledWindow); - filesBox.pack_start(*filesPreview); - vbox->pack_start(tagBox); - vbox->pack_start(messageBox); - vbox->pack_start(filesBox); - - //Let's do some customization - searchTagEntry = NULL; - Gtk::Container *cont = get_toplevel(); - std::vector entries; - findEntryWidgets(cont, entries); - if (entries.size() >=1 ) - { - //Catch when user hits [return] on the text field - searchTagEntry = entries[0]; - searchTagEntry->signal_activate().connect( - sigc::mem_fun(*this, &FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback)); - } - - add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - set_default(*add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK)); - - show_all_children(); - notFoundLabel->hide(); -} - -/** - * Destructor - */ -FileImportFromOCALDialogImplGtk::~FileImportFromOCALDialogImplGtk() -{ - -} - -/** - * Show this dialog modally. Return true if user hits [OK] - */ -bool -FileImportFromOCALDialogImplGtk::show() -{ - set_modal (TRUE); //Window - sp_transientize((GtkWidget *)gobj()); //Make transient - gint b = run(); //Dialog - hide(); - - if (b == Gtk::RESPONSE_OK) - { - return TRUE; - } - else - { - return FALSE; - } -} - - -/** - * Get the file extension type that was selected by the user. Valid after an [OK] - */ -Inkscape::Extension::Extension * -FileImportFromOCALDialogImplGtk::getSelectionType() -{ - return extension; -} - - -/** - * Get the file name chosen by the user. Valid after an [OK] - */ -Glib::ustring -FileImportFromOCALDialogImplGtk::getFilename (void) -{ - return filesList->getFilename(); -} - + } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h index 375ec23ad..eb441b709 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.h +++ b/src/ui/dialog/filedialogimpl-gtkmm.h @@ -59,11 +59,36 @@ namespace Inkscape namespace UI { namespace Dialog -{ +{ + +/*######################################################################### +### Utility +#########################################################################*/ +void +fileDialogExtensionToPattern(Glib::ustring &pattern, + Glib::ustring &extension); + +void +findEntryWidgets(Gtk::Container *parent, + std::vector &result); + +void +findExpanderWidgets(Gtk::Container *parent, + std::vector &result); /*######################################################################### ### SVG Preview Widget -#########################################################################*/ +#########################################################################*/ + +class FileType +{ + public: + FileType() {} + ~FileType() {} + Glib::ustring name; + Glib::ustring pattern; + Inkscape::Extension::Extension *extension; +}; /** * Simple class for displaying an SVG file in the "preview widget." @@ -209,7 +234,7 @@ class FileOpenDialogImplGtk : public FileOpenDialog, public FileDialogBaseGtk public: FileOpenDialogImplGtk(Gtk::Window& parentWindow, - const Glib::ustring &dir, + const Glib::ustring &dir, FileDialogType fileTypes, const Glib::ustring &title); @@ -248,17 +273,6 @@ private: }; -class FileType -{ - public: - FileType() {} - ~FileType() {} - Glib::ustring name; - Glib::ustring pattern; - Inkscape::Extension::Extension *extension; -}; - - //######################################################################## //# F I L E S A V E @@ -361,11 +375,11 @@ class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk { public: - FileExportDialogImpl(Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title, - const Glib::ustring &default_key); + FileExportDialogImpl(Gtk::Window& parentWindow, + const Glib::ustring &dir, + FileDialogType fileTypes, + const Glib::ustring &title, + const Glib::ustring &default_key); virtual ~FileExportDialogImpl(); @@ -567,205 +581,7 @@ private: }; - -/*######################################################################### -### F I L E D I A L O G O C A L B A S E C L A S S -#########################################################################*/ - -/** - * This class is the base implementation for export to OCAL. - */ -class FileDialogOCALBase : public Gtk::Dialog -{ -public: - - /** - * - */ - FileDialogOCALBase(const Glib::ustring &title) : Gtk::Dialog(title,true) - {} - /* - * - */ - virtual ~FileDialogOCALBase() - {} - -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 FileDialogOCALBase -{ - -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; -}; - - -//######################################################################### -//### F I L E I M P O R T F R O M O C A L -//######################################################################### - -/** - * Our implementation class for filesListView - */ -class FileListViewText : public Gtk::ListViewText -{ -public: - FileListViewText(guint columns_count, SVGPreview& filesPreview):ListViewText(columns_count) - { - myPreview = &filesPreview; - } - Glib::ustring getFilename(); -protected: - void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); -private: - Glib::ustring myFilename; - SVGPreview *myPreview; -}; - -/** - * Our implementation class for the FileImportFromOCALDialog interface.. - */ -class FileImportFromOCALDialogImplGtk : public FileImportFromOCALDialog, public FileDialogOCALBase -{ -public: - - FileImportFromOCALDialogImplGtk(Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title); - - virtual ~FileImportFromOCALDialogImplGtk(); - - bool show(); - - Inkscape::Extension::Extension *getSelectionType(); - - Glib::ustring getFilename(); - -private: - - /** - * Allow the user to type the tag to be searched - */ - Gtk::Entry *searchTagEntry; - FileListViewText *filesList; - SVGPreview *filesPreview; - Gtk::Label *notFoundLabel; - - // Child widgets - Gtk::HBox tagBox; - Gtk::HBox filesBox; - Gtk::HBox messageBox; - Gtk::ScrolledWindow listScrolledWindow; - Glib::RefPtr selection; - - /** - * Callback for user input into searchTagEntry - */ - void searchTagEntryChangedCallback(); - - - /** - * Prints the names of the all the xml elements - * that are siblings or children of a given xml node - */ - void print_xml_element_names(xmlNode * a_node); - - /** - * The extension to use to write this file - */ - Inkscape::Extension::Extension *extension; -}; - + } } } diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp new file mode 100644 index 000000000..ef65242fc --- /dev/null +++ b/src/ui/dialog/ocaldialogs.cpp @@ -0,0 +1,704 @@ +/** + * Implementation of the OCAL import/export dialogs + * + * Authors: + * Joel Holdsworth + * Bruno Dilly + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2007 Bruno Dilly + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ocaldialogs.h" +#include "dialogs/dialog-events.h" +#include "interface.h" + +#ifdef WITH_GNOME_VFS +# include +#endif + +namespace Inkscape +{ +namespace UI +{ +namespace Dialog +{ + +//######################################################################## +//# F I L E E X P O R T T O O C A L +//######################################################################## + + + +/** + * Callback for fileNameEntry widget + */ +void FileExportToOCALDialog::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); + + myFilename = fileName; + response(Gtk::RESPONSE_OK); +} + + + +/** + * Callback for fileNameEntry widget + */ +void FileExportToOCALDialog::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 FileExportToOCALDialog::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 + */ +FileExportToOCALDialog::FileExportToOCALDialog(Gtk::Window &parentWindow, + const Glib::ustring &title, + const Glib::ustring &default_key) : + FileDialogOCALBase(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 = ""; + + Gtk::VBox *vbox = get_vbox(); + + 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, &FileExportToOCALDialog::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, &FileExportToOCALDialog::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 + */ +FileExportToOCALDialog::~FileExportToOCALDialog() +{ +} + + + +/** + * Show this dialog modally. Return true if user hits [OK] + */ +bool +FileExportToOCALDialog::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 * +FileExportToOCALDialog::getSelectionType() +{ + return extension; +} + +void FileExportToOCALDialog::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 +FileExportToOCALDialog::getFilename() +{ + myFilename = fileNameEntry->get_text(); + updateNameAndExtension(); + return myFilename; +} + + +void +FileExportToOCALDialog::change_title(const Glib::ustring& title) +{ + this->set_title(title); +} + +void FileExportToOCALDialog::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 + } + } +} + +//######################################################################### +//### F I L E I M P O R T F R O M O C A L +//######################################################################### + +/* + * Callback for row activated + */ +void FileListViewText::on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) +{ + // create file path + myFilename = Glib::get_tmp_dir(); + myFilename.append(G_DIR_SEPARATOR_S); + std::vector posArray(1); + posArray = path.get_indices(); + myFilename.append(get_text(posArray[0], 2)); + +#ifdef WITH_GNOME_VFS + gnome_vfs_init(); + GnomeVFSHandle *from_handle = NULL; + GnomeVFSHandle *to_handle = NULL; + GnomeVFSFileSize bytes_read; + GnomeVFSFileSize bytes_written; + GnomeVFSResult result; + guint8 buffer[8192]; + + //get file url + Glib::ustring fileUrl = get_text(posArray[0], 1); //http url + + //Glib::ustring fileUrl = "dav://"; //dav url + //fileUrl.append(prefs_get_string_attribute("options.ocalurl", "str")); + //fileUrl.append("/dav/"); + //fileUrl.append(get_text(posArray[0], 3)); //author dir + //fileUrl.append("/"); + //fileUrl.append(get_text(posArray[0], 2)); //filename + + if (!Glib::get_charset()) //If we are not utf8 + fileUrl = Glib::filename_to_utf8(fileUrl); + + // verifies if the file wasn't previously downloaded + if(gnome_vfs_open(&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_READ) == GNOME_VFS_ERROR_NOT_FOUND) + { + // open the temp file to receive + result = gnome_vfs_open (&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_WRITE); + if (result == GNOME_VFS_ERROR_NOT_FOUND){ + result = gnome_vfs_create (&to_handle, myFilename.c_str(), GNOME_VFS_OPEN_WRITE, FALSE, GNOME_VFS_PERM_USER_ALL); + } + if (result != GNOME_VFS_OK) { + g_warning("Error creating temp file: %s", gnome_vfs_result_to_string(result)); + return; + } + result = gnome_vfs_open (&from_handle, fileUrl.c_str(), GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) { + g_warning("Could not find the file in Open Clip Art Library."); + return; + } + // copy the file + while (1) { + result = gnome_vfs_read (from_handle, buffer, 8192, &bytes_read); + if ((result == GNOME_VFS_ERROR_EOF) &&(!bytes_read)){ + result = gnome_vfs_close (from_handle); + result = gnome_vfs_close (to_handle); + break; + } + if (result != GNOME_VFS_OK) { + g_warning("%s", gnome_vfs_result_to_string(result)); + return; + } + result = gnome_vfs_write (to_handle, buffer, bytes_read, &bytes_written); + if (result != GNOME_VFS_OK) { + g_warning("%s", gnome_vfs_result_to_string(result)); + return; + } + if (bytes_read != bytes_written){ + g_warning("Bytes read not equal to bytes written"); + return; + } + } + } + else + { + gnome_vfs_close(to_handle); + } + myPreview->showImage(myFilename); +#endif +} + + +/* + * Returns the selected filename + */ +Glib::ustring FileListViewText::getFilename() +{ + return myFilename; +} + +/** + * Callback for user input into searchTagEntry + */ +void FileImportFromOCALDialog::searchTagEntryChangedCallback() +{ + if (!searchTagEntry) + return; + + notFoundLabel->hide(); + + Glib::ustring searchTag = searchTagEntry->get_text(); + // create the ocal uri to get rss feed + Glib::ustring uri = "http://www."; + uri.append(prefs_get_string_attribute("options.ocalurl", "str")); + uri.append("/media/feed/rss/"); + uri.append(searchTag); + if (!Glib::get_charset()) //If we are not utf8 + uri = Glib::filename_to_utf8(uri); + +#ifdef WITH_GNOME_VFS + + // get the rss feed + gnome_vfs_init(); + GnomeVFSHandle *from_handle = NULL; + GnomeVFSHandle *to_handle = NULL; + GnomeVFSFileSize bytes_read; + GnomeVFSFileSize bytes_written; + GnomeVFSResult result; + guint8 buffer[8192]; + + // create the temp file name + Glib::ustring fileName = Glib::get_tmp_dir (); + fileName.append(G_DIR_SEPARATOR_S); + fileName.append("ocalfeed.xml"); + + // open the temp file to receive + result = gnome_vfs_open (&to_handle, fileName.c_str(), GNOME_VFS_OPEN_WRITE); + if (result == GNOME_VFS_ERROR_NOT_FOUND){ + result = gnome_vfs_create (&to_handle, fileName.c_str(), GNOME_VFS_OPEN_WRITE, FALSE, GNOME_VFS_PERM_USER_ALL); + } + if (result != GNOME_VFS_OK) { + g_warning("Error creating temp file: %s", gnome_vfs_result_to_string(result)); + return; + } + + // open the rss feed + result = gnome_vfs_open (&from_handle, uri.c_str(), GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) { + sp_ui_error_dialog(_("Failed to receive the Open Clip Art Library RSS feed. Verify if the URL is correct in Configuration->Misc (e.g.: openclipart.org)")); + //g_warning("Could not find the Open Clip Art Library rss feed. Verify if the OCAL url is correct in Configuration"); + return; + } + + // copy the file + while (1) { + + result = gnome_vfs_read (from_handle, buffer, 8192, &bytes_read); + + if ((result == GNOME_VFS_ERROR_EOF) &&(!bytes_read)){ + result = gnome_vfs_close (from_handle); + result = gnome_vfs_close (to_handle); + break; + } + + if (result != GNOME_VFS_OK) { + g_warning("%s", gnome_vfs_result_to_string(result)); + return; + } + result = gnome_vfs_write (to_handle, buffer, bytes_read, &bytes_written); + if (result != GNOME_VFS_OK) { + g_warning("%s", gnome_vfs_result_to_string(result)); + return; + } + + if (bytes_read != bytes_written){ + g_warning("Bytes read not equal to bytes written"); + return; + } + + } + + // create the resulting xml document tree + // this initialize the library and test mistakes between compiled and shared library used + LIBXML_TEST_VERSION + xmlDoc *doc = NULL; + xmlNode *root_element = NULL; + doc = xmlReadFile(fileName.c_str(), NULL, 0); + if (doc == NULL) { + g_warning("Failed to parse %s\n", fileName.c_str()); + return; + } + + // get the root element node + root_element = xmlDocGetRootElement(doc); + + // clear the fileslist + filesList->clear_items(); + filesList->set_sensitive(false); + + // print all xml the element names + print_xml_element_names(root_element); + + if (filesList->size() == 0) + { + notFoundLabel->show(); + filesList->set_sensitive(false); + } + else + filesList->set_sensitive(true); + + // free the document + xmlFreeDoc(doc); + // free the global variables that may have been allocated by the parser + xmlCleanupParser(); + return; +#endif +} + +/** + * Prints the names of the all the xml elements + * that are siblings or children of a given xml node + */ +void FileImportFromOCALDialog::print_xml_element_names(xmlNode * a_node) +{ + xmlNode *cur_node = NULL; + guint row_num = 0; + for (cur_node = a_node; cur_node; cur_node = cur_node->next) { + // get itens information + if (strcmp((const char*)cur_node->name, "rss")) //avoid the root + if (cur_node->type == XML_ELEMENT_NODE && !strcmp((const char*)cur_node->parent->name, "item")) + { + if (!strcmp((const char*)cur_node->name, "title")) + { + xmlChar *title = xmlNodeGetContent(cur_node); + row_num = filesList->append_text((const char*)title); + xmlFree(title); + } +#ifdef WITH_GNOME_VFS + else if (!strcmp((const char*)cur_node->name, "enclosure")) + { + xmlChar *urlattribute = xmlGetProp(cur_node, (xmlChar*)"url"); + filesList->set_text(row_num, 1, (const char*)urlattribute); + gchar *tmp_file; + tmp_file = gnome_vfs_uri_extract_short_path_name(gnome_vfs_uri_new((const char*)urlattribute)); + filesList->set_text(row_num, 2, (const char*)tmp_file); + xmlFree(urlattribute); + } + else if (!strcmp((const char*)cur_node->name, "creator")) + { + filesList->set_text(row_num, 3, (const char*)xmlNodeGetContent(cur_node)); + } +#endif + } + print_xml_element_names(cur_node->children); + } +} + +/** + * Constructor. Not called directly. Use the factory. + */ +FileImportFromOCALDialog::FileImportFromOCALDialog(Gtk::Window& parentWindow, + const Glib::ustring &dir, + const Glib::ustring &title) : + FileDialogOCALBase(title) +{ + + // Initalize to Autodetect + extension = NULL; + // No filename to start out with + Glib::ustring searchTag = ""; + + Gtk::VBox *vbox = get_vbox(); + Gtk::Label *tagLabel = new Gtk::Label(_("Search Tag")); + notFoundLabel = new Gtk::Label(_("No files matched your search")); + messageBox.pack_start(*notFoundLabel); + searchTagEntry = new Gtk::Entry(); + searchTagEntry->set_text(searchTag); + searchTagEntry->set_max_length(252); // I am giving the extension approach. + tagBox.pack_start(*tagLabel); + tagBox.pack_start(*searchTagEntry, Gtk::PACK_EXPAND_WIDGET, 3); + filesPreview = new SVGPreview(); + filesPreview->showNoPreview(); + filesList = new FileListViewText(4, *filesPreview); + filesList->set_sensitive(false); + // add the listview inside a ScrolledWindow + listScrolledWindow.add(*filesList); + // only show the scrollbars when they are necessary: + listScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + filesList->set_column_title(0, _("Files Found")); + listScrolledWindow.set_size_request(200, 180); + filesList->get_column(1)->set_visible(false); // file url + filesList->get_column(2)->set_visible(false); // tmp file path + filesList->get_column(3)->set_visible(false); // author dir + filesBox.pack_start(listScrolledWindow); + filesBox.pack_start(*filesPreview); + vbox->pack_start(tagBox); + vbox->pack_start(messageBox); + vbox->pack_start(filesBox); + + //Let's do some customization + searchTagEntry = NULL; + Gtk::Container *cont = get_toplevel(); + std::vector entries; + findEntryWidgets(cont, entries); + if (entries.size() >=1 ) + { + //Catch when user hits [return] on the text field + searchTagEntry = entries[0]; + searchTagEntry->signal_activate().connect( + sigc::mem_fun(*this, &FileImportFromOCALDialog::searchTagEntryChangedCallback)); + } + + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + set_default(*add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK)); + + show_all_children(); + notFoundLabel->hide(); +} + +/** + * Destructor + */ +FileImportFromOCALDialog::~FileImportFromOCALDialog() +{ + +} + +/** + * Show this dialog modally. Return true if user hits [OK] + */ +bool +FileImportFromOCALDialog::show() +{ + set_modal (TRUE); //Window + sp_transientize((GtkWidget *)gobj()); //Make transient + gint b = run(); //Dialog + hide(); + + if (b == Gtk::RESPONSE_OK) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +/** + * Get the file extension type that was selected by the user. Valid after an [OK] + */ +Inkscape::Extension::Extension * +FileImportFromOCALDialog::getSelectionType() +{ + return extension; +} + + +/** + * Get the file name chosen by the user. Valid after an [OK] + */ +Glib::ustring +FileImportFromOCALDialog::getFilename (void) +{ + return filesList->getFilename(); +} + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h new file mode 100644 index 000000000..91ee54bf8 --- /dev/null +++ b/src/ui/dialog/ocaldialogs.h @@ -0,0 +1,251 @@ +/** + * Implementation of the OCAL import/export dialogs + * + * Authors: + * Joel Holdsworth + * Bruno Dilly + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2007 Bruno Dilly + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "filedialogimpl-gtkmm.h" + +namespace Inkscape +{ +namespace UI +{ +namespace Dialog +{ + +/*######################################################################### +### F I L E D I A L O G O C A L B A S E C L A S S +#########################################################################*/ + +/** + * This class is the base implementation for export to OCAL. + */ +class FileDialogOCALBase : public Gtk::Dialog +{ +public: + + /** + * + */ + FileDialogOCALBase(const Glib::ustring &title) : Gtk::Dialog(title,true) + {} + /* + * + */ + virtual ~FileDialogOCALBase() + {} + +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 FileExportToOCALDialog : public FileDialogOCALBase +{ + +public: + FileExportToOCALDialog(Gtk::Window& parentWindow, + const Glib::ustring &title, + const Glib::ustring &default_key); + + /** + * Destructor. + * Perform any necessary cleanups. + */ + virtual ~FileExportToOCALDialog(); + + bool show(); + + /** + * 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. + */ + 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; +}; + + +//######################################################################### +//### F I L E I M P O R T F R O M O C A L +//######################################################################### + +/** + * Our implementation class for filesListView + */ +class FileListViewText : public Gtk::ListViewText +{ +public: + FileListViewText(guint columns_count, SVGPreview& filesPreview):ListViewText(columns_count) + { + myPreview = &filesPreview; + } + Glib::ustring getFilename(); +protected: + void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); +private: + Glib::ustring myFilename; + SVGPreview *myPreview; +}; + +/** + * Our implementation class for the FileImportFromOCALDialog + */ +class FileImportFromOCALDialog : public FileDialogOCALBase +{ +public: + + FileImportFromOCALDialog(Gtk::Window& parentWindow, + const Glib::ustring &dir, + const Glib::ustring &title); + + /** + * Destructor. + * Perform any necessary cleanups. + */ + virtual ~FileImportFromOCALDialog(); + + /** + * Show an OpenFile file selector. + * @return the selected path if user selected one, else NULL + */ + bool show(); + + /** + * 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. + */ + Inkscape::Extension::Extension *getSelectionType(); + + Glib::ustring getFilename(); + +private: + + /** + * Allow the user to type the tag to be searched + */ + Gtk::Entry *searchTagEntry; + FileListViewText *filesList; + SVGPreview *filesPreview; + Gtk::Label *notFoundLabel; + + // Child widgets + Gtk::HBox tagBox; + Gtk::HBox filesBox; + Gtk::HBox messageBox; + Gtk::ScrolledWindow listScrolledWindow; + Glib::RefPtr selection; + + /** + * Callback for user input into searchTagEntry + */ + void searchTagEntryChangedCallback(); + + + /** + * Prints the names of the all the xml elements + * that are siblings or children of a given xml node + */ + void print_xml_element_names(xmlNode * a_node); + + /** + * The extension to use to write this file + */ + Inkscape::Extension::Extension *extension; +}; + +} +} +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- 2.30.2