1st attempt at an initial import.
[qwerkisync] / Windows / RestoreCrashBackupWindow.cpp
diff --git a/Windows/RestoreCrashBackupWindow.cpp b/Windows/RestoreCrashBackupWindow.cpp
new file mode 100644 (file)
index 0000000..fae2124
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "RestoreCrashBackupWindow.h"
+
+#include "EventLogBackupManager.h"
+
+#include "RestoreAccountStateWindow.h"
+
+#include <QtGui>
+
+#include <stdexcept>
+
+using namespace Windows;
+
+RestoreCrashBackupWindow::RestoreCrashBackupWindow(Settings& settings, QWidget *parent) :
+       BaseWindow(settings, parent)
+{
+       if(LockedBackupsPresent())
+               CreateContents();
+       else
+               Advance();
+}
+
+void RestoreCrashBackupWindow::CreateContents()
+{
+       switch(CurrentSettings().AppMode())
+       {
+               case Settings::APPMODE_GUI:
+               {
+                       QVBoxLayout *layout = new QVBoxLayout();
+                       {
+                               layout->setMargin(40);
+
+                               QLabel *lblNotice1 = new QLabel(tr("A backup has been found that suggests this program crashed during an import."));
+                               lblNotice1->setAlignment(Qt::AlignCenter);
+                               lblNotice1->setWordWrap(true);
+                               layout->addWidget(lblNotice1, 1);
+
+                               QLabel *lblNotice2 = new QLabel(tr("It is strongly advised that you restore this backup so the system is operating from a known valid state."));
+                               lblNotice2->setWordWrap(true);
+                               lblNotice2->setAlignment(Qt::AlignCenter);
+                               layout->addWidget(lblNotice2, 1);
+
+                               QLabel *lblNotice3 = new QLabel(tr("However, any events that have occurred since the backup was made will be lost."));
+                               lblNotice3->setWordWrap(true);
+                               lblNotice3->setAlignment(Qt::AlignCenter);
+                               layout->addWidget(lblNotice3, 1);
+
+                               QHBoxLayout *layoutButtons = new QHBoxLayout();
+                               {
+                                       QPushButton* btnRestoreBackup = new QPushButton(tr("Restore backup"));
+                                       QObject::connect(btnRestoreBackup, SIGNAL(clicked()), this, SLOT(RestoreBackup()));
+                                       layoutButtons->addWidget(btnRestoreBackup);
+                                       layoutButtons->setAlignment(btnRestoreBackup, Qt::AlignHCenter);
+
+                                       QPushButton* btnUnlockBackup = new QPushButton(tr("Unlock backup"));
+                                       QObject::connect(btnUnlockBackup, SIGNAL(clicked()), this, SLOT(UnlockBackup()));
+                                       layoutButtons->addWidget(btnUnlockBackup);
+                                       layoutButtons->setAlignment(btnUnlockBackup, Qt::AlignHCenter);
+                               }
+                               layout->addLayout(layoutButtons);
+
+                               centralWidget()->setLayout(layout);
+                       }
+
+                       break;
+               }
+
+               case Settings::APPMODE_CONSOLE:
+               {
+                       // Process args.
+
+                       Advance();
+                       break;
+               }
+       }
+}
+
+void RestoreCrashBackupWindow::RestoreBackup()
+{
+       EventLogBackupManager backupManager(CurrentSettings());
+       QFileInfoList lockedBackupPaths(backupManager.CurrentBackups(true));
+       if(lockedBackupPaths.count() > 1 && QMessageBox::Yes != QMessageBox::question(this,
+               tr("Warning! Multiple locked backups found!"),
+               tr("This should never be possible, and we're very sorry for the problem. Only the most recent backup will be restored and all other locked backups will be unlocked. Is this OK?"),
+               QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes))
+       {
+               return;
+       }
+
+       try
+       {
+               for(int i = 0; i < lockedBackupPaths.count(); ++i)
+               {
+                       // Only restore the most recent (the list returned from CurrentBackups is ordered by name desc)
+                       if(i == 0)
+                               backupManager.RestoreBackup(lockedBackupPaths.value(i).absoluteFilePath());
+
+                       backupManager.UnlockBackup(lockedBackupPaths.value(i).absoluteFilePath());
+               }
+
+               Advance();
+       }
+       catch(const std::exception &exception)
+       {
+               QMessageBox::critical(this,
+                       tr("Error"),
+                       QString(tr("A serious error has occurred whilst unlocking backups:\n%1\nPlease try again.")).arg(exception.what()));
+       }
+}
+
+void RestoreCrashBackupWindow::UnlockBackup()
+{
+       EventLogBackupManager backupManager(CurrentSettings());
+       QFileInfoList lockedBackupPaths(backupManager.CurrentBackups(true));
+       if(lockedBackupPaths.count() > 1 && QMessageBox::Yes != QMessageBox::question(this,
+               tr("Warning! Multiple locked backups found!"),
+               tr("This should never be possible, and we're very sorry for the problem. All locked backups must be unlocked before you continue. Is this OK?"),
+               QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes))
+       {
+               return;
+       }
+
+       try
+       {
+               foreach(QFileInfo backupPath, lockedBackupPaths)
+                       backupManager.UnlockBackup(backupPath.absoluteFilePath());
+
+               Advance();
+       }
+       catch(const std::exception &exception)
+       {
+               QMessageBox::critical(this,
+                       tr("Error"),
+                       QString(tr("A serious error has occurred whilst unlocking backups:\n%1\nPlease try again.")).arg(exception.what()));
+       }
+}
+
+void RestoreCrashBackupWindow::Advance()
+{
+       QWidget *next = new RestoreAccountStateWindow(CurrentSettings());
+       next->show();
+       close();
+}
+
+bool RestoreCrashBackupWindow::LockedBackupsPresent()
+{
+       EventLogBackupManager backupManager(CurrentSettings());
+       return backupManager.CurrentBackups(true).count() > 0;
+}