File indexing completed on 2024-04-14 05:39:28
0001 // SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com> 0002 // 0003 // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #include "filedigger.h" 0006 #include "mergedvfsmodel.h" 0007 #include "restoredialog.h" 0008 #include "versionlistmodel.h" 0009 #include "versionlistdelegate.h" 0010 0011 #include <KDirOperator> 0012 #include <KFilePlacesView> 0013 #include <KFilePlacesModel> 0014 #include <KGuiItem> 0015 #include <KIO/OpenUrlJob> 0016 #include <KIO/JobUiDelegate> 0017 #include <KIO/JobUiDelegateFactory> 0018 #include <KLocalizedString> 0019 #include <KMessageBox> 0020 #include <KStandardAction> 0021 #include <KToolBar> 0022 0023 #include <QGuiApplication> 0024 #include <QLabel> 0025 #include <QListView> 0026 #include <QPushButton> 0027 #include <QSplitter> 0028 #include <QTimer> 0029 #include <QTreeView> 0030 #include <QVBoxLayout> 0031 #include <utility> 0032 #include <kio_version.h> 0033 0034 FileDigger::FileDigger(QString pRepoPath, QString pBranchName, QWidget *pParent) 0035 : KMainWindow(pParent), mRepoPath(std::move(pRepoPath)), mBranchName(std::move(pBranchName)), mDirOperator(nullptr) 0036 { 0037 setWindowIcon(QIcon::fromTheme(QStringLiteral("kup"))); 0038 KToolBar *lAppToolBar = toolBar(); 0039 lAppToolBar->addAction(KStandardAction::quit(this, SLOT(close()), this)); 0040 QTimer::singleShot(0, this, [this]{repoPathAvailable();}); 0041 } 0042 0043 QSize FileDigger::sizeHint() const { 0044 return {800, 600}; 0045 } 0046 0047 void FileDigger::updateVersionModel(const QModelIndex &pCurrent, const QModelIndex &pPrevious) { 0048 Q_UNUSED(pPrevious) 0049 mVersionModel->setNode(MergedVfsModel::node(pCurrent)); 0050 mVersionView->selectionModel()->setCurrentIndex(mVersionModel->index(0,0), 0051 QItemSelectionModel::Select); 0052 } 0053 0054 void FileDigger::open(const QModelIndex &pIndex) { 0055 0056 auto *job = new KIO::OpenUrlJob(pIndex.data(VersionBupUrlRole).toUrl(), 0057 pIndex.data(VersionMimeTypeRole).toString()); 0058 #if KIO_VERSION > QT_VERSION_CHECK(5, 98, 0) 0059 auto *delegate = KIO::createDefaultJobUiDelegate(KIO::JobUiDelegate::AutoHandlingEnabled, this); 0060 #else 0061 auto *delegate = new KIO::JobUiDelegate(KIO::JobUiDelegate::AutoHandlingEnabled, this); 0062 #endif 0063 job->setUiDelegate(delegate); 0064 job->start(); 0065 } 0066 0067 void FileDigger::restore(const QModelIndex &pIndex) { 0068 auto lDialog = new RestoreDialog(pIndex.data(VersionSourceInfoRole).value<BupSourceInfo>(), this); 0069 lDialog->setAttribute(Qt::WA_DeleteOnClose); 0070 lDialog->show(); 0071 } 0072 0073 void FileDigger::repoPathAvailable() { 0074 if(mRepoPath.isEmpty()) { 0075 createSelectionView(); 0076 } else { 0077 QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 0078 MergedRepository *lRepository = createRepo(); 0079 if(lRepository != nullptr) { 0080 createRepoView(lRepository); 0081 } 0082 QGuiApplication::restoreOverrideCursor(); 0083 } 0084 } 0085 0086 void FileDigger::checkFileWidgetPath() { 0087 KFileItemList lList = mDirOperator->selectedItems(); 0088 if(lList.isEmpty()) { 0089 mRepoPath = mDirOperator->url().toLocalFile(); 0090 } else { 0091 mRepoPath = lList.first().url().toLocalFile(); 0092 } 0093 mBranchName = QStringLiteral("kup"); 0094 repoPathAvailable(); 0095 } 0096 0097 void FileDigger::enterUrl(const QUrl &pUrl) { 0098 mDirOperator->setUrl(pUrl, true); 0099 } 0100 0101 MergedRepository *FileDigger::createRepo() { 0102 auto lRepository = new MergedRepository(nullptr, mRepoPath, mBranchName); 0103 if(!lRepository->open()) { 0104 KMessageBox::error(nullptr, xi18nc("@info messagebox, %1 is a folder path", 0105 "The backup archive <filename>%1</filename> could not be opened. " 0106 "Check if the backups really are located there.", 0107 mRepoPath)); 0108 return nullptr; 0109 } 0110 if(!lRepository->readBranch()) { 0111 if(!lRepository->permissionsOk()) { 0112 KMessageBox::error(nullptr, xi18nc("@info messagebox", 0113 "You do not have permission needed to read this backup archive.")); 0114 } else { 0115 MergedRepository::askForIntegrityCheck(); 0116 } 0117 return nullptr; 0118 } 0119 return lRepository; 0120 } 0121 0122 void FileDigger::createRepoView(MergedRepository *pRepository) { 0123 auto lSplitter = new QSplitter(); 0124 mMergedVfsModel = new MergedVfsModel(pRepository, this); 0125 mMergedVfsView = new QTreeView(); 0126 mMergedVfsView->setHeaderHidden(true); 0127 mMergedVfsView->setSelectionMode(QAbstractItemView::SingleSelection); 0128 mMergedVfsView->setModel(mMergedVfsModel); 0129 lSplitter->addWidget(mMergedVfsView); 0130 connect(mMergedVfsView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), 0131 this, SLOT(updateVersionModel(QModelIndex,QModelIndex))); 0132 0133 mVersionView = new QListView(); 0134 mVersionView->setSelectionMode(QAbstractItemView::SingleSelection); 0135 mVersionModel = new VersionListModel(this); 0136 mVersionView->setModel(mVersionModel); 0137 auto lVersionDelegate = new VersionListDelegate(mVersionView,this); 0138 mVersionView->setItemDelegate(lVersionDelegate); 0139 lSplitter->addWidget(mVersionView); 0140 connect(lVersionDelegate, SIGNAL(openRequested(QModelIndex)), SLOT(open(QModelIndex))); 0141 connect(lVersionDelegate, SIGNAL(restoreRequested(QModelIndex)), SLOT(restore(QModelIndex))); 0142 mMergedVfsView->setFocus(); 0143 0144 //expand all levels from the top until the node has more than one child 0145 QModelIndex lIndex; 0146 forever { 0147 mMergedVfsView->expand(lIndex); 0148 if(mMergedVfsModel->rowCount(lIndex) == 1) { 0149 lIndex = mMergedVfsModel->index(0, 0, lIndex); 0150 } else { 0151 break; 0152 } 0153 } 0154 mMergedVfsView->selectionModel()->setCurrentIndex(mMergedVfsModel->index(0, 0, lIndex), QItemSelectionModel::Select); 0155 setCentralWidget(lSplitter); 0156 } 0157 0158 void FileDigger::createSelectionView() { 0159 if(mDirOperator != nullptr) { 0160 return; 0161 } 0162 auto lLabel = new QLabel(i18n("Select location of backup archive to open.")); 0163 0164 auto lPlaces = new KFilePlacesView; 0165 lPlaces->setModel(new KFilePlacesModel); 0166 0167 mDirOperator = new KDirOperator(); 0168 #if KIO_VERSION < QT_VERSION_CHECK(5, 100, 0) 0169 mDirOperator->setView(KFile::Tree); 0170 #else 0171 mDirOperator->setViewMode(KFile::Tree); 0172 #endif 0173 mDirOperator->setMode(KFile::Directory); 0174 mDirOperator->setEnableDirHighlighting(true); 0175 mDirOperator->setShowHiddenFiles(true); 0176 0177 connect(lPlaces, &KFilePlacesView::urlChanged, this, &FileDigger::enterUrl); 0178 0179 auto lOkButton = new QPushButton(this); 0180 KGuiItem::assign(lOkButton, KStandardGuiItem::ok()); 0181 connect(lOkButton, &QPushButton::pressed, this, &FileDigger::checkFileWidgetPath); 0182 0183 0184 auto lSelectionView = new QWidget; 0185 auto lVLayout1 = new QVBoxLayout; 0186 auto lSplitter = new QSplitter; 0187 0188 lVLayout1->addWidget(lLabel); 0189 lSplitter->addWidget(lPlaces); 0190 lSplitter->addWidget(mDirOperator); 0191 lVLayout1->addWidget(lSplitter, 1); 0192 lVLayout1->addWidget(lOkButton); 0193 lSelectionView->setLayout(lVLayout1); 0194 setCentralWidget(lSelectionView); 0195 }