3 * Copyright (C) 2016-2020 William Morrow
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include "bclistbox.h"
33 #include "channeldb.h"
34 #include "filesystem.h"
37 #include "recordbatches.h"
38 #include "timeentry.h"
40 const char * RecordBatches::
41 default_batch_titles[] = {
42 N_("On"), N_("Path"), N_("News"), N_("Start time"),
43 N_("Duration"), N_("Source"), N_("Mode")
46 const int RecordBatches::
47 default_columnwidth[] = {
48 30, 200, 100, 100, 100, 100, 70
52 load_defaults(ChannelDB * channeldb, Record * record)
54 char string[BCTEXTLEN];
55 BC_Hash *defaults = mwindow->defaults;
56 defaults->get("RECORD_DEFAULT_DIRECTORY", default_directory);
57 early_margin = defaults->get("RECORD_EARLY_MARGIN", early_margin);
58 late_margin = defaults->get("RECORD_LATE_MARGIN", late_margin);
59 for(int i = 0; i < BATCH_COLUMNS; i++) {
60 batch_titles[i] = _(default_batch_titles[i]);
61 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
62 column_widths[i] = defaults->get(string, xS(default_columnwidth[i]));
64 int total_batches = defaults->get("TOTAL_BATCHES", 1);
65 if(total_batches < 1) total_batches = 1;
66 for(int i = 0; i < total_batches; ++i) {
67 Batch *batch = new Batch(mwindow, record);
68 batch->create_objects();
69 batches.append(batch);
70 Asset *asset = batch->asset;
71 sprintf(string, "RECORD_PATH_%d", i);
72 defaults->get(string, asset->path);
73 sprintf(string, "RECORD_CHANNEL_%d", i);
74 int chan_no = channeldb->number_of(batch->channel);
75 chan_no = defaults->get(string, chan_no);
76 batch->channel = channeldb->get(chan_no);
77 sprintf(string, "RECORD_STARTDAY_%d", i);
78 batch->start_day = defaults->get(string, batch->start_day);
79 sprintf(string, "RECORD_STARTTIME_%d", i);
80 batch->start_time = defaults->get(string, batch->start_time);
81 sprintf(string, "RECORD_DURATION_%d", i);
82 batch->duration = defaults->get(string, batch->duration);
83 sprintf(string, "RECORD_MODE_%d", i);
84 batch->record_mode = defaults->get(string, batch->record_mode);
85 sprintf(string, "BATCH_ENABLED_%d", i);
86 batch->enabled = defaults->get(string, batch->enabled);
87 batch->update_times();
90 current_item = editing_item = 0;
94 save_defaults(ChannelDB * channeldb)
96 char string[BCTEXTLEN];
97 BC_Hash *defaults = mwindow->defaults;
98 defaults->update("RECORD_DEFAULT_DIRECTORY", default_directory);
99 defaults->update("RECORD_EARLY_MARGIN", early_margin);
100 defaults->update("RECORD_LATE_MARGIN", late_margin);
101 for(int i = 0; i < BATCH_COLUMNS; i++) {
102 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
103 defaults->update(string, column_widths[i]);
106 defaults->update("TOTAL_BATCHES", batches.total);
107 for(int i = 0; i < batches.total; ++i) {
108 Batch *batch = batches.values[i];
109 Asset *asset = batch->asset;
110 sprintf(string, "RECORD_PATH_%d", i);
111 defaults->update(string, asset->path);
112 sprintf(string, "RECORD_CHANNEL_%d", i);
113 int chan_no = channeldb->number_of(batch->channel);
114 defaults->update(string, chan_no);
115 sprintf(string, "RECORD_STARTDAY_%d", i);
116 defaults->update(string, batch->start_day);
117 sprintf(string, "RECORD_STARTTIME_%d", i);
118 defaults->update(string, batch->start_time);
119 sprintf(string, "RECORD_DURATION_%d", i);
120 defaults->update(string, batch->duration);
121 sprintf(string, "RECORD_MODE_%d", i);
122 defaults->update(string, batch->record_mode);
123 sprintf(string, "BATCH_ENABLED_%d", i);
124 defaults->update(string, batch->enabled);
129 save_default_channel(ChannelDB * channeldb)
131 BC_Hash *defaults = mwindow->defaults;
132 Batch *batch = get_editing_batch();
134 int chan_no = channeldb->number_of(batch->channel);
135 if( chan_no < 0 ) return;
136 defaults->update("RECORD_CURRENT_CHANNEL", chan_no);
140 RecordBatches(MWindow * mwindow)
142 this->mwindow = mwindow;
143 editing_item = current_item = -1;
145 early_margin = late_margin = 0.;
146 default_directory[0] = 0;
157 batches.remove(batch);
158 int total_batches = total();
159 if( current_item == editing_item ) {
160 if(current_item >= total_batches)
161 current_item = total_batches - 1;
162 editing_item = current_item;
165 if(current_item > editing_item)
167 if( editing_item >= total_batches )
168 editing_item = total_batches - 1;
175 batches.remove_all_objects();
176 for(int j = 0; j < BATCH_COLUMNS; j++) {
177 data[j].remove_all_objects();
179 current_item = editing_item = -1;
183 RecordBatchesGUI(RecordBatches &batches,
184 int x, int y, int w, int h)
185 : BC_ListBox(x, y, w, h, LISTBOX_TEXT, // Display text list or icons
186 batches.data, // Each column has an ArrayList of BC_ListBoxItems.
187 batches.batch_titles, // Titles for columns. Set to 0 for no titles
188 batches.column_widths, // width of each column
189 BATCH_COLUMNS, // Total columns.
190 0, // Pixel of top of window.
191 0, // If this listbox is a popup window
192 LISTBOX_SINGLE, // Select one item or multiple items
193 ICON_LEFT, // Position of icon relative to text of each item
194 1), // Allow dragging
200 // Do nothing for double clicks to protect active batch
201 int RecordBatchesGUI::
207 int RecordBatchesGUI::
208 update(int highlighted_item, int recalc_positions)
210 return BC_ListBox::update(batches.data, batches.batch_titles,
211 batches.column_widths, BATCH_COLUMNS,
212 get_xposition(), get_yposition(),
213 highlighted_item, recalc_positions);
216 int RecordBatchesGUI::
217 column_resize_event()
219 for(int i = 0; i < BATCH_COLUMNS; i++) {
220 batches.column_widths[i] = get_column_width(i);
225 int RecordBatchesGUI::
228 if(!BC_ListBox::drag_start_event()) return 0;
233 int RecordBatchesGUI::
236 if(!BC_ListBox::drag_motion_event()) return 0;
240 int RecordBatchesGUI::
243 int n = get_selection_number(0, 0);
245 set_editing_batch(n);
246 if(get_cursor_x() < batches.column_widths[0]) {
247 Batch *batch = batches[n];
248 batch->enabled = !batch->enabled;
255 int RecordBatchesGUI::
259 int total_batches = batches.total();
260 int src_item = editing_batch();
261 Batch *src_batch = batches[src_item];
262 int dst_item = get_highlighted_item();
263 if(dst_item < 0) dst_item = total_batches;
264 if(dst_item > src_item) --dst_item;
266 for(int i = src_item; i < total_batches - 1; i++)
267 batches[i] = batches[i + 1];
268 for(int i = total_batches - 1; i > dst_item; --i)
269 batches[i] = batches[i - 1];
270 batches[dst_item] = src_batch;
272 BC_ListBox::drag_stop_event();
274 set_editing_batch(dst_item);
275 update_batches(dst_item);
280 void RecordBatchesGUI::
281 update_batch_news(int item)
283 Batch *batch = batches[item];
284 batch->calculate_news();
285 batches.data[2].values[item]->set_text(batch->news);
289 void RecordBatchesGUI::
290 update_batches(int selection_item)
293 char string[BCTEXTLEN], string2[BCTEXTLEN];
295 for(int j = 0; j < BATCH_COLUMNS; j++) {
296 batches.data[j].remove_all_objects();
298 int total_batches = batches.total();
299 for(int i = 0; i < total_batches; i++) {
300 Batch *batch = batches[i];
301 batch->update_times();
302 batch->calculate_news();
305 if( i != batches.current_item ) {
306 if( batch->time_start < t )
308 else if( i > 0 && batches[i-1]->time_end > batch->time_start )
310 else if( batch->time_start - t > 2*24*3600 )
316 batches.data[0].append(
317 new BC_ListBoxItem((char *)(batch->enabled ? "X" : " "), color));
318 batches.data[1].append(
319 new BC_ListBoxItem(batch->asset->path, color));
320 batches.data[2].append(
321 new BC_ListBoxItem(batch->news, RED));
322 Units::totext(string2, batch->start_time, TIME_HMS3);
323 sprintf(string, "%s %s", TimeEntry::day_table[batch->start_day], string2);
324 batches.data[3].append(
325 new BC_ListBoxItem(string, color));
326 Units::totext(string, batch->duration, TIME_HMS3);
327 batches.data[4].append(
328 new BC_ListBoxItem(string, color));
329 sprintf(string, "%s", batch->channel ? batch->channel->title : _("None"));
330 batches.data[5].append(
331 new BC_ListBoxItem(string, color));
332 sprintf(string, "%s", Batch::mode_to_text(batch->record_mode));
333 batches.data[6].append(
334 new BC_ListBoxItem(string, color));
336 if(i == selection_item) {
337 for(int j = 0; j < BATCH_COLUMNS; j++) {
338 batches.data[j].values[i]->set_selected(1);
342 update(batches.editing_item, 1);
346 void RecordBatchesGUI::
347 set_row_color(int row, int color)
349 for(int i = 0; i < BATCH_COLUMNS; i++) {
350 BC_ListBoxItem *batch = batches.data[i].values[row];
351 batch->set_color(color);
356 RecordBatchesGUI::Dir::
357 Dir(RecordBatches &batches, const char *dir, int x, int y)
358 : BC_TextBox(x, y, xS(200), 1, dir),
360 directory(batches.default_directory)
362 strncpy(directory, dir, sizeof(directory));
363 dir_entries = new ArrayList<BC_ListBoxItem*>;
368 RecordBatchesGUI::Dir::
371 dir_entries->remove_all_objects();
375 int RecordBatchesGUI::Dir::
378 char *path = FileSystem::basepath(get_text());
379 strcpy(directory, path);
381 calculate_suggestions(dir_entries);
386 void RecordBatchesGUI::Dir::
387 load_dirs(const char *dir)
389 if( !strncmp(dir, entries_dir, sizeof(entries_dir)) ) return;
390 strncpy(entries_dir, dir, sizeof(entries_dir));
391 dir_entries->remove_all_objects();
392 FileSystem fs; fs.update(dir);
393 int total_files = fs.total_files();
394 for(int i = 0; i < total_files; i++) {
395 if( !fs.get_entry(i)->get_is_dir() ) continue;
396 const char *name = fs.get_entry(i)->get_name();
397 dir_entries->append(new BC_ListBoxItem(name));
401 RecordBatchesGUI::Path::
402 Path(RecordBatches &batches, int x, int y)
403 : BC_TextBox(x, y, xS(200), 1, batches.get_editing_batch()->asset->path),
408 RecordBatchesGUI::Path::
413 int RecordBatchesGUI::Path::
416 calculate_suggestions();
417 Batch *batch = batches.gui->get_editing_batch();
418 strcpy(batch->asset->path, get_text());
419 batches.gui->update_batches();
423 RecordBatchesGUI::StartTime::
424 StartTime(BC_Window *win, RecordBatches &batches, int x, int y, int w)
425 : TimeEntry(win, x, y,
426 &batches.get_editing_batch()->start_day,
427 &batches.get_editing_batch()->start_time, TIME_HMS3, w),
432 int RecordBatchesGUI::StartTime::
435 batches.gui->update_batches();
440 RecordBatchesGUI::Duration::
441 Duration(BC_Window *win, RecordBatches &batches, int x, int y, int w)
442 : TimeEntry(win, x, y, 0,
443 &batches.get_editing_batch()->duration, TIME_HMS2, w),
448 int RecordBatchesGUI::Duration::
451 batches.gui->update_batches();
456 RecordBatchesGUI::Source::
457 Source(BC_Window *win, RecordBatches &batches, int x, int y)
458 : BC_PopupTextBox(win, &sources,
459 batches.get_editing_batch()->get_source_text(),
460 x, y, xS(200), yS(200)),
465 int RecordBatchesGUI::Source::
468 batches.gui->update_batches();
473 RecordBatchesGUI::News::
474 News(RecordBatches &batches, int x, int y)
475 : BC_TextBox(x, y, xS(200), 1, batches.get_editing_batch()->news),
480 int RecordBatchesGUI::News::
487 RecordBatchesGUI::NewBatch::
488 NewBatch(RecordBatches &batches, int x, int y)
489 : BC_GenericButton(x, y, _("New")),
492 set_tooltip(_("Create new clip."));
495 int RecordBatchesGUI::NewBatch::
498 int new_item = batches.total()-1;
499 batches.editing_item = new_item;
500 batches.gui->update_batches(new_item);
505 RecordBatchesGUI::DeleteBatch::
506 DeleteBatch(RecordBatches &batches, int x, int y)
507 : BC_GenericButton(x, y, _("Delete")),
510 set_tooltip(_("Delete clip."));
513 int RecordBatchesGUI::DeleteBatch::
516 batches.gui->update_batches();
521 RecordBatchesGUI::StartBatches::
522 StartBatches(RecordBatches &batches, int x, int y)
523 : BC_GenericButton(x, y, _("Start")), batches(batches)
525 set_tooltip(_("Start batch recording\nfrom the current position."));
528 int RecordBatchesGUI::StartBatches::
531 batches.batch_active = 1;
536 RecordBatchesGUI::StopBatches::
537 StopBatches(RecordBatches &batches, int x, int y)
538 : BC_GenericButton(x, y, _("Stop")), batches(batches)
542 int RecordBatchesGUI::StopBatches::
545 batches.batch_active = 0;
550 RecordBatchesGUI::ActivateBatch::
551 ActivateBatch(RecordBatches &batches, int x, int y)
552 : BC_GenericButton(x, y, _("Activate")), batches(batches)
554 set_tooltip(_("Make the highlighted\nclip active."));
557 int RecordBatchesGUI::ActivateBatch::
564 RecordBatchesGUI::ClearBatch::
565 ClearBatch(RecordBatches &batches, int x, int y)
566 : BC_GenericButton(x, y, _("Clear")), batches(batches)
568 set_tooltip(_("Delete all clips."));
571 int RecordBatchesGUI::ClearBatch::
574 batches.gui->update_batches();