Use move to trash to the project manager instead of immediate delete

CHANGED: Delete in the project manager now moves files to the trash can

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2499
This commit is contained in:
Ian McInerney 2020-01-30 01:31:45 +00:00 committed by Ian McInerney
parent 56a531109a
commit a0d84e94fd
8 changed files with 200 additions and 90 deletions

View File

@ -369,67 +369,3 @@ wxString QuoteFullPath( wxFileName& fn, wxPathFormat format )
{ {
return wxT( "\"" ) + fn.GetFullPath( format ) + wxT( "\"" ); return wxT( "\"" ) + fn.GetFullPath( format ) + wxT( "\"" );
} }
bool DeleteDirectory( const wxString& aDirName, bool aRecurse, bool aIncludeHidden )
{
int hiddenFlag = ( aIncludeHidden ? wxDIR_HIDDEN : 0 );
wxDir mainDir( aDirName );
if( !mainDir.IsOpened() )
return false;
if( mainDir.HasSubDirs() && !aRecurse )
{
mainDir.Close();
return false;
}
// Get the name from wxWidgets so that we are sure all the separators are correct
wxString fullDirName = mainDir.GetNameWithSep();
wxString dir;
bool valid = mainDir.GetFirst( &dir, wxEmptyString, wxDIR_DIRS | hiddenFlag );
// Iterate over the subdirectories to recursively delete them and their contents
while( valid )
{
dir.Prepend( fullDirName );
// This call will also delete the actual directory, so we don't have to
if( !DeleteDirectory( dir, true, aIncludeHidden ) )
{
mainDir.Close();
return false;
}
valid = mainDir.GetNext( &dir );
}
wxString file;
valid = mainDir.GetFirst( &file, wxEmptyString, wxDIR_FILES | hiddenFlag );
// Iterate over the files to remove all of them from the directory
while( valid )
{
file.Prepend( fullDirName );
if( !wxRemoveFile( file ) )
{
mainDir.Close();
return false;
}
valid = mainDir.GetNext( &file );
}
mainDir.Close();
// Now delete the actual directory
if( !wxRmdir( aDirName ) )
{
mainDir.Close();
return false;
}
return true;
}

View File

@ -152,21 +152,4 @@ wxString FindKicadFile( const wxString& shortname );
*/ */
extern wxString QuoteFullPath( wxFileName& fn, wxPathFormat format = wxPATH_NATIVE ); extern wxString QuoteFullPath( wxFileName& fn, wxPathFormat format = wxPATH_NATIVE );
/**
* Delete a directory and all of its contents recursively.
* This function ensures that all contents of subdirectories are deleted before deleting
* the directory. If recursion is disabled, then the existence of subdirectories will
* cause the deletion to fail and the function to return false.
*
* Note that if hidden files/folders exist in the directory, and aIncludeHidden is false,
* then the directory may not be deleted.
*
* @param aRecurse specifies if subdirectories should also be deleted
* @param aIncludeHidden specifies if hidden files/directories should be deleted as well
* @return true if the directory could be deleted
*
*/
bool DeleteDirectory( const wxString& aDirName, bool aRecurse = true, bool aIncludeHidden = true );
#endif /* __INCLUDE__GESTFICH_H__ */ #endif /* __INCLUDE__GESTFICH_H__ */

View File

@ -31,10 +31,13 @@
#include <wx/regex.h> #include <wx/regex.h>
#include <confirm.h>
#include <gestfich.h> #include <gestfich.h>
#include <kiplatform/environment.h>
#include <kiway.h> #include <kiway.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/kicad_manager_actions.h> #include <tools/kicad_manager_actions.h>
#include "treeprojectfiles.h" #include "treeprojectfiles.h"
#include "pgm_kicad.h" #include "pgm_kicad.h"
#include "tree_project_frame.h" #include "tree_project_frame.h"
@ -126,16 +129,16 @@ bool TREEPROJECT_ITEM::Rename( const wxString& name, bool check )
void TREEPROJECT_ITEM::Delete() void TREEPROJECT_ITEM::Delete()
{ {
bool isDirectory = wxDirExists( GetFileName() ); wxString errMsg;
bool success;
if( !isDirectory ) if( !KIPLATFORM::ENV::MoveToTrash( GetFileName(), errMsg ) )
success = wxRemoveFile( GetFileName() ); {
else wxString dialogMsg = wxString::Format( _( "Failed to delete '%s'"), GetFileName() );
success = DeleteDirectory( GetFileName() ); DisplayErrorMessage( m_parent, dialogMsg, errMsg );
return;
}
if( success ) m_parent->Delete( GetId() );
m_parent->Delete( GetId() );
} }

