← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~smpettit/openlp/settings-export into lp:openlp

 

Stevan Pettit has proposed merging lp:~smpettit/openlp/settings-export into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)
Related bugs:
  Bug #794535 in OpenLP: "Method of exporting/importing settings"
  https://bugs.launchpad.net/openlp/+bug/794535

For more details, see:
https://code.launchpad.net/~smpettit/openlp/settings-export/+merge/72880

Bug #794535

Added code to mainwindow.py to allow exporting/importing of OpenLP settings to an INI file.

During importing, the selected file is checked to insure it is an OpenLP settings file.
The user is warned prior to the import that changes will be made.

I also changed the settings section of an entry in servicemanager from "service" to "servicemanager".

I changed my nick in about. 
-- 
https://code.launchpad.net/~smpettit/openlp/settings-export/+merge/72880
Your team OpenLP Core is requested to review the proposed merge of lp:~smpettit/openlp/settings-export into lp:openlp.
=== modified file 'openlp/core/ui/aboutdialog.py'
--- openlp/core/ui/aboutdialog.py	2011-06-13 18:10:06 +0000
+++ openlp/core/ui/aboutdialog.py	2011-08-25 12:58:24 +0000
@@ -116,7 +116,7 @@
             u'Scott "sguerrieri" Guerrieri',
             u'Matthias "matthub" Hub', u'Meinert "m2j" Jordan',
             u'Armin "orangeshirt" K\xf6hler', u'Joshua "milleja46" Miller',
-            u'Stevan "StevanP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru',
+            u'Stevan "ElderP" Pettit', u'Mattias "mahfiaz" P\xf5ldaru',
             u'Christian "crichter" Richter', u'Philip "Phill" Ridout',
             u'Simon "samscudder" Scudder', u'Jeffrey "whydoubt" Smith',
             u'Maikel Stuivenberg', u'Frode "frodus" Woldsund']
