diff --git a/resources/images/add_book.svg b/imgsrc/add_book.svg similarity index 100% rename from resources/images/add_book.svg rename to imgsrc/add_book.svg diff --git a/resources/images/arrow-down.svg b/imgsrc/arrow-down.svg similarity index 100% rename from resources/images/arrow-down.svg rename to imgsrc/arrow-down.svg diff --git a/resources/images/arrow-up.svg b/imgsrc/arrow-up.svg similarity index 100% rename from resources/images/arrow-up.svg rename to imgsrc/arrow-up.svg diff --git a/resources/images/auto_author_sort.svg b/imgsrc/auto_author_sort.svg similarity index 100% rename from resources/images/auto_author_sort.svg rename to imgsrc/auto_author_sort.svg diff --git a/resources/images/back.svg b/imgsrc/back.svg similarity index 100% rename from resources/images/back.svg rename to imgsrc/back.svg diff --git a/resources/images/blank.svg b/imgsrc/blank.svg similarity index 100% rename from resources/images/blank.svg rename to imgsrc/blank.svg diff --git a/resources/images/book.svg b/imgsrc/book.svg similarity index 100% rename from resources/images/book.svg rename to imgsrc/book.svg diff --git a/resources/images/bookmarks.svg b/imgsrc/bookmarks.svg similarity index 100% rename from resources/images/bookmarks.svg rename to imgsrc/bookmarks.svg diff --git a/resources/images/books_in_series.svg b/imgsrc/books_in_series.svg similarity index 100% rename from resources/images/books_in_series.svg rename to imgsrc/books_in_series.svg diff --git a/resources/images/catalog.svg b/imgsrc/catalog.svg similarity index 100% rename from resources/images/catalog.svg rename to imgsrc/catalog.svg diff --git a/resources/images/chapters.svg b/imgsrc/chapters.svg similarity index 100% rename from resources/images/chapters.svg rename to imgsrc/chapters.svg diff --git a/resources/images/clear_left.svg b/imgsrc/clear_left.svg similarity index 100% rename from resources/images/clear_left.svg rename to imgsrc/clear_left.svg diff --git a/imgsrc/column.svg b/imgsrc/column.svg new file mode 100644 index 0000000000..ac2f026473 --- /dev/null +++ b/imgsrc/column.svg @@ -0,0 +1,211 @@ + + + +Capitello modanatura modanature moulure mouluresbuildingArchitetto Francesco RollandinArchitetto Francesco RollandinArchitetto Francesco Rollandinimage/svg+xmlen + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/images/config.svg b/imgsrc/config.svg similarity index 100% rename from resources/images/config.svg rename to imgsrc/config.svg diff --git a/resources/images/connect_share.svg b/imgsrc/connect_share.svg similarity index 100% rename from resources/images/connect_share.svg rename to imgsrc/connect_share.svg diff --git a/resources/images/convert.svg b/imgsrc/convert.svg similarity index 100% rename from resources/images/convert.svg rename to imgsrc/convert.svg diff --git a/resources/images/cover_flow.svg b/imgsrc/cover_flow.svg similarity index 100% rename from resources/images/cover_flow.svg rename to imgsrc/cover_flow.svg diff --git a/resources/images/debug.svg b/imgsrc/debug.svg similarity index 100% rename from resources/images/debug.svg rename to imgsrc/debug.svg diff --git a/resources/images/default_cover.svg b/imgsrc/default_cover.svg similarity index 100% rename from resources/images/default_cover.svg rename to imgsrc/default_cover.svg diff --git a/resources/images/devices/folder.svg b/imgsrc/devices/folder.svg similarity index 100% rename from resources/images/devices/folder.svg rename to imgsrc/devices/folder.svg diff --git a/resources/images/dialog_error.svg b/imgsrc/dialog_error.svg similarity index 100% rename from resources/images/dialog_error.svg rename to imgsrc/dialog_error.svg diff --git a/resources/images/dialog_information.svg b/imgsrc/dialog_information.svg similarity index 100% rename from resources/images/dialog_information.svg rename to imgsrc/dialog_information.svg diff --git a/resources/images/dialog_question.svg b/imgsrc/dialog_question.svg similarity index 100% rename from resources/images/dialog_question.svg rename to imgsrc/dialog_question.svg diff --git a/resources/images/dialog_warning.svg b/imgsrc/dialog_warning.svg similarity index 100% rename from resources/images/dialog_warning.svg rename to imgsrc/dialog_warning.svg diff --git a/resources/images/dictionary.svg b/imgsrc/dictionary.svg similarity index 100% rename from resources/images/dictionary.svg rename to imgsrc/dictionary.svg diff --git a/resources/images/document_open.svg b/imgsrc/document_open.svg similarity index 100% rename from resources/images/document_open.svg rename to imgsrc/document_open.svg diff --git a/resources/images/donate.svg b/imgsrc/donate.svg similarity index 100% rename from resources/images/donate.svg rename to imgsrc/donate.svg diff --git a/imgsrc/drawer.svg b/imgsrc/drawer.svg new file mode 100644 index 0000000000..22e54a1537 --- /dev/null +++ b/imgsrc/drawer.svg @@ -0,0 +1,2508 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/images/edit_copy.svg b/imgsrc/edit_copy.svg similarity index 100% rename from resources/images/edit_copy.svg rename to imgsrc/edit_copy.svg diff --git a/resources/images/edit_input.svg b/imgsrc/edit_input.svg similarity index 100% rename from resources/images/edit_input.svg rename to imgsrc/edit_input.svg diff --git a/resources/images/eject.svg b/imgsrc/eject.svg similarity index 100% rename from resources/images/eject.svg rename to imgsrc/eject.svg diff --git a/resources/images/exec.svg b/imgsrc/exec.svg similarity index 100% rename from resources/images/exec.svg rename to imgsrc/exec.svg diff --git a/resources/images/font_size_larger.svg b/imgsrc/font_size_larger.svg similarity index 100% rename from resources/images/font_size_larger.svg rename to imgsrc/font_size_larger.svg diff --git a/resources/images/font_size_smaller.svg b/imgsrc/font_size_smaller.svg similarity index 100% rename from resources/images/font_size_smaller.svg rename to imgsrc/font_size_smaller.svg diff --git a/resources/images/forward.svg b/imgsrc/forward.svg similarity index 100% rename from resources/images/forward.svg rename to imgsrc/forward.svg diff --git a/resources/images/help.svg b/imgsrc/help.svg similarity index 100% rename from resources/images/help.svg rename to imgsrc/help.svg diff --git a/resources/images/jobs.svg b/imgsrc/jobs.svg similarity index 100% rename from resources/images/jobs.svg rename to imgsrc/jobs.svg diff --git a/resources/images/list_remove.svg b/imgsrc/list_remove.svg similarity index 100% rename from resources/images/list_remove.svg rename to imgsrc/list_remove.svg diff --git a/resources/images/lookfeel.svg b/imgsrc/lookfeel.svg similarity index 100% rename from resources/images/lookfeel.svg rename to imgsrc/lookfeel.svg diff --git a/resources/images/mail.svg b/imgsrc/mail.svg similarity index 100% rename from resources/images/mail.svg rename to imgsrc/mail.svg diff --git a/resources/images/merge_books.svg b/imgsrc/merge_books.svg similarity index 100% rename from resources/images/merge_books.svg rename to imgsrc/merge_books.svg diff --git a/resources/images/metadata.svg b/imgsrc/metadata.svg similarity index 100% rename from resources/images/metadata.svg rename to imgsrc/metadata.svg diff --git a/resources/images/mimetypes/bmp.svg b/imgsrc/mimetypes/bmp.svg similarity index 100% rename from resources/images/mimetypes/bmp.svg rename to imgsrc/mimetypes/bmp.svg diff --git a/resources/images/mimetypes/computer.svg b/imgsrc/mimetypes/computer.svg similarity index 100% rename from resources/images/mimetypes/computer.svg rename to imgsrc/mimetypes/computer.svg diff --git a/resources/images/mimetypes/dir.svg b/imgsrc/mimetypes/dir.svg similarity index 100% rename from resources/images/mimetypes/dir.svg rename to imgsrc/mimetypes/dir.svg diff --git a/imgsrc/mimetypes/epub.svg b/imgsrc/mimetypes/epub.svg new file mode 100644 index 0000000000..9f2648db6d --- /dev/null +++ b/imgsrc/mimetypes/epub.svg @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + PUB + e + + diff --git a/imgsrc/mimetypes/fb2.svg b/imgsrc/mimetypes/fb2.svg new file mode 100644 index 0000000000..a88a4a8b8c --- /dev/null +++ b/imgsrc/mimetypes/fb2.svg @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/resources/images/mimetypes/gif.svg b/imgsrc/mimetypes/gif.svg similarity index 100% rename from resources/images/mimetypes/gif.svg rename to imgsrc/mimetypes/gif.svg diff --git a/resources/images/mimetypes/html.svg b/imgsrc/mimetypes/html.svg similarity index 100% rename from resources/images/mimetypes/html.svg rename to imgsrc/mimetypes/html.svg diff --git a/resources/images/mimetypes/jpeg.svg b/imgsrc/mimetypes/jpeg.svg similarity index 100% rename from resources/images/mimetypes/jpeg.svg rename to imgsrc/mimetypes/jpeg.svg diff --git a/resources/images/mimetypes/lit.svg b/imgsrc/mimetypes/lit.svg similarity index 100% rename from resources/images/mimetypes/lit.svg rename to imgsrc/mimetypes/lit.svg diff --git a/resources/images/mimetypes/lrf.svg b/imgsrc/mimetypes/lrf.svg similarity index 100% rename from resources/images/mimetypes/lrf.svg rename to imgsrc/mimetypes/lrf.svg diff --git a/resources/images/mimetypes/lrx.svg b/imgsrc/mimetypes/lrx.svg similarity index 100% rename from resources/images/mimetypes/lrx.svg rename to imgsrc/mimetypes/lrx.svg diff --git a/imgsrc/mimetypes/mobi.svg b/imgsrc/mimetypes/mobi.svg new file mode 100644 index 0000000000..970456b0cb --- /dev/null +++ b/imgsrc/mimetypes/mobi.svg @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + mobi + + + + + diff --git a/resources/images/mimetypes/odt.svg b/imgsrc/mimetypes/odt.svg similarity index 100% rename from resources/images/mimetypes/odt.svg rename to imgsrc/mimetypes/odt.svg diff --git a/resources/images/mimetypes/pdf.svg b/imgsrc/mimetypes/pdf.svg similarity index 100% rename from resources/images/mimetypes/pdf.svg rename to imgsrc/mimetypes/pdf.svg diff --git a/resources/images/mimetypes/png.svg b/imgsrc/mimetypes/png.svg similarity index 100% rename from resources/images/mimetypes/png.svg rename to imgsrc/mimetypes/png.svg diff --git a/resources/images/mimetypes/rar.svg b/imgsrc/mimetypes/rar.svg similarity index 100% rename from resources/images/mimetypes/rar.svg rename to imgsrc/mimetypes/rar.svg diff --git a/resources/images/mimetypes/rtf.svg b/imgsrc/mimetypes/rtf.svg similarity index 100% rename from resources/images/mimetypes/rtf.svg rename to imgsrc/mimetypes/rtf.svg diff --git a/resources/images/mimetypes/svg.svg b/imgsrc/mimetypes/svg.svg similarity index 100% rename from resources/images/mimetypes/svg.svg rename to imgsrc/mimetypes/svg.svg diff --git a/resources/images/mimetypes/txt.svg b/imgsrc/mimetypes/txt.svg similarity index 100% rename from resources/images/mimetypes/txt.svg rename to imgsrc/mimetypes/txt.svg diff --git a/resources/images/mimetypes/unknown.svg b/imgsrc/mimetypes/unknown.svg similarity index 100% rename from resources/images/mimetypes/unknown.svg rename to imgsrc/mimetypes/unknown.svg diff --git a/resources/images/mimetypes/zero.svg b/imgsrc/mimetypes/zero.svg similarity index 100% rename from resources/images/mimetypes/zero.svg rename to imgsrc/mimetypes/zero.svg diff --git a/resources/images/mimetypes/zip.svg b/imgsrc/mimetypes/zip.svg similarity index 100% rename from resources/images/mimetypes/zip.svg rename to imgsrc/mimetypes/zip.svg diff --git a/resources/images/minus.svg b/imgsrc/minus.svg similarity index 100% rename from resources/images/minus.svg rename to imgsrc/minus.svg diff --git a/resources/images/network-server.svg b/imgsrc/network-server.svg similarity index 100% rename from resources/images/network-server.svg rename to imgsrc/network-server.svg diff --git a/resources/images/news.svg b/imgsrc/news.svg similarity index 100% rename from resources/images/news.svg rename to imgsrc/news.svg diff --git a/resources/images/next.svg b/imgsrc/next.svg similarity index 100% rename from resources/images/next.svg rename to imgsrc/next.svg diff --git a/resources/images/ok.svg b/imgsrc/ok.svg similarity index 100% rename from resources/images/ok.svg rename to imgsrc/ok.svg diff --git a/resources/images/page.svg b/imgsrc/page.svg similarity index 100% rename from resources/images/page.svg rename to imgsrc/page.svg diff --git a/resources/images/plugins.svg b/imgsrc/plugins.svg similarity index 100% rename from resources/images/plugins.svg rename to imgsrc/plugins.svg diff --git a/resources/images/plus.svg b/imgsrc/plus.svg similarity index 100% rename from resources/images/plus.svg rename to imgsrc/plus.svg diff --git a/resources/images/previous.svg b/imgsrc/previous.svg similarity index 100% rename from resources/images/previous.svg rename to imgsrc/previous.svg diff --git a/resources/images/print-preview.svg b/imgsrc/print-preview.svg similarity index 100% rename from resources/images/print-preview.svg rename to imgsrc/print-preview.svg diff --git a/resources/images/print.svg b/imgsrc/print.svg similarity index 100% rename from resources/images/print.svg rename to imgsrc/print.svg diff --git a/resources/images/reader.svg b/imgsrc/reader.svg similarity index 100% rename from resources/images/reader.svg rename to imgsrc/reader.svg diff --git a/resources/images/save.svg b/imgsrc/save.svg similarity index 100% rename from resources/images/save.svg rename to imgsrc/save.svg diff --git a/resources/images/scheduler.svg b/imgsrc/scheduler.svg similarity index 100% rename from resources/images/scheduler.svg rename to imgsrc/scheduler.svg diff --git a/resources/images/sd.svg b/imgsrc/sd.svg similarity index 100% rename from resources/images/sd.svg rename to imgsrc/sd.svg diff --git a/resources/images/search.svg b/imgsrc/search.svg similarity index 100% rename from resources/images/search.svg rename to imgsrc/search.svg diff --git a/resources/images/search_add_saved.svg b/imgsrc/search_add_saved.svg similarity index 100% rename from resources/images/search_add_saved.svg rename to imgsrc/search_add_saved.svg diff --git a/resources/images/search_copy_saved.svg b/imgsrc/search_copy_saved.svg similarity index 100% rename from resources/images/search_copy_saved.svg rename to imgsrc/search_copy_saved.svg diff --git a/resources/images/search_delete_saved.svg b/imgsrc/search_delete_saved.svg similarity index 100% rename from resources/images/search_delete_saved.svg rename to imgsrc/search_delete_saved.svg diff --git a/resources/images/series.svg b/imgsrc/series.svg similarity index 100% rename from resources/images/series.svg rename to imgsrc/series.svg diff --git a/resources/images/swap.svg b/imgsrc/swap.svg similarity index 100% rename from resources/images/swap.svg rename to imgsrc/swap.svg diff --git a/resources/images/sync.svg b/imgsrc/sync.svg similarity index 100% rename from resources/images/sync.svg rename to imgsrc/sync.svg diff --git a/resources/images/tags.svg b/imgsrc/tags.svg similarity index 100% rename from resources/images/tags.svg rename to imgsrc/tags.svg diff --git a/resources/images/trash.svg b/imgsrc/trash.svg similarity index 100% rename from resources/images/trash.svg rename to imgsrc/trash.svg diff --git a/resources/images/user_profile.svg b/imgsrc/user_profile.svg similarity index 100% rename from resources/images/user_profile.svg rename to imgsrc/user_profile.svg diff --git a/resources/images/view.svg b/imgsrc/view.svg similarity index 100% rename from resources/images/view.svg rename to imgsrc/view.svg diff --git a/resources/images/viewer.svg b/imgsrc/viewer.svg similarity index 100% rename from resources/images/viewer.svg rename to imgsrc/viewer.svg diff --git a/resources/images/welcome_wizard.svg b/imgsrc/welcome_wizard.svg similarity index 100% rename from resources/images/welcome_wizard.svg rename to imgsrc/welcome_wizard.svg diff --git a/resources/images/window-close.svg b/imgsrc/window-close.svg similarity index 100% rename from resources/images/window-close.svg rename to imgsrc/window-close.svg diff --git a/resources/images/wizard.svg b/imgsrc/wizard.svg similarity index 100% rename from resources/images/wizard.svg rename to imgsrc/wizard.svg diff --git a/resources/content_server/gui.js b/resources/content_server/gui.js index 8368866a5e..631fb8b617 100644 --- a/resources/content_server/gui.js +++ b/resources/content_server/gui.js @@ -26,7 +26,7 @@ var current_library_request = null; ////////////////////////////// GET BOOK LIST ////////////////////////////// -var LIBRARY_FETCH_TIMEOUT = 10000; // milliseconds +var LIBRARY_FETCH_TIMEOUT = 30000; // milliseconds function create_table_headers() { var thead = $('table#book_list thead tr'); diff --git a/resources/images/add_book.png b/resources/images/add_book.png new file mode 100644 index 0000000000..d6c678ecac Binary files /dev/null and b/resources/images/add_book.png differ diff --git a/resources/images/arrow-down.png b/resources/images/arrow-down.png new file mode 100644 index 0000000000..3ff7d46058 Binary files /dev/null and b/resources/images/arrow-down.png differ diff --git a/resources/images/arrow-up.png b/resources/images/arrow-up.png new file mode 100644 index 0000000000..f16e69a8ec Binary files /dev/null and b/resources/images/arrow-up.png differ diff --git a/resources/images/auto_author_sort.png b/resources/images/auto_author_sort.png new file mode 100644 index 0000000000..a6787f19fb Binary files /dev/null and b/resources/images/auto_author_sort.png differ diff --git a/resources/images/back.png b/resources/images/back.png new file mode 100644 index 0000000000..4b2bceb6ed Binary files /dev/null and b/resources/images/back.png differ diff --git a/resources/images/blank.png b/resources/images/blank.png new file mode 100644 index 0000000000..60b8803d95 Binary files /dev/null and b/resources/images/blank.png differ diff --git a/resources/images/book.png b/resources/images/book.png new file mode 100644 index 0000000000..a49c8f3db9 Binary files /dev/null and b/resources/images/book.png differ diff --git a/resources/images/bookmarks.png b/resources/images/bookmarks.png new file mode 100644 index 0000000000..91613db90b Binary files /dev/null and b/resources/images/bookmarks.png differ diff --git a/resources/images/books_in_series.png b/resources/images/books_in_series.png new file mode 100644 index 0000000000..67d5be2fdd Binary files /dev/null and b/resources/images/books_in_series.png differ diff --git a/resources/images/catalog.png b/resources/images/catalog.png new file mode 100644 index 0000000000..c422cf0861 Binary files /dev/null and b/resources/images/catalog.png differ diff --git a/resources/images/chapters.png b/resources/images/chapters.png new file mode 100644 index 0000000000..a904bcec87 Binary files /dev/null and b/resources/images/chapters.png differ diff --git a/resources/images/clear_left.png b/resources/images/clear_left.png new file mode 100644 index 0000000000..dcf7263e89 Binary files /dev/null and b/resources/images/clear_left.png differ diff --git a/resources/images/column.png b/resources/images/column.png new file mode 100644 index 0000000000..0a5f184601 Binary files /dev/null and b/resources/images/column.png differ diff --git a/resources/images/column.svg b/resources/images/column.svg deleted file mode 100644 index 4d6f4b809e..0000000000 --- a/resources/images/column.svg +++ /dev/null @@ -1,61 +0,0 @@ - -Capitello modanatura modanature moulure mouluresbuildingArchitetto Francesco RollandinArchitetto Francesco RollandinArchitetto Francesco Rollandinimage/svg+xmlen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/images/config.png b/resources/images/config.png new file mode 100644 index 0000000000..81d1318b56 Binary files /dev/null and b/resources/images/config.png differ diff --git a/resources/images/connect_share.png b/resources/images/connect_share.png new file mode 100644 index 0000000000..0932ce42de Binary files /dev/null and b/resources/images/connect_share.png differ diff --git a/resources/images/convert.png b/resources/images/convert.png new file mode 100644 index 0000000000..89f0d7352e Binary files /dev/null and b/resources/images/convert.png differ diff --git a/resources/images/cover_flow.png b/resources/images/cover_flow.png new file mode 100644 index 0000000000..0f3a324a1a Binary files /dev/null and b/resources/images/cover_flow.png differ diff --git a/resources/images/debug.png b/resources/images/debug.png new file mode 100644 index 0000000000..790a603dcd Binary files /dev/null and b/resources/images/debug.png differ diff --git a/resources/images/default_cover.png b/resources/images/default_cover.png new file mode 100644 index 0000000000..bd3d546203 Binary files /dev/null and b/resources/images/default_cover.png differ diff --git a/resources/images/devices/folder.png b/resources/images/devices/folder.png new file mode 100644 index 0000000000..febee0ce2c Binary files /dev/null and b/resources/images/devices/folder.png differ diff --git a/resources/images/dialog_error.png b/resources/images/dialog_error.png new file mode 100644 index 0000000000..2956723fee Binary files /dev/null and b/resources/images/dialog_error.png differ diff --git a/resources/images/dialog_information.png b/resources/images/dialog_information.png new file mode 100644 index 0000000000..bdfe771002 Binary files /dev/null and b/resources/images/dialog_information.png differ diff --git a/resources/images/dialog_question.png b/resources/images/dialog_question.png new file mode 100644 index 0000000000..251ced14c9 Binary files /dev/null and b/resources/images/dialog_question.png differ diff --git a/resources/images/dialog_warning.png b/resources/images/dialog_warning.png new file mode 100644 index 0000000000..8375ed463e Binary files /dev/null and b/resources/images/dialog_warning.png differ diff --git a/resources/images/dictionary.png b/resources/images/dictionary.png new file mode 100644 index 0000000000..a4b395685c Binary files /dev/null and b/resources/images/dictionary.png differ diff --git a/resources/images/document_open.png b/resources/images/document_open.png new file mode 100644 index 0000000000..b9fd9e5f1e Binary files /dev/null and b/resources/images/document_open.png differ diff --git a/resources/images/donate.png b/resources/images/donate.png new file mode 100644 index 0000000000..dc726c896a Binary files /dev/null and b/resources/images/donate.png differ diff --git a/resources/images/drawer.png b/resources/images/drawer.png new file mode 100644 index 0000000000..dd33c2ad6e Binary files /dev/null and b/resources/images/drawer.png differ diff --git a/resources/images/drawer.svg b/resources/images/drawer.svg deleted file mode 100644 index 679bca53b2..0000000000 --- a/resources/images/drawer.svg +++ /dev/null @@ -1,2679 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/images/edit_copy.png b/resources/images/edit_copy.png new file mode 100644 index 0000000000..0760f6b52b Binary files /dev/null and b/resources/images/edit_copy.png differ diff --git a/resources/images/edit_input.png b/resources/images/edit_input.png new file mode 100644 index 0000000000..63fe3d34e5 Binary files /dev/null and b/resources/images/edit_input.png differ diff --git a/resources/images/eject.png b/resources/images/eject.png new file mode 100644 index 0000000000..748a8b7f7d Binary files /dev/null and b/resources/images/eject.png differ diff --git a/resources/images/exec.png b/resources/images/exec.png new file mode 100644 index 0000000000..f4a2161d3f Binary files /dev/null and b/resources/images/exec.png differ diff --git a/resources/images/font_size_larger.png b/resources/images/font_size_larger.png new file mode 100644 index 0000000000..7bc0fad27a Binary files /dev/null and b/resources/images/font_size_larger.png differ diff --git a/resources/images/font_size_smaller.png b/resources/images/font_size_smaller.png new file mode 100644 index 0000000000..56bff937e1 Binary files /dev/null and b/resources/images/font_size_smaller.png differ diff --git a/resources/images/forward.png b/resources/images/forward.png new file mode 100644 index 0000000000..95bde41e8d Binary files /dev/null and b/resources/images/forward.png differ diff --git a/resources/images/help.png b/resources/images/help.png new file mode 100644 index 0000000000..5e869ef201 Binary files /dev/null and b/resources/images/help.png differ diff --git a/resources/images/jobs.png b/resources/images/jobs.png new file mode 100644 index 0000000000..a9e8dcec89 Binary files /dev/null and b/resources/images/jobs.png differ diff --git a/resources/images/list_remove.png b/resources/images/list_remove.png new file mode 100644 index 0000000000..323bcdd697 Binary files /dev/null and b/resources/images/list_remove.png differ diff --git a/resources/images/lookfeel.png b/resources/images/lookfeel.png new file mode 100644 index 0000000000..4d3690bf8d Binary files /dev/null and b/resources/images/lookfeel.png differ diff --git a/resources/images/mail.png b/resources/images/mail.png new file mode 100644 index 0000000000..718103cb53 Binary files /dev/null and b/resources/images/mail.png differ diff --git a/resources/images/merge_books.png b/resources/images/merge_books.png new file mode 100644 index 0000000000..4097e3457e Binary files /dev/null and b/resources/images/merge_books.png differ diff --git a/resources/images/metadata.png b/resources/images/metadata.png new file mode 100644 index 0000000000..0d294b1ca9 Binary files /dev/null and b/resources/images/metadata.png differ diff --git a/resources/images/mimetypes/bmp.png b/resources/images/mimetypes/bmp.png new file mode 100644 index 0000000000..f8d4274e14 Binary files /dev/null and b/resources/images/mimetypes/bmp.png differ diff --git a/resources/images/mimetypes/computer.png b/resources/images/mimetypes/computer.png new file mode 100644 index 0000000000..c15662dba7 Binary files /dev/null and b/resources/images/mimetypes/computer.png differ diff --git a/resources/images/mimetypes/dir.png b/resources/images/mimetypes/dir.png new file mode 100644 index 0000000000..36f9f423bb Binary files /dev/null and b/resources/images/mimetypes/dir.png differ diff --git a/resources/images/mimetypes/epub.png b/resources/images/mimetypes/epub.png new file mode 100644 index 0000000000..61f0f51384 Binary files /dev/null and b/resources/images/mimetypes/epub.png differ diff --git a/resources/images/mimetypes/epub.svg b/resources/images/mimetypes/epub.svg deleted file mode 100644 index 0c3a31964f..0000000000 --- a/resources/images/mimetypes/epub.svg +++ /dev/null @@ -1,830 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PUB - - e - diff --git a/resources/images/mimetypes/fb2.png b/resources/images/mimetypes/fb2.png new file mode 100644 index 0000000000..4778a4848f Binary files /dev/null and b/resources/images/mimetypes/fb2.png differ diff --git a/resources/images/mimetypes/fb2.svg b/resources/images/mimetypes/fb2.svg deleted file mode 100644 index 009ca7d109..0000000000 --- a/resources/images/mimetypes/fb2.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - diff --git a/resources/images/mimetypes/gif.png b/resources/images/mimetypes/gif.png new file mode 100644 index 0000000000..f8d4274e14 Binary files /dev/null and b/resources/images/mimetypes/gif.png differ diff --git a/resources/images/mimetypes/html.png b/resources/images/mimetypes/html.png new file mode 100644 index 0000000000..710c721ab3 Binary files /dev/null and b/resources/images/mimetypes/html.png differ diff --git a/resources/images/mimetypes/jpeg.png b/resources/images/mimetypes/jpeg.png new file mode 100644 index 0000000000..f8d4274e14 Binary files /dev/null and b/resources/images/mimetypes/jpeg.png differ diff --git a/resources/images/mimetypes/lit.png b/resources/images/mimetypes/lit.png new file mode 100644 index 0000000000..83999940a6 Binary files /dev/null and b/resources/images/mimetypes/lit.png differ diff --git a/resources/images/mimetypes/lrf.png b/resources/images/mimetypes/lrf.png new file mode 100644 index 0000000000..b29d3b381a Binary files /dev/null and b/resources/images/mimetypes/lrf.png differ diff --git a/resources/images/mimetypes/lrx.png b/resources/images/mimetypes/lrx.png new file mode 100644 index 0000000000..8496a30345 Binary files /dev/null and b/resources/images/mimetypes/lrx.png differ diff --git a/resources/images/mimetypes/mobi.png b/resources/images/mimetypes/mobi.png new file mode 100644 index 0000000000..cb1230a15b Binary files /dev/null and b/resources/images/mimetypes/mobi.png differ diff --git a/resources/images/mimetypes/mobi.svg b/resources/images/mimetypes/mobi.svg deleted file mode 100644 index 88d19f6c0d..0000000000 --- a/resources/images/mimetypes/mobi.svg +++ /dev/null @@ -1,583 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - mobi - - - - diff --git a/resources/images/mimetypes/odt.png b/resources/images/mimetypes/odt.png new file mode 100644 index 0000000000..8765b3eb0b Binary files /dev/null and b/resources/images/mimetypes/odt.png differ diff --git a/resources/images/mimetypes/pdf.png b/resources/images/mimetypes/pdf.png new file mode 100644 index 0000000000..a0b1961cde Binary files /dev/null and b/resources/images/mimetypes/pdf.png differ diff --git a/resources/images/mimetypes/png.png b/resources/images/mimetypes/png.png new file mode 100644 index 0000000000..edbe5afa1b Binary files /dev/null and b/resources/images/mimetypes/png.png differ diff --git a/resources/images/mimetypes/rar.png b/resources/images/mimetypes/rar.png new file mode 100644 index 0000000000..1be23aabbb Binary files /dev/null and b/resources/images/mimetypes/rar.png differ diff --git a/resources/images/mimetypes/rtf.png b/resources/images/mimetypes/rtf.png new file mode 100644 index 0000000000..4cc6604cc2 Binary files /dev/null and b/resources/images/mimetypes/rtf.png differ diff --git a/resources/images/mimetypes/svg.png b/resources/images/mimetypes/svg.png new file mode 100644 index 0000000000..c6ee95c4e2 Binary files /dev/null and b/resources/images/mimetypes/svg.png differ diff --git a/resources/images/mimetypes/txt.png b/resources/images/mimetypes/txt.png new file mode 100644 index 0000000000..1febe414d4 Binary files /dev/null and b/resources/images/mimetypes/txt.png differ diff --git a/resources/images/mimetypes/unknown.png b/resources/images/mimetypes/unknown.png new file mode 100644 index 0000000000..75d1ae4ae5 Binary files /dev/null and b/resources/images/mimetypes/unknown.png differ diff --git a/resources/images/mimetypes/zero.png b/resources/images/mimetypes/zero.png new file mode 100644 index 0000000000..43462d91f4 Binary files /dev/null and b/resources/images/mimetypes/zero.png differ diff --git a/resources/images/mimetypes/zip.png b/resources/images/mimetypes/zip.png new file mode 100644 index 0000000000..a3ee074086 Binary files /dev/null and b/resources/images/mimetypes/zip.png differ diff --git a/resources/images/minus.png b/resources/images/minus.png new file mode 100644 index 0000000000..d9054cc90c Binary files /dev/null and b/resources/images/minus.png differ diff --git a/resources/images/network-server.png b/resources/images/network-server.png new file mode 100644 index 0000000000..b75de74928 Binary files /dev/null and b/resources/images/network-server.png differ diff --git a/resources/images/news.png b/resources/images/news.png new file mode 100644 index 0000000000..bfa62b211f Binary files /dev/null and b/resources/images/news.png differ diff --git a/resources/images/news/kstar.png b/resources/images/news/kstar.png new file mode 100644 index 0000000000..03eced9c44 Binary files /dev/null and b/resources/images/news/kstar.png differ diff --git a/resources/images/next.png b/resources/images/next.png new file mode 100644 index 0000000000..2df68e42dc Binary files /dev/null and b/resources/images/next.png differ diff --git a/resources/images/ok.png b/resources/images/ok.png new file mode 100644 index 0000000000..3f8dc38a8c Binary files /dev/null and b/resources/images/ok.png differ diff --git a/resources/images/page.png b/resources/images/page.png new file mode 100644 index 0000000000..71a1b00e68 Binary files /dev/null and b/resources/images/page.png differ diff --git a/resources/images/plugins.png b/resources/images/plugins.png new file mode 100644 index 0000000000..804aa98d7a Binary files /dev/null and b/resources/images/plugins.png differ diff --git a/resources/images/plus.png b/resources/images/plus.png new file mode 100644 index 0000000000..130528836c Binary files /dev/null and b/resources/images/plus.png differ diff --git a/resources/images/previous.png b/resources/images/previous.png new file mode 100644 index 0000000000..d21b443aa3 Binary files /dev/null and b/resources/images/previous.png differ diff --git a/resources/images/print-preview.png b/resources/images/print-preview.png new file mode 100644 index 0000000000..88e7cc0c97 Binary files /dev/null and b/resources/images/print-preview.png differ diff --git a/resources/images/print.png b/resources/images/print.png new file mode 100644 index 0000000000..c120d5ff01 Binary files /dev/null and b/resources/images/print.png differ diff --git a/resources/images/reader.png b/resources/images/reader.png new file mode 100644 index 0000000000..bfc532f5ee Binary files /dev/null and b/resources/images/reader.png differ diff --git a/resources/images/save.png b/resources/images/save.png new file mode 100644 index 0000000000..57ba0686ae Binary files /dev/null and b/resources/images/save.png differ diff --git a/resources/images/scheduler.png b/resources/images/scheduler.png new file mode 100644 index 0000000000..0035262d1c Binary files /dev/null and b/resources/images/scheduler.png differ diff --git a/resources/images/sd.png b/resources/images/sd.png new file mode 100644 index 0000000000..23ebd3d6a5 Binary files /dev/null and b/resources/images/sd.png differ diff --git a/resources/images/search.png b/resources/images/search.png new file mode 100644 index 0000000000..1fd7872786 Binary files /dev/null and b/resources/images/search.png differ diff --git a/resources/images/search_add_saved.png b/resources/images/search_add_saved.png new file mode 100644 index 0000000000..1395f69094 Binary files /dev/null and b/resources/images/search_add_saved.png differ diff --git a/resources/images/search_copy_saved.png b/resources/images/search_copy_saved.png new file mode 100644 index 0000000000..579b529cf0 Binary files /dev/null and b/resources/images/search_copy_saved.png differ diff --git a/resources/images/search_delete_saved.png b/resources/images/search_delete_saved.png new file mode 100644 index 0000000000..5e40e68de3 Binary files /dev/null and b/resources/images/search_delete_saved.png differ diff --git a/resources/images/series.png b/resources/images/series.png new file mode 100644 index 0000000000..7b1138b5e4 Binary files /dev/null and b/resources/images/series.png differ diff --git a/resources/images/swap.png b/resources/images/swap.png new file mode 100644 index 0000000000..60b8803d95 Binary files /dev/null and b/resources/images/swap.png differ diff --git a/resources/images/sync.png b/resources/images/sync.png new file mode 100644 index 0000000000..2219f01fa8 Binary files /dev/null and b/resources/images/sync.png differ diff --git a/resources/images/tags.png b/resources/images/tags.png new file mode 100644 index 0000000000..816adb3504 Binary files /dev/null and b/resources/images/tags.png differ diff --git a/resources/images/trash.png b/resources/images/trash.png new file mode 100644 index 0000000000..f5d453a173 Binary files /dev/null and b/resources/images/trash.png differ diff --git a/resources/images/user_profile.png b/resources/images/user_profile.png new file mode 100644 index 0000000000..7f08ad437c Binary files /dev/null and b/resources/images/user_profile.png differ diff --git a/resources/images/view.png b/resources/images/view.png new file mode 100644 index 0000000000..6c9d3e498d Binary files /dev/null and b/resources/images/view.png differ diff --git a/resources/images/viewer.png b/resources/images/viewer.png new file mode 100644 index 0000000000..8bcab85ed2 Binary files /dev/null and b/resources/images/viewer.png differ diff --git a/resources/images/welcome_wizard.png b/resources/images/welcome_wizard.png new file mode 100644 index 0000000000..fa1536a3a4 Binary files /dev/null and b/resources/images/welcome_wizard.png differ diff --git a/resources/images/window-close.png b/resources/images/window-close.png new file mode 100644 index 0000000000..2bee0fc10e Binary files /dev/null and b/resources/images/window-close.png differ diff --git a/resources/images/wizard.png b/resources/images/wizard.png new file mode 100644 index 0000000000..df492e6112 Binary files /dev/null and b/resources/images/wizard.png differ diff --git a/resources/recipes/hawaii.recipe b/resources/recipes/hawaii.recipe index 30a2b26def..5413d289b5 100644 --- a/resources/recipes/hawaii.recipe +++ b/resources/recipes/hawaii.recipe @@ -2,8 +2,8 @@ from calibre.web.feeds.news import BasicNewsRecipe class AdvancedUserRecipe1282101454(BasicNewsRecipe): title = 'West Hawaii Today' - language = 'en' __author__ = 'Tony Stegall' + language = 'en' description = 'Westhawaiitoday.com' publisher = 'West Hawaii ' category = 'news,Hawaii,USA' @@ -22,7 +22,7 @@ class AdvancedUserRecipe1282101454(BasicNewsRecipe): ('Local News', 'http://www.westhawaiitoday.com/?rss=local/'), ('Local Sports', 'http://www.westhawaiitoday.com/?rss=sports/local_sports/'), ('Big Fish List', 'http://www.westhawaiitoday.com/?rss=sports/big_fish_list/'), - ('Local Features' 'http://www.westhawaiitoday.com/?rss=features/'), + ('Local Features', 'http://www.westhawaiitoday.com/?rss=features/'), ('Obituaries', 'http://www.westhawaiitoday.com/?rss=obituaries/'), ('Letters To Editor', 'http://www.westhawaiitoday.com/?rss=opinion/letters_-_your_voice/'), ('Editorial', 'http://www.westhawaiitoday.com/?rss=opinion/editorial/'), diff --git a/resources/recipes/kstar.recipe b/resources/recipes/kstar.recipe new file mode 100644 index 0000000000..fe44bfd679 --- /dev/null +++ b/resources/recipes/kstar.recipe @@ -0,0 +1,58 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1282101454(BasicNewsRecipe): + title = 'Kansascity Star' + language = 'en' + __author__ = 'TonytheBookworm' + description = 'www.kansascity.com feed' + publisher = 'Tony Stegall' + category = 'news, politics, USA, kansascity' + oldest_article = 7 + max_articles_per_feed = 100 + no_stylesheets = True + + masthead_url = 'http://media.kansascity.com/images/site_logo_340x60.gif' + keep_only_tags = [ + dict(attrs={'id':['storyTitle','sub_headline','byLine']}) + ,dict(name='div', attrs={'id':['storyDate-Links','storyBody']}) + + ] + feeds = [ + ('Kansas News', 'http://www.kansascity.com/105/index.xml'), + + ] + + + + + def print_version(self, url): + split1 = url.split("/") + #url1 = split1[0] + #url2 = split1[1] + url3 = split1[2] + url4 = split1[3] + url5 = split1[4] + url6 = split1[5] + url7 = split1[6] + url8 = split1[7] + + + #example of link to convert + #Original link: http://www.kansascity.com/2010/09/04/2199362/lees-summit-school-appears-to.html + #print version: http://www.kansascity.com/2010/09/04/v-print/2199362/lees-summit-school-appears-to.html + + print_url = 'http://' + url3 + '/' + url4 + '/' + url5 + '/' + url6 + '/v-print/' + url7 + '/' + url8 + + return print_url + + + + + + + + + + + + diff --git a/setup/installer/__init__.py b/setup/installer/__init__.py index 82902edf76..959d8d14e1 100644 --- a/setup/installer/__init__.py +++ b/setup/installer/__init__.py @@ -18,6 +18,7 @@ class Rsync(Command): SYNC_CMD = ('rsync -avz --delete --exclude src/calibre/plugins ' '--exclude src/calibre/manual --exclude src/calibre/trac ' '--exclude .bzr --exclude .build --exclude .svn --exclude build --exclude dist ' + '--exclude imgsrc ' '--exclude "*.pyc" --exclude "*.pyo" --exclude "*.swp" --exclude "*.swo" ' 'rsync://{host}/work/{project} ..') diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 27e319de14..083bc03723 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -393,9 +393,16 @@ class PreferencesPlugin(Plugin): # {{{ #: The category name displayed to the user for this plugin gui_category = None + #: The name displayed to the user for this plugin gui_name = None + #: The icon for this plugin, should be an absolute path + icon = None + + #: The description used for tooltips and the like + description = None + def create_widget(self, parent=None): ''' Create and return the actual Qt widget used for setting this group of @@ -404,9 +411,12 @@ class PreferencesPlugin(Plugin): # {{{ The default implementation uses :attr:`config_widget` to instantiate the widget. ''' - base = __import__(self.config_widget, fromlist=[1]) - widget = base.ConfigWidget(parent) - return widget + base, _, wc = self.config_widget.partition(':') + if not wc: + wc = 'ConfigWidget' + base = __import__(base, fromlist=[1]) + widget = getattr(base, wc) + return widget(parent) # }}} diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index d42f6b9da0..d95a7d1c8a 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -678,32 +678,181 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog, class LookAndFeel(PreferencesPlugin): name = 'Look & Feel' + icon = I('lookfeel.png') gui_name = _('Look and Feel') category = 'Interface' gui_category = _('Interface') category_order = 1 name_order = 1 config_widget = 'calibre.gui2.preferences.look_feel' + description = _('Adjust the look and feel of the calibre interface' + ' to suit your tastes') class Behavior(PreferencesPlugin): name = 'Behavior' + icon = I('config.png') gui_name = _('Behavior') category = 'Interface' gui_category = _('Interface') category_order = 1 name_order = 2 config_widget = 'calibre.gui2.preferences.behavior' + description = _('Change the way calibre behaves') class Columns(PreferencesPlugin): name = 'Custom Columns' + icon = I('column.png') gui_name = _('Add your own columns') category = 'Interface' gui_category = _('Interface') category_order = 1 name_order = 3 config_widget = 'calibre.gui2.preferences.columns' + description = _('Add/remove your own columns to the calibre book list') -plugins += [LookAndFeel, Behavior, Columns] +class Toolbar(PreferencesPlugin): + name = 'Toolbar' + icon = I('wizard.png') + gui_name = _('Customize the toolbar') + category = 'Interface' + gui_category = _('Interface') + category_order = 1 + name_order = 4 + config_widget = 'calibre.gui2.preferences.toolbar' + description = _('Customize the toolbars and context menus, changing which' + ' actions are available in each') + +class InputOptions(PreferencesPlugin): + name = 'Input Options' + icon = I('arrow-down.png') + gui_name = _('Input Options') + category = 'Conversion' + gui_category = _('Conversion') + category_order = 2 + name_order = 1 + config_widget = 'calibre.gui2.preferences.conversion:InputOptions' + description = _('Set conversion options specific to each input format') + +class CommonOptions(PreferencesPlugin): + name = 'Common Options' + icon = I('convert.png') + gui_name = _('Common Options') + category = 'Conversion' + gui_category = _('Conversion') + category_order = 2 + name_order = 2 + config_widget = 'calibre.gui2.preferences.conversion:CommonOptions' + description = _('Set conversion options common to all formats') + +class OutputOptions(PreferencesPlugin): + name = 'Output Options' + icon = I('arrow-up.png') + gui_name = _('Output Options') + category = 'Conversion' + gui_category = _('Conversion') + category_order = 2 + name_order = 3 + config_widget = 'calibre.gui2.preferences.conversion:OutputOptions' + description = _('Set conversion options specific to each output format') + +class Adding(PreferencesPlugin): + name = 'Adding' + icon = I('add_book.png') + gui_name = _('Adding books') + category = 'Import/Export' + gui_category = _('Import/Export') + category_order = 3 + name_order = 1 + config_widget = 'calibre.gui2.preferences.adding' + description = _('Control how calibre reads metadata from files when ' + 'adding books') + +class Saving(PreferencesPlugin): + name = 'Saving' + icon = I('save.png') + gui_name = _('Saving books to disk') + category = 'Import/Export' + gui_category = _('Import/Export') + category_order = 3 + name_order = 2 + config_widget = 'calibre.gui2.preferences.saving' + description = _('Control how calibre exports files from its database ' + 'to disk when using Save to disk') + +class Sending(PreferencesPlugin): + name = 'Sending' + icon = I('sync.png') + gui_name = _('Sending books to devices') + category = 'Import/Export' + gui_category = _('Import/Export') + category_order = 3 + name_order = 3 + config_widget = 'calibre.gui2.preferences.sending' + description = _('Control how calibre transfers files to your ' + 'ebook reader') + +class Email(PreferencesPlugin): + name = 'Email' + icon = I('mail.png') + gui_name = _('Sharing books by email') + category = 'Sharing' + gui_category = _('Sharing') + category_order = 4 + name_order = 1 + config_widget = 'calibre.gui2.preferences.emailp' + description = _('Setup sharing of books via email. Can be used ' + 'for automatic sending of downloaded news to your devices') + +class Server(PreferencesPlugin): + name = 'Server' + icon = I('network-server.png') + gui_name = _('Sharing over the net') + category = 'Sharing' + gui_category = _('Sharing') + category_order = 4 + name_order = 2 + config_widget = 'calibre.gui2.preferences.server' + description = _('Setup the calibre Content Server which will ' + 'give you access to your calibre library from anywhere, ' + 'on any device, over the internet') + +class Plugins(PreferencesPlugin): + name = 'Plugins' + icon = I('plugins.png') + gui_name = _('Plugins') + category = 'Advanced' + gui_category = _('Advanced') + category_order = 5 + name_order = 1 + config_widget = 'calibre.gui2.preferences.plugins' + description = _('Add/remove/customize various bits of calibre ' + 'functionality') + +class Tweaks(PreferencesPlugin): + name = 'Tweaks' + icon = I('drawer.png') + gui_name = _('Tweaks') + category = 'Advanced' + gui_category = _('Advanced') + category_order = 5 + name_order = 2 + config_widget = 'calibre.gui2.preferences.tweaks' + description = _('Fine tune how calibre behaves in various contexts') + +class Misc(PreferencesPlugin): + name = 'Misc' + icon = I('exec.png') + gui_name = _('Miscellaneous') + category = 'Advanced' + gui_category = _('Advanced') + category_order = 5 + name_order = 3 + config_widget = 'calibre.gui2.preferences.misc' + description = _('Miscellaneous advanced configuration') + +plugins += [LookAndFeel, Behavior, Columns, Toolbar, InputOptions, + CommonOptions, OutputOptions, Adding, Saving, Sending, Email, Server, + Plugins, Tweaks, Misc] #}}} diff --git a/src/calibre/devices/folder_device/driver.py b/src/calibre/devices/folder_device/driver.py index 552e713ad8..9cd1280cc9 100644 --- a/src/calibre/devices/folder_device/driver.py +++ b/src/calibre/devices/folder_device/driver.py @@ -42,7 +42,7 @@ class FOLDER_DEVICE(USBMS): SUPPORTS_SUB_DIRS = True #: Icon for this device - icon = I('devices/folder.svg') + icon = I('devices/folder.png') METADATA_CACHE = '.metadata.calibre' _main_prefix = '' diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 1384fa03d9..ab52b08568 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -43,7 +43,7 @@ class DevicePlugin(Plugin): path_sep = os.sep #: Icon for this device - icon = I('reader.svg') + icon = I('reader.png') # Used by gui2.ui:annotations_fetched() and devices.kindle.driver:get_annotations() UserAnnotation = namedtuple('Annotation','type, value') diff --git a/src/calibre/devices/jetbook/driver.py b/src/calibre/devices/jetbook/driver.py index 0d2e35e4fc..6ee1c07464 100644 --- a/src/calibre/devices/jetbook/driver.py +++ b/src/calibre/devices/jetbook/driver.py @@ -87,7 +87,7 @@ class MIBUK(USBMS): name = 'MiBuk Wolder Device Interface' description = _('Communicate with the MiBuk Wolder reader.') author = 'Kovid Goyal' - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['windows'] FORMATS = ['epub', 'mobi', 'prc', 'fb2', 'txt', 'rtf', 'pdf'] diff --git a/src/calibre/ebooks/conversion/preprocess.py b/src/calibre/ebooks/conversion/preprocess.py index 973e508746..f7b803974f 100644 --- a/src/calibre/ebooks/conversion/preprocess.py +++ b/src/calibre/ebooks/conversion/preprocess.py @@ -142,55 +142,78 @@ class HTMLPreProcessor(object): # Fix pdftohtml markup PDFTOHTML = [ # Fix umlauts - (re.compile(u'¨\s*()*\s*o', re.UNICODE), lambda match: u'ö'), - (re.compile(u'¨\s*()*\s*O', re.UNICODE), lambda match: u'Ö'), - (re.compile(u'¨\s*()*\s*u', re.UNICODE), lambda match: u'ü'), - (re.compile(u'¨\s*()*\s*U', re.UNICODE), lambda match: u'Ü'), + # ¨ + (re.compile(u'¨\s*()*\s*a', re.UNICODE), lambda match: u'ä'), + (re.compile(u'¨\s*()*\s*A', re.UNICODE), lambda match: u'Ä'), (re.compile(u'¨\s*()*\s*e', re.UNICODE), lambda match: u'ë'), (re.compile(u'¨\s*()*\s*E', re.UNICODE), lambda match: u'Ë'), (re.compile(u'¨\s*()*\s*i', re.UNICODE), lambda match: u'ï'), (re.compile(u'¨\s*()*\s*I', re.UNICODE), lambda match: u'Ï'), - (re.compile(u'¨\s*()*\s*a', re.UNICODE), lambda match: u'ä'), - (re.compile(u'¨\s*()*\s*A', re.UNICODE), lambda match: u'Ä'), + (re.compile(u'¨\s*()*\s*o', re.UNICODE), lambda match: u'ö'), + (re.compile(u'¨\s*()*\s*O', re.UNICODE), lambda match: u'Ö'), + (re.compile(u'¨\s*()*\s*u', re.UNICODE), lambda match: u'ü'), + (re.compile(u'¨\s*()*\s*U', re.UNICODE), lambda match: u'Ü'), # Fix accents - (re.compile(u'`\s*()*\s*o', re.UNICODE), lambda match: u'ò'), - (re.compile(u'`\s*()*\s*O', re.UNICODE), lambda match: u'Ò'), - (re.compile(u'`\s*()*\s*u', re.UNICODE), lambda match: u'ù'), - (re.compile(u'`\s*()*\s*U', re.UNICODE), lambda match: u'Ù'), + # ` + (re.compile(u'`\s*()*\s*a', re.UNICODE), lambda match: u'à'), + (re.compile(u'`\s*()*\s*A', re.UNICODE), lambda match: u'À'), (re.compile(u'`\s*()*\s*e', re.UNICODE), lambda match: u'è'), (re.compile(u'`\s*()*\s*E', re.UNICODE), lambda match: u'È'), (re.compile(u'`\s*()*\s*i', re.UNICODE), lambda match: u'ì'), (re.compile(u'`\s*()*\s*I', re.UNICODE), lambda match: u'Ì'), - (re.compile(u'`\s*()*\s*a', re.UNICODE), lambda match: u'à'), - (re.compile(u'`\s*()*\s*A', re.UNICODE), lambda match: u'À'), + (re.compile(u'`\s*()*\s*o', re.UNICODE), lambda match: u'ò'), + (re.compile(u'`\s*()*\s*O', re.UNICODE), lambda match: u'Ò'), + (re.compile(u'`\s*()*\s*u', re.UNICODE), lambda match: u'ù'), + (re.compile(u'`\s*()*\s*U', re.UNICODE), lambda match: u'Ù'), - (re.compile(u'´\s*()*\s*o', re.UNICODE), lambda match: u'ó'), - (re.compile(u'´\s*()*\s*O', re.UNICODE), lambda match: u'Ó'), - (re.compile(u'´\s*()*\s*u', re.UNICODE), lambda match: u'ú'), - (re.compile(u'´\s*()*\s*U', re.UNICODE), lambda match: u'Ú'), + # ´ + (re.compile(u'´\s*()*\s*a', re.UNICODE), lambda match: u'á'), + (re.compile(u'´\s*()*\s*A', re.UNICODE), lambda match: u'Á'), + (re.compile(u'´\s*()*\s*c', re.UNICODE), lambda match: u'ć'), + (re.compile(u'´\s*()*\s*C', re.UNICODE), lambda match: u'Ć'), (re.compile(u'´\s*()*\s*e', re.UNICODE), lambda match: u'é'), (re.compile(u'´\s*()*\s*E', re.UNICODE), lambda match: u'É'), (re.compile(u'´\s*()*\s*i', re.UNICODE), lambda match: u'í'), (re.compile(u'´\s*()*\s*I', re.UNICODE), lambda match: u'Í'), - (re.compile(u'´\s*()*\s*a', re.UNICODE), lambda match: u'á'), - (re.compile(u'´\s*()*\s*A', re.UNICODE), lambda match: u'Á'), + (re.compile(u'´\s*()*\s*o', re.UNICODE), lambda match: u'ó'), + (re.compile(u'´\s*()*\s*O', re.UNICODE), lambda match: u'Ó'), + (re.compile(u'´\s*()*\s*n', re.UNICODE), lambda match: u'ń'), + (re.compile(u'´\s*()*\s*N', re.UNICODE), lambda match: u'Ń'), + (re.compile(u'´\s*()*\s*s', re.UNICODE), lambda match: u'ś'), + (re.compile(u'´\s*()*\s*S', re.UNICODE), lambda match: u'Ś'), + (re.compile(u'´\s*()*\s*u', re.UNICODE), lambda match: u'ú'), + (re.compile(u'´\s*()*\s*U', re.UNICODE), lambda match: u'Ú'), + (re.compile(u'´\s*()*\s*z', re.UNICODE), lambda match: u'ź'), + (re.compile(u'´\s*()*\s*Z', re.UNICODE), lambda match: u'Ź'), - (re.compile(u'ˆ\s*()*\s*o', re.UNICODE), lambda match: u'ô'), - (re.compile(u'ˆ\s*()*\s*O', re.UNICODE), lambda match: u'Ô'), - (re.compile(u'ˆ\s*()*\s*u', re.UNICODE), lambda match: u'û'), - (re.compile(u'ˆ\s*()*\s*U', re.UNICODE), lambda match: u'Û'), + # ˆ + (re.compile(u'ˆ\s*()*\s*a', re.UNICODE), lambda match: u'â'), + (re.compile(u'ˆ\s*()*\s*A', re.UNICODE), lambda match: u'Â'), (re.compile(u'ˆ\s*()*\s*e', re.UNICODE), lambda match: u'ê'), (re.compile(u'ˆ\s*()*\s*E', re.UNICODE), lambda match: u'Ê'), (re.compile(u'ˆ\s*()*\s*i', re.UNICODE), lambda match: u'î'), (re.compile(u'ˆ\s*()*\s*I', re.UNICODE), lambda match: u'Î'), - (re.compile(u'ˆ\s*()*\s*a', re.UNICODE), lambda match: u'â'), - (re.compile(u'ˆ\s*()*\s*A', re.UNICODE), lambda match: u'Â'), + (re.compile(u'ˆ\s*()*\s*o', re.UNICODE), lambda match: u'ô'), + (re.compile(u'ˆ\s*()*\s*O', re.UNICODE), lambda match: u'Ô'), + (re.compile(u'ˆ\s*()*\s*u', re.UNICODE), lambda match: u'û'), + (re.compile(u'ˆ\s*()*\s*U', re.UNICODE), lambda match: u'Û'), - # Fix more special characters + # ¸ (re.compile(u'¸\s*()*\s*c', re.UNICODE), lambda match: u'ç'), (re.compile(u'¸\s*()*\s*C', re.UNICODE), lambda match: u'Ç'), + # ˛ + (re.compile(u'˛\s*()*\s*a', re.UNICODE), lambda match: u'ą'), + (re.compile(u'˛\s*()*\s*A', re.UNICODE), lambda match: u'Ą'), + (re.compile(u'˛\s*()*\s*e', re.UNICODE), lambda match: u'ę'), + (re.compile(u'˛\s*()*\s*E', re.UNICODE), lambda match: u'Ę'), + + # ˙ + (re.compile(u'˙\s*()*\s*z', re.UNICODE), lambda match: u'ż'), + (re.compile(u'˙\s*()*\s*Z', re.UNICODE), lambda match: u'Ż'), + + # Remove page links (re.compile(r'', re.IGNORECASE), lambda match: ''), # Remove
tags diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index d0b680009a..3987ffa1b8 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -153,8 +153,15 @@ class FB2MLizer(object): return ''.join(toc) def sectionize_chapters(self, text): - text = re.sub(r'(?imsu)(?P)\s*(?P(

)*\s*.+?\s*(

)*)', lambda mo: '
%s%s' % (mo.group('anchor'), mo.group('strong')), text) - text = re.sub(r'(?imsu)

