1818#include " propagateremotemove.h"
1919#include " ui_invalidfilenamedialog.h"
2020
21+ #include " filesystem.h"
2122#include < folder.h>
2223
2324#include < QPushButton>
@@ -84,13 +85,18 @@ InvalidFilenameDialog::InvalidFilenameDialog(AccountPtr account, Folder *folder,
8485 _ui->buttonBox ->button (QDialogButtonBox::Ok)->setEnabled (false );
8586 _ui->buttonBox ->button (QDialogButtonBox::Ok)->setText (tr (" Rename file" ));
8687
87- _ui->descriptionLabel ->setText (tr (" The file %1 could not be synced because the name contains characters which are not allowed on this system." ).arg (_originalFileName));
88- _ui->explanationLabel ->setText (tr (" The following characters are not allowed on the system: * \" | & ? , ; : \\ / ~ < >" ));
88+ _ui->descriptionLabel ->setText (tr (" The file \" %1 \" could not be synced because the name contains characters which are not allowed on this system." ).arg (_originalFileName));
89+ _ui->explanationLabel ->setText (tr (" The following characters are not allowed on the system: * \" | & ? , ; : \\ / ~ < > leading/trailing spaces " ));
8990 _ui->filenameLineEdit ->setText (filePathFileInfo.fileName ());
9091
9192 connect (_ui->buttonBox , &QDialogButtonBox::accepted, this , &QDialog::accept);
9293 connect (_ui->buttonBox , &QDialogButtonBox::rejected, this , &QDialog::reject);
9394
95+ _ui->errorLabel ->setText (
96+ tr (" Checking rename permissions..." ));
97+ _ui->buttonBox ->button (QDialogButtonBox::Ok)->setEnabled (false );
98+ _ui->filenameLineEdit ->setEnabled (false );
99+
94100 connect (_ui->filenameLineEdit , &QLineEdit::textChanged, this ,
95101 &InvalidFilenameDialog::onFilenameLineEditTextChanged);
96102
@@ -104,30 +110,88 @@ void InvalidFilenameDialog::checkIfAllowedToRename()
104110 const auto propfindJob = new PropfindJob (_account, QDir::cleanPath (_folder->remotePath () + _originalFileName));
105111 propfindJob->setProperties ({ " http://owncloud.org/ns:permissions" });
106112 connect (propfindJob, &PropfindJob::result, this , &InvalidFilenameDialog::onPropfindPermissionSuccess);
113+ connect (propfindJob, &PropfindJob::finishedWithError, this , &InvalidFilenameDialog::onPropfindPermissionError);
107114 propfindJob->start ();
108115}
109116
110- void InvalidFilenameDialog::onPropfindPermissionSuccess (const QVariantMap &values)
117+ void InvalidFilenameDialog::onCheckIfAllowedToRenameComplete (const QVariantMap &values, QNetworkReply *reply )
111118{
112- if (!values. contains ( " permissions " ) ) {
113- return ;
114- }
115- const auto remotePermissions = RemotePermissions::fromServerString (values[ " permissions " ]. toString ()) ;
116- if (!remotePermissions. hasPermission (remotePermissions. CanRename )
117- || !remotePermissions. hasPermission (remotePermissions. CanMove )) {
119+ const auto isAllowedToRename = []( const RemotePermissions remotePermissions ) {
120+ return remotePermissions. hasPermission (remotePermissions. CanRename )
121+ && remotePermissions. hasPermission (remotePermissions. CanMove );
122+ } ;
123+
124+ if (values. contains ( " permissions " ) && ! isAllowedToRename ( RemotePermissions::fromServerString (values[ " permissions " ]. toString ()) )) {
118125 _ui->errorLabel ->setText (
119126 tr (" You don't have the permission to rename this file. Please ask the author of the file to rename it." ));
120- _ui->buttonBox ->button (QDialogButtonBox::Ok)->setEnabled (false );
121- _ui->filenameLineEdit ->setEnabled (false );
127+ return ;
128+ } else if (reply) {
129+ if (reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt () != 404 ) {
130+ _ui->errorLabel ->setText (
131+ tr (" Failed to fetch permissions with error %1" ).arg (reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt ()));
132+ return ;
133+ }
122134 }
135+
136+ _ui->buttonBox ->button (QDialogButtonBox::Ok)->setEnabled (true );
137+ _ui->filenameLineEdit ->setEnabled (true );
138+ _ui->filenameLineEdit ->selectAll ();
139+
140+ const auto filePathFileInfo = QFileInfo (_filePath);
141+ const auto fileName = filePathFileInfo.fileName ();
142+ processLeadingOrTrailingSpacesError (fileName);
143+ }
144+
145+ bool InvalidFilenameDialog::processLeadingOrTrailingSpacesError (const QString &fileName)
146+ {
147+ const auto hasLeadingSpaces = fileName.startsWith (QLatin1Char (' ' ));
148+ const auto hasTrailingSpaces = fileName.endsWith (QLatin1Char (' ' ));
149+
150+ _ui->buttonBox ->setStandardButtons (_ui->buttonBox ->standardButtons () &~ QDialogButtonBox::No);
151+
152+ if (hasLeadingSpaces || hasTrailingSpaces) {
153+ if (hasLeadingSpaces && hasTrailingSpaces) {
154+ _ui->errorLabel ->setText (tr (" Filename contains leading and trailing spaces." ));
155+ }
156+ else if (hasLeadingSpaces) {
157+ _ui->errorLabel ->setText (tr (" Filename contains leading spaces." ));
158+ } else if (hasTrailingSpaces) {
159+ _ui->errorLabel ->setText (tr (" Filename contains trailing spaces." ));
160+ }
161+
162+ if (!Utility::isWindows ()) {
163+ _ui->buttonBox ->setStandardButtons (_ui->buttonBox ->standardButtons () | QDialogButtonBox::No);
164+ _ui->buttonBox ->button (QDialogButtonBox::No)->setText (tr (" Use invalid name" ));
165+ connect (_ui->buttonBox ->button (QDialogButtonBox::No), &QPushButton::clicked, this , &InvalidFilenameDialog::useInvalidName);
166+ }
167+
168+ return true ;
169+ }
170+
171+ return false ;
172+ }
173+
174+ void InvalidFilenameDialog::onPropfindPermissionSuccess (const QVariantMap &values)
175+ {
176+ onCheckIfAllowedToRenameComplete (values);
177+ }
178+
179+ void InvalidFilenameDialog::onPropfindPermissionError (QNetworkReply *reply)
180+ {
181+ onCheckIfAllowedToRenameComplete ({}, reply);
182+ }
183+
184+ void InvalidFilenameDialog::useInvalidName ()
185+ {
186+ emit acceptedInvalidName (_filePath);
123187}
124188
125189void InvalidFilenameDialog::accept ()
126190{
127191 _newFilename = _relativeFilePath + _ui->filenameLineEdit ->text ().trimmed ();
128192 const auto propfindJob = new PropfindJob (_account, QDir::cleanPath (_folder->remotePath () + _newFilename));
129- connect (propfindJob, &PropfindJob::result, this , &InvalidFilenameDialog::onRemoteFileAlreadyExists );
130- connect (propfindJob, &PropfindJob::finishedWithError, this , &InvalidFilenameDialog::onRemoteFileDoesNotExist );
193+ connect (propfindJob, &PropfindJob::result, this , &InvalidFilenameDialog::onRemoteDestinationFileAlreadyExists );
194+ connect (propfindJob, &PropfindJob::finishedWithError, this , &InvalidFilenameDialog::onRemoteDestinationFileDoesNotExist );
131195 propfindJob->start ();
132196}
133197
@@ -138,11 +202,10 @@ void InvalidFilenameDialog::onFilenameLineEditTextChanged(const QString &text)
138202 const auto containsIllegalChars = !illegalContainedCharacters.empty () || text.endsWith (QLatin1Char (' .' ));
139203 const auto isTextValid = isNewFileNameDifferent && !containsIllegalChars;
140204
141- if (isTextValid) {
142- _ui->errorLabel ->setText (" " );
143- } else {
144- _ui->errorLabel ->setText (tr (" Filename contains illegal characters: %1" )
145- .arg (illegalCharacterListToString (illegalContainedCharacters)));
205+ _ui->errorLabel ->setText (" " );
206+
207+ if (!processLeadingOrTrailingSpacesError (text) && !isTextValid){
208+ _ui->errorLabel ->setText (tr (" Filename contains illegal characters: %1" ).arg (illegalCharacterListToString (illegalContainedCharacters)));
146209 }
147210
148211 _ui->buttonBox ->button (QDialogButtonBox::Ok)
@@ -162,23 +225,49 @@ void InvalidFilenameDialog::onMoveJobFinished()
162225 QDialog::accept ();
163226}
164227
165- void InvalidFilenameDialog::onRemoteFileAlreadyExists (const QVariantMap &values)
228+ void InvalidFilenameDialog::onRemoteDestinationFileAlreadyExists (const QVariantMap &values)
166229{
167230 Q_UNUSED (values);
168231
169232 _ui->errorLabel ->setText (tr (" Cannot rename file because a file with the same name does already exist on the server. Please pick another name." ));
170233 _ui->buttonBox ->button (QDialogButtonBox::Ok)->setEnabled (false );
171234}
172235
173- void InvalidFilenameDialog::onRemoteFileDoesNotExist (QNetworkReply *reply)
236+ void InvalidFilenameDialog::onRemoteDestinationFileDoesNotExist (QNetworkReply *reply)
174237{
175238 Q_UNUSED (reply);
176239
177- // File does not exist. We can rename it.
240+ const auto propfindJob = new PropfindJob (_account, QDir::cleanPath (_folder->remotePath () + _originalFileName));
241+ connect (propfindJob, &PropfindJob::result, this , &InvalidFilenameDialog::onRemoteSourceFileAlreadyExists);
242+ connect (propfindJob, &PropfindJob::finishedWithError, this , &InvalidFilenameDialog::onRemoteSourceFileDoesNotExist);
243+ propfindJob->start ();
244+ }
245+
246+ void InvalidFilenameDialog::onRemoteSourceFileAlreadyExists (const QVariantMap &values)
247+ {
248+ Q_UNUSED (values);
249+
250+ // Remote source file exists. We need to start MoveJob to rename it
178251 const auto remoteSource = QDir::cleanPath (_folder->remotePath () + _originalFileName);
179252 const auto remoteDestionation = QDir::cleanPath (_account->davUrl ().path () + _folder->remotePath () + _newFilename);
180253 const auto moveJob = new MoveJob (_account, remoteSource, remoteDestionation, this );
181254 connect (moveJob, &MoveJob::finishedSignal, this , &InvalidFilenameDialog::onMoveJobFinished);
182255 moveJob->start ();
183256}
257+
258+ void InvalidFilenameDialog::onRemoteSourceFileDoesNotExist (QNetworkReply *reply)
259+ {
260+ Q_UNUSED (reply);
261+
262+ // It's a new file we've just created locally. We will attempt to rename it locally.
263+ const auto localSource = QDir::cleanPath (_folder->path () + _originalFileName);
264+ const auto localDestionation = QDir::cleanPath (_folder->path ()+ _newFilename);
265+
266+ QString error;
267+ if (!FileSystem::rename (localSource, localDestionation, &error)) {
268+ _ui->errorLabel ->setText (tr (" Could not rename local file. %1" ).arg (error));
269+ return ;
270+ }
271+ QDialog::accept ();
272+ }
184273}
0 commit comments