diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 5bfa96d4cb0..63fadd3e728 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -588,6 +588,13 @@ extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title); */ extern char *GHOST_GetTitle(GHOST_WindowHandle windowhandle); +/** + * Sets the file name represented by this window. + * \param filepath: The file directory. + * \return Indication if the backend implements file associated with window. + */ +extern GHOST_TSuccess GHOST_SetPath(GHOST_WindowHandle windowhandle, const char *filepath); + /** * Returns the window rectangle dimensions. * These are screen coordinates. diff --git a/intern/ghost/GHOST_IWindow.hh b/intern/ghost/GHOST_IWindow.hh index a88b1be1a2b..3899324ff15 100644 --- a/intern/ghost/GHOST_IWindow.hh +++ b/intern/ghost/GHOST_IWindow.hh @@ -81,6 +81,12 @@ class GHOST_IWindow { */ virtual std::string getTitle() const = 0; + /** + * Sets the file name represented by this window. + * \param filepath: The file directory. + */ + virtual GHOST_TSuccess setPath(const char *filepath) = 0; + /** * Returns the window rectangle dimensions. * These are screen coordinates. diff --git a/intern/ghost/intern/GHOST_C-api.cc b/intern/ghost/intern/GHOST_C-api.cc index 5dcc9bbe9db..a9d9281e673 100644 --- a/intern/ghost/intern/GHOST_C-api.cc +++ b/intern/ghost/intern/GHOST_C-api.cc @@ -600,6 +600,13 @@ char *GHOST_GetTitle(GHOST_WindowHandle windowhandle) return ctitle; } +GHOST_TSuccess GHOST_SetPath(GHOST_WindowHandle windowhandle, const char *filepath) +{ + GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; + + return window->setPath(filepath); +} + GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle) { const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle; diff --git a/intern/ghost/intern/GHOST_Window.hh b/intern/ghost/intern/GHOST_Window.hh index c059418b508..bccfe43814d 100644 --- a/intern/ghost/intern/GHOST_Window.hh +++ b/intern/ghost/intern/GHOST_Window.hh @@ -84,6 +84,11 @@ class GHOST_Window : public GHOST_IWindow { */ virtual void *getOSWindow() const override; + virtual GHOST_TSuccess setPath(const char * /*filepath*/) override + { + return GHOST_kFailure; + } + /** * Returns the current cursor shape. * \return The current cursor shape. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.hh b/intern/ghost/intern/GHOST_WindowCocoa.hh index 4d4389c3448..e773681812a 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.hh +++ b/intern/ghost/intern/GHOST_WindowCocoa.hh @@ -85,6 +85,12 @@ class GHOST_WindowCocoa : public GHOST_Window { */ std::string getTitle() const; + /** + * Sets the file name represented by this window. + * \param filepath: The file directory. + */ + GHOST_TSuccess setPath(const char *filepath); + /** * Returns the window rectangle dimensions. * The dimensions are given in screen coordinates that are diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 29df49961bc..e6ef790de20 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -494,39 +494,7 @@ void GHOST_WindowCocoa::setTitle(const char *title) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; - - // Set associated file if applicable - if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { - NSRange fileStrRange; - NSString *associatedFileName; - int len; - - fileStrRange.location = [windowTitle rangeOfString:@"["].location + 1; - len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; - - if (len > 0) { - fileStrRange.length = len; - associatedFileName = [windowTitle substringWithRange:fileStrRange]; - [m_window setTitle:[associatedFileName lastPathComponent]]; - - @try - { - [m_window setRepresentedFilename:associatedFileName]; - } - @catch (NSException *e) - { - printf("\nInvalid file path given in window title"); - } - } - else { - [m_window setTitle:windowTitle]; - [m_window setRepresentedFilename:@""]; - } - } - else { - [m_window setTitle:windowTitle]; - [m_window setRepresentedFilename:@""]; - } + [m_window setTitle:windowTitle]; [windowTitle release]; [pool drain]; @@ -550,6 +518,30 @@ std::string GHOST_WindowCocoa::getTitle() const return title; } +GHOST_TSuccess GHOST_WindowCocoa::setPath(const char *filepath) +{ + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setAssociatedFile(): window invalid"); + GHOST_TSuccess success = GHOST_kSuccess; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSString *associatedFileName = [[NSString alloc] initWithCString:filepath encoding:NSUTF8StringEncoding]; + + @try + { + [m_window setRepresentedFilename:associatedFileName]; + } + @catch (NSException *e) + { + printf("\nInvalid file path given for window"); + success = GHOST_kFailure; + } + + [associatedFileName release]; + [pool drain]; + + return success; +} + void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect &bounds) const { NSRect rect; diff --git a/intern/ghost/intern/GHOST_WindowNULL.hh b/intern/ghost/intern/GHOST_WindowNULL.hh index 1340cc4965d..7e302b1ee88 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.hh +++ b/intern/ghost/intern/GHOST_WindowNULL.hh @@ -75,6 +75,10 @@ class GHOST_WindowNULL : public GHOST_Window { { return "untitled"; } + GHOST_TSuccess setPath(const char * /*filepath*/) override + { + return GHOST_kFailure; + } void getWindowBounds(GHOST_Rect &bounds) const override { getClientBounds(bounds); diff --git a/source/blender/windowmanager/intern/wm_window.cc b/source/blender/windowmanager/intern/wm_window.cc index e7b58a6e4f2..9d0ccf4a635 100644 --- a/source/blender/windowmanager/intern/wm_window.cc +++ b/source/blender/windowmanager/intern/wm_window.cc @@ -485,28 +485,34 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) * because #WM_window_open always sets window title. */ } else if (win->ghostwin) { - char str[sizeof(Main::filepath) + 24]; - const char *filepath = BKE_main_blendfile_path_from_global(); - const char *filename = BLI_path_basename(filepath); - const bool has_filepath = filepath[0] != '\0'; - const bool has_directory = has_filepath && (filepath != filename); - SNPRINTF(str, - "%s %s%s%s%.*s%s - Blender %s", - wm->file_saved ? "" : "*", - has_filepath ? filename : IFACE_("(Unsaved)"), - G_MAIN->recovered ? IFACE_(" (Recovered)") : "", - has_directory ? " [" : "", - has_directory ? int(filename - filepath) : 0, - has_directory ? filepath : "", - has_directory ? "]" : "", - BKE_blender_version_string_compact()); - GHOST_SetTitle(static_cast(win->ghostwin), str); + GHOST_WindowHandle handle = static_cast(win->ghostwin); - /* Informs GHOST of unsaved changes, to set window modified visual indicator (macOS) - * and to give hint of unsaved changes for a user warning mechanism in case of OS application - * terminate request (e.g. OS Shortcut Alt+F4, Command+Q, (...), or session end). */ - GHOST_SetWindowModifiedState(static_cast(win->ghostwin), - bool(!wm->file_saved)); + std::string filepath = BKE_main_blendfile_path_from_global(); + std::string filename = BLI_path_basename(filepath.c_str()); + bool has_filepath = !filepath.empty(); + bool include_directory = has_filepath && (filepath != filename) && + GHOST_SetPath(handle, filepath.c_str()) == GHOST_kFailure; + + std::string str; + str += wm->file_saved ? " " : "* "; + str += has_filepath ? filename : IFACE_("(Unsaved)"); + if (G_MAIN->recovered) { + str += IFACE_(" (Recovered)"); + } + + if (include_directory) { + str += " [" + filepath.substr(0, filepath.length() - filename.length()) + "]"; + } + + str += " - Blender "; + str += BKE_blender_version_string_compact(); + + GHOST_SetTitle(handle, str.c_str()); + + /* Informs GHOST of unsaved changes to set the window modified visual indicator (macOS) + * and to give a hint of unsaved changes for a user warning mechanism in case of OS application + * terminate request (e.g., OS Shortcut Alt+F4, Command+Q, (...) or session end). */ + GHOST_SetWindowModifiedState(handle, static_cast(!wm->file_saved)); } }