← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~smpettit/openlp/data-path into lp:openlp

 

Stevan Pettit has proposed merging lp:~smpettit/openlp/data-path into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~smpettit/openlp/data-path/+merge/82291

Added code to allow user to change the location of the OpenLP data files.

The new location selected is a Root folder.  The actual data is stored in ...root/OpenLP/Data.
When the location is changed, the data files are copied to the new directory.  Files are not deleted from the old location.  (I don't think we should run the risk of deleting files on a users machine.)  The documentation can explain this.

If the data is in an alternate location, when settings/advanced is displayed, a button if made available to reset the location to the "default".

Various checks were added to insure the integrity of the data.

This code is a precursor to an OpenLP "Portable" version.
-- 
https://code.launchpad.net/~smpettit/openlp/data-path/+merge/82291
Your team OpenLP Core is requested to review the proposed merge of lp:~smpettit/openlp/data-path into lp:openlp.
=== modified file 'openlp/core/ui/advancedtab.py'
--- openlp/core/ui/advancedtab.py	2011-06-12 16:02:52 +0000
+++ openlp/core/ui/advancedtab.py	2011-11-15 15:43:31 +0000
@@ -29,9 +29,14 @@
 """
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import SettingsTab, translate, build_icon
+from distutils import dir_util
+from distutils.errors import DistutilsFileError
+import os
+import sys
+
+from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
 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):
     """
@@ -83,6 +88,28 @@
             u'enableAutoCloseCheckBox')
         self.uiLayout.addRow(self.enableAutoCloseCheckBox)
         self.leftLayout.addWidget(self.uiGroupBox)
+        self.dataDirectoryGroupBox = QtGui.QGroupBox(self.leftColumn)
+        self.dataDirectoryGroupBox.setObjectName(u'dataDirectoryGroupBox')
+        self.dataDirecdtoryLabel= QtGui.QLabel(self.dataDirectoryGroupBox)
+        self.dataDirecdtoryLabel.setObjectName(u'dataDirecdtoryLabel')
+        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.dataDirectoryLayout =QtGui.QFormLayout(self.dataDirectoryGroupBox)
+        self.dataDirectoryLayout.setObjectName(u'dataDirectoryLayout')
+        self.dataDirectoryLayout.addWidget(self.dataDirecdtoryLabel)
+        self.dataDirectoryLayout.addWidget(self.dataDirectoryBrowseButton)
+        self.dataDirectoryLayout.addWidget(self.dataDirectoryDefaultButton)
+        self.leftLayout.addWidget(self.dataDirectoryGroupBox)
         self.leftLayout.addStretch()
         self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
         self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
@@ -122,14 +149,20 @@
         self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
         self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
         self.rightLayout.addWidget(self.hideMouseGroupBox)
+        self.rightLayout.addWidget(self.defaultImageGroupBox)
         self.rightLayout.addStretch()
-
         QtCore.QObject.connect(self.defaultColorButton,
             QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
         QtCore.QObject.connect(self.defaultBrowseButton,
             QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
         QtCore.QObject.connect(self.defaultRevertButton,
             QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed)
+        QtCore.QObject.connect(self.dataDirectoryBrowseButton,
+            QtCore.SIGNAL(u'pressed()'),
+            self.onDataDirectoryBrowseButtonPressed)
+        QtCore.QObject.connect(self.dataDirectoryDefaultButton,
+            QtCore.SIGNAL(u'pressed()'),
+            self.onDataDirectoryDefaultButtonPressed)
 
     def retranslateUi(self):
         """
@@ -138,6 +171,8 @@
         self.tabTitleVisible = UiStrings().Advanced
         self.uiGroupBox.setTitle(
             translate('OpenLP.AdvancedTab', 'UI Settings'))
+        self.dataDirectoryGroupBox.setTitle(
+            translate('OpenLP.AdvancedTab', 'Data Location'))
         self.recentLabel.setText(
             translate('OpenLP.AdvancedTab',
                 'Number of recent files to display:'))
@@ -167,6 +202,15 @@
             'Browse for an image file to display.'))
         self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
             '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.'))
+
 
     def load(self):
         """
@@ -201,9 +245,34 @@
         self.default_color = settings.value(u'default color',
             QtCore.QVariant(u'#ffffff')).toString()
         self.defaultFileEdit.setText(settings.value(u'default image',
-            QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
-            .toString())
+            QtCore.QVariant(u':/graphics/openlp-splash-screen.png')).toString())
         settings.endGroup()
+        # Since data location can be changed, make sure the path is present.
+        data_path = AppLocation.get_data_path()
+        if AppLocation.IsDefaultDataPath:
+            self.dataDirectoryDefaultButton.hide()
+        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 moved 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()
+        self.dataDirecdtoryLabel.setText(data_path)
         self.defaultColorButton.setStyleSheet(
             u'background-color: %s' % self.default_color)
 
@@ -229,6 +298,7 @@
             QtCore.QVariant(self.hideMouseCheckBox.isChecked()))
         settings.setValue(u'default color', self.default_color)
         settings.setValue(u'default image', self.defaultFileEdit.text())
