Prevent component library editor from saving read only files (fixes lp:811118)

* Disable save library command when user does not have permission to write
  the active library.
* Append the active library file name displayed in the title bar with read
  only when the user does not have write permission.
* Test the selected folder permissions when user chooses the save library
  as command.
* The obligatory coding style policy fixes.
This commit is contained in:
Wayne Stambaugh 2011-08-12 13:43:16 -04:00
parent 58a3504c5a
commit e7eef8cf7b
4 changed files with 162 additions and 135 deletions

View File

@ -1,5 +1,5 @@
/*********************************************/
/* Headers for component library definition */
/* Headers for component library definition */
/*********************************************/
#ifndef CLASS_LIBRARY_H
@ -163,7 +163,13 @@ public:
void SetCache( void ) { isCache = true; }
/**
/**
* Function IsReadOnly
* @return true if current user does not have write access to the library file.
*/
bool IsReadOnly() const { return !fileName.IsFileWritable(); }
/**
* Load a string array with the names of all the entries in this library.
*
* @param aNames - String array to place entry names into.
@ -171,7 +177,7 @@ public:
* @param aMakeUpperCase - Force entry names to upper case.
*/
void GetEntryNames( wxArrayString& aNames, bool aSort = true,
bool aMakeUpperCase =
bool aMakeUpperCase =
#ifndef KICAD_KEEPCASE
true
#else

View File

@ -22,7 +22,6 @@
#include "dialogs/dialog_lib_new_component.h"
/* Update the main window title bar with the current library name. */
void LIB_EDIT_FRAME::DisplayLibInfos()
{
wxString msg = _( "Component Library Editor: " );
@ -30,33 +29,35 @@ void LIB_EDIT_FRAME::DisplayLibInfos()
EnsureActiveLibExists();
if( m_library )
{
msg += m_library->GetFullFileName();
if( m_library->IsReadOnly() )
msg += _( " [Read Only]" );
}
else
{
msg += _( "no library selected" );
}
SetTitle( msg );
}
/* Function to select the current library (working library) */
void LIB_EDIT_FRAME::SelectActiveLibrary( CMP_LIBRARY* aLibrary )
{
if( aLibrary == NULL )
aLibrary = SelectLibraryFromList( this );
if( aLibrary )
{
m_library = aLibrary;
}
DisplayLibInfos();
}
/*
* function LoadComponentAndSelectLib
* Select the current active library.
* aLibrary = the CMP_LIBRARY aLibrary to select
* aLibEntry = the lib component to load from aLibrary (can be an alias
* return true if OK.
*/
bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary )
{
if( GetScreen()->IsModify()
@ -68,12 +69,6 @@ bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRAR
}
/**
* function LoadComponentFromCurrentLib
* load a lib component from the current active library.
* @param aLibEntry = the lib component to load from aLibrary (can be an alias
* @return true if OK.
*/
bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry )
{
if( !LoadOneLibraryPartAux( aLibEntry, m_library ) )
@ -91,13 +86,7 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry )
return true;
}
/**
* Function LoadOneLibraryPart
* load a library component from the current selected library
* Prompt user for component name
* If there is no current selected library,
* prompt user for library name and make the selected library the current lib.
*/
void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event )
{
int i;
@ -115,11 +104,13 @@ void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event )
if( m_library == NULL )
{
SelectActiveLibrary();
if( m_library == NULL )
return;
}
i = GetNameOfPartToLoad( this, m_library, CmpName );
if( i == 0 )
return;
@ -150,13 +141,6 @@ void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event )
}
/*
* Routine to load into memory a copy of 1 library part.
* Returns
* 0 if OK
* 1 if error
* m_component advanced copy and created
*/
bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLibrary )
{
wxString msg, cmpName, rootName;
@ -222,7 +206,6 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLib
}
/* Function to redraw the current loaded library component */
void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
{
if( GetScreen() == NULL )
@ -254,10 +237,6 @@ void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
}
/*
* Save (on disk) the current library
* if exists the old file is renamed (.bak)
*/
void LIB_EDIT_FRAME::SaveActiveLibrary( wxCommandEvent& event )
{
wxFileName fn;
@ -265,18 +244,18 @@ void LIB_EDIT_FRAME::SaveActiveLibrary( wxCommandEvent& event )
DrawPanel->EndMouseCapture( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor() );
if( m_library == NULL )
{
DisplayError( this, _( "No library specified." ) );
return;
}
if( GetScreen()->IsModify() )
{
if( IsOK( this, _( "Include last component changes?" ) ) )
SaveOnePartInMemory();
}
if( m_library == NULL )
{
DisplayError( this, wxT( "No library specified." ) );
return;
}
if( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS )
{ // Get a new name for the library
wxString default_path = wxGetApp().ReturnLastVisitedLibraryPath();
@ -292,7 +271,7 @@ void LIB_EDIT_FRAME::SaveActiveLibrary( wxCommandEvent& event )
/* The GTK file chooser doesn't return the file extension added to
* file name so add it here. */
if( fn.GetExt().IsEmpty() )
fn.SetExt( SymbolFileExtension );
fn.SetExt( CompLibFileExtension );
wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() );
}
@ -306,6 +285,15 @@ void LIB_EDIT_FRAME::SaveActiveLibrary( wxCommandEvent& event )
return;
}
// Verify the user has write privileges before attempting to save the library file.
if( !fn.IsDirWritable() )
{
DisplayError( this,
wxString::Format( _( "You do not have permission to write to file <%s>." ),
GetChars( fn.GetFullPath() ) ) );
return;
}
bool success = m_library->Save( fn.GetFullPath(), true );
ClearMsgPanel();
@ -326,11 +314,6 @@ void LIB_EDIT_FRAME::SaveActiveLibrary( wxCommandEvent& event )
}
/*
* Display the documentation of the selected component.
*
* Used when displaying the list of library components.
*/
void LIB_EDIT_FRAME::DisplayCmpDoc()
{
wxString msg;
@ -380,20 +363,6 @@ void LIB_EDIT_FRAME::DisplayCmpDoc()
}
/*
* Delete component in the current library.
*
* (Delete only in memory, the file does not change)
*
* The entry can be an alias or a component.
* If an alias:
* It is removed, and the list of alias is updated.
*
* If a component:
* If the list of aliases is zero, it deletes the component
* Otherwise the alias becomes the new component name, and the other
* aliases become dependent on newly named component.
*/
void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event )
{
wxString CmpName;
@ -486,11 +455,6 @@ All changes will be lost. Discard changes?" ) ) )
/*
* Routine to create a new library component
*
* If an old component is currently in edit, it is deleted.
*/
void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event )
{
wxString name;
@ -537,14 +501,17 @@ lost!\n\nClear the current component from the screen?" ) ) )
LIB_COMPONENT* component = new LIB_COMPONENT( name );
component->GetReferenceField().m_Text = dlg.GetReference();
component->SetPartCount( dlg.GetPartCount() );
// Initialize component->m_TextInside member:
// if 0, pin text is outside the body (on the pin)
// if > 0, pin text is inside the body
component->SetConversion( dlg.GetAlternateBodyStyle() );
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
if( dlg.GetPinNameInside( ) )
if( dlg.GetPinNameInside() )
{
component->SetPinNameOffset( dlg.GetPinTextPosition() );
if( component->GetPinNameOffset() == 0 )
component->SetPinNameOffset( 1 );
}
@ -557,6 +524,7 @@ lost!\n\nClear the current component from the screen?" ) ) )
component->SetShowPinNumbers( dlg.GetShowPinNumber() );
component->SetShowPinNames( dlg.GetShowPinName() );
component->LockUnits( dlg.GetLockItems() );
if( dlg.GetPartCount() < 2 )
component->LockUnits( false );
@ -580,19 +548,12 @@ lost!\n\nClear the current component from the screen?" ) ) )
m_HToolBar->ToggleTool( ID_LIBEDIT_EDIT_PIN_BY_PIN, g_EditPinByPinIsOn );
m_lastDrawItem = NULL;
GetScreen()->ClearUndoRedoList();
OnModify( );
OnModify();
DrawPanel->Refresh();
m_HToolBar->Refresh();
}
/*
* Routine backup of "partlib" current in the current library.
*
* Save in memory only and NOT on file.
* The routine deletes the old component (and / or aliases) to replace
* If any, and saves the new and creates the corresponding alias.
*/
void LIB_EDIT_FRAME::SaveOnePartInMemory()
{
LIB_COMPONENT* oldComponent;

View File

@ -267,12 +267,6 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
}
/**
* Load library editor frame specific configuration settings.
*
* Don't forget to call this base method from any derived classes or the
* settings will not get loaded.
*/
void LIB_EDIT_FRAME::LoadSettings()
{
wxConfig* cfg;
@ -293,12 +287,7 @@ void LIB_EDIT_FRAME::SetDrawItem( LIB_ITEM* drawItem )
}
/**
* Save library editor frame specific configuration settings.
*
* Don't forget to call this base method from any derived classes or the
* settings will not get saved.
*/
void LIB_EDIT_FRAME::SaveSettings()
{
wxConfig* cfg;
@ -469,7 +458,8 @@ void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event )
{
event.Enable( m_library != NULL && ( m_library->IsModified() || GetScreen()->IsModify() ) );
event.Enable( m_library != NULL && !m_library->IsReadOnly()
&& ( m_library->IsModified() || GetScreen()->IsModify() ) );
}
@ -874,11 +864,6 @@ void LIB_EDIT_FRAME::SetLanguage( wxCommandEvent& event )
}
/**
* Function TempCopyComponent
* create a temporary copy of the current edited component
* Used to prepare an Undo ant/or abort command before editing the component
*/
void LIB_EDIT_FRAME::TempCopyComponent()
{
if( m_tempCopyComponent )
@ -890,11 +875,7 @@ void LIB_EDIT_FRAME::TempCopyComponent()
m_tempCopyComponent = new LIB_COMPONENT( *m_component );
}
/**
* Function RestoreComponent
* Restore the current edited component from its temporary copy.
* Used to abort a command
*/
void LIB_EDIT_FRAME::RestoreComponent()
{
if( m_tempCopyComponent == NULL )
@ -907,10 +888,7 @@ void LIB_EDIT_FRAME::RestoreComponent()
m_tempCopyComponent = NULL;
}
/**
* Function ClearTempCopyComponent
* delete temporary copy of the current component and clear pointer
*/
void LIB_EDIT_FRAME::ClearTempCopyComponent()
{
delete m_tempCopyComponent;
@ -918,8 +896,6 @@ void LIB_EDIT_FRAME::ClearTempCopyComponent()
}
/* Creates the SVG print file for the current edited component.
*/
void LIB_EDIT_FRAME::SVG_Print_Component( const wxString& FullFileName )
{
DIALOG_SVG_PRINT::DrawSVGPage( this, FullFileName, GetScreen() );

View File

@ -68,12 +68,44 @@ public:
void OnExportPart( wxCommandEvent& event );
void OnSelectAlias( wxCommandEvent& event );
void OnSelectPart( wxCommandEvent& event );
void DeleteOnePart( wxCommandEvent& event );
void CreateNewLibraryPart( wxCommandEvent& event );
/**
* Function DeleteOnePart
* is the command event handler to delete an entry from the current library.
*
* The deleted entry can be an alias or a component. If the entry is an alias,
* it is removed from the component and the list of alias is updated. If the
* entry is a component and the list of aliases is empty, the component and all
* it drawable items are deleted. Otherwise the first alias in the alias list
* becomes the new component name and the other aliases become dependent on
* renamed component.
*
* @note This only deletes the entry in memory. The file does not change.
*/
void DeleteOnePart( wxCommandEvent& event );
/**
* Function CreateNewLibraryPart
* is the command event handler to create a new library component.
*
* If an old component is currently in edit, it is deleted.
*/
void CreateNewLibraryPart( wxCommandEvent& event );
void OnCreateNewPartFromExisting( wxCommandEvent& event );
void OnEditComponentProperties( wxCommandEvent& event );
void InstallFieldsEditorDialog( wxCommandEvent& event );
void LoadOneLibraryPart( wxCommandEvent& event );
/**
* Function LoadOneLibraryPart
* loads a library component from the currently selected library.
*
* If a library is already selected, the user is prompted for the component name
* to load. If there is no current selected library, the user is prompted to select
* a library name and then select component to load.
*/
void LoadOneLibraryPart( wxCommandEvent& event );
void OnViewEntryDoc( wxCommandEvent& event );
void OnCheckComponent( wxCommandEvent& event );
void OnSelectBodyStyle( wxCommandEvent& event );
@ -95,7 +127,14 @@ public:
void UpdateAliasSelectList();
void UpdatePartSelectList();
void DisplayLibInfos();
/**
* Function DisplayLibInfos
* updates the main window title bar with the current library name and read only status
* of the library.
*/
void DisplayLibInfos();
void RedrawActiveWindow( wxDC* DC, bool EraseBg );
void OnCloseWindow( wxCloseEvent& Event );
void ReCreateHToolbar();
@ -112,8 +151,23 @@ public:
void GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
void LoadSettings();
void SaveSettings();
/**
* Function LoadSettings
* loads the library editor frame specific configuration settings.
*
* Don't forget to call this method from any derived classes or the settings will not
* get loaded.
*/
void LoadSettings();
/**
* Function SaveSettings
* saves the library editor frame specific configuration settings.
*
* Don't forget to call this base method from any derived classes or the settings will
* not get saved.
*/
void SaveSettings();
/**
* Function CloseWindow
@ -221,29 +275,58 @@ private:
virtual void OnActivate( wxActivateEvent& event );
// General:
void SaveOnePartInMemory();
/**
* function SelectActiveLibrary
* Select the current active library.
* @param aLibrary = the CMP_LIBRARY aLibrary to select, or NULL
* to select from a list
* Function SaveOnePartInMemory
* updates the current component being edited in the active library.
*
* Any changes are updated in memory only and NOT to a file. The old component is
* deleted from the library and/or any aliases before the edited component is updated
* in the library.
*/
void SelectActiveLibrary( CMP_LIBRARY* aLibrary = NULL);
void SaveActiveLibrary( wxCommandEvent& event );
void SaveOnePartInMemory();
/**
* function LoadComponentFromCurrentLib
* load a lib component from the current active library.
* @param aLibEntry = the lib component to load from aLibrary (can be an alias
* @return true if OK.
* Function SelectActiveLibrary
* sets the current active library to \a aLibrary.
*
* @param aLibrary A pointer to the CMP_LIBRARY object to select. If NULL, then display
* list of available libraries to select from.
*/
bool LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry );
void SelectActiveLibrary( CMP_LIBRARY* aLibrary = NULL );
bool LoadOneLibraryPartAux( LIB_ALIAS* LibEntry, CMP_LIBRARY* Library );
/**
* Function SaveActiveLibrary
* it the command event handler to save the changes to the current library.
*
* A backup file of the current library is saved with the .bak extension before the
* changes made to the library are saved.
*/
void SaveActiveLibrary( wxCommandEvent& event );
void DisplayCmpDoc();
/**
* Function LoadComponentFromCurrentLib
* loads a component from the current active library.
* @param aLibEntry The component to load from \a aLibrary (can be an alias)
* @return true if \a aLibEntry loaded correctly.
*/
bool LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry );
/**
* Function LoadOneLibraryPartAux
* loads a copy of \a aLibEntry from \a aLibrary into memory.
*
* @param aLibEntry A pointer to the LIB_ALIAS object to load.
* @param aLibrary A pointer to the CMP_LIBRARY object to load \a aLibEntry from.
* @returns True if a copy of \aLibEntry was successfully loaded from \aLibrary.
*/
bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary );
/**
* Function DisplayCmpDoc
* displays the documentation of the selected component.
*/
void DisplayCmpDoc();
/**
* Function OnRotateItem
@ -289,13 +372,14 @@ private:
public:
/**
* function LoadComponentAndSelectLib
* Select the current active library.
* @param aLibrary = the CMP_LIBRARY aLibrary to select
* @param aLibEntry = the lib component to load from aLibrary (can be an alias
* @return true if OK.
* Function LoadComponentAndSelectLib
* selects the current active library.
*
* @param aLibrary The CMP_LIBRARY to select
* @param aLibEntry The component to load from aLibrary (can be an alias).
* @return true if \a aLibEntry was loaded from \a aLibrary.
*/
bool LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary );
bool LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary );
/* Block commands: */
virtual int ReturnBlockCommand( int aKey );
@ -330,7 +414,7 @@ protected:
/** Default line width for drawing or editing graphic items. */
static int m_drawLineWidth;
/** The current active libary. NULL if no active library is selected. */
/** The current active library. NULL if no active library is selected. */
static CMP_LIBRARY* m_library;
/** The current component being edited. NULL if no component is selected. */
static LIB_COMPONENT* m_component;
@ -386,7 +470,7 @@ protected:
* Function SVG_Print_Component
* Creates the SVG print file for the current edited component.
* @param aFullFileName = the full filename of the file
*/
*/
void SVG_Print_Component( const wxString& aFullFileName );