1 /*
2  * Copyright (C) 2005 2006, Magnus Hjorth
3  *
4  * This file is part of mhWaveEdit.
5  *
6  * mhWaveEdit is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * mhWaveEdit is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with mhWaveEdit; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 
22 #ifndef DOCUMENT_H_INCLUDED
23 #define DOCUMENT_H_INCLUDED
24 
25 #include "chunk.h"
26 #include "listobject.h"
27 
28 #define DOCUMENT(obj) GTK_CHECK_CAST(obj,document_get_type(),Document)
29 #define DOCUMENT_CLASS(klass) GTK_CHECK_CLASS_CAST(klass,document_get_type(),DocumentClass)
30 #define IS_DOCUMENT(obj) GTK_CHECK_TYPE(obj,document_get_type())
31 
32 struct MarkList {
33      int length, alloced;
34      char **names;
35      off_t *places;
36 };
37 
38 struct HistoryEntry;
39 struct HistoryEntry {
40      Chunk *chunk;
41      off_t selstart,selend,viewstart,viewend,cursor;
42      struct MarkList marks;
43      struct HistoryEntry *next,*prev;
44 };
45 
46 
47 typedef struct {
48 
49      GtkObject object;
50 
51 
52      /* The filename associated with the document (or NULL if none). */
53      gchar *filename;
54      /* TRUE if the file referred to by filename has a lossy format. */
55      gboolean lossy;
56 
57 
58      /* A unique name for each document, either:
59       * the file's name part without the path
60       * the file's name part + a number (if >1 document with the same filename)
61       * "untitled #n" (if filename == NULL)
62       */
63      gchar *titlename; /* Unique for each window,
64 			* set whenever view->chunk!=NULL */
65      guint title_serial;
66 
67 
68      /* This points to where we are in the history or NULL if the
69       * history is empty */
70      struct HistoryEntry *history_pos;
71 
72      /* Pointer to Mark data structure */
73      struct MarkList marks;
74 
75      Chunk *chunk;              /* The chunk being viewed. */
76      off_t viewstart,viewend;   /* The view start and end+1  */
77      off_t selstart,selend;     /* Selection start and end+1 */
78      off_t cursorpos;           /* Cursor position */
79 
80      /* Used when sending the selection_changed signal */
81      off_t old_selstart, old_selend;
82      /* Used when sending the cursor_changed signal */
83      off_t old_cursorpos;
84      off_t playbufpos, old_playbufpos;
85 
86      gboolean followmode;       /* Follow mode flag */
87 
88      StatusBar *bar;
89 
90 } Document;
91 
92 
93 typedef struct {
94 
95      GtkObjectClass parent_class;
96 
97      /* Emitted when the view start/end is changed. */
98      void (*view_changed)(Document *doc);
99 
100      /* Emitted when the selection start/end is changed. */
101      void (*selection_changed)(Document *doc);
102 
103      /* Emitted when the cursor position is changed.
104       * Rolling is TRUE if the cursor was set because of playback */
105      void (*cursor_changed)(Document *doc, gboolean rolling);
106 
107      /* Emitted when an action has been performed. */
108      void (*state_changed)(Document *doc);
109 
110 } DocumentClass;
111 
112 
113 extern ListObject *document_objects;
114 
115 extern Document *playing_document;
116 
117 /* If TRUE and follow mode is enabled, the cursor will always be centered in
118  * view. */
119 extern gboolean view_follow_strict_flag;
120 
121 
122 
123 typedef Chunk *(*document_apply_proc)(Chunk *chunk, StatusBar *bar,
124 					 gpointer user_data);
125 
126 
127 
128 GtkType document_get_type(void);
129 
130 Document *document_new_with_file(gchar *filename, StatusBar *bar);
131 Document *document_new_with_chunk(Chunk *chunk, gchar *sourcename,
132 				  StatusBar *bar);
133 
134 void document_set_status_bar(Document *d, StatusBar *bar);
135 
136 gboolean document_save(Document *d, gchar *filename, gint type_id,
137 		       gboolean use_defs);
138 
139 
140 
141 void document_play(Document *d, off_t start, off_t end, gboolean loop,
142 		   gfloat speed);
143 void document_play_from_cursor(Document *d, gboolean loopmode, gfloat speed);
144 void document_play_selection(Document *d, gboolean loopmode, gfloat speed);
145 
146 /* Stop and keep cursor at current position */
147 void document_stop(Document *d, gboolean do_return);
148 
149 
150 /* Changes the document's chunk to new_chunk. The old state is pushed onto
151  * the history stack. All marks, selection endpoints and the cursor will be
152  * moved movedist (can be negative) samples if they're to the right of
153  * movestart. If that would move them to the left of movestart, they will be
154  * either removed (marks) or set to movestart (selection endpoints & cursor)
155  *
156  * To simplify other code, if new_chunk==NULL this function does nothing.
157  */
158 
159 void document_update(Document *d, Chunk *new_chunk, off_t movestart,
160 		     off_t movedist);
161 
162 
163 /* Apply a certain filter function on the selection (or on the whole file
164  * if nothing selected). */
165 gboolean document_apply(Document *d, chunk_filter_proc proc,
166 			chunk_filter_proc eof_proc, gint amount,
167 			gboolean convert, gchar *title);
168 
169 /* Same as document_apply but just parses the data, doesn't change it */
170 void document_parse(Document *d, chunk_parse_proc proc,
171 		    gboolean allchannels, gboolean convert, gchar *title);
172 
173 /* Call a procedure with a chunk representing the selection (or the whole
174  * file if nothing selected). The returned Chunk from the procedure will
175  * replace the selection.
176  */
177 gboolean document_apply_cb(Document *d, document_apply_proc proc,
178 			   gboolean selection_only, gpointer user_data);
179 
180 
181 
182 
183 void document_set_followmode(Document *d, gboolean followmode);
184 
185 
186 void document_set_cursor(Document *d, off_t cursorpos);
187 
188 off_t document_nudge_cursor(Document *d, off_t delta);
189 
190 void document_set_view(Document *d, off_t viewstart, off_t viewend);
191 
192 void document_scroll(Document *d, off_t distance);
193 
194 
195 /* Sets the selection.
196  * d - A Document.
197  * selstart - Starting point of the selection
198  * selend - End of selection + 1. If selend==selstart the selection is removed.
199  *          If selend<selstart the arguments are switched.
200  */
201 
202 void document_set_selection(Document *d, off_t selstart, off_t selend);
203 
204 
205 
206 /* Zoom in or out
207  * d - A Document
208  * zoom - The zooming factor. >1.0 means zooming in, <1.0 means zooming out.
209  *        Must be non-zero.
210  */
211 
212 void document_zoom(Document *d, gfloat zoom, gboolean followcursor);
213 
214 
215 /* Places a mark.
216  *
217  * d - A Document.
218  * label - A text label. If a mark with the same label exists, it will be
219  * removed.
220  * position - At which sample to place the mark. Specify DOCUMENT_BAD_MARK
221  *            to remove the mark.
222  */
223 
224 void document_set_mark(Document *d, gchar *label, off_t position);
225 
226 
227 /* Gets the position of a mark with a certain label.
228  * d - A Document
229  * label - The text label of the mark.
230  * Returns: The position of the mark, or DOCUMENT_BAD_MARK
231  * if it doesn't exist.
232  */
233 
234 off_t document_get_mark(Document *d, const gchar *label);
235 #define DOCUMENT_BAD_MARK ((off_t)-1)
236 
237 
238 /* Clears the filename component */
239 void document_forget_filename(Document *d);
240 
241 
242 /* Removes all marks. */
243 void document_clear_marks(Document *d);
244 
245 
246 void document_foreach_mark(Document *d,
247 			   void (*func)(gchar *label, off_t position,
248 					gpointer user_data),
249 			   gpointer user_data);
250 
251 gboolean document_can_undo(Document *d);
252 void document_undo(Document *d);
253 gboolean document_can_redo(Document *d);
254 void document_redo(Document *d);
255 
256 #endif
257