Marble

DataMigration.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de>
4//
5
6// Self
7#include "DataMigration.h"
8
9// Marble
10#include "MarbleDebug.h"
11#include "MarbleDirs.h"
12#include "ui_DataMigrationWidget.h"
13
14// Qt
15#include <QDebug>
16#include <QDir>
17#include <QDirIterator>
18#include <QPointer>
19#include <QStack>
20#include <QDialog>
21#include <QProgressDialog>
22
23// std
24#include <limits>
25
26namespace Marble
27{
28
29DataMigration::DataMigration( QObject *parent )
30 : QObject( parent )
31{
32}
33
34DataMigration::~DataMigration()
35{
36}
37
38void DataMigration::exec()
39{
40 QStringList oldLocalPaths = MarbleDirs::oldLocalPaths();
41
42 if( oldLocalPaths.isEmpty() ) {
43 return;
44 }
45
46 QString currentLocalPath = MarbleDirs::localPath();
47 QDir currentLocalDir( currentLocalPath );
48 if( currentLocalDir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot ).size() != 0 ) {
49 return;
50 }
51
52 for( const QString& oldLocalPath: oldLocalPaths ) {
53 QDir oldLocalDir( oldLocalPath );
54
55 if( oldLocalDir.entryList( QDir::AllEntries | QDir::NoDotAndDotDot ).size() == 0 ) {
56 continue;
57 }
58
59 QPointer<QDialog> dialog = new QDialog();
60 Ui::DataMigrationWidget dataMigrationWidget;
61
62 dataMigrationWidget.setupUi( dialog );
63 if( dialog->exec() == QDialog::Accepted ) {
64 DataMigration::moveFiles( oldLocalPath, currentLocalPath );
65 }
66 delete dialog;
67
68 return;
69 }
70}
71
72void DataMigration::moveFiles( const QString& source, const QString& target )
73{
74 if( !QDir().rmdir( target ) ) {
75 mDebug() << "Removing of the target directory failed";
76 }
77
78 // Trying to simply rename the directory. This is the fastest method, but it is not always
79 // possible. For example when the directories are on different file systems.
80 // If the renaming of the directory is not successful, we have to copy and delete each
81 // file separately.
82 mDebug() << "Rename" << source << "to" << target;
83 if( !QDir().rename( source, target ) ) {
84 mDebug() << "Simple renaming of the data directory failed. Moving single files";
85
86 QProgressDialog progressDialog;
87 progressDialog.setWindowModality( Qt::WindowModal );
88 progressDialog.setMinimum( 0 );
89 progressDialog.setMaximum( std::numeric_limits<int>::max() );
90 progressDialog.setAutoReset( false );
91 progressDialog.setAutoClose( false );
92 progressDialog.setWindowTitle( tr( "Marble data conversion" ) );
93 progressDialog.setLabelText( tr( "Converting data ..." ) );
94
95 QDir().mkpath( target );
96 QString sourcePath = QDir( source ).canonicalPath();
97 int sourcePathLength = sourcePath.length();
98
99 // Running through all files recursively
100 QStack<QString> dirs;
101 dirs.push( sourcePath );
102
103 QStack<int> progressSliceSizeStack;
104 progressSliceSizeStack.push( progressDialog.maximum() );
105 int progress = 0;
106
107 while( !dirs.isEmpty() ) {
108 if( progressDialog.wasCanceled() ) {
109 return;
110 }
111
112 QString sourceDirPath = dirs.top();
113 mDebug() << "DataMigration: Current source dir path ="
114 << sourceDirPath;
115 mDebug() << "SliceSize =" << progressSliceSizeStack.top();
116
117 if( !sourceDirPath.startsWith( sourcePath ) ) {
118 dirs.pop();
119 progress += progressSliceSizeStack.pop();
120 progressDialog.setValue( progress );
121 continue;
122 }
123
124 QDir sourceDir( sourceDirPath );
125 // Creating child file/dir lists.
126 QStringList files = sourceDir.entryList( QDir::Files
129 QStringList childDirs = sourceDir.entryList( QDir::Dirs
132 int childSliceSize = 0;
133 if( !childDirs.isEmpty() ) {
134 childSliceSize = progressSliceSizeStack.pop() / childDirs.size();
135 progressSliceSizeStack.push( 0 );
136 }
137
138 if( files.isEmpty() && childDirs.isEmpty() )
139 {
140 // Remove empty directory
141 mDebug() << "DataMigration:" << dirs.top()
142 << "finished";
143 QDir().rmdir( dirs.pop() );
144 progress += progressSliceSizeStack.pop();
145 progressDialog.setValue( progress );
146 }
147 else {
148 // Add child directories to the stack
149 for( const QString& childDir: childDirs ) {
150 dirs.push(sourceDirPath + QLatin1Char('/') + childDir);
151 progressSliceSizeStack.push( childSliceSize );
152 }
153
154 // Creating target dir
155 QString targetDirPath = sourceDirPath;
156 targetDirPath.remove( 0, sourcePathLength );
157 targetDirPath.prepend( target );
158 QDir().mkpath( targetDirPath );
159
160 // Copying contents
161 for( const QString& file: files ) {
162 if( progressDialog.wasCanceled() ) {
163 return;
164 }
165
166 const QString sourceFilePath = sourceDirPath + QLatin1Char('/') + file;
167
168 if( !sourceFilePath.startsWith( sourcePath ) ) {
169 continue;
170 }
171
172 QString targetFilePath = sourceFilePath;
173 targetFilePath.remove( 0, sourcePathLength );
174 targetFilePath.prepend( target );
175
176 QFile::copy( sourceFilePath, targetFilePath );
177 QFile::remove( sourceFilePath );
178 }
179 }
180 }
181 }
182}
183
184}
185
186#include "moc_DataMigration.cpp"
KIOCORE_EXPORT SimpleJob * rmdir(const QUrl &url)
KIOCORE_EXPORT SimpleJob * rename(const QUrl &src, const QUrl &dest, JobFlags flags=DefaultFlags)
Binds a QML item to a specific geodetic location in screen coordinates.
QString canonicalPath() const const
bool mkpath(const QString &dirPath) const const
bool rmdir(const QString &dirName) const const
bool copy(const QString &fileName, const QString &newName)
bool remove()
bool isEmpty() const const
qsizetype size() const const
void setAutoClose(bool close)
void setAutoReset(bool reset)
void setLabelText(const QString &text)
void setMaximum(int maximum)
void setMinimum(int minimum)
void setValue(int progress)
void push(const T &t)
T & top()
qsizetype length() const const
QString & prepend(QChar ch)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
WindowModal
void setWindowModality(Qt::WindowModality windowModality)
void setWindowTitle(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.