+        settings.setValue(u'data path', self.dataDirecdtoryLabel.text())
         settings.endGroup()
 
     def onDefaultColorButtonPressed(self):
@@ -249,6 +319,111 @@
             self.defaultFileEdit.setText(filename)
         self.defaultFileEdit.setFocus()
 
+    def onDataDirectoryBrowseButtonPressed(self):
+        old_data_path = str(self.dataDirecdtoryLabel.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))
+        new_data_path = os.path.join(new_path, 'openlp', 'data')
+        if new_path:
+            if old_data_path.lower() == new_data_path.lower():
+                return
+        else:
+            return
+        # Make sure they want to move 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' % (new_path,  new_data_path)),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Yes |
+            QtGui.QMessageBox.No),
+            QtGui.QMessageBox.No)
+        if answer != QtGui.QMessageBox.Yes:
+            return
+        # Move the data to the new location.
+        if not self.moveData(old_data_path, new_data_path):
+            return
+        self.dataDirecdtoryLabel.setText(new_data_path)
+        self.dataDirecdtoryLabel.setFocus()
+        # Change the location.
+        settings = QtCore.QSettings()
+        settings.setValue(u'%s/data path' % self.settingsSection,
+            self.dataDirecdtoryLabel.text())
+        QtGui.QMessageBox.information(self,
+            translate('OpenLP.AdvancedTab', 'New data directory'),
+            translate('OpenLP.AdvancedTab',
+            'OpenLP Data directory successfully changed to:\n\n %s \n\n'
+            'OpenLP will now close.  The new data file location will be used '
+            'the next time you start OpenLP.' % new_data_path),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Ok))
+        Receiver.send_message(u'cleanup')
+        QtCore.QCoreApplication.exit()
+
+    def onDataDirectoryDefaultButtonPressed(self):
+        # Make sure they want to move the data.
+        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?'), 
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Yes |
+            QtGui.QMessageBox.No),
+            QtGui.QMessageBox.No)
+        if answer != QtGui.QMessageBox.Yes:
+            return
+        old_data_path = str(self.dataDirecdtoryLabel.text())
+        new_data_path = str(AppLocation.set_default_data_path())
+        if self.moveData(old_data_path, new_data_path):
+            path = translate('OpenLP.AdvancedTab', 
+                u'The default location \n\n') + new_data_path
+            self.dataPathChanged(path)
+        else:
+            # Change the location back to what it was.
+            settings = QtCore.QSettings()
+            settings.setValue(u'%s/data path' % self.settingsSection,
+                old_data_path)
+
+    def moveData(self, old_data_path, new_data_path):
+        # Copy OpenLP data to new location.
+        Receiver.send_message(u'cursor_busy')
+        try:
+            Receiver.send_message(u'openlp_process_events')
+            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.AdvancedTab', 'New data directory error'),
+                translate('OpenLP.AdvancedTab',
+                'OpenLP Data directory move failed \n\n %s' % str(why)),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Ok))
+            return False
+        Receiver.send_message(u'cursor_normal')
+        return True
+        
+    def dataPathChanged(self, path):
+        # Display message data has been moved then terminate program.
+        QtGui.QMessageBox.information(self,
+            translate('OpenLP.AdvancedTab', 'New data directory'),
+            translate('OpenLP.AdvancedTab',
+            'OpenLP Data directory successfully changed to:\n\n %s \n\n'
+            'OpenLP will now close.  The new data file location will be used '
+            'the next time you start OpenLP.' % path),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Ok))
+        Receiver.send_message(u'cleanup')
+        QtCore.QCoreApplication.exit()
+
     def onDefaultRevertButtonPressed(self):
         self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
         self.defaultFileEdit.setFocus()

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2011-10-22 11:09:01 +0000
+++ openlp/core/ui/mainwindow.py	2011-11-15 15:43:31 +0000
@@ -616,6 +616,8 @@
             QtCore.SIGNAL(u'config_screen_changed'), self.screenChanged)
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'mainwindow_status_text'), self.showStatusMessage)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'cleanup'), self.cleanUp)
         # Media Manager
         QtCore.QObject.connect(self.mediaToolBox,
             QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged)
@@ -1309,7 +1311,6 @@
             settings.value(u'preview splitter geometry').toByteArray())
         self.controlSplitter.restoreState(
             settings.value(u'mainwindow splitter geometry').toByteArray())
-
         settings.endGroup()
 
     def saveSettings(self):

=== modified file 'openlp/core/utils/__init__.py'
--- openlp/core/utils/__init__.py	2011-11-13 08:57:29 +0000
+++ openlp/core/utils/__init__.py	2011-11-15 15:43:31 +0000
@@ -126,7 +126,8 @@
     VersionDir = 5
     CacheDir = 6
     LanguageDir = 7
-
+    IsDefaultDataPath = True
+    
     # Base path where data/config/cache dir is located
     BaseDir = None
 
@@ -165,11 +166,28 @@
         """
         Return the path OpenLP stores all its data under.
         """
-        path = AppLocation.get_directory(AppLocation.DataDir)
-        check_directory_exists(path)
+        # Check if we have a different data location.
+        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
 
     @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
     def get_section_data_path(section):
         """
         Return the path a particular module stores its data under.


Follow ups