void TagsDatabase::OpenDatabase(const wxFileName& fileName)
{
	if(m_fileName == fileName)
		return;

	// Did we get a file name to use?
	if(!fileName.IsOk() && !m_fileName.IsOk())
		return;

	// We did not get any file name to use BUT we
	// do have an open database, so we will use it
	if(!fileName.IsOk())
		return;

	if(!m_fileName.IsOk())
	{
		// First time we open the db
		m_db->Open(fileName.GetFullPath());
		CreateSchema();
		m_fileName = fileName;
	}
	else
	{
		// We have both fileName & m_fileName and they 
		// are different, Close previous db
		m_db->Close();
		m_db->Open(fileName.GetFullPath());
		CreateSchema();
		m_fileName = fileName;
	}
}
Exemplo n.º 2
0
const wxExVCSEntry wxExVCS::FindEntry(const wxFileName& filename)
{
  const int vcs = wxConfigBase::Get()->ReadLong("VCS", VCS_AUTO);

  if (vcs == VCS_AUTO)
  {
    if (filename.IsOk())
    {
      for (
        auto it = m_Entries.begin();
        it != m_Entries.end();
        ++it)
      {
        const bool toplevel = it->AdminDirIsTopLevel();
        const wxString admin_dir = it->GetAdminDir();

        if (toplevel && IsAdminDirTopLevel(admin_dir, filename))
        {
          return *it;
        }
        else if (IsAdminDir(admin_dir, filename))
        {
          return *it;
        }
      }
    }
  }
  else if (vcs >= VCS_START && vcs < m_Entries.size())
  {
    return m_Entries[vcs];
  }
  
  return wxExVCSEntry();
}
Exemplo n.º 3
0
wxString eDocumentPath::WinPathToCygwin(const wxFileName& path) { 
	wxASSERT(path.IsOk() && path.IsAbsolute());

#ifndef __WXMSW__
    return path.GetFullPath();
#else
    wxString fullpath = path.GetFullPath();

	// Check if we have a foward-slash unc path; cygwin can handle these directly.
	if (fullpath.StartsWith(wxT("//"))) {
		return fullpath;
	}
	
	// Check if we have a backslash unc path; convert to forward slash and pass on.
	if (fullpath.StartsWith(wxT("\\\\"))) {
		fullpath.Replace(wxT("\\"), wxT("/"));
		return fullpath;
	}

	// Convert C:\... to /cygdrive/c/...
	wxString unixPath = eDocumentPath::s_cygdrivePrefix + path.GetVolume().Lower();

	// Convert slashs in path segments
	const wxArrayString& dirs = path.GetDirs();
	for (unsigned int i = 0; i < dirs.GetCount(); ++i) {
		unixPath += wxT('/') + dirs[i];
	}

	// Add the filename, if there is one
	if (path.HasName()) unixPath += wxT('/') + path.GetFullName();

	return unixPath;
#endif
}
Exemplo n.º 4
0
bool FSOExecutable::HasFSOExecutables(const wxFileName& path) {
	wxCHECK_MSG(path.IsOk(), false,
		wxString::Format(_T("provided path %s to HasFSOExecutables is invalid"),
			path.GetFullPath().c_str()));
	
	return !FSOExecutable::GetBinariesFromRootFolder(path, true).IsEmpty(); 
}
Exemplo n.º 5
0
/*
        This routine is platform-independent.

        MMEX is a portable application which means ability to to run
        without installation, for example, from USB flash drive.

        If mmex finds mmexini.db3 in its folder, it assumes portable
        mode and GetUserDir() in such case points to that folder.

        FIXME: security issue - temp files will be created on host filesystem.
*/
const wxFileName mmex::GetUserDir(bool create)
{
    static wxFileName fname;

    if (!fname.IsOk())
    {
        fname = getSettingsPathPortable();

        bool portable_file_ok = fname.IsFileWritable() && fname.IsFileReadable();

        if (!portable_file_ok)
        {
            fname.AssignDir(wxStandardPaths::Get().GetUserDataDir());

            if (create && !fname.DirExists())
            {
                portable_file_ok = fname.Mkdir(0700, wxPATH_MKDIR_FULL); // 0700 - octal, "111 000 000"
                wxASSERT(portable_file_ok);
            }
        }

        fname.SetFullName(wxGetEmptyString());
    }

    return fname;
}
Exemplo n.º 6
0
bool wxExVCS::IsAdminDirTopLevel(
  const wxString& admin_dir, 
  const wxFileName& fn)
{
  if (!fn.IsOk() || admin_dir.empty())
  {
    return false;
  }
  
  // The .git dir only exists in the root, so check all components.
  wxFileName root(fn);

  while (root.DirExists() && root.GetDirCount() > 0)
  {
    wxFileName path(root);
    path.AppendDir(admin_dir);

    if (path.DirExists() && !path.FileExists())
    {
      return true;
    }

    root.RemoveLastDir();
  }

  return false;
}
Exemplo n.º 7
0
void ArchiveViewer::SetCurrentFilename(wxFileName filename)
{
	m_CurrentFilename = filename;

	if (filename.IsOk())
		SetTitle(m_WindowTitle + _T(" - ") + filename.GetFullName());
	else
		SetTitle(m_WindowTitle);
}
bool NormalizePath(wxFileName& f,const wxString& base)
{
    bool result = true;
//    if (!f.IsAbsolute())
    {
        f.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
        result = f.IsOk();
    }
    return result;
}
wxSQLite3ResultSet TagsDatabase::SelectTagsByFile(const wxString& file, const wxFileName& path)
{
	// Incase empty file path is provided, use the current file name
	wxFileName databaseFileName(path);
	path.IsOk() == false ? databaseFileName = m_fileName : databaseFileName = path;
	OpenDatabase(databaseFileName);

	wxString query;
	query = wxString::Format(_T("select * from tags where file='%s';"), file.GetData());
	return m_db->ExecuteQuery(query.GetData());
}
Exemplo n.º 10
0
/*
    $(prefix)/share/mmex.
    Default install prefix is /usr (often /usr/local).
*/
const wxFileName mmex::GetSharedDir()
{
    static wxFileName fname;

    if (!fname.IsOk()) 
    {
        SetInstallPrefix();
        fname = wxFileName::DirName(wxStandardPaths::Get().GetDataDir());
    }

    return fname;
}
Exemplo n.º 11
0
/*
    $(prefix)/share/mmex/res
*/
const wxFileName mmex::GetResourceDir()
{
    static wxFileName fname;

    if (!fname.IsOk()) 
    {
        fname = GetSharedDir();
        fname.AppendDir("res");
    }

    return fname;
}
Exemplo n.º 12
0
const wxFileName mmex::GetDocDir()
{
    static wxFileName fname;

    if (!fname.IsOk())
    {
        fname = GetSharedDir();
        fname.AppendDir("doc");
    }

    return fname;
}
Exemplo n.º 13
0
const wxFileName mmex::GetLogDir(bool create)
{
    static wxFileName fname;

    if (!fname.IsOk())
    {
        fname = GetUserDir(create);
        //FIXME: file not found ERROR
        //fname.AppendDir("logs");
    }

    return fname;
}
Exemplo n.º 14
0
CMP_LIBRARY::CMP_LIBRARY( int aType, const wxFileName& aFileName )
{
    type = aType;
    isModified = false;
    timeStamp = 0;
    isCache = false;
    timeStamp = wxDateTime::Now();

    if( aFileName.IsOk() )
        fileName = aFileName;
    else
        fileName = wxFileName( wxT( "unnamed.lib" ) );
}
Exemplo n.º 15
0
bool ArtDrvSim::ReadImage(const wxFileName &simName)
{
   FILE* ifi;
   if (!simName.IsOk()) return false;

   if ( (ifi = ::fopen(simName.GetFullPath().fn_str(), "rb"))==NULL) {
      // open fails...
      return false;
   }
   size_t fLength = m_camProps.nPixelsX*m_camProps.nPixelsY * 2;
   size_t fRead = ::fread(m_imageData, 1, fLength, ifi);
   ::fclose(ifi);
   return (fLength==fRead);
}
Exemplo n.º 16
0
bool wxExVCS::IsAdminDir(
  const wxString& admin_dir, 
  const wxFileName& fn)
{
  if (admin_dir.empty() || !fn.IsOk())
  {
    return false;
  }
  
  // these cannot be combined, as AppendDir is a void (2.9.1).
  wxFileName path(fn);
  path.AppendDir(admin_dir);
  return path.DirExists() && !path.FileExists();
}
Exemplo n.º 17
0
bool FSOExecutable::IsRootFolderValid(const wxFileName& path, bool quiet) {
	if ( !path.IsOk() ) {
		if (!quiet) {
			wxLogError(_T(" New root folder %s is not OK"), path.GetFullPath().c_str());			
		}
		return false;
	}
	if ( path.GetPath().IsEmpty() ) {
		if (!quiet) {
			wxLogError(_T(" Root folder %s is empty"), path.GetFullPath().c_str());
		}
		return false;
	}
	return HasFSOExecutables(path);
}
Exemplo n.º 18
0
/*
    $(prefix)/share/doc/mmex
*/
const wxFileName mmex::GetDocDir()
{
    static wxFileName fname;

    if (!fname.IsOk()) 
    {
        fname = GetSharedDir();

        const wxArrayString &dirs = fname.GetDirs();
        if (dirs.Last().Lower() == GetAppName())
            fname.RemoveLastDir(); // mmex folder

        fname.AppendDir("doc");
        fname.AppendDir(GetAppName());
    }

    return fname;
}
Exemplo n.º 19
0
wxString WinPathToCygwin(const wxFileName& path) { // static
	wxASSERT(path.IsOk() && path.IsAbsolute());

	// Drive
	wxString unixPath = wxT("/cygdrive/");
	unixPath += path.GetVolume().Lower();

	// Dirs
	const wxArrayString& dirs = path.GetDirs();
	for (unsigned int i = 0; i < dirs.GetCount(); ++i) {
		unixPath += wxT('/') + dirs[i];
	}

	// Filename
	if (path.HasName()) {
		unixPath += wxT('/') + path.GetFullName();
	}

	return unixPath;
}
Exemplo n.º 20
0
void wxExLogStatus(const wxFileName& fn, long flags)
{
    if (!fn.IsOk())
    {
        return;
    }

    wxString text = (flags & STAT_FULLPATH ?
                     fn.GetFullPath():
                     fn.GetFullName());

    if (fn.FileExists())
    {
        const wxString what = (flags & STAT_SYNC ?
                               _("Synchronized"):
                               _("Modified"));

        text += " " + what + " " + fn.GetModificationTime().Format();
    }

    wxLogStatus(text);
}
Exemplo n.º 21
0
bool NewFileDialog::GetIsFileNameValid(const wxFileName& fileName) const
{

    if (!fileName.IsOk())
    {
        return false;
    }

    // Check if the file name has illegal characters in it.

    wxString forbidden = fileName.GetForbiddenChars();

    const wxArrayString dirs = fileName.GetDirs();

    for (unsigned int i = 0; i < dirs.Count(); ++i)
    {
        for (unsigned int j = 0; j < dirs[i].Length(); ++j)
        {
            if (forbidden.Find(dirs[i][j]) != wxNOT_FOUND)
            {
                return false;
            }
        }
    }

    wxString fullName = fileName.GetFullName();

    for (unsigned int j = 0; j < fullName.Length(); ++j)
    {
        if (forbidden.Find(fullName[j]) != wxNOT_FOUND)
        {
            return false;
        }
    }

    return true;

}
Exemplo n.º 22
0
 bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
