Added code to allow user to change the location of the OpenLP data directory

This commit is contained in:
Stevan Pettit 2012-01-19 15:25:53 -05:00
parent 1862c7175b
commit ce230df91d
4 changed files with 318 additions and 6 deletions

View File

@ -29,9 +29,11 @@ The :mod:`advancedtab` provides an advanced settings facility.
""" """
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import os
import sys
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
from openlp.core.utils import get_images_filter from openlp.core.utils import get_images_filter, AppLocation
class AdvancedTab(SettingsTab): class AdvancedTab(SettingsTab):
""" """
@ -84,6 +86,53 @@ class AdvancedTab(SettingsTab):
u'enableAutoCloseCheckBox') u'enableAutoCloseCheckBox')
self.uiLayout.addRow(self.enableAutoCloseCheckBox) self.uiLayout.addRow(self.enableAutoCloseCheckBox)
self.leftLayout.addWidget(self.uiGroupBox) self.leftLayout.addWidget(self.uiGroupBox)
self.dataDirectoryGroupBox = QtGui.QGroupBox(self.leftColumn)
self.dataDirectoryGroupBox.setObjectName(u'dataDirectoryGroupBox')
self.dataDirectoryLabel= QtGui.QLabel(self.dataDirectoryGroupBox)
self.dataDirectoryLabel.setObjectName(u'dataDirectoryLabel')
self.newDataDirectoryEdit = QtGui.QLineEdit(self.dataDirectoryGroupBox)
self.newDataDirectoryEdit.setObjectName(u'newDataDirectoryEdit')
self.newDataDirectoryEdit.setReadOnly(True)
self.newDataDirectoryHasFilesLabel= QtGui.QLabel(self.dataDirectoryGroupBox)
self.newDataDirectoryHasFilesLabel.setObjectName(
u'newDataDirectoryHasFilesLabel')
self.newDataDirectoryHasFilesLabel.setWordWrap(True)
self.dataDirectoryBrowseButton = QtGui.QPushButton(
self.dataDirectoryGroupBox)
self.dataDirectoryBrowseButton.setObjectName(
u'dataDirectoryBrowseButton')
self.dataDirectoryBrowseButton.setIcon(
build_icon(u':/general/general_open.png'))
self.dataDirectoryDefaultButton = QtGui.QPushButton(
self.dataDirectoryGroupBox)
self.dataDirectoryDefaultButton.setObjectName(
u'dataDirectoryBrowseButton')
self.dataDirectoryDefaultButton.setIcon(
build_icon(u':/general/general_revert.png'))
self.dataDirectoryCancelButton = QtGui.QPushButton(
self.dataDirectoryGroupBox)
self.dataDirectoryCancelButton.setObjectName(
u'dataDirectoryCancelButton')
self.dataDirectoryCancelButton.setIcon(
build_icon(u':/general/general_revert.png'))
self.dataDirectoryCopyCheckBox = QtGui.QCheckBox(
self.dataDirectoryGroupBox)
self.dataDirectoryCopyCheckBox.setObjectName(
u'dataDirectoryCopyCheckBox')
self.dataDirectoryCopyCheckBox.hide()
self.newDataDirectoryHasFilesLabel.hide()
self.dataDirectoryDefaultButton.hide()
self.dataDirectoryCancelButton.hide()
self.dataDirectoryLayout =QtGui.QFormLayout(self.dataDirectoryGroupBox)
self.dataDirectoryLayout.setObjectName(u'dataDirectoryLayout')
self.dataDirectoryLayout.addWidget(self.dataDirectoryLabel)
self.dataDirectoryLayout.addWidget(self.dataDirectoryBrowseButton)
self.dataDirectoryLayout.addWidget(self.newDataDirectoryEdit)
self.dataDirectoryLayout.addWidget(self.dataDirectoryCopyCheckBox)
self.dataDirectoryLayout.addWidget(self.newDataDirectoryHasFilesLabel)
self.dataDirectoryLayout.addWidget(self.dataDirectoryDefaultButton)
self.dataDirectoryLayout.addWidget(self.dataDirectoryCancelButton)
self.leftLayout.addWidget(self.dataDirectoryGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn) self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox') self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
@ -141,6 +190,15 @@ class AdvancedTab(SettingsTab):
QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed)
QtCore.QObject.connect(self.x11BypassCheckBox, QtCore.QObject.connect(self.x11BypassCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onX11BypassCheckBoxToggled) QtCore.SIGNAL(u'toggled(bool)'), self.onX11BypassCheckBoxToggled)
QtCore.QObject.connect(self.dataDirectoryBrowseButton,
QtCore.SIGNAL(u'pressed()'),
self.onDataDirectoryBrowseButtonPressed)
QtCore.QObject.connect(self.dataDirectoryDefaultButton,
QtCore.SIGNAL(u'pressed()'),
self.onDataDirectoryDefaultButtonPressed)
QtCore.QObject.connect(self.dataDirectoryCancelButton,
QtCore.SIGNAL(u'pressed()'),
self.onDataDirectoryCancelButtonPressed)
def retranslateUi(self): def retranslateUi(self):
""" """
@ -149,6 +207,8 @@ class AdvancedTab(SettingsTab):
self.tabTitleVisible = UiStrings().Advanced self.tabTitleVisible = UiStrings().Advanced
self.uiGroupBox.setTitle( self.uiGroupBox.setTitle(
translate('OpenLP.AdvancedTab', 'UI Settings')) translate('OpenLP.AdvancedTab', 'UI Settings'))
self.dataDirectoryGroupBox.setTitle(
translate('OpenLP.AdvancedTab', 'Data Location'))
self.recentLabel.setText( self.recentLabel.setText(
translate('OpenLP.AdvancedTab', translate('OpenLP.AdvancedTab',
'Number of recent files to display:')) 'Number of recent files to display:'))
@ -178,6 +238,33 @@ class AdvancedTab(SettingsTab):
'Browse for an image file to display.')) 'Browse for an image file to display.'))
self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab', self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
'Revert to the default OpenLP logo.')) 'Revert to the default OpenLP logo.'))
self.dataDirectoryBrowseButton.setText(translate('OpenLP.AdvancedTab',
'Select new location.'))
self.dataDirectoryBrowseButton.setToolTip(
translate('OpenLP.AdvancedTab',
'Browse for new data file location.'))
self.dataDirectoryDefaultButton.setText(
translate('OpenLP.AdvancedTab',
'Set to default location.'))
self.dataDirectoryDefaultButton.setToolTip(
translate('OpenLP.AdvancedTab',
'Set the data location to the default.'))
self.dataDirectoryCancelButton.setText(
translate('OpenLP.AdvancedTab',
'Cancel data directory change'))
self.dataDirectoryCancelButton.setToolTip(
translate('OpenLP.AdvancedTab',
'Cancel OpenLP data directory location change.'))
self.dataDirectoryCopyCheckBox.setText(
translate('OpenLP.AdvancedTab',
'Copy data to new location.'))
self.dataDirectoryCopyCheckBox.setToolTip(
translate('OpenLP.AdvancedTab',
'Copy the OpenLP data files to the new location.'))
self.newDataDirectoryHasFilesLabel.setText(
translate('OpenLP.AdvancedTab',
'Warning - New data directory location contains OpenLP '
'data files. These files WILL be replaced during a copy.'))
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab', self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab',
'X11')) 'X11'))
self.x11BypassCheckBox.setText(translate('OpenLP.AdvancedTab', self.x11BypassCheckBox.setText(translate('OpenLP.AdvancedTab',
@ -221,6 +308,35 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\ QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
.toString()) .toString())
settings.endGroup() settings.endGroup()
# Since data location can be changed, make sure the path is present.
data_path = AppLocation.get_data_path()
if not os.path.exists(data_path):
answer = QtGui.QMessageBox.critical(self,
translate('OpenLP.AdvancedTab',
'Data directory error - Reset to default?'),
translate('OpenLP.AdvancedTab',
'OpenLP data directory was not found \n\n %s \n\n'
'This data directory was previously changed from the OpenLP '
'default location. If the new location was on removable '
'media, that media needs to be made available.\n\n'
'Click "No" to stop loading OpenLP. allowing you to fix '
'the the problem.\n\n'
'Click "Yes" to reset the data directory location to the '
'default' % data_path),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
Receiver.send_message(u'cleanup')
sys.exit()
data_path = AppLocation.set_default_data_path()
print AppLocation.IsDefaultDataPath
if AppLocation.IsDefaultDataPath:
self.dataDirectoryDefaultButton.hide()
else:
self.dataDirectoryDefaultButton.show()
self.dataDirectoryLabel.setText(data_path)
self.defaultColorButton.setStyleSheet( self.defaultColorButton.setStyleSheet(
u'background-color: %s' % self.default_color) u'background-color: %s' % self.default_color)
@ -248,6 +364,10 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(self.x11BypassCheckBox.isChecked())) QtCore.QVariant(self.x11BypassCheckBox.isChecked()))
settings.setValue(u'default color', self.default_color) settings.setValue(u'default color', self.default_color)
settings.setValue(u'default image', self.defaultFileEdit.text()) settings.setValue(u'default image', self.defaultFileEdit.text())
if not AppLocation.IsDefaultDataPath:
settings.setValue(u'data path', self.dataDirectoryLabel.text())
settings.setValue(u'copy data',
QtCore.QVariant(self.dataDirectoryCopyCheckBox.isChecked()))
settings.endGroup() settings.endGroup()
if self.display_changed: if self.display_changed:
Receiver.send_message(u'config_screen_changed') Receiver.send_message(u'config_screen_changed')
@ -271,6 +391,124 @@ class AdvancedTab(SettingsTab):
self.defaultFileEdit.setText(filename) self.defaultFileEdit.setText(filename)
self.defaultFileEdit.setFocus() self.defaultFileEdit.setFocus()
def onDataDirectoryBrowseButtonPressed(self):
"""
Browse for a new data directory location.
"""
old_data_path = str(self.dataDirectoryLabel.text())
old_root_path = os.path.abspath(os.path.join(
old_data_path, u'..', u'..'))
# Get the new directory location.
new_path = unicode(QtGui.QFileDialog.getExistingDirectory(self,
translate('OpenLP.AdvancedTab',
'Select Data Folder Root Directory'), old_root_path,
options=QtGui.QFileDialog.ShowDirsOnly))
# Set the new data path
settings = QtCore.QSettings()
new_data_path = os.path.join(new_path, 'OpenLP', 'Data')
if new_path:
if old_data_path.lower() == new_data_path.lower():
self.onDataDirectoryCancelButtonPressed()
return
else:
return
# Make sure they want to change the data.
answer = QtGui.QMessageBox.question(self,
translate('OpenLP.AdvancedTab', 'Change data directory?'),
translate('OpenLP.AdvancedTab',
'Are you sure you want to change the location of the OpenLP data\n'
'directory to:\n\n %s \n\n'
'This is the root folder for the data. The data will be stored '
'in:\n\n %s \n\n '
'The data directory will be changed when OpenLP is closed.'
% (new_path, new_data_path)),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer != QtGui.QMessageBox.Yes:
return
# Check if data already exists here
self.checkDataOverwrite(new_data_path)
# Save the new location.
settings.setValue(u'%s/new data path' % self.settingsSection,
new_data_path)
self.newDataDirectoryEdit.setText(new_data_path)
self.dataDirectoryCancelButton.show()
def onDataDirectoryDefaultButtonPressed(self):
"""
Re-set the data directory location to the 'default' location.
"""
# Make sure they want to change the data location back to the default.
answer = QtGui.QMessageBox.question(self,
translate('OpenLP.AdvancedTab', 'Reset data directory to default?'),
translate('OpenLP.AdvancedTab',
'Are you sure you want to change the location of the OpenLP data\n'
'directory to the default locatiom? \n\n'
'This location will be used after OpenLP is closed.'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer != QtGui.QMessageBox.Yes:
return
old_data_path = str(self.dataDirectoryLabel.text())
new_data_path = AppLocation.get_directory(AppLocation.DataDir)
if old_data_path.lower() == new_data_path.lower():
self.onDataDirectoryCancelButtonPressed()
return
self.checkDataOverwrite(new_data_path)
# Save the new location.
settings = QtCore.QSettings()
settings.setValue(u'%s/new data path' % self.settingsSection,
new_data_path)
self.newDataDirectoryEdit.setText(new_data_path)
self.dataDirectoryCancelButton.show()
def checkDataOverwrite(self, data_path ):
test_path = os.path.join(data_path, u'songs')
self.dataDirectoryCopyCheckBox.show()
if os.path.exists(test_path):
# Check is they want to replace existing data
answer = QtGui.QMessageBox.warning(self,
translate('OpenLP.AdvancedTab', 'Replace existing data?'),
translate('OpenLP.AdvancedTab',
'WARNING \n\n'
'The location you have selected \n\n %s \n\n'
'appears to contain OpenLP data files. Do you wish to replace '
'these files with the current data files?' % data_path),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.Yes:
self.dataDirectoryCopyCheckBox.setChecked(True)
else:
self.dataDirectoryCopyCheckBox.setChecked(False)
self.newDataDirectoryHasFilesLabel.show()
else:
self.dataDirectoryCopyCheckBox.setChecked(True)
self.newDataDirectoryHasFilesLabel.hide()
def onDataDirectoryCancelButtonPressed(self):
"""
Cancel the data directory location change
"""
self.newDataDirectoryEdit.setText(u'')
self.dataDirectoryCopyCheckBox.setChecked(False)
settings = QtCore.QSettings()
settings.remove(u'%s/new data path' % self.settingsSection)
settings.remove(u'%s/copy data' % self.settingsSection)
self.dataDirectoryCopyCheckBox.hide()
self.dataDirectoryCancelButton.hide()
self.newDataDirectoryHasFilesLabel.hide()
print AppLocation.IsDefaultDataPath
if AppLocation.IsDefaultDataPath:
self.dataDirectoryDefaultButton.hide()
else:
self.dataDirectoryDefaultButton.show()
def onDefaultRevertButtonPressed(self): def onDefaultRevertButtonPressed(self):
self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png') self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
self.defaultFileEdit.setFocus() self.defaultFileEdit.setFocus()

View File

@ -29,13 +29,16 @@ import logging
import os import os
import sys import sys
import shutil import shutil
from distutils import dir_util
from distutils.errors import DistutilsFileError
from tempfile import gettempdir from tempfile import gettempdir
from datetime import datetime from datetime import datetime
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \ from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
PluginManager, Receiver, translate, ImageManager, PluginStatus PluginManager, Receiver, translate, ImageManager, PluginStatus, \
SettingsManager
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \ from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
icon_action, shortcut_action icon_action, shortcut_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
@ -629,6 +632,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged) QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'mainwindow_status_text'), self.showStatusMessage) QtCore.SIGNAL(u'mainwindow_status_text'), self.showStatusMessage)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'cleanup'), self.cleanUp)
# Media Manager # Media Manager
QtCore.QObject.connect(self.mediaToolBox, QtCore.QObject.connect(self.mediaToolBox,
QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged) QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged)
@ -1181,6 +1186,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.pluginManager.finalise_plugins() self.pluginManager.finalise_plugins()
# Save settings # Save settings
self.saveSettings() self.saveSettings()
# Check if we need to change the data directory
if QtCore.QSettings().value(u'advanced/new data path',
QtCore.QVariant(u'none')).toString() != u'none':
self.changeDataDirectory()
# Close down the display # Close down the display
self.liveController.display.close() self.liveController.display.close()
@ -1445,3 +1454,48 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.timer_id = 0 self.timer_id = 0
self.loadProgressBar.hide() self.loadProgressBar.hide()
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def changeDataDirectory(self):
old_data_path = str(AppLocation.get_data_path())
settings = QtCore.QSettings()
new_data_path = str(settings.value(u'advanced/new data path',
QtCore.QVariant(u'none')).toString())
settings.remove(u'advanced/new data path')
# Copy OpenLP data to new location if requested.
if settings.value(u'advanced/copy data',
QtCore.QVariant(u'none')).toBool():
try:
Receiver.send_message(u'openlp_process_events')
QtGui.QMessageBox.information(self,
translate('OpenLP.MainWindow', 'Copy Data Directory'),
translate('OpenLP.MainWindow',
'OpenLP will now copy your data files from \n\n %s \n\n'
'to \n\n %s' % (old_data_path, new_data_path)),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok))
Receiver.send_message(u'cursor_busy')
dir_util.copy_tree(old_data_path, new_data_path)
except (IOError, os.error, DistutilsFileError), why:
Receiver.send_message(u'cursor_normal')
QtGui.QMessageBox.critical(self,
translate('OpenLP.MainWindow', 'New data directory error'),
translate('OpenLP.MainWindow',
'OpenLP Data directory copy failed \n\n %s' % str(why)),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok))
return False
settings.remove(u'advanced/copy data')
Receiver.send_message(u'cursor_normal')
# Change the location of data directory in config file.
settings.setValue(u'advanced/data path', new_data_path)
QtGui.QMessageBox.information(self,
translate('OpenLP.MainWindow', 'New data directory'),
translate('OpenLP.MainWindow',
'OpenLP Data directory successfully changed to:\n\n %s \n\n'
'The new data directory location will be used '
'the next time you start OpenLP.' % new_data_path),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok))
# Check if the new data path is our default.
if new_data_path == AppLocation.get_directory(AppLocation.DataDir):
settings.remove(u'advanced/data path')