\s*(?P)\s*

\s*(?P(

)*\s*.+?\s*(

)*)', lambda mo: '
%s%s' % (mo.group('anchor'), mo.group('strong')), text) + def remove_p(t): + t = t.replace('

', '') + t = t.replace('

', '') + return t + text = re.sub(r'(?imsu)(

)\s*(?P)\s*(

)\s*(

)\s*(?P.+?)\s*(

)', lambda mo: '
%s<p>%s</p>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text) + text = re.sub(r'(?imsu)(

)\s*(?P)\s*(

)\s*(?P.+?)', lambda mo: '
%s<p>%s</p>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text) + text = re.sub(r'(?imsu)(?P)\s*(

)\s*(?P.+?)\s*(

)', lambda mo: '
%s<p>%s</p>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text) + text = re.sub(r'(?imsu)(

)\s*(?P)\s*(?P.+?)\s*(

)', lambda mo: '
%s<p>%s</p>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text) + text = re.sub(r'(?imsu)(?P)\s*(?P.+?)', lambda mo: '
%s<p>%s</p>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text) return text def get_text(self): diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index 10f1ee32d6..5d5de7b153 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -1695,12 +1695,11 @@ class MobiWriter(object): header.write(pack('>I', 1)) # 0x1c - 0x1f : Text encoding ? - # header.write(pack('>I', 650001)) - # GR: This needs to be either 0xFDE9 or 0x4E4 - header.write(pack('>I', 0xFDE9)) + # GR: Language encoding for NCX entries (latin_1) + header.write(pack('>I', 0x4e4)) - # 0x20 - 0x23 : Language code? - header.write(iana2mobi(str(self._oeb.metadata.language[0]))) + # 0x20 - 0x23 : Mimicking kindleGen + header.write(pack('>I', 0xFFFFFFFF)) # 0x24 - 0x27 : Number of TOC entries in INDX1 header.write(pack('>I', indxt_count + 1)) @@ -1795,13 +1794,12 @@ class MobiWriter(object): self._oeb.log.debug('Index records dumped to', t) def _clean_text_value(self, text): - if text is not None and text.strip() : - text = text.strip() - if not isinstance(text, unicode): - text = text.decode('utf-8', 'replace') - text = text.encode('utf-8') - else : - text = "(none)".encode('utf-8') + if not text: + text = u'(none)' + text = text.strip() + if not isinstance(text, unicode): + text = text.decode('utf-8', 'replace') + text = text.encode('cp1252','replace') return text def _add_to_ctoc(self, ctoc_str, record_offset): @@ -2151,6 +2149,26 @@ class MobiWriter(object): indxt.write(decint(self._ctoc_map[index]['titleOffset'], DECINT_FORWARD)) # vwi title offset in CNCX indxt.write(decint(0, DECINT_FORWARD)) # unknown byte + def _write_subchapter_node(self, indxt, indices, index, offset, length, count): + # This style works without a parent chapter, mimicking what KindleGen does, + # using a value of 0x0B for parentIndex + # Writes an INDX1 NCXEntry of entryType 0x1F - subchapter + if self.opts.verbose > 2: + # *** GR: Turn this off while I'm developing my code + #self._oeb.log.debug('Writing TOC node to IDXT:', node.title, 'href:', node.href) + pass + + pos = 0xc0 + indxt.tell() + indices.write(pack('>H', pos)) # Save the offset for IDXTIndices + name = "%04X"%count + indxt.write(chr(len(name)) + name) # Write the name + indxt.write(INDXT['subchapter']) # entryType [0x0F | 0xDF | 0xFF | 0x3F] + indxt.write(decint(offset, DECINT_FORWARD)) # offset + indxt.write(decint(length, DECINT_FORWARD)) # length + indxt.write(decint(self._ctoc_map[index]['titleOffset'], DECINT_FORWARD)) # vwi title offset in CNCX + indxt.write(decint(0, DECINT_FORWARD)) # unknown byte + indxt.write(decint(0xb, DECINT_FORWARD)) # parentIndex - null + def _compute_offset_length(self, i, node, entries) : h = node.href if h not in self._id_offsets: diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 5ffd8d723a..1b61404589 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -233,7 +233,7 @@ def warning_dialog(parent, title, msg, det_msg='', show=False, d = MessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok, parent, det_msg) d.setEscapeButton(QMessageBox.Ok) - d.setIconPixmap(QPixmap(I('dialog_warning.svg'))) + d.setIconPixmap(QPixmap(I('dialog_warning.png'))) if not show_copy_button: d.cb.setVisible(False) if show: @@ -244,7 +244,7 @@ def error_dialog(parent, title, msg, det_msg='', show=False, show_copy_button=True): d = MessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok, parent, det_msg) - d.setIconPixmap(QPixmap(I('dialog_error.svg'))) + d.setIconPixmap(QPixmap(I('dialog_error.png'))) d.setEscapeButton(QMessageBox.Ok) if not show_copy_button: d.cb.setVisible(False) @@ -256,7 +256,7 @@ def question_dialog(parent, title, msg, det_msg='', show_copy_button=True, buttons=QMessageBox.Yes|QMessageBox.No): d = MessageBox(QMessageBox.Question, title, msg, buttons, parent, det_msg) - d.setIconPixmap(QPixmap(I('dialog_question.svg'))) + d.setIconPixmap(QPixmap(I('dialog_question.png'))) d.setEscapeButton(QMessageBox.No) if not show_copy_button: d.cb.setVisible(False) @@ -266,7 +266,7 @@ def question_dialog(parent, title, msg, det_msg='', show_copy_button=True, def info_dialog(parent, title, msg, det_msg='', show=False): d = MessageBox(QMessageBox.Information, title, msg, QMessageBox.Ok, parent, det_msg) - d.setIconPixmap(QPixmap(I('dialog_information.svg'))) + d.setIconPixmap(QPixmap(I('dialog_information.png'))) if show: return d.exec_() return d @@ -372,7 +372,7 @@ class FileIconProvider(QFileIconProvider): QFileIconProvider.__init__(self) self.icons = {} for key in self.__class__.ICONS.keys(): - self.icons[key] = I('mimetypes/')+self.__class__.ICONS[key]+'.svg' + self.icons[key] = I('mimetypes/')+self.__class__.ICONS[key]+'.png' for i in ('dir', 'default', 'zero'): self.icons[i] = QIcon(self.icons[i]) diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py index 95fdb9a6c6..f0ff794fab 100644 --- a/src/calibre/gui2/actions/add.py +++ b/src/calibre/gui2/actions/add.py @@ -22,7 +22,7 @@ from calibre.gui2.actions import InterfaceAction class AddAction(InterfaceAction): name = 'Add Books' - action_spec = (_('Add books'), 'add_book.svg', + action_spec = (_('Add books'), 'add_book.png', _('Add books to the calibre library/device from files on your computer') , _('A')) diff --git a/src/calibre/gui2/actions/add_to_library.py b/src/calibre/gui2/actions/add_to_library.py index 7771fa7ed6..6fc0d5fb1f 100644 --- a/src/calibre/gui2/actions/add_to_library.py +++ b/src/calibre/gui2/actions/add_to_library.py @@ -10,7 +10,7 @@ from calibre.gui2.actions import InterfaceAction class AddToLibraryAction(InterfaceAction): name = 'Add To Library' - action_spec = (_('Add books to library'), 'add_book.svg', + action_spec = (_('Add books to library'), 'add_book.png', _('Add books to your calibre library from the connected device'), None) dont_add_to = frozenset(['toolbar', 'context-menu']) diff --git a/src/calibre/gui2/actions/convert.py b/src/calibre/gui2/actions/convert.py index 20f5bc457a..ee0f06ab71 100644 --- a/src/calibre/gui2/actions/convert.py +++ b/src/calibre/gui2/actions/convert.py @@ -19,7 +19,7 @@ from calibre.customize.ui import plugin_for_input_format class ConvertAction(InterfaceAction): name = 'Convert Books' - action_spec = (_('Convert books'), 'convert.svg', None, _('C')) + action_spec = (_('Convert books'), 'convert.png', None, _('C')) dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) def genesis(self): diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index e0f3ae4d65..e50131afe3 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -15,7 +15,7 @@ from calibre.gui2.actions import InterfaceAction class DeleteAction(InterfaceAction): name = 'Remove Books' - action_spec = (_('Remove books'), 'trash.svg', None, _('Del')) + action_spec = (_('Remove books'), 'trash.png', None, _('Del')) def genesis(self): self.qaction.triggered.connect(self.delete_books) diff --git a/src/calibre/gui2/actions/device.py b/src/calibre/gui2/actions/device.py index e71b2d1f45..744ab20d10 100644 --- a/src/calibre/gui2/actions/device.py +++ b/src/calibre/gui2/actions/device.py @@ -23,7 +23,7 @@ class ShareConnMenu(QMenu): # {{{ def __init__(self, parent=None): QMenu.__init__(self, parent) - mitem = self.addAction(QIcon(I('devices/folder.svg')), _('Connect to folder')) + mitem = self.addAction(QIcon(I('devices/folder.png')), _('Connect to folder')) mitem.setEnabled(True) mitem.triggered.connect(lambda x : self.connect_to_folder.emit()) self.connect_to_folder_action = mitem @@ -36,7 +36,7 @@ class ShareConnMenu(QMenu): # {{{ mitem.setVisible(False) self.addSeparator() self.toggle_server_action = \ - self.addAction(QIcon(I('network-server.svg')), + self.addAction(QIcon(I('network-server.png')), _('Start Content Server')) self.toggle_server_action.triggered.connect(lambda x: self.toggle_server.emit()) @@ -63,9 +63,9 @@ class ShareConnMenu(QMenu): # {{{ for account in keys: formats, auto, default = opts.accounts[account] dest = 'mail:'+account+';'+formats - action1 = DeviceAction(dest, False, False, I('mail.svg'), + action1 = DeviceAction(dest, False, False, I('mail.png'), _('Email to')+' '+account) - action2 = DeviceAction(dest, True, False, I('mail.svg'), + action2 = DeviceAction(dest, True, False, I('mail.png'), _('Email to')+' '+account+ _(' and delete from library')) map(self.email_to_menu.addAction, (action1, action2)) map(self.memory.append, (action1, action2)) @@ -95,7 +95,7 @@ class ShareConnMenu(QMenu): # {{{ class SendToDeviceAction(InterfaceAction): name = 'Send To Device' - action_spec = (_('Send to device'), 'sync.svg', None, _('D')) + action_spec = (_('Send to device'), 'sync.png', None, _('D')) dont_remove_from = frozenset(['toolbar-device']) dont_add_to = frozenset(['toolbar', 'context-menu']) @@ -114,7 +114,7 @@ class SendToDeviceAction(InterfaceAction): class ConnectShareAction(InterfaceAction): name = 'Connect Share' - action_spec = (_('Connect/share'), 'connect_share.svg', None, None) + action_spec = (_('Connect/share'), 'connect_share.png', None, None) popup_type = QToolButton.InstantPopup def genesis(self): @@ -122,7 +122,7 @@ class ConnectShareAction(InterfaceAction): self.share_conn_menu.toggle_server.connect(self.toggle_content_server) self.share_conn_menu.config_email.connect(partial( self.gui.iactions['Preferences'].do_config, - initial_category='email')) + initial_plugin=('Sharing', 'Email'))) self.qaction.setMenu(self.share_conn_menu) self.share_conn_menu.connect_to_folder.connect(self.gui.connect_to_folder) self.share_conn_menu.connect_to_itunes.connect(self.gui.connect_to_itunes) diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index bb07cfda3d..7a1e589d2a 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -21,10 +21,10 @@ from calibre.gui2.dialogs.progress import BlockingBusy class EditMetadataAction(InterfaceAction): name = 'Edit Metadata' - action_spec = (_('Edit metadata'), 'edit_input.svg', None, _('E')) + action_spec = (_('Edit metadata'), 'edit_input.png', None, _('E')) def genesis(self): - self.create_action(spec=(_('Merge book records'), 'merge_books.svg', + self.create_action(spec=(_('Merge book records'), 'merge_books.png', None, _('M')), attr='action_merge') md = QMenu() md.addAction(_('Edit metadata individually'), diff --git a/src/calibre/gui2/actions/fetch_news.py b/src/calibre/gui2/actions/fetch_news.py index b2893e0834..98be7cdcb2 100644 --- a/src/calibre/gui2/actions/fetch_news.py +++ b/src/calibre/gui2/actions/fetch_news.py @@ -15,7 +15,7 @@ from calibre.gui2.actions import InterfaceAction class FetchNewsAction(InterfaceAction): name = 'Fetch News' - action_spec = (_('Fetch news'), 'news.svg', None, _('F')) + action_spec = (_('Fetch news'), 'news.png', None, _('F')) def location_selected(self, loc): enabled = loc == 'library' diff --git a/src/calibre/gui2/actions/help.py b/src/calibre/gui2/actions/help.py index 0c6b257b80..2294daf4bb 100644 --- a/src/calibre/gui2/actions/help.py +++ b/src/calibre/gui2/actions/help.py @@ -13,7 +13,7 @@ from calibre.gui2.actions import InterfaceAction class HelpAction(InterfaceAction): name = 'Help' - action_spec = (_('Help'), 'help.svg', _('Browse the calibre User Manual'), _('F1'),) + action_spec = (_('Help'), 'help.png', _('Browse the calibre User Manual'), _('F1'),) def genesis(self): self.qaction.triggered.connect(self.show_help) diff --git a/src/calibre/gui2/actions/open.py b/src/calibre/gui2/actions/open.py index 2c7da7b669..106bfa24f6 100644 --- a/src/calibre/gui2/actions/open.py +++ b/src/calibre/gui2/actions/open.py @@ -11,7 +11,7 @@ from calibre.gui2.actions import InterfaceAction class OpenFolderAction(InterfaceAction): name = 'Open Folder' - action_spec = (_('Open containing folder'), 'document_open.svg', None, + action_spec = (_('Open containing folder'), 'document_open.png', None, _('O')) dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) diff --git a/src/calibre/gui2/actions/preferences.py b/src/calibre/gui2/actions/preferences.py index 267cabf9f3..a379698140 100644 --- a/src/calibre/gui2/actions/preferences.py +++ b/src/calibre/gui2/actions/preferences.py @@ -8,19 +8,19 @@ __docformat__ = 'restructuredtext en' from PyQt4.Qt import QIcon, QMenu from calibre.gui2.actions import InterfaceAction -from calibre.gui2.dialogs.config import ConfigDialog -from calibre.gui2 import error_dialog, config +from calibre.gui2.preferences.main import Preferences +from calibre.gui2 import error_dialog class PreferencesAction(InterfaceAction): name = 'Preferences' - action_spec = (_('Preferences'), 'config.svg', None, _('Ctrl+P')) + action_spec = (_('Preferences'), 'config.png', None, _('Ctrl+P')) dont_remove_from = frozenset(['toolbar']) def genesis(self): pm = QMenu() - pm.addAction(QIcon(I('config.svg')), _('Preferences'), self.do_config) - pm.addAction(QIcon(I('wizard.svg')), _('Run welcome wizard'), + pm.addAction(QIcon(I('config.png')), _('Preferences'), self.do_config) + pm.addAction(QIcon(I('wizard.png')), _('Run welcome wizard'), self.gui.run_wizard) self.qaction.setMenu(pm) self.preferences_menu = pm @@ -28,7 +28,7 @@ class PreferencesAction(InterfaceAction): x.triggered.connect(self.do_config) - def do_config(self, checked=False, initial_category='general'): + def do_config(self, checked=False, initial_plugin=None): if self.gui.job_manager.has_jobs(): d = error_dialog(self.gui, _('Cannot configure'), _('Cannot configure while there are running jobs.')) @@ -39,20 +39,12 @@ class PreferencesAction(InterfaceAction): _('Cannot configure before calibre is restarted.')) d.exec_() return - d = ConfigDialog(self.gui, self.gui.library_view, - server=self.gui.content_server, initial_category=initial_category) + d = Preferences(self.gui, initial_plugin=initial_plugin) + d.show() - d.exec_() - self.gui.content_server = d.server - if self.gui.content_server is not None: - self.gui.content_server.state_callback = \ - self.Dispatcher(self.gui.iactions['Connect Share'].content_server_state_changed) - self.gui.content_server.state_callback(self.gui.content_server.is_running) - - if d.result() == d.Accepted: - self.gui.search.search_as_you_type(config['search_as_you_type']) + if d.committed: + self.gui.must_restart_before_config = d.must_restart self.gui.tags_view.set_new_model() # in case columns changed - self.gui.iactions['Save To Disk'].reread_prefs() self.gui.tags_view.recount() self.gui.create_device_menu() self.gui.set_device_menu_items_state(bool(self.gui.device_connected)) diff --git a/src/calibre/gui2/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py index fcd7c4e332..bfcc02e130 100644 --- a/src/calibre/gui2/actions/save_to_disk.py +++ b/src/calibre/gui2/actions/save_to_disk.py @@ -37,7 +37,7 @@ class SaveMenu(QMenu): # {{{ class SaveToDiskAction(InterfaceAction): name = "Save To Disk" - action_spec = (_('Save to disk'), 'save.svg', None, _('S')) + action_spec = (_('Save to disk'), 'save.png', None, _('S')) def genesis(self): self.qaction.triggered.connect(self.save_to_disk) diff --git a/src/calibre/gui2/actions/show_book_details.py b/src/calibre/gui2/actions/show_book_details.py index 40ea29bd3b..d17d0998f1 100644 --- a/src/calibre/gui2/actions/show_book_details.py +++ b/src/calibre/gui2/actions/show_book_details.py @@ -13,7 +13,7 @@ from calibre.gui2 import error_dialog class ShowBookDetailsAction(InterfaceAction): name = 'Show Book Details' - action_spec = (_('Show book details'), 'dialog_information.svg', None, + action_spec = (_('Show book details'), 'dialog_information.png', None, _('I')) dont_add_to = frozenset(['toolbar-device', 'context-menu-device']) diff --git a/src/calibre/gui2/actions/similar_books.py b/src/calibre/gui2/actions/similar_books.py index c36eb4915b..1a14869a9c 100644 --- a/src/calibre/gui2/actions/similar_books.py +++ b/src/calibre/gui2/actions/similar_books.py @@ -20,11 +20,11 @@ class SimilarBooksAction(InterfaceAction): def genesis(self): m = QMenu(self.gui) for text, icon, target, shortcut in [ - (_('Books by same author'), 'user_profile.svg', 'authors', _('Alt+A')), - (_('Books in this series'), 'books_in_series.svg', 'series', + (_('Books by same author'), 'user_profile.png', 'authors', _('Alt+A')), + (_('Books in this series'), 'books_in_series.png', 'series', _('Alt+Shift+S')), (_('Books by this publisher'), 'publisher.png', 'publisher', _('Alt+P')), - (_('Books with the same tags'), 'tags.svg', 'tag', _('Alt+T')),]: + (_('Books with the same tags'), 'tags.png', 'tag', _('Alt+T')),]: ac = self.create_action(spec=(text, icon, None, shortcut), attr=target) m.addAction(ac) diff --git a/src/calibre/gui2/actions/view.py b/src/calibre/gui2/actions/view.py index 22592be2fe..2f6be24e5b 100644 --- a/src/calibre/gui2/actions/view.py +++ b/src/calibre/gui2/actions/view.py @@ -21,7 +21,7 @@ from calibre.gui2.actions import InterfaceAction class ViewAction(InterfaceAction): name = 'View' - action_spec = (_('View'), 'view.svg', None, _('V')) + action_spec = (_('View'), 'view.png', None, _('V')) def genesis(self): self.persistent_files = [] diff --git a/src/calibre/gui2/add_wizard/__init__.py b/src/calibre/gui2/add_wizard/__init__.py index f7518db3fc..da1879ae97 100644 --- a/src/calibre/gui2/add_wizard/__init__.py +++ b/src/calibre/gui2/add_wizard/__init__.py @@ -146,11 +146,11 @@ class Wizard(QWizard): # {{{ QWizard.__init__(self, parent) self.setModal(True) self.setWindowTitle(_('Add books to calibre')) - self.setWindowIcon(QIcon(I('add_book.svg'))) + self.setWindowIcon(QIcon(I('add_book.png'))) self.setPixmap(self.LogoPixmap, QPixmap(P('content_server/calibre.png')).scaledToHeight(80, Qt.SmoothTransformation)) self.setPixmap(self.WatermarkPixmap, - QPixmap(I('welcome_wizard.svg'))) + QPixmap(I('welcome_wizard.png'))) self.register = {} diff --git a/src/calibre/gui2/add_wizard/welcome.ui b/src/calibre/gui2/add_wizard/welcome.ui index 52fcabb714..ad820718e8 100644 --- a/src/calibre/gui2/add_wizard/welcome.ui +++ b/src/calibre/gui2/add_wizard/welcome.ui @@ -59,7 +59,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index f08dd09429..6b8d4b1d3c 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -80,7 +80,7 @@ class CoverView(QWidget): # {{{ self.setSizePolicy(QSizePolicy.Expanding if vertical else QSizePolicy.Minimum, QSizePolicy.Expanding) - self.default_pixmap = QPixmap(I('book.svg')) + self.default_pixmap = QPixmap(I('book.png')) self.pixmap = self.default_pixmap self.pwidth = self.pheight = None self.data = {} diff --git a/src/calibre/gui2/convert/__init__.py b/src/calibre/gui2/convert/__init__.py index c8f8733899..0c3a8b5a4e 100644 --- a/src/calibre/gui2/convert/__init__.py +++ b/src/calibre/gui2/convert/__init__.py @@ -7,9 +7,10 @@ __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' import textwrap +from functools import partial from PyQt4.Qt import QWidget, QSpinBox, QDoubleSpinBox, QLineEdit, QTextEdit, \ - QCheckBox, QComboBox, Qt, QIcon, SIGNAL + QCheckBox, QComboBox, Qt, QIcon, pyqtSignal from calibre.customize.conversion import OptionRecommendation from calibre.ebooks.conversion.config import load_defaults, \ @@ -39,10 +40,13 @@ def bulk_defaults_for_input_format(fmt): class Widget(QWidget): TITLE = _('Unknown') - ICON = I('config.svg') + ICON = I('config.png') HELP = '' COMMIT_NAME = None + changed_signal = pyqtSignal() + set_help = pyqtSignal(object) + def __init__(self, parent, options): QWidget.__init__(self, parent) self.setupUi(self) @@ -54,6 +58,7 @@ class Widget(QWidget): if not hasattr(self, 'opt_'+name): raise Exception('Option %s missing in %s'%(name, self.__class__.__name__)) + self.connect_gui_obj(getattr(self, 'opt_'+name)) def initialize_options(self, get_option, get_help, db=None, book_id=None): ''' @@ -76,6 +81,12 @@ class Widget(QWidget): self.apply_recommendations(defaults) self.setup_help(get_help) + def restore_defaults(self, get_option): + defaults = GuiRecommendations() + defaults.merge_recommendations(get_option, OptionRecommendation.LOW, + self._options) + self.apply_recommendations(defaults) + def commit_options(self, save_defaults=False): recs = self.create_recommendations() if save_defaults: @@ -124,6 +135,35 @@ class Widget(QWidget): else: raise Exception('Can\'t get value from %s'%type(g)) + def gui_obj_changed(self, gui_obj, *args): + self.changed_signal.emit() + + def connect_gui_obj(self, g): + f = partial(self.gui_obj_changed, g) + try: + self.connect_gui_obj_handler(g, f) + return + except NotImplementedError: + pass + from calibre.gui2.convert.xpath_wizard import XPathEdit + from calibre.gui2.convert.regex_builder import RegexEdit + if isinstance(g, (QSpinBox, QDoubleSpinBox)): + g.valueChanged.connect(f) + elif isinstance(g, (QLineEdit, QTextEdit)): + g.textChanged.connect(f) + elif isinstance(g, QComboBox): + g.editTextChanged.connect(f) + g.currentIndexChanged.connect(f) + elif isinstance(g, QCheckBox): + g.stateChanged.connect(f) + elif isinstance(g, (XPathEdit, RegexEdit)): + g.edit.editTextChanged.connect(f) + g.edit.currentIndexChanged.connect(f) + else: + raise Exception('Can\'t connect %s'%type(g)) + + def connect_gui_obj_handler(self, gui_obj, slot): + raise NotImplementedError() def set_value(self, g, val): from calibre.gui2.convert.xpath_wizard import XPathEdit @@ -154,7 +194,7 @@ class Widget(QWidget): def set_help(self, msg): if msg and getattr(msg, 'strip', lambda:True)(): try: - self.emit(SIGNAL('set_help(PyQt_PyObject)'), msg) + self.set_help.emit(msg) except: pass diff --git a/src/calibre/gui2/convert/bulk.py b/src/calibre/gui2/convert/bulk.py index 821edd08bd..f0fdf9a9a1 100644 --- a/src/calibre/gui2/convert/bulk.py +++ b/src/calibre/gui2/convert/bulk.py @@ -76,7 +76,7 @@ class BulkConfig(Config): output_widget = __import__('calibre.gui2.convert.'+name, fromlist=[1]) pw = output_widget.PluginWidget - pw.ICON = I('back.svg') + pw.ICON = I('back.png') pw.HELP = _('Options specific to the output format.') output_widget = widget_factory(pw) except ImportError: diff --git a/src/calibre/gui2/convert/comic_input.py b/src/calibre/gui2/convert/comic_input.py index c2b6bfffaa..fe86f133d1 100644 --- a/src/calibre/gui2/convert/comic_input.py +++ b/src/calibre/gui2/convert/comic_input.py @@ -15,6 +15,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('Comic Input') HELP = _('Options specific to')+' comic '+_('input') COMMIT_NAME = 'comic_input' + ICON = I('mimetypes/png.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/debug.py b/src/calibre/gui2/convert/debug.py index 6fd1975443..e9963b4892 100644 --- a/src/calibre/gui2/convert/debug.py +++ b/src/calibre/gui2/convert/debug.py @@ -17,7 +17,7 @@ from calibre.gui2 import error_dialog, choose_dir class DebugWidget(Widget, Ui_Form): TITLE = _('Debug') - ICON = I('debug.svg') + ICON = I('debug.png') HELP = _('Debug the conversion process.') COMMIT_NAME = 'debug' diff --git a/src/calibre/gui2/convert/debug.ui b/src/calibre/gui2/convert/debug.ui index 27d2c6fef0..a6db339844 100644 --- a/src/calibre/gui2/convert/debug.ui +++ b/src/calibre/gui2/convert/debug.ui @@ -41,7 +41,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png @@ -65,7 +65,7 @@ - :/images/clear_left.svg:/images/clear_left.svg + :/images/clear_left.png:/images/clear_left.png diff --git a/src/calibre/gui2/convert/epub_output.py b/src/calibre/gui2/convert/epub_output.py index 2d1fcdfcd8..c1ef6282f7 100644 --- a/src/calibre/gui2/convert/epub_output.py +++ b/src/calibre/gui2/convert/epub_output.py @@ -15,6 +15,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('EPUB Output') HELP = _('Options specific to')+' EPUB '+_('output') COMMIT_NAME = 'epub_output' + ICON = I('mimetypes/epub.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/fb2_input.py b/src/calibre/gui2/convert/fb2_input.py index 702f87754f..ae4093eb07 100644 --- a/src/calibre/gui2/convert/fb2_input.py +++ b/src/calibre/gui2/convert/fb2_input.py @@ -12,6 +12,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('FB2 Input') HELP = _('Options specific to')+' FB2 '+_('input') COMMIT_NAME = 'fb2_input' + ICON = I('mimetypes/fb2.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/fb2_output.py b/src/calibre/gui2/convert/fb2_output.py index 145b14f8c9..a3cbe0e647 100644 --- a/src/calibre/gui2/convert/fb2_output.py +++ b/src/calibre/gui2/convert/fb2_output.py @@ -14,6 +14,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('FB2 Output') HELP = _('Options specific to')+' FB2 '+_('output') COMMIT_NAME = 'fb2_output' + ICON = I('mimetypes/fb2.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, ['inline_toc', 'sectionize_chapters']) diff --git a/src/calibre/gui2/convert/font_key.ui b/src/calibre/gui2/convert/font_key.ui index 41d355b9c6..6c8ad2be01 100644 --- a/src/calibre/gui2/convert/font_key.ui +++ b/src/calibre/gui2/convert/font_key.ui @@ -15,7 +15,7 @@ - :/images/wizard.svg:/images/wizard.svg + :/images/wizard.png:/images/wizard.png diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py index c5f579fc9e..b0403bf1dd 100644 --- a/src/calibre/gui2/convert/look_and_feel.py +++ b/src/calibre/gui2/convert/look_and_feel.py @@ -14,7 +14,7 @@ from calibre.gui2.convert import Widget class LookAndFeelWidget(Widget, Ui_Form): TITLE = _('Look & Feel') - ICON = I('lookfeel.svg') + ICON = I('lookfeel.png') HELP = _('Control the look and feel of the output') COMMIT_NAME = 'look_and_feel' diff --git a/src/calibre/gui2/convert/look_and_feel.ui b/src/calibre/gui2/convert/look_and_feel.ui index ad8f0a42a9..de48e7caf9 100644 --- a/src/calibre/gui2/convert/look_and_feel.ui +++ b/src/calibre/gui2/convert/look_and_feel.ui @@ -85,7 +85,7 @@ - :/images/wizard.svg:/images/wizard.svg + :/images/wizard.png:/images/wizard.png diff --git a/src/calibre/gui2/convert/lrf_output.py b/src/calibre/gui2/convert/lrf_output.py index 1b4f1acad3..75764164dd 100644 --- a/src/calibre/gui2/convert/lrf_output.py +++ b/src/calibre/gui2/convert/lrf_output.py @@ -19,6 +19,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('LRF Output') HELP = _('Options specific to')+' LRF '+_('output') COMMIT_NAME = 'lrf_output' + ICON = I('mimetypes/lrf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index daabd6226a..ea62b61f6a 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -39,7 +39,7 @@ def create_cover_file(db, book_id): class MetadataWidget(Widget, Ui_Form): TITLE = _('Metadata') - ICON = I('dialog_information.svg') + ICON = I('dialog_information.png') HELP = _('Set the metadata. The output file will contain as much of this ' 'metadata as possible.') COMMIT_NAME = 'metadata' @@ -89,7 +89,7 @@ class MetadataWidget(Widget, Ui_Form): self.cover.setPixmap(pm) self.cover_data = cover else: - self.cover.setPixmap(QPixmap(I('default_cover.svg'))) + self.cover.setPixmap(QPixmap(I('default_cover.png'))) def initialize_combos(self): diff --git a/src/calibre/gui2/convert/metadata.ui b/src/calibre/gui2/convert/metadata.ui index 7bc45e234e..a594f47b5d 100644 --- a/src/calibre/gui2/convert/metadata.ui +++ b/src/calibre/gui2/convert/metadata.ui @@ -87,7 +87,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index 7eff3b55a2..23c0b30253 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -20,6 +20,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('MOBI Output') HELP = _('Options specific to')+' MOBI '+_('output') COMMIT_NAME = 'mobi_output' + ICON = I('mimetypes/mobi.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/page_setup.py b/src/calibre/gui2/convert/page_setup.py index e824c18b57..a0ca16297c 100644 --- a/src/calibre/gui2/convert/page_setup.py +++ b/src/calibre/gui2/convert/page_setup.py @@ -36,6 +36,7 @@ class PageSetupWidget(Widget, Ui_Form): COMMIT_NAME = 'page_setup' def __init__(self, parent, get_option, get_help, db=None, book_id=None): + self.__connections = [] Widget.__init__(self, parent, ['margin_top', 'margin_left', 'margin_right', 'margin_bottom', 'input_profile', 'output_profile'] @@ -46,6 +47,10 @@ class PageSetupWidget(Widget, Ui_Form): self.output_model = ProfileModel(output_profiles()) self.opt_input_profile.setModel(self.input_model) self.opt_output_profile.setModel(self.output_model) + for g, slot in self.__connections: + g.selectionModel().currentChanged.connect(slot) + del self.__connections + for x in (self.opt_input_profile, self.opt_output_profile): x.setMouseTracking(True) self.connect(x, SIGNAL('entered(QModelIndex)'), self.show_desc) @@ -55,12 +60,15 @@ class PageSetupWidget(Widget, Ui_Form): it = unicode(self.opt_output_profile.toolTip()) self.opt_output_profile.setToolTip('

