diff options
| author | Andrew rugby471@gmail.com <> | 2011-03-24 19:14:21 +0000 |
|---|---|---|
| committer | Andrew rugby471@gmail.com <> | 2011-03-24 19:14:21 +0000 |
| commit | 002481162f050709a125e38dc60145ef77c10c98 (patch) | |
| tree | 8ab6929749e954648e2aae51992eefa94319babe /src | |
| parent | Split OCALDialog code in fill.cpp into two, so we can have async stuff working (diff) | |
| download | inkscape-002481162f050709a125e38dc60145ef77c10c98.tar.gz inkscape-002481162f050709a125e38dc60145ef77c10c98.zip | |
Made dialog's state persistant
Cleanup of code
Made download of image work
Put all images into a /tmp/openclipart directory
Use GUID for filename
(bzr r10092.1.18)
Diffstat (limited to 'src')
| -rw-r--r-- | src/file.cpp | 26 | ||||
| -rw-r--r-- | src/file.h | 3 | ||||
| -rw-r--r-- | src/io/sys.cpp | 9 | ||||
| -rw-r--r-- | src/io/sys.h | 2 | ||||
| -rw-r--r-- | src/ui/dialog/ocaldialogs.cpp | 236 | ||||
| -rw-r--r-- | src/ui/dialog/ocaldialogs.h | 29 |
6 files changed, 195 insertions, 110 deletions
diff --git a/src/file.cpp b/src/file.cpp index bfb10e6d6..cee5280c0 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1113,7 +1113,7 @@ sp_file_import(Gtk::Window &parentWindow) return; } - //# Get file name and extension type + // Get file name and extension type Glib::ustring fileName = importDialogInstance->getFilename(); Inkscape::Extension::Extension *selection = importDialogInstance->getSelectionType(); @@ -1440,16 +1440,17 @@ sp_file_export_to_ocal(Gtk::Window &parentWindow) ## I M P O R T F R O M O C A L ######################*/ +Inkscape::UI::Dialog::OCAL::ImportDialog* import_ocal_dialog = NULL; + /** * Display an ImportFromOcal Dialog, and the selected document from OCAL */ -void on_import_from_ocal_response(Glib::ustring filename, - Inkscape::UI::Dialog::OCAL::ImportDialog* import_dialog) +void on_import_from_ocal_response(Glib::ustring filename) { SPDocument *doc = SP_ACTIVE_DOCUMENT; if (!filename.empty()) { - Inkscape::Extension::Extension *selection = import_dialog->get_selection_type(); + Inkscape::Extension::Extension *selection = import_ocal_dialog->get_selection_type(); file_import(doc, filename, selection); } } @@ -1463,24 +1464,19 @@ sp_file_import_from_ocal(Gtk::Window &parent_window) if (!doc) return; - Inkscape::UI::Dialog::OCAL::ImportDialog* import_dialog = NULL; - - if (!import_dialog) { - import_dialog = new + if (import_ocal_dialog == NULL) { + import_ocal_dialog = new Inkscape::UI::Dialog::OCAL::ImportDialog( parent_window, import_path, Inkscape::UI::Dialog::IMPORT_TYPES, (char const *)_("Import From Open Clip Art Library")); - } - import_dialog->signal_response().connect( - sigc::bind<Inkscape::UI::Dialog::OCAL::ImportDialog*>( - sigc::ptr_fun(&on_import_from_ocal_response), - import_dialog) - ); + import_ocal_dialog->signal_response().connect( + sigc::ptr_fun(&on_import_from_ocal_response)); + } - import_dialog->show_all(); + import_ocal_dialog->show_all(); } /*###################### diff --git a/src/file.h b/src/file.h index c6f43e905..4a2b1f91f 100644 --- a/src/file.h +++ b/src/file.h @@ -168,8 +168,7 @@ bool sp_file_export_dialog (Gtk::Window &parentWindow); /** * Import a document from OCAL */ -void on_import_from_ocal_response(Glib::ustring filename, - Inkscape::UI::Dialog::OCAL::ImportDialog* import_dialog); +void on_import_from_ocal_response(Glib::ustring filename); /** * Import a document from OCAL diff --git a/src/io/sys.cpp b/src/io/sys.cpp index a68d02707..e7fdfaa2d 100644 --- a/src/io/sys.cpp +++ b/src/io/sys.cpp @@ -365,6 +365,15 @@ gchar* Inkscape::IO::sanitizeString( gchar const * str ) return result; } +/* + * Returns the file extension of a path/filename + */ +Glib::ustring Inkscape::IO::get_file_extension(Glib::ustring path) +{ + Glib::ustring::size_type period_location = path.find_last_of("."); + return path.substr(period_location); +} + /* Local Variables: mode:c++ diff --git a/src/io/sys.h b/src/io/sys.h index 8623f6be9..8ece3b84a 100644 --- a/src/io/sys.h +++ b/src/io/sys.h @@ -61,6 +61,8 @@ void spawn_async_with_pipes (const std::string& working_directory, int* standard_output, int* standard_error); +Glib::ustring get_file_extension(Glib::ustring path); + } } diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 854456e8f..3abce1a0b 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -305,6 +305,15 @@ void StatusWidget::clear() label->hide(); } +void StatusWidget::set_info(Glib::ustring text) +{ + spinner->hide(); + image->show(); + label->show(); + image->set(Gtk::Stock::DIALOG_INFO, Gtk::ICON_SIZE_MENU); + label->set_text(text); +} + void StatusWidget::set_error(Glib::ustring text) { spinner->hide(); @@ -396,7 +405,7 @@ LogoArea::LogoArea() : Gtk::EventBox() std::string logo_path = Glib::build_filename(INKSCAPE_PIXMAPDIR, "OCAL.png"); logo_mask = Cairo::ImageSurface::create_from_png(logo_path); draw_logo = true; - } catch( Cairo::logic_error ) { + } catch(Cairo::logic_error) { logo_mask = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 1,1); draw_logo = false; } @@ -461,13 +470,12 @@ SearchResultList::SearchResultList(guint columns_count, SVGPreview& filesPreview get_column(RESULTS_COLUMN_MARKUP)->add_attribute(*cr_markup, "markup", RESULTS_COLUMN_MARKUP); - get_column(RESULTS_COLUMN_TITLE)->set_visible(false); - get_column(RESULTS_COLUMN_DESCRIPTION)->set_visible(false); - get_column(RESULTS_COLUMN_CREATOR)->set_visible(false); - get_column(RESULTS_COLUMN_DATE)->set_visible(false); - get_column(RESULTS_COLUMN_FILENAME)->set_visible(false); - get_column(RESULTS_COLUMN_URL)->set_visible(false); - get_column(RESULTS_COLUMN_THUMBNAIL_URL)->set_visible(false); + // Hide all columns except for the MARKUP column + for (int i = 0; i < RESULTS_COLUMN_LENGTH; i++) { + if (i != RESULTS_COLUMN_MARKUP) { + get_column(i)->set_visible(false); + } + } } @@ -479,50 +487,9 @@ void ImportDialog::on_button_import_clicked() { int row = posArray[0]; download_image(row); + widget_status->start_process(_("Downloading image...")); } -void ImportDialog::download_image(int row) -{ - // Get Remote File URL - Glib::ustring url = list_results->get_text(row, RESULTS_COLUMN_URL); - file_remote = Gio::File::create_for_uri(url.c_str()); - - // Create local file - const std::string tmptemplate = "ocal-"; - std::string tmpname; - int fd = Inkscape::IO::file_open_tmp(tmpname, tmptemplate); - if (fd < 0) { - widget_status->set_error(_("Could not create image file")); - return; - } - close(fd); - // make sure we don't collide with other users on the same machine - filename_image = tmpname; - filename_image.append("-"); - filename_image.append(list_results->get_text(row, RESULTS_COLUMN_FILENAME)); - // rename based on original image's name, retaining extension - if (rename(tmpname.c_str(), filename_image.c_str()) < 0) { - unlink(tmpname.c_str()); - widget_status->set_error(_("Could not create image file")); - } - file_local = Gio::File::create_for_path(filename_image.c_str()); - - file_remote->copy_async(file_local, sigc::mem_fun(*this, - &ImportDialog::on_thumbnail_image_downloaded), Gio::FILE_COPY_OVERWRITE); -} - -void ImportDialog::on_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result) -{ - bool success = file_thumbnail_remote->copy_finish(result); - - if (success) { - m_signal_response.emit(filename_image); - } else { - filename_image = ""; - } -} - - /* * Callback for cursor chage */ @@ -550,48 +517,125 @@ void ImportDialog::update_preview(int row) Glib::ustring date = list_results->get_text(row, RESULTS_COLUMN_DATE); } -void ImportDialog::download_thumbnail_image(int row) + +std::string ImportDialog::get_temporary_dir(DownloadType type) +{ + std::string ocal_tmp_dir = Glib::build_filename(Glib::get_tmp_dir(), + "openclipart"); + + if (type == TYPE_THUMBNAIL) { + return Glib::build_filename(ocal_tmp_dir, "thumbnails"); + } else { + return Glib::build_filename(ocal_tmp_dir, "images"); + } +} + +void ImportDialog::create_temporary_dirs() +{ + // Make sure the temporary directories exists, if not, create them + std::string ocal_tmp_thumbnail_dir = get_temporary_dir(TYPE_THUMBNAIL); + std::string ocal_tmp_image_dir = get_temporary_dir(TYPE_IMAGE); + + if (!Glib::file_test(ocal_tmp_thumbnail_dir, Glib::FILE_TEST_EXISTS)) { + Glib::RefPtr<Gio::File> directory = Gio::File::create_for_path(ocal_tmp_thumbnail_dir); + directory->make_directory_with_parents(); + } + + if (!Glib::file_test(ocal_tmp_image_dir, Glib::FILE_TEST_EXISTS)) { + Glib::RefPtr<Gio::File> directory = Gio::File::create_for_path(ocal_tmp_image_dir); + directory->make_directory_with_parents(); + } +} + +void ImportDialog::download_image(int row) { // Get Remote File URL - Glib::ustring url = list_results->get_text(row, RESULTS_COLUMN_THUMBNAIL_URL); - file_thumbnail_remote = Gio::File::create_for_uri(url.c_str()); - - // Create local file - const std::string tmptemplate = "ocal-"; - std::string tmpname; - int fd = Inkscape::IO::file_open_tmp(tmpname, tmptemplate); - if (fd < 0) { - widget_status->set_error(_("Could not create thumbnail file")); - return; + Glib::ustring url = list_results->get_text(row, RESULTS_COLUMN_URL); + Glib::RefPtr<Gio::File> file_remote = Gio::File::create_for_uri(url.c_str()); + + std::string ocal_tmp_image_dir = get_temporary_dir(TYPE_IMAGE); + + // Make a unique filename for the clipart, in the form 'GUID.extension' + Glib::ustring guid = list_results->get_text(row, RESULTS_COLUMN_GUID); + Glib::ustring original_filename = list_results->get_text(row, RESULTS_COLUMN_FILENAME); + Glib::ustring extension = Inkscape::IO::get_file_extension(original_filename); + + Glib::ustring filename = Glib::ustring::compose("%1%2", guid, extension); + std::string path = Glib::build_filename(ocal_tmp_image_dir, filename.c_str()); + + // Download it asynchronously + Glib::RefPtr<Gio::File> file_local = Gio::File::create_for_path(path); + file_remote->copy_async(file_local, + sigc::bind<Glib::RefPtr<Gio::File> , Glib::ustring>( + sigc::mem_fun(*this, &ImportDialog::on_image_downloaded), + file_remote, path), + Gio::FILE_COPY_OVERWRITE); +} + +void ImportDialog::on_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result, + Glib::RefPtr<Gio::File> file_remote, Glib::ustring path) +{ + // Try to show the the thumbnail in the Preview widget + bool success = file_remote->copy_finish(result); + + try { + widget_status->clear(); + m_signal_response.emit(path); + widget_status->set_info(_("Clipart downloaded successfully")); + } catch(Glib::Error) { + success = false; } - close(fd); - // make sure we don't collide with other users on the same machine - filename_thumbnail = tmpname; - filename_thumbnail.append("-"); - filename_thumbnail.append(list_results->get_text(row, RESULTS_COLUMN_FILENAME)); - // rename based on original image's name, retaining extension - if (rename(tmpname.c_str(), filename_thumbnail.c_str()) < 0) { - unlink(tmpname.c_str()); - widget_status->set_error(_("Could not create thumbnail file")); + + // If anything went wrong, show an error message + if (!success) { + widget_status->set_error(_("Could not download image")); + path = ""; } - file_thumbnail_local = Gio::File::create_for_path(filename_thumbnail.c_str()); +} + +void ImportDialog::download_thumbnail_image(int row) +{ + // Get Remote File URL + Glib::ustring url = list_results->get_text(row, RESULTS_COLUMN_THUMBNAIL_URL); + Glib::RefPtr<Gio::File> file_thumbnail_remote = Gio::File::create_for_uri(url); + + std::string ocal_tmp_thumbnail_dir = get_temporary_dir(TYPE_THUMBNAIL); + + // Make a unique filename for the clipart, in the form 'GUID.extension' + Glib::ustring guid = list_results->get_text(row, RESULTS_COLUMN_GUID); + Glib::ustring original_filename = list_results->get_text(row, RESULTS_COLUMN_THUMBNAIL_FILENAME); + Glib::ustring extension = Inkscape::IO::get_file_extension(original_filename); - file_thumbnail_remote->copy_async(file_thumbnail_local, sigc::mem_fun(*this, - &ImportDialog::on_thumbnail_image_downloaded), Gio::FILE_COPY_OVERWRITE); + Glib::ustring filename_thumbnail = Glib::ustring::compose("%1%2", guid, extension); + std::string path_thumbnail = Glib::build_filename(ocal_tmp_thumbnail_dir, filename_thumbnail.c_str()); + + // Download it asynchronously + Glib::RefPtr<Gio::File> file_thumbnail_local = Gio::File::create_for_path(path_thumbnail); + file_thumbnail_remote->copy_async(file_thumbnail_local, + sigc::bind<Glib::RefPtr<Gio::File> , Glib::ustring>( + sigc::mem_fun(*this, &ImportDialog::on_thumbnail_image_downloaded), + file_thumbnail_remote, path_thumbnail), + Gio::FILE_COPY_OVERWRITE); } -/* - * Callback for row activated - */ -void ImportDialog::on_thumbnail_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result) + +void ImportDialog::on_thumbnail_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result, + Glib::RefPtr<Gio::File> file_thumbnail_remote, Glib::ustring path_thumbnail) { + // Try to show the the thumbnail in the Preview widget bool success = file_thumbnail_remote->copy_finish(result); - if (success) { - preview_files->showImage(filename_thumbnail); - } else { + try { + widget_status->clear(); + preview_files->showImage(path_thumbnail); + } catch(Glib::Error) { + success = false; + } + + // If anything went wrong, show an error message + if (!success) { widget_status->set_error(_("Could not download thumbnail file")); - filename_thumbnail = ""; + path_thumbnail = ""; } } @@ -674,10 +718,21 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) { xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, (xmlChar*) "url"); char* thumbnail_url = (char*) xml_thumbnail_url; + char* thumbnail_filename = g_path_get_basename(thumbnail_url); set_text(row_num, RESULTS_COLUMN_THUMBNAIL_URL, thumbnail_url); + set_text(row_num, RESULTS_COLUMN_THUMBNAIL_FILENAME, thumbnail_filename); xmlFree(xml_thumbnail_url); } + else if (!strcmp((const char*)cur_node->name, "guid")) + { + xmlChar *xml_guid = xmlNodeGetContent(cur_node); + char* guid_url = (char*) xml_guid; + char* guid = g_path_get_basename(guid_url); + + set_text(row_num, RESULTS_COLUMN_GUID, guid); + xmlFree(xml_guid); + } } populate_from_xml(cur_node->children); } @@ -691,6 +746,12 @@ void ImportDialog::on_button_search_clicked() on_entry_search_activated(); } + +void ImportDialog::on_button_close_clicked() +{ + hide_all(); +} + /** * Callback for user input into entry_search */ @@ -817,6 +878,7 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, preview_files = new SVGPreview(); /// Add the buttons in the bottom of the dialog button_cancel = new Gtk::Button(Gtk::Stock::CANCEL); + button_close = new Gtk::Button(_("Close")); button_import = new Gtk::Button(_("Import")); list_results = new SearchResultList(RESULTS_COLUMN_LENGTH, *preview_files, *label_description, *button_import); @@ -834,6 +896,7 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, hbox_bottom->pack_start(*widget_status, true, true); hbox_bottom->pack_start(*hbuttonbox_bottom, true, true); hbuttonbox_bottom->pack_start(*button_cancel, false, false); + hbuttonbox_bottom->pack_start(*button_close, false, false); hbuttonbox_bottom->pack_start(*button_import, false, false); hbuttonbox_search->pack_start(*button_search, false, false); hbox_tags.pack_start(*entry_search, true, true); @@ -851,7 +914,7 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, vbox->set_spacing(12); hbuttonbox_bottom->set_spacing(6); hbuttonbox_bottom->set_layout(Gtk::BUTTONBOX_END); - button_import->set_sensitive(false); + //button_import->set_sensitive(false); entry_search->set_max_length(255); hbox_tags.set_spacing(6); preview_files->showNoPreview(); @@ -870,12 +933,18 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, label_not_found->set_size_request(260, -1); notebook_content->set_show_tabs(false); notebook_content->set_show_border(false); + button_cancel->set_no_show_all(true); + button_close->set_no_show_all(true); + button_close->show(); + button_cancel->hide(); // Signals entry_search->signal_activate().connect( sigc::mem_fun(*this, &ImportDialog::on_entry_search_activated)); button_import->signal_clicked().connect( sigc::mem_fun(*this, &ImportDialog::on_button_import_clicked)); + button_close->signal_clicked().connect( + sigc::mem_fun(*this, &ImportDialog::on_button_close_clicked)); button_search->signal_clicked().connect( sigc::mem_fun(*this, &ImportDialog::on_button_search_clicked)); list_results->signal_cursor_changed().connect( @@ -885,6 +954,9 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, show_all_children(); entry_search->grab_focus(); + + // Make sure the temporary directories needed later exist + create_temporary_dirs(); } /** diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index 5085ad232..0850c64e1 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -82,9 +82,7 @@ public: FileDialogBase(const Glib::ustring &title, Gtk::Window& parent) : Gtk::Window(Gtk::WINDOW_TOPLEVEL) { set_title(title); - - //set_modal(TRUE); - //sp_transientize((GtkWidget*) gobj()); + sp_transientize((GtkWidget*) gobj()); } /* @@ -275,6 +273,7 @@ public: void clear(); void set_error(Glib::ustring text); + void set_info(Glib::ustring text); void start_process(Glib::ustring text); void end_process(); @@ -329,8 +328,10 @@ enum { RESULTS_COLUMN_CREATOR, RESULTS_COLUMN_DATE, RESULTS_COLUMN_FILENAME, + RESULTS_COLUMN_THUMBNAIL_FILENAME, RESULTS_COLUMN_URL, RESULTS_COLUMN_THUMBNAIL_URL, + RESULTS_COLUMN_GUID, RESULTS_COLUMN_LENGTH, }; @@ -340,6 +341,11 @@ enum { NOTEBOOK_PAGE_NOT_FOUND, }; +enum DownloadType { + TYPE_THUMBNAIL, + TYPE_IMAGE, +}; + /** * The TreeView which holds the search results */ @@ -402,6 +408,7 @@ private: Gtk::Label *label_description; Gtk::Button *button_search; Gtk::Button *button_import; + Gtk::Button *button_close; Gtk::Button *button_cancel; StatusWidget *widget_status; @@ -418,24 +425,24 @@ private: Glib::ustring xml_uri; char xml_buffer[8192]; - // File - Glib::RefPtr<Gio::File> file_local; - Glib::RefPtr<Gio::File> file_remote; - Glib::RefPtr<Gio::File> file_thumbnail_local; - Glib::RefPtr<Gio::File> file_thumbnail_remote; - void update_label_no_search_results(); void update_preview(int row); void on_list_results_cursor_changed(); void download_thumbnail_image(int row); - void on_thumbnail_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result); + void on_thumbnail_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result, + Glib::RefPtr<Gio::File> file_thumbnail_remote, Glib::ustring path_thumbnail); void download_image(int row); - void on_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result); + void on_image_downloaded(const Glib::RefPtr<Gio::AsyncResult>& result, + Glib::RefPtr<Gio::File> file_remote, Glib::ustring filename_image); void on_list_results_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); void on_button_import_clicked(); + void on_button_close_clicked(); + void on_button_cancel_clicked(); void on_button_search_clicked(); void on_entry_search_activated(); void on_xml_file_read(const Glib::RefPtr<Gio::AsyncResult>& result); + void create_temporary_dirs(); + std::string get_temporary_dir(DownloadType type); /** |
