~ubuntu-branches/ubuntu/wily/bombono-dvd/wily

« back to all changes in this revision

Viewing changes to src/mgui/dvdimport.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2010-03-12 08:42:05 UTC
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100312084205-kugmzrqqv7zm3k7n
Tags: upstream-0.5.5
Import upstream version 0.5.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include <mgui/render/common.h> // FillEmpty()
27
27
#include <mgui/project/mb-actions.h> // TryAddMedia()
 
28
#include <mgui/gettext.h>
28
29
 
 
30
#include "sdk/treemodel.h"
29
31
#include "sdk/window.h"
30
32
#include "sdk/packing.h"
31
33
#include "sdk/widget.h"
40
42
 
41
43
namespace DVD {
42
44
 
 
45
struct VobFields
 
46
{
 
47
    Gtk::TreeModelColumn<bool>          selState;
 
48
    Gtk::TreeModelColumn<RefPtr<Gdk::Pixbuf> > thumbnail;
 
49
    Gtk::TreeModelColumn<std::string>   name;
 
50
    Gtk::TreeModelColumn<std::string>   desc;
 
51
 
 
52
    VobFields(Gtk::TreeModelColumnRecord& rec)
 
53
    {
 
54
        rec.add(selState);
 
55
        rec.add(thumbnail);
 
56
        rec.add(name);
 
57
        rec.add(desc);
 
58
    }
 
59
};
 
60
 
43
61
static VobFields& VF()
44
62
{
45
 
    return VobFields::Instance();
 
63
    return GetColumnFields<VobFields>();
46
64
}
47
65
 
48
66
ImportData::ImportData(): srcChooser(Gtk::FILE_CHOOSER_ACTION_OPEN), 
60
78
    switch( pg_num )
61
79
    {
62
80
    case ipCHOOSE_SOURCE: 
63
 
        title = "Choose Source DVD-Video";
 
81
        title = _("Choose Source DVD-Video");
64
82
        break;
65
83
    case ipSELECT_VOBS: 
66
 
        title = "Select Videos to Import";
 
84
        title = _("Select Videos to Import");
67
85
        break;
68
86
    case ipCHOOSE_DEST: 
69
 
        title = "Select Folder to Save Videos";
 
87
        title = _("Select Folder to Save Videos");
70
88
        break;
71
89
    case ipIMPORT_PROC: 
72
 
        title = "Importing...";
 
90
        title = _("Importing...");
73
91
        break;
74
92
    case ipEND: 
75
 
        title = "Import is completed.";
 
93
        title = _("Import is completed.");
76
94
        break;
77
95
    default: 
78
96
        ASSERT(0);
185
203
                std::string desc = (str::stream(Mpeg::SecToHMS(vob.tmLen, true)) <<  ", "
186
204
                                    << vob.sz.x << "x" << vob.sz.y << ", "
187
205
                                    << (vob.aspect == af4_3 ? "4:3" : "16:9") << ", " 
188
 
                                    << std::fixed << std::setprecision(2) << vob.Count()/512. << " Mb").str();
 
206
                                    << std::fixed << std::setprecision(2) << vob.Count()/512. << " " << _("MB")).str();
189
207
                row[VF().desc]      = desc;
190
208
            }
191
209
            CompleteSelection(id, false);
194
212
            id.numToThumb = 0;
195
213
        }
196
214
        
197
 
        // бывают случаи вызова prepare на одной странице дважды 
198
 
        // - set_current_page() + "map"
199
 
        if( id.curPage != ipSELECT_VOBS ) // дважды
200
 
            id.thumbIdler.ConnectIdle(bl::bind(&OnSelectIdle, boost::ref(id)));
 
215
        ASSERT( id.curPage != ipSELECT_VOBS );
 
216
        id.thumbIdler.ConnectIdle(bl::bind(&OnSelectIdle, boost::ref(id)));
201
217
    }
202
218
    else
203
219
        id.CloseIdlers();