'+it.replace('t.','ce.\n
')) - - def show_desc(self, index): desc = index.model().data(index, Qt.StatusTipRole).toString() self.profile_description.setText(desc) + def connect_gui_obj_handler(self, g, slot): + if g not in (self.opt_input_profile, self.opt_output_profile): + raise NotImplementedError() + self.__connections.append((g, slot)) + def set_value_handler(self, g, val): if g in (self.opt_input_profile, self.opt_output_profile): g.clearSelection() diff --git a/src/calibre/gui2/convert/pdb_input.py b/src/calibre/gui2/convert/pdb_input.py index 6adc49c3ed..4510cf81ba 100644 --- a/src/calibre/gui2/convert/pdb_input.py +++ b/src/calibre/gui2/convert/pdb_input.py @@ -12,6 +12,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('PDB Input') HELP = _('Options specific to')+' PDB '+_('input') COMMIT_NAME = 'pdb_input' + ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/pdb_output.py b/src/calibre/gui2/convert/pdb_output.py index 3f9d9ad3dc..9f88656f2f 100644 --- a/src/calibre/gui2/convert/pdb_output.py +++ b/src/calibre/gui2/convert/pdb_output.py @@ -16,6 +16,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('PDB Output') HELP = _('Options specific to')+' PDB '+_('output') COMMIT_NAME = 'pdb_output' + ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, ['format', 'inline_toc']) diff --git a/src/calibre/gui2/convert/pdf_input.py b/src/calibre/gui2/convert/pdf_input.py index 511091ae85..967a0fe234 100644 --- a/src/calibre/gui2/convert/pdf_input.py +++ b/src/calibre/gui2/convert/pdf_input.py @@ -12,6 +12,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('PDF Input') HELP = _('Options specific to')+' PDF '+_('input') COMMIT_NAME = 'pdf_input' + ICON = I('mimetypes/pdf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/pdf_output.py b/src/calibre/gui2/convert/pdf_output.py index de0a34a508..5d6a595079 100644 --- a/src/calibre/gui2/convert/pdf_output.py +++ b/src/calibre/gui2/convert/pdf_output.py @@ -17,6 +17,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('PDF Output') HELP = _('Options specific to')+' PDF '+_('output') COMMIT_NAME = 'pdf_output' + ICON = I('mimetypes/pdf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, ['paper_size', diff --git a/src/calibre/gui2/convert/rb_output.py b/src/calibre/gui2/convert/rb_output.py index 5f8a961899..25d1d8b0e0 100644 --- a/src/calibre/gui2/convert/rb_output.py +++ b/src/calibre/gui2/convert/rb_output.py @@ -14,6 +14,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('RB Output') HELP = _('Options specific to')+' RB '+_('output') COMMIT_NAME = 'rb_output' + ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, ['inline_toc']) diff --git a/src/calibre/gui2/convert/single.py b/src/calibre/gui2/convert/single.py index b5cba20c2f..7fa8c29835 100644 --- a/src/calibre/gui2/convert/single.py +++ b/src/calibre/gui2/convert/single.py @@ -181,7 +181,7 @@ class Config(ResizableDialog, Ui_Dialog): output_widget = __import__('calibre.gui2.convert.'+name, fromlist=[1]) pw = output_widget.PluginWidget - pw.ICON = I('back.svg') + pw.ICON = I('back.png') pw.HELP = _('Options specific to the output format.') output_widget = widget_factory(pw) except ImportError: @@ -192,7 +192,7 @@ class Config(ResizableDialog, Ui_Dialog): input_widget = __import__('calibre.gui2.convert.'+name, fromlist=[1]) pw = input_widget.PluginWidget - pw.ICON = I('forward.svg') + pw.ICON = I('forward.png') pw.HELP = _('Options specific to the input format.') input_widget = widget_factory(pw) except ImportError: diff --git a/src/calibre/gui2/convert/single.ui b/src/calibre/gui2/convert/single.ui index 5b976a5cfb..ede548d8d7 100644 --- a/src/calibre/gui2/convert/single.ui +++ b/src/calibre/gui2/convert/single.ui @@ -15,7 +15,7 @@ - :/images/convert.svg:/images/convert.svg + :/images/convert.png:/images/convert.png diff --git a/src/calibre/gui2/convert/structure_detection.py b/src/calibre/gui2/convert/structure_detection.py index cc1a16c617..f2ca49d1bd 100644 --- a/src/calibre/gui2/convert/structure_detection.py +++ b/src/calibre/gui2/convert/structure_detection.py @@ -15,7 +15,7 @@ from calibre.gui2 import error_dialog class StructureDetectionWidget(Widget, Ui_Form): TITLE = _('Structure\nDetection') - ICON = I('chapters.svg') + ICON = I('chapters.png') HELP = _('Fine tune the detection of chapter headings and ' 'other document structure.') COMMIT_NAME = 'structure_detection' diff --git a/src/calibre/gui2/convert/toc.py b/src/calibre/gui2/convert/toc.py index 0908aba576..8121f23192 100644 --- a/src/calibre/gui2/convert/toc.py +++ b/src/calibre/gui2/convert/toc.py @@ -14,7 +14,7 @@ from calibre.gui2 import error_dialog class TOCWidget(Widget, Ui_Form): TITLE = _('Table of\nContents') - ICON = I('series.svg') + ICON = I('series.png') HELP = _('Control the creation/conversion of the Table of Contents.') COMMIT_NAME = 'toc' diff --git a/src/calibre/gui2/convert/txt_input.py b/src/calibre/gui2/convert/txt_input.py index 006c06dd00..31019251e2 100644 --- a/src/calibre/gui2/convert/txt_input.py +++ b/src/calibre/gui2/convert/txt_input.py @@ -12,6 +12,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('TXT Input') HELP = _('Options specific to')+' TXT '+_('input') COMMIT_NAME = 'txt_input' + ICON = I('mimetypes/txt.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/txt_output.py b/src/calibre/gui2/convert/txt_output.py index 1accd08485..8b2e131ec6 100644 --- a/src/calibre/gui2/convert/txt_output.py +++ b/src/calibre/gui2/convert/txt_output.py @@ -16,6 +16,7 @@ class PluginWidget(Widget, Ui_Form): TITLE = _('TXT Output') HELP = _('Options specific to')+' TXT '+_('output') COMMIT_NAME = 'txt_output' + ICON = I('mimetypes/txt.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, diff --git a/src/calibre/gui2/convert/xexp_edit.ui b/src/calibre/gui2/convert/xexp_edit.ui index f3427bce23..7e89ec5d43 100644 --- a/src/calibre/gui2/convert/xexp_edit.ui +++ b/src/calibre/gui2/convert/xexp_edit.ui @@ -60,7 +60,7 @@ - :/images/wizard.svg:/images/wizard.svg + :/images/wizard.png:/images/wizard.png diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 0e89358c53..67ab94d29a 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -57,7 +57,7 @@ class Bool(Base): QComboBox(parent)] w = self.widgets[1] items = [_('Yes'), _('No'), _('Undefined')] - icons = [I('ok.svg'), I('list_remove.svg'), I('blank.svg')] + icons = [I('ok.png'), I('list_remove.png'), I('blank.png')] if tweaks['bool_custom_columns_are_tristate'] == 'no': items = items[:-1] icons = icons[:-1] diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index bc79a3c9de..5fb8b1028b 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -9,9 +9,8 @@ from itertools import repeat from functools import partial from binascii import unhexlify -from PyQt4.Qt import QMenu, QAction, QActionGroup, QIcon, SIGNAL, QPixmap, \ - Qt, pyqtSignal, QColor, QPainter, QDialog, QMessageBox -from PyQt4.QtSvg import QSvgRenderer +from PyQt4.Qt import QMenu, QAction, QActionGroup, QIcon, SIGNAL, \ + Qt, pyqtSignal, QDialog, QMessageBox from calibre.customize.ui import available_input_formats, available_output_formats, \ device_plugins @@ -21,7 +20,7 @@ from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.utils.ipc.job import BaseJob from calibre.devices.scanner import DeviceScanner from calibre.gui2 import config, error_dialog, Dispatcher, dynamic, \ - pixmap_to_data, warning_dialog, \ + warning_dialog, \ question_dialog, info_dialog, choose_dir from calibre.ebooks.metadata import authors_to_string from calibre import preferred_encoding, prints @@ -34,7 +33,7 @@ from calibre.devices.folder_device.driver import FOLDER_DEVICE from calibre.ebooks.metadata.meta import set_metadata from calibre.constants import DEBUG from calibre.utils.config import prefs, tweaks - +from calibre.utils.magick.draw import thumbnail # }}} class DeviceJob(BaseJob): # {{{ @@ -417,33 +416,33 @@ class DeviceMenu(QMenu): # {{{ self._memory = [] self.set_default_menu = QMenu(_('Set default send to device action')) - self.set_default_menu.setIcon(QIcon(I('config.svg'))) + self.set_default_menu.setIcon(QIcon(I('config.png'))) basic_actions = [ - ('main:', False, False, I('reader.svg'), + ('main:', False, False, I('reader.png'), _('Send to main memory')), - ('carda:0', False, False, I('sd.svg'), + ('carda:0', False, False, I('sd.png'), _('Send to storage card A')), - ('cardb:0', False, False, I('sd.svg'), + ('cardb:0', False, False, I('sd.png'), _('Send to storage card B')), ] delete_actions = [ - ('main:', True, False, I('reader.svg'), + ('main:', True, False, I('reader.png'), _('Main Memory')), - ('carda:0', True, False, I('sd.svg'), + ('carda:0', True, False, I('sd.png'), _('Storage Card A')), - ('cardb:0', True, False, I('sd.svg'), + ('cardb:0', True, False, I('sd.png'), _('Storage Card B')), ] specific_actions = [ - ('main:', False, True, I('reader.svg'), + ('main:', False, True, I('reader.png'), _('Main Memory')), - ('carda:0', False, True, I('sd.svg'), + ('carda:0', False, True, I('sd.png'), _('Storage Card A')), - ('cardb:0', False, True, I('sd.svg'), + ('cardb:0', False, True, I('sd.png'), _('Storage Card B')), ] @@ -488,7 +487,7 @@ class DeviceMenu(QMenu): # {{{ self.group.triggered.connect(self.change_default_action) self.addSeparator() - mitem = self.addAction(QIcon(I('eject.svg')), _('Eject device')) + mitem = self.addAction(QIcon(I('eject.png')), _('Eject device')) mitem.setEnabled(False) mitem.triggered.connect(lambda x : self.disconnect_mounted_device.emit()) self.disconnect_mounted_device_action = mitem @@ -617,14 +616,8 @@ class DeviceMixin(object): # {{{ self.connect_to_folder_named(tweaks['auto_connect_to_folder']) def set_default_thumbnail(self, height): - r = QSvgRenderer(I('book.svg')) - pixmap = QPixmap(height, height) - pixmap.fill(QColor(255,255,255)) - p = QPainter(pixmap) - r.render(p) - p.end() - self.default_thumbnail = (pixmap.width(), pixmap.height(), - pixmap_to_data(pixmap)) + img = I('book.png', data=True) + self.default_thumbnail = thumbnail(img, height, height) def connect_to_folder_named(self, folder): if os.path.exists(folder) and os.path.isdir(folder): @@ -959,13 +952,12 @@ class DeviceMixin(object): # {{{ self.library_view.model().delete_books_by_id(remove) def cover_to_thumbnail(self, data): - p = QPixmap() - p.loadFromData(data) - if not p.isNull(): - ht = self.device_manager.device.THUMBNAIL_HEIGHT \ - if self.device_manager else DevicePlugin.THUMBNAIL_HEIGHT - p = p.scaledToHeight(ht, Qt.SmoothTransformation) - return (p.width(), p.height(), pixmap_to_data(p)) + ht = self.device_manager.device.THUMBNAIL_HEIGHT \ + if self.device_manager else DevicePlugin.THUMBNAIL_HEIGHT + try: + return thumbnail(data, ht, ht) + except: + pass def email_news(self, id): opts = email_config().parse() diff --git a/src/calibre/gui2/device_drivers/configwidget.ui b/src/calibre/gui2/device_drivers/configwidget.ui index 497ba43259..1e8ee75852 100644 --- a/src/calibre/gui2/device_drivers/configwidget.ui +++ b/src/calibre/gui2/device_drivers/configwidget.ui @@ -41,7 +41,7 @@ - :/images/arrow-up.svg:/images/arrow-up.svg + :/images/arrow-up.png:/images/arrow-up.png @@ -65,7 +65,7 @@ - :/images/arrow-down.svg:/images/arrow-down.svg + :/images/arrow-down.png:/images/arrow-down.png diff --git a/src/calibre/gui2/dialogs/add_from_isbn.ui b/src/calibre/gui2/dialogs/add_from_isbn.ui index e4882f7d18..ef4a4ebb8f 100644 --- a/src/calibre/gui2/dialogs/add_from_isbn.ui +++ b/src/calibre/gui2/dialogs/add_from_isbn.ui @@ -15,7 +15,7 @@ - :/images/add_book.svg:/images/add_book.svg + :/images/add_book.png:/images/add_book.png diff --git a/src/calibre/gui2/dialogs/book_info.ui b/src/calibre/gui2/dialogs/book_info.ui index 39f9abf3c5..18c4f8a7c8 100644 --- a/src/calibre/gui2/dialogs/book_info.ui +++ b/src/calibre/gui2/dialogs/book_info.ui @@ -70,7 +70,7 @@ - :/images/previous.svg:/images/previous.svg + :/images/previous.png:/images/previous.png @@ -81,7 +81,7 @@ - :/images/next.svg:/images/next.svg + :/images/next.png:/images/next.png diff --git a/src/calibre/gui2/dialogs/catalog.py b/src/calibre/gui2/dialogs/catalog.py index e1adbac0b3..f8e0f83746 100644 --- a/src/calibre/gui2/dialogs/catalog.py +++ b/src/calibre/gui2/dialogs/catalog.py @@ -52,7 +52,7 @@ class Catalog(QDialog, Ui_Dialog): fromlist=[1]) pw = catalog_widget.PluginWidget() pw.initialize(name) - pw.ICON = I('forward.svg') + pw.ICON = I('forward.png') self.widgets.append(pw) [self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types] except ImportError: @@ -83,7 +83,7 @@ class Catalog(QDialog, Ui_Dialog): catalog_widget = __import__(name, fromlist=[1]) pw = catalog_widget.PluginWidget() pw.initialize(name) - pw.ICON = I('forward.svg') + pw.ICON = I('forward.png') self.widgets.append(pw) [self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types] except ImportError: diff --git a/src/calibre/gui2/dialogs/choose_format.ui b/src/calibre/gui2/dialogs/choose_format.ui index 50dd4b4fc1..639d8db401 100644 --- a/src/calibre/gui2/dialogs/choose_format.ui +++ b/src/calibre/gui2/dialogs/choose_format.ui @@ -13,7 +13,7 @@ Choose Format - :/images/mimetypes/unknown.svg + :/images/mimetypes/unknown.png diff --git a/src/calibre/gui2/dialogs/choose_library.ui b/src/calibre/gui2/dialogs/choose_library.ui index ca2cfd5d96..6cf1b4386c 100644 --- a/src/calibre/gui2/dialogs/choose_library.ui +++ b/src/calibre/gui2/dialogs/choose_library.ui @@ -118,7 +118,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png diff --git a/src/calibre/gui2/dialogs/comicconf.ui b/src/calibre/gui2/dialogs/comicconf.ui index 03911b2171..b5eab32547 100644 --- a/src/calibre/gui2/dialogs/comicconf.ui +++ b/src/calibre/gui2/dialogs/comicconf.ui @@ -15,7 +15,7 @@ - :/images/convert.svg:/images/convert.svg + :/images/convert.png:/images/convert.png diff --git a/src/calibre/gui2/dialogs/config/__init__.py b/src/calibre/gui2/dialogs/config/__init__.py deleted file mode 100644 index 091b98dc86..0000000000 --- a/src/calibre/gui2/dialogs/config/__init__.py +++ /dev/null @@ -1,1028 +0,0 @@ -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' - -import os, re, time, textwrap, copy, sys - -from PyQt4.Qt import QDialog, QListWidgetItem, QIcon, \ - QVBoxLayout, QLabel, QPlainTextEdit, \ - QStringListModel, QAbstractItemModel, QFont, \ - SIGNAL, QThread, Qt, QSize, QVariant, QUrl, \ - QModelIndex, QAbstractTableModel, \ - QDialogButtonBox, QTabWidget, QBrush, QLineEdit, \ - QProgressDialog - -from calibre.constants import iswindows, isosx -from calibre.gui2.dialogs.config.config_ui import Ui_Dialog -from calibre.gui2.dialogs.config.create_custom_column import CreateCustomColumn -from calibre.gui2.dialogs.config.toolbar import ToolbarLayout -from calibre.gui2 import error_dialog, config, gprefs, \ - open_url, open_local_file, \ - ALL_COLUMNS, NONE, info_dialog, choose_files, \ - warning_dialog, ResizableDialog, question_dialog -from calibre.utils.config import prefs, read_raw_tweaks, write_tweaks -from calibre.ebooks import BOOK_EXTENSIONS -from calibre.ebooks.oeb.iterator import is_supported -from calibre.library.server import server_config -from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \ - disable_plugin, customize_plugin, \ - plugin_customization, add_plugin, \ - remove_plugin, all_input_formats, \ - input_format_plugins, \ - output_format_plugins, available_output_formats -from calibre.utils.smtp import config as smtp_prefs -from calibre.gui2.convert import config_widget_for_input_plugin -from calibre.gui2.convert.look_and_feel import LookAndFeelWidget -from calibre.gui2.convert.page_setup import PageSetupWidget -from calibre.gui2.convert.structure_detection import StructureDetectionWidget -from calibre.ebooks.conversion.plumber import Plumber -from calibre.utils.logging import Log -from calibre.gui2.convert.toc import TOCWidget -from calibre.utils.search_query_parser import saved_searches - - -class ConfigTabs(QTabWidget): - - def __init__(self, parent): - QTabWidget.__init__(self, parent) - log = Log() - log.outputs = [] - - self.plumber = Plumber('dummy.epub', 'dummy.epub', log, dummy=True, - merge_plugin_recs=False) - - def widget_factory(cls): - return cls(self, self.plumber.get_option_by_name, - self.plumber.get_option_help, None, None) - - lf = widget_factory(LookAndFeelWidget) - ps = widget_factory(PageSetupWidget) - sd = widget_factory(StructureDetectionWidget) - toc = widget_factory(TOCWidget) - - self.widgets = [lf, ps, sd, toc] - - for plugin in input_format_plugins(): - pw = config_widget_for_input_plugin(plugin) - if pw is not None: - pw.ICON = I('forward.svg') - self.widgets.append(widget_factory(pw)) - - for plugin in output_format_plugins(): - name = plugin.name.lower().replace(' ', '_') - try: - output_widget = __import__('calibre.gui2.convert.'+name, - fromlist=[1]) - pw = output_widget.PluginWidget - pw.ICON = I('forward.svg') - self.widgets.append(widget_factory(pw)) - except ImportError: - continue - - for i, widget in enumerate(self.widgets): - self.addTab(widget, widget.TITLE.replace('\n', ' ').replace('&', - '&&')) - self.setTabToolTip(i, widget.HELP if widget.HELP else widget.TITLE) - self.setUsesScrollButtons(True) - - def commit(self): - for widget in self.widgets: - if not widget.pre_commit_check(): - return False - widget.commit(save_defaults=True) - return True - -class PluginModel(QAbstractItemModel): - - def __init__(self, *args): - QAbstractItemModel.__init__(self, *args) - self.icon = QVariant(QIcon(I('plugins.svg'))) - p = QIcon(self.icon).pixmap(32, 32, QIcon.Disabled, QIcon.On) - self.disabled_icon = QVariant(QIcon(p)) - self._p = p - self.populate() - - def populate(self): - self._data = {} - for plugin in initialized_plugins(): - if plugin.type not in self._data: - self._data[plugin.type] = [plugin] - else: - self._data[plugin.type].append(plugin) - self.categories = sorted(self._data.keys()) - - for plugins in self._data.values(): - plugins.sort(cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())) - - def index(self, row, column, parent): - if not self.hasIndex(row, column, parent): - return QModelIndex() - - if parent.isValid(): - return self.createIndex(row, column, 1+parent.row()) - else: - return self.createIndex(row, column, 0) - - def parent(self, index): - if not index.isValid() or index.internalId() == 0: - return QModelIndex() - return self.createIndex(index.internalId()-1, 0, 0) - - def rowCount(self, parent): - if not parent.isValid(): - return len(self.categories) - if parent.internalId() == 0: - category = self.categories[parent.row()] - return len(self._data[category]) - return 0 - - def columnCount(self, parent): - return 1 - - def index_to_plugin(self, index): - category = self.categories[index.parent().row()] - return self._data[category][index.row()] - - def plugin_to_index(self, plugin): - for i, category in enumerate(self.categories): - parent = self.index(i, 0, QModelIndex()) - for j, p in enumerate(self._data[category]): - if plugin == p: - return self.index(j, 0, parent) - return QModelIndex() - - def refresh_plugin(self, plugin, rescan=False): - if rescan: - self.populate() - idx = self.plugin_to_index(plugin) - self.emit(SIGNAL('dataChanged(QModelIndex,QModelIndex)'), idx, idx) - - def flags(self, index): - if not index.isValid(): - return 0 - if index.internalId() == 0: - return Qt.ItemIsEnabled - flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled - return flags - - def data(self, index, role): - if not index.isValid(): - return NONE - if index.internalId() == 0: - if role == Qt.DisplayRole: - category = self.categories[index.row()] - return QVariant(_("%(plugin_type)s %(plugins)s")%\ - dict(plugin_type=category, plugins=_('plugins'))) - else: - plugin = self.index_to_plugin(index) - if role == Qt.DisplayRole: - ver = '.'.join(map(str, plugin.version)) - desc = '\n'.join(textwrap.wrap(plugin.description, 50)) - ans='%s (%s) %s %s\n%s'%(plugin.name, ver, _('by'), plugin.author, desc) - c = plugin_customization(plugin) - if c: - ans += _('\nCustomization: ')+c - return QVariant(ans) - if role == Qt.DecorationRole: - return self.disabled_icon if is_disabled(plugin) else self.icon - if role == Qt.ForegroundRole and is_disabled(plugin): - return QVariant(QBrush(Qt.gray)) - if role == Qt.UserRole: - return plugin - return NONE - - - -class CategoryModel(QStringListModel): - - CATEGORIES = [ - ('general', _('General'), 'dialog_information.svg'), - ('interface', _('Interface'), 'lookfeel.svg'), - ('conversion', _('Conversion'), 'convert.svg'), - ('email', _('Email\nDelivery'), 'mail.svg'), - ('add/save', _('Add/Save'), 'save.svg'), - ('advanced', _('Advanced'), 'view.svg'), - ('server', _('Content\nServer'), 'network-server.svg'), - ('plugins', _('Plugins'), 'plugins.svg'), - ] - - def __init__(self, *args): - QStringListModel.__init__(self, *args) - self.setStringList([x[1] for x in self.CATEGORIES]) - - def data(self, index, role): - if role == Qt.DecorationRole: - return QVariant(QIcon(I(self.CATEGORIES[index.row()][2]))) - return QStringListModel.data(self, index, role) - - def index_for_name(self, name): - for i, x in enumerate(self.CATEGORIES): - if x[0] == name: - return self.index(i) - return self.index(0) - -class EmailAccounts(QAbstractTableModel): - - def __init__(self, accounts): - QAbstractTableModel.__init__(self) - self.accounts = accounts - self.account_order = sorted(self.accounts.keys()) - self.headers = map(QVariant, [_('Email'), _('Formats'), _('Auto send')]) - self.default_font = QFont() - self.default_font.setBold(True) - self.default_font = QVariant(self.default_font) - self.tooltips =[NONE] + map(QVariant, - [_('Formats to email. The first matching format will be sent.'), - '

'+_('If checked, downloaded news will be automatically ' - 'mailed
to this email address ' - '(provided it is in one of the listed formats).')]) - - def rowCount(self, *args): - return len(self.account_order) - - def columnCount(self, *args): - return 3 - - def headerData(self, section, orientation, role): - if role == Qt.DisplayRole and orientation == Qt.Horizontal: - return self.headers[section] - return NONE - - def data(self, index, role): - row, col = index.row(), index.column() - if row < 0 or row >= self.rowCount(): - return NONE - account = self.account_order[row] - if role == Qt.UserRole: - return (account, self.accounts[account]) - if role == Qt.ToolTipRole: - return self.tooltips[col] - if role in [Qt.DisplayRole, Qt.EditRole]: - if col == 0: - return QVariant(account) - if col == 1: - return QVariant(self.accounts[account][0]) - if role == Qt.FontRole and self.accounts[account][2]: - return self.default_font - if role == Qt.CheckStateRole and col == 2: - return QVariant(Qt.Checked if self.accounts[account][1] else Qt.Unchecked) - return NONE - - def flags(self, index): - if index.column() == 2: - return QAbstractTableModel.flags(self, index)|Qt.ItemIsUserCheckable - else: - return QAbstractTableModel.flags(self, index)|Qt.ItemIsEditable - - def setData(self, index, value, role): - if not index.isValid(): - return False - row, col = index.row(), index.column() - account = self.account_order[row] - if col == 2: - self.accounts[account][1] ^= True - elif col == 1: - self.accounts[account][0] = unicode(value.toString()).upper() - else: - na = unicode(value.toString()) - from email.utils import parseaddr - addr = parseaddr(na)[-1] - if not addr: - return False - self.accounts[na] = self.accounts.pop(account) - self.account_order[row] = na - if '@kindle.com' in addr: - self.accounts[na][0] = 'AZW, MOBI, TPZ, PRC, AZW1' - - self.emit(SIGNAL('dataChanged(QModelIndex,QModelIndex)'), - self.index(index.row(), 0), self.index(index.row(), 2)) - return True - - def make_default(self, index): - if index.isValid(): - row = index.row() - for x in self.accounts.values(): - x[2] = False - self.accounts[self.account_order[row]][2] = True - self.reset() - - def add(self): - x = _('new email address') - y = x - c = 0 - while y in self.accounts: - c += 1 - y = x + str(c) - auto_send = len(self.accounts) < 1 - self.accounts[y] = ['MOBI, EPUB', auto_send, - len(self.account_order) == 0] - self.account_order = sorted(self.accounts.keys()) - self.reset() - return self.index(self.account_order.index(y), 0) - - def remove(self, index): - if index.isValid(): - row = index.row() - account = self.account_order[row] - self.accounts.pop(account) - self.account_order = sorted(self.accounts.keys()) - has_default = False - for account in self.account_order: - if self.accounts[account][2]: - has_default = True - break - if not has_default and self.account_order: - self.accounts[self.account_order[0]][2] = True - - self.reset() - - -class ConfigDialog(ResizableDialog, Ui_Dialog): - - def category_current_changed(self, n, p): - self.stackedWidget.setCurrentIndex(n.row()) - - def __init__(self, parent, library_view, server=None, - initial_category='general'): - ResizableDialog.__init__(self, parent) - self._category_model = CategoryModel() - - self.category_view.currentChanged = self.category_current_changed - self.category_view.setModel(self._category_model) - self.parent = parent - self.library_view = library_view - self.model = library_view.model() - self.db = self.model.db - self.server = server - self.connect(self.compact_button, SIGNAL('clicked(bool)'), self.compact) - - input_map = prefs['input_format_order'] - all_formats = set() - for fmt in all_input_formats().union(set(['ZIP', 'RAR'])): - all_formats.add(fmt.upper()) - for format in input_map + list(all_formats.difference(input_map)): - item = QListWidgetItem(format, self.input_order) - item.setData(Qt.UserRole, QVariant(format)) - item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable) - - self.connect(self.input_up, SIGNAL('clicked()'), self.up_input) - self.connect(self.input_down, SIGNAL('clicked()'), self.down_input) - - rn = config['use_roman_numerals_for_series_number'] - self.timeout.setValue(prefs['network_timeout']) - self.roman_numerals.setChecked(rn) - self.new_version_notification.setChecked(config['new_version_notification']) - - # Set up columns - colmap = list(self.model.column_map) - state = self.library_view.get_state() - hidden_cols = state['hidden_columns'] - positions = state['column_positions'] - colmap.sort(cmp=lambda x,y: cmp(positions[x], positions[y])) - self.custcols = copy.deepcopy(self.db.field_metadata.get_custom_field_metadata()) - for col in colmap: - item = QListWidgetItem(self.model.headers[col], self.columns) - item.setData(Qt.UserRole, QVariant(col)) - flags = Qt.ItemIsEnabled|Qt.ItemIsSelectable - if col != 'ondevice': - flags |= Qt.ItemIsUserCheckable - item.setFlags(flags) - if col != 'ondevice': - item.setCheckState(Qt.Unchecked if col in hidden_cols else - Qt.Checked) - self.column_up.clicked.connect(self.up_column) - self.column_down.clicked.connect(self.down_column) - self.del_custcol_button.clicked.connect(self.del_custcol) - self.add_custcol_button.clicked.connect(self.add_custcol) - self.edit_custcol_button.clicked.connect(self.edit_custcol) - - output_formats = sorted(available_output_formats()) - output_formats.remove('oeb') - for f in output_formats: - self.output_format.addItem(f.upper()) - default_index = \ - self.output_format.findText(prefs['output_format'].upper()) - self.output_format.setCurrentIndex(default_index if default_index != -1 else 0) - - - self.cover_browse.setValue(config['cover_flow_queue_length']) - self.systray_notifications.setChecked(not config['disable_tray_notification']) - from calibre.utils.localization import available_translations, \ - get_language, get_lang - lang = get_lang() - if lang is None or lang not in available_translations(): - lang = 'en' - self.language.addItem(get_language(lang), QVariant(lang)) - items = [(l, get_language(l)) for l in available_translations() \ - if l != lang] - if lang != 'en': - items.append(('en', get_language('en'))) - items.sort(cmp=lambda x, y: cmp(x[1], y[1])) - for item in items: - self.language.addItem(item[1], QVariant(item[0])) - - exts = set([]) - for ext in BOOK_EXTENSIONS: - ext = ext.lower() - ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext) - if ext == 'lrf' or is_supported('book.'+ext): - exts.add(ext) - - for ext in sorted(exts): - self.viewer.addItem(ext.upper()) - self.viewer.item(self.viewer.count()-1).setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable) - self.viewer.item(self.viewer.count()-1).setCheckState(Qt.Checked if ext.upper() in config['internally_viewed_formats'] else Qt.Unchecked) - self.viewer.sortItems() - self.start.setEnabled(not getattr(self.server, 'is_running', False)) - self.test.setEnabled(not self.start.isEnabled()) - self.stop.setDisabled(self.start.isEnabled()) - self.connect(self.start, SIGNAL('clicked()'), self.start_server) - self.connect(self.view_logs, SIGNAL('clicked()'), self.view_server_logs) - self.connect(self.stop, SIGNAL('clicked()'), self.stop_server) - self.connect(self.test, SIGNAL('clicked()'), self.test_server) - self.connect(self.show_server_password, SIGNAL('stateChanged(int)'), - lambda s: self.password.setEchoMode(self.password.Normal if s == Qt.Checked else self.password.Password)) - self.password.setEchoMode(self.password.Password) - opts = server_config().parse() - self.max_cover_size.setText(opts.max_cover) - self.port.setValue(opts.port) - self.username.setText(opts.username) - self.password.setText(opts.password if opts.password else '') - self.opt_max_opds_items.setValue(opts.max_opds_items) - self.opt_max_opds_ungrouped_items.setValue(opts.max_opds_ungrouped_items) - self.auto_launch.setChecked(config['autolaunch_server']) - self.systray_icon.setChecked(config['systray_icon']) - self.sync_news.setChecked(config['upload_news_to_device']) - self.delete_news.setChecked(config['delete_news_from_library_on_upload']) - p = {'normal':0, 'high':1, 'low':2}[prefs['worker_process_priority']] - self.priority.setCurrentIndex(p) - self.priority.setVisible(iswindows) - self.priority_label.setVisible(iswindows) - self.new_book_tags.setText(', '.join(prefs['new_book_tags'])) - self._plugin_model = PluginModel() - self.plugin_view.setModel(self._plugin_model) - self.plugin_view.setStyleSheet( - "QTreeView::item { padding-bottom: 10px;}") - self.connect(self.toggle_plugin, SIGNAL('clicked()'), lambda : self.modify_plugin(op='toggle')) - self.connect(self.customize_plugin, SIGNAL('clicked()'), lambda : self.modify_plugin(op='customize')) - self.connect(self.remove_plugin, SIGNAL('clicked()'), lambda : self.modify_plugin(op='remove')) - self.connect(self.button_plugin_browse, SIGNAL('clicked()'), self.find_plugin) - self.connect(self.button_plugin_add, SIGNAL('clicked()'), self.add_plugin) - self.connect(self.button_osx_symlinks, SIGNAL('clicked()'), - self.create_symlinks) - self.button_osx_symlinks.setVisible(isosx) - self.separate_cover_flow.setChecked(config['separate_cover_flow']) - self.setup_email_page() - self.delete_news.setEnabled(bool(self.sync_news.isChecked())) - self.connect(self.sync_news, SIGNAL('toggled(bool)'), - self.delete_news.setEnabled) - self.setup_conversion_options() - self.opt_worker_limit.setValue(config['worker_limit']) - self.connect(self.button_open_config_dir, SIGNAL('clicked()'), - self.open_config_dir) - self.opt_get_social_metadata.setChecked(config['get_social_metadata']) - self.opt_overwrite_author_title_metadata.setChecked(config['overwrite_author_title_metadata']) - self.opt_enforce_cpu_limit.setChecked(config['enforce_cpu_limit']) - self.device_detection_button.clicked.connect(self.debug_device_detection) - self.port.editingFinished.connect(self.check_port_value) - self.search_as_you_type.setChecked(config['search_as_you_type']) - self.show_avg_rating.setChecked(config['show_avg_rating']) - self.show_splash_screen.setChecked(gprefs.get('show_splash_screen', - True)) - li = None - for i, z in enumerate([('wide', _('Wide')), - ('narrow', _('Narrow'))]): - x, y = z - self.opt_gui_layout.addItem(y, QVariant(x)) - if x == config['gui_layout']: - li = i - self.opt_gui_layout.setCurrentIndex(li) - restrictions = sorted(saved_searches().names(), - cmp=lambda x,y: cmp(x.lower(), y.lower())) - restrictions.insert(0, '') - for x in ('gui', 'cs'): - w = getattr(self, 'opt_%s_restriction'%x) - w.addItems(restrictions) - idx = w.findText(self.db.prefs.get(x+'_restriction', '')) - w.setCurrentIndex(0 if idx < 0 else idx) - self.opt_disable_animations.setChecked(config['disable_animations']) - idx = 0 - for i, x in enumerate([(_('Small'), 'small'), (_('Medium'), 'medium'), - (_('Large'), 'large')]): - if x[1] == gprefs.get('toolbar_icon_size', 'medium'): - idx = i - self.opt_toolbar_icon_size.addItem(x[0], x[1]) - self.opt_toolbar_icon_size.setCurrentIndex(idx) - idx = 0 - for i, x in enumerate([(_('Automatic'), 'auto'), (_('Always'), 'always'), - (_('Never'), 'never')]): - if x[1] == gprefs.get('toolbar_text', 'auto'): - idx = i - self.opt_toolbar_text.addItem(x[0], x[1]) - self.opt_toolbar_text.setCurrentIndex(idx) - self.reset_confirmation_button.clicked.connect(self.reset_confirmation) - - deft, curt = read_raw_tweaks() - self.current_tweaks.setPlainText(curt.decode('utf-8')) - self.default_tweaks.setPlainText(deft.decode('utf-8')) - self.restore_tweaks_to_default_button.clicked.connect(self.restore_tweaks_to_default) - self.toolbar_cm_widget = ToolbarLayout(parent, parent) - self.toolbar_cm_tab.addTab(self.toolbar_cm_widget, - _('Toolbars/Context menus')) - - self.category_view.setCurrentIndex(self.category_view.model().index_for_name(initial_category)) - - def restore_tweaks_to_default(self, *args): - deft, curt = read_raw_tweaks() - self.current_tweaks.setPlainText(deft.decode('utf-8')) - - - def reset_confirmation(self): - from calibre.gui2 import dynamic - for key in dynamic.keys(): - if key.endswith('_again') and dynamic[key] is False: - dynamic[key] = True - info_dialog(self, _('Done'), - _('Confirmation dialogs have all been reset'), show=True) - - def check_port_value(self, *args): - port = self.port.value() - if port < 1025: - warning_dialog(self, _('System port selected'), '

'+ - _('The value %d you have chosen for the content ' - 'server port is a system port. Your operating ' - 'system may not allow the server to run on this ' - 'port. To be safe choose a port number larger than ' - '1024.')%port, show=True) - - def debug_device_detection(self): - from calibre.gui2.dialogs.config.device_debug import DebugDevice - d = DebugDevice(self) - d.exec_() - - def open_config_dir(self): - from calibre.utils.config import config_dir - open_local_file(config_dir) - - def create_symlinks(self): - from calibre.utils.osx_symlinks import create_symlinks - loc, paths = create_symlinks() - if loc is None: - error_dialog(self, _('Error'), - _('Failed to install command line tools.'), - det_msg=paths, show=True) - else: - info_dialog(self, _('Command line tools installed'), - '

'+_('Command line tools installed in')+' '+loc+ - '
'+ _('If you move calibre.app, you have to re-install ' - 'the command line tools.'), - det_msg='\n'.join(paths), show=True) - - def setup_conversion_options(self): - self.conversion_options = ConfigTabs(self) - self.stackedWidget.insertWidget(2, self.conversion_options) - - def setup_email_page(self): - def x(): - if self._email_accounts.account_order: - return self._email_accounts.account_order[0] - self.send_email_widget.initialize(x) - opts = self.send_email_widget.smtp_opts - self._email_accounts = EmailAccounts(opts.accounts) - self.email_view.setModel(self._email_accounts) - - self.connect(self.email_add, SIGNAL('clicked(bool)'), - self.add_email_account) - self.connect(self.email_make_default, SIGNAL('clicked(bool)'), - lambda c: self._email_accounts.make_default(self.email_view.currentIndex())) - self.email_view.resizeColumnsToContents() - self.connect(self.email_remove, SIGNAL('clicked()'), - self.remove_email_account) - - def add_email_account(self, checked): - index = self._email_accounts.add() - self.email_view.setCurrentIndex(index) - self.email_view.resizeColumnsToContents() - self.email_view.edit(index) - - def remove_email_account(self, *args): - idx = self.email_view.currentIndex() - self._email_accounts.remove(idx) - - def set_email_settings(self): - to_set = bool(self._email_accounts.accounts) - if not self.send_email_widget.set_email_settings(to_set): - return False - conf = smtp_prefs() - conf.set('accounts', self._email_accounts.accounts) - return True - - - def add_plugin(self): - path = unicode(self.plugin_path.text()) - if path and os.access(path, os.R_OK) and path.lower().endswith('.zip'): - add_plugin(path) - self._plugin_model.populate() - self._plugin_model.reset() - else: - error_dialog(self, _('No valid plugin path'), - _('%s is not a valid plugin path')%path).exec_() - - def find_plugin(self): - path = choose_files(self, 'choose plugin dialog', _('Choose plugin'), - filters=[('Plugins', ['zip'])], all_files=False, - select_only_single_file=True) - if path: - self.plugin_path.setText(path[0]) - - def modify_plugin(self, op=''): - index = self.plugin_view.currentIndex() - if index.isValid(): - plugin = self._plugin_model.index_to_plugin(index) - if op == 'toggle': - if not plugin.can_be_disabled: - error_dialog(self,_('Plugin cannot be disabled'), - _('The plugin: %s cannot be disabled')%plugin.name).exec_() - return - if is_disabled(plugin): - enable_plugin(plugin) - else: - disable_plugin(plugin) - self._plugin_model.refresh_plugin(plugin) - if op == 'customize': - if not plugin.is_customizable(): - info_dialog(self, _('Plugin not customizable'), - _('Plugin: %s does not need customization')%plugin.name).exec_() - return - config_dialog = QDialog(self) - button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - v = QVBoxLayout(config_dialog) - - config_dialog.connect(button_box, SIGNAL('accepted()'), config_dialog.accept) - config_dialog.connect(button_box, SIGNAL('rejected()'), config_dialog.reject) - config_dialog.setWindowTitle(_('Customize') + ' ' + plugin.name) - - if hasattr(plugin, 'config_widget'): - config_widget = plugin.config_widget() - v.addWidget(config_widget) - v.addWidget(button_box) - config_dialog.exec_() - - if config_dialog.result() == QDialog.Accepted: - plugin.save_settings(config_widget) - self._plugin_model.refresh_plugin(plugin) - else: - help_text = plugin.customization_help(gui=True) - help_text = QLabel(help_text, config_dialog) - help_text.setWordWrap(True) - help_text.setTextInteractionFlags(Qt.LinksAccessibleByMouse - | Qt.LinksAccessibleByKeyboard) - help_text.setOpenExternalLinks(True) - v.addWidget(help_text) - sc = plugin_customization(plugin) - if not sc: - sc = '' - sc = sc.strip() - sc = QLineEdit(sc, config_dialog) - v.addWidget(sc) - v.addWidget(button_box) - config_dialog.exec_() - - if config_dialog.result() == QDialog.Accepted: - sc = unicode(sc.text()).strip() - customize_plugin(plugin, sc) - - self._plugin_model.refresh_plugin(plugin) - elif op == 'remove': - if remove_plugin(plugin): - self._plugin_model.populate() - self._plugin_model.reset() - else: - error_dialog(self, _('Cannot remove builtin plugin'), - plugin.name + _(' cannot be removed. It is a ' - 'builtin plugin. Try disabling it instead.')).exec_() - - def up_input(self): - idx = self.input_order.currentRow() - if idx > 0: - self.input_order.insertItem(idx-1, self.input_order.takeItem(idx)) - self.input_order.setCurrentRow(idx-1) - - def set_tweaks(self): - raw = unicode(self.current_tweaks.toPlainText()).encode('utf-8') - try: - exec raw - except: - import traceback - error_dialog(self, _('Invalid tweaks'), - _('The tweaks you entered are invalid, try resetting the' - ' tweaks to default and changing them one by one until' - ' you find the invalid setting.'), - det_msg=traceback.format_exc(), show=True) - return False - write_tweaks(raw) - return True - - def down_input(self): - idx = self.input_order.currentRow() - if idx < self.input_order.count()-1: - self.input_order.insertItem(idx+1, self.input_order.takeItem(idx)) - self.input_order.setCurrentRow(idx+1) - - # Column settings {{{ - def up_column(self): - idx = self.columns.currentRow() - if idx > 0: - self.columns.insertItem(idx-1, self.columns.takeItem(idx)) - self.columns.setCurrentRow(idx-1) - - def down_column(self): - idx = self.columns.currentRow() - if idx < self.columns.count()-1: - self.columns.insertItem(idx+1, self.columns.takeItem(idx)) - self.columns.setCurrentRow(idx+1) - - def del_custcol(self): - idx = self.columns.currentRow() - if idx < 0: - return error_dialog(self, '', _('You must select a column to delete it'), - show=True) - col = unicode(self.columns.item(idx).data(Qt.UserRole).toString()) - if col not in self.custcols: - return error_dialog(self, '', - _('The selected column is not a custom column'), show=True) - if not question_dialog(self, _('Are you sure?'), - _('Do you really want to delete column %s and all its data?') % - self.custcols[col]['name'], show_copy_button=False): - return - self.columns.item(idx).setCheckState(False) - self.columns.takeItem(idx) - self.custcols[col]['*deleteme'] = True - return - - def add_custcol(self): - CreateCustomColumn(self, False, self.model.orig_headers, ALL_COLUMNS) - - def edit_custcol(self): - CreateCustomColumn(self, True, self.model.orig_headers, ALL_COLUMNS) - - def apply_custom_column_changes(self): - config_cols = [unicode(self.columns.item(i).data(Qt.UserRole).toString())\ - for i in range(self.columns.count())] - if not config_cols: - config_cols = ['title'] - removed_cols = set(self.model.column_map) - set(config_cols) - hidden_cols = set([unicode(self.columns.item(i).data(Qt.UserRole).toString())\ - for i in range(self.columns.count()) \ - if self.columns.item(i).checkState()==Qt.Unchecked]) - hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols - hidden_cols = list(hidden_cols.intersection(set(self.model.column_map))) - if 'ondevice' in hidden_cols: - hidden_cols.remove('ondevice') - def col_pos(x, y): - xidx = config_cols.index(x) if x in config_cols else sys.maxint - yidx = config_cols.index(y) if y in config_cols else sys.maxint - return cmp(xidx, yidx) - positions = {} - for i, col in enumerate((sorted(self.model.column_map, cmp=col_pos))): - positions[col] = i - state = {'hidden_columns': hidden_cols, 'column_positions':positions} - self.library_view.apply_state(state) - self.library_view.save_state() - - must_restart = False - for c in self.custcols: - if self.custcols[c]['colnum'] is None: - self.db.create_custom_column( - label=self.custcols[c]['label'], - name=self.custcols[c]['name'], - datatype=self.custcols[c]['datatype'], - is_multiple=self.custcols[c]['is_multiple'], - display = self.custcols[c]['display']) - must_restart = True - elif '*deleteme' in self.custcols[c]: - self.db.delete_custom_column(label=self.custcols[c]['label']) - must_restart = True - elif '*edited' in self.custcols[c]: - cc = self.custcols[c] - self.db.set_custom_column_metadata(cc['colnum'], name=cc['name'], - label=cc['label'], - display = self.custcols[c]['display']) - if '*must_restart' in self.custcols[c]: - must_restart = True - return must_restart - # }}} - - def view_server_logs(self): - from calibre.library.server import log_access_file, log_error_file - d = QDialog(self) - d.resize(QSize(800, 600)) - layout = QVBoxLayout() - d.setLayout(layout) - layout.addWidget(QLabel(_('Error log:'))) - el = QPlainTextEdit(d) - layout.addWidget(el) - try: - el.setPlainText(open(log_error_file, 'rb').read().decode('utf8', 'replace')) - except IOError: - el.setPlainText('No error log found') - layout.addWidget(QLabel(_('Access log:'))) - al = QPlainTextEdit(d) - layout.addWidget(al) - try: - al.setPlainText(open(log_access_file, 'rb').read().decode('utf8', 'replace')) - except IOError: - al.setPlainText('No access log found') - bx = QDialogButtonBox(QDialogButtonBox.Ok) - layout.addWidget(bx) - self.connect(bx, SIGNAL('accepted()'), d.accept) - d.show() - - def set_server_options(self): - c = server_config() - c.set('port', self.port.value()) - c.set('username', unicode(self.username.text()).strip()) - p = unicode(self.password.text()).strip() - if not p: - p = None - c.set('password', p) - - def start_server(self): - self.set_server_options() - from calibre.library.server.main import start_threaded_server - self.server = start_threaded_server(self.db, server_config().parse()) - while not self.server.is_running and self.server.exception is None: - time.sleep(1) - if self.server.exception is not None: - error_dialog(self, _('Failed to start content server'), - unicode(self.server.exception)).exec_() - return - self.start.setEnabled(False) - self.test.setEnabled(True) - self.stop.setEnabled(True) - - def stop_server(self): - from calibre.library.server.main import stop_threaded_server - stop_threaded_server(self.server) - self.server = None - self.start.setEnabled(True) - self.test.setEnabled(False) - self.stop.setEnabled(False) - - def test_server(self): - open_url(QUrl('http://127.0.0.1:'+str(self.port.value()))) - - def compact(self, toggled): - d = CheckIntegrity(self.db, self) - d.exec_() - - def accept(self): - mcs = unicode(self.max_cover_size.text()).strip() - if not re.match(r'\d+x\d+', mcs): - error_dialog(self, _('Invalid size'), - _('The size %s is invalid. must be of the form widthxheight')%mcs).exec_() - return - if not self.set_email_settings(): - return - if not self.conversion_options.commit(): - return - if not self.add_save.save_settings(): - return - if not self.set_tweaks(): - return - wl = self.opt_worker_limit.value() - if wl%2 != 0: - wl += 1 - self.toolbar_cm_widget.commit() - config['worker_limit'] = wl - - config['use_roman_numerals_for_series_number'] = bool(self.roman_numerals.isChecked()) - config['new_version_notification'] = bool(self.new_version_notification.isChecked()) - prefs['network_timeout'] = int(self.timeout.value()) - input_cols = [unicode(self.input_order.item(i).data(Qt.UserRole).toString()) for i in range(self.input_order.count())] - prefs['input_format_order'] = input_cols - - must_restart = self.apply_custom_column_changes() - - config['separate_cover_flow'] = bool(self.separate_cover_flow.isChecked()) - config['disable_tray_notification'] = not self.systray_notifications.isChecked() - p = {0:'normal', 1:'high', 2:'low'}[self.priority.currentIndex()] - prefs['worker_process_priority'] = p - nbt = [x.strip() for x in - unicode(self.new_book_tags.text()).strip().split(',')] - prefs['new_book_tags'] = [x for x in nbt if x] - prefs['output_format'] = unicode(self.output_format.currentText()).upper() - config['cover_flow_queue_length'] = self.cover_browse.value() - prefs['language'] = str(self.language.itemData(self.language.currentIndex()).toString()) - config['systray_icon'] = self.systray_icon.checkState() == Qt.Checked - config['autolaunch_server'] = self.auto_launch.isChecked() - sc = server_config() - sc.set('username', unicode(self.username.text()).strip()) - sc.set('password', unicode(self.password.text()).strip()) - sc.set('port', self.port.value()) - sc.set('max_cover', mcs) - sc.set('max_opds_items', self.opt_max_opds_items.value()) - sc.set('max_opds_ungrouped_items', - self.opt_max_opds_ungrouped_items.value()) - config['delete_news_from_library_on_upload'] = self.delete_news.isChecked() - config['upload_news_to_device'] = self.sync_news.isChecked() - config['search_as_you_type'] = self.search_as_you_type.isChecked() - config['show_avg_rating'] = self.show_avg_rating.isChecked() - config['get_social_metadata'] = self.opt_get_social_metadata.isChecked() - config['overwrite_author_title_metadata'] = self.opt_overwrite_author_title_metadata.isChecked() - config['enforce_cpu_limit'] = bool(self.opt_enforce_cpu_limit.isChecked()) - config['disable_animations'] = bool(self.opt_disable_animations.isChecked()) - gprefs['show_splash_screen'] = bool(self.show_splash_screen.isChecked()) - for x in ('toolbar_icon_size', 'toolbar_text'): - w = getattr(self, 'opt_'+x) - data = w.itemData(w.currentIndex()).toString() - gprefs[x] = unicode(data) - fmts = [] - for i in range(self.viewer.count()): - if self.viewer.item(i).checkState() == Qt.Checked: - fmts.append(str(self.viewer.item(i).text())) - config['internally_viewed_formats'] = fmts - val = self.opt_gui_layout.itemData(self.opt_gui_layout.currentIndex()).toString() - config['gui_layout'] = unicode(val) - for x in ('gui', 'cs'): - w = getattr(self, 'opt_%s_restriction'%x) - self.db.prefs.set(x+'_restriction', unicode(w.currentText())) - - if must_restart: - warning_dialog(self, _('Must restart'), - _('The changes you made require that Calibre be ' - 'restarted. Please restart as soon as practical.'), - show=True, show_copy_button=False) - self.parent.must_restart_before_config = True - QDialog.accept(self) - -class VacThread(QThread): - - def __init__(self, parent, db): - QThread.__init__(self, parent) - self.db = db - self._parent = parent - - def run(self): - err = bad = None - try: - bad = self.db.check_integrity(self.callback) - except: - import traceback - err = traceback.format_exc() - self.emit(SIGNAL('check_done(PyQt_PyObject, PyQt_PyObject)'), bad, err) - - def callback(self, progress, msg): - self.emit(SIGNAL('callback(PyQt_PyObject,PyQt_PyObject)'), progress, - msg) - -class CheckIntegrity(QProgressDialog): - - def __init__(self, db, parent=None): - QProgressDialog.__init__(self, parent) - self.db = db - self.setCancelButton(None) - self.setMinimum(0) - self.setMaximum(100) - self.setWindowTitle(_('Checking database integrity')) - self.setAutoReset(False) - self.setValue(0) - - self.vthread = VacThread(self, db) - self.connect(self.vthread, SIGNAL('check_done(PyQt_PyObject,PyQt_PyObject)'), - self.check_done, - Qt.QueuedConnection) - self.connect(self.vthread, - SIGNAL('callback(PyQt_PyObject,PyQt_PyObject)'), - self.callback, Qt.QueuedConnection) - self.vthread.start() - - def callback(self, progress, msg): - self.setLabelText(msg) - self.setValue(int(100*progress)) - - def check_done(self, bad, err): - if err: - error_dialog(self, _('Error'), - _('Failed to check database integrity'), - det_msg=err, show=True) - elif bad: - titles = [self.db.title(x, index_is_id=True) for x in bad] - det_msg = '\n'.join(titles) - warning_dialog(self, _('Some inconsistencies found'), - _('The following books had formats listed in the ' - 'database that are not actually available. ' - 'The entries for the formats have been removed. ' - 'You should check them manually. This can ' - 'happen if you manipulate the files in the ' - 'library folder directly.'), det_msg=det_msg, show=True) - self.reset() - - - -if __name__ == '__main__': - from calibre.library.database2 import LibraryDatabase2 - from PyQt4.Qt import QApplication - app = QApplication([]) - d=ConfigDialog(None, LibraryDatabase2('/tmp')) - d.show() - app.exec_() diff --git a/src/calibre/gui2/dialogs/config/add_save.py b/src/calibre/gui2/dialogs/config/add_save.py deleted file mode 100644 index 8eb6cf7bd0..0000000000 --- a/src/calibre/gui2/dialogs/config/add_save.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -from __future__ import with_statement - -__license__ = 'GPL v3' -__copyright__ = '2009, Kovid Goyal ' -__docformat__ = 'restructuredtext en' - -import textwrap - -from PyQt4.Qt import QTabWidget - -from calibre.gui2.dialogs.config.add_save_ui import Ui_TabWidget -from calibre.library.save_to_disk import config -from calibre.utils.config import prefs -from calibre.gui2.widgets import FilenamePattern - -class AddSave(QTabWidget, Ui_TabWidget): - - def __init__(self, parent=None): - QTabWidget.__init__(self, parent) - self.setupUi(self) - while self.count() > 3: - self.removeTab(3) - c = config() - opts = c.parse() - for x in ('asciiize', 'update_metadata', 'save_cover', 'write_opf', - 'replace_whitespace', 'to_lowercase'): - g = getattr(self, 'opt_'+x) - g.setChecked(getattr(opts, x)) - help = '\n'.join(textwrap.wrap(c.get_option(x).help, 75)) - g.setToolTip(help) - g.setWhatsThis(help) - - for x in ('formats', 'timefmt'): - g = getattr(self, 'opt_'+x) - g.setText(getattr(opts, x)) - help = '\n'.join(textwrap.wrap(c.get_option(x).help, 75)) - g.setToolTip(help) - g.setWhatsThis(help) - - - self.opt_read_metadata_from_filename.setChecked(not prefs['read_file_metadata']) - self.filename_pattern = FilenamePattern(self) - self.metadata_box.layout().insertWidget(0, self.filename_pattern) - self.opt_swap_author_names.setChecked(prefs['swap_author_names']) - self.opt_add_formats_to_existing.setChecked(prefs['add_formats_to_existing']) - if prefs['manage_device_metadata'] == 'manual': - self.manage_device_metadata.setCurrentIndex(0) - elif prefs['manage_device_metadata'] == 'on_send': - self.manage_device_metadata.setCurrentIndex(1) - else: - self.manage_device_metadata.setCurrentIndex(2) - help = '\n'.join(textwrap.wrap(c.get_option('template').help, 75)) - self.save_template.initialize('save_to_disk', opts.template, help) - self.send_template.initialize('send_to_device', opts.send_template, help) - - def validate(self): - return self.save_template.validate() and self.send_template.validate() - - def save_settings(self): - if not self.validate(): - return False - c = config() - for x in ('asciiize', 'update_metadata', 'save_cover', 'write_opf', - 'replace_whitespace', 'to_lowercase'): - c.set(x, getattr(self, 'opt_'+x).isChecked()) - for x in ('formats', 'timefmt'): - val = unicode(getattr(self, 'opt_'+x).text()).strip() - if x == 'formats' and not val: - val = 'all' - c.set(x, val) - self.save_template.save_settings(c, 'template') - self.send_template.save_settings(c, 'send_template') - prefs['read_file_metadata'] = not bool(self.opt_read_metadata_from_filename.isChecked()) - pattern = self.filename_pattern.commit() - prefs['filename_pattern'] = pattern - prefs['swap_author_names'] = bool(self.opt_swap_author_names.isChecked()) - prefs['add_formats_to_existing'] = bool(self.opt_add_formats_to_existing.isChecked()) - if self.manage_device_metadata.currentIndex() == 0: - prefs['manage_device_metadata'] = 'manual' - elif self.manage_device_metadata.currentIndex() == 1: - prefs['manage_device_metadata'] = 'on_send' - else: - prefs['manage_device_metadata'] = 'on_connect' - return True - -if __name__ == '__main__': - from PyQt4.Qt import QApplication - app=QApplication([]) - a = AddSave() - a.show() - app.exec_() - a.save_settings() - diff --git a/src/calibre/gui2/dialogs/config/add_save.ui b/src/calibre/gui2/dialogs/config/add_save.ui deleted file mode 100644 index c8ee0419a9..0000000000 --- a/src/calibre/gui2/dialogs/config/add_save.ui +++ /dev/null @@ -1,280 +0,0 @@ - - - TabWidget - - - - 0 - 0 - 671 - 516 - - - - TabWidget - - - 0 - - - - &Adding books - - - - - - Here you can control how calibre will read metadata from the files you add to it. calibre can either read metadata from the contents of the file, or from the filename. - - - true - - - - - - - Read metadata only from &file name - - - - - - - Swap the firstname and lastname of the author. This affects only metadata read from file names. - - - &Swap author firstname and lastname - - - - - - - If an existing book with a similar title and author is found that does not have the format being added, the format is added -to the existing book, instead of creating a new entry. If the existing book already has the format, then it is silently ignored. - -Title match ignores leading indefinite articles ("the", "a", "an"), punctuation, case, etc. Author match is exact. - - - If books with similar titles and authors found, &merge the new files automatically - - - - - - - &Configure metadata from file name - - - - - - Qt::Vertical - - - - 20 - 363 - - - - - - - - - - - - &Saving books - - - - - - Here you can control how calibre will save your books when you click the Save to Disk button: - - - true - - - - - - - Save &cover separately - - - - - - - Update &metadata in saved copies - - - - - - - Save metadata in &OPF file - - - - - - - Convert non-English characters to &English equivalents - - - - - - - Format &dates as: - - - opt_timefmt - - - - - - - - - - File &formats to save: - - - opt_formats - - - - - - - - - - Replace space with &underscores - - - - - - - Change paths to &lowercase - - - - - - - - - - - Sending to &device - - - - - - - 0 - 0 - - - - Metadata &management: - - - manage_device_metadata - - - - - - - - 0 - 0 - - - - - Manual management - - - - - Only on send - - - - - Automatic management - - - - - - - - Qt::Horizontal - - - - 313 - 20 - - - - - - - - <li><b>Manual Management</b>: Calibre updates the metadata and adds collections only when a book is sent. With this option, calibre will never remove a collection.</li> -<li><b>Only on send</b>: Calibre updates metadata and adds/removes collections for a book only when it is sent to the device. </li> -<li><b>Automatic management</b>: Calibre automatically keeps metadata on the device in sync with the calibre library, on every connect</li></ul> - - - true - - - - - - - - - - - - - - Here you can control how calibre will save your books when you click the Send to Device button. This setting can be overriden for individual devices by customizing the device interface plugins in Preferences->Plugins - - - true - - - - - - - - - - - - SaveTemplate - QWidget -

calibre/gui2/dialogs/config/save_template.h
- 1 - - - - - diff --git a/src/calibre/gui2/dialogs/config/config.ui b/src/calibre/gui2/dialogs/config/config.ui deleted file mode 100644 index 5a2bf805da..0000000000 --- a/src/calibre/gui2/dialogs/config/config.ui +++ /dev/null @@ -1,1398 +0,0 @@ - - - Kovid Goyal - Dialog - - - - 0 - 0 - 1001 - 730 - - - - Preferences - - - - :/images/config.svg:/images/config.svg - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - QAbstractItemView::NoEditTriggers - - - true - - - false - - - - 48 - 48 - - - - QAbstractItemView::ScrollPerItem - - - QAbstractItemView::ScrollPerPixel - - - QListView::TopToBottom - - - 20 - - - QListView::ListMode - - - - - - - - 1 - 0 - - - - QFrame::Plain - - - 0 - - - true - - - - - 0 - 0 - 725 - 683 - - - - - 0 - - - - - - 100 - 0 - - - - 0 - - - 0 - - - - - - - Show notification when &new version is available - - - - - - - Download &social metadata (tags/ratings/etc.) by default - - - - - - - &Overwrite author and title by default when fetching metadata - - - - - - - - - Default network &timeout: - - - timeout - - - - - - - Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information) - - - seconds - - - 2 - - - 120 - - - 5 - - - - - - - - - - Choose &language (requires restart): - - - language - - - - - - - - Normal - - - - - High - - - - - Low - - - - - - - - Job &priority: - - - priority - - - - - - - Preferred &output format: - - - output_format - - - - - - - - - - Tags to apply when adding a book: - - - new_book_tags - - - - - - - A comma-separated list of tags that will be applied to books added to the library - - - - - - - - - Reset all disabled &confirmation dialogs - - - - - - - Preferred &input format order: - - - - - - - - true - - - QAbstractItemView::SelectRows - - - - - - - - - ... - - - - :/images/arrow-up.svg:/images/arrow-up.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - ... - - - - :/images/arrow-down.svg:/images/arrow-down.svg - - - - - - - - - - - - - - - - - - 0 - - - - &Miscellaneous - - - - - - User Interface &layout (needs restart): - - - opt_gui_layout - - - - - - - - 250 - 16777215 - - - - - - - - &Number of covers to show in browse mode (needs restart): - - - cover_browse - - - - - - - - - - Restriction to apply when the current library is opened: - - - opt_gui_restriction - - - - - - - - 250 - 16777215 - - - - Apply this restriction on calibre startup if the current library is being used. Also applied when switching to this library. Note that this setting is per library. - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - 15 - - - - - - - Disable all animations. Useful if you have a slow/old computer. - - - Disable &animations - - - - - - - &Toolbar - - - - - - - - - &Icon size: - - - opt_toolbar_icon_size - - - - - - - - - - Show &text under icons: - - - opt_toolbar_text - - - - - - - - - - &Delete news from library when it is automatically sent to reader - - - - - - - - - Select visible &columns in library view - - - - - - - - true - - - QAbstractItemView::SelectRows - - - - - - - - - ... - - - - :/images/arrow-up.svg:/images/arrow-up.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Remove a user-defined column - - - ... - - - - :/images/minus.svg:/images/minus.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Add a user-defined column - - - ... - - - - :/images/plus.svg:/images/plus.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Edit settings of a user-defined column - - - ... - - - - :/images/edit_input.svg:/images/edit_input.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - ... - - - - :/images/arrow-down.svg:/images/arrow-down.svg - - - - - - - - - - - - - - Use internal &viewer for: - - - - - - true - - - QAbstractItemView::NoSelection - - - - - - - - - - - - Search as you type - - - true - - - - - - - Use &Roman numerals for series - - - true - - - - - - - Enable system &tray icon (needs restart) - - - - - - - Show &average ratings in the tags browser - - - true - - - - - - - Automatically send downloaded &news to ebook reader - - - - - - - Show &splash screen at startup - - - - - - - Show cover &browser in a separate window (needs restart) - - - - - - - Show &notifications in system tray - - - - - - - - - - - - - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - - - - - - - Add an email address to which to send books - - - &Add email - - - - :/images/plus.svg:/images/plus.svg - - - - 24 - 24 - - - - Qt::ToolButtonTextUnderIcon - - - - - - - Make &default - - - - - - - &Remove email - - - - :/images/minus.svg:/images/minus.svg - - - - 24 - 24 - - - - Qt::ToolButtonTextUnderIcon - - - - - - - - - - - calibre can send your books to you (or your reader) by email. Emails will be automatically sent for downloaded news to all email addresses that have Auto-send checked. - - - true - - - - - - - - - - - - - - - - - - - - - 0 - - - - &Miscellaneous - - - - - - &Maximum number of waiting worker processes (needs restart): - - - opt_worker_limit - - - - - - - 2 - - - 10000 - - - 2 - - - - - - - Limit the max. simultaneous jobs to the available CPU &cores - - - - - - - Qt::Vertical - - - - 20 - 79 - - - - - - - - Debug &device detection - - - - - - - Qt::Vertical - - - - 20 - 80 - - - - - - - - &Check database integrity - - - - - - - Qt::Vertical - - - - 20 - 79 - - - - - - - - Open calibre &configuration directory - - - - - - - Qt::Vertical - - - - 20 - 80 - - - - - - - - &Install command line tools - - - - - - - Qt::Vertical - - - - 20 - 79 - - - - - - - - - &Tweaks - - - - - - Values for the tweaks are shown below. Edit them to change the behavior of calibre - - - true - - - - - - - All available tweaks - - - - - - true - - - - - - - - - - &Current tweaks - - - - - - - - - - - - &Restore to defaults - - - - - - - - - - - - - - - calibre contains a network server that allows you to access your book collection using a browser from anywhere in the world. Any changes to the settings will only take effect after a server restart. - - - true - - - - - - - - - Server &port: - - - port - - - - - - - 65535 - - - 8080 - - - - - - - &Username: - - - username - - - - - - - - - - &Password: - - - password - - - - - - - If you leave the password blank, anyone will be able to access your book collection using the web interface. - - - - - - - The maximum size (widthxheight) for displayed covers. Larger covers are resized. - - - - - - - - - - Max. &cover size: - - - max_cover_size - - - - - - - &Show password - - - - - - - Max. &OPDS items per query: - - - opt_max_opds_items - - - - - - - 10 - - - 10000 - - - - - - - 25 - - - 1000000 - - - - - - - Max. OPDS &ungrouped items: - - - opt_max_opds_ungrouped_items - - - - - - - Restriction (saved search) to apply: - - - - - - - This restriction (based on a saved search) will restrict the books the content server makes available to those matching the search. This setting is per library (i.e. you can have a different restriction per library). - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - 20 - - - - - - - - - - - &Start Server - - - - - - - St&op Server - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &Test Server - - - - - - - - - Run server &automatically on startup - - - - - - - View &server logs - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <p>Remember to leave calibre running as the server only runs as long as calibre is running. -<p>Stanza should see your calibre collection automatically. If not, try adding the URL http://myhostname:8080 as a new catalog in the Stanza reader on your iPhone. Here myhostname should be the fully qualified hostname or the IP address of the computer calibre is running on. - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Here you can customize the behavior of Calibre by controlling what plugins it uses. - - - true - - - - - - - true - - - - 32 - 32 - - - - true - - - true - - - true - - - - - - - - - Enable/&Disable plugin - - - - - - - &Customize plugin - - - - - - - &Remove plugin - - - - - - - - - Add new plugin - - - - - - - - Plugin &file: - - - plugin_path - - - - - - - - - - ... - - - - :/images/document_open.svg:/images/document_open.svg - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &Add - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - SendEmail - QWidget -
calibre/gui2/wizard/send_email.h
- 1 -
- - AddSave - QTabWidget -
calibre/gui2/dialogs/config/add_save.h
- 1 -
-
- - - - - - buttonBox - accepted() - Dialog - accept() - - - 239 - 558 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 307 - 558 - - - 286 - 274 - - - - -
diff --git a/src/calibre/gui2/dialogs/config/create_custom_column.py b/src/calibre/gui2/dialogs/config/create_custom_column.py deleted file mode 100644 index c0f17b8cba..0000000000 --- a/src/calibre/gui2/dialogs/config/create_custom_column.py +++ /dev/null @@ -1,173 +0,0 @@ -__license__ = 'GPL v3' -__copyright__ = '2010, Kovid Goyal ' - -'''Dialog to create a new custom column''' - -import re -from functools import partial - -from PyQt4.QtCore import SIGNAL -from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant - -from calibre.gui2.dialogs.config.create_custom_column_ui import Ui_QCreateCustomColumn -from calibre.gui2 import error_dialog - -class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): - - column_types = { - 0:{'datatype':'text', - 'text':_('Text, column shown in the tag browser'), - 'is_multiple':False}, - 1:{'datatype':'*text', - 'text':_('Comma separated text, like tags, shown in the tag browser'), - 'is_multiple':True}, - 2:{'datatype':'comments', - 'text':_('Long text, like comments, not shown in the tag browser'), - 'is_multiple':False}, - 3:{'datatype':'series', - 'text':_('Text column for keeping series-like information'), - 'is_multiple':False}, - 4:{'datatype':'datetime', - 'text':_('Date'), 'is_multiple':False}, - 5:{'datatype':'float', - 'text':_('Floating point numbers'), 'is_multiple':False}, - 6:{'datatype':'int', - 'text':_('Integers'), 'is_multiple':False}, - 7:{'datatype':'rating', - 'text':_('Ratings, shown with stars'), - 'is_multiple':False}, - 8:{'datatype':'bool', - 'text':_('Yes/No'), 'is_multiple':False}, - } - - def __init__(self, parent, editing, standard_colheads, standard_colnames): - QDialog.__init__(self, parent) - Ui_QCreateCustomColumn.__init__(self) - self.setupUi(self) - # Remove help icon on title bar - icon = self.windowIcon() - self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) - self.setWindowIcon(icon) - - self.simple_error = partial(error_dialog, self, show=True, - show_copy_button=False) - self.connect(self.button_box, SIGNAL("accepted()"), self.accept) - self.connect(self.button_box, SIGNAL("rejected()"), self.reject) - self.parent = parent - self.editing_col = editing - self.standard_colheads = standard_colheads - self.standard_colnames = standard_colnames - for t in self.column_types: - self.column_type_box.addItem(self.column_types[t]['text']) - self.column_type_box.currentIndexChanged.connect(self.datatype_changed) - if not self.editing_col: - self.datatype_changed() - self.exec_() - return - idx = parent.columns.currentRow() - if idx < 0: - self.simple_error(_('No column selected'), - _('No column has been selected')) - return - col = unicode(parent.columns.item(idx).data(Qt.UserRole).toString()) - if col not in parent.custcols: - self.simple_error('', _('Selected column is not a user-defined column')) - return - - c = parent.custcols[col] - self.column_name_box.setText(c['label']) - self.column_heading_box.setText(c['name']) - ct = c['datatype'] if not c['is_multiple'] else '*text' - self.orig_column_number = c['colnum'] - self.orig_column_name = col - column_numbers = dict(map(lambda x:(self.column_types[x]['datatype'], x), self.column_types)) - self.column_type_box.setCurrentIndex(column_numbers[ct]) - self.column_type_box.setEnabled(False) - if ct == 'datetime': - if c['display'].get('date_format', None): - self.date_format_box.setText(c['display'].get('date_format', '')) - self.datatype_changed() - self.exec_() - - def datatype_changed(self, *args): - try: - col_type = self.column_types[self.column_type_box.currentIndex()]['datatype'] - except: - col_type = None - df_visible = col_type == 'datetime' - for x in ('box', 'default_label', 'label'): - getattr(self, 'date_format_'+x).setVisible(df_visible) - - - def accept(self): - col = unicode(self.column_name_box.text()) - if not col: - return self.simple_error('', _('No lookup name was provided')) - if re.match('^\w*$', col) is None or not col[0].isalpha() or col.lower() != col: - return self.simple_error('', _('The lookup name must contain only lower case letters, digits and underscores, and start with a letter')) - if col.endswith('_index'): - return self.simple_error('', _('Lookup names cannot end with _index, because these names are reserved for the index of a series column.')) - col_heading = unicode(self.column_heading_box.text()) - col_type = self.column_types[self.column_type_box.currentIndex()]['datatype'] - if col_type == '*text': - col_type='text' - is_multiple = True - else: - is_multiple = False - if not col_heading: - return self.simple_error('', _('No column heading was provided')) - bad_col = False - if col in self.parent.custcols: - if not self.editing_col or self.parent.custcols[col]['colnum'] != self.orig_column_number: - bad_col = True - if bad_col: - return self.simple_error('', _('The lookup name %s is already used')%col) - bad_head = False - for t in self.parent.custcols: - if self.parent.custcols[t]['name'] == col_heading: - if not self.editing_col or self.parent.custcols[t]['colnum'] != self.orig_column_number: - bad_head = True - for t in self.standard_colheads: - if self.standard_colheads[t] == col_heading: - bad_head = True - if bad_head: - return self.simple_error('', _('The heading %s is already used')%col_heading) - - date_format = {} - if col_type == 'datetime': - if self.date_format_box.text(): - date_format = {'date_format':unicode(self.date_format_box.text())} - else: - date_format = {'date_format': None} - - key = self.parent.db.field_metadata.custom_field_prefix+col - if not self.editing_col: - self.parent.db.field_metadata - self.parent.custcols[key] = { - 'label':col, - 'name':col_heading, - 'datatype':col_type, - 'editable':True, - 'display':date_format, - 'normalized':None, - 'colnum':None, - 'is_multiple':is_multiple, - } - item = QListWidgetItem(col_heading, self.parent.columns) - item.setData(Qt.UserRole, QVariant(key)) - item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable) - item.setCheckState(Qt.Checked) - else: - idx = self.parent.columns.currentRow() - item = self.parent.columns.item(idx) - item.setData(Qt.UserRole, QVariant(key)) - item.setText(col_heading) - self.parent.custcols[self.orig_column_name]['label'] = col - self.parent.custcols[self.orig_column_name]['name'] = col_heading - self.parent.custcols[self.orig_column_name]['display'].update(date_format) - self.parent.custcols[self.orig_column_name]['*edited'] = True - self.parent.custcols[self.orig_column_name]['*must_restart'] = True - QDialog.accept(self) - - def reject(self): - QDialog.reject(self) diff --git a/src/calibre/gui2/dialogs/config/create_custom_column.ui b/src/calibre/gui2/dialogs/config/create_custom_column.ui deleted file mode 100644 index 5cb9494845..0000000000 --- a/src/calibre/gui2/dialogs/config/create_custom_column.ui +++ /dev/null @@ -1,191 +0,0 @@ - - - QCreateCustomColumn - - - Qt::ApplicationModal - - - - 0 - 0 - 528 - 199 - - - - - 0 - 0 - - - - Create or edit custom columns - - - - - - QLayout::SetDefaultConstraint - - - 5 - - - - - 0 - - - - - &Lookup name - - - column_name_box - - - - - - - Column &heading - - - column_heading_box - - - - - - - - 20 - 0 - - - - Used for searching the column. Must contain only digits and lower case letters. - - - - - - - Column heading in the library view and category name in the tag browser - - - - - - - Column &type - - - column_type_box - - - - - - - - 0 - 0 - - - - - 70 - 0 - - - - What kind of information will be kept in the column. - - - - - - - - - - 0 - 0 - - - - <p>Date format. Use 1-4 'd's for day, 1-4 'M's for month, and 2 or 4 'y's for year.</p> -<p>For example: -<ul> -<li> ddd, d MMM yyyy gives Mon, 5 Jan 2010<li> -<li>dd MMMM yy gives 05 January 10</li> -</ul> - - - - - - - Use MMM yyyy for month + year, yyyy for year only - - - Default: dd MMM yyyy. - - - - - - - - - Format for &dates - - - date_format_box - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - true - - - - - - - - 75 - true - - - - Create or edit custom columns - - - - - - - - - column_name_box - column_heading_box - column_type_box - date_format_box - button_box - - - - diff --git a/src/calibre/gui2/dialogs/confirm_delete.py b/src/calibre/gui2/dialogs/confirm_delete.py index 1aabcb7b9e..4e0a259824 100644 --- a/src/calibre/gui2/dialogs/confirm_delete.py +++ b/src/calibre/gui2/dialogs/confirm_delete.py @@ -25,7 +25,7 @@ class Dialog(QDialog, Ui_Dialog): def toggle(self, *args): dynamic[_config_name(self.name)] = self.again.isChecked() -def confirm(msg, name, parent=None, pixmap='dialog_warning.svg'): +def confirm(msg, name, parent=None, pixmap='dialog_warning.png'): if not dynamic.get(_config_name(name), True): return True d = Dialog(msg, name, parent) diff --git a/src/calibre/gui2/dialogs/confirm_delete.ui b/src/calibre/gui2/dialogs/confirm_delete.ui index eee2c9fdfd..c45b180483 100644 --- a/src/calibre/gui2/dialogs/confirm_delete.ui +++ b/src/calibre/gui2/dialogs/confirm_delete.ui @@ -14,7 +14,7 @@ - :/images/dialog_warning.svg:/images/dialog_warning.svg + :/images/dialog_warning.png:/images/dialog_warning.png @@ -22,7 +22,7 @@ - :/images/dialog_warning.svg + :/images/dialog_warning.png diff --git a/src/calibre/gui2/dialogs/conversion_error.ui b/src/calibre/gui2/dialogs/conversion_error.ui index 6521cb8c59..c51c868d1b 100644 --- a/src/calibre/gui2/dialogs/conversion_error.ui +++ b/src/calibre/gui2/dialogs/conversion_error.ui @@ -23,7 +23,7 @@ - :/images/dialog_error.svg + :/images/dialog_error.png diff --git a/src/calibre/gui2/dialogs/fetch_metadata.ui b/src/calibre/gui2/dialogs/fetch_metadata.ui index dab12a1917..03a362096c 100644 --- a/src/calibre/gui2/dialogs/fetch_metadata.ui +++ b/src/calibre/gui2/dialogs/fetch_metadata.ui @@ -18,7 +18,7 @@ - :/images/metadata.svg:/images/metadata.svg + :/images/metadata.png:/images/metadata.png diff --git a/src/calibre/gui2/dialogs/job_view.ui b/src/calibre/gui2/dialogs/job_view.ui index a66fdd482d..8b54c23573 100644 --- a/src/calibre/gui2/dialogs/job_view.ui +++ b/src/calibre/gui2/dialogs/job_view.ui @@ -14,7 +14,7 @@ - :/images/view.svg:/images/view.svg + :/images/view.png:/images/view.png diff --git a/src/calibre/gui2/dialogs/jobs.ui b/src/calibre/gui2/dialogs/jobs.ui index 0fc946f996..5b311bf056 100644 --- a/src/calibre/gui2/dialogs/jobs.ui +++ b/src/calibre/gui2/dialogs/jobs.ui @@ -15,7 +15,7 @@ - :/images/jobs.svg:/images/jobs.svg + :/images/jobs.png:/images/jobs.png diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index 4287ca5c79..0eeee61c7e 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -15,7 +15,7 @@ - :/images/edit_input.svg:/images/edit_input.svg + :/images/edit_input.png:/images/edit_input.png @@ -177,7 +177,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 3e07422967..1393a50738 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -30,7 +30,7 @@ from calibre.ebooks.metadata import MetaInformation from calibre.utils.config import prefs, tweaks from calibre.utils.date import qt_to_dt, local_tz, utcfromtimestamp from calibre.customize.ui import run_plugins_on_import, get_isbndb_key -from calibre.gui2.dialogs.config.social import SocialMetadata +from calibre.gui2.preferences.social import SocialMetadata from calibre.gui2.custom_column_widgets import populate_metadata_page from calibre import strftime @@ -102,7 +102,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): view_format = pyqtSignal(object) def do_reset_cover(self, *args): - pix = QPixmap(I('default_cover.svg')) + pix = QPixmap(I('default_cover.png')) self.cover.setPixmap(pix) self.cover_changed = True self.cover_data = None @@ -432,7 +432,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): if cover: pm.loadFromData(cover) if pm.isNull(): - pm = QPixmap(I('default_cover.svg')) + pm = QPixmap(I('default_cover.png')) else: self.cover_data = cover self.cover.setPixmap(pm) diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index a943425a89..4ea68f539d 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -21,7 +21,7 @@ - :/images/edit_input.svg:/images/edit_input.svg + :/images/edit_input.png:/images/edit_input.png true @@ -110,7 +110,7 @@ - :/images/swap.svg:/images/swap.svg + :/images/swap.png:/images/swap.png @@ -165,7 +165,7 @@ - :/images/auto_author_sort.svg:/images/auto_author_sort.svg + :/images/auto_author_sort.png:/images/auto_author_sort.png @@ -248,7 +248,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -301,7 +301,7 @@ - :/images/trash.svg:/images/trash.svg + :/images/trash.png:/images/trash.png @@ -478,7 +478,7 @@ - :/images/add_book.svg:/images/add_book.svg + :/images/add_book.png:/images/add_book.png @@ -498,7 +498,7 @@ - :/images/trash.svg:/images/trash.svg + :/images/trash.png:/images/trash.png @@ -518,7 +518,7 @@ - :/images/book.svg:/images/book.svg + :/images/book.png:/images/book.png @@ -538,7 +538,7 @@ - :/images/edit_input.svg:/images/edit_input.svg + :/images/edit_input.png:/images/edit_input.png @@ -619,7 +619,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png @@ -633,7 +633,7 @@ - :/images/trash.svg:/images/trash.svg + :/images/trash.png:/images/trash.png diff --git a/src/calibre/gui2/dialogs/password.ui b/src/calibre/gui2/dialogs/password.ui index 811e042153..f5ac6600e7 100644 --- a/src/calibre/gui2/dialogs/password.ui +++ b/src/calibre/gui2/dialogs/password.ui @@ -15,7 +15,7 @@ - :/images/mimetypes/unknown.svg:/images/mimetypes/unknown.svg + :/images/mimetypes/unknown.png:/images/mimetypes/unknown.png diff --git a/src/calibre/gui2/dialogs/progress.ui b/src/calibre/gui2/dialogs/progress.ui index 451b9dfb59..4fa859eaba 100644 --- a/src/calibre/gui2/dialogs/progress.ui +++ b/src/calibre/gui2/dialogs/progress.ui @@ -14,7 +14,7 @@ - :/images/jobs.svg:/images/jobs.svg + :/images/jobs.png:/images/jobs.png diff --git a/src/calibre/gui2/dialogs/saved_search_editor.ui b/src/calibre/gui2/dialogs/saved_search_editor.ui index 6d98d25667..3ba37bdf10 100644 --- a/src/calibre/gui2/dialogs/saved_search_editor.ui +++ b/src/calibre/gui2/dialogs/saved_search_editor.ui @@ -15,7 +15,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -90,7 +90,7 @@ - :/images/minus.svg:/images/minus.svg + :/images/minus.png:/images/minus.png @@ -130,7 +130,7 @@ - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index 3dbf7ffffd..fd8184933f 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -216,11 +216,11 @@ class Scheduler(QObject): self.download_queue = set([]) self.news_menu = QMenu() - self.news_icon = QIcon(I('news.svg')) - self.scheduler_action = QAction(QIcon(I('scheduler.svg')), _('Schedule news download'), self) + self.news_icon = QIcon(I('news.png')) + self.scheduler_action = QAction(QIcon(I('scheduler.png')), _('Schedule news download'), self) self.news_menu.addAction(self.scheduler_action) self.connect(self.scheduler_action, SIGNAL('triggered(bool)'), self.show_dialog) - self.cac = QAction(QIcon(I('user_profile.svg')), _('Add a custom news source'), self) + self.cac = QAction(QIcon(I('user_profile.png')), _('Add a custom news source'), self) self.connect(self.cac, SIGNAL('triggered(bool)'), self.customize_feeds) self.news_menu.addAction(self.cac) self.news_menu.addSeparator() diff --git a/src/calibre/gui2/dialogs/scheduler.ui b/src/calibre/gui2/dialogs/scheduler.ui index bcfa82e56a..8e6ab37162 100644 --- a/src/calibre/gui2/dialogs/scheduler.ui +++ b/src/calibre/gui2/dialogs/scheduler.ui @@ -15,7 +15,7 @@ - :/images/scheduler.svg:/images/scheduler.svg + :/images/scheduler.png:/images/scheduler.png diff --git a/src/calibre/gui2/dialogs/search.ui b/src/calibre/gui2/dialogs/search.ui index dc66aae6a9..9e8817b1f4 100644 --- a/src/calibre/gui2/dialogs/search.ui +++ b/src/calibre/gui2/dialogs/search.ui @@ -14,7 +14,7 @@ - :/images/search.svg:/images/search.svg + :/images/search.png:/images/search.png diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py index e3f1c17f3c..679a5c9da9 100644 --- a/src/calibre/gui2/dialogs/tag_categories.py +++ b/src/calibre/gui2/dialogs/tag_categories.py @@ -36,11 +36,11 @@ class TagCategories(QDialog, Ui_TagCategories): self.db = db self.applied_items = [] - cc_icon = QIcon(I('column.svg')) + cc_icon = QIcon(I('column.png')) self.category_labels = self.category_labels_orig[:] - category_icons = [None, QIcon(I('user_profile.svg')), QIcon(I('series.svg')), - QIcon(I('publisher.png')), QIcon(I('tags.svg'))] + category_icons = [None, QIcon(I('user_profile.png')), QIcon(I('series.png')), + QIcon(I('publisher.png')), QIcon(I('tags.png'))] category_values = [None, lambda: [n.replace('|', ',') for (id, n) in self.db.all_authors()], lambda: [n for (id, n) in self.db.all_series()], diff --git a/src/calibre/gui2/dialogs/tag_categories.ui b/src/calibre/gui2/dialogs/tag_categories.ui index d280d5061a..a9319cc5f5 100644 --- a/src/calibre/gui2/dialogs/tag_categories.ui +++ b/src/calibre/gui2/dialogs/tag_categories.ui @@ -15,7 +15,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -91,7 +91,7 @@ - :/images/forward.svg:/images/forward.svg + :/images/forward.png:/images/forward.png @@ -176,7 +176,7 @@ - :/images/list_remove.svg:/images/list_remove.svg + :/images/list_remove.png:/images/list_remove.png @@ -267,7 +267,7 @@ - :/images/minus.svg:/images/minus.svg + :/images/minus.png:/images/minus.png @@ -307,7 +307,7 @@ - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png diff --git a/src/calibre/gui2/dialogs/tag_editor.ui b/src/calibre/gui2/dialogs/tag_editor.ui index 1db1abb1d3..c418b3ac87 100644 --- a/src/calibre/gui2/dialogs/tag_editor.ui +++ b/src/calibre/gui2/dialogs/tag_editor.ui @@ -15,7 +15,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -59,7 +59,7 @@ - :/images/trash.svg:/images/trash.svg + :/images/trash.png:/images/trash.png @@ -105,7 +105,7 @@ - :/images/forward.svg:/images/forward.svg + :/images/forward.png:/images/forward.png @@ -190,7 +190,7 @@ - :/images/list_remove.svg:/images/list_remove.svg + :/images/list_remove.png:/images/list_remove.png @@ -251,7 +251,7 @@ - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png diff --git a/src/calibre/gui2/dialogs/tag_list_editor.ui b/src/calibre/gui2/dialogs/tag_list_editor.ui index 39076aa1f6..9c8231dd91 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.ui +++ b/src/calibre/gui2/dialogs/tag_list_editor.ui @@ -15,7 +15,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -61,7 +61,7 @@ - :/images/trash.svg:/images/trash.svg + :/images/trash.png:/images/trash.png @@ -81,7 +81,7 @@ - :/images/edit_input.svg:/images/edit_input.svg + :/images/edit_input.png:/images/edit_input.png diff --git a/src/calibre/gui2/dialogs/test_email.ui b/src/calibre/gui2/dialogs/test_email.ui index 241468793f..bdfc53681f 100644 --- a/src/calibre/gui2/dialogs/test_email.ui +++ b/src/calibre/gui2/dialogs/test_email.ui @@ -15,7 +15,7 @@ - :/images/config.svg:/images/config.svg + :/images/config.png:/images/config.png diff --git a/src/calibre/gui2/dialogs/user_profiles.ui b/src/calibre/gui2/dialogs/user_profiles.ui index 48f92a108c..4eca4045b1 100644 --- a/src/calibre/gui2/dialogs/user_profiles.ui +++ b/src/calibre/gui2/dialogs/user_profiles.ui @@ -15,7 +15,7 @@ - :/images/user_profile.svg:/images/user_profile.svg + :/images/user_profile.png:/images/user_profile.png @@ -76,7 +76,7 @@ - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png @@ -87,7 +87,7 @@ - :/images/list_remove.svg:/images/list_remove.svg + :/images/list_remove.png:/images/list_remove.png @@ -98,7 +98,7 @@ - :/images/forward.svg:/images/forward.svg + :/images/forward.png:/images/forward.png @@ -109,7 +109,7 @@ - :/images/news.svg:/images/news.svg + :/images/news.png:/images/news.png @@ -120,7 +120,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png @@ -285,7 +285,7 @@ p, li { white-space: pre-wrap; } - :/images/arrow-up.svg:/images/arrow-up.svg + :/images/arrow-up.png:/images/arrow-up.png @@ -299,7 +299,7 @@ p, li { white-space: pre-wrap; } - :/images/list_remove.svg:/images/list_remove.svg + :/images/list_remove.png:/images/list_remove.png @@ -310,7 +310,7 @@ p, li { white-space: pre-wrap; } - :/images/arrow-down.svg:/images/arrow-down.svg + :/images/arrow-down.png:/images/arrow-down.png @@ -361,7 +361,7 @@ p, li { white-space: pre-wrap; } - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py index c983e111d4..74f511e6a2 100644 --- a/src/calibre/gui2/init.py +++ b/src/calibre/gui2/init.py @@ -95,7 +95,7 @@ class LibraryWidget(Splitter): # {{{ idx = 0 if orientation == Qt.Vertical else 1 size = 300 if orientation == Qt.Vertical else 550 Splitter.__init__(self, 'cover_browser_splitter', _('Cover Browser'), - I('cover_flow.svg'), + I('cover_flow.png'), orientation=orientation, parent=parent, connect_button=not config['separate_cover_flow'], side_index=idx, initial_side_size=size, initial_show=False, @@ -113,7 +113,7 @@ class Stack(QStackedWidget): # {{{ parent.cb_splitter = LibraryWidget(parent) self.tb_widget = TagBrowserWidget(parent) parent.tb_splitter = Splitter('tag_browser_splitter', - _('Tag Browser'), I('tags.svg'), + _('Tag Browser'), I('tags.png'), parent=parent, side_index=0, initial_side_size=200, shortcut=_('Shift+Alt+T')) parent.tb_splitter.addWidget(self.tb_widget) @@ -207,7 +207,7 @@ class LayoutMixin(object): # {{{ self.book_details = BookDetails(False, self) self.stack = Stack(self) self.bd_splitter = Splitter('book_details_splitter', - _('Book Details'), I('book.svg'), + _('Book Details'), I('book.png'), orientation=Qt.Vertical, parent=self, side_index=1, shortcut=_('Alt+D')) self.bd_splitter.addWidget(self.stack) @@ -217,7 +217,7 @@ class LayoutMixin(object): # {{{ # }}} else: # wide {{{ self.bd_splitter = Splitter('book_details_splitter', - _('Book Details'), I('book.svg'), initial_side_size=200, + _('Book Details'), I('book.png'), initial_side_size=200, orientation=Qt.Horizontal, parent=self, side_index=1, shortcut=_('Shift+Alt+D')) self.stack = Stack(self) @@ -258,7 +258,9 @@ class LayoutMixin(object): # {{{ getattr(self, x+'_view').save_state() for x in ('cb', 'tb', 'bd'): - getattr(self, x+'_splitter').save_state() + s = getattr(self, x+'_splitter') + s.update_desired_state() + s.save_state() def read_layout_settings(self): # View states are restored automatically when set_database is called diff --git a/src/calibre/gui2/jobs.py b/src/calibre/gui2/jobs.py index fd23234c8a..8a63b6fac5 100644 --- a/src/calibre/gui2/jobs.py +++ b/src/calibre/gui2/jobs.py @@ -33,10 +33,10 @@ class JobManager(QAbstractTableModel): def __init__(self): QAbstractTableModel.__init__(self) - self.wait_icon = QVariant(QIcon(I('jobs.svg'))) - self.running_icon = QVariant(QIcon(I('exec.svg'))) - self.error_icon = QVariant(QIcon(I('dialog_error.svg'))) - self.done_icon = QVariant(QIcon(I('ok.svg'))) + self.wait_icon = QVariant(QIcon(I('jobs.png'))) + self.running_icon = QVariant(QIcon(I('exec.png'))) + self.error_icon = QVariant(QIcon(I('dialog_error.png'))) + self.done_icon = QVariant(QIcon(I('ok.png'))) self.jobs = [] self.add_job = Dispatcher(self._add_job) diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index 4eccf597c2..68f093da95 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -50,7 +50,7 @@ class LocationManager(QObject): # {{{ a = m.addAction(icon, tooltip) a.triggered.connect(receiver) self._mem.append(a) - a = m.addAction(QIcon(I('eject.svg')), _('Eject this device')) + a = m.addAction(QIcon(I('eject.png')), _('Eject this device')) a.triggered.connect(self._eject_requested) ac.setMenu(m) self._mem.append(a) @@ -61,11 +61,11 @@ class LocationManager(QObject): # {{{ ac('library', _('Library'), 'lt.png', _('Show books in calibre library')) - ac('main', _('Reader'), 'reader.svg', + ac('main', _('Reader'), 'reader.png', _('Show books in the main memory of the device')) - ac('carda', _('Card A'), 'sd.svg', + ac('carda', _('Card A'), 'sd.png', _('Show books in storage card A')) - ac('cardb', _('Card B'), 'sd.svg', + ac('cardb', _('Card B'), 'sd.png', _('Show books in storage card B')) def _location_selected(self, location, *args): @@ -80,7 +80,7 @@ class LocationManager(QObject): # {{{ def update_devices(self, cp=(None, None), fs=[-1, -1, -1], icon=None): if icon is None: - icon = I('reader.svg') + icon = I('reader.png') self.location_main.setIcon(QIcon(icon)) had_device = self.has_device if cp is None: @@ -148,7 +148,7 @@ class SearchBar(QWidget): # {{{ x.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) parent.advanced_search_button = x = QToolButton(self) - x.setIcon(QIcon(I('search.svg'))) + x.setIcon(QIcon(I('search.png'))) l.addWidget(x) x.setToolTip(_("Advanced search")) @@ -163,7 +163,7 @@ class SearchBar(QWidget): # {{{ l.addWidget(x) x = parent.clear_button = QToolButton(self) - x.setIcon(QIcon(I('clear_left.svg'))) + x.setIcon(QIcon(I('clear_left.png'))) x.setObjectName("clear_button") l.addWidget(x) x.setToolTip(_("Reset Quick Search")) @@ -175,19 +175,19 @@ class SearchBar(QWidget): # {{{ l.addWidget(x) x = parent.copy_search_button = QToolButton(self) - x.setIcon(QIcon(I("search_copy_saved.svg"))) + x.setIcon(QIcon(I("search_copy_saved.png"))) x.setObjectName("copy_search_button") l.addWidget(x) x.setToolTip(_("Copy current search text (instead of search name)")) x = parent.save_search_button = QToolButton(self) - x.setIcon(QIcon(I("search_add_saved.svg"))) + x.setIcon(QIcon(I("search_add_saved.png"))) x.setObjectName("save_search_button") l.addWidget(x) x.setToolTip(_("Save current search under the name shown in the box")) x = parent.delete_search_button = QToolButton(self) - x.setIcon(QIcon(I("search_delete_saved.svg"))) + x.setIcon(QIcon(I("search_delete_saved.png"))) x.setObjectName("delete_search_button") l.addWidget(x) x.setToolTip(_("Delete current saved search")) diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py index d98d9a240b..bf233b1175 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -282,7 +282,7 @@ class CcBoolDelegate(QStyledItemDelegate): # {{{ def createEditor(self, parent, option, index): editor = QComboBox(parent) items = [_('Y'), _('N'), ' '] - icons = [I('ok.svg'), I('list_remove.svg'), I('blank.svg')] + icons = [I('ok.png'), I('list_remove.png'), I('blank.png')] if tweaks['bool_custom_columns_are_tristate'] == 'no': items = items[:-1] icons = icons[:-1] diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index e442007c9a..ae9487f801 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -49,7 +49,7 @@ _default_image = None def default_image(): global _default_image if _default_image is None: - _default_image = QImage(I('default_cover.svg')) + _default_image = QImage(I('default_cover.png')) return _default_image class BooksModel(QAbstractTableModel): # {{{ @@ -89,9 +89,9 @@ class BooksModel(QAbstractTableModel): # {{{ self.alignment_map = {} self.buffer_size = buffer self.cover_cache = None - self.bool_yes_icon = QIcon(I('ok.svg')) - self.bool_no_icon = QIcon(I('list_remove.svg')) - self.bool_blank_icon = QIcon(I('blank.svg')) + self.bool_yes_icon = QIcon(I('ok.png')) + self.bool_no_icon = QIcon(I('list_remove.png')) + self.bool_blank_icon = QIcon(I('blank.png')) self.device_connected = False self.read_config() diff --git a/src/calibre/gui2/lrf_renderer/config.ui b/src/calibre/gui2/lrf_renderer/config.ui index 448ee2f9a0..9145b4b29f 100644 --- a/src/calibre/gui2/lrf_renderer/config.ui +++ b/src/calibre/gui2/lrf_renderer/config.ui @@ -15,7 +15,7 @@ - :/images/config.svg:/images/config.svg + :/images/config.png:/images/config.png diff --git a/src/calibre/gui2/lrf_renderer/main.py b/src/calibre/gui2/lrf_renderer/main.py index 87ec55e114..8ddda175fa 100644 --- a/src/calibre/gui2/lrf_renderer/main.py +++ b/src/calibre/gui2/lrf_renderer/main.py @@ -310,7 +310,7 @@ def main(args=sys.argv, logger=None): pid = os.fork() if (islinux or isfreebsd) else -1 if pid <= 0: app = Application(args) - app.setWindowIcon(QIcon(I('viewer.svg'))) + app.setWindowIcon(QIcon(I('viewer.png'))) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) opts = normalize_settings(parser, opts) diff --git a/src/calibre/gui2/lrf_renderer/main.ui b/src/calibre/gui2/lrf_renderer/main.ui index 2eeb400cc4..0e7b54edb8 100644 --- a/src/calibre/gui2/lrf_renderer/main.ui +++ b/src/calibre/gui2/lrf_renderer/main.ui @@ -20,7 +20,7 @@ - :/images/viewer.svg:/images/viewer.svg + :/images/viewer.png:/images/viewer.png @@ -174,7 +174,7 @@ - :/images/next.svg:/images/next.svg + :/images/next.png:/images/next.png Next Page @@ -183,7 +183,7 @@ - :/images/previous.svg:/images/previous.svg + :/images/previous.png:/images/previous.png Previous Page @@ -192,7 +192,7 @@ - :/images/back.svg:/images/back.svg + :/images/back.png:/images/back.png Back @@ -201,7 +201,7 @@ - :/images/forward.svg:/images/forward.svg + :/images/forward.png:/images/forward.png Forward @@ -215,7 +215,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png Open ebook @@ -224,7 +224,7 @@ - :/images/config.svg:/images/config.svg + :/images/config.png:/images/config.png Configure diff --git a/src/calibre/gui2/main_window.py b/src/calibre/gui2/main_window.py index 2779a18733..a2221acd3a 100644 --- a/src/calibre/gui2/main_window.py +++ b/src/calibre/gui2/main_window.py @@ -58,8 +58,8 @@ class MainWindow(QMainWindow): @classmethod def get_menubar_actions(cls): - preferences_action = QAction(QIcon(I('config.svg')), _('&Preferences'), None) - quit_action = QAction(QIcon(I('window-close.svg')), _('&Quit'), None) + preferences_action = QAction(QIcon(I('config.png')), _('&Preferences'), None) + quit_action = QAction(QIcon(I('window-close.png')), _('&Quit'), None) preferences_action.setMenuRole(QAction.PreferencesRole) quit_action.setMenuRole(QAction.QuitRole) return preferences_action, quit_action diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index 5d46ee2eb9..045d7ceebb 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -5,14 +5,23 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import textwrap + from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \ QLineEdit, QComboBox, QVariant from calibre.customize.ui import preferences_plugins +from calibre.utils.config import ConfigProxy + +class AbortCommit(Exception): + pass class ConfigWidgetInterface(object): changed_signal = None + supports_restoring_to_defaults = True + restore_defaults_desc = _('Restore settings to default values. ' + 'You have to click Apply to actually save the default settings.') def genesis(self, gui): raise NotImplementedError() @@ -24,6 +33,15 @@ class ConfigWidgetInterface(object): pass def commit(self): + ''' + Save any changed settings. Return True if the changes require a + restart, False otherwise. Raise an :class:`AbortCommit` exception + to indicate that an error occurred. You are responsible for giving the + suer feedback about what the error is and how to correct it. + ''' + return False + + def refresh_gui(self, gui): pass class Setting(object): @@ -56,6 +74,20 @@ class Setting(object): else: raise ValueError('Unknown data type') + if isinstance(self.config_obj, ConfigProxy) and \ + not unicode(self.gui_obj.toolTip()): + h = self.config_obj.help(self.name) + if h: + self.gui_obj.setToolTip(h) + tt = unicode(self.gui_obj.toolTip()) + if tt: + if not unicode(self.gui_obj.whatsThis()): + self.gui_obj.setWhatsThis(tt) + if not unicode(self.gui_obj.statusTip()): + self.gui_obj.setStatusTip(tt) + tt = '\n'.join(textwrap.wrap(tt, 70)) + self.gui_obj.setToolTip(tt) + def changed(self, *args): self.widget.changed_signal.emit() @@ -111,7 +143,7 @@ class Setting(object): elif self.datatype == 'number': val = self.gui_obj.value() elif self.datatype == 'string': - val = unicode(self.gui_name.text()).strip() + val = unicode(self.gui_obj.text()).strip() if self.empty_string_is_None and not val: val = None elif self.datatype == 'choice': @@ -139,6 +171,7 @@ class CommaSeparatedList(Setting): class ConfigWidgetBase(QWidget, ConfigWidgetInterface): changed_signal = pyqtSignal() + supports_restoring_to_defaults = True def __init__(self, parent=None): QWidget.__init__(self, parent) @@ -147,9 +180,10 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): self.settings = {} def register(self, name, config_obj, gui_name=None, choices=None, - restart_required=False, setting=Setting): + restart_required=False, empty_string_is_None=True, setting=Setting): setting = setting(name, config_obj, self, gui_name=gui_name, - choices=choices, restart_required=restart_required) + choices=choices, restart_required=restart_required, + empty_string_is_None=empty_string_is_None) return self.register_setting(setting) def register_setting(self, setting): @@ -173,7 +207,6 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): setting.restore_defaults() - def get_plugin(category, name): for plugin in preferences_plugins(): if plugin.category == category and plugin.name == name: @@ -182,10 +215,33 @@ def get_plugin(category, name): 'No Preferences Plugin with category: %s and name: %s found' % (category, name)) -def test_widget(category, name, gui=None): # {{{ +# Testing {{{ + +def init_gui(): + from calibre.gui2.ui import Main + from calibre.gui2.main import option_parser + from calibre.library import db + parser = option_parser() + opts, args = parser.parse_args([]) + actions = tuple(Main.create_application_menubar()) + db = db() + gui = Main(opts) + gui.initialize(db.library_path, db, None, actions, show_gui=False) + return gui + +def test_widget(category, name, gui=None): from PyQt4.Qt import QDialog, QVBoxLayout, QDialogButtonBox + class Dialog(QDialog): + def set_widget(self, w): self.w = w + def accept(self): + try: + self.restart_required = self.w.commit() + except AbortCommit: + return + QDialog.accept(self) + pl = get_plugin(category, name) - d = QDialog() + d = Dialog() d.resize(750, 550) d.setWindowTitle(category + " - " + name) bb = QDialogButtonBox(d) @@ -193,7 +249,9 @@ def test_widget(category, name, gui=None): # {{{ bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) w = pl.create_widget(d) + d.set_widget(w) bb.button(bb.RestoreDefaults).clicked.connect(w.restore_defaults) + bb.button(bb.RestoreDefaults).setEnabled(w.supports_restoring_to_defaults) bb.button(bb.Apply).setEnabled(False) bb.button(bb.Apply).clicked.connect(d.accept) w.changed_signal.connect(lambda : bb.button(bb.Apply).setEnabled(True)) @@ -203,24 +261,28 @@ def test_widget(category, name, gui=None): # {{{ l.addWidget(bb) mygui = gui is None if gui is None: - from calibre.gui2.ui import Main - from calibre.gui2.main import option_parser - from calibre.library import db - parser = option_parser() - opts, args = parser.parse_args([]) - actions = tuple(Main.create_application_menubar()) - db = db() - gui = Main(opts) - gui.initialize(db.library_path, db, None, actions, show_gui=False) + gui = init_gui() + mygui = True w.genesis(gui) w.initialize() - restart_required = False - if d.exec_() == QDialog.Accepted: - restart_required = w.commit() - if restart_required: + d.exec_() + if getattr(d, 'restart_required', False): from calibre.gui2 import warning_dialog warning_dialog(gui, 'Restart required', 'Restart required', show=True) if mygui: gui.shutdown() + +def test_all(): + from PyQt4.Qt import QApplication + app = QApplication([]) + app + gui = init_gui() + for plugin in preferences_plugins(): + test_widget(plugin.category, plugin.name, gui=gui) + gui.shutdown() + +if __name__ == '__main__': + test_all() # }}} + diff --git a/src/calibre/gui2/preferences/adding.py b/src/calibre/gui2/preferences/adding.py new file mode 100644 index 0000000000..7a27ed8f2d --- /dev/null +++ b/src/calibre/gui2/preferences/adding.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences.adding_ui import Ui_Form +from calibre.utils.config import prefs +from calibre.gui2.widgets import FilenamePattern + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + + r = self.register + + r('read_file_metadata', prefs) + r('swap_author_names', prefs) + r('add_formats_to_existing', prefs) + + self.filename_pattern = FilenamePattern(self) + self.metadata_box.layout().insertWidget(0, self.filename_pattern) + self.filename_pattern.changed_signal.connect(self.changed_signal.emit) + + + def initialize(self): + ConfigWidgetBase.initialize(self) + self.filename_pattern.blockSignals(True) + self.filename_pattern.initialize() + self.filename_pattern.blockSignals(False) + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + self.filename_pattern.initialize(defaults=True) + + def commit(self): + pattern = self.filename_pattern.commit() + prefs['filename_pattern'] = pattern + return ConfigWidgetBase.commit(self) + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Import/Export', 'Adding') + diff --git a/src/calibre/gui2/preferences/adding.ui b/src/calibre/gui2/preferences/adding.ui new file mode 100644 index 0000000000..062c45e1ad --- /dev/null +++ b/src/calibre/gui2/preferences/adding.ui @@ -0,0 +1,83 @@ + + + Form + + + + 0 + 0 + 1010 + 339 + + + + Form + + + + + + Here you can control how calibre will read metadata from the files you add to it. calibre can either read metadata from the contents of the file, or from the filename. + + + true + + + + + + + Read metadata from &file contents rather than file name + + + + + + + If an existing book with a similar title and author is found that does not have the format being added, the format is added +to the existing book, instead of creating a new entry. If the existing book already has the format, then it is silently ignored. + +Title match ignores leading indefinite articles ("the", "a", "an"), punctuation, case, etc. Author match is exact. + + + If books with similar titles and authors found, &merge the new files automatically + + + + + + + &Configure metadata from file name + + + + + + Qt::Vertical + + + + 20 + 363 + + + + + + + + + + + Swap the firstname and lastname of the author. This affects only metadata read from file names. + + + &Swap author firstname and lastname + + + + + + + + diff --git a/src/calibre/gui2/preferences/behavior.ui b/src/calibre/gui2/preferences/behavior.ui index e751a9b4f6..8332212235 100644 --- a/src/calibre/gui2/preferences/behavior.ui +++ b/src/calibre/gui2/preferences/behavior.ui @@ -214,7 +214,7 @@ - :/images/arrow-up.svg:/images/arrow-up.svg + :/images/arrow-up.png:/images/arrow-up.png @@ -238,7 +238,7 @@ - :/images/arrow-down.svg:/images/arrow-down.svg + :/images/arrow-down.png:/images/arrow-down.png diff --git a/src/calibre/gui2/preferences/columns.ui b/src/calibre/gui2/preferences/columns.ui index 58d54e48f5..b5dc9b8c90 100644 --- a/src/calibre/gui2/preferences/columns.ui +++ b/src/calibre/gui2/preferences/columns.ui @@ -43,7 +43,7 @@ - :/images/arrow-up.svg:/images/arrow-up.svg + :/images/arrow-up.png:/images/arrow-up.png @@ -70,7 +70,7 @@ - :/images/minus.svg:/images/minus.svg + :/images/minus.png:/images/minus.png @@ -97,7 +97,7 @@ - :/images/plus.svg:/images/plus.svg + :/images/plus.png:/images/plus.png @@ -124,7 +124,7 @@ - :/images/edit_input.svg:/images/edit_input.svg + :/images/edit_input.png:/images/edit_input.png @@ -148,7 +148,7 @@ - :/images/arrow-down.svg:/images/arrow-down.svg + :/images/arrow-down.png:/images/arrow-down.png diff --git a/src/calibre/gui2/preferences/conversion.py b/src/calibre/gui2/preferences/conversion.py new file mode 100644 index 0000000000..0063d4a341 --- /dev/null +++ b/src/calibre/gui2/preferences/conversion.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import QIcon, Qt, QStringListModel, QVariant + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, AbortCommit +from calibre.ebooks.conversion.plumber import Plumber +from calibre.utils.logging import Log +from calibre.gui2.preferences.conversion_ui import Ui_Form +from calibre.gui2.convert.look_and_feel import LookAndFeelWidget +from calibre.gui2.convert.page_setup import PageSetupWidget +from calibre.gui2.convert.structure_detection import StructureDetectionWidget +from calibre.gui2.convert.toc import TOCWidget +from calibre.customize.ui import input_format_plugins, output_format_plugins +from calibre.gui2.convert import config_widget_for_input_plugin + +class Model(QStringListModel): + + def __init__(self, widgets): + QStringListModel.__init__(self) + self.widgets = widgets + self.setStringList([w.TITLE for w in widgets]) + + def data(self, index, role): + if role == Qt.DecorationRole: + w = self.widgets[index.row()] + if w.ICON: + return QVariant(QIcon(w.ICON)) + return QStringListModel.data(self, index, role) + +class Base(ConfigWidgetBase, Ui_Form): + + restore_defaults_desc = _('Restore settings to default values. ' + 'Only settings for the currently selected section ' + 'are restored.') + + def genesis(self, gui): + log = Log() + log.outputs = [] + + self.plumber = Plumber('dummy.epub', 'dummy.epub', log, dummy=True, + merge_plugin_recs=False) + + def widget_factory(cls): + return cls(self, self.plumber.get_option_by_name, + self.plumber.get_option_help, None, None) + + self.load_conversion_widgets() + widgets = list(map(widget_factory, self.conversion_widgets)) + self.model = Model(widgets) + self.list.setModel(self.model) + + for w in widgets: + w.changed_signal.connect(self.changed_signal) + self.stack.addWidget(w) + + self.list.currentChanged = self.category_current_changed + self.list.setCurrentIndex(self.model.index(0)) + + def initialize(self): + ConfigWidgetBase.initialize(self) + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + self.stack.currentWidget().restore_defaults(self.plumber.get_option_by_name) + self.changed_signal.emit() + + def commit(self): + for widget in self.model.widgets: + if not widget.pre_commit_check(): + raise AbortCommit('abort') + widget.commit(save_defaults=True) + return ConfigWidgetBase.commit(self) + + def category_current_changed(self, n, p): + self.stack.setCurrentIndex(n.row()) + +class CommonOptions(Base): + + def load_conversion_widgets(self): + self.conversion_widgets = [LookAndFeelWidget, PageSetupWidget, + StructureDetectionWidget, TOCWidget] + +class InputOptions(Base): + + def load_conversion_widgets(self): + self.conversion_widgets = [] + for plugin in input_format_plugins(): + pw = config_widget_for_input_plugin(plugin) + if pw is not None: + self.conversion_widgets.append(pw) + +class OutputOptions(Base): + + def load_conversion_widgets(self): + self.conversion_widgets = [] + for plugin in output_format_plugins(): + name = plugin.name.lower().replace(' ', '_') + try: + output_widget = __import__('calibre.gui2.convert.'+name, + fromlist=[1]) + pw = output_widget.PluginWidget + self.conversion_widgets.append(pw) + except ImportError: + continue + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + #test_widget('Conversion', 'Input Options') + test_widget('Conversion', 'Common Options') + #test_widget('Conversion', 'Output Options') + diff --git a/src/calibre/gui2/preferences/conversion.ui b/src/calibre/gui2/preferences/conversion.ui new file mode 100644 index 0000000000..d9f335d443 --- /dev/null +++ b/src/calibre/gui2/preferences/conversion.ui @@ -0,0 +1,82 @@ + + + Form + + + + 0 + 0 + 720 + 603 + + + + Form + + + + + + + 0 + 0 + + + + + 180 + 0 + + + + + 180 + 16777215 + + + + + 75 + true + + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + + 48 + 48 + + + + QAbstractItemView::ScrollPerItem + + + QAbstractItemView::ScrollPerPixel + + + QListView::TopToBottom + + + 10 + + + QListView::ListMode + + + + + + + + + + + diff --git a/src/calibre/gui2/dialogs/config/device_debug.py b/src/calibre/gui2/preferences/device_debug.py similarity index 97% rename from src/calibre/gui2/dialogs/config/device_debug.py rename to src/calibre/gui2/preferences/device_debug.py index ae4a8e4f45..90927fe9b9 100644 --- a/src/calibre/gui2/dialogs/config/device_debug.py +++ b/src/calibre/gui2/preferences/device_debug.py @@ -22,7 +22,7 @@ class DebugDevice(QDialog): self.copy = QPushButton(_('Copy to &clipboard')) self.copy.setDefault(True) self.setWindowTitle(_('Debug device detection')) - self.setWindowIcon(QIcon(I('debug.svg'))) + self.setWindowIcon(QIcon(I('debug.png'))) self.copy.clicked.connect(self.copy_to_clipboard) self.ok = QPushButton('&OK') self.ok.setAutoDefault(False) diff --git a/src/calibre/gui2/preferences/email.ui b/src/calibre/gui2/preferences/email.ui new file mode 100644 index 0000000000..2ffeb756d9 --- /dev/null +++ b/src/calibre/gui2/preferences/email.ui @@ -0,0 +1,112 @@ + + + Form + + + + 0 + 0 + 701 + 494 + + + + Form + + + + + + calibre can send your books to you (or your reader) by email. Emails will be automatically sent for downloaded news to all email addresses that have Auto-send checked. + + + true + + + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + + + + + + Add an email address to which to send books + + + &Add email + + + + :/images/plus.png:/images/plus.png + + + + 24 + 24 + + + + Qt::ToolButtonTextUnderIcon + + + + + + + Make &default + + + + + + + &Remove email + + + + :/images/minus.png:/images/minus.png + + + + 24 + 24 + + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + + + + + SendEmail + QWidget +
calibre/gui2/wizard/send_email.h
+ 1 +
+
+ + + + +
diff --git a/src/calibre/gui2/preferences/emailp.py b/src/calibre/gui2/preferences/emailp.py new file mode 100644 index 0000000000..f0b079e209 --- /dev/null +++ b/src/calibre/gui2/preferences/emailp.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import QAbstractTableModel, QVariant, QFont, Qt + + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \ + AbortCommit +from calibre.gui2.preferences.email_ui import Ui_Form +from calibre.utils.config import ConfigProxy +from calibre.gui2 import NONE +from calibre.utils.smtp import config as smtp_prefs + +class EmailAccounts(QAbstractTableModel): # {{{ + + def __init__(self, accounts): + QAbstractTableModel.__init__(self) + self.accounts = accounts + self.account_order = sorted(self.accounts.keys()) + self.headers = map(QVariant, [_('Email'), _('Formats'), _('Auto send')]) + self.default_font = QFont() + self.default_font.setBold(True) + self.default_font = QVariant(self.default_font) + self.tooltips =[NONE] + map(QVariant, + [_('Formats to email. The first matching format will be sent.'), + '

'+_('If checked, downloaded news will be automatically ' + 'mailed
to this email address ' + '(provided it is in one of the listed formats).')]) + + def rowCount(self, *args): + return len(self.account_order) + + def columnCount(self, *args): + return 3 + + def headerData(self, section, orientation, role): + if role == Qt.DisplayRole and orientation == Qt.Horizontal: + return self.headers[section] + return NONE + + def data(self, index, role): + row, col = index.row(), index.column() + if row < 0 or row >= self.rowCount(): + return NONE + account = self.account_order[row] + if role == Qt.UserRole: + return (account, self.accounts[account]) + if role == Qt.ToolTipRole: + return self.tooltips[col] + if role in [Qt.DisplayRole, Qt.EditRole]: + if col == 0: + return QVariant(account) + if col == 1: + return QVariant(self.accounts[account][0]) + if role == Qt.FontRole and self.accounts[account][2]: + return self.default_font + if role == Qt.CheckStateRole and col == 2: + return QVariant(Qt.Checked if self.accounts[account][1] else Qt.Unchecked) + return NONE + + def flags(self, index): + if index.column() == 2: + return QAbstractTableModel.flags(self, index)|Qt.ItemIsUserCheckable + else: + return QAbstractTableModel.flags(self, index)|Qt.ItemIsEditable + + def setData(self, index, value, role): + if not index.isValid(): + return False + row, col = index.row(), index.column() + account = self.account_order[row] + if col == 2: + self.accounts[account][1] ^= True + elif col == 1: + self.accounts[account][0] = unicode(value.toString()).upper() + else: + na = unicode(value.toString()) + from email.utils import parseaddr + addr = parseaddr(na)[-1] + if not addr: + return False + self.accounts[na] = self.accounts.pop(account) + self.account_order[row] = na + if '@kindle.com' in addr: + self.accounts[na][0] = 'AZW, MOBI, TPZ, PRC, AZW1' + + self.dataChanged.emit( + self.index(index.row(), 0), self.index(index.row(), 2)) + return True + + def make_default(self, index): + if index.isValid(): + row = index.row() + for x in self.accounts.values(): + x[2] = False + self.accounts[self.account_order[row]][2] = True + self.reset() + + def add(self): + x = _('new email address') + y = x + c = 0 + while y in self.accounts: + c += 1 + y = x + str(c) + auto_send = len(self.accounts) < 1 + self.accounts[y] = ['MOBI, EPUB', auto_send, + len(self.account_order) == 0] + self.account_order = sorted(self.accounts.keys()) + self.reset() + return self.index(self.account_order.index(y), 0) + + def remove(self, index): + if index.isValid(): + row = index.row() + account = self.account_order[row] + self.accounts.pop(account) + self.account_order = sorted(self.accounts.keys()) + has_default = False + for account in self.account_order: + if self.accounts[account][2]: + has_default = True + break + if not has_default and self.account_order: + self.accounts[self.account_order[0]][2] = True + + self.reset() + +# }}} + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + supports_restoring_to_defaults = False + + def genesis(self, gui): + self.gui = gui + self.proxy = ConfigProxy(smtp_prefs()) + + self.send_email_widget.initialize(self.preferred_to_address) + self.send_email_widget.changed_signal.connect(self.changed_signal.emit) + opts = self.send_email_widget.smtp_opts + self._email_accounts = EmailAccounts(opts.accounts) + self._email_accounts.dataChanged.connect(lambda x,y: + self.changed_signal.emit()) + self.email_view.setModel(self._email_accounts) + + self.email_add.clicked.connect(self.add_email_account) + self.email_make_default.clicked.connect(self.make_default) + self.email_view.resizeColumnsToContents() + self.email_remove.clicked.connect(self.remove_email_account) + + def preferred_to_address(self): + if self._email_accounts.account_order: + return self._email_accounts.account_order[0] + + def initialize(self): + ConfigWidgetBase.initialize(self) + # Initializing all done in genesis + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + # No defaults to restore to + + def commit(self): + to_set = bool(self._email_accounts.accounts) + if not self.send_email_widget.set_email_settings(to_set): + raise AbortCommit('abort') + self.proxy['accounts'] = self._email_accounts.accounts + return ConfigWidgetBase.commit(self) + + def make_default(self, *args): + self._email_accounts.make_default(self.email_view.currentIndex()) + self.changed_signal.emit() + + def add_email_account(self, *args): + index = self._email_accounts.add() + self.email_view.setCurrentIndex(index) + self.email_view.resizeColumnsToContents() + self.email_view.edit(index) + self.changed_signal.emit() + + def remove_email_account(self, *args): + idx = self.email_view.currentIndex() + self._email_accounts.remove(idx) + self.changed_signal.emit() + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Sharing', 'Email') + diff --git a/src/calibre/gui2/dialogs/config/history.py b/src/calibre/gui2/preferences/history.py similarity index 70% rename from src/calibre/gui2/dialogs/config/history.py rename to src/calibre/gui2/preferences/history.py index 74b88a4380..c1c68642f6 100644 --- a/src/calibre/gui2/dialogs/config/history.py +++ b/src/calibre/gui2/preferences/history.py @@ -6,6 +6,8 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import textwrap + from PyQt4.Qt import QComboBox, QStringList, Qt from calibre.gui2 import config as gui_conf @@ -17,15 +19,22 @@ class HistoryBox(QComboBox): self.setEditable(True) def initialize(self, opt_name, default, help=None): - history = gui_conf[opt_name] - if default not in history: - history.append(default) - self.addItems(QStringList(history)) - self.setCurrentIndex(self.findText(default, Qt.MatchFixedString)) - if help is not None: + self.opt_name = opt_name + self.set_value(default) + if help: + self.setStatusTip(help) + help = '\n'.join(textwrap.wrap(help)) self.setToolTip(help) self.setWhatsThis(help) + def set_value(self, val): + history = gui_conf[self.opt_name] + if val not in history: + history.append(val) + self.clear() + self.addItems(QStringList(history)) + self.setCurrentIndex(self.findText(val, Qt.MatchFixedString)) + def save_history(self, opt_name): history = [unicode(self.itemText(i)) for i in range(self.count())] ct = self.text() diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index a0805e8915..f30b2fddbb 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -23,7 +23,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('gui_layout', config, restart_required=True, choices= [(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) - r('cover_flow_queue_length', config) + r('cover_flow_queue_length', config, restart_required=True) lang = get_lang() if lang is None or lang not in available_translations(): @@ -55,6 +55,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) + def refresh_gui(self, gui): + gui.search.search_as_you_type(config['search_as_you_type']) + + if __name__ == '__main__': from PyQt4.Qt import QApplication app = QApplication([]) diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py new file mode 100644 index 0000000000..9b3f932a08 --- /dev/null +++ b/src/calibre/gui2/preferences/main.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import textwrap +from functools import partial + +from PyQt4.Qt import QMainWindow, Qt, QIcon, QStatusBar, QFont, QWidget, \ + QScrollArea, QStackedWidget, QVBoxLayout, QLabel, QFrame, \ + QToolBar, QSize, pyqtSignal, QSizePolicy, QToolButton + +from calibre.constants import __appname__, __version__ +from calibre.gui2 import gprefs, min_available_height, available_width, \ + warning_dialog +from calibre.gui2.preferences import init_gui, AbortCommit, get_plugin +from calibre.customize.ui import preferences_plugins +from calibre.utils.ordered_dict import OrderedDict + +class StatusBar(QStatusBar): # {{{ + + def __init__(self, parent=None): + QStatusBar.__init__(self, parent) + self.default_message = __appname__ + ' ' + _('version') + ' ' + \ + __version__ + ' ' + _('created by Kovid Goyal') + self.device_string = '' + self._font = QFont() + self._font.setBold(True) + self.setFont(self._font) + + self.messageChanged.connect(self.message_changed, + type=Qt.QueuedConnection) + self.message_changed('') + + def message_changed(self, msg): + if not msg or msg.isEmpty() or msg.isNull() or \ + not unicode(msg).strip(): + self.showMessage(self.default_message) + +# }}} + +class Category(QWidget): + + plugin_activated = pyqtSignal(object) + + def __init__(self, name, plugins, parent=None): + QWidget.__init__(self, parent) + self._layout = QVBoxLayout() + self.setLayout(self._layout) + self.label = QLabel(name) + self.sep = QFrame(self) + self.bf = QFont() + self.bf.setBold(True) + self.label.setFont(self.bf) + self.sep.setFrameShape(QFrame.HLine) + self._layout.addWidget(self.label) + self._layout.addWidget(self.sep) + + self.plugins = plugins + + self.bar = QToolBar(self) + self.bar.setIconSize(QSize(48, 48)) + self.bar.setMovable(False) + self.bar.setFloatable(False) + self.bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) + self._layout.addWidget(self.bar) + self.actions = [] + for p in plugins: + target = partial(self.triggered, p) + ac = self.bar.addAction(QIcon(p.icon), p.gui_name, target) + ac.setToolTip(textwrap.fill(p.description)) + ac.setWhatsThis(textwrap.fill(p.description)) + ac.setStatusTip(p.description) + self.actions.append(ac) + w = self.bar.widgetForAction(ac) + w.setStyleSheet('QToolButton { margin-right: 20px; min-width: 100px }') + w.setCursor(Qt.PointingHandCursor) + w.setAutoRaise(True) + + def triggered(self, plugin, *args): + self.plugin_activated.emit(plugin) + + +class Browser(QScrollArea): + + show_plugin = pyqtSignal(object) + + def __init__(self, parent=None): + QScrollArea.__init__(self, parent) + self.setWidgetResizable(True) + + category_map = {} + for plugin in preferences_plugins(): + if plugin.category not in category_map: + category_map[plugin.category] = plugin.category_order + if category_map[plugin.category] < plugin.category_order: + category_map[plugin.category] = plugin.category_order + + categories = list(category_map.keys()) + categories.sort(cmp=lambda x, y: cmp(category_map[x], category_map[y])) + + self.category_map = OrderedDict() + for c in categories: + self.category_map[c] = [] + + for plugin in preferences_plugins(): + self.category_map[plugin.category].append(plugin) + + for plugins in self.category_map.values(): + plugins.sort(cmp=lambda x, y: cmp(x.name_order, y.name_order)) + + self.widgets = [] + self._layout = QVBoxLayout() + self.container = QWidget(self) + self.container.setLayout(self._layout) + self.setWidget(self.container) + for name, plugins in self.category_map.items(): + w = Category(name, plugins, self) + self.widgets.append(w) + self._layout.addWidget(w) + w.plugin_activated.connect(self.show_plugin.emit) + + + +class Preferences(QMainWindow): + + def __init__(self, gui, initial_plugin=None): + QMainWindow.__init__(self, gui) + self.gui = gui + self.must_restart = False + self.committed = False + + self.resize(900, 700) + nh, nw = min_available_height()-25, available_width()-10 + if nh < 0: + nh = 800 + if nw < 0: + nw = 600 + nh = min(self.height(), nh) + nw = min(self.width(), nw) + self.resize(nw, nh) + + geom = gprefs.get('preferences_window_geometry', None) + if geom is not None: + self.restoreGeometry(geom) + + self.setWindowModality(Qt.WindowModal) + self.setWindowTitle(__appname__ + ' - ' + _('Preferences')) + self.setWindowIcon(QIcon(I('config.png'))) + + self.status_bar = StatusBar(self) + self.setStatusBar(self.status_bar) + + self.stack = QStackedWidget(self) + self.setCentralWidget(self.stack) + self.browser = Browser(self) + self.browser.show_plugin.connect(self.show_plugin) + self.stack.addWidget(self.browser) + self.scroll_area = QScrollArea(self) + self.stack.addWidget(self.scroll_area) + self.scroll_area.setWidgetResizable(True) + + self.bar = QToolBar(self) + self.addToolBar(self.bar) + self.bar.setVisible(False) + self.bar.setIconSize(QSize(32, 32)) + self.bar.setMovable(False) + self.bar.setFloatable(False) + self.bar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) + self.apply_action = self.bar.addAction(QIcon(I('ok.png')), _('&Apply'), + self.commit) + self.cancel_action = self.bar.addAction(QIcon(I('window-close.png')), + _('&Cancel'), self.cancel) + self.bar_filler = QLabel('') + self.bar_filler.setSizePolicy(QSizePolicy.Expanding, + QSizePolicy.Preferred) + self.bar_filler.setStyleSheet( + 'QLabel { font-weight: bold }') + self.bar_filler.setAlignment(Qt.AlignHCenter | Qt.AlignCenter) + self.bar.addWidget(self.bar_filler) + self.restore_action = self.bar.addAction(QIcon(I('clear_left.png')), + _('Restore &defaults'), self.restore_defaults) + for ac, tt in [('apply', _('Save changes')), + ('cancel', _('Cancel and return to overview'))]: + ac = getattr(self, ac+'_action') + ac.setToolTip(tt) + ac.setWhatsThis(tt) + ac.setStatusTip(tt) + + for ch in self.bar.children(): + if isinstance(ch, QToolButton): + ch.setCursor(Qt.PointingHandCursor) + ch.setAutoRaise(True) + + self.stack.setCurrentIndex(0) + + if initial_plugin is not None: + category, name = initial_plugin + plugin = get_plugin(category, name) + if plugin is not None: + self.show_plugin(plugin) + + + def show_plugin(self, plugin): + self.showing_widget = plugin.create_widget(self.scroll_area) + self.showing_widget.genesis(self.gui) + self.showing_widget.initialize() + self.scroll_area.setWidget(self.showing_widget) + self.stack.setCurrentIndex(1) + self.showing_widget.show() + self.setWindowTitle(__appname__ + ' - ' + _('Preferences') + ' - ' + + plugin.gui_name) + self.apply_action.setEnabled(False) + self.showing_widget.changed_signal.connect(lambda : + self.apply_action.setEnabled(True)) + self.restore_action.setEnabled(self.showing_widget.supports_restoring_to_defaults) + tt = self.showing_widget.restore_defaults_desc + if not self.restore_action.isEnabled(): + tt = _('Restoring to defaults not supported for') + ' ' + \ + plugin.gui_name + self.restore_action.setToolTip(textwrap.fill(tt)) + self.restore_action.setWhatsThis(textwrap.fill(tt)) + self.restore_action.setStatusTip(tt) + self.bar_filler.setText(plugin.gui_name) + self.setWindowIcon(QIcon(plugin.icon)) + self.bar.setVisible(True) + + + def hide_plugin(self): + self.showing_widget = QWidget(self.scroll_area) + self.scroll_area.setWidget(self.showing_widget) + self.setWindowTitle(__appname__ + ' - ' + _('Preferences')) + self.bar.setVisible(False) + self.stack.setCurrentIndex(0) + self.setWindowIcon(QIcon(I('config.png'))) + + def commit(self, *args): + try: + must_restart = self.showing_widget.commit() + except AbortCommit: + return + self.committed = True + if must_restart: + self.must_restart = True + warning_dialog(self, _('Restart needed'), + _('Some of the changes you made require a restart.' + ' Please restart calibre as soon as possible.'), + show=True) + self.showing_widget.refresh_gui(self.gui) + self.hide_plugin() + + + def cancel(self, *args): + self.hide_plugin() + + def restore_defaults(self, *args): + self.showing_widget.restore_defaults() + + def closeEvent(self, *args): + gprefs.set('preferences_window_geometry', + bytearray(self.saveGeometry())) + return QMainWindow.closeEvent(self, *args) + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + app + gui = init_gui() + + p = Preferences(gui) + p.show() + app.exec_() + gui.shutdown() diff --git a/src/calibre/gui2/preferences/misc.py b/src/calibre/gui2/preferences/misc.py new file mode 100644 index 0000000000..eae79fdfc0 --- /dev/null +++ b/src/calibre/gui2/preferences/misc.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import QProgressDialog, QThread, Qt, pyqtSignal + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences.misc_ui import Ui_Form +from calibre.gui2 import error_dialog, config, warning_dialog, \ + open_local_file, info_dialog +from calibre.constants import isosx + +# Check Integrity {{{ + +class VacThread(QThread): + + check_done = pyqtSignal(object, object) + callback = pyqtSignal(object, object) + + def __init__(self, parent, db): + QThread.__init__(self, parent) + self.db = db + self._parent = parent + + def run(self): + err = bad = None + try: + bad = self.db.check_integrity(self.callbackf) + except: + import traceback + err = traceback.format_exc() + self.check_done.emit(bad, err) + + def callbackf(self, progress, msg): + self.callback.emit(progress, msg) + + +class CheckIntegrity(QProgressDialog): + + def __init__(self, db, parent=None): + QProgressDialog.__init__(self, parent) + self.db = db + self.setCancelButton(None) + self.setMinimum(0) + self.setMaximum(100) + self.setWindowTitle(_('Checking database integrity')) + self.setAutoReset(False) + self.setValue(0) + + self.vthread = VacThread(self, db) + self.vthread.check_done.connect(self.check_done, + type=Qt.QueuedConnection) + self.vthread.callback.connect(self.callback, type=Qt.QueuedConnection) + self.vthread.start() + + def callback(self, progress, msg): + self.setLabelText(msg) + self.setValue(int(100*progress)) + + def check_done(self, bad, err): + if err: + error_dialog(self, _('Error'), + _('Failed to check database integrity'), + det_msg=err, show=True) + elif bad: + titles = [self.db.title(x, index_is_id=True) for x in bad] + det_msg = '\n'.join(titles) + warning_dialog(self, _('Some inconsistencies found'), + _('The following books had formats listed in the ' + 'database that are not actually available. ' + 'The entries for the formats have been removed. ' + 'You should check them manually. This can ' + 'happen if you manipulate the files in the ' + 'library folder directly.'), det_msg=det_msg, show=True) + self.reset() + +# }}} + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + r = self.register + r('worker_limit', config, restart_required=True) + r('enforce_cpu_limit', config, restart_required=True) + self.device_detection_button.clicked.connect(self.debug_device_detection) + self.compact_button.clicked.connect(self.compact) + self.button_open_config_dir.clicked.connect(self.open_config_dir) + self.button_osx_symlinks.clicked.connect(self.create_symlinks) + self.button_osx_symlinks.setVisible(isosx) + + def debug_device_detection(self, *args): + from calibre.gui2.preferences.device_debug import DebugDevice + d = DebugDevice(self) + d.exec_() + + def compact(self, *args): + d = CheckIntegrity(self.gui.library_view.model().db, self) + d.exec_() + + def open_config_dir(self, *args): + from calibre.utils.config import config_dir + open_local_file(config_dir) + + def create_symlinks(self): + from calibre.utils.osx_symlinks import create_symlinks + loc, paths = create_symlinks() + if loc is None: + error_dialog(self, _('Error'), + _('Failed to install command line tools.'), + det_msg=paths, show=True) + else: + info_dialog(self, _('Command line tools installed'), + '

'+_('Command line tools installed in')+' '+loc+ + '
'+ _('If you move calibre.app, you have to re-install ' + 'the command line tools.'), + det_msg='\n'.join(paths), show=True) + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Advanced', 'Misc') + diff --git a/src/calibre/gui2/preferences/misc.ui b/src/calibre/gui2/preferences/misc.ui new file mode 100644 index 0000000000..f8582a3675 --- /dev/null +++ b/src/calibre/gui2/preferences/misc.ui @@ -0,0 +1,144 @@ + + + Form + + + + 0 + 0 + 502 + 314 + + + + Form + + + + + + &Maximum number of waiting worker processes (needs restart): + + + opt_worker_limit + + + + + + + 2 + + + 10000 + + + 2 + + + + + + + Limit the max. simultaneous jobs to the available CPU &cores + + + + + + + Qt::Vertical + + + + 20 + 18 + + + + + + + + Debug &device detection + + + + + + + Qt::Vertical + + + + 20 + 19 + + + + + + + + &Check database integrity + + + + + + + Qt::Vertical + + + + 20 + 18 + + + + + + + + Open calibre &configuration directory + + + + + + + Qt::Vertical + + + + 20 + 19 + + + + + + + + &Install command line tools + + + + + + + Qt::Vertical + + + + 20 + 18 + + + + + + + + + diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py new file mode 100644 index 0000000000..a26553db1c --- /dev/null +++ b/src/calibre/gui2/preferences/plugins.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import textwrap, os + +from PyQt4.Qt import Qt, QModelIndex, QAbstractItemModel, QVariant, QIcon, \ + QBrush, QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QLineEdit + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences.plugins_ui import Ui_Form +from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \ + disable_plugin, customize_plugin, \ + plugin_customization, add_plugin, \ + remove_plugin +from calibre.gui2 import NONE, error_dialog, info_dialog, choose_files + +class PluginModel(QAbstractItemModel): # {{{ + + def __init__(self, *args): + QAbstractItemModel.__init__(self, *args) + self.icon = QVariant(QIcon(I('plugins.png'))) + p = QIcon(self.icon).pixmap(32, 32, QIcon.Disabled, QIcon.On) + self.disabled_icon = QVariant(QIcon(p)) + self._p = p + self.populate() + + def populate(self): + self._data = {} + for plugin in initialized_plugins(): + if plugin.type not in self._data: + self._data[plugin.type] = [plugin] + else: + self._data[plugin.type].append(plugin) + self.categories = sorted(self._data.keys()) + + for plugins in self._data.values(): + plugins.sort(cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())) + + def index(self, row, column, parent): + if not self.hasIndex(row, column, parent): + return QModelIndex() + + if parent.isValid(): + return self.createIndex(row, column, 1+parent.row()) + else: + return self.createIndex(row, column, 0) + + def parent(self, index): + if not index.isValid() or index.internalId() == 0: + return QModelIndex() + return self.createIndex(index.internalId()-1, 0, 0) + + def rowCount(self, parent): + if not parent.isValid(): + return len(self.categories) + if parent.internalId() == 0: + category = self.categories[parent.row()] + return len(self._data[category]) + return 0 + + def columnCount(self, parent): + return 1 + + def index_to_plugin(self, index): + category = self.categories[index.parent().row()] + return self._data[category][index.row()] + + def plugin_to_index(self, plugin): + for i, category in enumerate(self.categories): + parent = self.index(i, 0, QModelIndex()) + for j, p in enumerate(self._data[category]): + if plugin == p: + return self.index(j, 0, parent) + return QModelIndex() + + def refresh_plugin(self, plugin, rescan=False): + if rescan: + self.populate() + idx = self.plugin_to_index(plugin) + self.dataChanged.emit(idx, idx) + + def flags(self, index): + if not index.isValid(): + return 0 + if index.internalId() == 0: + return Qt.ItemIsEnabled + flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled + return flags + + def data(self, index, role): + if not index.isValid(): + return NONE + if index.internalId() == 0: + if role == Qt.DisplayRole: + category = self.categories[index.row()] + return QVariant(_("%(plugin_type)s %(plugins)s")%\ + dict(plugin_type=category, plugins=_('plugins'))) + else: + plugin = self.index_to_plugin(index) + if role == Qt.DisplayRole: + ver = '.'.join(map(str, plugin.version)) + desc = '\n'.join(textwrap.wrap(plugin.description, 50)) + ans='%s (%s) %s %s\n%s'%(plugin.name, ver, _('by'), plugin.author, desc) + c = plugin_customization(plugin) + if c: + ans += _('\nCustomization: ')+c + return QVariant(ans) + if role == Qt.DecorationRole: + return self.disabled_icon if is_disabled(plugin) else self.icon + if role == Qt.ForegroundRole and is_disabled(plugin): + return QVariant(QBrush(Qt.gray)) + if role == Qt.UserRole: + return plugin + return NONE + +# }}} + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + supports_restoring_to_defaults = False + + def genesis(self, gui): + self.gui = gui + self._plugin_model = PluginModel() + self.plugin_view.setModel(self._plugin_model) + self.plugin_view.setStyleSheet( + "QTreeView::item { padding-bottom: 10px;}") + self.toggle_plugin_button.clicked.connect(self.toggle_plugin) + self.customize_plugin_button.clicked.connect(self.customize_plugin) + self.remove_plugin_button.clicked.connect(self.remove_plugin) + self.button_plugin_browse.clicked.connect(self.find_plugin) + self.button_plugin_add.clicked.connect(self.add_plugin) + + def toggle_plugin(self, *args): + self.modify_plugin(op='toggle') + + def customize_plugin(self, *args): + self.modify_plugin(op='customize') + + def remove_plugin(self, *args): + self.modify_plugin(op='remove') + + def add_plugin(self): + path = unicode(self.plugin_path.text()) + if path and os.access(path, os.R_OK) and path.lower().endswith('.zip'): + add_plugin(path) + self._plugin_model.populate() + self._plugin_model.reset() + self.changed_signal.emit() + else: + error_dialog(self, _('No valid plugin path'), + _('%s is not a valid plugin path')%path).exec_() + + def find_plugin(self): + path = choose_files(self, 'choose plugin dialog', _('Choose plugin'), + filters=[('Plugins', ['zip'])], all_files=False, + select_only_single_file=True) + if path: + self.plugin_path.setText(path[0]) + + def modify_plugin(self, op=''): + index = self.plugin_view.currentIndex() + if index.isValid(): + plugin = self._plugin_model.index_to_plugin(index) + if op == 'toggle': + if not plugin.can_be_disabled: + error_dialog(self,_('Plugin cannot be disabled'), + _('The plugin: %s cannot be disabled')%plugin.name).exec_() + return + if is_disabled(plugin): + enable_plugin(plugin) + else: + disable_plugin(plugin) + self._plugin_model.refresh_plugin(plugin) + self.changed_signal.emit() + if op == 'customize': + if not plugin.is_customizable(): + info_dialog(self, _('Plugin not customizable'), + _('Plugin: %s does not need customization')%plugin.name).exec_() + return + self.changed_signal.emit() + + config_dialog = QDialog(self) + button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + v = QVBoxLayout(config_dialog) + + button_box.accepted.connect(config_dialog.accept) + button_box.rejected.connect(config_dialog.reject) + config_dialog.setWindowTitle(_('Customize') + ' ' + plugin.name) + + if hasattr(plugin, 'config_widget'): + config_widget = plugin.config_widget() + v.addWidget(config_widget) + v.addWidget(button_box) + config_dialog.exec_() + + if config_dialog.result() == QDialog.Accepted: + plugin.save_settings(config_widget) + self._plugin_model.refresh_plugin(plugin) + else: + help_text = plugin.customization_help(gui=True) + help_text = QLabel(help_text, config_dialog) + help_text.setWordWrap(True) + help_text.setTextInteractionFlags(Qt.LinksAccessibleByMouse + | Qt.LinksAccessibleByKeyboard) + help_text.setOpenExternalLinks(True) + v.addWidget(help_text) + sc = plugin_customization(plugin) + if not sc: + sc = '' + sc = sc.strip() + sc = QLineEdit(sc, config_dialog) + v.addWidget(sc) + v.addWidget(button_box) + config_dialog.exec_() + + if config_dialog.result() == QDialog.Accepted: + sc = unicode(sc.text()).strip() + customize_plugin(plugin, sc) + + self._plugin_model.refresh_plugin(plugin) + elif op == 'remove': + if remove_plugin(plugin): + self._plugin_model.populate() + self._plugin_model.reset() + self.changed_signal.emit() + else: + error_dialog(self, _('Cannot remove builtin plugin'), + plugin.name + _(' cannot be removed. It is a ' + 'builtin plugin. Try disabling it instead.')).exec_() + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Advanced', 'Plugins') + diff --git a/src/calibre/gui2/preferences/plugins.ui b/src/calibre/gui2/preferences/plugins.ui new file mode 100644 index 0000000000..8979867bbc --- /dev/null +++ b/src/calibre/gui2/preferences/plugins.ui @@ -0,0 +1,141 @@ + + + Form + + + + 0 + 0 + 723 + 540 + + + + Form + + + + + + Here you can customize the behavior of Calibre by controlling what plugins it uses. + + + true + + + + + + + true + + + + 32 + 32 + + + + true + + + true + + + true + + + + + + + + + Enable/&Disable plugin + + + + + + + &Customize plugin + + + + + + + &Remove plugin + + + + + + + + + Add new plugin + + + + + + + + Plugin &file: + + + plugin_path + + + + + + + + + + ... + + + + :/images/document_open.png:/images/document_open.png + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Add + + + + + + + + + + + + + + + diff --git a/src/calibre/gui2/dialogs/config/save_template.py b/src/calibre/gui2/preferences/save_template.py similarity index 80% rename from src/calibre/gui2/dialogs/config/save_template.py rename to src/calibre/gui2/preferences/save_template.py index 71eb15f4aa..d325ac42ff 100644 --- a/src/calibre/gui2/dialogs/config/save_template.py +++ b/src/calibre/gui2/preferences/save_template.py @@ -6,15 +6,17 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from PyQt4.Qt import QWidget +from PyQt4.Qt import QWidget, pyqtSignal from calibre.gui2 import error_dialog -from calibre.gui2.dialogs.config.save_template_ui import Ui_Form +from calibre.gui2.preferences.save_template_ui import Ui_Form from calibre.library.save_to_disk import FORMAT_ARG_DESCS, \ preprocess_template class SaveTemplate(QWidget, Ui_Form): + changed_signal = pyqtSignal() + def __init__(self, *args): QWidget.__init__(self, *args) Ui_Form.__init__(self) @@ -31,8 +33,13 @@ class SaveTemplate(QWidget, Ui_Form): self.opt_template.initialize(name+'_template_history', default, help) + self.opt_template.editTextChanged.connect(self.changed) + self.opt_template.currentIndexChanged.connect(self.changed) self.option_name = name + def changed(self, *args): + self.changed_signal.emit() + def validate(self): tmpl = preprocess_template(self.opt_template.text()) fa = {} @@ -47,6 +54,9 @@ class SaveTemplate(QWidget, Ui_Form): return False return True + def set_value(self, val): + self.opt_template.set_value(val) + def save_settings(self, config, name): val = unicode(self.opt_template.text()) config.set(name, val) diff --git a/src/calibre/gui2/dialogs/config/save_template.ui b/src/calibre/gui2/preferences/save_template.ui similarity index 96% rename from src/calibre/gui2/dialogs/config/save_template.ui rename to src/calibre/gui2/preferences/save_template.ui index 02506891bb..0d7422abcf 100644 --- a/src/calibre/gui2/dialogs/config/save_template.ui +++ b/src/calibre/gui2/preferences/save_template.ui @@ -52,7 +52,7 @@ HistoryBox QComboBox -

