Jamoma API  0.6.0.a19
Max/source/j.model/j.model_preset.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.model / j.view - - preset features
6  *
7  * @details
8  *
9  * @authors Théo de la Hogue, Trond Lossius
10  *
11  * @copyright Copyright © 2010 Théo de la Hogue @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "j.model.h"
18 
20 {
22  TTAddress modelAdrs;
23  TTValue v, a, args, none;
24  TTAddress presetAddress;
25 
26  // get model:address
27  EXTRA->modelInfo->get(kTTSym_address, v);
28  modelAdrs = v[0];
29 
30  // create the preset manager
31  jamoma_presetManager_create((t_object*)x, *EXTRA->presetManager);
32 
33  // suscribe it under a preset node
34  presetAddress = modelAdrs.appendAddress(TTAddress("preset"));
35 
36  args = TTValue(presetAddress, *EXTRA->presetManager, x->patcherPtr);
37 
38  if (!JamomaApplication.send("ObjectRegister", args, none)) {
39 
40  EXTRA->presetManager->set(kTTSym_address, modelAdrs);
41 
42  defer_low(x, (method)model_preset_default, 0, 0, 0L);
43  }
44 }
45 
46 /*
47 void model_preset_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
48 {
49  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
50 
51  // avoid blank before line
52  if (msg == _sym_nothing)
53  outlet_atoms(x->outlets[line_out], argc, argv);
54  else
55  outlet_anything(x->outlets[line_out], msg, argc, argv);
56 }
57 */
58 
59 void model_preset_return_names(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
60 {
62  outlet_anything(x->outlets[dump_out], gensym("names"), argc, argv);
63 }
64 
65 void model_preset_read(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
66 {
67  defer(self, (method)model_preset_doread, msg, argc, argv);
68 }
69 
70 void model_preset_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
71 {
73  TTValue o, v, none;
74  TTSymbol fullpath;
75  TTObject aTextHandler;
76  TTErr tterr;
77 
78  if (EXTRA->presetManager->valid()) {
79 
80  fullpath = jamoma_file_read((t_object*)x, argc, argv, 'TEXT');
81  v.append(fullpath);
82 
83  tterr = x->internals->lookup(kTTSym_TextHandler, o);
84 
85  if (!tterr) {
86 
87  aTextHandler = o[0];
88 
89  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
90 
91  critical_enter(0);
92  tterr = aTextHandler.send(kTTSym_Read, v, none);
93  critical_exit(0);
94 
95  if (!tterr)
96  object_obex_dumpout(self, _sym_read, argc, argv);
97  else
98  object_obex_dumpout(self, _sym_error, 0, NULL);
99  }
100  }
101 }
102 
104 {
105  defer(self, (method)model_preset_doread_again, NULL, 0, NULL);
106 }
107 
109 {
111  TTObject aTextHandler;
112  TTValue o;
113  TTErr tterr;
114 
115  tterr = x->internals->lookup(kTTSym_TextHandler, o);
116 
117  if (!tterr) {
118 
119  aTextHandler = o[0];
120 
121  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
122 
123  critical_enter(0);
124  tterr = aTextHandler.send(kTTSym_ReadAgain);
125  critical_exit(0);
126 
127  if (!tterr)
128  object_obex_dumpout(self, _sym_read, 0, NULL);
129  else
130  object_obex_dumpout(self, _sym_error, 0, NULL);
131  }
132 }
133 
134 void model_preset_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
135 {
136  defer(self, (method)model_preset_dowrite, msg, argc, argv);
137 }
138 
139 void model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
140 {
142  char filename[MAX_FILENAME_CHARS];
143  TTSymbol fullpath;
144  TTValue o, v, none;
145  TTObject aTextHandler;
146  TTErr tterr;
147 
148  // stop filewatcher
149  if (EXTRA->filewatcher)
150  filewatcher_stop(EXTRA->filewatcher);
151 
152  if (EXTRA->presetManager->valid()) {
153 
154  // Default TEXT File Name
155  snprintf(filename, MAX_FILENAME_CHARS, "%s.%s.presets.txt", x->patcherClass.c_str(), x->patcherContext.c_str());
156  fullpath = jamoma_file_write((t_object*)x, argc, argv, filename);
157  v.append(fullpath);
158 
159  tterr = x->internals->lookup(kTTSym_TextHandler, o);
160 
161  if (!tterr) {
162  aTextHandler = o[0];
163 
164  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
165 
166  critical_enter(0);
167  tterr = aTextHandler.send(kTTSym_Write, v, none);
168  critical_exit(0);
169 
170  if (!tterr)
171  object_obex_dumpout(self, _sym_write, argc, argv);
172  else
173  object_obex_dumpout(self, _sym_error, 0, NULL);
174  }
175  }
176 
177  // start filewatcher
178  if (EXTRA->filewatcher)
179  filewatcher_start(EXTRA->filewatcher);
180 }
181 
183 {
184  defer(self, (method)model_preset_dowrite_again, NULL, 0, NULL);
185 }
186 
188 {
190  TTObject aTextHandler;
191  TTValue o;
192  TTErr tterr;
193 
194  // stop filewatcher
195  if (EXTRA->filewatcher)
196  filewatcher_stop(EXTRA->filewatcher);
197 
198  tterr = x->internals->lookup(kTTSym_TextHandler, o);
199 
200  if (!tterr) {
201 
202  aTextHandler = o[0];
203 
204  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
205 
206  critical_enter(0);
207  tterr = aTextHandler.send(kTTSym_WriteAgain);
208  critical_exit(0);
209 
210  if (!tterr)
211  object_obex_dumpout(self, _sym_write, 0, NULL);
212  else
213  object_obex_dumpout(self, _sym_error, 0, NULL);
214  }
215 
216  // start filewatcher
217  if (EXTRA->filewatcher)
218  filewatcher_start(EXTRA->filewatcher);
219 }
220 
222 {
224  short outvol;
225  t_fourcc outtype, filetype = 'TEXT';
226  char fullpath[MAX_PATH_CHARS]; // path and name passed on to the xml parser
227  char posixpath[MAX_PATH_CHARS];
228  t_atom a;
229  t_symbol* textfile;
230 
231  if (x->patcherClass != kTTSymEmpty) {
232 
233  if (EXTRA->attr_presets != kTTSym_none) {
234 
235  textfile = gensym(EXTRA->attr_presets.c_str());
236  }
237  else if (x->patcherContext == kTTSym_model)
238  jamoma_edit_filename(*ModelPresetFormat, x->patcherClass, &textfile);
239 
240  else if (x->patcherContext == kTTSym_view)
241  jamoma_edit_filename(*ViewPresetFormat, x->patcherClass, &textfile);
242  else
243  return object_error((t_object*)x, "preset_default : can't get the context of the patcher");
244 
245  if (locatefile_extended((char*)textfile->s_name, &outvol, &outtype, &filetype, 1)) {
246  //object_warn((t_object*)x, "preset_default : can't find %s file in the Max search path", textfile.data());
247  return;
248  }
249 
250  path_topathname(outvol, (char*)textfile->s_name, fullpath);
251  path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
252 
253  atom_setsym(&a, gensym(posixpath));
254  defer_low(self, (method)model_preset_doread, gensym("read"), 1, &a);
255 
256  // recall the default preset if exists
257  atom_setsym(&a, gensym("default"));
258  defer_low((t_object*)x, (method)model_preset_dorecall, NULL, 1, &a);
259 
260  // replace filewatcher
261  if (EXTRA->filewatcher) {
262  filewatcher_stop(EXTRA->filewatcher);
263  object_free(EXTRA->filewatcher);
264  }
265 
266  EXTRA->filewatcher = filewatcher_new((t_object*)x, outvol, (char*)textfile->s_name);
267  filewatcher_start(EXTRA->filewatcher);
268  }
269  else
270  object_error((t_object*)x, "preset_default : can't get the class of the patcher");
271 }
272 
273 void model_preset_filechanged(TTPtr self, char *filename, short path)
274 {
276  char fullpath[MAX_PATH_CHARS]; // path and name passed on to the xml parser
277  char posixpath[MAX_PATH_CHARS];
278  TTValue v;
279  TTSymbol current;
280  t_atom a;
281 
282  // get current preset
283  EXTRA->presetManager->get("current", v);
284 
285  path_topathname(path, filename, fullpath);
286  path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
287 
288  atom_setsym(&a, gensym(posixpath));
289  defer_low(self, (method)model_preset_doread, gensym("read"), 1, &a);
290 
291  /* since JamomaMax#711 : we decide to mute the triggering of the current preset
292 
293  // try to recall last current preset
294  current = v[0];
295  atom_setsym(&a, gensym((char*)current.c_str()));
296  defer_low((t_object*)x, (method)model_preset_dorecall, NULL, 1, &a);
297 
298  */
299 }
300 
301 void model_preset_dorecall(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
302 {
304  TTValue v, none;
305 
306  if (argc && argv)
307  if (atom_gettype(argv) == A_SYM)
308  v = TTValue(TTSymbol(atom_getsym(argv)->s_name));
309 
310  // recall the preset
311  EXTRA->presetManager->send(kTTSym_Recall, v, none);
312 }
313 
314 void model_preset_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
315 {
317  TTString *buffer;
318  char title[MAX_FILENAME_CHARS];
319  TTObject aTextHandler;
320  TTHashPtr allPresets;
321  TTValue v, o, args, none;
322  TTSymbol name;
323  t_atom a;
324  TTErr tterr;
325 
326  // choose object to edit : default the cuelist
327  *EXTRA->toEdit = *EXTRA->presetManager;
328  EXTRA->presetName = kTTSymEmpty;
329 
330  if (argc && argv) {
331 
332  if (atom_gettype(argv) == A_LONG) {
333 
334  // get presets names
335  EXTRA->presetManager->get("names", v);
336 
337  if (atom_getlong(argv) <= (TTInt32) v.size())
338  name = v[atom_getlong(argv)-1];
339 
340  else {
341  object_error((t_object*)x, "%d does'nt exist", atom_getlong(argv));
342  return;
343  }
344  }
345  else if (atom_gettype(argv) == A_SYM)
346  name = TTSymbol(atom_getsym(argv)->s_name);
347 
348  if (name != kTTSymEmpty) {
349 
350  // get preset object table
351  EXTRA->presetManager->get("presets", v);
352  allPresets = TTHashPtr((TTPtr)v[0]);
353 
354  if (allPresets) {
355 
356  // get cue to edit
357  if (!allPresets->lookup(name, v)) {
358 
359  // edit a preset
360  *EXTRA->toEdit = v[0];
361  EXTRA->presetName = name;
362  }
363  else {
364  object_error((t_object*)x, "%s does'nt exist", atom_getsym(argv)->s_name);
365  return;
366  }
367  }
368  }
369  }
370 
371  // only one editor can be open in the same time
372  if (!EXTRA->textEditor) {
373 
374  EXTRA->textEditor = (t_object*)object_new(_sym_nobox, _sym_jed, x, 0);
375 
376  buffer = new TTString();
377 
378  // get the buffer handler
379  tterr = x->internals->lookup(kTTSym_TextHandler, o);
380 
381  if (!tterr) {
382 
383  aTextHandler = o[0];
384 
385  critical_enter(0);
386  aTextHandler.set(kTTSym_object, *EXTRA->toEdit);
387  tterr = aTextHandler.send(kTTSym_Write, (TTPtr)buffer, none);
388  critical_exit(0);
389  }
390 
391  // pass the buffer to the editor
392  object_method(EXTRA->textEditor, _sym_settext, buffer->c_str(), _sym_utf_8);
393  object_attr_setchar(EXTRA->textEditor, gensym("scratch"), 1);
394 
395  snprintf(title, MAX_FILENAME_CHARS, "%s preset editor", x->patcherClass.c_str());
396  object_attr_setsym(EXTRA->textEditor, _sym_title, gensym(title));
397 
398  // output a flag
399  atom_setsym(&a, gensym("opened"));
400  object_obex_dumpout(self, gensym("editor"), 1, &a);
401 
402  buffer->clear();
403  delete buffer;
404  buffer = NULL;
405  }
406 }
407 
408 void model_preset_edclose(TTPtr self, char **text, long size)
409 {
411 
412  EXTRA->text = new TTString(*text);
413  EXTRA->textEditor = NULL;
414 
415  defer_low((t_object*)x, (method)model_preset_doedit, NULL, 0, NULL);
416 }
417 
419 {
421  TTObject aTextHandler;
422  TTValue o, none;
423  t_atom a;
424  TTErr tterr;
425 
426  // get the buffer handler
427  tterr = x->internals->lookup(kTTSym_TextHandler, o);
428 
429  if (!tterr) {
430 
431  aTextHandler = o[0];
432 
433  critical_enter(0);
434  tterr = aTextHandler.send(kTTSym_Read, (TTPtr)EXTRA->text, none);
435  critical_exit(0);
436 
437  // output a flag
438  atom_setsym(&a, gensym("closed"));
439  object_obex_dumpout(self, gensym("editor"), 1, &a);
440 
441  if (!tterr)
442  object_obex_dumpout(self, _sym_read, 0, NULL);
443  else
444  object_obex_dumpout(self, _sym_error, 0, NULL);
445  }
446 
447  delete EXTRA->text;
448  EXTRA->text = NULL;
449  EXTRA->textEditor = NULL;
450  *EXTRA->toEdit = *EXTRA->presetManager;
451  EXTRA->presetName = kTTSymEmpty;
452 }
453 
454 t_max_err model_preset_set_presets(TTPtr self, TTPtr attr, long ac, const t_atom *av)
455 {
457 
458  if (ac&&av) {
459  EXTRA->attr_presets = TTSymbol(atom_getsym(av)->s_name);
460  }
461  else
462  EXTRA->attr_presets = kTTSym_none; // default true
463 
464  return MAX_ERR_NONE;
465 }
466 
467 t_max_err model_preset_get_presets(TTPtr self, TTPtr attr, long *ac, t_atom **av)
468 {
470 
471  if ((*ac)&&(*av)) {
472  //memory passed in, use it
473  } else {
474  //otherwise allocate memory
475  *ac = 1;
476  if (!(*av = (t_atom*)getbytes(sizeof(t_atom)*(*ac)))) {
477  *ac = 0;
478  return MAX_ERR_OUT_OF_MEM;
479  }
480  }
481 
482  atom_setsym(*av, gensym(EXTRA->attr_presets.c_str()));
483 
484  return MAX_ERR_NONE;
485 }
void model_preset_read_again(TTPtr self)
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
t_max_err model_preset_get_presets(TTPtr self, TTPtr attr, long *ac, t_atom **av)
void model_preset_amenities(TTPtr self)
void JAMOMA_EXPORT jamoma_edit_filename(TTString format, TTSymbol className, t_symbol **returnedFileName)
Edit a file name from a given file format and a class name.
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTHandle outlets
an array of outlet
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
TTSymbol patcherClass
the patcher class in which the external is
const char * c_str() const
Return a pointer to the internal C-string.
Definition: TTString.h:83
void model_preset_dorecall(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
Create and use Jamoma object instances.
Definition: TTObject.h:29
size_type size() const noexcept
Return the number of elements.
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
TTSymbol JAMOMA_EXPORT jamoma_file_read(t_object *x, long argc, const t_atom *argv, t_fourcc filetype)
Get BOOT style filepath from args or, if no args open a dialog to read a file.
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
void model_preset_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
void model_preset_dowrite_again(TTPtr self)
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
void model_preset_read(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_filechanged(TTPtr self, char *filename, short path)
void model_preset_doread_again(TTPtr self)
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTSymbol JAMOMA_EXPORT jamoma_file_write(t_object *x, long argc, const t_atom *argv, char *default_filename)
Get BOOT style filepath from args or, if no args open a dialog to write a file.
void model_preset_default(TTPtr self)
t_max_err model_preset_set_presets(TTPtr self, TTPtr attr, long ac, const t_atom *av)
void model_preset_edclose(TTPtr self, char **text, long size)
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
j.model / j.view - The main control center of Jamoma model and view patcher
void model_preset_return_names(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTErr JAMOMA_EXPORT jamoma_presetManager_create(t_object *x, TTObject &returnedPresetManager)
Create a #TTPresetManager object.
void model_preset_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
Data Structure for this object.
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTSymbol patcherContext
the patcher context in which the external is (model, view)
The TTString class is used to represent a string.
Definition: TTString.h:34
void model_preset_doedit(TTPtr self)
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
void model_preset_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
void model_preset_write_again(TTPtr self)