233
249
    return reader;
234
250
}
235
251
 
236
 
static void OnSelectSource(ImportData& id)
 
252
static ReaderPtr OpenDVD(const std::string& dvd_path, ImportData& id)
237
253
{
238
 
    Gtk::FileChooserWidget& fcw = id.srcChooser;
239
 
    std::string dvd_path = fcw.get_filename().raw();
240
 
 
241
254
    bool is_pal;
242
255
    ReaderPtr rd = OpenDVD(dvd_path, is_pal);
243
256
    if( rd && id.addToProject && (is_pal != Project::AData().PalTvSystem()) )
250
263
 
251
264
    id.reader = rd;
252
265
    SetCurPageComplete(id.ast, id.reader);
 
266
 
 
267
    return rd;
 
268
}
 
269
 
 
270
static void OnSelectSource(ImportData& id)
 
271
{
 
272
    if( id.ast.get_current_page() != ipCHOOSE_SOURCE )
 
273
        return;
 
274
 
 
275
    // :TODO: порой тупит и выдает "" (файл не выделен якобы)
 
276
    // Из-за этого errLbl может скрываться когда не надо
 
277
    Gtk::FileChooserWidget& fcw = id.srcChooser;
 
278
    std::string dvd_path = fcw.get_filename().raw();
 
279
 
 
280
    OpenDVD(dvd_path, id);
253
281
}
254
282
 
255
283
bool SetVobSel(Gtk::TreeIter& itr, bool select_all)
356
384
static void PackSelectionButton(Gtk::HBox& hbox, RefPtr<Gtk::SizeGroup> sg, bool select_all,
357
385
                                ImportData& id)