calibre/gui2/dialogs/config/history.h
+
calibre/gui2/preferences/history.h
diff --git a/src/calibre/gui2/preferences/saving.py b/src/calibre/gui2/preferences/saving.py new file mode 100644 index 0000000000..e4b6a33917 --- /dev/null +++ b/src/calibre/gui2/preferences/saving.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \ + AbortCommit +from calibre.gui2.preferences.saving_ui import Ui_Form +from calibre.utils.config import ConfigProxy +from calibre.library.save_to_disk import config + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + self.proxy = ConfigProxy(config()) + + r = self.register + + for x in ('asciiize', 'update_metadata', 'save_cover', 'write_opf', + 'replace_whitespace', 'to_lowercase', 'formats', 'timefmt'): + r(x, self.proxy) + + self.save_template.changed_signal.connect(self.changed_signal.emit) + + + def initialize(self): + ConfigWidgetBase.initialize(self) + self.save_template.blockSignals(True) + self.save_template.initialize('save_to_disk', self.proxy['template'], + self.proxy.help('template')) + self.save_template.blockSignals(False) + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + self.save_template.set_value(self.proxy.defaults['template']) + + def commit(self): + if not self.save_template.validate(): + raise AbortCommit('abort') + self.save_template.save_settings(self.proxy, 'template') + return ConfigWidgetBase.commit(self) + + def refresh_gui(self, gui): + gui.iactions['Save To Disk'].reread_prefs() + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Import/Export', 'Saving') + diff --git a/src/calibre/gui2/preferences/saving.ui b/src/calibre/gui2/preferences/saving.ui new file mode 100644 index 0000000000..e4f5aaeb47 --- /dev/null +++ b/src/calibre/gui2/preferences/saving.ui @@ -0,0 +1,110 @@ + + + Form + + + + 0 + 0 + 707 + 340 + + + + Form + + + + + + Here you can control how calibre will save your books when you click the Save to Disk button: + + + true + + + + + + + Save &cover separately + + + + + + + Replace space with &underscores + + + + + + + Update &metadata in saved copies + + + + + + + Change paths to &lowercase + + + + + + + Format &dates as: + + + opt_timefmt + + + + + + + + + + File &formats to save: + + + opt_formats + + + + + + + + + + + + + Convert non-English characters to &English equivalents + + + + + + + Save metadata in &OPF file + + + + + + + + SaveTemplate + QWidget +
calibre/gui2/preferences/save_template.h
+ 1 +
+
+ + +
diff --git a/src/calibre/gui2/preferences/sending.py b/src/calibre/gui2/preferences/sending.py new file mode 100644 index 0000000000..748c6b2a2d --- /dev/null +++ b/src/calibre/gui2/preferences/sending.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \ + AbortCommit +from calibre.gui2.preferences.sending_ui import Ui_Form +from calibre.utils.config import ConfigProxy +from calibre.library.save_to_disk import config +from calibre.utils.config import prefs + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + self.proxy = ConfigProxy(config()) + + r = self.register + + choices = [(_('Manual management'), 'manual'), + (_('Only on send'), 'on_send'), + (_('Automatic management'), 'on_connect')] + r('manage_device_metadata', prefs, choices=choices) + + self.send_template.changed_signal.connect(self.changed_signal.emit) + + + def initialize(self): + ConfigWidgetBase.initialize(self) + self.send_template.blockSignals(True) + self.send_template.initialize('send_to_device', self.proxy['send_template'], + self.proxy.help('send_template')) + self.send_template.blockSignals(False) + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + self.send_template.set_value(self.proxy.defaults['send_template']) + + def commit(self): + if not self.send_template.validate(): + raise AbortCommit('abort') + self.send_template.save_settings(self.proxy, 'send_template') + return ConfigWidgetBase.commit(self) + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Import/Export', 'Sending') + diff --git a/src/calibre/gui2/preferences/sending.ui b/src/calibre/gui2/preferences/sending.ui new file mode 100644 index 0000000000..e064646afd --- /dev/null +++ b/src/calibre/gui2/preferences/sending.ui @@ -0,0 +1,108 @@ + + + Form + + + + 0 + 0 + 807 + 331 + + + + Form + + + + + + + 0 + 0 + + + + Metadata &management: + + + opt_manage_device_metadata + + + + + + + + 0 + 0 + + + + + Manual management + + + + + Only on send + + + + + Automatic management + + + + + + + + Qt::Horizontal + + + + 457 + 20 + + + + + + + + <li><b>Manual management</b>: Calibre updates the metadata and adds collections only when a book is sent. With this option, calibre will never remove a collection.</li> +<li><b>Only on send</b>: Calibre updates metadata and adds/removes collections for a book only when it is sent to the device. </li> +<li><b>Automatic management</b>: Calibre automatically keeps metadata on the device in sync with the calibre library, on every connect</li></ul> + + + true + + + + + + + Here you can control how calibre will save your books when you click the Send to Device button. This setting can be overriden for individual devices by customizing the device interface plugins in Preferences->Advanced->Plugins + + + true + + + + + + + + + + + SaveTemplate + QWidget +
calibre/gui2/preferences/save_template.h
+ 1 +
+
+ + +
diff --git a/src/calibre/gui2/preferences/server.py b/src/calibre/gui2/preferences/server.py new file mode 100644 index 0000000000..4db1244d75 --- /dev/null +++ b/src/calibre/gui2/preferences/server.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import time + +from PyQt4.Qt import Qt, QUrl, QDialog, QSize, QVBoxLayout, QLabel, \ + QPlainTextEdit, QDialogButtonBox + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences.server_ui import Ui_Form +from calibre.utils.search_query_parser import saved_searches +from calibre.library.server import server_config +from calibre.utils.config import ConfigProxy +from calibre.gui2 import error_dialog, config, open_url, warning_dialog, \ + Dispatcher + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + self.proxy = ConfigProxy(server_config()) + db = self.db = gui.library_view.model().db + self.server = self.gui.content_server + + r = self.register + + r('port', self.proxy) + r('username', self.proxy) + r('password', self.proxy) + r('max_cover', self.proxy) + r('max_opds_items', self.proxy) + r('max_opds_ungrouped_items', self.proxy) + + self.show_server_password.stateChanged[int].connect( + lambda s: self.opt_password.setEchoMode( + self.opt_password.Normal if s == Qt.Checked + else self.opt_password.Password)) + self.opt_password.setEchoMode(self.opt_password.Password) + + restrictions = sorted(saved_searches().names(), + cmp=lambda x,y: cmp(x.lower(), y.lower())) + choices = [('', '')] + [(x, x) for x in restrictions] + r('cs_restriction', db.prefs, choices=choices) + + self.start_button.setEnabled(not getattr(self.server, 'is_running', False)) + self.test_button.setEnabled(not self.start_button.isEnabled()) + self.stop_button.setDisabled(self.start_button.isEnabled()) + self.start_button.clicked.connect(self.start_server) + self.stop_button.clicked.connect(self.stop_server) + self.test_button.clicked.connect(self.test_server) + self.view_logs.clicked.connect(self.view_server_logs) + + r('autolaunch_server', config) + + def set_server_options(self): + c = self.proxy + c.set('port', self.opt_port.value()) + c.set('username', unicode(self.opt_username.text()).strip()) + p = unicode(self.opt_password.text()).strip() + if not p: + p = None + c.set('password', p) + + def start_server(self): + self.set_server_options() + from calibre.library.server.main import start_threaded_server + self.server = start_threaded_server(self.db, server_config().parse()) + while not self.server.is_running and self.server.exception is None: + time.sleep(1) + if self.server.exception is not None: + error_dialog(self, _('Failed to start content server'), + unicode(self.server.exception)).exec_() + return + self.start_button.setEnabled(False) + self.test_button.setEnabled(True) + self.stop_button.setEnabled(True) + + def stop_server(self): + from calibre.library.server.main import stop_threaded_server + stop_threaded_server(self.server) + self.server = None + self.start_button.setEnabled(True) + self.test_button.setEnabled(False) + self.stop_button.setEnabled(False) + + def test_server(self): + open_url(QUrl('http://127.0.0.1:'+str(self.opt_port.value()))) + + def view_server_logs(self): + from calibre.library.server import log_access_file, log_error_file + d = QDialog(self) + d.resize(QSize(800, 600)) + layout = QVBoxLayout() + d.setLayout(layout) + layout.addWidget(QLabel(_('Error log:'))) + el = QPlainTextEdit(d) + layout.addWidget(el) + try: + el.setPlainText(open(log_error_file, 'rb').read().decode('utf8', 'replace')) + except IOError: + el.setPlainText('No error log found') + layout.addWidget(QLabel(_('Access log:'))) + al = QPlainTextEdit(d) + layout.addWidget(al) + try: + al.setPlainText(open(log_access_file, 'rb').read().decode('utf8', 'replace')) + except IOError: + al.setPlainText('No access log found') + bx = QDialogButtonBox(QDialogButtonBox.Ok) + layout.addWidget(bx) + bx.accepted.connect(d.accept) + d.show() + + def commit(self): + ConfigWidgetBase.commit(self) + warning_dialog(self, _('Restart needed'), + _('You need to restart the server for changes to' + ' take effect'), show=True) + return False + + def refresh_gui(self, gui): + gui.content_server = self.server + if gui.content_server is not None: + gui.content_server.state_callback = \ + Dispatcher(gui.iactions['Connect Share'].content_server_state_changed) + gui.content_server.state_callback(gui.content_server.is_running) + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Sharing', 'Server') + diff --git a/src/calibre/gui2/preferences/server.ui b/src/calibre/gui2/preferences/server.ui new file mode 100644 index 0000000000..d043f6f52c --- /dev/null +++ b/src/calibre/gui2/preferences/server.ui @@ -0,0 +1,261 @@ + + + Form + + + + 0 + 0 + 641 + 563 + + + + Form + + + + + + + + Server &port: + + + opt_port + + + + + + + 65535 + + + 8080 + + + + + + + &Username: + + + opt_username + + + + + + + + + + &Password: + + + opt_password + + + + + + + If you leave the password blank, anyone will be able to access your book collection using the web interface. + + + + + + + The maximum size (widthxheight) for displayed covers. Larger covers are resized. + + + + + + + + + + Max. &cover size: + + + opt_max_cover + + + + + + + &Show password + + + + + + + Max. &OPDS items per query: + + + opt_max_opds_items + + + + + + + 10 + + + 10000 + + + + + + + 25 + + + 1000000 + + + + + + + Max. OPDS &ungrouped items: + + + opt_max_opds_ungrouped_items + + + + + + + Restriction (saved search) to apply: + + + + + + + This restriction (based on a saved search) will restrict the books the content server makes available to those matching the search. This setting is per library (i.e. you can have a different restriction per library). + + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + 20 + + + + + + + + + + + &Start Server + + + + + + + St&op Server + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Test Server + + + + + + + + + calibre contains a network server that allows you to access your book collection using a browser from anywhere in the world. Any changes to the settings will only take effect after a server restart. + + + true + + + + + + + Run server &automatically on startup + + + + + + + View &server logs + + + + + + + Qt::Vertical + + + + 20 + 36 + + + + + + + + <p>Remember to leave calibre running as the server only runs as long as calibre is running. +<p>Stanza should see your calibre collection automatically. If not, try adding the URL http://myhostname:8080 as a new catalog in the Stanza reader on your iPhone. Here myhostname should be the fully qualified hostname or the IP address of the computer calibre is running on. + + + true + + + + + + + Qt::Vertical + + + + 20 + 37 + + + + + + + + + diff --git a/src/calibre/gui2/dialogs/config/social.py b/src/calibre/gui2/preferences/social.py similarity index 100% rename from src/calibre/gui2/dialogs/config/social.py rename to src/calibre/gui2/preferences/social.py diff --git a/src/calibre/gui2/dialogs/config/toolbar.py b/src/calibre/gui2/preferences/toolbar.py similarity index 93% rename from src/calibre/gui2/dialogs/config/toolbar.py rename to src/calibre/gui2/preferences/toolbar.py index 5d5b0e1bfc..c13d956aea 100644 --- a/src/calibre/gui2/dialogs/config/toolbar.py +++ b/src/calibre/gui2/preferences/toolbar.py @@ -7,11 +7,12 @@ __docformat__ = 'restructuredtext en' from functools import partial -from PyQt4.Qt import QWidget, QAbstractListModel, Qt, QIcon, \ +from PyQt4.Qt import QAbstractListModel, Qt, QIcon, \ QVariant, QItemSelectionModel -from calibre.gui2.dialogs.config.toolbar_ui import Ui_Form +from calibre.gui2.preferences.toolbar_ui import Ui_Form from calibre.gui2 import gprefs, NONE, warning_dialog +from calibre.gui2.preferences import ConfigWidgetBase, test_widget class FakeAction(object): @@ -27,7 +28,7 @@ class BaseModel(QAbstractListModel): def name_to_action(self, name, gui): if name == 'Donate': - return FakeAction(name, 'donate.svg', + return FakeAction(name, 'donate.png', dont_add_to=frozenset(['context-menu', 'context-menu-device'])) if name == 'Location Manager': @@ -53,7 +54,7 @@ class BaseModel(QAbstractListModel): if role == Qt.DecorationRole: ic = action[1] if ic is None: - ic = 'blank.svg' + ic = 'blank.png' return QVariant(QIcon(I(ic))) if role == Qt.ToolTipRole and action[2] is not None: return QVariant(action[2]) @@ -195,7 +196,7 @@ class CurrentModel(BaseModel): self.reset() -class ToolbarLayout(QWidget, Ui_Form): +class ConfigWidget(ConfigWidgetBase, Ui_Form): LOCATIONS = [ ('toolbar', _('The main toolbar')), @@ -206,10 +207,7 @@ class ToolbarLayout(QWidget, Ui_Form): 'the device')) ] - def __init__(self, gui, parent=None): - QWidget.__init__(self, parent) - self.setupUi(self) - + def genesis(self, gui): self.models = {} for key, text in self.LOCATIONS: self.what.addItem(text, key) @@ -222,7 +220,6 @@ class ToolbarLayout(QWidget, Ui_Form): self.add_action_button.clicked.connect(self.add_action) self.remove_action_button.clicked.connect(self.remove_action) - self.restore_defaults_button.clicked.connect(self.restore_defaults) self.action_up_button.clicked.connect(partial(self.move, -1)) self.action_down_button.clicked.connect(partial(self.move, 1)) @@ -248,6 +245,7 @@ class ToolbarLayout(QWidget, Ui_Form): ca = self.current_actions idx = ca.model().index(ca.model().rowCount(None)-1) ca.scrollTo(idx) + self.changed_signal.emit() def remove_action(self, *args): x = self.current_actions.selectionModel().selectedIndexes() @@ -262,6 +260,8 @@ class ToolbarLayout(QWidget, Ui_Form): _('Cannot remove the actions %s from this location') % ','.join([a.action_spec[0] for a in not_removed]), show=True) + else: + self.changed_signal.emit() def move(self, delta, *args): ci = self.current_actions.currentIndex() @@ -272,24 +272,22 @@ class ToolbarLayout(QWidget, Ui_Form): self.current_actions.setCurrentIndex(ni) self.current_actions.selectionModel().select(ni, QItemSelectionModel.ClearAndSelect) + self.changed_signal.emit() def commit(self): for am, cm in self.models.values(): cm.commit() + return False - def restore_defaults(self, *args): + def restore_defaults(self): for am, cm in self.models.values(): cm.restore_defaults() am.restore_defaults() + self.changed_signal.emit() if __name__ == '__main__': from PyQt4.Qt import QApplication - from calibre.gui2.ui import Main - app=QApplication([]) - m = Main(None) - a = ToolbarLayout(m) - a.show() - app.exec_() - a.commit() + app = QApplication([]) + test_widget('Interface', 'Toolbar') diff --git a/src/calibre/gui2/dialogs/config/toolbar.ui b/src/calibre/gui2/preferences/toolbar.ui similarity index 86% rename from src/calibre/gui2/dialogs/config/toolbar.ui rename to src/calibre/gui2/preferences/toolbar.ui index 091f21c4ae..0e601f74a2 100644 --- a/src/calibre/gui2/dialogs/config/toolbar.ui +++ b/src/calibre/gui2/preferences/toolbar.ui @@ -95,8 +95,8 @@ ... - - :/images/arrow-up.svg:/images/arrow-up.svg + + :/images/arrow-up.png:/images/arrow-up.png @@ -128,8 +128,8 @@ ... - - :/images/arrow-down.svg:/images/arrow-down.svg + + :/images/arrow-down.png:/images/arrow-down.png @@ -158,8 +158,8 @@ ... - - :/images/forward.svg:/images/forward.svg + + :/images/forward.png:/images/forward.png @@ -194,8 +194,8 @@ ... - - :/images/back.svg:/images/back.svg + + :/images/back.png:/images/back.png @@ -207,17 +207,10 @@
- - - - Restore to &default - - -
- + diff --git a/src/calibre/gui2/preferences/tweaks.py b/src/calibre/gui2/preferences/tweaks.py new file mode 100644 index 0000000000..62bc87c490 --- /dev/null +++ b/src/calibre/gui2/preferences/tweaks.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2010, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, AbortCommit +from calibre.gui2.preferences.tweaks_ui import Ui_Form +from calibre.gui2 import error_dialog +from calibre.utils.config import read_raw_tweaks, write_tweaks + + +class ConfigWidget(ConfigWidgetBase, Ui_Form): + + def genesis(self, gui): + self.gui = gui + self.current_tweaks.textChanged.connect(self.changed) + + def changed(self, *args): + self.changed_signal.emit() + + def initialize(self): + deft, curt = read_raw_tweaks() + self.current_tweaks.blockSignals(True) + self.current_tweaks.setPlainText(curt.decode('utf-8')) + self.current_tweaks.blockSignals(False) + + self.default_tweaks.setPlainText(deft.decode('utf-8')) + + def restore_defaults(self): + ConfigWidgetBase.restore_defaults(self) + deft, curt = read_raw_tweaks() + self.current_tweaks.setPlainText(deft.decode('utf-8')) + + + def commit(self): + raw = unicode(self.current_tweaks.toPlainText()).encode('utf-8') + try: + exec raw + except: + import traceback + error_dialog(self, _('Invalid tweaks'), + _('The tweaks you entered are invalid, try resetting the' + ' tweaks to default and changing them one by one until' + ' you find the invalid setting.'), + det_msg=traceback.format_exc(), show=True) + raise AbortCommit('abort') + write_tweaks(raw) + return ConfigWidgetBase.commit(self) + + +if __name__ == '__main__': + from PyQt4.Qt import QApplication + app = QApplication([]) + test_widget('Advanced', 'Tweaks') + diff --git a/src/calibre/gui2/preferences/tweaks.ui b/src/calibre/gui2/preferences/tweaks.ui new file mode 100644 index 0000000000..3234f4be9b --- /dev/null +++ b/src/calibre/gui2/preferences/tweaks.ui @@ -0,0 +1,59 @@ + + + Form + + + + 0 + 0 + 660 + 351 + + + + Form + + + + + + Values for the tweaks are shown below. Edit them to change the behavior of calibre + + + true + + + + + + + All available tweaks + + + + + + true + + + + + + + + + + &Current tweaks + + + + + + + + + + + + + diff --git a/src/calibre/gui2/shortcuts.ui b/src/calibre/gui2/shortcuts.ui index 4afe564640..b26976c8e2 100644 --- a/src/calibre/gui2/shortcuts.ui +++ b/src/calibre/gui2/shortcuts.ui @@ -69,7 +69,7 @@ - :/images/clear_left.svg:/images/clear_left.svg + :/images/clear_left.png:/images/clear_left.png @@ -110,7 +110,7 @@ - :/images/clear_left.svg:/images/clear_left.svg + :/images/clear_left.png:/images/clear_left.png diff --git a/src/calibre/gui2/tag_view.py b/src/calibre/gui2/tag_view.py index 7d2333f58b..72f0efd9bf 100644 --- a/src/calibre/gui2/tag_view.py +++ b/src/calibre/gui2/tag_view.py @@ -372,19 +372,19 @@ class TagsModel(QAbstractItemModel): # {{{ # before a QPaintDevice'. The ':' in front avoids polluting either the # user-defined categories (':' at end) or columns namespaces (no ':'). self.category_icon_map = TagsIcons({ - 'authors' : QIcon(I('user_profile.svg')), - 'series' : QIcon(I('series.svg')), - 'formats' : QIcon(I('book.svg')), + 'authors' : QIcon(I('user_profile.png')), + 'series' : QIcon(I('series.png')), + 'formats' : QIcon(I('book.png')), 'publisher' : QIcon(I('publisher.png')), 'rating' : QIcon(I('star.png')), - 'news' : QIcon(I('news.svg')), - 'tags' : QIcon(I('tags.svg')), - ':custom' : QIcon(I('column.svg')), - ':user' : QIcon(I('drawer.svg')), - 'search' : QIcon(I('search.svg'))}) + 'news' : QIcon(I('news.png')), + 'tags' : QIcon(I('tags.png')), + ':custom' : QIcon(I('column.png')), + ':user' : QIcon(I('drawer.png')), + 'search' : QIcon(I('search.png'))}) self.categories_with_ratings = ['authors', 'series', 'publisher', 'tags'] - self.icon_state_map = [None, QIcon(I('plus.svg')), QIcon(I('minus.svg'))] + self.icon_state_map = [None, QIcon(I('plus.png')), QIcon(I('minus.png'))] self.db = db self.tags_view = parent self.hidden_categories = hidden_categories diff --git a/src/calibre/gui2/throbber.py b/src/calibre/gui2/throbber.py index e27438b60d..9d8c508f60 100644 --- a/src/calibre/gui2/throbber.py +++ b/src/calibre/gui2/throbber.py @@ -64,7 +64,7 @@ if __name__ == '__main__': w = QWidget() w.setLayout(QHBoxLayout()) b = ThrobbingButton() - b.setIcon(QIcon(I('donate.svg'))) + b.setIcon(QIcon(I('donate.png'))) w.layout().addWidget(b) w.show() b.set_normal_icon_size(64, 64) diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 142fa11c59..84f5a1a2c9 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -164,13 +164,13 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{ self.system_tray_icon.show() self.system_tray_menu = QMenu(self) self.restore_action = self.system_tray_menu.addAction( - QIcon(I('page.svg')), _('&Restore')) + QIcon(I('page.png')), _('&Restore')) self.donate_action = self.system_tray_menu.addAction( - QIcon(I('donate.svg')), _('&Donate to support calibre')) + QIcon(I('donate.png')), _('&Donate to support calibre')) self.donate_button.setDefaultAction(self.donate_action) self.donate_button.setStatusTip(self.donate_button.toolTip()) self.eject_action = self.system_tray_menu.addAction( - QIcon(I('eject.svg')), _('&Eject connected device')) + QIcon(I('eject.png')), _('&Eject connected device')) self.eject_action.setEnabled(False) self.addAction(self.quit_action) self.system_tray_menu.addAction(self.quit_action) @@ -514,7 +514,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{ d = QMessageBox(QMessageBox.Warning, _('WARNING: Active jobs'), msg, QMessageBox.Yes|QMessageBox.No, self) - d.setIconPixmap(QPixmap(I('dialog_warning.svg'))) + d.setIconPixmap(QPixmap(I('dialog_warning.png'))) d.setDefaultButton(QMessageBox.No) if d.exec_() != QMessageBox.Yes: return False diff --git a/src/calibre/gui2/viewer/config.ui b/src/calibre/gui2/viewer/config.ui index d6e71c77d2..09c38fc908 100644 --- a/src/calibre/gui2/viewer/config.ui +++ b/src/calibre/gui2/viewer/config.ui @@ -15,7 +15,7 @@ - :/images/config.svg:/images/config.svg + :/images/config.png:/images/config.png diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 75f95b1a90..60ee362882 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -444,12 +444,12 @@ class DocumentView(QWebView): self.connect(self.document, SIGNAL('animated_scroll_done()'), self.animated_scroll_done, Qt.QueuedConnection) copy_action = self.pageAction(self.document.Copy) - copy_action.setIcon(QIcon(I('convert.svg'))) + copy_action.setIcon(QIcon(I('convert.png'))) d = self.document self.unimplemented_actions = list(map(self.pageAction, [d.DownloadImageToDisk, d.OpenLinkInNewWindow, d.DownloadLinkToDisk, d.OpenImageInNewWindow, d.OpenLink])) - self.dictionary_action = QAction(QIcon(I('dictionary.svg')), + self.dictionary_action = QAction(QIcon(I('dictionary.png')), _('&Lookup in dictionary'), self) self.dictionary_action.setShortcut(Qt.CTRL+Qt.Key_L) self.dictionary_action.triggered.connect(self.lookup) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 32bfdd22ce..c8f1f62856 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -266,7 +266,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.action_full_screen.setCheckable(True) self.print_menu = QMenu() - self.print_menu.addAction(QIcon(I('print-preview.svg')), _('Print Preview')) + self.print_menu.addAction(QIcon(I('print-preview.png')), _('Print Preview')) self.action_print.setMenu(self.print_menu) self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup) self.connect(self.action_print, SIGNAL("triggered(bool)"), partial(self.print_book, preview=False)) @@ -694,7 +694,7 @@ def main(args=sys.argv): pid = os.fork() if False and (islinux or isfreebsd) else -1 if pid <= 0: app = Application(args) - app.setWindowIcon(QIcon(I('viewer.svg'))) + app.setWindowIcon(QIcon(I('viewer.png'))) QApplication.setOrganizationName(ORG_NAME) QApplication.setApplicationName(APP_UID) main = EbookViewer(args[1] if len(args) > 1 else None, diff --git a/src/calibre/gui2/viewer/main.ui b/src/calibre/gui2/viewer/main.ui index 78d0d3b2da..e3b8fb8a61 100644 --- a/src/calibre/gui2/viewer/main.ui +++ b/src/calibre/gui2/viewer/main.ui @@ -15,7 +15,7 @@ - :/images/viewer.svg:/images/viewer.svg + :/images/viewer.png:/images/viewer.png @@ -84,7 +84,7 @@ - :/images/window-close.svg:/images/window-close.svg + :/images/window-close.png:/images/window-close.png @@ -147,7 +147,7 @@ - :/images/back.svg:/images/back.svg + :/images/back.png:/images/back.png Back @@ -156,7 +156,7 @@ - :/images/forward.svg:/images/forward.svg + :/images/forward.png:/images/forward.png Forward @@ -165,7 +165,7 @@ - :/images/next.svg:/images/next.svg + :/images/next.png:/images/next.png Next page @@ -174,7 +174,7 @@ - :/images/previous.svg:/images/previous.svg + :/images/previous.png:/images/previous.png Previous page @@ -183,7 +183,7 @@ - :/images/font_size_larger.svg:/images/font_size_larger.svg + :/images/font_size_larger.png:/images/font_size_larger.png Font size larger @@ -192,7 +192,7 @@ - :/images/font_size_smaller.svg:/images/font_size_smaller.svg + :/images/font_size_smaller.png:/images/font_size_smaller.png Font size smaller @@ -201,7 +201,7 @@ - :/images/chapters.svg:/images/chapters.svg + :/images/chapters.png:/images/chapters.png Table of Contents @@ -210,7 +210,7 @@ - :/images/dialog_information.svg:/images/dialog_information.svg + :/images/dialog_information.png:/images/dialog_information.png Metadata @@ -219,7 +219,7 @@ - :/images/document_open.svg:/images/document_open.svg + :/images/document_open.png:/images/document_open.png Open ebook @@ -228,7 +228,7 @@ - :/images/arrow-down.svg:/images/arrow-down.svg + :/images/arrow-down.png:/images/arrow-down.png Find next @@ -243,7 +243,7 @@ - :/images/edit_copy.svg:/images/edit_copy.svg + :/images/edit_copy.png:/images/edit_copy.png Copy to clipboard @@ -252,7 +252,7 @@ - :/images/config.svg:/images/config.svg + :/images/config.png:/images/config.png Preferences @@ -261,7 +261,7 @@ - :/images/lookfeel.svg:/images/lookfeel.svg + :/images/lookfeel.png:/images/lookfeel.png Reference Mode @@ -270,7 +270,7 @@ - :/images/bookmarks.svg:/images/bookmarks.svg + :/images/bookmarks.png:/images/bookmarks.png Bookmark @@ -279,7 +279,7 @@ - :/images/page.svg:/images/page.svg + :/images/page.png:/images/page.png Toggle full screen @@ -288,7 +288,7 @@ - :/images/print.svg:/images/print.svg + :/images/print.png:/images/print.png Print @@ -297,7 +297,7 @@ - :/images/arrow-up.svg:/images/arrow-up.svg + :/images/arrow-up.png:/images/arrow-up.png Find previous diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index ae7f8d259e..60224aefc7 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -61,13 +61,24 @@ class ProgressIndicator(QWidget): class FilenamePattern(QWidget, Ui_Form): + changed_signal = pyqtSignal() + def __init__(self, parent): QWidget.__init__(self, parent) self.setupUi(self) self.connect(self.test_button, SIGNAL('clicked()'), self.do_test) self.connect(self.re, SIGNAL('returnPressed()'), self.do_test) - self.re.setText(prefs['filename_pattern']) + self.initialize() + self.re.textChanged.connect(lambda x: self.changed_signal.emit()) + + def initialize(self, defaults=False): + if defaults: + val = prefs.defaults['filename_pattern'] + else: + val = prefs['filename_pattern'] + self.re.setText(val) + def do_test(self): try: @@ -1021,6 +1032,9 @@ class Splitter(QSplitter): # Public API {{{ + def update_desired_state(self): + self.desired_show = not self.is_side_index_hidden + def save_state(self): if self.count() > 1: gprefs[self.save_name+'_state'] = self.get_state() diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 394b919016..f3234d48d5 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -668,8 +668,8 @@ class Wizard(QWizard): self.setPixmap(self.LogoPixmap, p.scaledToHeight(80, Qt.SmoothTransformation)) self.setPixmap(self.WatermarkPixmap, - QPixmap(I('welcome_wizard.svg'))) - self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.svg'))) + QPixmap(I('welcome_wizard.png'))) + self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.png'))) self.device_page = DevicePage() self.library_page = LibraryPage() self.connect(self.library_page, SIGNAL('retranslate()'), diff --git a/src/calibre/gui2/wizard/device.ui b/src/calibre/gui2/wizard/device.ui index a422140bb1..229f83be9e 100644 --- a/src/calibre/gui2/wizard/device.ui +++ b/src/calibre/gui2/wizard/device.ui @@ -15,7 +15,7 @@ - :/images/wizard.svg:/images/wizard.svg + :/images/wizard.png:/images/wizard.png Welcome to calibre diff --git a/src/calibre/gui2/wizard/send_email.py b/src/calibre/gui2/wizard/send_email.py index 504c426359..61b9c9f934 100644 --- a/src/calibre/gui2/wizard/send_email.py +++ b/src/calibre/gui2/wizard/send_email.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import cStringIO, sys from binascii import hexlify, unhexlify -from PyQt4.Qt import QWidget, SIGNAL, QDialog, Qt +from PyQt4.Qt import QWidget, pyqtSignal, QDialog, Qt from calibre.gui2.wizard.send_email_ui import Ui_Form from calibre.utils.smtp import config as smtp_prefs @@ -24,7 +24,7 @@ class TestEmail(QDialog, TE_Dialog): self.setupUi(self) opts = smtp_prefs().parse() self.test_func = parent.test_email_settings - self.connect(self.test_button, SIGNAL('clicked(bool)'), self.test) + self.test_button.clicked.connect(self.test) self.from_.setText(unicode(self.from_.text())%opts.from_) if pa: self.to.setText(pa) @@ -33,7 +33,7 @@ class TestEmail(QDialog, TE_Dialog): (opts.relay_username, unhexlify(opts.relay_password), opts.relay_host, opts.relay_port, opts.encryption)) - def test(self): + def test(self, *args): self.log.setPlainText(_('Sending...')) self.test_button.setEnabled(False) try: @@ -47,6 +47,8 @@ class TestEmail(QDialog, TE_Dialog): class SendEmail(QWidget, Ui_Form): + changed_signal = pyqtSignal() + def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) @@ -57,23 +59,31 @@ class SendEmail(QWidget, Ui_Form): self.smtp_opts = opts if opts.from_: self.email_from.setText(opts.from_) + self.email_from.textChanged.connect(self.changed) if opts.relay_host: self.relay_host.setText(opts.relay_host) + self.relay_host.textChanged.connect(self.changed) self.relay_port.setValue(opts.relay_port) + self.relay_port.valueChanged.connect(self.changed) if opts.relay_username: self.relay_username.setText(opts.relay_username) + self.relay_username.textChanged.connect(self.changed) if opts.relay_password: self.relay_password.setText(unhexlify(opts.relay_password)) + self.relay_password.textChanged.connect(self.changed) (self.relay_tls if opts.encryption == 'TLS' else self.relay_ssl).setChecked(True) - self.connect(self.relay_use_gmail, SIGNAL('clicked(bool)'), - self.create_gmail_relay) - self.connect(self.relay_show_password, SIGNAL('stateChanged(int)'), - lambda - state:self.relay_password.setEchoMode(self.relay_password.Password if - state == 0 else self.relay_password.Normal)) - self.connect(self.test_email_button, SIGNAL('clicked(bool)'), - self.test_email) + self.relay_tls.toggled.connect(self.changed) + self.relay_use_gmail.clicked.connect( + self.create_gmail_relay) + self.relay_show_password.stateChanged.connect( + lambda state : self.relay_password.setEchoMode( + self.relay_password.Password if + state == 0 else self.relay_password.Normal)) + self.test_email_button.clicked.connect(self.test_email) + + def changed(self, *args): + self.changed_signal.emit() def test_email(self, *args): pa = self.preferred_to_address() diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index b4fd537729..4637730116 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -2587,24 +2587,8 @@ class EPUB_MOBI(CatalogPlugin): # Check to see if thumbnail exists thumb_fp = "%s/thumbnail_default.jpg" % (image_dir) cover = "%s/DefaultCover.png" % (self.catalogPath) - - # Init Qt for image conversion - from calibre.gui2 import is_ok_to_use_qt - if is_ok_to_use_qt(): - from PyQt4.Qt import QImage, QColor, QPainter, Qt - - # Convert .svg to .jpg - cover_img = QImage(I('book.svg')) - i = QImage(cover_img.size(), - QImage.Format_ARGB32_Premultiplied) - i.fill(QColor(Qt.white).rgb()) - p = QPainter(i) - p.drawImage(0, 0, cover_img) - p.end() - i.save(cover) - else: - if not os.path.exists(cover): - shutil.copyfile(I('library.png'), cover) + if not os.path.exists(cover): + shutil.copyfile(I('book.png'), cover) if os.path.isfile(thumb_fp): # Check to see if default cover is newer than thumbnail diff --git a/src/calibre/library/save_to_disk.py b/src/calibre/library/save_to_disk.py index 15020855f7..f5c4063789 100644 --- a/src/calibre/library/save_to_disk.py +++ b/src/calibre/library/save_to_disk.py @@ -61,7 +61,7 @@ def config(defaults=None): 'actual e-book file(s).')) x('formats', default='all', help=_('Comma separated list of formats to save for each book.' - ' By default all available books are saved.')) + ' By default all available formats are saved.')) x('template', default=DEFAULT_TEMPLATE, help=_('The template to control the filename and directory structure of the saved files. ' 'Default is "%s" which will save books into a per-author ' diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 9323581c53..eceea6a262 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -334,7 +334,7 @@ class PostInstall: with TemporaryDirectory() as tdir: with CurrentDir(tdir): - render_img('mimetypes/lrf.svg', 'calibre-lrf.png') + render_img('mimetypes/lrf.png', 'calibre-lrf.png') check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True) self.icon_resources.append(('mimetypes', 'application-lrf', '128')) check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True) @@ -343,7 +343,7 @@ class PostInstall: render_img('lt.png', 'calibre-gui.png') check_call('xdg-icon-resource install --noupdate --size 128 calibre-gui.png calibre-gui', shell=True) self.icon_resources.append(('apps', 'calibre-gui', '128')) - render_img('viewer.svg', 'calibre-viewer.png') + render_img('viewer.png', 'calibre-viewer.png') check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) self.icon_resources.append(('apps', 'calibre-viewer', '128')) diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 4cf17d66e9..116d4d6fce 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.7.17\n" -"POT-Creation-Date: 2010-09-03 12:17+MDT\n" -"PO-Revision-Date: 2010-09-03 12:17+MDT\n" +"POT-Creation-Date: 2010-09-05 17:35+MDT\n" +"PO-Revision-Date: 2010-09-05 17:35+MDT\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -107,14 +107,14 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:292 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:137 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:144 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:111 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:136 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:138 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:869 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:878 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1163 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1166 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:862 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:871 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1155 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1158 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:155 @@ -176,8 +176,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:376 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:17 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:22 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:612 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:201 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:234 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:206 msgid "Preferences" msgstr "" @@ -239,20 +241,156 @@ msgstr "" msgid "Set metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:681 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:682 msgid "Look and Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:683 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:692 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:199 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:684 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:696 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:707 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:718 msgid "Interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:690 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:688 +msgid "Adjust the look and feel of the calibre interface to suit your tastes" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:694 msgid "Behavior" msgstr "" +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:700 +msgid "Change the way calibre behaves" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:705 +msgid "Add your own columns" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:711 +msgid "Add/remove your own columns to the calibre book list" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:716 +msgid "Customize the toolbar" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:722 +msgid "Customize the toolbars and context menus, changing which actions are available in each" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:728 +msgid "Input Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:730 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:741 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:752 +msgid "Conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:734 +msgid "Set conversion options specific to each input format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:739 +msgid "Common Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:745 +msgid "Set conversion options common to all formats" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:750 +msgid "Output Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:756 +msgid "Set conversion options specific to each output format" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:761 +msgid "Adding books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:763 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:775 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:787 +msgid "Import/Export" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:767 +msgid "Control how calibre reads metadata from files when adding books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:773 +msgid "Saving books to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:779 +msgid "Control how calibre exports files from its database to disk when using Save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:785 +msgid "Sending books to devices" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:791 +msgid "Control how calibre transfers files to your ebook reader" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:797 +msgid "Sharing books by email" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:799 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:811 +msgid "Sharing" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:803 +msgid "Setup sharing of books via email. Can be used for automatic sending of downloaded news to your devices" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:809 +msgid "Sharing over the net" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:815 +msgid "Setup the calibre Content Server which will give you access to your calibre library from anywhere, on any device, over the internet" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:822 +msgid "Plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:824 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:836 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:847 +msgid "Advanced" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:828 +msgid "Add/remove/customize various bits of calibre functionality" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:834 +msgid "Tweaks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:840 +msgid "Fine tune how calibre behaves in various contexts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:845 +msgid "Miscellaneous" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:851 +msgid "Miscellaneous advanced configuration" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/customize/conversion.py:102 msgid "Conversion Input" msgstr "" @@ -832,7 +970,7 @@ msgid "Place files in sub directories if the device supports them" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:43 -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:86 msgid "Read metadata from files on device" msgstr "" @@ -845,7 +983,7 @@ msgid "Template to control how books are saved" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:50 -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:89 msgid "Extra customization" msgstr "" @@ -1678,9 +1816,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:35 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:210 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:211 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:189 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:99 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:72 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:318 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1079 msgid "Comments" @@ -1977,7 +2115,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1401 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:53 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:199 msgid "Table of Contents" msgstr "" @@ -2611,7 +2749,7 @@ msgid "Add books to your calibre library from the connected device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/annotate.py:20 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:498 msgid "Fetch annotations (experimental)" msgstr "" @@ -2702,7 +2840,7 @@ msgid "Select destination for %s.%s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:81 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:51 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:111 msgid "%d books" msgstr "" @@ -2749,8 +2887,8 @@ msgid "The folder %s already exists. Delete it first." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:186 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:753 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns.py:100 msgid "Are you sure?" msgstr "" @@ -2835,7 +2973,7 @@ msgid "Could not copy books: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:137 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:678 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:671 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:234 msgid "Failed" msgstr "" @@ -2897,14 +3035,14 @@ msgid "Main memory" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:436 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:445 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:444 msgid "Storage Card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:438 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:447 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:446 msgid "Storage Card B" msgstr "" @@ -3061,9 +3199,9 @@ msgid "Failed to download metadata:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:608 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:570 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:1005 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:607 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:112 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:54 msgid "Error" msgstr "" @@ -3327,7 +3465,7 @@ msgid "The specified directory could not be processed." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:228 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:811 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:804 msgid "No books" msgstr "" @@ -3376,7 +3514,7 @@ msgid "Looking for duplicates based on file hash" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/__init__.py:109 -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:70 msgid "Choose root folder" msgstr "" @@ -3393,7 +3531,7 @@ msgid "Add books to calibre" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/scan_ui.py:21 -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:62 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/finish_ui.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/kindle_ui.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/library_ui.py:49 @@ -3409,94 +3547,92 @@ msgstr "" msgid "This may take a few minutes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:63 msgid "Choose the location to add books from" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:64 msgid "Select a folder on your hard disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:65 msgid "" "

