File indexing completed on 2025-01-19 03:53:48
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-11-14 0007 * Description : database migration dialog 0008 * 0009 * SPDX-FileCopyrightText: 2009-2010 by Holger Foerster <Hamsi2k at freenet dot de> 0010 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "dbmigrationdlg.h" 0017 0018 // QT includes 0019 0020 #include <QApplication> 0021 #include <QGridLayout> 0022 #include <QWidget> 0023 #include <QList> 0024 #include <QSqlQuery> 0025 #include <QMap> 0026 #include <QSqlError> 0027 #include <QLabel> 0028 #include <QGroupBox> 0029 #include <QDialogButtonBox> 0030 #include <QVBoxLayout> 0031 #include <QPushButton> 0032 #include <QMessageBox> 0033 0034 // KDE includes 0035 0036 #include <klocalizedstring.h> 0037 0038 // Local includes 0039 0040 #include "digikam_debug.h" 0041 #include "digikam_globals.h" 0042 #include "applicationsettings.h" 0043 #include "coredbaccess.h" 0044 #include "dbengineparameters.h" 0045 #include "coredbschemaupdater.h" 0046 0047 namespace Digikam 0048 { 0049 0050 class Q_DECL_HIDDEN DatabaseCopyThread::Private 0051 { 0052 public: 0053 0054 explicit Private() 0055 { 0056 } 0057 0058 DbEngineParameters fromDbEngineParameters; 0059 DbEngineParameters toDbEngineParameters; 0060 }; 0061 0062 DatabaseCopyThread::DatabaseCopyThread(QWidget* const parent) 0063 : QThread(parent), 0064 d (new Private) 0065 { 0066 } 0067 0068 DatabaseCopyThread::~DatabaseCopyThread() 0069 { 0070 delete d; 0071 } 0072 0073 void DatabaseCopyThread::run() 0074 { 0075 m_copyManager.copyDatabases(d->fromDbEngineParameters, d->toDbEngineParameters); 0076 } 0077 0078 void DatabaseCopyThread::init(const DbEngineParameters& fromDbEngineParameters, 0079 const DbEngineParameters& toDbEngineParameters) 0080 { 0081 d->fromDbEngineParameters = fromDbEngineParameters; 0082 d->toDbEngineParameters = toDbEngineParameters; 0083 } 0084 0085 // --------------------------------------------------------------------------- 0086 0087 class Q_DECL_HIDDEN DatabaseMigrationDialog::Private 0088 { 0089 public: 0090 0091 explicit Private() 0092 : fromDatabaseSettingsWidget (nullptr), 0093 toDatabaseSettingsWidget (nullptr), 0094 migrateButton (nullptr), 0095 cancelButton (nullptr), 0096 overallStepTitle (nullptr), 0097 progressBar (nullptr), 0098 progressBarSmallStep (nullptr), 0099 buttons (nullptr), 0100 copyThread (nullptr) 0101 { 0102 } 0103 0104 DatabaseSettingsWidget* fromDatabaseSettingsWidget; 0105 DatabaseSettingsWidget* toDatabaseSettingsWidget; 0106 QPushButton* migrateButton; 0107 QPushButton* cancelButton; 0108 QLabel* overallStepTitle; 0109 QProgressBar* progressBar; 0110 QProgressBar* progressBarSmallStep; 0111 QDialogButtonBox* buttons; 0112 DatabaseCopyThread* copyThread; 0113 }; 0114 0115 DatabaseMigrationDialog::DatabaseMigrationDialog(QWidget* const parent) 0116 : QDialog(parent), 0117 d (new Private) 0118 { 0119 setupMainArea(); 0120 } 0121 0122 DatabaseMigrationDialog::~DatabaseMigrationDialog() 0123 { 0124 d->copyThread->wait(); 0125 delete d; 0126 } 0127 0128 void DatabaseMigrationDialog::setupMainArea() 0129 { 0130 d->buttons = new QDialogButtonBox(QDialogButtonBox::Close | QDialogButtonBox::Help, this); 0131 d->buttons->button(QDialogButtonBox::Close)->setDefault(true); 0132 0133 d->copyThread = new DatabaseCopyThread(this); 0134 d->fromDatabaseSettingsWidget = new DatabaseSettingsWidget(this); 0135 d->toDatabaseSettingsWidget = new DatabaseSettingsWidget(this); 0136 d->migrateButton = new QPushButton(i18n("Migrate ->"), this); 0137 d->cancelButton = new QPushButton(i18n("Cancel"), this); 0138 d->cancelButton->setEnabled(false); 0139 0140 QGroupBox* const progressBox = new QGroupBox(i18n("Progress Information"), this); 0141 QGridLayout* const grid = new QGridLayout(progressBox); 0142 0143 d->progressBar = new QProgressBar(progressBox); 0144 d->progressBar->setTextVisible(true); 0145 d->progressBar->setRange(0, 22); 0146 d->progressBarSmallStep = new QProgressBar(progressBox); 0147 d->progressBarSmallStep->setTextVisible(true); 0148 0149 d->overallStepTitle = new QLabel(i18n("Step Progress"), progressBox); 0150 QLabel* const overallSteps = new QLabel(i18n("Overall Progress"), progressBox); 0151 0152 grid->addWidget(d->overallStepTitle, 0, 0, 1, 1); 0153 grid->addWidget(new QLabel(this), 0, 1, 1, 1); 0154 grid->addWidget(overallSteps, 0, 2, 1, 1); 0155 grid->addWidget(d->progressBarSmallStep, 1, 0, 1, 1); 0156 grid->addWidget(new QLabel(this), 1, 1, 1, 1); 0157 grid->addWidget(d->progressBar, 1, 2, 1, 1); 0158 grid->setColumnStretch(0, 10); 0159 grid->setColumnStretch(1, 2); 0160 grid->setColumnStretch(2, 10); 0161 0162 QWidget* const mainWidget = new QWidget; 0163 QGridLayout* const layout = new QGridLayout; 0164 mainWidget->setLayout(layout); 0165 0166 layout->addWidget(d->fromDatabaseSettingsWidget, 0, 0, 4, 1); 0167 layout->addWidget(d->migrateButton, 1, 1); 0168 layout->addWidget(d->cancelButton, 2, 1); 0169 layout->addWidget(d->toDatabaseSettingsWidget, 0, 2, 4, 1); 0170 layout->addWidget(progressBox, 4, 0, 1, 3); 0171 0172 QVBoxLayout* const vbx = new QVBoxLayout(this); 0173 vbx->addWidget(mainWidget); 0174 vbx->addWidget(d->buttons); 0175 setLayout(vbx); 0176 0177 dataInit(); 0178 0179 // -------------------------------------------------------------------------- 0180 0181 connect(d->buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), 0182 this, SLOT(accept())); 0183 0184 connect(d->buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), 0185 this, SLOT(accept())); 0186 0187 connect(d->migrateButton, SIGNAL(clicked()), 0188 this, SLOT(slotPerformCopy())); 0189 0190 // connect signal handlers for copy d->copyThread 0191 0192 connect(&(d->copyThread->m_copyManager), SIGNAL(finished(int,QString)), 0193 this, SLOT(slotHandleFinish(int,QString))); 0194 0195 connect(&(d->copyThread->m_copyManager), SIGNAL(stepStarted(QString)), 0196 this, SLOT(slotHandleStepStarted(QString))); 0197 0198 connect(&(d->copyThread->m_copyManager), SIGNAL(smallStepStarted(int,int)), 0199 this, SLOT(slotHandleSmallStepStarted(int,int))); 0200 0201 connect(d->buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), 0202 &(d->copyThread->m_copyManager), SLOT(stopProcessing())); 0203 0204 connect(d->cancelButton, SIGNAL(clicked()), 0205 &(d->copyThread->m_copyManager), SLOT(stopProcessing())); 0206 } 0207 0208 void DatabaseMigrationDialog::slotHelp() 0209 { 0210 openOnlineDocumentation(QLatin1String("setup_application"), QLatin1String("database_settings"), QLatin1String("database_migration")); 0211 } 0212 0213 void DatabaseMigrationDialog::slotPerformCopy() 0214 { 0215 DbEngineParameters toDBParameters = d->toDatabaseSettingsWidget->getDbEngineParameters(); 0216 DbEngineParameters fromDBParameters = d->fromDatabaseSettingsWidget->getDbEngineParameters(); 0217 0218 if (fromDBParameters == toDBParameters) 0219 { 0220 QMessageBox::critical(this, qApp->applicationName(), 0221 i18n("Database type or location must be different!")); 0222 return; 0223 } 0224 0225 if (fromDBParameters.internalServer && toDBParameters.internalServer) 0226 { 0227 QMessageBox::critical(this, qApp->applicationName(), 0228 i18n("Internal server can only be used once!")); 0229 return; 0230 } 0231 0232 DbEngineParameters orgPrms = ApplicationSettings::instance()->getDbEngineParameters(); 0233 0234 if ((fromDBParameters.internalServer || toDBParameters.internalServer) && !orgPrms.internalServer) 0235 { 0236 QMessageBox::critical(this, qApp->applicationName(), 0237 i18n("Internal server is not used and is not active!")); 0238 return; 0239 } 0240 0241 d->copyThread->init(fromDBParameters, toDBParameters); 0242 0243 slotLockInputFields(); 0244 d->copyThread->start(); 0245 } 0246 0247 void DatabaseMigrationDialog::dataInit() 0248 { 0249 d->fromDatabaseSettingsWidget->setParametersFromSettings(ApplicationSettings::instance(), true); 0250 d->toDatabaseSettingsWidget->setParametersFromSettings(ApplicationSettings::instance(), true); 0251 } 0252 0253 void DatabaseMigrationDialog::slotUnlockInputFields() 0254 { 0255 d->fromDatabaseSettingsWidget->setEnabled(true); 0256 d->toDatabaseSettingsWidget->setEnabled(true); 0257 d->migrateButton->setEnabled(true); 0258 d->progressBar->setValue(0); 0259 d->progressBarSmallStep->setValue(0); 0260 0261 d->cancelButton->setEnabled(false); 0262 } 0263 0264 void DatabaseMigrationDialog::slotLockInputFields() 0265 { 0266 d->fromDatabaseSettingsWidget->setEnabled(false); 0267 d->toDatabaseSettingsWidget->setEnabled(false); 0268 d->migrateButton->setEnabled(false); 0269 d->cancelButton->setEnabled(true); 0270 } 0271 0272 void DatabaseMigrationDialog::slotHandleFinish(int finishState, const QString& errorMsg) 0273 { 0274 switch (finishState) 0275 { 0276 case CoreDbCopyManager::failed: 0277 QMessageBox::critical(this, qApp->applicationName(), errorMsg); 0278 slotUnlockInputFields(); 0279 break; 0280 0281 case CoreDbCopyManager::success: 0282 QMessageBox::information(this, qApp->applicationName(), i18n("Database copied successfully.")); 0283 slotUnlockInputFields(); 0284 break; 0285 0286 case CoreDbCopyManager::canceled: 0287 QMessageBox::information(this, qApp->applicationName(), i18n("Database conversion canceled.")); 0288 slotUnlockInputFields(); 0289 break; 0290 } 0291 } 0292 0293 void DatabaseMigrationDialog::slotHandleStepStarted(const QString& stepName) 0294 { 0295 int progressBarValue = d->progressBar->value(); 0296 d->overallStepTitle->setText(i18n("Step Progress (%1)", stepName)); 0297 d->progressBar->setValue(++progressBarValue); 0298 } 0299 0300 void DatabaseMigrationDialog::slotHandleSmallStepStarted(int currentValue, int maxValue) 0301 { 0302 d->progressBarSmallStep->setMaximum(maxValue); 0303 d->progressBarSmallStep->setValue(currentValue); 0304 } 0305 0306 } // namespace Digikam 0307 0308 #include "moc_dbmigrationdlg.cpp"