3 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * 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,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "awindowgui.h"
23 #include "binfolder.h"
28 #include "indexable.h"
30 #include "mainerror.h"
31 #include "mainsession.h"
37 const char *BinFolderEnabled::types[] = {
45 const char *BinFolderTarget::types[] = {
58 const char *BinFolderOp::types[] = {
70 const char *sfx, *sfxs;
73 { N_("min"), N_("mins"), 60, },
74 { N_("hour"), N_("hours"), 60*60, },
75 { N_("day"), N_("days"), 24*60*60, },
76 { N_("week"), N_("weeks"), 24*60*60*7, },
77 { N_("month"), N_("months"), 24*60*60*31, },
78 { N_("year"), N_("years"), 24*60*60*365.25, },
80 #define SCAN_RANGE_DAYS 2
81 #define DBL_INF 9007199254740991.
83 static int scan_inf(const char *cp, char *&bp)
86 const char *inf = _("inf");
87 const int linf = strlen(inf);
88 if( strncasecmp(cp,inf,linf) ) return 0;
89 bp = (char *)(cp + linf);
93 static double scan_no(const char *cp, char *&bp)
95 while( *cp == ' ' ) ++cp;
96 if( scan_inf(cp, bp) ) return DBL_INF;
97 if( *cp == '+' ) return 0;
98 double v = strtod(cp, &bp);
100 case 'T': v *= 1099511627776.; break;
101 case 't': v *= 1e12; break;
102 case 'G': v *= 1073741824.; break;
103 case 'g': v *= 1e9; break;
104 case 'M': v *= 1048576.; break;
105 case 'm': v *= 1e6; break;
106 case 'K': v *= 1024.; break;
107 case 'k': v *= 1e3; break;
114 static void scan_around(const char *cp, char *&bp, double &v, double &a)
117 double sv = scan_no(cp, bp);
118 if( bp > cp ) v = sv;
120 double sa = scan_no(cp=bp+1, bp);
121 if( bp > cp ) a = sa;
125 static void show_no(double v, char *&cp, char *ep, const char *fmt="%0.0f")
128 cp += snprintf(cp, ep-cp, "%s", _("inf"));
132 static const struct { double radix; const char *sfx; } sfxs[] = {
133 { 1024., "K" }, { 1e3, "k" },
134 { 1048576., "M" }, { 1e6, "m" },
135 { 1073741824., "G" }, { 1e9, "g" },
136 { 1099511627776., "T" }, { 1e12, "t" },
138 for( int i=sizeof(sfxs)/sizeof(sfxs[0]); --i>=0; ) {
139 if( v < sfxs[i].radix ) continue;
140 if( fmod(v, sfxs[i].radix) == 0 ) {
146 cp += snprintf(cp, ep-cp, fmt, v);
147 if( sfx ) cp += snprintf(cp, ep-cp, "%s", sfx);
150 static double scan_duration(const char *cp, char *&bp)
152 if( scan_inf(cp, bp) ) return DBL_INF;
155 double v = strtod(cp, &bp);
156 if( cp >= bp ) break;
157 int k = sizeof(scan_ranges)/sizeof(scan_ranges[0]);
159 const char *tsfx = _(scan_ranges[k].sfx);
160 int lsfx = strlen(tsfx), msfx = strncasecmp(bp, tsfx, lsfx);
161 const char *tsfxs = _(scan_ranges[k].sfxs);
162 int lsfxs = strlen(tsfxs), msfxs = strncasecmp(bp, tsfxs, lsfxs);
163 int len = !msfx && !msfxs ? (lsfx > lsfxs ? lsfx : lsfxs) :
164 !msfx ? lsfx : !msfxs ? lsfxs : -1;
166 secs += v * scan_ranges[k].radix;
172 int hour = 0, mins = 0;
173 if( *bp == ':' && v == (int)v ) {
175 v = strtod(cp=bp+1, &bp);
176 if( *bp == ':' && v == (int)v ) {
177 hour = mins; mins = v;
178 v = strtod(cp=bp+1, &bp);
181 secs += hour*3600 + mins*60 + v;
183 while( *bp && (*bp<'0' || *bp>'9') ) ++bp;
189 static void show_duration(double v, char *&cp, char *ep)
192 cp += snprintf(cp, ep-cp, "%s", _("inf"));
195 double secs = v; char *bp = cp;
196 int k = sizeof(scan_ranges)/sizeof(scan_ranges[0]);
197 while( --k >= SCAN_RANGE_DAYS ) {
198 if( secs >= scan_ranges[k].radix ) {
199 int v = secs/scan_ranges[k].radix;
200 secs -= v * scan_ranges[k].radix;
201 cp += snprintf(cp, ep-cp,"%d%s", v,
202 v > 1 ? _(scan_ranges[k].sfxs) : _(scan_ranges[k].sfx));
206 if( cp > bp && cp < ep ) *cp++ = ' ';
207 int64_t n = secs; int hour = n/3600, min = (n/60)%60, sec = n%60;
208 if( hour > 0 ) cp += snprintf(cp, ep-cp, "%d:", hour);
209 if( hour > 0 || min > 0 ) cp += snprintf(cp, ep-cp, "%02d:", min);
210 cp += snprintf(cp, ep-cp, n>=10 ? "%02d" : "%d", sec);
214 static int64_t scan_date(const char *cp, char *&bp)
216 double year=0, mon=1, day=1;
217 double hour=0, min=0;
219 while( *bp == ' ' ) ++bp;
220 if( *bp == '+' ) return 0;
221 double secs = strtod(cp=bp, &bp);
222 if( *bp == '/' && secs == (int)secs ) {
223 year = secs; secs = 0;
224 mon = strtod(cp=bp+1, &bp);
225 if( *bp == '/' && mon == (int)mon ) {
226 day = strtod(cp=bp+1, &bp);
227 while( *bp == ' ' ) ++bp;
228 secs = *bp != '+' ? strtod(cp=bp, &bp) : 0;
231 if( *bp == ':' && secs == (int)secs ) {
232 hour = secs; secs = 0;
233 min = strtod(cp=bp+1, &bp);
234 if( *bp == ':' && min == (int)min ) {
235 secs = strtod(cp=bp+1, &bp);
238 struct tm ttm; memset(&ttm, 0, sizeof(ttm));
239 ttm.tm_year = year-1900; ttm.tm_mon = mon-1; ttm.tm_mday = day;
240 ttm.tm_hour = hour; ttm.tm_min = min; ttm.tm_sec = secs;
241 ttm.tm_wday = ttm.tm_yday = 0; ttm.tm_isdst = daylight; /* tzset in main */
242 time_t t = mktime(&ttm);
246 static void show_date(time_t t, char *&cp, char *ep)
248 struct tm tm; localtime_r(&t, &tm);
249 cp += snprintf(cp, ep-cp, "%04d/%02d/%02d %02d:%02d:%02d",
250 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
251 tm.tm_hour, tm.tm_min, tm.tm_sec);
254 double BinFolder::matches_indexable(Indexable *idxbl)
257 for( int i=0; i<filters.size(); ++i ) {
258 BinFolderFilter *filter = filters[i];
259 double ret = filter->op->test(filter->target, idxbl);
260 switch( filter->enabled->type ) {
261 case FOLDER_ENABLED_OR: {
262 if( result < 0 ) result = ret;
264 case FOLDER_ENABLED_AND: {
265 if( ret < 0 ) result = -1;
267 case FOLDER_ENABLED_OR_NOT: {
268 if( ret < 0 ) result = 1;
270 case FOLDER_ENABLED_AND_NOT: {
271 if( ret >= 0 ) result = -1;
279 BinFolder::BinFolder(int awindow_folder, const char *title)
281 this->awindow_folder = awindow_folder;
282 char *bp = this->title;
283 int len = sizeof(this->title);
284 while( --len>0 && *title ) *bp++ = *title++;
288 BinFolder::BinFolder(BinFolder &that)
293 void BinFolder::copy_from(BinFolder *that)
295 strcpy(title, that->title);
296 awindow_folder = that->awindow_folder;
297 filters.copy_from(&that->filters);
300 BinFolder::~BinFolder()
304 void BinFolder::save_xml(FileXML *file)
306 file->tag.set_title("FOLDER");
307 file->tag.set_property("TITLE", title);
308 file->tag.set_property("AWINDOW_FOLDER", awindow_folder);
310 file->append_newline();
311 for( int i=0; i<filters.size(); ++i )
312 filters[i]->save_xml(file);
313 file->tag.set_title("/FOLDER");
315 file->append_newline();
318 int BinFolder::load_xml(FileXML *file)
321 file->tag.get_property("TITLE", title);
322 awindow_folder = file->tag.get_property("AWINDOW_FOLDER", -1);
323 filters.remove_all_objects();
326 while( !(ret=file->read_tag()) ) {
327 if( file->tag.title_is("/FOLDER") ) break;
328 if( file->tag.title_is("FILTER") ) {
329 BinFolderFilter *filter = new BinFolderFilter();
330 filter->load_xml(file);
331 filters.append(filter);
337 void BinFolder::add_patterns(ArrayList<Indexable*> *drag_assets)
339 int n = drag_assets->size();
342 for( int i=0; i<n; ++i )
343 len += strlen(drag_assets->get(i)->path) + 1;
344 char *pats = new char[len], *bp = pats;
345 const char *cp = drag_assets->get(0)->path;
346 while( *cp ) *bp++ = *cp++;
347 for( int i=1; i<n; ++i ) {
349 cp = drag_assets->get(i)->path;
350 while( *cp ) *bp++ = *cp++;
353 // new pattern filter
354 BinFolderFilter *filter = new BinFolderFilter();
355 filter->update_enabled(FOLDER_ENABLED_OR);
356 filter->update_target(FOLDER_TARGET_PATTERNS);
357 filter->update_op(FOLDER_OP_MATCHES);
358 BinFolderTargetPatterns *patterns = (BinFolderTargetPatterns *)(filter->target);
359 patterns->update(pats);
360 filters.append(filter);
365 double BinFolders::matches_indexable(int folder, Indexable *idxbl)
368 while( --k>=0 && get(k)->awindow_folder!=folder );
369 return k < 0 ? 0 : get(k)->matches_indexable(idxbl);
372 void BinFolders::save_xml(FileXML *file)
374 file->tag.set_title("FOLDERS");
376 file->append_newline();
377 for( int i=0; i<size(); ++i )
378 get(i)->save_xml(file);
379 file->tag.set_title("/FOLDERS");
381 file->append_newline();
384 int BinFolders::load_xml(FileXML *file)
388 while( !(ret=file->read_tag()) ) {
389 if( file->tag.title_is("/FOLDERS") ) break;
390 if( file->tag.title_is("FOLDER") ) {
391 BinFolder *folder = new BinFolder(-1, "folder");
392 folder->load_xml(file);
399 void BinFolders::copy_from(BinFolders *that)
402 for( int i=0; i<that->size(); ++i )
403 append(new BinFolder(*that->get(i)));
407 BinFolderFilter::BinFolderFilter()
414 BinFolderFilter::~BinFolderFilter()
422 void BinFolderFilter::update_enabled(int type)
425 enabled = new BinFolderEnabled(this, type);
427 enabled->update(type);
430 void BinFolderFilter::update_target(int type)
433 if( target->type == type ) return;
434 delete target; target = 0;
437 case FOLDER_TARGET_PATTERNS: target = new BinFolderTargetPatterns(this); break;
438 case FOLDER_TARGET_FILE_SIZE: target = new BinFolderTargetFileSize(this); break;
439 case FOLDER_TARGET_MOD_TIME: target = new BinFolderTargetTime(this); break;
440 case FOLDER_TARGET_TRACK_TYPE: target = new BinFolderTargetTrackType(this); break;
441 case FOLDER_TARGET_WIDTH: target = new BinFolderTargetWidth(this); break;
442 case FOLDER_TARGET_HEIGHT: target = new BinFolderTargetHeight(this); break;
443 case FOLDER_TARGET_FRAMERATE: target = new BinFolderTargetFramerate(this); break;
444 case FOLDER_TARGET_SAMPLERATE: target = new BinFolderTargetSamplerate(this); break;
445 case FOLDER_TARGET_CHANNELS: target = new BinFolderTargetChannels(this); break;
446 case FOLDER_TARGET_DURATION: target = new BinFolderTargetDuration(this); break;
450 void BinFolderFilter::update_op(int type)
453 if( op->type == type ) return;
457 case FOLDER_OP_AROUND: op = new BinFolderOpAround(this); break;
458 case FOLDER_OP_EQ: op = new BinFolderOpEQ(this); break;
459 case FOLDER_OP_GE: op = new BinFolderOpGE(this); break;
460 case FOLDER_OP_GT: op = new BinFolderOpGT(this); break;
461 case FOLDER_OP_NE: op = new BinFolderOpNE(this); break;
462 case FOLDER_OP_LE: op = new BinFolderOpLE(this); break;
463 case FOLDER_OP_LT: op = new BinFolderOpLT(this); break;
464 case FOLDER_OP_MATCHES: op = new BinFolderOpMatches(this); break;
468 void BinFolderFilter::update_value(const char *text)
471 value = new BinFolderValue(this, text);
476 void BinFolderFilter::save_xml(FileXML *file)
478 file->tag.set_title("FILTER");
479 file->tag.set_property("ENABLED", enabled->type);
480 file->tag.set_property("OP", op->type);
481 file->tag.set_property("TARGET", target->type);
482 target->save_xml(file);
484 if( target->type == FOLDER_TARGET_PATTERNS )
485 file->append_text(((BinFolderTargetPatterns *)target)->text);
486 file->tag.set_title("/FILTER");
488 file->append_newline();
491 int BinFolderFilter::load_xml(FileXML *file)
493 int enabled_type = file->tag.get_property("ENABLED", FOLDER_ENABLED_AND);
494 int op_type = file->tag.get_property("OP", FOLDER_OP_MATCHES);
495 int target_type = file->tag.get_property("TARGET", FOLDER_TARGET_PATTERNS);
497 file->read_text_until("/FILTER", data, sizeof(data), 0);
498 update_enabled(enabled_type);
499 update_target(target_type);
501 target->load_xml(file);
502 if( target->type == FOLDER_TARGET_PATTERNS )
503 ((BinFolderTargetPatterns *)target)->update(data);
507 void BinFolderFilters::copy_from(BinFolderFilters *that)
510 for( int i=0; i<that->size(); ++i ) {
511 BinFolderFilter *filter = new BinFolderFilter();
512 BinFolderFilter *tp = that->get(i);
513 filter->update_enabled(tp->enabled->type);
514 filter->update_target(tp->target->type);
515 filter->update_op(tp->op->type);
516 filter->target->copy_from(tp->target);
517 filter->op->copy_from(tp->op);
522 double BinFolderOp::around(double v, double a)
524 if( type != FOLDER_OP_AROUND || a <= 0 ) return v;
525 if( (v=fabs(v)) > a ) return -1;
529 // string theory: Feynman, Einstein and Schrodinger string compare
530 // Feynman: try all possible matches, weight the outcomes
531 // Schrodinger: it may be there several ways at the same time
532 // Einstein: the more matches there are, the heavier it is
533 double BinFolderOp::around(const char *ap, const char *bp)
535 int64_t v = 0, vmx = 0;
536 int alen = strlen(ap), blen = strlen(bp);
538 const char *cp = ap; ap = bp; bp = cp;
539 int clen = alen; alen = blen; blen = clen;
541 // 4 level loop (with strncmp), don't try long strings
542 for( int n=0; ++n<=alen; ) {
544 int an = alen-n+1, bn = blen-n+1;
545 for( int i=an; --i>=0; ) {
546 for( int j=bn; --j>=0; ) {
547 if( !strncmp(ap+i, bp+j, n) ) v += nn;
552 return !vmx ? -1 : 1 - v / (double)vmx;
556 double BinFolderOp::compare(BinFolderTarget *target, Indexable *idxbl)
559 switch( target->type ) {
560 case FOLDER_TARGET_PATTERNS: {
561 BinFolderTargetPatterns *tgt = (BinFolderTargetPatterns *)target;
563 case FOLDER_OP_AROUND: {
564 const char *cp = idxbl->path;
565 const char *bp = strrchr(cp, '/');
566 if( bp ) cp = bp + 1;
567 v = around(cp, tgt->text);
569 case FOLDER_OP_EQ: case FOLDER_OP_GT: case FOLDER_OP_GE:
570 case FOLDER_OP_NE: case FOLDER_OP_LT: case FOLDER_OP_LE: {
571 const char *cp = idxbl->path;
572 const char *bp = strrchr(cp, '/');
573 if( bp ) cp = bp + 1;
574 v = strcmp(cp, tgt->text);
576 case FOLDER_OP_MATCHES: {
578 char *cp = tgt->text;
579 while( v < 0 && *cp ) {
580 char pattern[BCTEXTLEN], *bp = pattern, ch;
581 while( *cp && (ch=*cp++)!='\n' ) *bp++ = ch;
584 !FileSystem::test_filter(idxbl->path, pattern) )
590 case FOLDER_TARGET_FILE_SIZE: {
591 BinFolderTargetFileSize *tgt = (BinFolderTargetFileSize *)target;
592 int64_t file_size = !idxbl->is_asset ? -1 :
593 FileSystem::get_size(idxbl->path);
594 v = around(file_size - tgt->file_size, tgt->around);
596 case FOLDER_TARGET_MOD_TIME: {
597 BinFolderTargetTime *tgt = (BinFolderTargetTime *)target;
599 if( stat(idxbl->path, &st) ) break;
600 v = around(st.st_mtime - tgt->mtime, tgt->around);
602 case FOLDER_TARGET_TRACK_TYPE: {
603 BinFolderTargetTrackType *tgt = (BinFolderTargetTrackType *)target;
604 int want_audio = (tgt->data_types&(1<<TRACK_AUDIO)) ? 1 : 0;
605 int has_audio = idxbl->have_audio();
606 if( want_audio != has_audio ) break;
607 int want_video = (tgt->data_types&(1<<TRACK_VIDEO)) ? 1 : 0;
608 int has_video = idxbl->have_video();
609 if( want_video != has_video ) break;
612 case FOLDER_TARGET_WIDTH: {
613 BinFolderTargetWidth *tgt = (BinFolderTargetWidth *)target;
614 int w = idxbl->get_w();
615 v = around(w - tgt->width, tgt->around);
617 case FOLDER_TARGET_HEIGHT: {
618 BinFolderTargetHeight *tgt = (BinFolderTargetHeight *)target;
619 int h = idxbl->get_h();
620 v = around(h - tgt->height, tgt->around);
622 case FOLDER_TARGET_FRAMERATE: {
623 BinFolderTargetFramerate *tgt = (BinFolderTargetFramerate *)target;
624 double rate = idxbl->get_frame_rate();
625 v = around(rate - tgt->framerate, tgt->around);
627 case FOLDER_TARGET_SAMPLERATE: {
628 BinFolderTargetSamplerate *tgt = (BinFolderTargetSamplerate *)target;
629 double rate = idxbl->get_sample_rate();
630 v = around(rate - tgt->samplerate, tgt->around);
632 case FOLDER_TARGET_CHANNELS: {
633 BinFolderTargetChannels *tgt = (BinFolderTargetChannels *)target;
634 double chs = idxbl->get_audio_channels();
635 v = around(chs - tgt->channels, tgt->around);
637 case FOLDER_TARGET_DURATION: {
638 BinFolderTargetDuration *tgt = (BinFolderTargetDuration *)target;
640 double video_rate = !idxbl->have_video() ? 0 : idxbl->get_frame_rate();
641 if( video_rate > 0 ) {
642 double video_length = idxbl->get_video_frames() / video_rate;
643 if( video_length > len ) len = video_length;
645 double audio_rate = !idxbl->have_audio() ? 0 : idxbl->get_sample_rate();
646 if( audio_rate > 0 ) {
647 double audio_length = idxbl->get_audio_samples() / audio_rate;
648 if( audio_length > len ) len = audio_length;
650 v = around(len - tgt->duration, tgt->around);
657 BinFolderEnabled::BinFolderEnabled(BinFolderFilter *filter, int type)
658 : BC_ListBoxItem(_(types[type]))
660 this->filter = filter;
664 BinFolderEnabled::~BinFolderEnabled()
668 void BinFolderEnabled::update(int type)
671 set_text(_(types[type]));
674 BinFolderEnabledType::BinFolderEnabledType(int no)
675 : BC_MenuItem(_(BinFolderEnabled::types[no]))
679 BinFolderEnabledType::~BinFolderEnabledType()
683 int BinFolderEnabledType::handle_event()
685 BinFolderEnabledPopup *enabled_popup = (BinFolderEnabledPopup *)get_popup_menu();
686 BinFolderList *folder_list = enabled_popup->folder_list;
687 int i = folder_list->get_selection_number(FOLDER_COLUMN_ENABLE, 0);
689 BinFolder *folder = folder_list->folder;
690 BinFolderFilter *filter = folder->filters[i];
691 filter->update_enabled(no);
692 folder_list->create_list();
697 BinFolderEnabledPopup::BinFolderEnabledPopup(BinFolderList *folder_list)
698 : BC_PopupMenu(0, 0, 0, "", 0)
700 this->folder_list = folder_list;
704 void BinFolderEnabledPopup::create_objects()
706 add_item(new BinFolderEnabledType(FOLDER_ENABLED_OFF));
707 add_item(new BinFolderEnabledType(FOLDER_ENABLED_AND));
708 add_item(new BinFolderEnabledType(FOLDER_ENABLED_OR));
709 add_item(new BinFolderEnabledType(FOLDER_ENABLED_AND_NOT));
710 add_item(new BinFolderEnabledType(FOLDER_ENABLED_OR_NOT));
713 void BinFolderEnabledPopup::activate_menu(BC_ListBoxItem *item)
715 this->enabled = (BinFolderEnabled *)item;
716 BC_PopupMenu::activate_menu();
719 BinFolderTarget::BinFolderTarget(BinFolderFilter *filter, int type)
720 : BC_ListBoxItem(_(types[type]))
722 this->filter = filter;
727 BinFolderTarget::~BinFolderTarget()
731 BC_Window *BinFolderTarget::new_gui(ModifyTargetThread *thread)
733 ModifyTargetGUI *window = new ModifyTargetGUI(thread);
734 window->create_objects();
738 BinFolderTargetType::BinFolderTargetType(int no)
739 : BC_MenuItem(_(BinFolderTarget::types[no]))
743 BinFolderTargetType::~BinFolderTargetType()
747 int BinFolderTargetType::handle_event()
749 BinFolderTargetPopup *target_popup = (BinFolderTargetPopup *)get_popup_menu();
750 BinFolderList *folder_list = target_popup->folder_list;
751 int i = folder_list->get_selection_number(FOLDER_COLUMN_TARGET, 0);
753 BinFolder *folder = folder_list->folder;
754 BinFolderFilter *filter = folder->filters[i];
755 filter->update_target(no);
756 folder_list->create_list();
761 BinFolderTargetPopup::BinFolderTargetPopup(BinFolderList *folder_list)
762 : BC_PopupMenu(0, 0, 0, "", 0)
764 this->folder_list = folder_list;
768 void BinFolderTargetPopup::create_objects()
770 add_item(new BinFolderTargetType(FOLDER_TARGET_PATTERNS));
771 add_item(new BinFolderTargetType(FOLDER_TARGET_FILE_SIZE));
772 add_item(new BinFolderTargetType(FOLDER_TARGET_MOD_TIME));
773 add_item(new BinFolderTargetType(FOLDER_TARGET_TRACK_TYPE));
774 add_item(new BinFolderTargetType(FOLDER_TARGET_WIDTH));
775 add_item(new BinFolderTargetType(FOLDER_TARGET_HEIGHT));
776 add_item(new BinFolderTargetType(FOLDER_TARGET_FRAMERATE));
777 add_item(new BinFolderTargetType(FOLDER_TARGET_SAMPLERATE));
778 add_item(new BinFolderTargetType(FOLDER_TARGET_CHANNELS));
779 add_item(new BinFolderTargetType(FOLDER_TARGET_DURATION));
782 void BinFolderTargetPopup::activate_menu(BC_ListBoxItem *item)
784 this->target = (BinFolderTarget *)item;
785 BC_PopupMenu::activate_menu();
789 BinFolderTargetPatterns::BinFolderTargetPatterns(BinFolderFilter *filter)
790 : BinFolderTarget(filter, FOLDER_TARGET_PATTERNS)
795 BinFolderTargetPatterns::~BinFolderTargetPatterns()
800 void BinFolderTargetPatterns::save_xml(FileXML *file) {}
801 void BinFolderTargetPatterns::load_xml(FileXML *file) {}
803 void BinFolderTargetPatterns::copy_from(BinFolderTarget *that)
805 BinFolderTargetPatterns *tp = (BinFolderTargetPatterns*)that;
809 void BinFolderTargetPatterns::update(const char *text)
811 delete [] this->text;
812 this->text = cstrdup(text);
813 filter->update_value(text);
816 BC_Window *BinFolderTargetPatterns::new_gui(ModifyTargetThread *thread)
818 return new ModifyTargetPatternsGUI(thread);
822 BinFolderTargetFileSize::BinFolderTargetFileSize(BinFolderFilter *filter)
823 : BinFolderTarget(filter, FOLDER_TARGET_FILE_SIZE)
826 update(file_size, -1);
828 BinFolderTargetFileSize::~BinFolderTargetFileSize()
832 void BinFolderTargetFileSize::save_xml(FileXML *file)
834 file->tag.set_property("FILE_SIZE", file_size);
835 file->tag.set_property("AROUND", around);
838 void BinFolderTargetFileSize::load_xml(FileXML *file)
840 int64_t file_size = file->tag.get_property("FILE_SIZE", this->file_size);
841 double around = file->tag.get_property("AROUND", this->around);
842 update(file_size, around);
845 void BinFolderTargetFileSize::copy_from(BinFolderTarget *that)
847 BinFolderTargetFileSize *tp = (BinFolderTargetFileSize *)that;
848 update(tp->file_size, tp->around);
851 void BinFolderTargetFileSize::update(int64_t file_size, double around)
853 this->file_size = file_size;
854 this->around = around;
855 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
856 show_no(file_size, cp, ep);
857 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
858 if( cp < ep ) *cp++ = '+';
859 show_no(around, cp, ep);
862 filter->update_value(txt);
865 BC_Window *BinFolderTargetFileSize::new_gui(ModifyTargetThread *thread)
867 return new ModifyTargetFileSizeGUI(thread);
871 BinFolderTargetTime::BinFolderTargetTime(BinFolderFilter *filter)
872 : BinFolderTarget(filter, FOLDER_TARGET_MOD_TIME)
878 BinFolderTargetTime::~BinFolderTargetTime()
882 void BinFolderTargetTime::save_xml(FileXML *file)
884 file->tag.set_property("MTIME", mtime);
885 file->tag.set_property("AROUND", around);
888 void BinFolderTargetTime::load_xml(FileXML *file)
890 int64_t mtime = file->tag.get_property("MTIME", this->mtime);
891 double around = file->tag.get_property("AROUND", this->around);
892 update(mtime, around);
895 void BinFolderTargetTime::copy_from(BinFolderTarget *that)
897 BinFolderTargetTime *tp = (BinFolderTargetTime *)that;
898 update(tp->mtime, tp->around);
901 void BinFolderTargetTime::update(int64_t mtime, double around)
904 this->around = around;
905 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
906 show_date(mtime, cp, ep);
907 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
908 if( cp < ep ) *cp++ = '+';
909 show_duration(around, cp, ep);
912 filter->update_value(txt);
915 BC_Window *BinFolderTargetTime::new_gui(ModifyTargetThread *thread)
917 return new ModifyTargetTimeGUI(thread);
921 BinFolderTargetTrackType::BinFolderTargetTrackType(BinFolderFilter *filter)
922 : BinFolderTarget(filter, FOLDER_TARGET_TRACK_TYPE)
924 data_types = (1<<TRACK_AUDIO);
927 BinFolderTargetTrackType::~BinFolderTargetTrackType()
931 void BinFolderTargetTrackType::save_xml(FileXML *file)
933 file->tag.set_property("DATA_TYPES", data_types);
936 void BinFolderTargetTrackType::load_xml(FileXML *file)
938 int data_types = file->tag.get_property("DATA_TYPES", this->data_types);
942 void BinFolderTargetTrackType::copy_from(BinFolderTarget *that)
944 BinFolderTargetTrackType *tp = (BinFolderTargetTrackType *)that;
945 update(tp->data_types);
948 void BinFolderTargetTrackType::update(int data_types)
950 this->data_types = data_types;
952 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
953 if( data_types & (1<<TRACK_AUDIO) ) {
954 if( cp > txt && cp < ep ) *cp++ = ' ';
955 cp += snprintf(cp, ep-cp, "%s",_("audio"));
957 if( data_types & (1<<TRACK_VIDEO) ) {
958 if( cp > txt && cp < ep ) *cp++ = ' ';
959 cp += snprintf(cp, ep-cp, "%s",_("video"));
962 filter->update_value(txt);
965 BC_Window *BinFolderTargetTrackType::new_gui(ModifyTargetThread *thread)
967 return new ModifyTargetTrackTypeGUI(thread);
971 BinFolderTargetWidth::BinFolderTargetWidth(BinFolderFilter *filter)
972 : BinFolderTarget(filter, FOLDER_TARGET_WIDTH)
977 BinFolderTargetWidth::~BinFolderTargetWidth()
981 void BinFolderTargetWidth::save_xml(FileXML *file)
983 file->tag.set_property("WIDTH", width);
984 file->tag.set_property("AROUND", around);
986 void BinFolderTargetWidth::load_xml(FileXML *file)
988 int width = file->tag.get_property("WIDTH", this->width);
989 double around = file->tag.get_property("AROUND", this->around);
990 update(width, around);
993 void BinFolderTargetWidth::copy_from(BinFolderTarget *that)
995 BinFolderTargetWidth *tp = (BinFolderTargetWidth *)that;
996 update(tp->width, tp->around);
999 void BinFolderTargetWidth::update(int width, double around)
1001 this->width = width;
1002 this->around = around;
1003 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1004 show_no(width, cp, ep);
1005 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1006 if( cp < ep ) *cp++ = '+';
1007 show_no(around, cp, ep);
1010 filter->update_value(txt);
1013 BC_Window *BinFolderTargetWidth::new_gui(ModifyTargetThread *thread)
1015 return new ModifyTargetWidthGUI(thread);
1019 BinFolderTargetHeight::BinFolderTargetHeight(BinFolderFilter *filter)
1020 : BinFolderTarget(filter, FOLDER_TARGET_HEIGHT)
1025 BinFolderTargetHeight::~BinFolderTargetHeight()
1029 void BinFolderTargetHeight::save_xml(FileXML *file)
1031 file->tag.set_property("HEIGHT", height);
1032 file->tag.set_property("AROUND", around);
1034 void BinFolderTargetHeight::load_xml(FileXML *file)
1036 int height = file->tag.get_property("HEIGHT", this->height);
1037 double around = file->tag.get_property("AROUND", this->around);
1038 update(height, around);
1041 void BinFolderTargetHeight::copy_from(BinFolderTarget *that)
1043 BinFolderTargetHeight *tp = (BinFolderTargetHeight *)that;
1044 update(tp->height, tp->around);
1047 void BinFolderTargetHeight::update(int height, double around)
1049 this->height = height;
1050 this->around = around;
1051 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1052 show_no(height, cp, ep);
1053 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1054 if( cp < ep ) *cp++ = '+';
1055 show_no(around, cp, ep);
1058 filter->update_value(txt);
1061 BC_Window *BinFolderTargetHeight::new_gui(ModifyTargetThread *thread)
1063 return new ModifyTargetHeightGUI(thread);
1067 BinFolderTargetFramerate::BinFolderTargetFramerate(BinFolderFilter *filter)
1068 : BinFolderTarget(filter, FOLDER_TARGET_FRAMERATE)
1071 update(framerate, -1);
1073 BinFolderTargetFramerate::~BinFolderTargetFramerate()
1077 void BinFolderTargetFramerate::save_xml(FileXML *file)
1079 file->tag.set_property("FRAMERATE", framerate);
1080 file->tag.set_property("AROUND", around);
1083 void BinFolderTargetFramerate::load_xml(FileXML *file)
1085 double framerate = file->tag.get_property("FRAMERATE", this->framerate);
1086 double around = file->tag.get_property("AROUND", this->around);
1087 update(framerate, around);
1090 void BinFolderTargetFramerate::copy_from(BinFolderTarget *that)
1092 BinFolderTargetFramerate *tp = (BinFolderTargetFramerate *)that;
1093 update(tp->framerate, tp->around);
1096 void BinFolderTargetFramerate::update(double framerate, double around)
1098 this->framerate = framerate;
1099 this->around = around;
1100 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1101 show_no(framerate, cp, ep, "%0.3f");
1102 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1103 if( cp < ep ) *cp++ = '+';
1104 show_no(around, cp, ep, "%0.3f");
1107 filter->update_value(txt);
1110 BC_Window *BinFolderTargetFramerate::new_gui(ModifyTargetThread *thread)
1112 return new ModifyTargetFramerateGUI(thread);
1116 BinFolderTargetSamplerate::BinFolderTargetSamplerate(BinFolderFilter *filter)
1117 : BinFolderTarget(filter, FOLDER_TARGET_SAMPLERATE)
1120 update(samplerate, -1);
1123 BinFolderTargetSamplerate::~BinFolderTargetSamplerate()
1127 void BinFolderTargetSamplerate::save_xml(FileXML *file)
1129 file->tag.set_property("SAMPLERATE", samplerate);
1130 file->tag.set_property("AROUND", around);
1133 void BinFolderTargetSamplerate::load_xml(FileXML *file)
1135 double samplerate = file->tag.get_property("SAMPLERATE", this->samplerate);
1136 double around = file->tag.get_property("AROUND", this->around);
1137 update(samplerate, around);
1140 void BinFolderTargetSamplerate::copy_from(BinFolderTarget *that)
1142 BinFolderTargetSamplerate *tp = (BinFolderTargetSamplerate *)that;
1143 update(tp->samplerate, tp->around);
1146 void BinFolderTargetSamplerate::update(int samplerate, double around)
1148 this->samplerate = samplerate;
1149 this->around = around;
1150 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1151 show_no(samplerate, cp, ep);
1152 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1153 if( cp < ep ) *cp++ = '+';
1154 show_no(around, cp, ep);
1157 filter->update_value(txt);
1160 BC_Window *BinFolderTargetSamplerate::new_gui(ModifyTargetThread *thread)
1162 return new ModifyTargetSamplerateGUI(thread);
1166 BinFolderTargetChannels::BinFolderTargetChannels(BinFolderFilter *filter)
1167 : BinFolderTarget(filter, FOLDER_TARGET_CHANNELS)
1170 update(channels, -1);
1172 BinFolderTargetChannels::~BinFolderTargetChannels()
1176 void BinFolderTargetChannels::save_xml(FileXML *file)
1178 file->tag.set_property("CHANNELS", channels);
1179 file->tag.set_property("AROUND", around);
1182 void BinFolderTargetChannels::load_xml(FileXML *file)
1184 int channels = file->tag.get_property("CHANNELS", this->channels);
1185 double around = file->tag.get_property("AROUND", this->around);
1186 update(channels, around);
1189 void BinFolderTargetChannels::copy_from(BinFolderTarget *that)
1191 BinFolderTargetChannels *tp = (BinFolderTargetChannels *)that;
1192 update(tp->channels, tp->around);
1195 void BinFolderTargetChannels::update(int channels, double around)
1197 this->channels = channels;
1198 this->around = around;
1199 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1200 show_no(channels, cp, ep);
1201 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1202 if( cp < ep ) *cp++ = '+';
1203 show_no(around, cp, ep);
1206 filter->update_value(txt);
1209 BC_Window *BinFolderTargetChannels::new_gui(ModifyTargetThread *thread)
1211 return new ModifyTargetChannelsGUI(thread);
1215 BinFolderTargetDuration::BinFolderTargetDuration(BinFolderFilter *filter)
1216 : BinFolderTarget(filter, FOLDER_TARGET_DURATION)
1219 update(duration, -1);
1221 BinFolderTargetDuration::~BinFolderTargetDuration()
1225 void BinFolderTargetDuration::save_xml(FileXML *file)
1227 file->tag.set_property("DURATION", duration);
1228 file->tag.set_property("AROUND", around);
1231 void BinFolderTargetDuration::load_xml(FileXML *file)
1233 int64_t duration = file->tag.get_property("DURATION", this->duration);
1234 double around = file->tag.get_property("AROUND", this->around);
1235 update(duration, around);
1238 void BinFolderTargetDuration::copy_from(BinFolderTarget *that)
1240 BinFolderTargetDuration *tp = (BinFolderTargetDuration *)that;
1241 update(tp->duration, tp->around);
1244 void BinFolderTargetDuration::update(int64_t duration, double around)
1246 this->duration = duration;
1247 this->around = around;
1248 char txt[BCSTRLEN], *cp = txt, *ep = cp + sizeof(txt)-1;
1249 show_duration(duration, cp, ep);
1250 if( around >= 0 && filter->op->type == FOLDER_OP_AROUND ) {
1251 if( cp < ep ) *cp++ = '+';
1252 show_duration(around, cp, ep);
1255 filter->update_value(txt);
1258 BC_Window *BinFolderTargetDuration::new_gui(ModifyTargetThread *thread)
1260 return new ModifyTargetDurationGUI(thread);
1264 BinFolderOp::BinFolderOp(BinFolderFilter *filter, int type)
1265 : BC_ListBoxItem(_(types[type]))
1267 this->filter = filter;
1271 BinFolderOp::~BinFolderOp()
1275 void BinFolderOp::copy_from(BinFolderOp *that)
1280 BinFolderOpType::BinFolderOpType(int no)
1281 : BC_MenuItem(_(BinFolderOp::types[no]))
1285 BinFolderOpType::~BinFolderOpType()
1289 int BinFolderOpType::handle_event()
1291 BinFolderOpPopup *op_popup = (BinFolderOpPopup *)get_popup_menu();
1292 BinFolderList *folder_list = op_popup->folder_list;
1293 int i = folder_list->get_selection_number(FOLDER_COLUMN_OP, 0);
1295 BinFolder *folder = folder_list->folder;
1296 BinFolderFilter *filter = folder->filters[i];
1297 filter->update_op(no);
1298 folder_list->create_list();
1303 BinFolderOpPopup::BinFolderOpPopup(BinFolderList *folder_list)
1304 : BC_PopupMenu(0, 0, 0, "", 0)
1306 this->folder_list = folder_list;
1310 void BinFolderOpPopup::create_objects()
1312 add_item(new BinFolderOpType(FOLDER_OP_AROUND));
1313 add_item(new BinFolderOpType(FOLDER_OP_EQ));
1314 add_item(new BinFolderOpType(FOLDER_OP_GE));
1315 add_item(new BinFolderOpType(FOLDER_OP_GT));
1316 add_item(new BinFolderOpType(FOLDER_OP_NE));
1317 add_item(new BinFolderOpType(FOLDER_OP_LE));
1318 add_item(new BinFolderOpType(FOLDER_OP_LT));
1319 add_item(new BinFolderOpType(FOLDER_OP_MATCHES));
1322 void BinFolderOpPopup::activate_menu(BC_ListBoxItem *item)
1324 this->op = (BinFolderOp *)item;
1325 BC_PopupMenu::activate_menu();
1328 double BinFolderOp::test(BinFolderTarget *target, Indexable *idxbl)
1333 double BinFolderOpEQ::test(BinFolderTarget *target, Indexable *idxbl)
1335 double v = compare(target, idxbl);
1336 return v == 0 ? 1 : -1;
1339 double BinFolderOpGT::test(BinFolderTarget *target, Indexable *idxbl)
1341 double v = compare(target, idxbl);
1342 return v > 0 ? 1 : -1;
1345 double BinFolderOpGE::test(BinFolderTarget *target, Indexable *idxbl)
1347 double v = compare(target, idxbl);
1348 return v >= 0 ? 1 : -1;
1351 double BinFolderOpNE::test(BinFolderTarget *target, Indexable *idxbl)
1353 double v = compare(target, idxbl);
1354 return v != 0 ? 1 : -1;
1357 double BinFolderOpLT::test(BinFolderTarget *target, Indexable *idxbl)
1359 double v = compare(target, idxbl);
1360 return v < 0 ? 1 : -1;
1363 double BinFolderOpLE::test(BinFolderTarget *target, Indexable *idxbl)
1365 double v = compare(target, idxbl);
1366 return v <= 0 ? 1 : -1;
1369 double BinFolderOpMatches::test(BinFolderTarget *target, Indexable *idxbl)
1371 double v = compare(target, idxbl);
1375 double BinFolderOpAround::test(BinFolderTarget *target, Indexable *idxbl)
1377 double v = compare(target, idxbl);
1381 BinFolderValue::BinFolderValue(BinFolderFilter *filter, const char *text)
1384 this->filter = filter;
1388 BinFolderValue::~BinFolderValue()
1393 void BinFolderValue::update(const char *text)
1395 const char *cp = text;
1396 char txt[BCSTRLEN], *tp = txt;
1397 for( int i=sizeof(txt); --i>0 && *cp!=0 && *cp!='\n'; ++tp,++cp ) *tp = *cp;
1403 BinFolderList::BinFolderList(BinFolder *folder, MWindow *mwindow,
1404 ModifyFolderGUI *window, int x, int y, int w, int h)
1405 : BC_ListBox(x, y, w, h, LISTBOX_TEXT, 0,
1406 0, 0, 1, 0, 0, LISTBOX_SINGLE, ICON_LEFT, 1)
1408 this->folder = folder;
1409 this->mwindow = mwindow;
1410 this->window = window;
1412 set_process_drag(1);
1419 BinFolderList::~BinFolderList()
1421 save_defaults(mwindow->defaults);
1422 delete modify_target;
1425 void BinFolderList::create_objects()
1427 list_titles[FOLDER_COLUMN_ENABLE] = _("Enable");
1428 list_titles[FOLDER_COLUMN_TARGET] = _("Target");
1429 list_titles[FOLDER_COLUMN_OP] = _("Op");
1430 list_titles[FOLDER_COLUMN_VALUE] = _("Value");
1431 list_width[FOLDER_COLUMN_ENABLE] = 80;
1432 list_width[FOLDER_COLUMN_TARGET] = 80;
1433 list_width[FOLDER_COLUMN_OP] = 50;
1434 list_width[FOLDER_COLUMN_VALUE] = 180;
1435 load_defaults(mwindow->defaults);
1437 add_subwindow(enabled_popup = new BinFolderEnabledPopup(this));
1438 enabled_popup->create_objects();
1439 add_subwindow(op_popup = new BinFolderOpPopup(this));
1440 op_popup->create_objects();
1441 add_subwindow(target_popup = new BinFolderTargetPopup(this));
1442 target_popup->create_objects();
1444 modify_target = new ModifyTargetThread(this);
1447 void BinFolderList::create_list()
1449 for( int i=0; i<FOLDER_COLUMNS; ++i )
1450 list_items[i].remove_all();
1451 for( int i=0; i<folder->filters.size(); ++i ) {
1452 BinFolderFilter *filter = folder->filters[i];
1453 list_items[FOLDER_COLUMN_ENABLE].append(filter->enabled);
1454 list_items[FOLDER_COLUMN_TARGET].append(filter->target);
1455 list_items[FOLDER_COLUMN_OP].append(filter->op);
1456 list_items[FOLDER_COLUMN_VALUE].append(filter->value);
1458 update(list_items, list_titles, list_width, FOLDER_COLUMNS,
1459 get_xposition(), get_yposition(), get_highlighted_item(),
1463 int BinFolderList::handle_event()
1468 int BinFolderList::selection_changed()
1470 if( !cursor_above() ) return 0;
1471 int no = get_selection_number(0, 0);
1472 if( no < 0 ) return 0;
1473 BinFolderFilter *filter = folder->filters[no];
1474 if( get_button_down() && get_buttonpress() == 3 ) {
1475 int cx = get_cursor_x(), col = -1;
1476 for( int i=0; col<0 && i<FOLDER_COLUMNS; ++i ) {
1477 int ofs = get_column_offset(i);
1478 if( cx >= ofs && cx < ofs+get_column_width(i) ) {
1482 BC_ListBoxItem *item = col >= 0 ? get_selection(col, 0) : 0;
1484 deactivate_selection();
1486 case FOLDER_COLUMN_ENABLE:
1487 enabled_popup->activate_menu(item);
1489 case FOLDER_COLUMN_TARGET:
1490 target_popup->activate_menu(item);
1492 case FOLDER_COLUMN_OP:
1493 op_popup->activate_menu(item);
1495 case FOLDER_COLUMN_VALUE: {
1496 modify_target->close_window();
1497 int cw = filter->target->type == FOLDER_TARGET_PATTERNS ? 400 : 320;
1498 int ch = filter->target->type == FOLDER_TARGET_PATTERNS ? 300 : 120;
1499 int cx, cy; get_abs_cursor(cx, cy);
1500 if( (cx-=cw/2) < 50 ) cx = 50;
1501 if( (cy-=ch/2) < 50 ) cy = 50;
1502 modify_target->start(filter->target, cx, cy, cw, ch);
1510 int BinFolderList::column_resize_event()
1512 for( int i = 0; i < FOLDER_COLUMNS; i++ ) {
1513 list_width[i] = get_column_width(i);
1518 int BinFolderList::drag_start_event()
1520 if( BC_ListBox::drag_start_event() ) {
1528 int BinFolderList::drag_motion_event()
1530 if( BC_ListBox::drag_motion_event() ) {
1536 int BinFolderList::drag_stop_event()
1538 if( dragging_item ) {
1539 int src = get_selection_number(0, 0);
1540 int dst = get_highlighted_item();
1542 move_filter(src, dst);
1544 BC_ListBox::drag_stop_event();
1550 void BinFolderList::move_filter(int src, int dst)
1552 BinFolderFilters &filters = folder->filters;
1553 BinFolderFilter *src_filter = filters[src];
1554 if( dst < 0 ) dst = filters.size()-1;
1557 for( int i=src; i<filters.size()-1; ++i )
1558 filters[i] = filters[i+1];
1559 for( int i=filters.size(); --i>dst; )
1560 filters[i] = filters[i-1];
1561 filters[dst] = src_filter;
1565 void BinFolderList::save_defaults(BC_Hash *defaults)
1567 defaults->update("BIN_FOLDER_ENA", list_width[FOLDER_COLUMN_ENABLE]);
1568 defaults->update("BIN_FOLDER_TGT", list_width[FOLDER_COLUMN_TARGET]);
1569 defaults->update("BIN_FOLDER_OPR", list_width[FOLDER_COLUMN_OP]);
1570 defaults->update("BIN_FOLDER_VAL", list_width[FOLDER_COLUMN_VALUE]);
1572 void BinFolderList::load_defaults(BC_Hash *defaults)
1574 list_width[FOLDER_COLUMN_ENABLE] = defaults->get("BIN_FOLDER_ENA", list_width[FOLDER_COLUMN_ENABLE]);
1575 list_width[FOLDER_COLUMN_TARGET] = defaults->get("BIN_FOLDER_TGT", list_width[FOLDER_COLUMN_TARGET]);
1576 list_width[FOLDER_COLUMN_OP] = defaults->get("BIN_FOLDER_OPR", list_width[FOLDER_COLUMN_OP]);
1577 list_width[FOLDER_COLUMN_VALUE] = defaults->get("BIN_FOLDER_VAL", list_width[FOLDER_COLUMN_VALUE]);
1580 BinFolderAddFilter::BinFolderAddFilter(BinFolderList *folder_list, int x, int y)
1581 : BC_GenericButton(x, y, _("Add"))
1583 this->folder_list = folder_list;
1585 BinFolderAddFilter::~BinFolderAddFilter()
1589 int BinFolderAddFilter::handle_event()
1591 folder_list->modify_target->close_window();
1592 // default new filter
1593 BinFolderFilter *filter = new BinFolderFilter();
1594 filter->update_enabled(FOLDER_ENABLED_OR);
1595 filter->update_target(FOLDER_TARGET_PATTERNS);
1596 filter->update_op(FOLDER_OP_MATCHES);
1597 BinFolderTargetPatterns *patterns = (BinFolderTargetPatterns *)(filter->target);
1598 filter->update_value(patterns->text);
1599 folder_list->folder->filters.append(filter);
1600 folder_list->create_list();
1604 BinFolderDelFilter::BinFolderDelFilter(BinFolderList *folder_list, int x, int y)
1605 : BC_GenericButton(x, y, _("Del"))
1607 this->folder_list = folder_list;
1609 BinFolderDelFilter::~BinFolderDelFilter()
1613 int BinFolderDelFilter::handle_event()
1615 folder_list->modify_target->close_window();
1616 int no = folder_list->get_selection_number(0, 0);
1618 folder_list->folder->filters.remove_object_number(no);
1619 folder_list->create_list();
1624 BinFolderApplyFilter::BinFolderApplyFilter(BinFolderList *folder_list, int x, int y)
1625 : BC_GenericButton(x, y, _("Apply"))
1627 this->folder_list = folder_list;
1629 BinFolderApplyFilter::~BinFolderApplyFilter()
1633 int BinFolderApplyFilter::handle_event()
1635 ModifyFolderThread *thread = folder_list->window->thread;
1636 thread->original->copy_from(thread->folder);
1637 thread->agui->async_update_assets();
1642 NewFolderGUI::NewFolderGUI(NewFolderThread *thread, int x, int y, int w, int h)
1643 : BC_Window(_(PROGRAM_NAME ": New folder"),
1644 x, y, w, h, -1, -1, 0, 0, 1)
1646 this->thread = thread;
1649 NewFolderGUI::~NewFolderGUI()
1653 void NewFolderGUI::create_objects()
1655 lock_window("NewFolderGUI::create_objects");
1658 add_subwindow(title = new BC_Title(x, y, _("Enter the name of the folder:")));
1659 y += title->get_h() + 5;
1660 add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, _("Untitled")));
1661 add_subwindow(new BC_OKButton(this));
1662 add_subwindow(new BC_CancelButton(this));
1667 const char* NewFolderGUI::get_text()
1669 return text_box->get_text();
1673 NewFolderThread::NewFolderThread(AWindowGUI *agui)
1679 NewFolderThread::~NewFolderThread()
1684 void NewFolderThread::start(int x, int y, int w, int h)
1692 BC_Window *NewFolderThread::new_gui()
1694 window = new NewFolderGUI(this, wx, wy, ww, wh);
1695 window->create_objects();
1699 void NewFolderThread::handle_done_event(int result)
1702 const char *text = window->get_text();
1703 agui->mwindow->new_folder(text);
1707 void NewFolderThread::handle_close_event(int result)
1711 ModifyFolderGUI::ModifyFolderGUI(ModifyFolderThread *thread, int x, int y, int w, int h)
1712 : BC_Window(_(PROGRAM_NAME ": Modify folder"), x, y, w, h, 320, 200, 1, 0, 1)
1714 this->thread = thread;
1717 ModifyFolderGUI::~ModifyFolderGUI()
1721 int ModifyFolderGUI::receive_custom_xatoms(xatom_event *event)
1723 if( event->message_type == modify_folder_xatom ) {
1730 void ModifyFolderGUI::async_update_filters()
1733 event.message_type = modify_folder_xatom;
1734 send_custom_xatom(&event);
1738 void ModifyFolderGUI::create_objects()
1740 lock_window("ModifyFolderGUI::create_objects");
1741 modify_folder_xatom = create_xatom("CWINDOWGUI_UPDATE_FILTERS");
1743 add_tool(new BC_Title(x, y, _("Enter the name of the folder:")));
1745 add_subwindow(text_box = new BC_TextBox(x, y, 300, 1, thread->folder->title));
1747 int lh = get_h() - y - BC_OKButton::calculate_h() - 30;
1748 int lw = get_w() - x - 120;
1749 add_subwindow(folder_list =
1750 new BinFolderList(thread->folder, thread->agui->mwindow, this, x, y, lw, lh));
1751 folder_list->create_objects();
1752 int x1 = x + folder_list->get_w() + 15, y1 = y;
1753 add_subwindow(add_filter = new BinFolderAddFilter(folder_list, x1, y1));
1754 y1 += add_filter->get_h() + 10;
1755 add_subwindow(del_filter = new BinFolderDelFilter(folder_list, x1, y1));
1756 y1 += del_filter->get_h() + 10;
1757 add_subwindow(apply_filter = new BinFolderApplyFilter(folder_list, x1, y1));
1758 add_subwindow(ok_button = new BC_OKButton(this));
1759 add_subwindow(cancel_button = new BC_CancelButton(this));
1764 int ModifyFolderGUI::resize_event(int w, int h)
1766 MWindow *mwindow = thread->agui->mwindow;
1767 mwindow->session->bwindow_w = w;
1768 mwindow->session->bwindow_h = h;
1769 int lx = folder_list->get_x();
1770 int ly = folder_list->get_y();
1771 int lh = h - ly - BC_OKButton::calculate_h() - 30;
1772 int lw = w - lx - 120;
1773 folder_list->reposition_window(lx, ly, lw, lh);
1774 int x1 = lx + lw + 15;
1775 add_filter->reposition_window(x1, add_filter->get_y());
1776 del_filter->reposition_window(x1, del_filter->get_y());
1777 apply_filter->reposition_window(x1,apply_filter->get_y());
1778 ok_button->resize_event(w, h);
1779 cancel_button->resize_event(w, h);
1783 const char* ModifyFolderGUI::get_text()
1785 return text_box->get_text();
1788 void ModifyFolderGUI::update_filters()
1790 folder_list->create_list();
1794 ModifyFolderThread::ModifyFolderThread(AWindowGUI *agui)
1802 ModifyFolderThread::~ModifyFolderThread()
1808 void ModifyFolderThread::start(BinFolder *folder, int x, int y, int w, int h)
1811 this->original = folder;
1812 agui->mwindow->edl->add_user();
1813 this->folder = new BinFolder(*folder);
1819 BC_Window *ModifyFolderThread::new_gui()
1821 window = new ModifyFolderGUI(this, wx, wy, ww, wh);
1822 window->create_objects();
1826 void ModifyFolderThread::handle_done_event(int result)
1829 const char *title = window->get_text();
1830 if( strcmp(folder->title, title) ) {
1831 if( agui->mwindow->edl->get_folder_number(title) >= 0 ) {
1832 eprintf("folder already exists: %s", title);
1836 strncpy(folder->title, title,sizeof(folder->title));
1840 original->copy_from(folder);
1841 agui->async_update_assets();
1843 delete folder; folder = 0;
1845 agui->mwindow->edl->remove_user();
1848 void ModifyFolderThread::handle_close_event(int result)
1853 ModifyTargetThread::ModifyTargetThread(BinFolderList *folder_list)
1856 this->folder_list = folder_list;
1860 ModifyTargetThread::~ModifyTargetThread()
1865 void ModifyTargetThread::start(BinFolderTarget *target, int x, int y, int w, int h)
1867 this->target = target;
1873 BC_Window *ModifyTargetThread::new_gui()
1875 window = (ModifyTargetGUI *)target->new_gui(this);
1876 window->create_objects();
1880 void ModifyTargetThread::handle_done_event(int result)
1884 folder_list->window->async_update_filters();
1888 void ModifyTargetThread::handle_close_event(int result)
1893 ModifyTargetGUI::ModifyTargetGUI(ModifyTargetThread *thread)
1894 : BC_Window(_(PROGRAM_NAME ": Modify target"),
1895 thread->wx, thread->wy, thread->ww, thread->wh,
1898 this->thread = thread;
1901 ModifyTargetGUI::~ModifyTargetGUI()
1905 void ModifyTargetGUI::create_objects(BC_TextBox *&text_box)
1907 lock_window("ModifyTargetGUI::create_objects");
1909 const char *text = thread->target->filter->value->get_text();
1910 add_subwindow(text_box = new BC_TextBox(x, y, get_w()-20, 1, text));
1911 add_subwindow(new BC_OKButton(this));
1912 add_subwindow(new BC_CancelButton(this));
1917 ModifyTargetPatternsGUI::ModifyTargetPatternsGUI(ModifyTargetThread *thread)
1918 : ModifyTargetGUI(thread)
1920 this->thread = thread;
1921 scroll_text_box = 0;
1924 ModifyTargetPatternsGUI::~ModifyTargetPatternsGUI()
1926 delete scroll_text_box;
1929 void ModifyTargetPatternsGUI::create_objects()
1931 lock_window("ModifyTargetPatternsGUI::create_objects");
1932 BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;
1934 int text_font = MEDIUMFONT;
1935 int text_rowsz = get_text_ascent(text_font)+1 + get_text_descent(text_font)+1;
1936 int th = get_h() - BC_OKButton::calculate_h() - y - 10;
1937 int rows = th / text_rowsz;
1938 scroll_text_box = new BC_ScrollTextBox(this, x, y, get_w()-20, rows, target->text);
1939 scroll_text_box->create_objects();
1940 add_subwindow(new BC_OKButton(this));
1941 add_subwindow(new BC_CancelButton(this));
1946 void ModifyTargetPatternsGUI::update()
1948 BinFolderTargetPatterns *target = (BinFolderTargetPatterns *)thread->target;
1949 const char *cp = scroll_text_box->get_text();
1954 ModifyTargetFileSizeGUI::ModifyTargetFileSizeGUI(ModifyTargetThread *thread)
1955 : ModifyTargetGUI(thread)
1959 ModifyTargetFileSizeGUI::~ModifyTargetFileSizeGUI()
1963 void ModifyTargetFileSizeGUI::create_objects()
1965 ModifyTargetGUI::create_objects(text_box);
1968 void ModifyTargetFileSizeGUI::update()
1970 BinFolderTargetFileSize *target = (BinFolderTargetFileSize *)thread->target;
1971 double file_size = target->file_size, around = target->around;
1972 const char *cp = text_box->get_text(); char *bp = 0;
1973 scan_around(cp, bp, file_size, around);
1974 target->update(file_size, around);
1978 ModifyTargetTimeGUI::ModifyTargetTimeGUI(ModifyTargetThread *thread)
1979 : ModifyTargetGUI(thread)
1983 ModifyTargetTimeGUI::~ModifyTargetTimeGUI()
1987 void ModifyTargetTimeGUI::create_objects()
1989 ModifyTargetGUI::create_objects(text_box);
1992 void ModifyTargetTimeGUI::update()
1994 BinFolderTargetTime *target = (BinFolderTargetTime *)thread->target;
1995 int64_t mtime = target->mtime; double around = target->around;
1996 const char *cp = text_box->get_text(); char *bp = 0;
1997 int64_t v = scan_date(cp, bp);
2001 v = scan_duration(cp=bp+1, bp);
2002 if( bp > cp ) around = v;
2005 target->update(mtime, around);
2009 ModifyTargetTrackTypeGUI::ModifyTargetTrackTypeGUI(ModifyTargetThread *thread)
2010 : ModifyTargetGUI(thread)
2014 ModifyTargetTrackTypeGUI::~ModifyTargetTrackTypeGUI()
2018 void ModifyTargetTrackTypeGUI::create_objects()
2020 ModifyTargetGUI::create_objects(text_box);
2023 void ModifyTargetTrackTypeGUI::update()
2025 BinFolderTargetTrackType *target = (BinFolderTargetTrackType *)thread->target;
2026 const char *cp = text_box->get_text();
2028 if( bstrcasestr(cp, _("audio")) ) data_types |= (1<<TRACK_AUDIO);
2029 if( bstrcasestr(cp, _("video")) ) data_types |= (1<<TRACK_VIDEO);
2030 target->update(data_types);
2034 ModifyTargetWidthGUI::ModifyTargetWidthGUI(ModifyTargetThread *thread)
2035 : ModifyTargetGUI(thread)
2039 ModifyTargetWidthGUI::~ModifyTargetWidthGUI()
2043 void ModifyTargetWidthGUI::create_objects()
2045 ModifyTargetGUI::create_objects(text_box);
2048 void ModifyTargetWidthGUI::update()
2050 BinFolderTargetWidth *target = (BinFolderTargetWidth *)thread->target;
2051 double width = target->width, around = target->around;
2052 const char *cp = text_box->get_text(); char *bp = 0;
2053 scan_around(cp, bp, width, around);
2054 target->update(width, around);
2058 ModifyTargetHeightGUI::ModifyTargetHeightGUI(ModifyTargetThread *thread)
2059 : ModifyTargetGUI(thread)
2063 ModifyTargetHeightGUI::~ModifyTargetHeightGUI()
2067 void ModifyTargetHeightGUI::create_objects()
2069 ModifyTargetGUI::create_objects(text_box);
2072 void ModifyTargetHeightGUI::update()
2074 BinFolderTargetHeight *target = (BinFolderTargetHeight *)thread->target;
2075 double height = target->height, around = target->around;
2076 const char *cp = text_box->get_text(); char *bp = 0;
2077 scan_around(cp, bp, height, around);
2078 target->update(height, around);
2082 ModifyTargetFramerateGUI::ModifyTargetFramerateGUI(ModifyTargetThread *thread)
2083 : ModifyTargetGUI(thread)
2087 ModifyTargetFramerateGUI::~ModifyTargetFramerateGUI()
2091 void ModifyTargetFramerateGUI::create_objects()
2093 ModifyTargetGUI::create_objects(text_box);
2096 void ModifyTargetFramerateGUI::update()
2098 BinFolderTargetFramerate *target = (BinFolderTargetFramerate *)thread->target;
2099 double framerate = target->framerate, around = target->around;
2100 const char *cp = text_box->get_text(); char *bp = 0;
2101 scan_around(cp, bp, framerate, around);
2102 target->update(framerate, around);
2106 ModifyTargetSamplerateGUI::ModifyTargetSamplerateGUI(ModifyTargetThread *thread)
2107 : ModifyTargetGUI(thread)
2111 ModifyTargetSamplerateGUI::~ModifyTargetSamplerateGUI()
2115 void ModifyTargetSamplerateGUI::create_objects()
2117 ModifyTargetGUI::create_objects(text_box);
2120 void ModifyTargetSamplerateGUI::update()
2122 BinFolderTargetSamplerate *target = (BinFolderTargetSamplerate *)thread->target;
2123 double samplerate = target->samplerate, around = target->around;
2124 const char *cp = text_box->get_text(); char *bp = 0;
2125 scan_around(cp, bp, samplerate, around);
2126 target->update(samplerate, around);
2130 ModifyTargetChannelsGUI::ModifyTargetChannelsGUI(ModifyTargetThread *thread)
2131 : ModifyTargetGUI(thread)
2135 ModifyTargetChannelsGUI::~ModifyTargetChannelsGUI()
2139 void ModifyTargetChannelsGUI::create_objects()
2141 ModifyTargetGUI::create_objects(text_box);
2144 void ModifyTargetChannelsGUI::update()
2146 BinFolderTargetChannels *target = (BinFolderTargetChannels *)thread->target;
2147 double channels = target->channels, around = target->around;
2148 const char *cp = text_box->get_text(); char *bp = 0;
2149 scan_around(cp, bp, channels, around);
2150 target->update(channels, around);
2154 ModifyTargetDurationGUI::ModifyTargetDurationGUI(ModifyTargetThread *thread)
2155 : ModifyTargetGUI(thread)
2159 ModifyTargetDurationGUI::~ModifyTargetDurationGUI()
2163 void ModifyTargetDurationGUI::create_objects()
2165 ModifyTargetGUI::create_objects(text_box);
2168 void ModifyTargetDurationGUI::update()
2170 BinFolderTargetDuration *target = (BinFolderTargetDuration *)thread->target;
2171 int64_t duration = target->duration, around = target->around;
2172 const char *cp = text_box->get_text(); char *bp = 0;
2173 int64_t v = scan_duration(cp, bp);
2177 v = scan_duration(cp=bp+1, bp);
2178 if( bp > cp ) around = v;
2181 target->update(duration, around);