e2b3b6aa8c64011156e26fb6e8cfcb80e5092b62
[blender.git] / source / blender / editors / io / io_cache.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software  Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2016 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup editor/io
22  */
23
24 #include "MEM_guardedalloc.h"
25
26 #include "DNA_cachefile_types.h"
27 #include "DNA_space_types.h"
28
29 #include "BLI_listbase.h"
30 #include "BLI_path_util.h"
31 #include "BLI_string.h"
32
33 #include "BKE_cachefile.h"
34 #include "BKE_context.h"
35 #include "BKE_library.h"
36 #include "BKE_main.h"
37 #include "BKE_report.h"
38
39 #include "RNA_access.h"
40
41 #include "DEG_depsgraph.h"
42
43 #include "UI_interface.h"
44
45 #include "WM_api.h"
46 #include "WM_types.h"
47
48 #include "io_cache.h"
49
50 static void cachefile_init(bContext *C, wmOperator *op)
51 {
52   PropertyPointerRNA *pprop;
53
54   op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
55   UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
56 }
57
58 static int cachefile_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
59 {
60   if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
61     char filepath[FILE_MAX];
62     Main *bmain = CTX_data_main(C);
63
64     BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
65     BLI_path_extension_replace(filepath, sizeof(filepath), ".abc");
66     RNA_string_set(op->ptr, "filepath", filepath);
67   }
68
69   cachefile_init(C, op);
70
71   WM_event_add_fileselect(C, op);
72
73   return OPERATOR_RUNNING_MODAL;
74
75   UNUSED_VARS(event);
76 }
77
78 static void open_cancel(bContext *UNUSED(C), wmOperator *op)
79 {
80   MEM_freeN(op->customdata);
81   op->customdata = NULL;
82 }
83
84 static int cachefile_open_exec(bContext *C, wmOperator *op)
85 {
86   if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
87     BKE_report(op->reports, RPT_ERROR, "No filename given");
88     return OPERATOR_CANCELLED;
89   }
90
91   char filename[FILE_MAX];
92   RNA_string_get(op->ptr, "filepath", filename);
93
94   Main *bmain = CTX_data_main(C);
95
96   CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename), 0);
97   BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
98   DEG_id_tag_update(&cache_file->id, ID_RECALC_COPY_ON_WRITE);
99
100   /* Will be set when running invoke, not exec directly. */
101   if (op->customdata != NULL) {
102     /* hook into UI */
103     PropertyPointerRNA *pprop = op->customdata;
104     if (pprop->prop) {
105       /* When creating new ID blocks, use is already 1, but RNA
106        * pointer see also increases user, so this compensates it. */
107       id_us_min(&cache_file->id);
108
109       PointerRNA idptr;
110       RNA_id_pointer_create(&cache_file->id, &idptr);
111       RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
112       RNA_property_update(C, &pprop->ptr, pprop->prop);
113     }
114
115     MEM_freeN(op->customdata);
116   }
117
118   return OPERATOR_FINISHED;
119 }
120
121 void CACHEFILE_OT_open(wmOperatorType *ot)
122 {
123   ot->name = "Open Cache File";
124   ot->description = "Load a cache file";
125   ot->idname = "CACHEFILE_OT_open";
126
127   ot->invoke = cachefile_open_invoke;
128   ot->exec = cachefile_open_exec;
129   ot->cancel = open_cancel;
130
131   WM_operator_properties_filesel(ot,
132                                  FILE_TYPE_ALEMBIC | FILE_TYPE_FOLDER,
133                                  FILE_BLENDER,
134                                  FILE_SAVE,
135                                  WM_FILESEL_FILEPATH,
136                                  FILE_DEFAULTDISPLAY,
137                                  FILE_SORT_ALPHA);
138 }
139
140 /* ***************************** Reload Operator **************************** */
141
142 static int cachefile_reload_exec(bContext *C, wmOperator *UNUSED(op))
143 {
144   CacheFile *cache_file = CTX_data_edit_cachefile(C);
145
146   if (!cache_file) {
147     return OPERATOR_CANCELLED;
148   }
149
150   Depsgraph *depsgraph = CTX_data_depsgraph(C);
151   BKE_cachefile_reload(depsgraph, cache_file);
152
153   return OPERATOR_FINISHED;
154 }
155
156 void CACHEFILE_OT_reload(wmOperatorType *ot)
157 {
158   ot->name = "Refresh Archive";
159   ot->description = "Update objects paths list with new data from the archive";
160   ot->idname = "CACHEFILE_OT_reload";
161
162   /* api callbacks */
163   ot->exec = cachefile_reload_exec;
164
165   /* flags */
166   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
167 }