X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fui%2Fdialog%2Focaldialogs.cpp;h=2ae7d6989f05a76ed3ad5b386402d8f31ffcaee6;hb=5d7c0d9429969cd5c5cd253e48a5fbd602c3e196;hp=ae2dbd315043299c5f2e152cdfe333ca25369cc0;hpb=83965d687aa02620e79151c91948d313bda9cbf1;p=inkscape.git diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index ae2dbd315..2ae7d6989 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1,7 +1,7 @@ -/** - * Implementation of the ocal dialog interfaces defined in ocaldialog.h - * - * Authors: +/** @file + * @brief Open Clip Art Library integration dialogs - implementation + */ +/* Authors: * Bruno Dilly * Other dudes from The Inkscape Organization * @@ -14,11 +14,18 @@ # include #endif +#include // rename() +#include // close() +#include // errno +#include // strerror() + #include "ocaldialogs.h" #include "filedialogimpl-gtkmm.h" #include "interface.h" #include "gc-core.h" #include +#include "io/sys.h" +#include "preferences.h" namespace Inkscape { @@ -31,63 +38,11 @@ namespace Dialog //# 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) -{ - FileExportToOCALDialog *dialog = new FileExportToOCALDialogImpl(parentWindow, fileTypes, title); - return dialog; -} - -//######################################################################## -//# F I L E E X P O R T T O O C A L P A S S W O R D -//######################################################################## - - -/** - * Public factory method. Used in file.cpp - */ - -FileExportToOCALPasswordDialog *FileExportToOCALPasswordDialog::create(Gtk::Window& parentWindow, - const Glib::ustring &title) -{ - FileExportToOCALPasswordDialog *dialog = new FileExportToOCALPasswordDialogImpl(parentWindow, title); - 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; -} - - -//######################################################################## -//# F I L E E X P O R T T O O C A L -//######################################################################## - - - /** * Callback for fileNameEntry widget */ -void FileExportToOCALDialogImpl::fileNameEntryChangedCallback() +/* +void FileExportToOCALDialog::fileNameEntryChangedCallback() { if (!fileNameEntry) return; @@ -99,29 +54,32 @@ void FileExportToOCALDialogImpl::fileNameEntryChangedCallback() myFilename = fileName; response(Gtk::RESPONSE_OK); } - - - - +*/ /** * Constructor */ -FileExportToOCALDialogImpl::FileExportToOCALDialogImpl(Gtk::Window &parentWindow, +/* +FileExportToOCALDialog::FileExportToOCALDialog(Gtk::Window &parentWindow, FileDialogType fileTypes, const Glib::ustring &title) : - FileDialogOCALBase(title) + FileDialogOCALBase(title, parentWindow) { - /* +*/ + /* * 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(); @@ -144,7 +102,7 @@ FileExportToOCALDialogImpl::FileExportToOCALDialogImpl(Gtk::Window &parentWindow //Catch when user hits [return] on the text field fileNameEntry = entries[0]; fileNameEntry->signal_activate().connect( - sigc::mem_fun(*this, &FileExportToOCALDialogImpl::fileNameEntryChangedCallback) ); + sigc::mem_fun(*this, &FileExportToOCALDialog::fileNameEntryChangedCallback) ); } add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); @@ -152,21 +110,21 @@ FileExportToOCALDialogImpl::FileExportToOCALDialogImpl(Gtk::Window &parentWindow show_all_children(); } - - - +*/ /** * Destructor */ -FileExportToOCALDialogImpl::~FileExportToOCALDialogImpl() +/* +FileExportToOCALDialog::~FileExportToOCALDialog() { } - +*/ /** * Show this dialog modally. Return true if user hits [OK] */ +/* bool -FileExportToOCALDialogImpl::show() +FileExportToOCALDialog::show() { set_modal (TRUE); //Window sp_transientize((GtkWidget *)gobj()); //Make transient @@ -182,12 +140,13 @@ FileExportToOCALDialogImpl::show() return FALSE; } } - +*/ /** * Get the file name chosen by the user. Valid after an [OK] */ +/* Glib::ustring -FileExportToOCALDialogImpl::getFilename() +FileExportToOCALDialog::getFilename() { myFilename = fileNameEntry->get_text(); if (!Glib::get_charset()) //If we are not utf8 @@ -198,11 +157,11 @@ FileExportToOCALDialogImpl::getFilename() void -FileExportToOCALDialogImpl::change_title(const Glib::ustring& title) +FileExportToOCALDialog::change_title(const Glib::ustring& title) { this->set_title(title); } - +*/ //######################################################################## //# F I L E E X P O R T T O O C A L P A S S W O R D @@ -212,14 +171,17 @@ FileExportToOCALDialogImpl::change_title(const Glib::ustring& title) /** * Constructor */ -FileExportToOCALPasswordDialogImpl::FileExportToOCALPasswordDialogImpl(Gtk::Window &parentWindow, - const Glib::ustring &title) : FileDialogOCALBase(title) +/* +FileExportToOCALPasswordDialog::FileExportToOCALPasswordDialog(Gtk::Window &parentWindow, + const Glib::ustring &title) : FileDialogOCALBase(title, parentWindow) { +*/ /* * Start Taking the vertical Box and putting 2 Labels * and 2 Entries to take the username and password */ /* No username and password to start out with */ +/* myUsername = ""; myPassword = ""; @@ -246,26 +208,28 @@ FileExportToOCALPasswordDialogImpl::FileExportToOCALPasswordDialogImpl(Gtk::Wind passBox.pack_start(*passLabel); passBox.pack_start(*passwordEntry, Gtk::PACK_EXPAND_WIDGET, 3); vbox->pack_start(passBox); - + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); set_default(*add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK)); show_all_children(); } - +*/ /** * Destructor */ -FileExportToOCALPasswordDialogImpl::~FileExportToOCALPasswordDialogImpl() +/* +FileExportToOCALPasswordDialog::~FileExportToOCALPasswordDialog() { } - +*/ /** * Show this dialog modally. Return true if user hits [OK] */ +/* bool -FileExportToOCALPasswordDialogImpl::show() +FileExportToOCALPasswordDialog::show() { set_modal (TRUE); //Window sp_transientize((GtkWidget *)gobj()); //Make transient @@ -281,33 +245,35 @@ FileExportToOCALPasswordDialogImpl::show() return FALSE; } } - +*/ /** * Get the username. Valid after an [OK] */ +/* Glib::ustring -FileExportToOCALPasswordDialogImpl::getUsername() +FileExportToOCALPasswordDialog::getUsername() { myUsername = usernameEntry->get_text(); return myUsername; } - +*/ /** * Get the password. Valid after an [OK] */ +/* Glib::ustring -FileExportToOCALPasswordDialogImpl::getPassword() +FileExportToOCALPasswordDialog::getPassword() { myPassword = passwordEntry->get_text(); return myPassword; } void -FileExportToOCALPasswordDialogImpl::change_title(const Glib::ustring& title) +FileExportToOCALPasswordDialog::change_title(const Glib::ustring& title) { this->set_title(title); } - +*/ //######################################################################### //### F I L E I M P O R T F R O M O C A L @@ -318,14 +284,10 @@ FileExportToOCALPasswordDialogImpl::change_title(const Glib::ustring& title) */ void FileListViewText::on_cursor_changed() { - // create file path - myFilename = Glib::get_tmp_dir(); - myFilename.append(G_DIR_SEPARATOR_S); std::vector pathlist; pathlist = this->get_selection()->get_selected_rows(); std::vector posArray(1); posArray = pathlist[0].get_indices(); - myFilename.append(get_text(posArray[0], 2)); #ifdef WITH_GNOME_VFS gnome_vfs_init(); @@ -335,12 +297,37 @@ void FileListViewText::on_cursor_changed() GnomeVFSFileSize bytes_written; GnomeVFSResult result; guint8 buffer[8192]; + Glib::ustring fileUrl; + + // FIXME: this would be better as a per-user OCAL cache of files + // instead of filling /tmp with downloads. + // + // create file path + const std::string tmptemplate = "ocal-"; + std::string tmpname; + int fd = Inkscape::IO::file_open_tmp(tmpname, tmptemplate); + if (fd<0) { + g_warning("Error creating temp file"); + return; + } + close(fd); + // make sure we don't collide with other users on the same machine + myFilename = tmpname; + myFilename.append("-"); + myFilename.append(get_text(posArray[0], 2)); + // rename based on original image's name, retaining extension + if (rename(tmpname.c_str(),myFilename.c_str())<0) { + unlink(tmpname.c_str()); + g_warning("Error creating destination file '%s': %s", myFilename.c_str(), strerror(errno)); + goto failquit; + } //get file url - Glib::ustring fileUrl = get_text(posArray[0], 1); //http url + fileUrl = get_text(posArray[0], 1); //http url + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); //Glib::ustring fileUrl = "dav://"; //dav url - //fileUrl.append(prefs_get_string_attribute("options.ocalurl", "str")); + //fileUrl.append(prefs->getString("/options/ocalurl/str")); //fileUrl.append("/dav.php/"); //fileUrl.append(get_text(posArray[0], 3)); //author dir //fileUrl.append("/"); @@ -349,8 +336,6 @@ void FileListViewText::on_cursor_changed() 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); @@ -358,13 +343,13 @@ void FileListViewText::on_cursor_changed() 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; + g_warning("Error creating temp file '%s': %s", myFilename.c_str(), gnome_vfs_result_to_string(result)); + goto fail; } 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; + goto fail; } // copy the file while (1) { @@ -376,33 +361,34 @@ void FileListViewText::on_cursor_changed() } if (result != GNOME_VFS_OK) { g_warning("%s", gnome_vfs_result_to_string(result)); - return; + goto fail; } 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; + goto fail; } if (bytes_read != bytes_written){ g_warning("Bytes read not equal to bytes written"); - return; + goto fail; } } } - else - { - gnome_vfs_close(to_handle); - } myPreview->showImage(myFilename); myLabel->set_text(get_text(posArray[0], 4)); #endif + return; +fail: + unlink(myFilename.c_str()); +failquit: + myFilename = ""; } /* * Callback for row activated */ -void FileListViewText::on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) +void FileListViewText::on_row_activated(const Gtk::TreeModel::Path& /*path*/, Gtk::TreeViewColumn* /*column*/) { this->on_cursor_changed(); myButton->activate(); @@ -417,21 +403,47 @@ Glib::ustring FileListViewText::getFilename() return myFilename; } + +#ifdef WITH_GNOME_VFS +/** + * Read callback for xmlReadIO(), used below + */ +static int vfs_read_callback (GnomeVFSHandle *handle, char* buf, int nb) +{ + GnomeVFSFileSize ndone; + GnomeVFSResult result; + + result = gnome_vfs_read (handle, buf, nb, &ndone); + + if (result == GNOME_VFS_OK) { + return (int)ndone; + } else { + if (result != GNOME_VFS_ERROR_EOF) { + sp_ui_error_dialog(_("Error while reading the Open Clip Art RSS feed")); + g_warning("%s\n", gnome_vfs_result_to_string(result)); + } + return -1; + } +} +#endif + + /** * Callback for user input into searchTagEntry */ -void FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback() +void FileImportFromOCALDialog::searchTagEntryChangedCallback() { if (!searchTagEntry) return; notFoundLabel->hide(); descriptionLabel->set_text(""); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring searchTag = searchTagEntry->get_text(); // create the ocal uri to get rss feed Glib::ustring uri = "http://"; - uri.append(prefs_get_string_attribute("options.ocalurl", "str")); + uri.append(prefs->getString("/options/ocalurl/str")); uri.append("/media/feed/rss/"); uri.append(searchTag); if (!Glib::get_charset()) //If we are not utf8 @@ -439,76 +451,32 @@ void FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback() #ifdef WITH_GNOME_VFS - // get the rss feed + // open 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 server name is correct in Configuration->Misc (e.g.: openclipart.org)")); + sp_ui_error_dialog(_("Failed to receive the Open Clip Art Library RSS feed. Verify if the server name is correct in Configuration->Import/Export (e.g.: openclipart.org)")); 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 + LIBXML_TEST_VERSION xmlDoc *doc = NULL; xmlNode *root_element = NULL; - doc = xmlReadFile(fileName.c_str(), NULL, 0); + + doc = xmlReadIO ((xmlInputReadCallback) vfs_read_callback, + (xmlInputCloseCallback) gnome_vfs_close, from_handle, uri.c_str(), NULL, + XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR); if (doc == NULL) { - g_warning("Failed to parse %s\n", fileName.c_str()); - return; + sp_ui_error_dialog(_("Server supplied malformed Clip Art feed")); + g_warning("Failed to parse %s\n", uri.c_str()); + return; } - + // get the root element node root_element = xmlDocGetRootElement(doc); @@ -532,14 +500,15 @@ void FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback() // free the global variables that may have been allocated by the parser xmlCleanupParser(); return; -#endif +#endif } + /** - * Prints the names of the all the xml elements + * 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) +void FileImportFromOCALDialog::print_xml_element_names(xmlNode * a_node) { xmlNode *cur_node = NULL; guint row_num = 0; @@ -581,11 +550,11 @@ void FileImportFromOCALDialogImplGtk::print_xml_element_names(xmlNode * a_node) /** * Constructor. Not called directly. Use the factory. */ -FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title) : - FileDialogOCALBase(title) +FileImportFromOCALDialog::FileImportFromOCALDialog(Gtk::Window& parentWindow, + const Glib::ustring &/*dir*/, + FileDialogType fileTypes, + const Glib::ustring &title) : + FileDialogOCALBase(title, parentWindow) { // Initalize to Autodetect extension = NULL; @@ -594,11 +563,13 @@ FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& pa dialogType = fileTypes; Gtk::VBox *vbox = get_vbox(); - Gtk::Label *tagLabel = new Gtk::Label(_("Search Tag")); + Gtk::Label *tagLabel = new Gtk::Label(_("Search for:")); notFoundLabel = new Gtk::Label(_("No files matched your search")); descriptionLabel = new Gtk::Label(); - descriptionLabel->set_max_width_chars(60); + descriptionLabel->set_max_width_chars(260); + descriptionLabel->set_size_request(500, -1); descriptionLabel->set_single_line_mode(false); + descriptionLabel->set_line_wrap(true); messageBox.pack_start(*notFoundLabel); descriptionBox.pack_start(*descriptionLabel); searchTagEntry = new Gtk::Entry(); @@ -621,7 +592,7 @@ FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& pa 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")); + filesList->set_column_title(0, _("Files found")); listScrolledWindow.set_size_request(400, 180); filesList->get_column(1)->set_visible(false); // file url filesList->get_column(2)->set_visible(false); // tmp file path @@ -629,7 +600,7 @@ FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& pa filesList->get_column(4)->set_visible(false); // file description filesBox.pack_start(listScrolledWindow); filesBox.pack_start(*filesPreview); - vbox->pack_start(tagBox); + vbox->pack_start(tagBox, false, false); vbox->pack_start(messageBox); vbox->pack_start(filesBox); vbox->pack_start(descriptionBox); @@ -644,11 +615,11 @@ FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& pa //Catch when user hits [return] on the text field searchTagEntry = entries[0]; searchTagEntry->signal_activate().connect( - sigc::mem_fun(*this, &FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback)); + sigc::mem_fun(*this, &FileImportFromOCALDialog::searchTagEntryChangedCallback)); } searchButton->signal_clicked().connect( - sigc::mem_fun(*this, &FileImportFromOCALDialogImplGtk::searchTagEntryChangedCallback)); + sigc::mem_fun(*this, &FileImportFromOCALDialog::searchTagEntryChangedCallback)); show_all_children(); notFoundLabel->hide(); @@ -657,7 +628,7 @@ FileImportFromOCALDialogImplGtk::FileImportFromOCALDialogImplGtk(Gtk::Window& pa /** * Destructor */ -FileImportFromOCALDialogImplGtk::~FileImportFromOCALDialogImplGtk() +FileImportFromOCALDialog::~FileImportFromOCALDialog() { } @@ -666,7 +637,7 @@ FileImportFromOCALDialogImplGtk::~FileImportFromOCALDialogImplGtk() * Show this dialog modally. Return true if user hits [OK] */ bool -FileImportFromOCALDialogImplGtk::show() +FileImportFromOCALDialog::show() { set_modal (TRUE); //Window sp_transientize((GtkWidget *)gobj()); //Make transient @@ -688,7 +659,7 @@ FileImportFromOCALDialogImplGtk::show() * Get the file extension type that was selected by the user. Valid after an [OK] */ Inkscape::Extension::Extension * -FileImportFromOCALDialogImplGtk::getSelectionType() +FileImportFromOCALDialog::getSelectionType() { return extension; } @@ -698,7 +669,7 @@ FileImportFromOCALDialogImplGtk::getSelectionType() * Get the file name chosen by the user. Valid after an [OK] */ Glib::ustring -FileImportFromOCALDialogImplGtk::getFilename (void) +FileImportFromOCALDialog::getFilename (void) { return filesList->getFilename(); }