calibre can scan your computer for existing books automatically. These books will then be copied into the calibre library. This wizard will help you customize the scanning and import process for your existing book collection.

\n" "

Choose a root folder. Books will be searched for only inside this folder and any sub-folders.

\n" "

Make sure that the folder you chose for your calibre library is not under the root folder you choose.

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:68 msgid "&Root folder:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:69 msgid "This folder and its sub-folders will be scanned for books to import into calibre's library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:66 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:52 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:53 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:53 -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:79 -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:80 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:72 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:629 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:630 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:642 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:644 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:646 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:648 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:649 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:702 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:101 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:103 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:108 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:364 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:77 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:369 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:383 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:394 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:396 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:398 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:404 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:87 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:90 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:156 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:159 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:163 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:166 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:388 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:403 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:171 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:135 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:77 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:267 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:269 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:275 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:156 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:157 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:78 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:80 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:82 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:83 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:85 -#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:75 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:110 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:80 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:191 msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:72 msgid "Handle multiple files per book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:73 msgid "&One book per folder, assumes every ebook file in a folder is the same book in a different format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/add_wizard/welcome_ui.py:74 msgid "&Multiple books per folder, assumes every ebook file is a different book" msgstr "" @@ -3520,8 +3656,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:118 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:119 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:229 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:24 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:100 msgid "Formats" msgstr "" @@ -3544,9 +3680,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1074 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1078 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:47 -#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:73 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:78 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:293 msgid "None" msgstr "" @@ -3596,13 +3732,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi_ui.py:68 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_tab_template_ui.py:27 #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:88 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:31 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:124 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:171 #: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output_ui.py:66 #: /home/kovid/work/calibre/src/calibre/gui2/convert/page_setup_ui.py:115 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdb_input_ui.py:31 @@ -3614,16 +3750,26 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:62 #: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_input_ui.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output_ui.py:45 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:55 #: /home/kovid/work/calibre/src/calibre/gui2/convert/xpath_wizard_ui.py:67 -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:77 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template_ui.py:41 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:82 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_item_ui.py:35 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/adding_ui.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:136 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/conversion_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template_ui.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks_ui.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:107 msgid "Form" msgstr "" @@ -3785,52 +3931,52 @@ msgid "input" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:89 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:94 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 msgid "&Number of Colors:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:90 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:101 msgid "Disable &normalize" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:91 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:102 msgid "Keep &aspect ratio" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:92 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:103 msgid "Disable &Sharpening" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:93 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:109 msgid "Disable &Trimming" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:94 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:108 msgid "&Wide" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:95 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:104 msgid "&Landscape" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:96 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:106 msgid "&Right to left" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:97 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:105 msgid "Don't so&rt" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:98 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:102 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:107 msgid "De&speckle" msgstr "" @@ -3839,7 +3985,7 @@ msgid "&Disable comic processing" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:100 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:120 msgid "&Output format:" msgstr "" @@ -3856,7 +4002,7 @@ msgid "Debug the conversion process." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug.py:39 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:56 msgid "Choose debug folder" msgstr "" @@ -3868,11 +4014,11 @@ msgstr "" msgid "Failed to create debug directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:55 msgid "Choose a folder to put the debug output into. If you specify a folder, calibre will place a lot of debug output into it. This will be useful in understanding the conversion process and figuring out the correct values for conversion parameters like Table of Contents and Chapter Detection." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:59 msgid "The debug process outputs the intermediate HTML generated at various stages of the conversion process. This HTML can sometimes serve as a good starting point for hand editing a conversion." msgstr "" @@ -3927,36 +4073,36 @@ msgstr "" msgid "Sectionize Chapters (Use with care!)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:104 msgid "Font rescaling wizard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:105 msgid "" "

