prevent popup deactivation while button_down
[goodguy/history.git] / cinelerra-5.0 / cinelerra / mainindexes.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program 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  * This program 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 this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "asset.h"
23 #include "bcsignals.h"
24 #include "bchash.h"
25 #include "edl.h"
26 #include "file.h"
27 #include "filesystem.h"
28 #include "indexfile.h"
29 #include "indexstate.h"
30 #include "condition.h"
31 #include "language.h"
32 #include "loadfile.h"
33 #include "guicast.h"
34 #include "mainindexes.h"
35 #include "mainprogress.h"
36 #include "mutex.h"
37 #include "mwindow.h"
38 #include "mwindowgui.h"
39 #include "preferences.h"
40
41 #include <string.h>
42
43
44 MainIndexes::MainIndexes(MWindow *mwindow)
45  : Thread(1, 0, 0)
46 {
47         set_synchronous(1);
48         this->mwindow = mwindow;
49         input_lock = new Condition(0, "MainIndexes::input_lock");
50         next_lock = new Mutex("MainIndexes::next_lock");
51         index_lock = new Mutex("MainIndexes::index_lock");
52         interrupt_lock = new Condition(1, "MainIndexes::interrupt_lock");
53         interrupt_flag = 0;
54         indexfile = 0;
55         done = 0;
56 }
57
58 MainIndexes::~MainIndexes()
59 {
60         mwindow->mainprogress->cancelled = 1;
61         stop_loop();
62         delete next_lock;
63         delete input_lock;
64         delete interrupt_lock;
65         delete indexfile;
66         delete index_lock;
67 }
68
69 void MainIndexes::add_next_asset(File *file, Indexable *indexable)
70 {
71         next_lock->lock("MainIndexes::add_next_asset");
72
73 SET_TRACE
74 // Test current asset
75         IndexFile indexfile(mwindow, indexable);
76         IndexState *index_state = 0;
77         index_state = indexable->index_state;
78
79 SET_TRACE
80         int got_it = 0;
81
82 SET_TRACE
83         if(!indexfile.open_index())
84         {
85                 index_state->index_status = INDEX_READY;
86                 indexfile.close_index();
87                 got_it = 1;
88         }
89
90 //printf("MainIndexes::add_next_asset %d %f\n", __LINE__, indexable->get_frame_rate());
91
92 SET_TRACE
93 // No index
94         if(!got_it)
95         {
96                 File *this_file = file;
97
98 SET_TRACE
99                 if(!file && indexable->is_asset)
100                 {
101                         Asset *asset = (Asset *)indexable;
102                         this_file = new File;
103                         this_file->open_file(mwindow->preferences, asset, 1, 0);
104                 }
105
106
107 SET_TRACE
108                 char index_filename[BCTEXTLEN];
109                 char source_filename[BCTEXTLEN];
110 SET_TRACE
111                 IndexFile::get_index_filename(source_filename, 
112                         mwindow->preferences->index_directory, 
113                         index_filename, 
114                         indexable->path);
115
116 SET_TRACE
117                 if(this_file && !this_file->get_index(index_filename))
118                 {
119 SET_TRACE
120                         if(!indexfile.open_index())
121                         {
122 SET_TRACE
123                                 indexfile.close_index();
124 SET_TRACE
125                                 index_state->index_status = INDEX_READY;
126                                 got_it = 1;
127                         }
128 SET_TRACE
129                 }
130
131 SET_TRACE
132                 if(this_file && !file) delete this_file;
133 SET_TRACE
134         }
135 SET_TRACE
136
137 //printf("MainIndexes::add_next_asset %d %f\n", __LINE__, indexable->get_frame_rate());
138
139 // Put source in stack
140         if(!got_it)
141         {
142                 index_state->index_status = INDEX_NOTTESTED;
143                 next_indexables.append(indexable);
144                 indexable->add_user();
145         }
146         next_lock->unlock();
147 }
148
149 void MainIndexes::delete_current_sources()
150 {
151         for(int i = 0; i < current_indexables.size(); i++)
152                 current_indexables.get(i)->Garbage::remove_user();
153         current_indexables.remove_all();
154 }
155
156 void MainIndexes::start_loop()
157 {
158         interrupt_flag = 0;
159         Thread::start();
160 }
161
162 void MainIndexes::stop_loop()
163 {
164         interrupt_flag = 1;
165         done = 1;
166         input_lock->unlock();
167         interrupt_lock->unlock();
168         Thread::join();
169 }
170
171
172 void MainIndexes::start_build()
173 {
174 //printf("MainIndexes::start_build 1\n");
175         interrupt_flag = 0;
176 // Locked up when indexes were already being built and an indexable was 
177 // pasted.
178 //      interrupt_lock.lock();
179         input_lock->unlock();
180 }
181
182 void MainIndexes::interrupt_build()
183 {
184 //printf("MainIndexes::interrupt_build 1\n");
185         interrupt_flag = 1;
186         index_lock->lock("MainIndexes::interrupt_build");
187         if(indexfile) indexfile->interrupt_index();
188         index_lock->unlock();
189 //printf("MainIndexes::interrupt_build 2\n");
190         interrupt_lock->lock("MainIndexes::interrupt_build");
191 //printf("MainIndexes::interrupt_build 3\n");
192         interrupt_lock->unlock();
193 //printf("MainIndexes::interrupt_build 4\n");
194 }
195
196 void MainIndexes::load_next_sources()
197 {
198         delete_current_sources();
199
200 // Transfer from new list
201         next_lock->lock("MainIndexes::load_next_sources");
202         for(int i = 0; i < next_indexables.size(); i++)
203                 current_indexables.append(next_indexables.get(i));
204
205 // Clear pointers from new list only
206         next_indexables.remove_all();
207         next_lock->unlock();
208 }
209
210
211 void MainIndexes::run()
212 {
213         while(!done)
214         {
215 // Wait for new indexables to be released
216                 input_lock->lock("MainIndexes::run 1");
217                 if(done) return;
218
219
220                 interrupt_lock->lock("MainIndexes::run 2");
221                 load_next_sources();
222                 interrupt_flag = 0;
223
224
225
226
227
228
229 // test index of each indexable
230                 MainProgressBar *progress = 0;
231                 int total_sources = current_indexables.size();
232                 for(int i = 0; 
233                         i < total_sources && !interrupt_flag; 
234                         i++)
235                 {
236                         Indexable *indexable = 0;
237 // Take an indexable
238                         indexable = current_indexables.get(i);
239
240                         IndexState *index_state = 0;
241                         index_state = indexable->index_state;
242
243 //printf("MainIndexes::run 3 %s %d %d\n", indexable->path, indexable->index_status, indexable->audio_data);
244
245                         if(index_state->index_status == INDEX_NOTTESTED && 
246                                 indexable->have_audio())
247                         {
248
249
250                                 index_lock->lock("MainIndexes::run 1");
251                                 indexfile = new IndexFile(mwindow, indexable);
252                                 index_lock->unlock();
253
254
255 // Doesn't exist if this returns 1.
256                                 if(indexfile->open_index())
257                                 {
258 // Try to create index now.
259                                         if(!progress)
260                                         {
261                                                 if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 1");
262                                                 progress = mwindow->mainprogress->start_progress(_("Building Indexes..."), 1);
263                                                 if(mwindow->gui) mwindow->gui->unlock_window();
264                                         }
265
266
267                                         indexfile->create_index(progress);
268                                         if(progress->is_cancelled()) interrupt_flag = 1;
269                                 }
270                                 else
271 // Exists.  Update real thing.
272                                 {
273 //printf("MainIndexes::run 8\n");
274                                         if(index_state->index_status == INDEX_NOTTESTED)
275                                         {
276                                                 index_state->index_status = INDEX_READY;
277                                                 if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 2");
278                                                 mwindow->edl->set_index_file(indexable);
279                                                 if(mwindow->gui) mwindow->gui->unlock_window();
280                                         }
281                                         indexfile->close_index();
282                                 }
283
284                                 index_lock->lock("MainIndexes::run 2");
285                                 delete indexfile;
286                                 indexfile = 0;
287                                 index_lock->unlock();
288 //printf("MainIndexes::run 8\n");
289                         }
290 //printf("MainIndexes::run 9\n");
291                 }
292
293                 if(progress)     // progress box is only created when an index is built
294                 {
295                         if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 3");
296                         progress->stop_progress();
297                         delete progress;
298                         if(mwindow->gui) mwindow->gui->unlock_window();
299                         progress = 0;
300                 }
301
302
303
304
305
306
307                 interrupt_lock->unlock();
308         }
309 }
310