WIP: Brush assets project #106303
|
@ -19,6 +19,11 @@ struct ReportList;
|
||||||
struct UserDef;
|
struct UserDef;
|
||||||
struct WorkspaceConfigFileData;
|
struct WorkspaceConfigFileData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The suffix used for blendfiles managed by the asset system.
|
||||||
|
*/
|
||||||
|
#define BLENDER_ASSET_FILE_SUFFIX ".asset.blend"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether given path ends with a blend file compatible extension
|
* Check whether given path ends with a blend file compatible extension
|
||||||
* (`.blend`, `.ble` or `.blend.gz`).
|
* (`.blend`, `.ble` or `.blend.gz`).
|
||||||
|
|
|
@ -142,6 +142,14 @@ struct Main {
|
||||||
* could try to use more refined detection on load. */
|
* could try to use more refined detection on load. */
|
||||||
bool has_forward_compatibility_issues;
|
bool has_forward_compatibility_issues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently opened .blend file was created as an asset library storage.
|
||||||
|
*
|
||||||
|
* This is used to warn the user when they try to save it from Blender UI, since this will likely
|
||||||
|
* break the automatic management from the asset library system.
|
||||||
|
*/
|
||||||
|
bool is_asset_repository;
|
||||||
|
|
||||||
/** Commit timestamp from `buildinfo`. */
|
/** Commit timestamp from `buildinfo`. */
|
||||||
uint64_t build_commit_timestamp;
|
uint64_t build_commit_timestamp;
|
||||||
/** Commit Hash from `buildinfo`. */
|
/** Commit Hash from `buildinfo`. */
|
||||||
|
@ -299,6 +307,17 @@ void BKE_main_merge(Main *bmain_dst, Main **r_bmain_src, MainMergeReport &report
|
||||||
*/
|
*/
|
||||||
bool BKE_main_is_empty(Main *bmain);
|
bool BKE_main_is_empty(Main *bmain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the bmain has issues, e.g. for reporting in the status bar.
|
||||||
|
*/
|
||||||
|
bool BKE_main_has_issues(const Main *bmain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether user confirmation should be required when overwriting this `bmain` into its source
|
||||||
|
* blendfile.
|
||||||
|
*/
|
||||||
|
bool BKE_main_needs_overwrite_confirm(const Main *bmain);
|
||||||
|
|
||||||
void BKE_main_lock(Main *bmain);
|
void BKE_main_lock(Main *bmain);
|
||||||
void BKE_main_unlock(Main *bmain);
|
void BKE_main_unlock(Main *bmain);
|
||||||
|
|
||||||
|
|
|
@ -853,6 +853,9 @@ static void setup_app_data(bContext *C,
|
||||||
* nullptr curscreen)... */
|
* nullptr curscreen)... */
|
||||||
else if (ELEM(nullptr, bfd->curscreen, bfd->curscene)) {
|
else if (ELEM(nullptr, bfd->curscreen, bfd->curscene)) {
|
||||||
BKE_report(reports->reports, RPT_WARNING, "Library file, loading empty scene");
|
BKE_report(reports->reports, RPT_WARNING, "Library file, loading empty scene");
|
||||||
|
if (blender::StringRefNull(bfd->main->filepath).endswith(BLENDER_ASSET_FILE_SUFFIX)) {
|
||||||
|
bfd->main->is_asset_repository = true;
|
||||||
|
}
|
||||||
mode = LOAD_UI_OFF;
|
mode = LOAD_UI_OFF;
|
||||||
}
|
}
|
||||||
else if (G.fileflags & G_FILE_NO_UI) {
|
else if (G.fileflags & G_FILE_NO_UI) {
|
||||||
|
|
|
@ -444,6 +444,16 @@ bool BKE_main_is_empty(Main *bmain)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BKE_main_has_issues(const Main *bmain)
|
||||||
|
{
|
||||||
|
return bmain->has_forward_compatibility_issues || bmain->is_asset_repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BKE_main_needs_overwrite_confirm(const Main *bmain)
|
||||||
|
{
|
||||||
|
return bmain->has_forward_compatibility_issues || bmain->is_asset_repository;
|
||||||
|
}
|
||||||
|
|
||||||
void BKE_main_lock(Main *bmain)
|
void BKE_main_lock(Main *bmain)
|
||||||
{
|
{
|
||||||
BLI_spin_lock((SpinLock *)bmain->lock);
|
BLI_spin_lock((SpinLock *)bmain->lock);
|
||||||
|
|
|
@ -6558,13 +6558,47 @@ void uiTemplateInputStatus(uiLayout *layout, bContext *C)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ui_template_status_info_warnings_messages(Main *bmain,
|
||||||
|
Scene *scene,
|
||||||
|
ViewLayer *view_layer,
|
||||||
|
std::string &warning_message,
|
||||||
|
std::string ®ular_message,
|
||||||
|
std::string &tooltip_message)
|
||||||
|
{
|
||||||
|
tooltip_message = "";
|
||||||
|
char statusbar_info_flag = U.statusbar_flag;
|
||||||
|
|
||||||
|
if (bmain->has_forward_compatibility_issues) {
|
||||||
|
warning_message = ED_info_statusbar_string_ex(
|
||||||
|
bmain, scene, view_layer, STATUSBAR_SHOW_VERSION);
|
||||||
|
statusbar_info_flag &= ~STATUSBAR_SHOW_VERSION;
|
||||||
|
|
||||||
|
char writer_ver_str[12];
|
||||||
|
BKE_blender_version_blendfile_string_from_values(
|
||||||
|
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, -1);
|
||||||
|
tooltip_message += fmt::format(RPT_("File saved by newer Blender\n({}), expect loss of data"),
|
||||||
|
writer_ver_str);
|
||||||
|
}
|
||||||
|
if (bmain->is_asset_repository) {
|
||||||
|
if (!tooltip_message.empty()) {
|
||||||
|
tooltip_message += "\n\n";
|
||||||
|
}
|
||||||
|
tooltip_message += RPT_(
|
||||||
|
"This file is managed by the Blender asset system\n"
|
||||||
|
"By editing it as a regular blend file, it will no longer\n"
|
||||||
|
"be possible to update its assets through the asset browser");
|
||||||
|
}
|
||||||
|
|
||||||
|
regular_message = ED_info_statusbar_string_ex(bmain, scene, view_layer, statusbar_info_flag);
|
||||||
|
}
|
||||||
|
|
||||||
void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
||||||
{
|
{
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
|
|
||||||
if (!bmain->has_forward_compatibility_issues) {
|
if (!BKE_main_has_issues(bmain)) {
|
||||||
const char *status_info_txt = ED_info_statusbar_string(bmain, scene, view_layer);
|
const char *status_info_txt = ED_info_statusbar_string(bmain, scene, view_layer);
|
||||||
uiItemL(layout, status_info_txt, ICON_NONE);
|
uiItemL(layout, status_info_txt, ICON_NONE);
|
||||||
return;
|
return;
|
||||||
|
@ -6573,13 +6607,13 @@ void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
||||||
/* Blender version part is shown as warning area when there are forward compatibility issues with
|
/* Blender version part is shown as warning area when there are forward compatibility issues with
|
||||||
* currently loaded .blend file. */
|
* currently loaded .blend file. */
|
||||||
|
|
||||||
const char *status_info_txt = ED_info_statusbar_string_ex(
|
std::string warning_message;
|
||||||
bmain, scene, view_layer, (U.statusbar_flag & ~STATUSBAR_SHOW_VERSION));
|
std::string regular_message;
|
||||||
uiItemL(layout, status_info_txt, ICON_NONE);
|
std::string tooltip_message;
|
||||||
|
ui_template_status_info_warnings_messages(
|
||||||
|
bmain, scene, view_layer, warning_message, regular_message, tooltip_message);
|
||||||
|
|
||||||
status_info_txt = ED_info_statusbar_string_ex(bmain, scene, view_layer, STATUSBAR_SHOW_VERSION);
|
uiItemL(layout, regular_message.c_str(), ICON_NONE);
|
||||||
|
|
||||||
uiBut *but;
|
|
||||||
|
|
||||||
const uiStyle *style = UI_style_get();
|
const uiStyle *style = UI_style_get();
|
||||||
uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
|
uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
|
||||||
|
@ -6587,27 +6621,28 @@ void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
||||||
eUIEmbossType previous_emboss = UI_block_emboss_get(block);
|
eUIEmbossType previous_emboss = UI_block_emboss_get(block);
|
||||||
|
|
||||||
UI_fontstyle_set(&style->widgetlabel);
|
UI_fontstyle_set(&style->widgetlabel);
|
||||||
int width = int(
|
const int width = max_ii(int(BLF_width(style->widgetlabel.uifont_id,
|
||||||
BLF_width(style->widgetlabel.uifont_id, status_info_txt, strlen(status_info_txt)));
|
warning_message.c_str(),
|
||||||
width = max_ii(width, int(10 * UI_SCALE_FAC));
|
warning_message.length())),
|
||||||
|
int(10 * UI_SCALE_FAC));
|
||||||
|
|
||||||
UI_block_align_begin(block);
|
UI_block_align_begin(block);
|
||||||
|
|
||||||
/* Background for icon. */
|
/* Background for icon. */
|
||||||
but = uiDefBut(block,
|
uiBut *but = uiDefBut(block,
|
||||||
UI_BTYPE_ROUNDBOX,
|
UI_BTYPE_ROUNDBOX,
|
||||||
0,
|
0,
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
UI_UNIT_X + (6 * UI_SCALE_FAC),
|
UI_UNIT_X + (6 * UI_SCALE_FAC),
|
||||||
UI_UNIT_Y,
|
UI_UNIT_Y,
|
||||||
nullptr,
|
nullptr,
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"");
|
"");
|
||||||
/* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
|
/* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
|
||||||
UI_GetThemeColorType4ubv(TH_INFO_WARNING, SPACE_INFO, but->col);
|
UI_GetThemeColorType4ubv(TH_INFO_WARNING, SPACE_INFO, but->col);
|
||||||
|
|
||||||
|
@ -6634,14 +6669,13 @@ void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
||||||
UI_block_align_end(block);
|
UI_block_align_end(block);
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||||
|
|
||||||
/* The report icon itself. */
|
/* Tool tips have to be static currently.
|
||||||
static char compat_error_msg[256];
|
* FIXME This is a horrible requirement from uiBut, should probably just store an std::string for
|
||||||
char writer_ver_str[12];
|
* the tooltip as well? */
|
||||||
BKE_blender_version_blendfile_string_from_values(
|
static char tooltip_static_storage[256];
|
||||||
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, -1);
|
BLI_strncpy(tooltip_static_storage, tooltip_message.c_str(), sizeof(tooltip_static_storage));
|
||||||
SNPRINTF(compat_error_msg,
|
|
||||||
RPT_("File saved by newer Blender\n(%s), expect loss of data"),
|
/* The warning icon itself. */
|
||||||
writer_ver_str);
|
|
||||||
but = uiDefIconBut(block,
|
but = uiDefIconBut(block,
|
||||||
UI_BTYPE_BUT,
|
UI_BTYPE_BUT,
|
||||||
0,
|
0,
|
||||||
|
@ -6655,25 +6689,27 @@ void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
compat_error_msg);
|
tooltip_static_storage);
|
||||||
UI_GetThemeColorType4ubv(TH_INFO_WARNING_TEXT, SPACE_INFO, but->col);
|
UI_GetThemeColorType4ubv(TH_INFO_WARNING_TEXT, SPACE_INFO, but->col);
|
||||||
but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
|
but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
|
||||||
|
|
||||||
/* The report message. */
|
/* The warning message, if any. */
|
||||||
but = uiDefBut(block,
|
if (!warning_message.empty()) {
|
||||||
UI_BTYPE_BUT,
|
but = uiDefBut(block,
|
||||||
0,
|
UI_BTYPE_BUT,
|
||||||
status_info_txt,
|
0,
|
||||||
UI_UNIT_X,
|
warning_message.c_str(),
|
||||||
0,
|
UI_UNIT_X,
|
||||||
short(width + UI_UNIT_X),
|
0,
|
||||||
UI_UNIT_Y,
|
short(width + UI_UNIT_X),
|
||||||
nullptr,
|
UI_UNIT_Y,
|
||||||
0.0f,
|
nullptr,
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
0.0f,
|
0.0f,
|
||||||
compat_error_msg);
|
0.0f,
|
||||||
|
tooltip_static_storage);
|
||||||
|
}
|
||||||
|
|
||||||
UI_block_emboss_set(block, previous_emboss);
|
UI_block_emboss_set(block, previous_emboss);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3552,8 +3552,8 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blendfile_path[0] != '\0') {
|
if (blendfile_path[0] != '\0') {
|
||||||
if (CTX_data_main(C)->has_forward_compatibility_issues) {
|
if (BKE_main_needs_overwrite_confirm(CTX_data_main(C))) {
|
||||||
wm_save_file_forwardcompat_dialog(C, op);
|
wm_save_file_overwrite_dialog(C, op);
|
||||||
ret = OPERATOR_INTERFACE;
|
ret = OPERATOR_INTERFACE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3907,49 +3907,62 @@ static void wm_free_operator_properties_callback(void *user_data)
|
||||||
IDP_FreeProperty(properties);
|
IDP_FreeProperty(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *save_file_forwardcompat_dialog_name = "save_file_forwardcompat_popup";
|
static const char *save_file_overwrite_dialog_name = "save_file_overwrite_popup";
|
||||||
|
|
||||||
static void file_forwardcompat_detailed_info_show(uiLayout *parent_layout, Main *bmain)
|
static void file_overwrite_detailed_info_show(uiLayout *parent_layout, Main *bmain)
|
||||||
{
|
{
|
||||||
uiLayout *layout = uiLayoutColumn(parent_layout, true);
|
uiLayout *layout = uiLayoutColumn(parent_layout, true);
|
||||||
/* Trick to make both lines of text below close enough to look like they are part of a same
|
/* Trick to make both lines of text below close enough to look like they are part of a same
|
||||||
* block. */
|
* block. */
|
||||||
uiLayoutSetScaleY(layout, 0.70f);
|
uiLayoutSetScaleY(layout, 0.70f);
|
||||||
|
|
||||||
char writer_ver_str[16];
|
if (bmain->has_forward_compatibility_issues) {
|
||||||
char current_ver_str[16];
|
char writer_ver_str[16];
|
||||||
if (bmain->versionfile == BLENDER_VERSION) {
|
char current_ver_str[16];
|
||||||
BKE_blender_version_blendfile_string_from_values(
|
if (bmain->versionfile == BLENDER_VERSION) {
|
||||||
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, bmain->subversionfile);
|
BKE_blender_version_blendfile_string_from_values(
|
||||||
BKE_blender_version_blendfile_string_from_values(
|
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, bmain->subversionfile);
|
||||||
current_ver_str, sizeof(current_ver_str), BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION);
|
BKE_blender_version_blendfile_string_from_values(
|
||||||
}
|
current_ver_str, sizeof(current_ver_str), BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION);
|
||||||
else {
|
}
|
||||||
BKE_blender_version_blendfile_string_from_values(
|
else {
|
||||||
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, -1);
|
BKE_blender_version_blendfile_string_from_values(
|
||||||
BKE_blender_version_blendfile_string_from_values(
|
writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, -1);
|
||||||
current_ver_str, sizeof(current_ver_str), BLENDER_VERSION, -1);
|
BKE_blender_version_blendfile_string_from_values(
|
||||||
|
current_ver_str, sizeof(current_ver_str), BLENDER_VERSION, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char message_line1[256];
|
||||||
|
char message_line2[256];
|
||||||
|
SNPRINTF(message_line1,
|
||||||
|
RPT_("This file was saved by a newer version of Blender (%s)"),
|
||||||
|
writer_ver_str);
|
||||||
|
SNPRINTF(message_line2,
|
||||||
|
RPT_("Saving it with this Blender (%s) may cause loss of data"),
|
||||||
|
current_ver_str);
|
||||||
|
uiItemL(layout, message_line1, ICON_NONE);
|
||||||
|
uiItemL(layout, message_line2, ICON_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
char message_line1[256];
|
if (bmain->is_asset_repository) {
|
||||||
char message_line2[256];
|
if (bmain->has_forward_compatibility_issues) {
|
||||||
SNPRINTF(message_line1,
|
uiItemS_ex(layout, 1.4f);
|
||||||
RPT_("This file was saved by a newer version of Blender (%s)"),
|
}
|
||||||
writer_ver_str);
|
|
||||||
SNPRINTF(message_line2,
|
uiItemL(layout, RPT_("This file is managed by the Blender asset system"), ICON_NONE);
|
||||||
RPT_("Saving it with this Blender (%s) may cause loss of data"),
|
uiItemL(
|
||||||
current_ver_str);
|
layout, RPT_("By overwriting it as a regular blend file, it will no longer "), ICON_NONE);
|
||||||
uiItemL(layout, message_line1, ICON_NONE);
|
uiItemL(layout, RPT_("be possible to update its assets through the asset browser"), ICON_NONE);
|
||||||
uiItemL(layout, message_line2, ICON_NONE);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_cancel(bContext *C, void *arg_block, void * /*arg_data*/)
|
static void save_file_overwrite_cancel(bContext *C, void *arg_block, void * /*arg_data*/)
|
||||||
{
|
{
|
||||||
wmWindow *win = CTX_wm_window(C);
|
wmWindow *win = CTX_wm_window(C);
|
||||||
UI_popup_block_close(C, win, static_cast<uiBlock *>(arg_block));
|
UI_popup_block_close(C, win, static_cast<uiBlock *>(arg_block));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_cancel_button(uiBlock *block, wmGenericCallback *post_action)
|
static void save_file_overwrite_cancel_button(uiBlock *block, wmGenericCallback *post_action)
|
||||||
{
|
{
|
||||||
uiBut *but = uiDefIconTextBut(block,
|
uiBut *but = uiDefIconTextBut(block,
|
||||||
UI_BTYPE_BUT,
|
UI_BTYPE_BUT,
|
||||||
|
@ -3966,11 +3979,11 @@ static void save_file_forwardcompat_cancel_button(uiBlock *block, wmGenericCallb
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"");
|
"");
|
||||||
UI_but_func_set(but, save_file_forwardcompat_cancel, block, post_action);
|
UI_but_func_set(but, save_file_overwrite_cancel, block, post_action);
|
||||||
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_overwrite(bContext *C, void *arg_block, void *arg_data)
|
static void save_file_overwrite_confirm(bContext *C, void *arg_block, void *arg_data)
|
||||||
{
|
{
|
||||||
wmWindow *win = CTX_wm_window(C);
|
wmWindow *win = CTX_wm_window(C);
|
||||||
|
|
||||||
|
@ -3993,8 +4006,7 @@ static void save_file_forwardcompat_overwrite(bContext *C, void *arg_block, void
|
||||||
WM_generic_callback_free(callback);
|
WM_generic_callback_free(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_overwrite_button(uiBlock *block,
|
static void save_file_overwrite_confirm_button(uiBlock *block, wmGenericCallback *post_action)
|
||||||
wmGenericCallback *post_action)
|
|
||||||
{
|
{
|
||||||
uiBut *but = uiDefIconTextBut(block,
|
uiBut *but = uiDefIconTextBut(block,
|
||||||
UI_BTYPE_BUT,
|
UI_BTYPE_BUT,
|
||||||
|
@ -4011,20 +4023,37 @@ static void save_file_forwardcompat_overwrite_button(uiBlock *block,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"");
|
"");
|
||||||
UI_but_func_set(but, save_file_forwardcompat_overwrite, block, post_action);
|
UI_but_func_set(but, save_file_overwrite_confirm, block, post_action);
|
||||||
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
||||||
UI_but_flag_enable(but, UI_BUT_REDALERT);
|
UI_but_flag_enable(but, UI_BUT_REDALERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_saveas(bContext *C, void *arg_block, void * /*arg_data*/)
|
static void save_file_overwrite_saveas(bContext *C, void *arg_block, void * /*arg_data*/)
|
||||||
{
|
{
|
||||||
|
Main *bmain = CTX_data_main(C);
|
||||||
wmWindow *win = CTX_wm_window(C);
|
wmWindow *win = CTX_wm_window(C);
|
||||||
UI_popup_block_close(C, win, static_cast<uiBlock *>(arg_block));
|
UI_popup_block_close(C, win, static_cast<uiBlock *>(arg_block));
|
||||||
|
|
||||||
WM_operator_name_call(C, "WM_OT_save_as_mainfile", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
|
PointerRNA props_ptr;
|
||||||
|
wmOperatorType *ot = WM_operatortype_find("WM_OT_save_as_mainfile", false);
|
||||||
|
WM_operator_properties_create_ptr(&props_ptr, ot);
|
||||||
|
|
||||||
|
if (bmain->is_asset_repository) {
|
||||||
|
/* If needed, substitute the 'proposed' Save As filepath by replacing the `.asset.blend` part
|
||||||
|
* of it by just `.blend`. */
|
||||||
|
std::string filepath = BKE_main_blendfile_path(bmain);
|
||||||
|
if (blender::StringRef(filepath).endswith(BLENDER_ASSET_FILE_SUFFIX)) {
|
||||||
|
filepath.replace(
|
||||||
|
filepath.rfind(BLENDER_ASSET_FILE_SUFFIX), strlen(BLENDER_ASSET_FILE_SUFFIX), ".blend");
|
||||||
|
RNA_string_set(&props_ptr, "filepath", filepath.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr);
|
||||||
|
WM_operator_properties_free(&props_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_file_forwardcompat_saveas_button(uiBlock *block, wmGenericCallback *post_action)
|
static void save_file_overwrite_saveas_button(uiBlock *block, wmGenericCallback *post_action)
|
||||||
{
|
{
|
||||||
uiBut *but = uiDefIconTextBut(block,
|
uiBut *but = uiDefIconTextBut(block,
|
||||||
UI_BTYPE_BUT,
|
UI_BTYPE_BUT,
|
||||||
|
@ -4041,19 +4070,17 @@ static void save_file_forwardcompat_saveas_button(uiBlock *block, wmGenericCallb
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"");
|
"");
|
||||||
UI_but_func_set(but, save_file_forwardcompat_saveas, block, post_action);
|
UI_but_func_set(but, save_file_overwrite_saveas, block, post_action);
|
||||||
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
||||||
UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
|
UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uiBlock *block_create_save_file_forwardcompat_dialog(bContext *C,
|
static uiBlock *block_create_save_file_overwrite_dialog(bContext *C, ARegion *region, void *arg1)
|
||||||
ARegion *region,
|
|
||||||
void *arg1)
|
|
||||||
{
|
{
|
||||||
wmGenericCallback *post_action = static_cast<wmGenericCallback *>(arg1);
|
wmGenericCallback *post_action = static_cast<wmGenericCallback *>(arg1);
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
|
|
||||||
uiBlock *block = UI_block_begin(C, region, save_file_forwardcompat_dialog_name, UI_EMBOSS);
|
uiBlock *block = UI_block_begin(C, region, save_file_overwrite_dialog_name, UI_EMBOSS);
|
||||||
UI_block_flag_enable(
|
UI_block_flag_enable(
|
||||||
block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
|
block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
|
||||||
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
||||||
|
@ -4061,8 +4088,27 @@ static uiBlock *block_create_save_file_forwardcompat_dialog(bContext *C,
|
||||||
uiLayout *layout = uiItemsAlertBox(block, 34, ALERT_ICON_WARNING);
|
uiLayout *layout = uiItemsAlertBox(block, 34, ALERT_ICON_WARNING);
|
||||||
|
|
||||||
/* Title. */
|
/* Title. */
|
||||||
uiItemL_ex(
|
if (bmain->has_forward_compatibility_issues) {
|
||||||
layout, RPT_("Overwrite file with an older Blender version?"), ICON_NONE, true, false);
|
if (bmain->is_asset_repository) {
|
||||||
|
uiItemL_ex(
|
||||||
|
layout,
|
||||||
|
RPT_("Convert asset blend file to regular blend file with an older Blender version?"),
|
||||||
|
ICON_NONE,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uiItemL_ex(
|
||||||
|
layout, RPT_("Overwrite file with an older Blender version?"), ICON_NONE, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bmain->is_asset_repository) {
|
||||||
|
uiItemL_ex(
|
||||||
|
layout, RPT_("Convert asset blend file to regular blend file?"), ICON_NONE, true, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
/* Filename. */
|
/* Filename. */
|
||||||
const char *blendfile_path = BKE_main_blendfile_path(CTX_data_main(C));
|
const char *blendfile_path = BKE_main_blendfile_path(CTX_data_main(C));
|
||||||
|
@ -4079,7 +4125,7 @@ static uiBlock *block_create_save_file_forwardcompat_dialog(bContext *C,
|
||||||
uiItemL(layout, filename, ICON_NONE);
|
uiItemL(layout, filename, ICON_NONE);
|
||||||
|
|
||||||
/* Detailed message info. */
|
/* Detailed message info. */
|
||||||
file_forwardcompat_detailed_info_show(layout, bmain);
|
file_overwrite_detailed_info_show(layout, bmain);
|
||||||
|
|
||||||
uiItemS_ex(layout, 4.0f);
|
uiItemS_ex(layout, 4.0f);
|
||||||
|
|
||||||
|
@ -4089,7 +4135,7 @@ static uiBlock *block_create_save_file_forwardcompat_dialog(bContext *C,
|
||||||
uiLayoutSetScaleY(split, 1.2f);
|
uiLayoutSetScaleY(split, 1.2f);
|
||||||
|
|
||||||
uiLayoutColumn(split, false);
|
uiLayoutColumn(split, false);
|
||||||
save_file_forwardcompat_overwrite_button(block, post_action);
|
save_file_overwrite_confirm_button(block, post_action);
|
||||||
|
|
||||||
uiLayout *split_right = uiLayoutSplit(split, 0.1f, true);
|
uiLayout *split_right = uiLayoutSplit(split, 0.1f, true);
|
||||||
|
|
||||||
|
@ -4097,25 +4143,25 @@ static uiBlock *block_create_save_file_forwardcompat_dialog(bContext *C,
|
||||||
/* Empty space. */
|
/* Empty space. */
|
||||||
|
|
||||||
uiLayoutColumn(split_right, false);
|
uiLayoutColumn(split_right, false);
|
||||||
save_file_forwardcompat_cancel_button(block, post_action);
|
save_file_overwrite_cancel_button(block, post_action);
|
||||||
|
|
||||||
uiLayoutColumn(split_right, false);
|
uiLayoutColumn(split_right, false);
|
||||||
save_file_forwardcompat_saveas_button(block, post_action);
|
save_file_overwrite_saveas_button(block, post_action);
|
||||||
|
|
||||||
UI_block_bounds_set_centered(block, 14 * UI_SCALE_FAC);
|
UI_block_bounds_set_centered(block, 14 * UI_SCALE_FAC);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wm_save_file_forwardcompat_dialog(bContext *C, wmOperator *op)
|
void wm_save_file_overwrite_dialog(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
if (!UI_popup_block_name_exists(CTX_wm_screen(C), save_file_forwardcompat_dialog_name)) {
|
if (!UI_popup_block_name_exists(CTX_wm_screen(C), save_file_overwrite_dialog_name)) {
|
||||||
wmGenericCallback *callback = MEM_cnew<wmGenericCallback>(__func__);
|
wmGenericCallback *callback = MEM_cnew<wmGenericCallback>(__func__);
|
||||||
callback->exec = nullptr;
|
callback->exec = nullptr;
|
||||||
callback->user_data = IDP_CopyProperty(op->properties);
|
callback->user_data = IDP_CopyProperty(op->properties);
|
||||||
callback->free_user_data = wm_free_operator_properties_callback;
|
callback->free_user_data = wm_free_operator_properties_callback;
|
||||||
|
|
||||||
UI_popup_block_invoke(
|
UI_popup_block_invoke(
|
||||||
C, block_create_save_file_forwardcompat_dialog, callback, free_post_file_close_action);
|
C, block_create_save_file_overwrite_dialog, callback, free_post_file_close_action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4245,7 +4291,7 @@ static void wm_block_file_close_discard_button(uiBlock *block, wmGenericCallback
|
||||||
|
|
||||||
static void wm_block_file_close_save_button(uiBlock *block,
|
static void wm_block_file_close_save_button(uiBlock *block,
|
||||||
wmGenericCallback *post_action,
|
wmGenericCallback *post_action,
|
||||||
const bool has_forwardcompat_issues)
|
const bool needs_overwrite_confirm)
|
||||||
{
|
{
|
||||||
uiBut *but = uiDefIconTextBut(
|
uiBut *but = uiDefIconTextBut(
|
||||||
block,
|
block,
|
||||||
|
@ -4253,7 +4299,7 @@ static void wm_block_file_close_save_button(uiBlock *block,
|
||||||
0,
|
0,
|
||||||
ICON_NONE,
|
ICON_NONE,
|
||||||
/* Forward compatibility issues force using 'save as' operator instead of 'save' one. */
|
/* Forward compatibility issues force using 'save as' operator instead of 'save' one. */
|
||||||
has_forwardcompat_issues ? IFACE_("Save As...") : IFACE_("Save"),
|
needs_overwrite_confirm ? IFACE_("Save As...") : IFACE_("Save"),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -4289,7 +4335,7 @@ static uiBlock *block_create__close_file_dialog(bContext *C, ARegion *region, vo
|
||||||
|
|
||||||
uiLayout *layout = uiItemsAlertBox(block, 34, ALERT_ICON_QUESTION);
|
uiLayout *layout = uiItemsAlertBox(block, 34, ALERT_ICON_QUESTION);
|
||||||
|
|
||||||
const bool has_forwardcompat_issues = bmain->has_forward_compatibility_issues;
|
const bool needs_overwrite_confirm = BKE_main_needs_overwrite_confirm(bmain);
|
||||||
|
|
||||||
/* Title. */
|
/* Title. */
|
||||||
uiItemL_ex(layout, RPT_("Save changes before closing?"), ICON_NONE, true, false);
|
uiItemL_ex(layout, RPT_("Save changes before closing?"), ICON_NONE, true, false);
|
||||||
|
@ -4306,8 +4352,8 @@ static uiBlock *block_create__close_file_dialog(bContext *C, ARegion *region, vo
|
||||||
uiItemL(layout, filename, ICON_NONE);
|
uiItemL(layout, filename, ICON_NONE);
|
||||||
|
|
||||||
/* Potential forward compatibility issues message. */
|
/* Potential forward compatibility issues message. */
|
||||||
if (has_forwardcompat_issues) {
|
if (needs_overwrite_confirm) {
|
||||||
file_forwardcompat_detailed_info_show(layout, bmain);
|
file_overwrite_detailed_info_show(layout, bmain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image Saving Warnings. */
|
/* Image Saving Warnings. */
|
||||||
|
@ -4416,7 +4462,7 @@ static uiBlock *block_create__close_file_dialog(bContext *C, ARegion *region, vo
|
||||||
uiLayoutSetScaleY(split, 1.2f);
|
uiLayoutSetScaleY(split, 1.2f);
|
||||||
|
|
||||||
uiLayoutColumn(split, false);
|
uiLayoutColumn(split, false);
|
||||||
wm_block_file_close_save_button(block, post_action, has_forwardcompat_issues);
|
wm_block_file_close_save_button(block, post_action, needs_overwrite_confirm);
|
||||||
|
|
||||||
uiLayoutColumn(split, false);
|
uiLayoutColumn(split, false);
|
||||||
wm_block_file_close_discard_button(block, post_action);
|
wm_block_file_close_discard_button(block, post_action);
|
||||||
|
@ -4442,7 +4488,7 @@ static uiBlock *block_create__close_file_dialog(bContext *C, ARegion *region, vo
|
||||||
wm_block_file_close_cancel_button(block, post_action);
|
wm_block_file_close_cancel_button(block, post_action);
|
||||||
|
|
||||||
uiLayoutColumn(split_right, false);
|
uiLayoutColumn(split_right, false);
|
||||||
wm_block_file_close_save_button(block, post_action, has_forwardcompat_issues);
|
wm_block_file_close_save_button(block, post_action, needs_overwrite_confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_block_bounds_set_centered(block, 14 * UI_SCALE_FAC);
|
UI_block_bounds_set_centered(block, 14 * UI_SCALE_FAC);
|
||||||
|
|
|
@ -97,7 +97,7 @@ bool wm_file_or_session_data_has_unsaved_changes(const Main *bmain, const wmWind
|
||||||
*
|
*
|
||||||
* Important to ask confirmation, as this is a very common scenario of data loss.
|
* Important to ask confirmation, as this is a very common scenario of data loss.
|
||||||
*/
|
*/
|
||||||
void wm_save_file_forwardcompat_dialog(bContext *C, wmOperator *op);
|
void wm_save_file_overwrite_dialog(bContext *C, wmOperator *op);
|
||||||
|
|
||||||
void WM_OT_save_homefile(wmOperatorType *ot);
|
void WM_OT_save_homefile(wmOperatorType *ot);
|
||||||
void WM_OT_save_userpref(wmOperatorType *ot);
|
void WM_OT_save_userpref(wmOperatorType *ot);
|
||||||
|
|
Loading…
Reference in New Issue