diff --git a/src/calibre/gui2/dialogs/choose_library.py b/src/calibre/gui2/dialogs/choose_library.py new file mode 100644 index 0000000000..d656a93b6d --- /dev/null +++ b/src/calibre/gui2/dialogs/choose_library.py @@ -0,0 +1,82 @@ +#!/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 os + +from PyQt4.Qt import QDialog + +from calibre.gui2.dialogs.choose_library_ui import Ui_Dialog +from calibre.gui2 import error_dialog, choose_dir +from calibre.constants import filesystem_encoding +from calibre import isbytestring, patheq +from calibre.utils.config import prefs +from calibre.gui2.wizard import move_library + +class ChooseLibrary(QDialog, Ui_Dialog): + + def __init__(self, db, callback, parent): + QDialog.__init__(self, parent) + self.setupUi(self) + self.db = db + self.new_db = None + self.callback = callback + + lp = db.library_path + if isbytestring(lp): + lp = lp.decode(filesystem_encoding) + loc = unicode(self.old_location.text()).format(lp) + self.old_location.setText(loc) + self.browse_button.clicked.connect(self.choose_loc) + + def choose_loc(self, *args): + loc = choose_dir(self, 'choose library location', + _('Choose location for calibre library')) + if loc is not None: + self.location.setText(loc) + + def check_action(self, ac, loc): + exists = self.db.exists_at(loc) + if patheq(loc, self.db.library_path): + error_dialog(self, _('Same as current'), + _('The location %s contains the current calibre' + ' library')%loc, show=True) + return False + empty = not os.listdir(loc) + if ac == 'existing' and not exists: + error_dialog(self, _('No existing library found'), + _('There is no existing calibre library at %s')%loc, + show=True) + return False + if ac in ('new', 'move') and not empty: + error_dialog(self, _('Not empty'), + _('The folder %s is not empty. Please choose an empty' + ' folder')%loc, + show=True) + return False + + return True + + def perform_action(self, ac, loc): + if ac in ('new', 'existing'): + prefs['library_path'] = loc + self.callback(loc) + else: + move_library(self.db.library_path, loc, self.parent(), + self.callback) + + def accept(self): + action = 'move' + if self.existing_library.isChecked(): + action = 'existing' + elif self.empty_library.isChecked(): + action = 'new' + loc = os.path.abspath(unicode(self.location.text()).strip()) + if not loc or not os.path.exists(loc) or not self.check_action(action, + loc): + return + QDialog.accept(self) + self.perform_action(action, loc) diff --git a/src/calibre/gui2/dialogs/choose_library.ui b/src/calibre/gui2/dialogs/choose_library.ui new file mode 100644 index 0000000000..793c805eda --- /dev/null +++ b/src/calibre/gui2/dialogs/choose_library.ui @@ -0,0 +1,171 @@ + + + Dialog + + + + 0 + 0 + 602 + 245 + + + + Choose your calibre library + + + + :/images/lt.png:/images/lt.png + + + + + + Your calibre library is currently located at {0} + + + true + + + + + + + New &Location: + + + location + + + + + + + true + + + + + + + Use &existing library at the new location + + + true + + + + + + + &Create an empty library at the new location + + + + + + + &Move current library to new location + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + :/images/document_open.svg:/images/document_open.svg + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/calibre/gui2/dialogs/config/__init__.py b/src/calibre/gui2/dialogs/config/__init__.py index b064dc53c2..84d55c8fb6 100644 --- a/src/calibre/gui2/dialogs/config/__init__.py +++ b/src/calibre/gui2/dialogs/config/__init__.py @@ -14,7 +14,7 @@ from PyQt4.Qt import QDialog, QListWidgetItem, QIcon, \ 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 import choose_dir, error_dialog, config, gprefs, \ +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 @@ -343,9 +343,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog): self.model = library_view.model() self.db = self.model.db self.server = server - path = prefs['library_path'] - self.location.setText(path if path else '') - self.connect(self.browse_button, SIGNAL('clicked(bool)'), self.browse) self.connect(self.compact_button, SIGNAL('clicked(bool)'), self.compact) input_map = prefs['input_format_order'] @@ -808,12 +805,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog): d = CheckIntegrity(self.db, self) d.exec_() - def browse(self): - dir = choose_dir(self, 'database location dialog', - _('Select location for books')) - if dir: - self.location.setText(dir) - def accept(self): mcs = unicode(self.max_cover_size.text()).strip() if not re.match(r'\d+x\d+', mcs): @@ -834,7 +825,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog): 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()) - path = unicode(self.location.text()) 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 @@ -875,24 +865,13 @@ class ConfigDialog(ResizableDialog, Ui_Dialog): val = self.opt_gui_layout.itemData(self.opt_gui_layout.currentIndex()).toString() config['gui_layout'] = unicode(val) - if not path or not os.path.exists(path) or not os.path.isdir(path): - d = error_dialog(self, _('Invalid database location'), - _('Invalid database location ')+path+ - _('
Must be a directory.')) - d.exec_() - elif not os.access(path, os.W_OK): - d = error_dialog(self, _('Invalid database location'), - _('Invalid database location.
Cannot write to ')+path) - d.exec_() - else: - self.database_location = os.path.abspath(path) - 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) + 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): diff --git a/src/calibre/gui2/dialogs/config/config.ui b/src/calibre/gui2/dialogs/config/config.ui index 5f890631b2..5d6bff2467 100644 --- a/src/calibre/gui2/dialogs/config/config.ui +++ b/src/calibre/gui2/dialogs/config/config.ui @@ -113,50 +113,6 @@ - - - - - - - 16777215 - 70 - - - - &Location of ebooks (The ebooks are stored in folders sorted by author and metadata is stored in the file metadata.db) - - - true - - - location - - - - - - - - - - - - Browse for the new database location - - - ... - - - - :/images/mimetypes/dir.svg:/images/mimetypes/dir.svg - - - - - - - diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index d4d2f86ef7..3116037685 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -329,6 +329,7 @@ class MainWindowMixin(object): self.tool_bar = ToolBar(all_actions, self.donate_button, self.location_manager, self) self.addToolBar(Qt.TopToolBarArea, self.tool_bar) + self.tool_bar.choose_action.triggered.connect(self.choose_library) l = self.centralwidget.layout() l.addWidget(self.search_bar) @@ -337,6 +338,12 @@ class MainWindowMixin(object): def read_toolbar_settings(self): pass + def choose_library(self, *args): + from calibre.gui2.dialogs.choose_library import ChooseLibrary + db = self.library_view.model().db + c = ChooseLibrary(db, self.library_moved, self) + c.exec_() + def setup_actions(self): # {{{ all_actions = [] diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index be669d4aca..eec03876e9 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -18,7 +18,7 @@ from PyQt4.Qt import Qt, SIGNAL, QTimer, \ QSystemTrayIcon, QApplication, QKeySequence, QAction, \ QMessageBox, QHelpEvent -from calibre import prints, patheq +from calibre import prints from calibre.constants import __appname__, isosx from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.config import prefs, dynamic @@ -27,7 +27,6 @@ from calibre.gui2 import error_dialog, GetMetadata, open_local_file, \ gprefs, max_available_height, config, info_dialog from calibre.gui2.cover_flow import CoverFlowMixin from calibre.gui2.widgets import ProgressIndicator -from calibre.gui2.wizard import move_library from calibre.gui2.dialogs.scheduler import Scheduler from calibre.gui2.update import UpdateMixin from calibre.gui2.main_window import MainWindow @@ -389,10 +388,6 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{ self.tags_view.recount() self.create_device_menu() self.set_device_menu_items_state(bool(self.device_connected)) - if not patheq(self.library_path, d.database_location): - newloc = d.database_location - move_library(self.library_path, newloc, self, - self.library_moved) def library_moved(self, newloc): if newloc is None: return diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 1534d3ffbf..85e951d4b0 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -116,6 +116,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): # missing functions self.books_list_filter = self.conn.create_dynamic_filter('books_list_filter') + @classmethod + def exists_at(cls, path): + return path and os.path.exists(os.path.join(path, 'metadata.db')) + def __init__(self, library_path, row_factory=False): self.field_metadata = FieldMetadata() if not os.path.exists(library_path):