File indexing completed on 2024-05-12 04:58:21

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2014 Franz Fellner <alpine.art.de@googlemail.com>
0004 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
0005 *
0006 * This program is free software: you can redistribute it and/or modify
0007 * it under the terms of the GNU General Public License as published by
0008 * the Free Software Foundation, either version 3 of the License, or
0009 * (at your option) any later version.
0010 *
0011 * This program is distributed in the hope that it will be useful,
0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 * GNU General Public License for more details.
0015 *
0016 * You should have received a copy of the GNU General Public License
0017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018 * ============================================================ */
0019 #include "restoremanager.h"
0020 #include "recoveryjsobject.h"
0021 #include "datapaths.h"
0022 
0023 #include <QFile>
0024 
0025 static const int restoreDataVersion = 2;
0026 
0027 bool RestoreData::isValid() const
0028 {
0029     for (const BrowserWindow::SavedWindow &window : std::as_const(windows)) {
0030         if (!window.isValid()) {
0031             return false;
0032         }
0033     }
0034     return !windows.isEmpty();
0035 }
0036 
0037 void RestoreData::clear()
0038 {
0039     windows.clear();
0040     crashedSession.clear();
0041     closedWindows.clear();
0042 }
0043 
0044 QDataStream &operator<<(QDataStream &stream, const RestoreData &data)
0045 {
0046     stream << static_cast<int>(data.windows.count());
0047     for (const BrowserWindow::SavedWindow &window : std::as_const(data.windows)) {
0048         stream << window;
0049     }
0050 
0051     stream << restoreDataVersion;
0052     stream << data.crashedSession;
0053     stream << data.closedWindows;
0054 
0055     return stream;
0056 }
0057 
0058 QDataStream &operator>>(QDataStream &stream, RestoreData &data)
0059 {
0060     int windowCount;
0061     stream >> windowCount;
0062     data.windows.reserve(windowCount);
0063 
0064     for (int i = 0; i < windowCount; ++i) {
0065         BrowserWindow::SavedWindow window;
0066         stream >> window;
0067         data.windows.append(window);
0068     }
0069 
0070     int version;
0071     stream >> version;
0072 
0073     if (version >= 1) {
0074         stream >> data.crashedSession;
0075     }
0076 
0077     if (version >= 2) {
0078         stream >> data.closedWindows;
0079     }
0080 
0081     return stream;
0082 }
0083 
0084 RestoreManager::RestoreManager(const QString &file)
0085     : m_recoveryObject(new RecoveryJsObject(this))
0086 {
0087     createFromFile(file);
0088 }
0089 
0090 RestoreManager::~RestoreManager()
0091 {
0092     delete m_recoveryObject;
0093 }
0094 
0095 RestoreData RestoreManager::restoreData() const
0096 {
0097     return m_data;
0098 }
0099 
0100 void RestoreManager::clearRestoreData()
0101 {
0102     QByteArray crashedSession = m_data.crashedSession;
0103     m_data.clear();
0104     QDataStream stream(&crashedSession, QIODevice::ReadOnly);
0105     stream >> m_data;
0106 }
0107 
0108 bool RestoreManager::isValid() const
0109 {
0110     return m_data.isValid();
0111 }
0112 
0113 QObject *RestoreManager::recoveryObject(WebPage *page)
0114 {
0115     m_recoveryObject->setPage(page);
0116     return m_recoveryObject;
0117 }
0118 
0119 static void loadCurrentVersion(QDataStream &stream, RestoreData &data)
0120 {
0121     stream >> data;
0122 }
0123 
0124 static void loadVersion3(QDataStream &stream, RestoreData &data)
0125 {
0126     int windowCount;
0127     stream >> windowCount;
0128     data.windows.reserve(windowCount);
0129 
0130     for (int i = 0; i < windowCount; ++i) {
0131         QByteArray tabsState;
0132         QByteArray windowState;
0133 
0134         stream >> tabsState;
0135         stream >> windowState;
0136 
0137         BrowserWindow::SavedWindow window;
0138 
0139 #ifdef QZ_WS_X11
0140         QDataStream stream1(&windowState, QIODevice::ReadOnly);
0141         stream1 >> window.windowState;
0142         stream1 >> window.virtualDesktop;
0143 #else
0144         window.windowState = windowState;
0145 #endif
0146 
0147         int tabsCount = -1;
0148         QDataStream stream2(&tabsState, QIODevice::ReadOnly);
0149         stream2 >> tabsCount;
0150         window.tabs.reserve(tabsCount);
0151         for (int i = 0; i < tabsCount; ++i) {
0152             WebTab::SavedTab tab;
0153             stream2 >> tab;
0154             window.tabs.append(tab);
0155         }
0156         stream2 >> window.currentTab;
0157 
0158         data.windows.append(window);
0159     }
0160 }
0161 
0162 // static
0163 bool RestoreManager::validateFile(const QString &file)
0164 {
0165     RestoreData data;
0166     createFromFile(file, data);
0167     return data.isValid();
0168 }
0169 
0170 // static
0171 void RestoreManager::createFromFile(const QString &file, RestoreData &data)
0172 {
0173     if (!QFile::exists(file)) {
0174         return;
0175     }
0176 
0177     QFile recoveryFile(file);
0178     if (!recoveryFile.open(QIODevice::ReadOnly)) {
0179         return;
0180     }
0181 
0182     QDataStream stream(&recoveryFile);
0183 
0184     int version;
0185     stream >> version;
0186 
0187     if (version == Qz::sessionVersion) {
0188         loadCurrentVersion(stream, data);
0189     } else if (version == 0x0003 || version == (0x0003 | 0x050000)) {
0190         loadVersion3(stream, data);
0191     } else {
0192         qWarning() << "Unsupported session file version" << version;
0193     }
0194 }
0195 
0196 void RestoreManager::createFromFile(const QString &file)
0197 {
0198     createFromFile(file, m_data);
0199 }