This wizard will help you choose an appropriate font size key for your needs. Just enter the base font size of the input document and then enter an input font size. The wizard will display what font size it will be mapped to, by the font rescaling algorithm. You can adjust the algorithm by adjusting the output base font size and font key below. When you find values suitable for you, click OK.

\n" "

By default, if the output base font size is zero and/or no font size key is specified, calibre will use the values from the current Output Profile.

\n" "

See the User Manual for a discussion of how font size rescaling works.

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:108 msgid "&Output document" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:109 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:114 msgid "&Base font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:105 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:128 msgid "Font size &key:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:110 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:117 #: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:118 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/convert/lrf_output_ui.py:125 @@ -3967,23 +4113,23 @@ msgstr "" msgid " pt" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:112 msgid "Use &default values" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:113 msgid "&Input document" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:116 msgid "&Font size: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:118 msgid " will map to size: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/font_key_ui.py:119 msgid "0.0 pt" msgstr "" @@ -4007,63 +4153,63 @@ msgstr "" msgid "Justify text" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:125 msgid "&Disable font size rescaling" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:126 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:129 msgid "Wizard to help you choose an appropriate font size key" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:131 msgid "Line &height:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:133 msgid "Input character &encoding:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:134 msgid "Remove &spacing between paragraphs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:135 msgid "Indent size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:131 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136 msgid "