View File

@ -29,7 +29,7 @@ The :mod:`settingsform` provides a user interface for the OpenLP settings
""" """
import logging import logging
from PyQt4 import QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, build_icon, PluginStatus from openlp.core.lib import Receiver, build_icon, PluginStatus
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
@ -102,6 +102,8 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
""" """
Process the form saving the settings Process the form saving the settings
""" """
# Dialog was cancelled, remove any pending data move
QtCore.QSettings().remove(u'advanced/new data path')
for tabIndex in range(0, self.stackedLayout.count()): for tabIndex in range(0, self.stackedLayout.count()):
self.stackedLayout.widget(tabIndex).cancel() self.stackedLayout.widget(tabIndex).cancel()
return QtGui.QDialog.reject(self) return QtGui.QDialog.reject(self)

View File

@ -126,6 +126,7 @@ class AppLocation(object):
VersionDir = 5 VersionDir = 5
CacheDir = 6 CacheDir = 6
LanguageDir = 7 LanguageDir = 7
IsDefaultDataPath = True
# Base path where data/config/cache dir is located # Base path where data/config/cache dir is located
BaseDir = None BaseDir = None
@ -165,10 +166,27 @@ class AppLocation(object):
""" """
Return the path OpenLP stores all its data under. Return the path OpenLP stores all its data under.
""" """
path = AppLocation.get_directory(AppLocation.DataDir) # Check if we have a different data location.
check_directory_exists(path) path = unicode(QtCore.QSettings().value(
u'advanced/data path', QtCore.QVariant(u'none')).toString())
if path == u'none':
AppLocation.IsDefaultDataPath = True
path = AppLocation.get_directory(AppLocation.DataDir)
check_directory_exists(path)
else:
AppLocation.IsDefaultDataPath = False
return path return path
@staticmethod
def set_default_data_path():
"""
Reset to default and return the path OpenLP stores all its data under.
"""
# Remove override location.
QtCore.QSettings().remove(u'advanced/data path')
data_path = AppLocation.get_data_path()
return data_path
@staticmethod @staticmethod
def get_section_data_path(section): def get_section_data_path(section):
""" """