1 /* abstract base class for things which form the model of a model/view pair
2  */
3 
4 /*
5 
6     Copyright (C) 1991-2003 The National Gallery
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 
22  */
23 
24 /*
25 
26     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
27 
28  */
29 
30 /* When scrolling, do we want the top or the bottom of the object visible.
31  * Important for Columns, since we sometimes want to see the title bar and
32  * sometimes the edit box at the bottom.
33  */
34 typedef enum {
35 	MODEL_SCROLL_TOP,
36 	MODEL_SCROLL_BOTTOM
37 } ModelScrollPosition;
38 
39 /* How to rename symbols.
40  */
41 typedef struct _ModelRename {
42 	char *old_name;
43 	char *new_name;
44 } ModelRename;
45 
46 /* What we track during a load operation.
47  */
48 typedef struct _ModelLoadState {
49 	char *filename;		/* Name we loaded from */
50 	char *filename_user;	/* The filename to record in the model */
51 	xmlDoc *xdoc;		/* Document we load from */
52 
53 	/*
54 
55 		FIXME ... a linked list? try a hash sometime
56 		see model_loadstate_rewrite_name()
57 
58 		would probably only see a speedup for merging very large
59 		workspaces, not something we do often
60 
61 	 */
62 	GSList *renames;	/* Rename table for this load context */
63 
64 	/* The column renames we have planned. Don't rewrite exprs with these.
65 	 */
66 	GSList *column_renames;
67 
68 	/* Version info we read from this XML file.
69 	 */
70 	int major;
71 	int minor;
72 	int micro;
73 
74 	/* Log error messages here.
75 	 */
76 	char error_log_buffer[MAX_STRSIZE];
77 	VipsBuf error_log;
78 
79 	/* Set this bool to rewrite string constants using the filename
80 	 * rewrite system.
81 	 */
82 	gboolean rewrite_path;
83 
84 	/* The old_dir we added with path_rewrite_add() ... if non, NULL,
85 	 * unset this rewrite rule on close.
86 	 */
87 	char *old_dir;
88 } ModelLoadState;
89 
90 #define TYPE_MODEL (model_get_type())
91 #define MODEL( obj ) \
92 	(G_TYPE_CHECK_INSTANCE_CAST( (obj), TYPE_MODEL, Model ))
93 #define MODEL_CLASS( klass ) \
94 	(G_TYPE_CHECK_CLASS_CAST( (klass), TYPE_MODEL, ModelClass))
95 #define IS_MODEL( obj ) \
96 	(G_TYPE_CHECK_INSTANCE_TYPE( (obj), TYPE_MODEL ))
97 #define IS_MODEL_CLASS( klass ) \
98 	(G_TYPE_CHECK_CLASS_TYPE( (klass), TYPE_MODEL ))
99 #define MODEL_GET_CLASS( obj ) \
100 	(G_TYPE_INSTANCE_GET_CLASS( (obj), TYPE_MODEL, ModelClass ))
101 
102 struct _Model {
103 	iContainer parent_object;
104 
105 	/* My instance vars.
106 	 */
107 	gboolean display;	/* This model should have a view */
108 
109 	/* For things that have a pop-up window (eg. iimage, plot), the
110 	 * position and size of the window.
111 	 */
112 	int window_x, window_y;
113 	int window_width, window_height;
114 };
115 
116 typedef struct _ModelClass {
117 	iContainerClass parent_class;
118 
119 	/* Build display methods.
120 
121 		view_new	make a view for this model ... make the top
122 				view yourself, thereafter view will watch
123 				child_add etc. and manage subviews
124 				automatically ... use model->display to create
125 				and destroy views
126 
127 	 */
128 
129 	View *(*view_new)( Model *model, View *parent );
130 
131 	/* Change methods
132 
133 		edit		open an editor on the model
134 
135 		header		view model header
136 
137 		scrollto	try to make views visible
138 
139 		reset		signals views to reset ... eg. textview pops
140 				back to whatever the ws says it should be
141 				displaying (value or formula)
142 
143 		layout 		try to lay child view out
144 
145 		front		trigger view_child_front() for all views
146 
147 		display		create and destroy views
148 
149 	 */
150 
151 	void (*edit)( GtkWidget *, Model * );
152 	void (*header)( GtkWidget *, Model * );
153 	void (*scrollto)( Model *, ModelScrollPosition );
154 	void (*reset)( Model * );
155 	void (*layout)( Model * );
156 	void (*front)( Model * );
157 	void (*display)( Model *, gboolean display );
158 
159 	/* Load and save methods.
160 
161 		save		write model as child of node
162 
163 		save_test	predicate ... save model if save_test is
164 				defined and true
165 
166 		save_text	plain text save ... eg. for toolkits
167 
168 		load		_init() model from xmlNode
169 
170 		load_text	_init() from plain text ... eg. toolkit
171 
172 		empty		remove contents of model
173 
174 	 */
175 	xmlNode *(*save)( Model *, xmlNode * );
176 	gboolean (*save_test)( Model * );
177 	gboolean (*save_text)( Model *, iOpenFile * );
178 	gboolean (*load)( Model *model,
179 		ModelLoadState *state, Model *parent, xmlNode *xnode );
180 	gboolean (*load_text)( Model *model, Model *parent, iOpenFile * );
181 	void (*empty)( Model * );
182 } ModelClass;
183 
184 extern ModelLoadState *model_loadstate;
185 
186 gboolean model_loadstate_rename_new( ModelLoadState *state,
187 	const char *old_name, const char *new_name );
188 gboolean model_loadstate_taken( ModelLoadState *state, const char *name );
189 gboolean model_loadstate_column_rename_new( ModelLoadState *state,
190 	const char *old_name, const char *new_name );
191 gboolean model_loadstate_column_taken( ModelLoadState *state,
192 	const char *name );
193 ModelLoadState *model_loadstate_new(
194 	const char *filename, const char *filename_user );
195 ModelLoadState *model_loadstate_new_openfile( iOpenFile *of );
196 void model_loadstate_destroy( ModelLoadState *state );
197 char *model_loadstate_rewrite_name( char *name );
198 void model_loadstate_rewrite( ModelLoadState *state,
199 	char *old_rhs, char *new_rhs );
200 
201 void model_register_loadable( ModelClass *model_class );
202 
203 View *model_view_new( Model *model, View *parent );
204 void model_scrollto( Model *model, ModelScrollPosition position );
205 void model_layout( Model *model );
206 void *model_reset( Model *model );
207 void *model_edit( GtkWidget *parent, Model *model );
208 void *model_header( GtkWidget *parent, Model *model );
209 void model_front( Model *model );
210 void model_display( Model *model, gboolean display );
211 
212 void *model_save( Model *model, xmlNode * );
213 gboolean model_save_test( Model *model );
214 void *model_save_text( Model *model, iOpenFile * );
215 void *model_load( Model *model,
216 	ModelLoadState *state, Model *parent, xmlNode *xnode );
217 void *model_load_text( Model *model, Model *parent, iOpenFile * );
218 void *model_empty( Model *model );
219 
220 gboolean model_new_xml( ModelLoadState *state, Model *parent, xmlNode *xnode );
221 
222 GType model_get_type( void );
223 
224 void model_base_init( void );
225 
226 View *model_build_display_all( Model *model, View *parent );
227 
228 void model_check_destroy( GtkWidget *parent, Model *model, iWindowFn done_cb );
229 
230 void *model_clear_edited( Model *model );
231