View File

@ -1,8 +1,8 @@
# Add the appropriate source files # Add the appropriate source files
if( APPLE ) if( APPLE )
set( PLATFORM_SRCS set( PLATFORM_SRCS
osx/app.mm osx/app.mm
osx/environment.mm
osx/ui.mm osx/ui.mm
) )
@ -15,13 +15,27 @@ if( APPLE )
elseif( WIN32 ) elseif( WIN32 )
set( PLATFORM_SRCS set( PLATFORM_SRCS
msw/app.cpp msw/app.cpp
msw/environment.cpp
msw/ui.cpp msw/ui.cpp
) )
elseif( UNIX ) elseif( UNIX )
set( PLATFORM_SRCS set( PLATFORM_SRCS
gtk/app.cpp gtk/app.cpp
gtk/environment.cpp
gtk/ui.cpp gtk/ui.cpp
) )
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
# Detect GTK3 and configure it
set( PLATFORM_LIBS
${GTK3_LIBRARIES}
)
include_directories( SYSTEM ${GTK3_INCLUDE_DIRS} )
link_directories( ${GTK3_LIBRARY_DIRS} )
add_definitions( ${GTK3_CFLAGS_OTHER} )
endif() endif()

View File

@ -0,0 +1,40 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gio/gio.h>
#include <kiplatform/environment.h>
bool KIPLATFORM::ENV::MoveToTrash( const wxString& aPath, wxString& aError )
{
GError* err = nullptr;
GFile* file = g_file_new_for_path( aPath.fn_str() );
bool retVal = g_file_trash( file, NULL, &err );
// Extract the error string if the operation failed
if( !retVal && err )
aError = err->message;
g_clear_error( &err );
g_object_unref( file );
return retVal;
}

View File

@ -0,0 +1,37 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wx/string.h>
namespace KIPLATFORM
{
namespace ENV
{
/**
* Move the specified file/directory to the trash bin/recycle bin.
*
* @param aPath is the absolute path of the file/directory to move to the trash
* @param aError is the error message saying why the operation failed
*
* @return true if the operation succeeds, false if it fails (see the contents of aError)
*/
bool MoveToTrash( const wxString& aPath, wxString& aError );
}
}

View File

@ -0,0 +1,51 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <kiplatform/environment.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <Windows.h>
#include <shellapi.h>
bool KIPLATFORM::ENV::MoveToTrash( const wxString& aPath, wxString& aError )
{
// The filename field must be a double-null terminated string
wxString temp = aPath + '\0';
SHFILEOPSTRUCT fileOp;
::ZeroMemory( &fileOp, sizeof( fileOp ) );
fileOp.hwnd = NULL; // Set to null since there is no progress dialog
fileOp.wFunc = FO_DELETE;
fileOp.pFrom = temp.c_str();
fileOp.pTo = NULL; // Set to to NULL since we aren't moving the file
fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
int eVal = SHFileOperation( &fileOp );
if( eVal != 0 )
{
aError = wxString::Format( _( "Error code: %d" ), eVal );
return false;
}
return true;
}

View File

@ -0,0 +1,46 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <kiplatform/environment.h>
#import <Cocoa/Cocoa.h>
#include <wx/osx/core/cfstring.h>
bool KIPLATFORM::ENV::MoveToTrash( const wxString& aPath, wxString& aError )
{
wxString temp = "file:///" + aPath;
NSURL* url = [NSURL URLWithString:wxCFStringRef( temp ).AsNSString()];
NSError* err = NULL;
BOOL result = [[NSFileManager defaultManager] trashItemAtURL:url resultingItemURL:nil error:&err];
// Extract the error string if the operation failed
if( result == NO )
{
NSString* errmsg;
errmsg = [err.localizedFailureReason stringByAppendingFormat:@"\n\n%@", err.localizedRecoverySuggestion];
aError = wxCFStringRef::AsString( (CFStringRef) errmsg );
return false;
}
return true;
}