@@ -125,7 +125,7 @@
         packagers = ['Thomas "tabthorpe" Abthorpe (FreeBSD)',
             u'Tim "TRB143" Bentley (Fedora)',
             u'Matthias "matthub" Hub (Mac OS X)',
-            u'Stevan "StevanP" Pettit (Windows)',
+            u'Stevan "ElderP" Pettit (Windows)',
             u'Raoul "superfly" Snyman (Ubuntu)']
         translators = {
             u'af': [u'Johan "nuvolari" Mynhardt'],

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2011-08-20 19:36:51 +0000
+++ openlp/core/ui/mainwindow.py	2011-08-25 12:58:24 +0000
@@ -27,14 +27,16 @@
 
 import logging
 import os
-import sys
+import sys, string
 import shutil
 from tempfile import gettempdir
+from datetime import datetime
 
 from PyQt4 import QtCore, QtGui
 
 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, \
     icon_action, shortcut_action
 from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
@@ -214,7 +216,7 @@
             self.mediaManagerDock.isVisible(), UiStrings().View)
         self.viewThemeManagerItem = shortcut_action(mainWindow,
             u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
-            self.toggleThemeManager,  u':/system/system_thememanager.png',
+            self.toggleThemeManager, u':/system/system_thememanager.png',
             self.themeManagerDock.isVisible(), UiStrings().View)
         self.viewServiceManagerItem = shortcut_action(mainWindow,
             u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
@@ -284,6 +286,10 @@
         self.settingsConfigureItem = icon_action(mainWindow,
             u'settingsConfigureItem', u':/system/system_settings.png',
             category=UiStrings().Settings)
+        self.settingsImportItem = base_action(mainWindow,
+           u'settingsImportItem', category=UiStrings().Settings)
+        self.settingsExportItem = base_action(mainWindow,
+           u'settingsExportItem', category=UiStrings().Settings)    
         action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
         self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
             [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
@@ -301,10 +307,10 @@
             u':/system/system_online_help.png', category=UiStrings().Help)
         self.webSiteItem = base_action(
             mainWindow, u'webSiteItem', category=UiStrings().Help)
-        add_actions(self.fileImportMenu,
-            (self.importThemeItem, self.importLanguageItem))
-        add_actions(self.fileExportMenu,
-            (self.exportThemeItem, self.exportLanguageItem))
+        add_actions(self.fileImportMenu, (self.settingsImportItem, None,
+            self.importThemeItem, self.importLanguageItem))
+        add_actions(self.fileExportMenu, (self.settingsExportItem, None,
+            self.exportThemeItem, self.exportLanguageItem))
         add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
             self.fileSaveItem, self.fileSaveAsItem,
             self.recentFilesMenu.menuAction(), None,
@@ -357,6 +363,7 @@
         self.importLanguageItem.setVisible(False)
         self.exportLanguageItem.setVisible(False)
         self.setLockPanel(panelLocked)
+        self.settingsImported = False
 
     def retranslateUi(self, mainWindow):
         """
@@ -420,6 +427,15 @@
             translate('OpenLP.MainWindow', 'Configure &Formatting Tags...'))
         self.settingsConfigureItem.setText(
             translate('OpenLP.MainWindow', '&Configure OpenLP...'))
+        self.settingsExportItem.setStatusTip(translate('OpenLP.MainWindow',
+            'Export OpenLP settings to a specified Ini file'))
+        self.settingsExportItem.setText(
+            translate('OpenLP.MainWindow', 'Settings'))
+        self.settingsImportItem.setStatusTip(translate('OpenLP.MainWindow',
+            'Import OpenLP settings from a specified Ini file previously '
+            'exported on this or another machine'))
+        self.settingsImportItem.setText(
+            translate('OpenLP.MainWindow', 'Settings'))
         self.viewMediaManagerItem.setText(
             translate('OpenLP.MainWindow', '&Media Manager'))
         self.viewMediaManagerItem.setToolTip(
@@ -523,8 +539,12 @@
         # (not for use by plugins)
         self.uiSettingsSection = u'user interface'
         self.generalSettingsSection = u'general'
-        self.serviceSettingsSection = u'servicemanager'
+        self.advancedlSettingsSection = u'advanced'
+        self.servicemanagerSettingsSection = u'servicemanager'
         self.songsSettingsSection = u'songs'
+        self.themesSettingsSection = u'themes'
+        self.displayTagsSection = u'displayTags'
+        self.headerSection = u'SettingsImport'
         self.serviceNotSaved = False
         self.aboutForm = AboutForm(self)
         self.settingsForm = SettingsForm(self, self)
@@ -573,6 +593,10 @@
             QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
         QtCore.QObject.connect(self.settingsShortcutsItem,
             QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked)
+        QtCore.QObject.connect(self.settingsImportItem,
+            QtCore.SIGNAL(u'triggered()'), self.onSettingsImportItemClicked)
+        QtCore.QObject.connect(self.settingsExportItem,
+            QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked)
         # i18n set signals for languages
         self.languageGroup.triggered.connect(LanguageManager.set_language)
         QtCore.QObject.connect(self.modeDefaultItem,
@@ -868,6 +892,172 @@
         if self.shortcutForm.exec_():
             self.shortcutForm.save()
 
+    def onSettingsImportItemClicked(self):
+        """
+        Import settings from an export INI file
+        """
+        answer = QtGui.QMessageBox.critical(self,
+            translate('OpenLP.MainWindow', 'Import settings?'),
+            translate('OpenLP.MainWindow',
+            'Are you sure you want to import settings?\n\n'
+            'Importing settings will make permanent changes to your current '
+            'OpenLP configuration.\n\n'
+            'Importing incorrect settings may cause erratic behaviour or '
+            'OpenLP to terminate abnormally.'),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Yes |
+            QtGui.QMessageBox.No),
+            QtGui.QMessageBox.No)
+        if answer == QtGui.QMessageBox.No:
+            return
+        importFileName = unicode(QtGui.QFileDialog.getOpenFileName(self,
+                translate('OpenLP.MainWindow', 'Open File'),
+                '',
+                translate('OpenLP.MainWindow',
+                'OpenLP Export Settings Files (*.ini)')))
+        if not importFileName:
+            return
+        settingSections = []
+        # Add main sections.
+        settingSections.extend([self.generalSettingsSection])
+        settingSections.extend([self.advancedlSettingsSection])
+        settingSections.extend([self.uiSettingsSection])
+        settingSections.extend([self.servicemanagerSettingsSection])
+        settingSections.extend([self.themesSettingsSection])
+        settingSections.extend([self.displayTagsSection])
+        settingSections.extend([self.headerSection])
+        # Add plugin sections.
+        for plugin in self.pluginManager.plugins:
+            settingSections.extend([plugin.name])
+        settings = QtCore.QSettings()
+        importSettings = QtCore.QSettings(importFileName,
+            QtCore.QSettings.IniFormat)
+        importKeys = importSettings.allKeys()
+        for sectionKey in importKeys:
+            # We need to handle the really bad files.
+            try:
+                section, key = string.split(sectionKey, u'/')
+            except:
+                section = u'unknown'
+                key = u''
+            # Switch General back to lowercase.
+            if section == u'General':
+                section = u'general'
+            sectionKey = section + "/" + key
+            # Make sure it's a valid section for us.
+            if not section in settingSections:
+                QtGui.QMessageBox.critical(self,
+                    translate('OpenLP.MainWindow', 'Import settings'),
+                    translate('OpenLP.MainWindow',
+                    'The file you selected does appear to be a valid OpenLP '
+                    'settings file.\n\n'
+                    'Section [%s] is not valid \n\n'
+                    'Processing has terminated and no changed have been made.'
+                    % section),
+                    QtGui.QMessageBox.StandardButtons(
+                    QtGui.QMessageBox.Ok))
+                return
+        # We have a good file, import it.
+        for sectionKey in importKeys:
+            value = importSettings.value(sectionKey)
+            settings.setValue(u'%s' % (sectionKey) ,
+                QtCore.QVariant(value))
+        now = datetime.now()
+        settings.beginGroup(self.headerSection)
+        settings.setValue( u'file_imported' , QtCore.QVariant(importFileName))
+        settings.setValue(u'file_date_imported',
+            now.strftime("%Y-%m-%d %H:%M"))
+        settings.endGroup()
+        settings.sync()
+        # We must do an immediate restart or current configuration will
+        # overwrite what was just imported when application terminates
+        # normally.   We need to exit without saving configuration.
+        QtGui.QMessageBox.information(self,
+            translate('OpenLP.MainWindow', 'Import settings'),
+            translate('OpenLP.MainWindow',
+            'OpenLP will now close.  Imported settings will '
+            'take place the next time you start OpenLP'),
+            QtGui.QMessageBox.StandardButtons(
+            QtGui.QMessageBox.Ok))
+        self.settingsImported = True
+        self.cleanUp()
+        os._exit(0)
+
+    def onSettingsExportItemClicked(self, exportFileName=None):
+        """
+        Export settings to an INI file
+        """
+        if not exportFileName:
+            exportFileName = unicode(QtGui.QFileDialog.getSaveFileName(self,
+                translate('OpenLP.MainWindow', 'Export Settings File'), '',
+                translate('OpenLP.MainWindow',
+                    'OpenLP Export Settings File (*.ini)')))
+        if not exportFileName:
+            return
+        # Make sure it's an .ini file.
+        if not exportFileName.endswith(u'ini'):
+            exportFileName = exportFileName + u'.ini'
+        temp_file = os.path.join(unicode(gettempdir()), 
+            u'openlp', u'exportIni.tmp')
+        self.saveSettings()
+        settingSections = []
+        # Add main sections.
+        settingSections.extend([self.generalSettingsSection])
+        settingSections.extend([self.advancedlSettingsSection])
+        settingSections.extend([self.uiSettingsSection])
+        settingSections.extend([self.servicemanagerSettingsSection])
+        settingSections.extend([self.themesSettingsSection])
+        settingSections.extend([self.displayTagsSection])
+        # Add plugin sections.
+        for plugin in self.pluginManager.plugins:
+            settingSections.extend([plugin.name])
+        # Delete old files if found.
+        if os.path.exists(temp_file):
+            os.remove(temp_file)
+        if os.path.exists(exportFileName):
+            os.remove(exportFileName)
+        settings = QtCore.QSettings()
+        settings.remove(self.headerSection)
+        # Get the settings.
+        keys = settings.allKeys()
+        exportSettings = QtCore.QSettings(temp_file,
+            QtCore.QSettings.IniFormat)
+        # Add a header section.
+        # This is to insure it's our ini file for import.
+        now = datetime.now()
+        applicationVersion = get_application_version()
+        # Write INI format using Qsettings.
+        # Write our header.
+        exportSettings.beginGroup(self.headerSection)
+        exportSettings.setValue(u'Make_Changes', u'At_Own_RISK')
+        exportSettings.setValue(u'type', u'OpenLP_settings_export')
+        exportSettings.setValue(u'file_date_created',
+            now.strftime("%Y-%m-%d %H:%M"))
+        exportSettings.setValue(u'version', applicationVersion[u'full'])
+        exportSettings.endGroup()
+        # Write all the sections and keys.
+        for sectionKey in keys:
+            section, key = string.split(sectionKey, u'/')
+            keyValue = settings.value(sectionKey)
+            sectionKey = section + u"/" + key
+            # Change the service section to servicemanager.
+            if section == u'service':
+                sectionKey = u'servicemanager/' + key
+            exportSettings.setValue(sectionKey, keyValue)
+        exportSettings.sync()
+        # Temp INI file has been written.  Blanks in keys are now '%20'.
+        # Read the  temp file and output the user's INI file with blanks to
+        # make it more readable.
+        tempIni = open(temp_file, u'r')
+        exportIni = open(exportFileName,  u'w')
+        for fileRecord in tempIni:
+            fileRecord = fileRecord.replace(u'%20',  u' ')
+            exportIni.write(fileRecord)
+        tempIni.close()
+        exportIni.close()
+        os.remove(temp_file)
+        return
+
     def onModeDefaultItemClicked(self):
         """
         Put OpenLP into "Default" view mode.
@@ -920,6 +1110,9 @@
         """
         Hook to close the main window and display windows on exit
         """
+        # If we just did a settings import, close without saving changes.
+        if self.settingsImported:
+            event.accept()
         if self.serviceManagerContents.isModified():
             ret = self.serviceManagerContents.saveModifiedService()
             if ret == QtGui.QMessageBox.Save:
@@ -1117,6 +1310,9 @@
         """
         Save the main window settings.
         """
+        # Exit if we just did a settings import.
+        if self.settingsImported:
+            return
         log.debug(u'Saving QSettings')
         settings = QtCore.QSettings()
         settings.beginGroup(self.generalSettingsSection)

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2011-08-14 13:05:39 +0000
+++ openlp/core/ui/servicemanager.py	2011-08-25 12:58:24 +0000
@@ -290,7 +290,7 @@
             QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
         # Last little bits of setting up
         self.service_theme = unicode(QtCore.QSettings().value(
-            self.mainwindow.serviceSettingsSection + u'/service theme',
+            self.mainwindow.servicemanagerSettingsSection + u'/service theme',
             QtCore.QVariant(u'')).toString())
         self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
         # build the drag and drop context menu
@@ -371,7 +371,7 @@
         self.mainwindow.setServiceModified(self.isModified(),
             self.shortFileName())
         QtCore.QSettings(). \
-            setValue(u'service/last file',QtCore.QVariant(fileName))
+            setValue(u'servicemanager/last file',QtCore.QVariant(fileName))
 
     def fileName(self):
         """
@@ -429,14 +429,15 @@
                 self.mainwindow,
                 translate('OpenLP.ServiceManager', 'Open File'),
                 SettingsManager.get_last_dir(
-                self.mainwindow.serviceSettingsSection),
+                self.mainwindow.servicemanagerSettingsSection),
                 translate('OpenLP.ServiceManager',
                 'OpenLP Service Files (*.osz)')))
             if not fileName:
                 return False
         else:
             fileName = loadFile
-        SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
+        SettingsManager.set_last_dir(
+            self.mainwindow.servicemanagerSettingsSection,
             split_filename(fileName)[0])
         self.loadFile(fileName)
 
@@ -461,7 +462,7 @@
         self.setFileName(u'')
         self.setModified(False)
         QtCore.QSettings(). \
-            setValue(u'service/last file',QtCore.QVariant(u''))
+            setValue(u'servicemanager/last file',QtCore.QVariant(u''))
 
     def saveFile(self):
         """
@@ -474,7 +475,8 @@
         (basename, extension) = os.path.splitext(file_name)
         service_file_name = basename + '.osd'
         log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
-        SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
+        SettingsManager.set_last_dir(
+            self.mainwindow.servicemanagerSettingsSection,
             path)
         service = []
         write_list = []
@@ -562,7 +564,7 @@
         fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
             UiStrings().SaveService,
             SettingsManager.get_last_dir(
-            self.mainwindow.serviceSettingsSection),
+            self.mainwindow.servicemanagerSettingsSection),
             translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
         if not fileName:
             return False
@@ -624,7 +626,7 @@
                 self.mainwindow.addRecentFile(fileName)
                 self.setModified(False)
                 QtCore.QSettings().setValue(
-                    'service/last file', QtCore.QVariant(fileName))
+                    'servicemanager/last file', QtCore.QVariant(fileName))
             else:
                 critical_error_message_box(
                     message=translate('OpenLP.ServiceManager',
@@ -666,7 +668,7 @@
         present.
         """
         fileName = QtCore.QSettings(). \
-            value(u'service/last file',QtCore.QVariant(u'')).toString()
+            value(u'servicemanager/last file',QtCore.QVariant(u'')).toString()
         if fileName:
             self.loadFile(fileName)
 
@@ -1008,7 +1010,8 @@
         self.service_theme = unicode(self.themeComboBox.currentText())
         self.mainwindow.renderer.set_service_theme(self.service_theme)
         QtCore.QSettings().setValue(
-            self.mainwindow.serviceSettingsSection + u'/service theme',
+            self.mainwindow.servicemanagerSettingsSection +
+                u'/service theme',
             QtCore.QVariant(self.service_theme))
         self.regenerateServiceItems()
 


Follow ups