358
386
{
359
 
    const char* text = select_all ? "Select All" : "Unselect All" ;
 
387
    const char* text = select_all ? _("Select All") : _("Unselect All") ;
360
388
    Gtk::Button& btn = PackStart(hbox, NewManaged<Gtk::Button>(text));
361
389
    sg->add_widget(btn);
362
390
 
378
406
{
379
407
    // мы не можем пустить исключение здесь, потому что оно пойдет
380
408
    // и через C-шный код (Gtk) - отложим
381
 
    if( MessageBox("Are you sure to stop importing?", 
 
409
    if( MessageBox(_("Are you sure to stop importing?"), 
382
410
                   Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO) == Gtk::RESPONSE_YES )
383
411
        id.isBreak = true;
384
412
}
400
428
 
401
429
static void OnApply(ImportData& id)
402
430
{
 
431
// смотри коммит ae37d209 в git://git.gnome.org/gtk+
 
432
#if GTK_CHECK_VERSION(2,17,7)
 
433
    id.ast.set_current_page(ipIMPORT_PROC);
 
434
#endif
 
435
 
403
436
    std::string& dir_path = id.destPath;
404
437
    VobArr& arr = id.dvdVobs;
405
438
    ASSERT( fs::is_directory(dir_path) );
406
439
 
407
440
    bool res = Project::HaveFullAccess(dir_path);
408
441
    if( !res )
409
 
        MessageBox("Cant write to folder " + dir_path + " (check permissions).",
 
442
        MessageBox(BF_("Cant write to folder %1% (check permissions).") % dir_path % bf::stop,
410
443
                   Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK);
411
444
    else
412
445
    {
434
467
                    std::string name  = itr->get_value(VF().name);
435
468
                    std::string fname = AppendPath(dir_path, name);
436
469
                    if( fs::exists(fname) )
437
 
                        if( MessageBox("The file already " + name + " already exists. Overwrite it?",
 
470
                        if( MessageBox(BF_("A file named \"%1%\" already exists. Do you want to replace it?") % name % bf::stop,
438
471
                                       Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO) != Gtk::RESPONSE_YES )
439
472
                        {
440
473
                            res = false;    
463
496
                        std::string err_str;
464
497
                        Gtk::TreePath pth;
465
498
                        if( !Project::TryAddMedia(fname.c_str(), pth, err_str) )
 
499
                        {    
466
500
                            LOG_ERR << "Import error: " << err_str << io::endl;
 
501
                        }
467
502
                    }
468
503
                }
469
504
        }
470
505
        catch(const std::exception& err)
471
506
        {
472
507
            res = false;
473
 
            const char* what = err.what();
474
 
            if( what && (strcmp(what, USERT_BREAK_STR) != 0) )
475
 
              MessageBox("Import error!", Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, what);
 
508
            const char* what = err.what();
 
509
            if( what && (strcmp(what, USERT_BREAK_STR) != 0) )
 
510
                MessageBox(_("Import error!"), Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, what);
476
511
        }
477
512
    }
478
513
 
479
 
    const char* final = res ? "Videos successfully imported." 
480
 
        : "Import has been interrupted." ;
 
514
    const char* final = res ? _("Videos successfully imported.") 
 
515
        : _("Import has been interrupted.") ;
481
516
    FillLabelForImport(id.finalMsg, final);
 
517
 
 
518
// смотри коммит ae37d209 в git://git.gnome.org/gtk+
 
519
#if !GTK_CHECK_VERSION(2,17,7)
482
520
    id.ast.set_current_page(ipEND);
 
521
#endif
483
522
}
484
523
 
485
524
static Gtk::VBox& AppendVBoxAsPage(Gtk::Assistant& ast, Gtk::Container*& page)
507
546
void ConstructImporter(ImportData& id)
508
547
{
509
548
    Gtk::Assistant& ast = id.ast;
510
 
    ast.set_title("DVD-Video Import");
 
549
    ast.set_title(_("DVD-Video Import"));
511
550
    ast.set_default_size(600, 500);
512
551
 
513
552
    ast.signal_cancel().connect(&Gtk::Main::quit);
530
569
                typ = Gtk::ASSISTANT_PAGE_INTRO;
531
570
 
532
571
                Gtk::FileChooserWidget& fcw = id.srcChooser;
533
 
                PackFCWPage(vbox, fcw, "Choose DVD disc, DVD folder or iso image file.");
 
572
                PackFCWPage(vbox, fcw, _("Choose DVD disc, DVD folder or iso image file."));
534
573
                fcw.signal_selection_changed().connect(bl::bind(&OnSelectSource, ref_id));
535
574
 
536
575
                // 
547
586
                //fcw.set_filter(ff);
548
587
 
549
588
                Gtk::Label& err_lbl = id.errLbl;
550
 
                err_lbl.set_markup("<span foreground=\"red\">NTSC/PAL mismatch. Try another disc"
551
 
                                   " or import to project of corresponding type.</span>");
 
589
                err_lbl.set_markup(boost::format("<span foreground=\"red\">%1%</span>")
 
590
                                   % _("NTSC/PAL mismatch. Try another disc or import to project of corresponding type.")
 
591
                                   % bf::stop);
552
592
                ast.add_action_widget(err_lbl); // по умолчанию не видна
553
593
                SetExpandFill(err_lbl);
554
594
                SetAlign(err_lbl);
561
601
                page = &hbox;
562
602
 
563
603
                RefPtr<Gtk::ListStore>& vob_list = id.vobList;
564
 
                vob_list = Gtk::ListStore::create(VF());
 
604
                vob_list = Gtk::ListStore::create(GetColumnRecord<VobFields>());
565
605
 
566
606
                Gtk::TreeView& view = NewManaged<Gtk::TreeView>(vob_list);
567
607
                view.signal_row_activated().connect(bl::bind(&OnVobActivate, bl::_1, ref_id));
571
611
                sel_rndr.signal_toggled().connect(bl::bind(&OnSelVob, ref_id));
572
612
 
573
613
                // имя
574
 
                Gtk::TreeView::Column& name_cln = NewManaged<Gtk::TreeView::Column>("Name");
 
614
                Gtk::TreeView::Column& name_cln = NewManaged<Gtk::TreeView::Column>(_("Name"));
575
615
                name_cln.set_resizable(true);
576
616
                name_cln.set_expand(true);
577
617
 
584
624
                name_cln.pack_start(rndr);
585
625
                name_cln.set_renderer(rndr, VF().name);
586
626
                view.append_column(name_cln);
587
 
                view.append_column("Details", VF().desc);
 
627
                view.append_column(_("Details"), VF().desc);
588
628
 
589
629
                Gtk::ScrolledWindow& scr_win = PackStart(hbox, NewManaged<Gtk::ScrolledWindow>(),
590
630
                                                         Gtk::PACK_EXPAND_WIDGET);
630
670
                typ = Gtk::ASSISTANT_PAGE_CONFIRM;
631
671
 
632
672
                Gtk::FileChooserWidget& fcw = NewManaged<Gtk::FileChooserWidget>(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
633
 
                PackFCWPage(vbox, fcw, "It is desirable the destination folder to be empty.");
 
673
                PackFCWPage(vbox, fcw, _("It is desirable the destination folder to be empty."));
634
674
 
635
675
                fcw.signal_selection_changed().connect(
636
676
                    bl::bind(&OnSelectDest, boost::ref(fcw), ref_id));
681
721
    id.addToProject = true;
682
722
 
683
723
    ConstructImporter(id);
684
 
    
 
724
    //
 
725
    // По опыту с помощником (GtkAssistant) стало ясно:
 
726
    // - до момента show_all() вообще нельзя менять текущую страницу,
 
727
    //   типы страниц и т.д.; иначе легко получить "UB", выражающееся в сегфолтах
 
728
    //   и хз еще в чем
 
729
    // - вывод: хочется изменения в помощнике - создавай его по-другому с самого
 
730
    //   начала (ConstructImporter())
 
731
    //
 
732
    ast.show_all();
 
733
 
685
734
    if( !dvd_path.empty() )
686
735
    {
687
 
        // реализовать переход сразу на 2ю страницу оказалось
688
 
        // непростым делом:
689
 
        // - после явного открытия reader'а самое главное - 
690
 
        //   не дать srcChooser переустановить его вызовом
691
 
        //   OnSelectSource() =>
692
 
        // - перепробовав все, что можно (и скрытие, и удаление
693
 
        //   первой страницы, ...), стало ясно, что нельзя вызывать
694
 
        //   show_all() окна, если на первой странице =>
695
 
        // - простой переход на 2ю страницу дает сегфолт, если
696
 
        //   ранее не проходил show_all() (см. интересную функцию
697
 
        //   compute_last_button_state()) - пат
698
 
        // - и только смена типа с GTK_ASSISTANT_PAGE_CONTENT на любой
699
 
        //   другой дала нужный результат!
700
 
 
701
 
        bool is_pal;
702
 
        ReaderPtr rd = OpenDVD(dvd_path, is_pal);
703
 
        if( rd && (is_pal == Project::AData().PalTvSystem()) )
704
 
        {
705
 
            // чтоб не смутить OnPreparePage()
706
 
            id.curPage = ipCHOOSE_SOURCE;
707
 
            id.reader = rd;
708
 
 
709
 
            ast.set_page_type(*ast.get_nth_page(ipSELECT_VOBS), Gtk::ASSISTANT_PAGE_INTRO);
 
736
        // перейдем в директорию
 
737
        id.srcChooser.set_filename(dvd_path);
 
738
 
 
739
        if( OpenDVD(dvd_path, id) )
710
740
            ast.set_current_page(ipSELECT_VOBS);
711
 
        }
712
 
        else
713
 
            // не получилось - тогда хотя бы перейдем в директорию
714
 
            id.srcChooser.select_filename(dvd_path);
715
741
    }
716
 
    RunWindow(ast);
 
742
 
 
743
    Gtk::Main::run(ast);
717
744
}
718
745
 
719
746
} // namespace DVD