When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137 msgid " em" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138 msgid "Text justification:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:139 msgid "&Linearize tables" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:140 msgid "Extra &CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:141 msgid "&Transliterate unicode characters to ASCII" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:142 msgid "Insert &blank line" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/look_and_feel_ui.py:143 msgid "Keep &ligatures" msgstr "" @@ -4121,7 +4267,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:200 msgid "Metadata" msgstr "" @@ -4160,82 +4306,82 @@ msgstr "" msgid " is not a valid picture" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:167 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:405 msgid "Book Cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:173 msgid "Use cover from &source file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:169 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:406 msgid "Change &cover image:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:175 msgid "Browse for an image to use as the cover of this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:366 msgid "&Title: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:367 msgid "Change the title of this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:161 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:370 msgid "&Author(s): " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:180 msgid "Author So&rt:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:181 msgid "Change the author(s) of this book. Multiple authors should be separated by a comma" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:177 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:170 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:374 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:379 msgid "&Publisher: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:178 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:375 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:380 msgid "Ta&gs: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:179 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:381 msgid "Tags categorize the book. This is particularly useful while searching.

They can be any words or phrases, separated by commas." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:180 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:179 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:379 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:384 msgid "&Series:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:181 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:182 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:180 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:181 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:380 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:381 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:187 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:386 msgid "List of known series. You can add new series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:183 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:386 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:391 msgid "Book " msgstr "" @@ -4243,7 +4389,7 @@ msgstr "" msgid "MOBI Output" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/mobi_output.py:43 msgid "Default" msgstr "" @@ -4406,18 +4552,18 @@ msgstr "" msgid "Options specific to the input format." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:112 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:64 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:53 msgid "Dialog" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:118 msgid "&Input format:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single_ui.py:119 msgid "Use &saved conversion settings for individual books" msgstr "" @@ -4448,12 +4594,12 @@ msgid "Footer regular expression:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:87 msgid "Invalid regular expression" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:77 +#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:88 msgid "Invalid regular expression: %s" msgstr "" @@ -4575,18 +4721,18 @@ msgstr "" msgid "Force maximum line length" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:51 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:65 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:66 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:41 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:49 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:49 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress_ui.py:55 msgid "TextLabel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:57 msgid "Use a wizard to help construct the XPath expression" msgstr "" @@ -4681,16 +4827,12 @@ msgid "Undefined" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:133 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:241 #: /home/kovid/work/calibre/src/calibre/library/server/xml.py:119 msgid "Yes" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:134 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:243 #: /home/kovid/work/calibre/src/calibre/library/server/xml.py:121 msgid "No" @@ -4713,7 +4855,7 @@ msgid " index:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:451 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:188 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:193 msgid "Automatically number books in this series" msgstr "" @@ -4729,267 +4871,267 @@ msgstr "" msgid "tags to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:48 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:136 msgid "No details available." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:165 msgid "Device no longer connected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:284 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:283 msgid "Get device information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:294 msgid "Get list of books on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:305 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:304 msgid "Get annotations from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:313 msgid "Send metadata to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:319 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:318 msgid "Send collections to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:342 msgid "Upload %d books to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:358 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:357 msgid "Delete books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:375 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:374 msgid "Download books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:384 msgid "View book on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:418 msgid "Set default send to device action" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:425 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:424 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:427 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:426 msgid "Send to storage card A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:429 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:428 msgid "Send to storage card B" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:434 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:443 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:433 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:442 msgid "Main Memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:454 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:453 msgid "Send and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:455 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:454 msgid "Send specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:491 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:490 msgid "Eject device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:609 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:608 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:636 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:629 msgid "Select folder to open as device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:684 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:677 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:685 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:678 msgid "There was a temporary error talking to the device. Please unplug and reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:717 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:726 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:719 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:812 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:805 msgid "selected to send" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:817 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:810 msgid "Choose format to send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:826 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:819 msgid "No device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:827 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:820 msgid "Cannot send: No device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:830 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:834 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:823 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:827 msgid "No card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:831 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:835 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:828 msgid "Cannot send: Device has no storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:876 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:869 msgid "E-book:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:879 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:872 msgid "Attached, you will find the e-book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:880 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:873 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:107 msgid "by" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:881 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:874 msgid "in the %s format." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:894 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:887 msgid "Sending email to" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:924 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:932 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1026 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1088 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:917 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:925 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1018 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1080 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1199 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:1207 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1215 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:925 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:918 msgid "Auto convert the following books before sending via email?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:933 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:926 msgid "Could not email the following books as no suitable formats were found:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:951 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:944 msgid "Failed to email books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:952 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:945 msgid "Failed to email the following books:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:956 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:949 msgid "Sent by email:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:985 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:977 msgid "News:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:986 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:978 msgid "Attached is the" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:997 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:989 msgid "Sent news to" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1027 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1089 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1208 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1019 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1081 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1200 msgid "Auto convert the following books before uploading to the device?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1057 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1049 msgid "Sending catalogs to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1121 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1113 msgid "Sending news to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1174 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1166 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1216 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1208 msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1278 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1270 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1279 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1271 msgid "