Exemplo n.º 23
0
void TagsDatabase::Store(TagTreePtr tree, const wxFileName& path, bool autoCommit)
{
	if(!path.IsOk() && !m_fileName.IsOk())
	{
		// An attempt is made to save the tree into db but no database
		// is provided and none is currently opened to use
		return;
	}
	
	if( !tree )
		return;

	OpenDatabase(path);
	TreeWalker<wxString, TagEntry> walker( tree->GetRoot() );

	try
	{
		// Create the statements before the execution
		TagEntry dummy;
		wxSQLite3Statement insertStmt = m_db->PrepareStatement( dummy.GetInsertOneStatement() );
		
		std::vector<TagEntry> updateList;

		// AddChild entries to database
		if( autoCommit )
			m_db->Begin();

		for(; !walker.End(); walker++)
		{
			// Skip root node
			if(walker.GetNode() == tree->GetRoot())
				continue;

			walker.GetNode()->GetData().SetParentId(walker.GetNode()->GetParent()->GetData().GetId());
			if(walker.GetNode()->GetData().Store(insertStmt) == TagExist)
			{
				// Update the record
				updateList.push_back(walker.GetNode()->GetData());
			}
		}
		insertStmt.Finalize();

		if( autoCommit )
			m_db->Commit();

		// Do we need to update?
		if(!updateList.empty())
		{
			wxSQLite3Statement updateStmt = m_db->PrepareStatement( updateList[0].GetUpdateOneStatement() );
			if( autoCommit )
				m_db->Begin();
			for(size_t i=0; i<updateList.size(); i++)
				updateList[i].Update(updateStmt);
			updateStmt.Finalize();
			if( autoCommit )
				m_db->Commit();
		}
	}
	catch (wxSQLite3Exception& e)
	{
		wxUnusedVar(e);
		if( autoCommit )
			m_db->Rollback();
	}
}
Exemplo n.º 24
0
void TagsDatabase::Store(const std::vector<DbRecordPtr> &records, const wxFileName& path, bool autoCommit)
{
	if(!path.IsOk() && !m_fileName.IsOk())
	{
		// An attempt is made to save the tree into db but no database
		// is provided and none is currently opened to use
		return;
	}

	if(records.empty())
		return;

	OpenDatabase(path);
	try
	{
		// Create the statements before the execution
		wxSQLite3Statement insertStmt = m_db->PrepareStatement(records[0]->GetInsertOneStatement());
		
		std::vector<DbRecordPtr> updateList;

		// AddChild entries to database
		// we break the bug transaction into samller ones of 1000 operations
		// each
		const size_t bulk = 1000;
		if( autoCommit )
			m_db->Begin();

		size_t i=0;
		for(; i<records.size(); i++)
		{
			if(records[i]->Store(insertStmt) == TagExist)
			{
				// Update the record
				updateList.push_back(records[i]);
			}
			else
			{
				// insert succeeded
				if(i % bulk == 0 && autoCommit)
				{
					m_db->Commit();
					m_db->Begin();
				}
			}
		}
		insertStmt.Finalize();

		if( autoCommit )
			m_db->Commit();

		// Do we need to update?
		if(!updateList.empty())
		{
			wxSQLite3Statement updateStmt = m_db->PrepareStatement( updateList[0]->GetUpdateOneStatement() );
			if( autoCommit )
				m_db->Begin();
			for(size_t i=0; i<updateList.size(); i++)
			{
				updateList[i]->Update(updateStmt);
				if( i % bulk == 0 && autoCommit )
				{
					m_db->Commit();
					m_db->Begin();
				}
			}
			updateStmt.Finalize();
			if( autoCommit )
				m_db->Commit();
		}
	}
	catch (wxSQLite3Exception& e)
	{
		wxUnusedVar(e);
		if( autoCommit )
			m_db->Rollback();
	}	
}
Exemplo n.º 25
0
void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName,
                                           const wxString&   aBackupFileExtension )
{
    wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
    wxCHECK_RET( !aBackupFileExtension.IsEmpty(), wxT( "Invalid backup file extension!" ) );

    wxFileName autoSaveFileName = aFileName;

    // Check for auto save file.
    autoSaveFileName.SetName( wxT( "$" ) + aFileName.GetName() );

    wxLogTrace( traceAutoSave,
                wxT( "Checking for auto save file " ) + autoSaveFileName.GetFullPath() );

    if( !autoSaveFileName.FileExists() )
        return;

    wxString msg = wxString::Format( _(
            "Well this is potentially embarrassing!  It appears that the last time "
            "you were editing the file '%s' it was not saved properly.  Do you wish to restore the last "
            "edits you made?" ),
            GetChars( aFileName.GetFullName() )
        );

    int response = wxMessageBox( msg, Pgm().App().GetAppName(), wxYES_NO | wxICON_QUESTION, this );

    // Make a backup of the current file, delete the file, and rename the auto save file to
    // the file name.
    if( response == wxYES )
    {
        // Get the backup file name.
        wxFileName backupFileName = aFileName;
        backupFileName.SetExt( aBackupFileExtension );

        // If an old backup file exists, delete it.  If an old copy of the file exists, rename
        // it to the backup file name
        if( aFileName.FileExists() )
        {
            // Remove the old file backup file.
            if( backupFileName.FileExists() )
                wxRemoveFile( backupFileName.GetFullPath() );

            // Rename the old file to the backup file name.
            if( !wxRenameFile( aFileName.GetFullPath(), backupFileName.GetFullPath() ) )
            {
                msg.Printf( _( "Could not create backup file <%s>" ),
                            GetChars( backupFileName.GetFullPath() ) );
                wxMessageBox( msg );
            }
        }

        if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
        {
            wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
                          Pgm().App().GetAppName(), wxOK | wxICON_EXCLAMATION, this );
        }
    }
    else
    {
        wxLogTrace( traceAutoSave,
                    wxT( "Removing auto save file " ) + autoSaveFileName.GetFullPath() );

        // Remove the auto save file when using the previous file as is.
        wxRemoveFile( autoSaveFileName.GetFullPath() );
    }
}
Exemplo n.º 26
0
// checks if the image file exists in UserData or current dir
// returns true if the file exists and the simName is containing the filename
bool ArtDrvSim::CheckSimFile(wxFileName &simName, unsigned short Device)
{
   // look for sim files in GetUserDataDir()
   // Return the directory for the user-dependent application data files:
   // Unix: ~/.appname
   // Windows: C:\Documents and Settings\username\Application Data\appname
   wxStandardPaths px;
   // if we did not found a file we check the current dir for compatibility reasons
   switch (Device) {
   case ACT_Art429:
      simName.Assign(px.GetUserDataDir(), wxT(ART429_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART429_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   case ACT_Art285:
      simName.Assign(px.GetUserDataDir(), wxT(ART285_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART285_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   case ACT_Art424:
      simName.Assign(px.GetUserDataDir(), wxT(ART424_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART424_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   case ACT_Art415:
      simName.Assign(px.GetUserDataDir(), wxT(ART415_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART415_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   case ACT_Art4021:
      simName.Assign(px.GetUserDataDir(), wxT(ART4021_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART4021_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   case ACT_Art11002:
      simName.Assign(px.GetUserDataDir(), wxT(ART11002_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      simName.Assign(wxT("."), wxT(ART11002_FILE), wxT("raw"));
      if (simName.IsOk()) if (simName.FileExists()) return true;
      break;
   default:
      ;
   }// switch
   simName.Clear();
   return false;
}
Exemplo n.º 27
0
void EDA_3D_VIEWER::takeScreenshot( wxCommandEvent& event )
{
    wxString   fullFileName;
    bool       fmt_is_jpeg = false;

    if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
        fmt_is_jpeg = true;

    if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
        // Remember path between saves during this session only.
        static wxFileName fn;
        const wxString file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" );
        const wxString mask     = wxT( "*." ) + file_ext;

        // First time path is set to the project path.
        if( !fn.IsOk() )
            fn = Parent()->Prj().GetProjectFullName();

        fn.SetExt( file_ext );

        fullFileName = EDA_FILE_SELECTOR( _( "3D Image File Name:" ), fn.GetPath(),
                                          m_defaultFileName, file_ext, mask, this,
                                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT, true );

        if( fullFileName.IsEmpty() )
            return;

        fn = fullFileName;

        // Be sure the screen area destroyed by the file dialog is redrawn
        // before making a screen copy.
        // Without this call, under Linux the screen refresh is made to late.
        wxYield();
    }

    // Be sure we have the latest 3D view (remember 3D view is buffered)
    Refresh();
    wxYield();

    // Build image from the 3D buffer
    wxWindowUpdateLocker noUpdates( this );

    wxImage screenshotImage;

    if( m_canvas )
        m_canvas->GetScreenshot( screenshotImage );

    if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
        wxBitmap bitmap( screenshotImage );

        if( wxTheClipboard->Open() )
        {
            wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );

            if( !wxTheClipboard->SetData( dobjBmp ) )
                wxMessageBox( _( "Failed to copy image to clipboard" ) );

            wxTheClipboard->Flush();    /* the data in clipboard will stay
                                         * available after the application exits */
            wxTheClipboard->Close();
        }
    }
    else
    {
        if( !screenshotImage.SaveFile( fullFileName,
                             fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
            wxMessageBox( _( "Can't save file" ) );

        screenshotImage.Destroy();
    }

}
Exemplo n.º 28
0
void EDA_3D_CANVAS::TakeScreenshot( wxCommandEvent& event )
{
    static wxFileName fn;                 // Remember path between saves during this session only.
    wxString          FullFileName;
    wxString          file_ext, mask;
    bool              fmt_is_jpeg = false;

    // First time path is set to the project path.
    if( !fn.IsOk() )
        fn = Parent()->Prj().GetProjectFullName();

    if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
        fmt_is_jpeg = true;

    if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
        file_ext     = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" );
        mask         = wxT( "*." ) + file_ext;
        fn.SetExt( file_ext );

        FullFileName = EDA_FileSelector( _( "3D Image File Name:" ), fn.GetPath(),
                                         fn.GetFullName(), file_ext, mask, this,
                                         wxFD_SAVE | wxFD_OVERWRITE_PROMPT, true );

        if( FullFileName.IsEmpty() )
            return;

        fn = FullFileName;

        // Be sure the screen area destroyed by the file dialog is redrawn before making
        // a screen copy.
        // Without this call, under Linux the screen refresh is made to late.
        wxYield();
    }

    struct viewport_params
    {
        GLint originx;
        GLint originy;
        GLint x;
        GLint y;
    } viewport;

    // Be sure we have the latest 3D view (remember 3D view is buffered)
    Refresh();
    wxYield();

    // Build image from the 3D buffer
    wxWindowUpdateLocker noUpdates( this );
    glGetIntegerv( GL_VIEWPORT, (GLint*) &viewport );

    unsigned char*       pixelbuffer = (unsigned char*) malloc( viewport.x * viewport.y * 3 );
    unsigned char*       alphabuffer = (unsigned char*) malloc( viewport.x * viewport.y );
    wxImage image( viewport.x, viewport.y );

    glPixelStorei( GL_PACK_ALIGNMENT, 1 );
    glReadBuffer( GL_BACK_LEFT );
    glReadPixels( viewport.originx, viewport.originy,
                  viewport.x, viewport.y,
                  GL_RGB, GL_UNSIGNED_BYTE, pixelbuffer );
    glReadPixels( viewport.originx, viewport.originy,
                  viewport.x, viewport.y,
                  GL_ALPHA, GL_UNSIGNED_BYTE, alphabuffer );

    image.SetData( pixelbuffer );
    image.SetAlpha( alphabuffer );
    image = image.Mirror( false );
    wxBitmap bitmap( image );

    if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
    {
        if( wxTheClipboard->Open() )
        {
            wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );

            if( !wxTheClipboard->SetData( dobjBmp ) )
                wxMessageBox( _( "Failed to copy image to clipboard" ) );

            wxTheClipboard->Flush();    /* the data in clipboard will stay
                                         * available after the application exits */
            wxTheClipboard->Close();
        }
    }
    else
    {
        wxImage image = bitmap.ConvertToImage();

        if( !image.SaveFile( FullFileName,
                             fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
            wxMessageBox( _( "Can't save file" ) );

        image.Destroy();
    }
}