Marble

DataMigration.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Bastian Holst <[email protected]>
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 
26 namespace Marble
27 {
28 
29 DataMigration::DataMigration( QObject *parent )
30  : QObject( parent )
31 {
32 }
33 
34 DataMigration::~DataMigration()
35 {
36 }
37 
38 void 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 
72 void 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
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"
bool remove()
void setValue(int progress)
bool copy(const QString &newName)
WindowModal
QString & prepend(QChar ch)
void setLabelText(const QString &text)
void setMinimum(int minimum)
int size() const const
T & top()
bool rmdir(const QString &dirName) const const
void setWindowModality(Qt::WindowModality windowModality)
QString canonicalPath() const const
int length() const const
void setWindowTitle(const QString &)
bool mkpath(const QString &dirPath) const const
void setAutoClose(bool close)
bool isEmpty() const const
Binds a QML item to a specific geodetic location in screen coordinates.
QString & remove(int position, int n)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void push(const T &t)
void setAutoReset(bool reset)
KStandardDirs * dirs()
KIOCORE_EXPORT SimpleJob * rmdir(const QUrl &url)
int rename(const QString &in, const QString &out)
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
void setMaximum(int maximum)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 04:12:25 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.