Beispiel #1
0
void wxGenericFileCtrl::SetWildcard( const wxString& wildCard )
{
    if ( wildCard.empty() || wildCard == wxFileSelectorDefaultWildcardStr )
    {
        m_wildCard = wxString::Format( _( "All files (%s)|%s" ),
                                       wxFileSelectorDefaultWildcardStr,
                                       wxFileSelectorDefaultWildcardStr );
    }
    else
        m_wildCard = wildCard;

    wxArrayString wildDescriptions, wildFilters;
    const size_t count = wxParseCommonDialogsFilter( m_wildCard,
                         wildDescriptions,
                         wildFilters );
    wxCHECK_RET( count, wxT( "wxFileDialog: bad wildcard string" ) );

    m_choice->Clear();

    for ( size_t n = 0; n < count; n++ )
    {
        m_choice->Append(wildDescriptions[n], new wxStringClientData(wildFilters[n]));
    }

    SetFilterIndex( 0 );
}
Beispiel #2
0
void wxGtkFileChooser::SetWildcard( const wxString& wildCard )
{
    m_wildcards.Empty();

    // parse filters
    wxArrayString wildDescriptions, wildFilters;

    if ( !wxParseCommonDialogsFilter( wildCard, wildDescriptions, wildFilters ) )
    {
        wxFAIL_MSG( wxT( "wxGtkFileChooser::SetWildcard - bad wildcard string" ) );
    }
    else
    {
        // Parsing went fine. Set m_wildCard to be returned by wxGtkFileChooserBase::GetWildcard
        GtkFileChooser* chooser = m_widget;

        // empty current filter list:
        GSList* ifilters = gtk_file_chooser_list_filters( chooser );
        GSList* filters = ifilters;

        m_ignoreNextFilterEvent = true;
        wxON_BLOCK_EXIT_SET(m_ignoreNextFilterEvent, false);

        while ( ifilters )
        {
            gtk_file_chooser_remove_filter( chooser, GTK_FILE_FILTER( ifilters->data ) );
            ifilters = ifilters->next;
        }
        g_slist_free( filters );

        if (!wildCard.empty())
        {
            // add parsed to GtkChooser
            for ( size_t n = 0; n < wildFilters.GetCount(); ++n )
            {
                GtkFileFilter* filter = gtk_file_filter_new();

                gtk_file_filter_set_name( filter, wxGTK_CONV_SYS( wildDescriptions[n] ) );

                wxStringTokenizer exttok( wildFilters[n], wxT( ";" ) );

                int n1 = 1;
                while ( exttok.HasMoreTokens() )
                {
                    wxString token = exttok.GetNextToken();
                    gtk_file_filter_add_pattern( filter, wxGTK_CONV_SYS( token ) );

                    if (n1 == 1)
                        m_wildcards.Add( token ); // Only add first pattern to list, used later when saving
                    n1++;
                }

                gtk_file_chooser_add_filter( chooser, filter );
            }

            // Reset the filter index
            SetFilterIndex( 0 );
        }
    }
}
Beispiel #3
0
wxString FileSelector(const wxString & title,
                      const wxString & defaultDir,
                      const wxString & defaultFileName,
                      const wxString & defaultExtension,
                      const wxString & filter,
                      int flags,
                      wxWindow *parent)
{
   // The defaultExtension, if non-empty, is
   // appended to the filename if the user fails to type an extension. The new
   // implementation (taken from wxFileSelectorEx) appends the extension
   // automatically, by looking at the filter specification. In fact this
   // should be better than the native Microsoft implementation because
   // Windows only allows *one* default extension, whereas here we do the
   // right thing depending on the filter the user has chosen.

   // If there's a default extension specified but no filter, we create a
   // suitable filter.

   wxString filter2;
   if (!defaultExtension.empty() && filter.empty())
      filter2 = wxString(wxT("*.")) + defaultExtension;
   else if (!filter.empty())
      filter2 = filter;

   FileDialog fileDialog(parent, title, defaultDir,
                         defaultFileName, filter2,
                         flags);

   // if filter is of form "All files (*)|*|..." set correct filter index
   if (!defaultExtension.empty() && filter2.find(wxT('|')) != wxString::npos)
   {
      int filterIndex = 0;
      
      wxArrayString descriptions, filters;
      // don't care about errors, handled already by FileDialog
      (void)wxParseCommonDialogsFilter(filter2, descriptions, filters);
      
      for (size_t n=0; n<filters.GetCount(); n++)
      {
         if (filters[n].Contains(defaultExtension))
         {
            filterIndex = (int)n; // Convert to int to avoid compiler warning, because we probably do not need many tens of thousands of filters.
            break;
         }
      }
      
      if (filterIndex > 0)
         fileDialog.SetFilterIndex(filterIndex);
   }
   
   wxString filename;
   if (fileDialog.ShowModal() == wxID_OK)
   {
      filename = fileDialog.GetPath();
   }
   
   return filename;
}
Beispiel #4
0
void wxFileDialog::SetWildcard(const wxString& wildCard)
{
#ifdef __WXGTK24__
    if (!gtk_check_version(2,4,0))
    {
        // parse filters
        wxArrayString wildDescriptions, wildFilters;
        if (!wxParseCommonDialogsFilter(wildCard, wildDescriptions, wildFilters))
        {
            wxFAIL_MSG( wxT("wxFileDialog::SetWildCard - bad wildcard string") );
        }
        else
        {
            // Parsing went fine. Set m_wildCard to be returned by wxFileDialogBase::GetWildcard
            m_wildCard = wildCard;

            GtkFileChooser* chooser = GTK_FILE_CHOOSER(m_widget);

            // empty current filter list:
            GSList* ifilters = gtk_file_chooser_list_filters(chooser);
            GSList* filters = ifilters;

            while (ifilters)
            {
                gtk_file_chooser_remove_filter(chooser,GTK_FILE_FILTER(ifilters->data));
                ifilters = ifilters->next;
            }
            g_slist_free(filters);

            // add parsed to GtkChooser
            for (size_t n = 0; n < wildFilters.GetCount(); ++n)
            {
                GtkFileFilter* filter = gtk_file_filter_new();
                gtk_file_filter_set_name(filter, wxGTK_CONV(wildDescriptions[n]));

                wxStringTokenizer exttok(wildFilters[n], wxT(";"));
                while (exttok.HasMoreTokens())
                {
                    wxString token = exttok.GetNextToken();
                    gtk_file_filter_add_pattern(filter, wxGTK_CONV(token));
                }

                gtk_file_chooser_add_filter(chooser, filter);
            }

            // Reset the filter index
            SetFilterIndex(0);
        }
    }
    else
#endif
        wxGenericFileDialog::SetWildcard( wildCard );
}
Beispiel #5
0
void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilter)
{
    Clear();
    wxArrayString descriptions, filters;
    size_t n = (size_t) wxParseCommonDialogsFilter(filter, descriptions, filters);

    if (n > 0 && defaultFilter < (int) n)
    {
        for (size_t i = 0; i < n; i++)
            Append(descriptions[i]);
        SetSelection(defaultFilter);
    }
}
Beispiel #6
0
// Extract description and actual filter from overall filter string
bool wxGenericDirCtrl::ExtractWildcard(const wxString& filterStr, int n, wxString& filter, wxString& description)
{
    wxArrayString filters, descriptions;
    int count = wxParseCommonDialogsFilter(filterStr, descriptions, filters);
    if (count > 0 && n < count)
    {
        filter = filters[n];
        description = descriptions[n];
        return true;
    }

    return false;
}
Beispiel #7
0
void MiscGUIFuncsTestCase::ParseFileDialogFilter()
{
    wxArrayString descs,
                  filters;

    CPPUNIT_ASSERT_EQUAL
    (
        1,
        wxParseCommonDialogsFilter("Image files|*.jpg;*.png", descs, filters)
    );

    CPPUNIT_ASSERT_EQUAL( "Image files", descs[0] );
    CPPUNIT_ASSERT_EQUAL( "*.jpg;*.png", filters[0] );

    CPPUNIT_ASSERT_EQUAL
    (
        2,
        wxParseCommonDialogsFilter
        (
            "All files (*.*)|*.*|Python source (*.py)|*.py",
            descs, filters
        )
    );

    CPPUNIT_ASSERT_EQUAL( "*.*", filters[0] );
    CPPUNIT_ASSERT_EQUAL( "*.py", filters[1] );

    // Test some invalid ones too.
    WX_ASSERT_FAILS_WITH_ASSERT
    (
        wxParseCommonDialogsFilter
        (
            "All files (*.*)|*.*|Python source (*.py)|*.py|",
            descs, filters
        )
    );
}
Beispiel #8
0
static wxString ParseWildCard( const wxString& wild )
{
#if wxDEBUG_LEVEL
    static const char *msg =
        "Motif file dialog does not understand this wildcard syntax";
#endif

    wxArrayString wildDescriptions, wildFilters;
    const size_t count = wxParseCommonDialogsFilter(wild,
                                                    wildDescriptions,
                                                    wildFilters);
    wxCHECK_MSG( count, wxT("*.*"), wxT("wxFileDialog: bad wildcard string") );
    wxCHECK_MSG( count == 1, wxT("*.*"), msg );

    // check for *.txt;*.rtf
    wxStringTokenizer tok2( wildFilters[0], wxT(";") );
    wxString wildcard = tok2.GetNextToken();

    wxCHECK_MSG( tok2.CountTokens() <= 1, wildcard, msg );
    return wildcard;
}
void wxGenericFileDialog::SetWildcard(const wxString& wildCard)
{
    wxFileDialogBase::SetWildcard(wildCard);

    wxArrayString wildDescriptions, wildFilters;
    const size_t count = wxParseCommonDialogsFilter(m_wildCard,
                         wildDescriptions,
                         wildFilters);
    wxCHECK_RET( count, wxT("wxFileDialog: bad wildcard string") );

    const size_t countOld = m_choice->GetCount();
    size_t n;
    for ( n = 0; n < countOld; n++ )
    {
        delete (wxString *)m_choice->GetClientData(n);
    }

    for ( n = 0; n < count; n++ )
    {
        m_choice->Append( wildDescriptions[n], new wxString( wildFilters[n] ) );
    }

    SetFilterIndex( 0 );
}
Beispiel #10
0
int wxFileDialog::ShowModal()
{
    HWND hWnd = 0;
    if (m_parent) hWnd = (HWND) m_parent->GetHWND();
    if (!hWnd && wxTheApp->GetTopWindow())
        hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND();

    static wxChar fileNameBuffer [ wxMAXPATH ];           // the file-name
    wxChar        titleBuffer    [ wxMAXFILE+1+wxMAXEXT ];  // the file-name, without path

    *fileNameBuffer = wxT('\0');
    *titleBuffer    = wxT('\0');

    long msw_flags = OFN_HIDEREADONLY;

    if ( HasFdFlag(wxFD_FILE_MUST_EXIST) )
        msw_flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    /*
        If the window has been moved the programmer is probably
        trying to center or position it.  Thus we set the callback
        or hook function so that we can actually adjust the position.
        Without moving or centering the dlg, it will just stay
        in the upper left of the frame, it does not center
        automatically.
    */
    if (m_bMovedWindow || HasExtraControlCreator()) // we need these flags.
    {
        msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK;
#ifndef __WXWINCE__
        msw_flags |= OFN_ENABLESIZING;
#endif
    }

    if ( HasFdFlag(wxFD_MULTIPLE) )
    {
        // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT
        msw_flags |= OFN_EXPLORER | OFN_ALLOWMULTISELECT;
    }

    // if wxFD_CHANGE_DIR flag is not given we shouldn't change the CWD which the
    // standard dialog does by default (notice that under NT it does it anyhow,
    // OFN_NOCHANGEDIR or not, see below)
    if ( !HasFdFlag(wxFD_CHANGE_DIR) )
    {
        msw_flags |= OFN_NOCHANGEDIR;
    }

    if ( HasFdFlag(wxFD_OVERWRITE_PROMPT) )
    {
        msw_flags |= OFN_OVERWRITEPROMPT;
    }

    wxOPENFILENAME of;
    wxZeroMemory(of);

    of.lStructSize       = gs_ofStructSize;
    of.hwndOwner         = hWnd;
    of.lpstrTitle        = m_message.wx_str();
    of.lpstrFileTitle    = titleBuffer;
    of.nMaxFileTitle     = wxMAXFILE + 1 + wxMAXEXT;

#ifndef __WXWINCE__
    GlobalPtr hgbl;
    if ( HasExtraControlCreator() )
    {
        msw_flags |= OFN_ENABLETEMPLATEHANDLE;

        hgbl.Init(256, GMEM_ZEROINIT);
        GlobalPtrLock hgblLock(hgbl);
        LPDLGTEMPLATE lpdt = static_cast<LPDLGTEMPLATE>(hgblLock.Get());

        // Define a dialog box.

        lpdt->style = DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS;
        lpdt->cdit = 0;         // Number of controls
        lpdt->x = 0;
        lpdt->y = 0;

        // convert the size of the extra controls to the dialog units
        const wxSize extraSize = GetExtraControlSize();
        const LONG baseUnits = ::GetDialogBaseUnits();
        lpdt->cx = ::MulDiv(extraSize.x, 4, LOWORD(baseUnits));
        lpdt->cy = ::MulDiv(extraSize.y, 8, HIWORD(baseUnits));

        // after the DLGTEMPLATE there are 3 additional WORDs for dialog menu,
        // class and title, all three set to zeros.

        of.hInstance = (HINSTANCE)lpdt;
    }
#endif // __WXWINCE__

    // Convert forward slashes to backslashes (file selector doesn't like
    // forward slashes) and also squeeze multiple consecutive slashes into one
    // as it doesn't like two backslashes in a row neither

    wxString  dir;
    size_t    i, len = m_dir.length();
    dir.reserve(len);
    for ( i = 0; i < len; i++ )
    {
        wxChar ch = m_dir[i];
        switch ( ch )
        {
            case wxT('/'):
                // convert to backslash
                ch = wxT('\\');

                // fall through

            case wxT('\\'):
                while ( i < len - 1 )
                {
                    wxChar chNext = m_dir[i + 1];
                    if ( chNext != wxT('\\') && chNext != wxT('/') )
                        break;

                    // ignore the next one, unless it is at the start of a UNC path
                    if (i > 0)
                        i++;
                    else
                        break;
                }
                // fall through

            default:
                // normal char
                dir += ch;
        }
    }

    of.lpstrInitialDir   = dir.c_str();

    of.Flags             = msw_flags;
    of.lpfnHook          = wxFileDialogHookFunction;
    of.lCustData         = (LPARAM)this;

    wxArrayString wildDescriptions, wildFilters;

    size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, wildFilters);

    wxASSERT_MSG( items > 0 , wxT("empty wildcard list") );

    wxString filterBuffer;

    for (i = 0; i < items ; i++)
    {
        filterBuffer += wildDescriptions[i];
        filterBuffer += wxT("|");
        filterBuffer += wildFilters[i];
        filterBuffer += wxT("|");
    }

    // Replace | with \0
    for (i = 0; i < filterBuffer.length(); i++ ) {
        if ( filterBuffer.GetChar(i) == wxT('|') ) {
            filterBuffer[i] = wxT('\0');
        }
    }

    of.lpstrFilter  = (LPTSTR)filterBuffer.wx_str();
    of.nFilterIndex = m_filterIndex + 1;

    //=== Setting defaultFileName >>=========================================

    wxStrlcpy(fileNameBuffer, m_fileName.c_str(), WXSIZEOF(fileNameBuffer));

    of.lpstrFile = fileNameBuffer;  // holds returned filename
    of.nMaxFile  = wxMAXPATH;

    // we must set the default extension because otherwise Windows would check
    // for the existing of a wrong file with wxFD_OVERWRITE_PROMPT (i.e. if the
    // user types "foo" and the default extension is ".bar" we should force it
    // to check for "foo.bar" existence and not "foo")
    wxString defextBuffer; // we need it to be alive until GetSaveFileName()!
    if (HasFdFlag(wxFD_SAVE))
    {
        const wxChar* extension = filterBuffer.wx_str();
        int maxFilter = (int)(of.nFilterIndex*2L) - 1;

        for( int i = 0; i < maxFilter; i++ )           // get extension
            extension = extension + wxStrlen( extension ) + 1;

        // use dummy name a to avoid assert in AppendExtension
        defextBuffer = AppendExtension(wxT("a"), extension);
        if (defextBuffer.StartsWith(wxT("a.")))
        {
            defextBuffer = defextBuffer.Mid(2); // remove "a."
            of.lpstrDefExt = defextBuffer.c_str();
        }
    }

    // store off before the standard windows dialog can possibly change it
    const wxString cwdOrig = wxGetCwd();

    //== Execute FileDialog >>=================================================

    if ( !ShowCommFileDialog(&of, m_windowStyle) )
        return wxID_CANCEL;

    // GetOpenFileName will always change the current working directory on
    // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag
    // OFN_NOCHANGEDIR has no effect.  If the user did not specify
    // wxFD_CHANGE_DIR let's restore the current working directory to what it
    // was before the dialog was shown.
    if ( msw_flags & OFN_NOCHANGEDIR )
    {
        wxSetWorkingDirectory(cwdOrig);
    }

    m_fileNames.Empty();

    if ( ( HasFdFlag(wxFD_MULTIPLE) ) &&
#if defined(OFN_EXPLORER)
         ( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
#else
         ( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
#endif // OFN_EXPLORER
       )
    {
#if defined(OFN_EXPLORER)
        m_dir = fileNameBuffer;
        i = of.nFileOffset;
        m_fileName = &fileNameBuffer[i];
        m_fileNames.Add(m_fileName);
        i += m_fileName.length() + 1;

        while (fileNameBuffer[i] != wxT('\0'))
        {
            m_fileNames.Add(&fileNameBuffer[i]);
            i += wxStrlen(&fileNameBuffer[i]) + 1;
        }
#else
        wxStringTokenizer toke(fileNameBuffer, wxT(" \t\r\n"));
        m_dir = toke.GetNextToken();
        m_fileName = toke.GetNextToken();
        m_fileNames.Add(m_fileName);

        while (toke.HasMoreTokens())
            m_fileNames.Add(toke.GetNextToken());
#endif // OFN_EXPLORER

        wxString dir(m_dir);
        if ( m_dir.Last() != wxT('\\') )
            dir += wxT('\\');

        m_path = dir + m_fileName;
        m_filterIndex = (int)of.nFilterIndex - 1;
    }
    else
    {
        //=== Adding the correct extension >>=================================

        m_filterIndex = (int)of.nFilterIndex - 1;

        if ( !of.nFileExtension ||
             (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
        {
            // User has typed a filename without an extension:
            const wxChar* extension = filterBuffer.wx_str();
            int   maxFilter = (int)(of.nFilterIndex*2L) - 1;

            for( int i = 0; i < maxFilter; i++ )           // get extension
                extension = extension + wxStrlen( extension ) + 1;

            m_fileName = AppendExtension(fileNameBuffer, extension);
            wxStrlcpy(fileNameBuffer, m_fileName.c_str(), WXSIZEOF(fileNameBuffer));
        }

        m_path = fileNameBuffer;
        m_fileName = wxFileNameFromPath(fileNameBuffer);
        m_fileNames.Add(m_fileName);
        m_dir = wxPathOnly(fileNameBuffer);
        }

    return wxID_OK;

}
Beispiel #11
0
int wxFileDialog::ShowModal()
{
    HWND hWnd = 0;
    if (m_parent) hWnd = (HWND) m_parent->GetHWND();
    if (!hWnd && wxTheApp->GetTopWindow())
        hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND();

    static wxChar fileNameBuffer [ wxMAXPATH ];           // the file-name
    wxChar        titleBuffer    [ wxMAXFILE+1+wxMAXEXT ];  // the file-name, without path

    *fileNameBuffer = wxT('\0');
    *titleBuffer    = wxT('\0');

#if WXWIN_COMPATIBILITY_2_4
    long msw_flags = 0;
    if ( HasFdFlag(wxHIDE_READONLY) || HasFdFlag(wxFD_SAVE) )
        msw_flags |= OFN_HIDEREADONLY;
#else
    long msw_flags = OFN_HIDEREADONLY;
#endif

    if ( HasFdFlag(wxFD_FILE_MUST_EXIST) )
        msw_flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    /*
        If the window has been moved the programmer is probably
        trying to center or position it.  Thus we set the callback
        or hook function so that we can actually adjust the position.
        Without moving or centering the dlg, it will just stay
        in the upper left of the frame, it does not center
        automatically.
    */
    if (m_bMovedWindow) // we need these flags.
    {
        msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK;
#ifndef __WXWINCE__
        msw_flags |= OFN_ENABLESIZING;
#endif
    }

    if ( HasFdFlag(wxFD_MULTIPLE) )
    {
        // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT
        msw_flags |= OFN_EXPLORER | OFN_ALLOWMULTISELECT;
    }

    // if wxFD_CHANGE_DIR flag is not given we shouldn't change the CWD which the
    // standard dialog does by default (notice that under NT it does it anyhow,
    // OFN_NOCHANGEDIR or not, see below)
    if ( !HasFdFlag(wxFD_CHANGE_DIR) )
    {
        msw_flags |= OFN_NOCHANGEDIR;
    }

    if ( HasFdFlag(wxFD_OVERWRITE_PROMPT) )
    {
        msw_flags |= OFN_OVERWRITEPROMPT;
    }

    wxOPENFILENAME of;
    wxZeroMemory(of);

    of.lStructSize       = gs_ofStructSize;
    of.hwndOwner         = hWnd;
    of.lpstrTitle        = WXSTRINGCAST m_message;
    of.lpstrFileTitle    = titleBuffer;
    of.nMaxFileTitle     = wxMAXFILE + 1 + wxMAXEXT;

    // Convert forward slashes to backslashes (file selector doesn't like
    // forward slashes) and also squeeze multiple consecutive slashes into one
    // as it doesn't like two backslashes in a row neither

    wxString  dir;
    size_t    i, len = m_dir.length();
    dir.reserve(len);
    for ( i = 0; i < len; i++ )
    {
        wxChar ch = m_dir[i];
        switch ( ch )
        {
            case _T('/'):
                // convert to backslash
                ch = _T('\\');

                // fall through

            case _T('\\'):
                while ( i < len - 1 )
                {
                    wxChar chNext = m_dir[i + 1];
                    if ( chNext != _T('\\') && chNext != _T('/') )
                        break;

                    // ignore the next one, unless it is at the start of a UNC path
                    if (i > 0)
                        i++;
                    else
                        break;
                }
                // fall through

            default:
                // normal char
                dir += ch;
        }
    }

    of.lpstrInitialDir   = dir.c_str();

    of.Flags             = msw_flags;
    of.lpfnHook          = wxFileDialogHookFunction;

    wxArrayString wildDescriptions, wildFilters;

    size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, wildFilters);

    wxASSERT_MSG( items > 0 , _T("empty wildcard list") );

    wxString filterBuffer;

    for (i = 0; i < items ; i++)
    {
        filterBuffer += wildDescriptions[i];
        filterBuffer += wxT("|");
        filterBuffer += wildFilters[i];
        filterBuffer += wxT("|");
    }

    // Replace | with \0
    for (i = 0; i < filterBuffer.length(); i++ ) {
        if ( filterBuffer.GetChar(i) == wxT('|') ) {
            filterBuffer[i] = wxT('\0');
        }
    }

    of.lpstrFilter  = (LPTSTR)filterBuffer.c_str();
    of.nFilterIndex = m_filterIndex + 1;

    //=== Setting defaultFileName >>=========================================

    wxStrncpy( fileNameBuffer, (const wxChar *)m_fileName, wxMAXPATH-1 );
    fileNameBuffer[ wxMAXPATH-1 ] = wxT('\0');

    of.lpstrFile = fileNameBuffer;  // holds returned filename
    of.nMaxFile  = wxMAXPATH;

    // we must set the default extension because otherwise Windows would check
    // for the existing of a wrong file with wxFD_OVERWRITE_PROMPT (i.e. if the
    // user types "foo" and the default extension is ".bar" we should force it
    // to check for "foo.bar" existence and not "foo")
    wxString defextBuffer; // we need it to be alive until GetSaveFileName()!
    if (HasFdFlag(wxFD_SAVE))
    {
        const wxChar* extension = filterBuffer;
        int maxFilter = (int)(of.nFilterIndex*2L) - 1;

        for( int i = 0; i < maxFilter; i++ )           // get extension
            extension = extension + wxStrlen( extension ) + 1;

        // use dummy name a to avoid assert in AppendExtension
        defextBuffer = AppendExtension(wxT("a"), extension);
        if (defextBuffer.StartsWith(wxT("a.")))
        {
            defextBuffer = defextBuffer.Mid(2); // remove "a."
            of.lpstrDefExt = defextBuffer.c_str();
        }
    }

    // store off before the standard windows dialog can possibly change it
    const wxString cwdOrig = wxGetCwd();

    //== Execute FileDialog >>=================================================

    DWORD errCode;
    bool success = DoShowCommFileDialog(&of, m_windowStyle, &errCode);

#ifdef wxTRY_SMALLER_OPENFILENAME
    // the system might be too old to support the new version file dialog
    // boxes, try with the old size
    if ( !success && errCode == CDERR_STRUCTSIZE &&
            of.lStructSize != wxOPENFILENAME_V4_SIZE )
    {
        of.lStructSize = wxOPENFILENAME_V4_SIZE;

        success = DoShowCommFileDialog(&of, m_windowStyle, &errCode);

        if ( success || !errCode )
        {
            // use this struct size for subsequent dialogs
            gs_ofStructSize = of.lStructSize;
        }
    }
#endif // wxTRY_SMALLER_OPENFILENAME

    if ( success )
    {
        // GetOpenFileName will always change the current working directory on
        // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag
        // OFN_NOCHANGEDIR has no effect.  If the user did not specify
        // wxFD_CHANGE_DIR let's restore the current working directory to what it
        // was before the dialog was shown.
        if ( msw_flags & OFN_NOCHANGEDIR )
        {
            wxSetWorkingDirectory(cwdOrig);
        }

        m_fileNames.Empty();

        if ( ( HasFdFlag(wxFD_MULTIPLE) ) &&
#if defined(OFN_EXPLORER)
             ( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
#else
             ( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
#endif // OFN_EXPLORER
           )
        {
#if defined(OFN_EXPLORER)
            m_dir = fileNameBuffer;
            i = of.nFileOffset;
            m_fileName = &fileNameBuffer[i];
            m_fileNames.Add(m_fileName);
            i += m_fileName.length() + 1;

            while (fileNameBuffer[i] != wxT('\0'))
            {
                m_fileNames.Add(&fileNameBuffer[i]);
                i += wxStrlen(&fileNameBuffer[i]) + 1;
            }
#else
            wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n"));
            m_dir = toke.GetNextToken();
            m_fileName = toke.GetNextToken();
            m_fileNames.Add(m_fileName);

            while (toke.HasMoreTokens())
                m_fileNames.Add(toke.GetNextToken());
#endif // OFN_EXPLORER

            wxString dir(m_dir);
            if ( m_dir.Last() != _T('\\') )
                dir += _T('\\');

            m_path = dir + m_fileName;
            m_filterIndex = (int)of.nFilterIndex - 1;
        }
        else
        {
            //=== Adding the correct extension >>=================================

            m_filterIndex = (int)of.nFilterIndex - 1;

            if ( !of.nFileExtension ||
                 (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
            {
                // User has typed a filename without an extension:
                const wxChar* extension = filterBuffer;
                int   maxFilter = (int)(of.nFilterIndex*2L) - 1;

                for( int i = 0; i < maxFilter; i++ )           // get extension
                    extension = extension + wxStrlen( extension ) + 1;

                m_fileName = AppendExtension(fileNameBuffer, extension);
                wxStrncpy(fileNameBuffer, m_fileName.c_str(), wxMin(m_fileName.length(), wxMAXPATH-1));
                fileNameBuffer[wxMin(m_fileName.length(), wxMAXPATH-1)] = wxT('\0');
            }

            m_path = fileNameBuffer;
            m_fileName = wxFileNameFromPath(fileNameBuffer);
            m_fileNames.Add(m_fileName);
            m_dir = wxPathOnly(fileNameBuffer);
        }
    }
#ifdef __WXDEBUG__
    else
    {
        // common dialog failed - why?
        if ( errCode != 0 )
        {
            // this msg is only for developers so don't translate it
            wxLogError(wxT("Common dialog failed with error code %0lx."),
                       errCode);
        }
        //else: it was just cancelled
    }
#endif // __WXDEBUG__

    return success ? wxID_OK : wxID_CANCEL;

}
int FileDialog::ShowModal()
{
   HWND hWnd = 0;
   if (m_parent) hWnd = (HWND) m_parent->GetHWND();
   if (!hWnd && wxTheApp->GetTopWindow())
      hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND();
   
   static wxChar fileNameBuffer [ wxMAXPATH ];           // the file-name
   wxChar        titleBuffer    [ wxMAXFILE+1+wxMAXEXT ];  // the file-name, without path
   
   *fileNameBuffer = wxT('\0');
   *titleBuffer    = wxT('\0');
   
#if WXWIN_COMPATIBILITY_2_4
   long msw_flags = 0;
   if ( (m_dialogStyle & wxHIDE_READONLY) || (m_dialogStyle & wxSAVE) )
      msw_flags |= OFN_HIDEREADONLY;
#else
   long msw_flags = OFN_HIDEREADONLY;
#endif
   
   if ( m_dialogStyle & wxFILE_MUST_EXIST )
      msw_flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
   /*
    If the window has been moved the programmer is probably
    trying to center or position it.  Thus we set the callback
    or hook function so that we can actually adjust the position.
    Without moving or centering the dlg, it will just stay
    in the upper left of the frame, it does not center
    automatically..  One additional note, when the hook is
    enabled, the PLACES BAR in the dlg (shown on later versions
    of windows (2000 and XP) will automatically be turned off
    according to the MSDN docs.  This is normal.  If the
    programmer needs the PLACES BAR (left side of dlg) they
    just shouldn't move or center the dlg.
    */
   if (m_bMovedWindow) // we need these flags.
   {
      msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK;
#ifndef __WXWINCE__
      msw_flags |= OFN_ENABLESIZING;
#endif
   }
   
   if (m_dialogStyle & wxMULTIPLE )
   {
      // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT
      msw_flags |= OFN_EXPLORER | OFN_ALLOWMULTISELECT;
   }
   
   // if wxCHANGE_DIR flag is not given we shouldn't change the CWD which the
   // standard dialog does by default (notice that under NT it does it anyhow, 
   // OFN_NOCHANGEDIR or not, see below)
   if ( !(m_dialogStyle & wxCHANGE_DIR) )
   {
      msw_flags |= OFN_NOCHANGEDIR;
   }
   
   if ( m_dialogStyle & wxOVERWRITE_PROMPT )
   {
      msw_flags |= OFN_OVERWRITEPROMPT;
   }
   
   if ( m_dialogStyle & wxRESIZE_BORDER )
   {
      msw_flags |= OFN_ENABLESIZING;
   }
   
   if ( m_callback != NULL )
   {
      msw_flags |= OFN_SHOWHELP | OFN_EXPLORER | OFN_ENABLEHOOK;
   }
   
   // We always need EXPLORER and ENABLEHOOK to use our filtering code
   msw_flags |= OFN_EXPLORER | OFN_ENABLEHOOK;
   
   OPENFILENAME of;
   wxZeroMemory(of);
   
   // Allow Places bar to show on supported platforms
   if ( wxGetOsVersion() == wxWINDOWS_NT )
   {
      of.lStructSize       = sizeof(OPENFILENAME);
   }
   else
   {
      of.lStructSize       = OPENFILENAME_SIZE_VERSION_400;
   }
   
   of.hwndOwner         = hWnd;
   of.lpstrTitle        = WXSTRINGCAST m_message;
   of.lpstrFileTitle    = titleBuffer;
   of.nMaxFileTitle     = wxMAXFILE + 1 + wxMAXEXT;    // Windows 3.0 and 3.1
   of.lCustData         = (LPARAM) this;
   
   // Convert forward slashes to backslashes (file selector doesn't like
   // forward slashes) and also squeeze multiple consecutive slashes into one
   // as it doesn't like two backslashes in a row neither
   
   wxString  dir;
   size_t    i, len = m_dir.length();
   dir.reserve(len);
   for ( i = 0; i < len; i++ )
   {
      wxChar ch = m_dir[i];
      switch ( ch )
      {
         case _T('/'):
            // convert to backslash
            ch = _T('\\');
            
            // fall through
            
         case _T('\\'):
            while ( i < len - 1 )
            {
               wxChar chNext = m_dir[i + 1];
               if ( chNext != _T('\\') && chNext != _T('/') )
                  break;
               
               // ignore the next one, unless it is at the start of a UNC path
               if (i > 0)
                  i++;
               else
                  break;
            }
            // fall through
            
            default:
            // normal char
            dir += ch;
      }
   }
   
   of.lpstrInitialDir   = dir.c_str();
   
   of.Flags             = msw_flags;
   of.lpfnHook          = FileDialogHookFunction;
   
   wxArrayString wildDescriptions;
   
   size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, m_FilterGroups);
   
   wxASSERT_MSG( items > 0 , _T("empty wildcard list") );
   
   wxString filterBuffer;
   
   for (i = 0; i < items ; i++)
   {
      filterBuffer += wildDescriptions[i];
      filterBuffer += wxT("|");
      filterBuffer += wxT("*.*");
      filterBuffer += wxT("|");
   }
   
   // Replace | with \0
   for (i = 0; i < filterBuffer.Len(); i++ )
   {
      if ( filterBuffer.GetChar(i) == wxT('|') )
      {
         filterBuffer[i] = wxT('\0');
      }
   }
   
   of.lpstrFilter  = (LPTSTR)filterBuffer.c_str();
   of.nFilterIndex = m_filterIndex + 1;
   
   ParseFilter(of.nFilterIndex);
   
   //=== Setting defaultFileName >>=========================================
   
   wxStrncpy( fileNameBuffer, (const wxChar *)m_fileName, wxMAXPATH-1 );
   fileNameBuffer[ wxMAXPATH-1 ] = wxT('\0');
   
   of.lpstrFile = fileNameBuffer;  // holds returned filename
   of.nMaxFile  = wxMAXPATH;
   
   // we must set the default extension because otherwise Windows would check
   // for the existing of a wrong file with wxOVERWRITE_PROMPT (i.e. if the
   // user types "foo" and the default extension is ".bar" we should force it
   // to check for "foo.bar" existence and not "foo")
   wxString defextBuffer; // we need it to be alive until GetSaveFileName()!
   if (m_dialogStyle & wxSAVE && m_dialogStyle & wxOVERWRITE_PROMPT)
   {
      const wxChar* extension = filterBuffer;
      int maxFilter = (int)(of.nFilterIndex*2L) - 1;
      
      for( int i = 0; i < maxFilter; i++ )           // get extension
         extension = extension + wxStrlen( extension ) + 1;
      
      // use dummy name a to avoid assert in AppendExtension
      defextBuffer = AppendExtension(wxT("a"), extension);
      if (defextBuffer.StartsWith(wxT("a.")))
      {
         defextBuffer.Mid(2);
         of.lpstrDefExt = defextBuffer.c_str();
      }
   }
   
   // store off before the standard windows dialog can possibly change it 
   const wxString cwdOrig = wxGetCwd(); 
   
   //== Execute FileDialog >>=================================================
   
   bool success = (m_dialogStyle & wxSAVE ? GetSaveFileName(&of)
                   : GetOpenFileName(&of)) != 0;
   
#ifdef __WXWINCE__
   DWORD errCode = GetLastError();
#else
   DWORD errCode = CommDlgExtendedError();
   
   // GetOpenFileName will always change the current working directory on 
   // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag 
   // OFN_NOCHANGEDIR has no effect.  If the user did not specify wxCHANGE_DIR 
   // let's restore the current working directory to what it was before the 
   // dialog was shown (assuming this behavior extends to Windows Server 2003 
   // seems safe). 
   if ( success && 
       (msw_flags & OFN_NOCHANGEDIR) && 
       wxGetOsVersion() == wxWINDOWS_NT ) 
   { 
      wxSetWorkingDirectory(cwdOrig); 
   } 
   
#ifdef __WIN32__
   if (!success && (errCode == CDERR_STRUCTSIZE))
   {
      // The struct size has changed so try a smaller or bigger size
      
      int oldStructSize = of.lStructSize;
      of.lStructSize       = oldStructSize - (sizeof(void *) + 2*sizeof(DWORD));
      success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0)
      : (GetOpenFileName(&of) != 0);
      errCode = CommDlgExtendedError();
      
      if (!success && (errCode == CDERR_STRUCTSIZE))
      {
         of.lStructSize       = oldStructSize + (sizeof(void *) + 2*sizeof(DWORD));
         success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0)
         : (GetOpenFileName(&of) != 0);
      }
   }
#endif // __WIN32__
#endif // __WXWINCE__
   
   if ( success )
   {
      m_fileNames.Empty();
      
      if ( ( m_dialogStyle & wxMULTIPLE ) &&
#if defined(OFN_EXPLORER)
          ( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
#else
          ( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
#endif // OFN_EXPLORER
          )
      {
#if defined(OFN_EXPLORER)
         m_dir = fileNameBuffer;
         i = of.nFileOffset;
         m_fileName = &fileNameBuffer[i];
         m_fileNames.Add(m_fileName);
         i += m_fileName.Len() + 1;
         
         while (fileNameBuffer[i] != wxT('\0'))
         {
            m_fileNames.Add(&fileNameBuffer[i]);
            i += wxStrlen(&fileNameBuffer[i]) + 1;
         }
#else
         wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n"));
         m_dir = toke.GetNextToken();
         m_fileName = toke.GetNextToken();
         m_fileNames.Add(m_fileName);
         
         while (toke.HasMoreTokens())
            m_fileNames.Add(toke.GetNextToken());
#endif // OFN_EXPLORER
         
         wxString dir(m_dir);
         if ( m_dir.Last() != _T('\\') )
            dir += _T('\\');
         
         m_path = dir + m_fileName;
         m_filterIndex = (int)of.nFilterIndex - 1;
      }
      else
      {
         //=== Adding the correct extension >>=================================
         m_filterIndex = (int)of.nFilterIndex - 1;
         
#if 0
         // LLL:  Removed to prevent adding extension during Export
         //       processing.
         
         if ( !of.nFileExtension ||
             (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
         {
            // User has typed a filename without an extension:
            const wxChar* extension = filterBuffer;
            int   maxFilter = (int)(of.nFilterIndex*2L) - 1;
            
            for( int i = 0; i < maxFilter; i++ )           // get extension
               extension = extension + wxStrlen( extension ) + 1;
            
            m_fileName = AppendExtension(fileNameBuffer, extension);
            wxStrncpy(fileNameBuffer, m_fileName.c_str(), wxMin(m_fileName.Len(), wxMAXPATH-1));
            fileNameBuffer[wxMin(m_fileName.Len(), wxMAXPATH-1)] = wxT('\0');
         }
#endif
         m_path = fileNameBuffer;
         m_fileName = wxFileNameFromPath(fileNameBuffer);
         m_fileNames.Add(m_fileName);
         m_dir = wxPathOnly(fileNameBuffer);
      }
   }
   else
   {
      // common dialog failed - why?
#ifdef __WXDEBUG__
#ifdef __WXWINCE__
      if (errCode == 0)
      {
         // OK, user cancelled the dialog
      }
      else if (errCode == ERROR_INVALID_PARAMETER)
      {
         wxLogError(wxT("Invalid parameter passed to file dialog function."));
      }
      else if (errCode == ERROR_OUTOFMEMORY)
      {
         wxLogError(wxT("Out of memory when calling file dialog function."));
      }
      else if (errCode == ERROR_CALL_NOT_IMPLEMENTED)
      {
         wxLogError(wxT("Call not implemented when calling file dialog function."));
      }
      else
      {
         wxLogError(wxT("Unknown error %d when calling file dialog function."), errCode);
      }
#else
      DWORD dwErr = CommDlgExtendedError();
      if ( dwErr != 0 )
      {
         // this msg is only for developers
         wxLogError(wxT("Common dialog failed with error code %0lx."),
                    dwErr);
      }
      //else: it was just cancelled
#endif
#endif
   }
   
   return success ? wxID_OK : wxID_CANCEL;
   
}
Beispiel #13
0
wxString wxFileSelector(const wxChar *title,
                               const wxChar *defaultDir,
                               const wxChar *defaultFileName,
                               const wxChar *defaultExtension,
                               const wxChar *filter,
                               int flags,
                               wxWindow *parent,
                               int x, int y)
{
    // The defaultExtension, if non-NULL, is
    // appended to the filename if the user fails to type an extension. The new
    // implementation (taken from wxFileSelectorEx) appends the extension
    // automatically, by looking at the filter specification. In fact this
    // should be better than the native Microsoft implementation because
    // Windows only allows *one* default extension, whereas here we do the
    // right thing depending on the filter the user has chosen.

    // If there's a default extension specified but no filter, we create a
    // suitable filter.

    wxString filter2;
    if ( defaultExtension && !filter )
        filter2 = wxString(wxT("*.")) + defaultExtension;
    else if ( filter )
        filter2 = filter;

    wxString defaultDirString;
    if (defaultDir)
        defaultDirString = defaultDir;

    wxString defaultFilenameString;
    if (defaultFileName)
        defaultFilenameString = defaultFileName;

    wxFileDialog fileDialog(parent, title, defaultDirString,
                            defaultFilenameString, filter2,
                            flags, wxPoint(x, y));

   // if filter is of form "All files (*)|*|..." set correct filter index
    if((wxStrlen(defaultExtension) != 0) && (filter2.Find(wxT('|')) != wxNOT_FOUND))
    {
        int filterIndex = 0;

        wxArrayString descriptions, filters;
        // don't care about errors, handled already by wxFileDialog
        (void)wxParseCommonDialogsFilter(filter2, descriptions, filters);
        for (size_t n=0; n<filters.GetCount(); n++)
        {
            if (filters[n].Contains(defaultExtension))
            {
                filterIndex = n;
                        break;
            }
        }

        if (filterIndex > 0)
            fileDialog.SetFilterIndex(filterIndex);
    }

    wxString filename;
    if ( fileDialog.ShowModal() == wxID_OK )
    {
        filename = fileDialog.GetPath();
    }

    return filename;
}