#include "wx/cmdproc.h"
#include "wx/tokenzr.h"
#include "wx/filename.h"
+#include "wx/stdpaths.h"
#include "wx/vector.h"
+#include "wx/ptr_scpd.h"
#if wxUSE_STD_IOSTREAM
#include "wx/ioswrap.h"
wxString FindExtension(const wxString& path)
{
wxString ext;
- wxSplitPath(path, NULL, NULL, &ext);
+ wxFileName::SplitPath(path, NULL, NULL, &ext);
// VZ: extensions are considered not case sensitive - is this really a good
// idea?
bool wxDocument::Save()
{
- if (!IsModified() && m_savedYet)
+ if ( AlreadySaved() )
return true;
if ( m_documentFile.empty() || !m_savedYet )
wxString filter = docTemplate->GetFileFilter() ;
#endif
wxString defaultDir = docTemplate->GetDirectory();
- if (defaultDir.IsEmpty())
+ if ( defaultDir.empty() )
+ {
defaultDir = wxPathOnly(GetFilename());
+ if ( defaultDir.empty() )
+ defaultDir = GetDocumentManager()->GetLastDirectory();
+ }
- wxString tmp = wxFileSelector(_("Save As"),
+ wxString fileName = wxFileSelector(_("Save As"),
defaultDir,
wxFileNameFromPath(GetFilename()),
docTemplate->GetDefaultExtension(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
GetDocumentWindow());
- if (tmp.empty())
+ if (fileName.empty())
return false;
- wxString fileName(tmp);
- wxString path, name, ext;
- wxSplitPath(fileName, & path, & name, & ext);
+ wxString ext;
+ wxFileName::SplitPath(fileName, NULL, NULL, &ext);
if (ext.empty())
{
fileName += docTemplate->GetDefaultExtension();
}
- SetFilename(fileName);
- SetTitle(wxFileNameFromPath(fileName));
-
- // Notify the views that the filename has changed
- wxList::compatibility_iterator node = m_documentViews.GetFirst();
- while (node)
- {
- wxView *view = (wxView *)node->GetData();
- view->OnChangeFilename();
- node = node->GetNext();
- }
-
// Files that were not saved correctly are not added to the FileHistory.
- if (!OnSaveDocument(m_documentFile))
+ if (!OnSaveDocument(fileName))
return false;
+ SetTitle(wxFileNameFromPath(fileName));
+ SetFilename(fileName, true); // will call OnChangeFileName automatically
+
// A file that doesn't use the default extension of its document template cannot be opened
// via the FileHistory, so we do not add it.
if (docTemplate->FileMatchesTemplate(fileName))
(
wxString::Format
(
- _("Do you want to save changes to document %s?"),
+ _("Do you want to save changes to %s?"),
GetUserReadableName()
),
wxTheApp->GetAppDisplayName(),
- wxYES_NO | wxCANCEL | wxICON_QUESTION,
- GetDocumentWindow()
+ wxYES_NO | wxCANCEL | wxICON_QUESTION | wxCENTRE,
+ wxFindSuitableParent()
) )
{
case wxNO:
void wxDocument::SetFilename(const wxString& filename, bool notifyViews)
{
m_documentFile = filename;
+ OnChangeFilename(notifyViews);
+}
+
+void wxDocument::OnChangeFilename(bool notifyViews)
+{
if ( notifyViews )
{
// Notify the views that the filename has changed
bool wxDocument::DoSaveDocument(const wxString& file)
{
- wxString msgTitle;
- if (!wxTheApp->GetAppDisplayName().empty())
- msgTitle = wxTheApp->GetAppDisplayName();
- else
- msgTitle = wxString(_("File error"));
-
#if wxUSE_STD_IOSTREAM
wxSTD ofstream store(file.mb_str(), wxSTD ios::binary);
- if (store.fail() || store.bad())
+ if ( !store )
#else
wxFileOutputStream store(file);
- if (store.GetLastError() != wxSTREAM_NO_ERROR)
+ if ( store.GetLastError() != wxSTREAM_NO_ERROR )
#endif
{
- (void)wxMessageBox(_("Sorry, could not open this file for saving."), msgTitle, wxOK | wxICON_EXCLAMATION,
- GetDocumentWindow());
- // Saving error
+ wxLogError(_("File \"%s\" could not be opened for writing."), file);
return false;
}
+
if (!SaveObject(store))
{
- (void)wxMessageBox(_("Sorry, could not save this file."), msgTitle, wxOK | wxICON_EXCLAMATION,
- GetDocumentWindow());
- // Saving error
+ wxLogError(_("Failed to save document to the file \"%s\"."), file);
return false;
}
{
#if wxUSE_STD_IOSTREAM
wxSTD ifstream store(file.mb_str(), wxSTD ios::binary);
- if (!store.fail() && !store.bad())
+ if ( !store )
#else
wxFileInputStream store(file);
- if (store.GetLastError() == wxSTREAM_NO_ERROR)
+ if (store.GetLastError() != wxSTREAM_NO_ERROR || !store.IsOk())
#endif
{
+ wxLogError(_("File \"%s\" could not be opened for reading."), file);
+ return false;
+ }
+
#if wxUSE_STD_IOSTREAM
- LoadObject(store);
- if ( !!store || store.eof() )
+ LoadObject(store);
+ if ( !store )
#else
- int res = LoadObject(store).GetLastError();
- if ( res == wxSTREAM_NO_ERROR || res == wxSTREAM_EOF )
+ int res = LoadObject(store).GetLastError();
+ if ( res != wxSTREAM_NO_ERROR && res != wxSTREAM_EOF )
#endif
- return true;
+ {
+ wxLogError(_("Failed to read document from the file \"%s\"."), file);
+ return false;
}
- wxLogError(_("Sorry, could not open this file."));
- return false;
+ return true;
}
wxView *wxDocTemplate::CreateView(wxDocument *doc, long flags)
{
- wxView *view = DoCreateView();
- if ( view == NULL )
+ wxScopedPtr<wxView> view(DoCreateView());
+ if ( !view )
return NULL;
view->SetDocument(doc);
- if (view->OnCreate(doc, flags))
- {
- return view;
- }
- else
- {
- delete view;
+ if ( !view->OnCreate(doc, flags) )
return NULL;
- }
+
+ return view.release();
}
// The default (very primitive) format detection: check is the extension is
return true;
}
+wxString wxDocManager::GetLastDirectory() const
+{
+ // use the system-dependent default location for the document files if
+ // we're being opened for the first time
+ if ( m_lastDirectory.empty() )
+ {
+ wxDocManager * const self = const_cast<wxDocManager *>(this);
+ self->m_lastDirectory = wxStandardPaths::Get().GetAppDocumentsDir();
+ }
+
+ return m_lastDirectory;
+}
+
wxFileHistory *wxDocManager::OnCreateFileHistory()
{
return new wxFileHistory;
void wxDocManager::OnFileNew(wxCommandEvent& WXUNUSED(event))
{
- CreateDocument( wxEmptyString, wxDOC_NEW );
+ CreateNewDocument();
}
void wxDocManager::OnFileOpen(wxCommandEvent& WXUNUSED(event))
void wxDocManager::OnUpdateFileOpen(wxUpdateUIEvent& event)
{
- event.Enable( true );
+ // CreateDocument() (which is called from OnFileOpen) may succeed
+ // only when there is at least a template:
+ event.Enable( GetTemplates().GetCount()>0 );
}
void wxDocManager::OnUpdateDisableIfNoDoc(wxUpdateUIEvent& event)
void wxDocManager::OnUpdateFileNew(wxUpdateUIEvent& event)
{
- event.Enable( true );
+ // CreateDocument() (which is called from OnFileNew) may succeed
+ // only when there is at least a template:
+ event.Enable( GetTemplates().GetCount()>0 );
}
void wxDocManager::OnUpdateFileSave(wxUpdateUIEvent& event)
{
- wxDocument *doc = GetCurrentDocument();
- event.Enable( doc && doc->IsModified() );
+ wxDocument * const doc = GetCurrentDocument();
+ event.Enable( doc && !doc->AlreadySaved() );
}
void wxDocManager::OnUpdateUndo(wxUpdateUIEvent& event)
wxWindow* parent = wxFindSuitableParent();
wxString pathTmp = wxFileSelectorEx(_("Open File"),
- m_lastDirectory,
+ GetLastDirectory(),
wxEmptyString,
&FilterIndex,
descrBuf,
else
msgTitle = wxString(_("File error"));
- (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle, wxOK | wxICON_EXCLAMATION,
+ (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle, wxOK | wxICON_EXCLAMATION | wxCENTRE,
parent);
path = wxEmptyString;
return NULL;
}
- m_lastDirectory = wxPathOnly(pathTmp);
+
+ SetLastDirectory(wxPathOnly(pathTmp));
path = pathTmp;
// can only happen if the application changes the allowed templates in runtime.
(void)wxMessageBox(_("Sorry, the format for this file is unknown."),
_("Open File"),
- wxOK | wxICON_EXCLAMATION, wxFindSuitableParent());
+ wxOK | wxICON_EXCLAMATION | wxCENTRE, wxFindSuitableParent());
}
}
else
{
RemoveFileFromHistory(--numFiles);
}
- else // add a new menu item to all file menus (will be updated below)
+
+ // add a new menu item to all file menus (they will be updated below)
+ for ( wxList::compatibility_iterator node = m_fileMenus.GetFirst();
+ node;
+ node = node->GetNext() )
{
- for ( wxList::compatibility_iterator node = m_fileMenus.GetFirst();
- node;
- node = node->GetNext() )
- {
- wxMenu * const menu = (wxMenu *)node->GetData();
+ wxMenu * const menu = (wxMenu *)node->GetData();
- if ( !numFiles && menu->GetMenuItemCount() )
- menu->AppendSeparator();
+ if ( !numFiles && menu->GetMenuItemCount() )
+ menu->AppendSeparator();
- // label doesn't matter, it will be set below anyhow, but it can't
- // be empty (this is supposed to indicate a stock item)
- menu->Append(m_idBase + numFiles, " ");
- }
+ // label doesn't matter, it will be set below anyhow, but it can't
+ // be empty (this is supposed to indicate a stock item)
+ menu->Append(m_idBase + numFiles, " ");
}
-
// insert the new file in the beginning of the file history
m_fileHistory.insert(m_fileHistory.begin(), file);
numFiles++;