diff --git a/contrib/brushexport/callbacks.cpp b/contrib/brushexport/callbacks.cpp index b31eeea3..f7f973f7 100644 --- a/contrib/brushexport/callbacks.cpp +++ b/contrib/brushexport/callbacks.cpp @@ -6,6 +6,8 @@ #include "qerplugin.h" #include "debugging/debugging.h" #include "os/path.h" +#include "os/file.h" +#include "stream/stringstream.h" #include "support.h" #include "export.h" @@ -18,11 +20,28 @@ void OnExportClicked( GtkButton* button, gpointer choose_path ){ GtkWidget* window = lookup_widget( GTK_WIDGET( button ), "w_plugplug2" ); ASSERT_NOTNULL( window ); if( choose_path ){ - const char* cpath = GlobalRadiant().m_pfnFileDialog( window, false, "Save as Obj", 0, 0, false, false, true ); + StringOutputStream buffer( 1024 ); + + if( !s_export_path.empty() ){ + buffer << s_export_path.c_str(); + } + if( buffer.empty() ){ + buffer << GlobalRadiant().getEnginePath() << GlobalRadiant().getGameName() << "/models/"; + + if ( !file_readable( buffer.c_str() ) ) { + // just go to fsmain + buffer.clear(); + buffer << GlobalRadiant().getEnginePath() << GlobalRadiant().getGameName(); + } + } + + const char* cpath = GlobalRadiant().m_pfnFileDialog( window, false, "Save as Obj", buffer.c_str(), 0, false, false, true ); if ( !cpath ) { return; } s_export_path = cpath; + if( !string_equal_suffix_nocase( s_export_path.c_str(), ".obj" ) ) + s_export_path += ".obj"; // enable button to reexport with the selected name GtkWidget* b_export = lookup_widget( GTK_WIDGET( button ), "b_export" ); ASSERT_NOTNULL( b_export ); diff --git a/contrib/brushexport/export.cpp b/contrib/brushexport/export.cpp index 6ed858d9..369a007e 100644 --- a/contrib/brushexport/export.cpp +++ b/contrib/brushexport/export.cpp @@ -174,7 +174,7 @@ bool WriteToFile( const std::string& path, collapsemode mode ) const; bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode mode ) const { std::string objFile = path; - if ( path.compare( path.length() - 4, 4, ".obj" ) != 0 ) { + if ( !string_equal_suffix_nocase( objFile.c_str(), ".obj" ) ) { objFile += ".obj"; } diff --git a/libs/gtkutil/filechooser.cpp b/libs/gtkutil/filechooser.cpp index 101e8c88..5b29cb00 100644 --- a/libs/gtkutil/filechooser.cpp +++ b/libs/gtkutil/filechooser.cpp @@ -176,14 +176,15 @@ const char* file_dialog_show( GtkWidget* parent, bool open, const char* title, c { *w++ = ( *r == '/' ) ? G_DIR_SEPARATOR : *r; } - // remove separator from end of path if required - if ( *( w - 1 ) == G_DIR_SEPARATOR ) { - --w; - } // terminate string *w = '\0'; - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), new_path.data() ); + if( file_is_directory( new_path.data() ) ){ // folder path + gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), new_path.data() ); + } + else{ // file path + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( dialog ), new_path.data() ); + } } // we should add all important paths as shortcut folder... diff --git a/libs/gtkutil/filechooser.h b/libs/gtkutil/filechooser.h index f4610bea..49140460 100644 --- a/libs/gtkutil/filechooser.h +++ b/libs/gtkutil/filechooser.h @@ -26,7 +26,7 @@ /// GTK+ file-chooser dialogs. typedef struct _GtkWidget GtkWidget; -const char* file_dialog( GtkWidget *parent, bool open, const char* title, const char* path = 0, const char* pattern = 0, bool want_load = false, bool want_import = false, bool want_save = false ); +const char* file_dialog( GtkWidget *parent, bool open, const char* title, const char* path = nullptr, const char* pattern = nullptr, bool want_load = false, bool want_import = false, bool want_save = false ); /// \brief Prompts the user to browse for a directory. diff --git a/radiant/entity.cpp b/radiant/entity.cpp index afea0f4a..b0b17a8d 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -585,18 +585,25 @@ void Entity_setColour(){ } } -const char* misc_model_dialog( GtkWidget* parent ){ +const char* misc_model_dialog( GtkWidget* parent, const char* filepath ){ StringOutputStream buffer( 1024 ); - buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; + if( !string_empty( filepath ) ){ + const char* root = GlobalFileSystem().findFile( filepath ); + if( !string_empty( root ) && file_is_directory( root ) ) + buffer << root << filepath; + } + if( buffer.empty() ){ + buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; - if ( !file_readable( buffer.c_str() ) ) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str(); + if ( !file_readable( buffer.c_str() ) ) { + // just go to fsmain + buffer.clear(); + buffer << g_qeglobals.m_userGamePath.c_str(); + } } - const char *filename = file_dialog( parent, TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name() ); + const char *filename = file_dialog( parent, true, "Choose Model", buffer.c_str(), ModelLoader::Name() ); if ( filename != 0 ) { // use VFS to get the correct relative path const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) ); diff --git a/radiant/entity.h b/radiant/entity.h index 4638d6a7..79abdcc4 100644 --- a/radiant/entity.h +++ b/radiant/entity.h @@ -31,7 +31,7 @@ void Scene_EntitySetClassname_Selected( const char* classname ); typedef struct _GtkWidget GtkWidget; -const char* misc_model_dialog( GtkWidget* parent ); +const char* misc_model_dialog( GtkWidget* parent, const char* filepath = "" ); void Entity_setColour(); typedef struct _GtkMenu GtkMenu; diff --git a/radiant/entityinspector.cpp b/radiant/entityinspector.cpp index b7acd486..b2b4e570 100644 --- a/radiant/entityinspector.cpp +++ b/radiant/entityinspector.cpp @@ -312,7 +312,7 @@ void update(){ } typedef MemberCaller UpdateCaller; void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ - const char *filename = misc_model_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ) ); + const char *filename = misc_model_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ), gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ) ); if ( filename != 0 ) { setPath( filename ); @@ -322,18 +322,25 @@ void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ typedef MemberCaller1 BrowseCaller; }; -const char* browse_sound( GtkWidget* parent ){ +const char* browse_sound( GtkWidget* parent, const char* filepath ){ StringOutputStream buffer( 1024 ); - buffer << g_qeglobals.m_userGamePath.c_str() << "sound/"; + if( !string_empty( filepath ) ){ + const char* root = GlobalFileSystem().findFile( filepath ); + if( !string_empty( root ) && file_is_directory( root ) ) + buffer << root << filepath; + } + if( buffer.empty() ){ + buffer << g_qeglobals.m_userGamePath.c_str() << "sound/"; - if ( !file_readable( buffer.c_str() ) ) { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str(); + if ( !file_readable( buffer.c_str() ) ) { + // just go to fsmain + buffer.clear(); + buffer << g_qeglobals.m_userGamePath.c_str(); + } } - const char* filename = file_dialog( parent, TRUE, "Open Wav File", buffer.c_str(), "sound" ); + const char* filename = file_dialog( parent, true, "Open Wav File", buffer.c_str(), "sound" ); if ( filename != 0 ) { const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) ); if ( relative == filename ) { @@ -375,7 +382,7 @@ void update(){ } typedef MemberCaller UpdateCaller; void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ - const char *filename = browse_sound( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ) ); + const char *filename = browse_sound( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ), gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ) ); if ( filename != 0 ) { setPath( filename ); diff --git a/radiant/gtkmisc.cpp b/radiant/gtkmisc.cpp index 7f9b52f2..1f0b26ba 100644 --- a/radiant/gtkmisc.cpp +++ b/radiant/gtkmisc.cpp @@ -164,7 +164,7 @@ bool OpenGLFont_dialog( GtkWidget *parent, const char* font, CopiedString &newfo } void button_clicked_entry_browse_file( GtkWidget* widget, GtkEntry* entry ){ - const char *filename = file_dialog( gtk_widget_get_toplevel( widget ), TRUE, "Choose File", gtk_entry_get_text( entry ) ); + const char *filename = file_dialog( gtk_widget_get_toplevel( widget ), true, "Choose File", gtk_entry_get_text( entry ) ); if ( filename != 0 ) { gtk_entry_set_text( entry, filename ); diff --git a/radiant/map.cpp b/radiant/map.cpp index 4ab84a96..f679ab18 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -1982,15 +1982,18 @@ const char* getMapsPath(){ } const char* map_open( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getMapsPath(), MapFormat::Name(), true, false, false ); + const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name(), true, false, false ); } const char* map_import( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getMapsPath(), MapFormat::Name(), false, true, false ); + const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name(), false, true, false ); } const char* map_save( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), FALSE, title, getMapsPath(), MapFormat::Name(), false, false, true ); + const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), false, title, path, MapFormat::Name(), false, false, true ); } void OpenMap(){ diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 1bbefe02..6ff592b5 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -1341,7 +1341,7 @@ const char* BackgroundImage::background_image_dialog(){ buffer << g_qeglobals.m_userGamePath.c_str(); } - const char *filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, "Background Image", buffer.c_str(), NULL ); + const char *filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, "Background Image", buffer.c_str() ); if ( filename != 0 ) { // use VFS to get the correct relative path const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) );