Cannot upload books to device there is no more free space available " msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:78 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:83 msgid "Select available formats and their order for this device" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:87 msgid "Use sub directories" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:88 msgid "Use author sort for author" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:90 msgid "Save &template:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:43 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:48 msgid "Add books by ISBN" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:44 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:49 msgid "

Enter a list of ISBNs in the box to the left, one per line. calibre will automatically create entries for books based on the ISBN and download metadata and covers for them.

Any invalid ISBNs in the list will be ignored." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:45 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_from_isbn_ui.py:50 msgid "&Paste from clipboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:73 msgid "Fit &cover within view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:74 msgid "&Previous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:75 msgid "&Next" msgstr "" @@ -5022,7 +5164,7 @@ msgstr "" msgid "Catalog options" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:40 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_format_ui.py:45 msgid "Choose Format" msgstr "" @@ -5070,27 +5212,27 @@ msgstr "" msgid "%s is not an existing folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:66 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:71 msgid "Choose your calibre library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:67 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:72 msgid "Your calibre library is currently located at {0}" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:73 msgid "New &Location:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:74 msgid "Use &existing library at the new location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:75 msgid "&Create an empty library at the new location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/choose_library_ui.py:76 msgid "&Move current library to new location" msgstr "" @@ -5102,15 +5244,15 @@ msgstr "" msgid "Set options for converting %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:97 msgid "&Title:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:98 msgid "&Author(s):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:100 msgid "&Profile:" msgstr "" @@ -5118,1081 +5260,11 @@ msgstr "" msgid "Edit Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:173 -msgid "%(plugin_type)s %(plugins)s" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:174 -msgid "plugins" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:183 -msgid "" -"\n" -"Customization: " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:198 -msgid "General" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:200 -msgid "Conversion" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:201 -msgid "" -"Email\n" -"Delivery" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:202 -msgid "Add/Save" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:203 -msgid "Advanced" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:204 -msgid "" -"Content\n" -"Server" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:205 -msgid "Plugins" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:229 -msgid "Auto send" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:229 -msgid "Email" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:234 -msgid "Formats to email. The first matching format will be sent." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:235 -msgid "If checked, downloaded news will be automatically mailed
to this email address (provided it is in one of the listed formats)." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:309 -msgid "new email address" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:492 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:24 -msgid "Wide" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:493 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:24 -msgid "Narrow" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:509 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:50 -msgid "Medium" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:509 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:50 -msgid "Small" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:51 -msgid "Large" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:516 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:54 -msgid "Always" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:516 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:54 -msgid "Automatic" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:55 -msgid "Never" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:530 -msgid "Toolbars/Context menus" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:544 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:156 -msgid "Done" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:545 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:157 -msgid "Confirmation dialogs have all been reset" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:550 -msgid "System port selected" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:551 -msgid "The value %d you have chosen for the content server port is a system port. Your operating system may not allow the server to run on this port. To be safe choose a port number larger than 1024." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:571 -msgid "Failed to install command line tools." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:574 -msgid "Command line tools installed" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:575 -msgid "Command line tools installed in" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:576 -msgid "If you move calibre.app, you have to re-install the command line tools." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:627 -msgid "No valid plugin path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:628 -msgid "%s is not a valid plugin path" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:631 -msgid "Choose plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:643 -msgid "Plugin cannot be disabled" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:644 -msgid "The plugin: %s cannot be disabled" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:653 -msgid "Plugin not customizable" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:654 -msgid "Plugin: %s does not need customization" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:662 -msgid "Customize" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:700 -msgid "Cannot remove builtin plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:701 -msgid " cannot be removed. It is a builtin plugin. Try disabling it instead." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:716 -msgid "Invalid tweaks" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:717 -msgid "The tweaks you entered are invalid, try resetting the tweaks to default and changing them one by one until you find the invalid setting." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:747 -msgid "You must select a column to delete it" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:752 -msgid "The selected column is not a custom column" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:754 -msgid "Do you really want to delete column %s and all its data?" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:821 -msgid "Error log:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:828 -msgid "Access log:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:856 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:319 -msgid "Failed to start content server" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:881 -msgid "Invalid size" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:882 -msgid "The size %s is invalid. must be of the form widthxheight" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:951 -msgid "Must restart" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:952 -msgid "The changes you made require that Calibre be restarted. Please restart as soon as practical." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:986 -msgid "Checking database integrity" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:1006 -msgid "Failed to check database integrity" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:1011 -msgid "Some inconsistencies found" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:1012 -msgid "The following books had formats listed in the database that are not actually available. The entries for the formats have been removed. You should check them manually. This can happen if you manipulate the files in the library folder directly." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:133 -msgid "TabWidget" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:134 -msgid "Here you can control how calibre will read metadata from the files you add to it. calibre can either read metadata from the contents of the file, or from the filename." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:135 -msgid "Read metadata only from &file name" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:136 -msgid "Swap the firstname and lastname of the author. This affects only metadata read from file names." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:137 -msgid "&Swap author firstname and lastname" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:138 -msgid "" -"If an existing book with a similar title and author is found that does not have the format being added, the format is added\n" -"to the existing book, instead of creating a new entry. If the existing book already has the format, then it is silently ignored.\n" -"\n" -"Title match ignores leading indefinite articles (\"the\", \"a\", \"an\"), punctuation, case, etc. Author match is exact." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:142 -msgid "If books with similar titles and authors found, &merge the new files automatically" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:143 -msgid "&Configure metadata from file name" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:144 -msgid "&Adding books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:145 -msgid "Here you can control how calibre will save your books when you click the Save to Disk button:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:146 -msgid "Save &cover separately" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:147 -msgid "Update &metadata in saved copies" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:148 -msgid "Save metadata in &OPF file" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:149 -msgid "Convert non-English characters to &English equivalents" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:150 -msgid "Format &dates as:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:151 -msgid "File &formats to save:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:152 -msgid "Replace space with &underscores" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:153 -msgid "Change paths to &lowercase" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:154 -msgid "&Saving books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:155 -msgid "Metadata &management:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:156 -msgid "Manual management" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:157 -msgid "Only on send" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:158 -msgid "Automatic management" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:159 -msgid "" -"

  • Manual Management: Calibre updates the metadata and adds collections only when a book is sent. With this option, calibre will never remove a collection.
  • \n" -"
  • Only on send: Calibre updates metadata and adds/removes collections for a book only when it is sent to the device.
  • \n" -"
  • Automatic management: Calibre automatically keeps metadata on the device in sync with the calibre library, on every connect
  • " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:162 -msgid "Here you can control how calibre will save your books when you click the Send to Device button. This setting can be overriden for individual devices by customizing the device interface plugins in Preferences->Plugins" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/add_save_ui.py:163 -msgid "Sending to &device" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:613 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:139 -msgid "Show notification when &new version is available" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:614 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:138 -msgid "Download &social metadata (tags/ratings/etc.) by default" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:615 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:137 -msgid "&Overwrite author and title by default when fetching metadata" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:616 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:142 -msgid "Default network &timeout:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:617 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:143 -msgid "Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:618 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:144 -msgid " seconds" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:619 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:100 -msgid "Choose &language (requires restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:620 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:31 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:145 -msgid "Normal" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:621 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:31 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:146 -msgid "High" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:622 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior.py:31 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:147 -msgid "Low" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:623 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:148 -msgid "Job &priority:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:624 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:149 -msgid "Preferred &output format:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:625 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:153 -msgid "Tags to apply when adding a book:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:626 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:152 -msgid "A comma-separated list of tags that will be applied to books added to the library" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:627 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:154 -msgid "Reset all disabled &confirmation dialogs" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:628 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:155 -msgid "Preferred &input format order:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:631 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:98 -msgid "User Interface &layout (needs restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:632 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:99 -msgid "&Number of covers to show in browse mode (needs restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:633 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:150 -msgid "Restriction to apply when the current library is opened:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:634 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:151 -msgid "Apply this restriction on calibre startup if the current library is being used. Also applied when switching to this library. Note that this setting is per library. " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:635 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:102 -msgid "Disable all animations. Useful if you have a slow/old computer." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:636 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:103 -msgid "Disable &animations" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:637 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:110 -msgid "&Toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:638 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:111 -msgid "&Icon size:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:639 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:112 -msgid "Show &text under icons:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:640 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:141 -msgid "&Delete news from library when it is automatically sent to reader" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:641 -msgid "Select visible &columns in library view" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:643 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:79 -msgid "Remove a user-defined column" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:645 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:81 -msgid "Add a user-defined column" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:647 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:83 -msgid "Edit settings of a user-defined column" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:650 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:158 -msgid "Use internal &viewer for:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:651 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:109 -msgid "Search as you type" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:652 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:107 -msgid "Use &Roman numerals for series" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:653 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:104 -msgid "Enable system &tray icon (needs restart)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:654 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:101 -msgid "Show &average ratings in the tags browser" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:655 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/behavior_ui.py:140 -msgid "Automatically send downloaded &news to ebook reader" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:656 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:105 -msgid "Show &splash screen at startup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:657 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:108 -msgid "Show cover &browser in a separate window (needs restart)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:658 -msgid "Show ¬ifications in system tray" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:659 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:671 -msgid "&Miscellaneous" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:660 -msgid "Add an email address to which to send books" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:661 -msgid "&Add email" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:662 -msgid "Make &default" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:663 -msgid "&Remove email" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:664 -msgid "calibre can send your books to you (or your reader) by email. Emails will be automatically sent for downloaded news to all email addresses that have Auto-send checked." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:665 -msgid "&Maximum number of waiting worker processes (needs restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:666 -msgid "Limit the max. simultaneous jobs to the available CPU &cores" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:667 -msgid "Debug &device detection" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:668 -msgid "&Check database integrity" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:669 -msgid "Open calibre &configuration directory" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:670 -msgid "&Install command line tools" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:672 -msgid "Values for the tweaks are shown below. Edit them to change the behavior of calibre" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:673 -msgid "All available tweaks" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:674 -msgid "&Current tweaks" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:675 -msgid "&Restore to defaults" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:676 -msgid "&Tweaks" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:677 -msgid "calibre contains a network server that allows you to access your book collection using a browser from anywhere in the world. Any changes to the settings will only take effect after a server restart." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:678 -msgid "Server &port:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:679 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:212 -#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:117 -msgid "&Username:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:680 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:213 -#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:119 -msgid "&Password:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:681 -msgid "If you leave the password blank, anyone will be able to access your book collection using the web interface." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:682 -msgid "The maximum size (widthxheight) for displayed covers. Larger covers are resized. " -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:683 -msgid "Max. &cover size:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:684 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:60 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:214 -msgid "&Show password" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:685 -msgid "Max. &OPDS items per query:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:686 -msgid "Max. OPDS &ungrouped items:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:687 -msgid "Restriction (saved search) to apply:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:688 -msgid "This restriction (based on a saved search) will restrict the books the content server makes available to those matching the search. This setting is per library (i.e. you can have a different restriction per library)." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:689 -msgid "&Start Server" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:690 -msgid "St&op Server" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:691 -msgid "&Test Server" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:692 -msgid "Run server &automatically on startup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:693 -msgid "View &server logs" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:694 -#: /home/kovid/work/calibre/src/calibre/gui2/wizard/stanza_ui.py:46 -msgid "" -"

    Remember to leave calibre running as the server only runs as long as calibre is running.\n" -"

    Stanza should see your calibre collection automatically. If not, try adding the URL http://myhostname:8080 as a new catalog in the Stanza reader on your iPhone. Here myhostname should be the fully qualified hostname or the IP address of the computer calibre is running on." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:696 -msgid "Here you can customize the behavior of Calibre by controlling what plugins it uses." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:697 -msgid "Enable/&Disable plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:698 -msgid "&Customize plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:699 -msgid "&Remove plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:700 -msgid "Add new plugin" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:701 -msgid "Plugin &file:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/config_ui.py:703 -msgid "&Add" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:125 -msgid "Create Tag-based Column" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:126 -msgid "Lookup name" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:127 -msgid "Column heading" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:128 -msgid "Column type" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:129 -msgid "Use brackets" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:130 -msgid "Values can be edited" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:135 -msgid "Text" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:136 -msgid "Number" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:137 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:31 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:69 -#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:889 -#: /home/kovid/work/calibre/src/calibre/library/server/opds.py:588 -msgid "Date" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:138 -msgid "Tag on book" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:139 -msgid "Explanation text added in create_ct_column.py" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_ct_column_ui.py:140 -msgid "Create and edit tag-based columns" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:19 -msgid "Text, column shown in the tag browser" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:22 -msgid "Comma separated text, like tags, shown in the tag browser" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:25 -msgid "Long text, like comments, not shown in the tag browser" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:28 -msgid "Text column for keeping series-like information" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:33 -msgid "Floating point numbers" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:35 -msgid "Integers" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:37 -msgid "Ratings, shown with stars" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:40 -msgid "Yes/No" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:69 -msgid "No column selected" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:70 -msgid "No column has been selected" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:74 -msgid "Selected column is not a user-defined column" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:105 -msgid "No lookup name was provided" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:107 -msgid "The lookup name must contain only lower case letters, digits and underscores, and start with a letter" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:109 -msgid "Lookup names cannot end with _index, because these names are reserved for the index of a series column." -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:118 -msgid "No column heading was provided" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:124 -msgid "The lookup name %s is already used" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column.py:134 -msgid "The heading %s is already used" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:101 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:117 -msgid "Create or edit custom columns" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:102 -msgid "&Lookup name" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:103 -msgid "Column &heading" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:104 -msgid "Used for searching the column. Must contain only digits and lower case letters." -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:105 -msgid "Column heading in the library view and category name in the tag browser" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:106 -msgid "Column &type" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:107 -msgid "What kind of information will be kept in the column." -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:108 -msgid "" -"

    Date format. Use 1-4 'd's for day, 1-4 'M's for month, and 2 or 4 'y's for year.

    \n" -"

    For example:\n" -"

      \n" -"
    • ddd, d MMM yyyy gives Mon, 5 Jan 2010
    • \n" -"
    • dd MMMM yy gives 05 January 10
    • \n" -"
    " -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:114 -msgid "Use MMM yyyy for month + year, yyyy for year only" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:115 -msgid "Default: dd MMM yyyy." -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/create_custom_column_ui.py:116 -msgid "Format for &dates" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/device_debug.py:21 -msgid "Getting debug information" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/device_debug.py:22 -msgid "Copy to &clipboard" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/device_debug.py:24 -msgid "Debug device detection" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template.py:44 -msgid "Invalid template" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template.py:45 -msgid "The template %s is invalid:" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template_ui.py:42 -msgid "Save &template" -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template_ui.py:43 -msgid "By adjusting the template below, you can control what folders the files are saved in and what filenames they are given. You can use the / character to indicate sub-folders. Available metadata variables are described below. If a particular book does not have some metadata, the variable will be replaced by the empty string." -msgstr "" - -#: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/save_template_ui.py:44 -msgid "Available variables:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/social.py:34 -msgid "Downloading social metadata, please wait..." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:35 -msgid "Switch between library and device views" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:38 -msgid "Separator" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:51 -msgid "Choose library" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:201 -msgid "The main toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:202 -msgid "The main toolbar when a device is connected" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:203 -msgid "The context menu for the books in the calibre library" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:205 -msgid "The context menu for the books on the device" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:243 -msgid "Cannot add" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:244 -msgid "Cannot add the actions %s to this location" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:261 -msgid "Cannot remove" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar.py:262 -msgid "Cannot remove the actions %s from this location" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:97 -msgid "Customize the actions in:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:98 -msgid "A&vailable actions" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:99 -msgid "&Current actions" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:100 -msgid "Move selected action up" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:102 -msgid "Move selected action down" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:104 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:78 -msgid "Ctrl+S" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:105 -msgid "Add selected actions to toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:107 -msgid "Remove selected actions from toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/toolbar_ui.py:109 -msgid "Restore to &default" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:55 msgid "&Show this warning again" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/conversion_error_ui.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/conversion_error_ui.py:47 msgid "ERROR" msgstr "" @@ -6206,6 +5278,15 @@ msgstr "" msgid "Location" msgstr "" +#: +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:69 +#: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:889 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/create_custom_column.py:31 +#: /home/kovid/work/calibre/src/calibre/library/server/opds.py:588 +msgid "Date" +msgstr "" + #: #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1064 @@ -6282,55 +5363,55 @@ msgstr "" msgid "No metadata found, try adjusting the title and author or the ISBN key." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:90 msgid "Fetch metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:91 msgid "

    calibre can find metadata for your books from two locations: Google Books and isbndb.com.

    To use isbndb.com you must sign up for a free account and enter your access key below." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:92 msgid "&Access Key:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:93 msgid "Fetch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:94 msgid "Matches" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:95 msgid "Select the book that most closely matches your copy from the list below" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:96 msgid "Download &social metadata (tags/rating/etc.) for the selected book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:97 msgid "Overwrite author and title with author and title of selected book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:42 msgid "Details of job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:44 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:49 msgid "Active Jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:45 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:50 msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:46 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:51 msgid "Show job &details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:47 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:52 msgid "Stop &all non device jobs" msgstr "" @@ -6342,80 +5423,80 @@ msgstr "" msgid "Applying changes to %d books. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:165 msgid "Edit Meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:167 msgid "A&utomatically set author sort" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:168 msgid "Author s&ort: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:164 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:367 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:372 msgid "Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:165 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:370 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:375 msgid "&Rating:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:166 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:167 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:371 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:372 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:376 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:377 msgid "Rating of this book. 0-5 stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:173 msgid "No change" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:169 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:378 msgid " stars" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:176 msgid "Add ta&gs: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:173 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:174 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:377 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:378 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:382 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:383 msgid "Open Tag Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:180 msgid "&Remove tags:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:181 msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:182 msgid "Remove all" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:183 msgid "Check this box to remove all tags from the books." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:187 msgid "Remove &format:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:183 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:188 msgid "&Swap title and author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:189 msgid "" "Selected books will be automatically numbered,\n" "in the order you selected them.\n" @@ -6423,24 +5504,24 @@ msgid "" "Book A will have series number 1 and Book B series number 2." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:189 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:194 msgid "" "Remove stored conversion settings for the selected books.\n" "\n" "Future conversion of these books will use the default settings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:197 msgid "Remove &stored conversion settings for the selected books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:193 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:408 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:198 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:413 msgid "&Basic metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:194 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:414 msgid "&Custom metadata" msgstr "" @@ -6580,98 +5661,118 @@ msgstr "" msgid "Could not open %s. Is it being used by another program?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:364 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:360 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:365 msgid "Meta information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:368 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:371 msgid "Author S&ort: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:368 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:373 msgid "Automatically create the author sort entry based on the current author entry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:382 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:387 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:384 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:389 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:390 msgid "Publishe&d:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:388 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:393 msgid "dd MMM yyyy" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:389 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:394 msgid "&Date:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:390 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:395 msgid "&Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:391 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:396 msgid "&Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:397 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:393 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:398 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:395 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:400 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:397 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:402 msgid "Set the cover for the book from the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:404 msgid "Update metadata from the metadata in the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:402 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:407 msgid "&Browse" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:403 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:408 msgid "Reset cover to default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:405 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:410 msgid "Download &cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:411 msgid "Generate a default cover based on the title and author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:407 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:412 msgid "&Generate cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:61 msgid "Password needed" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:117 +msgid "&Username:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:119 +msgid "&Password:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:65 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:130 +msgid "&Show password" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress.py:59 msgid "Aborting..." msgstr "" @@ -6685,37 +5786,37 @@ msgid "The current saved search will be permanently deleted. Are you sure msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:88 msgid "Saved Search Editor" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:89 msgid "Saved Search: " msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:90 msgid "Select a saved search to edit" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:91 msgid "Delete this selected saved search" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:93 msgid "Enter a new saved search name." msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:94 msgid "Add the new saved search" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor_ui.py:96 msgid "Change the contents of the saved search" msgstr "" @@ -6744,7 +5845,7 @@ msgid "Last downloaded" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:220 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:197 msgid "Schedule news download" msgstr "" @@ -6764,111 +5865,111 @@ msgstr "" msgid "Cannot download news as no internet connection is active" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:198 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:278 msgid "Recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:199 msgid "Download all scheduled recipes at once" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:200 msgid "Download &all scheduled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:196 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:201 msgid "blurb" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:202 msgid "&Schedule for download:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:198 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:208 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:203 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:213 msgid "Every " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:204 msgid "day" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:200 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:205 msgid "Monday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:201 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:206 msgid "Tuesday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:202 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:207 msgid "Wednesday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:203 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:208 msgid "Thursday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:209 msgid "Friday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:205 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:210 msgid "Saturday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:211 msgid "Sunday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:212 msgid "at" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:209 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:214 msgid "Interval at which to download this recipe. A value of zero means that the recipe will be downloaded every hour." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:210 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:222 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:268 msgid " days" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:216 msgid "&Account" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:220 msgid "For the scheduling to work, you must leave calibre running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:216 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:221 msgid "&Schedule" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:222 msgid "Add &title as tag" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:223 msgid "&Extra tags:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:224 msgid "&Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:220 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:225 msgid "&Download now" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:226 msgid "Delete downloaded news older than the specified number of days. Set to zero to disable." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:228 msgid "Delete downloaded news older than " msgstr "" @@ -6888,55 +5989,55 @@ msgstr "" msgid "Negate" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:113 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:118 msgid "Advanced Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:119 msgid "Find entries that have..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:120 msgid "&All these words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:121 msgid "This exact &phrase:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:122 msgid "&One or more of these words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:123 msgid "But dont show entries that have..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:124 msgid "Any of these &unwanted words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:125 msgid "What kind of match to use:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:126 msgid "Contains: the word or phrase matches anywhere in the metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:127 msgid "Equals: the word or phrase must match an entire metadata field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:128 msgid "Regular expression: the expression must match anywhere in the metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:129 msgid " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:130 msgid "See the User Manual for more help" msgstr "" @@ -6962,51 +6063,51 @@ msgstr "" msgid "The current tag category will be permanently deleted. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:158 msgid "User Categories Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:159 msgid "A&vailable items" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:160 msgid "Apply tags to current tag category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:162 msgid "A&pplied items" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:163 msgid "Unapply (remove) tag from current tag category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:160 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:165 msgid "Category name: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:166 msgid "Select a category to edit" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:167 msgid "Delete this selected tag category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:169 msgid "Enter a new category name. Select the kind before adding it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:165 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:170 msgid "Add the new category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:167 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:172 msgid "Category filter: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_categories_ui.py:173 msgid "Select the content kind of the new category" msgstr "" @@ -7019,39 +6120,39 @@ msgstr "" msgid "The following tags are used by one or more books. Are you certain you want to delete them?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 msgid "Tag Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:129 msgid "A&vailable tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:130 msgid "Delete tag from database. This will unapply the tag from all books and then remove it from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:132 msgid "Apply tag to current book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:134 msgid "A&pplied tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:135 msgid "Unapply (remove) tag from current book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:137 msgid "&Add tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:138 msgid "If the tag you want is not in the available list, you can add it here. Accepts a comma separated list of tags." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:139 msgid "Add tag to available tags and apply it to current book" msgstr "" @@ -7089,31 +6190,36 @@ msgstr "" msgid "Are you certain you want to delete the following items?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:77 msgid "Category Editor" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:73 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:78 msgid "Items in use" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:79 msgid "Delete item from database. This will unapply the item from all books and then remove it from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:81 msgid "Rename the item in every book where it is used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:51 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:106 +msgid "Ctrl+S" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:56 msgid "Test email settings" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:52 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:57 msgid "Send test mail from %s to:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/test_email_ui.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 msgid "&Test" msgstr "" @@ -7132,7 +6238,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:150 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:161 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:255 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:260 msgid "Switch to Advanced mode" msgstr "" @@ -7197,35 +6303,35 @@ msgstr "" msgid "Choose a recipe file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:253 msgid "Add custom news source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:254 msgid "Available user recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:250 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:255 msgid "Add/Update &recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:251 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:256 msgid "&Remove recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:252 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:257 msgid "&Share recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:253 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:258 msgid "Customize &builtin recipe" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:254 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:259 msgid "&Load recipe from file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:261 msgid "" "