~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to gtk2_ardour/export_range_markers_dialog.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2006 Paul Davis
 
3
    Author: Andre Raue
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 
 
19
*/
 
20
 
 
21
#include <sys/stat.h>
 
22
 
 
23
#include <sstream>
 
24
 
 
25
#include "ardour/audioengine.h"
 
26
#include "ardour/sndfile_helpers.h"
 
27
 
 
28
#include "ardour_ui.h"
 
29
#include "export_range_markers_dialog.h"
 
30
 
 
31
#include "i18n.h"
 
32
 
 
33
using namespace Gtk;
 
34
using namespace ARDOUR;
 
35
using namespace PBD;
 
36
using namespace std;
 
37
 
 
38
ExportRangeMarkersDialog::ExportRangeMarkersDialog (PublicEditor& editor)
 
39
        : ExportDialog(editor)
 
40
{
 
41
        set_title (_("Export Ranges"));
 
42
        file_frame.set_label (_("Export to Directory"));
 
43
 
 
44
        do_not_allow_export_cd_markers();
 
45
 
 
46
        total_duration = 0;
 
47
        current_range_marker_index = 0;
 
48
}
 
49
 
 
50
Gtk::FileChooserAction
 
51
ExportRangeMarkersDialog::browse_action () const
 
52
{
 
53
        return Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER;
 
54
}
 
55
 
 
56
void
 
57
ExportRangeMarkersDialog::export_data ()
 
58
{
 
59
        getSession().locations()->apply(*this, &ExportRangeMarkersDialog::process_range_markers_export);
 
60
}
 
61
 
 
62
void
 
63
ExportRangeMarkersDialog::process_range_markers_export(Locations::LocationList& locations)
 
64
{
 
65
        Locations::LocationList::iterator locationIter;
 
66
        current_range_marker_index = 0;
 
67
        init_progress_computing(locations);
 
68
 
 
69
        for (locationIter = locations.begin(); locationIter != locations.end(); ++locationIter) {
 
70
                Location *currentLocation = (*locationIter);
 
71
 
 
72
                if(currentLocation->is_range_marker()){
 
73
                        // init filename
 
74
                        string filepath = get_target_filepath(
 
75
                                get_selected_file_name(),
 
76
                                currentLocation->name(),
 
77
                                get_selected_header_format());
 
78
 
 
79
                        initSpec(filepath);
 
80
 
 
81
                        spec.start_frame = currentLocation->start();
 
82
                        spec.end_frame = currentLocation->end();
 
83
 
 
84
                        if (getSession().start_export(spec)){
 
85
                                // if export fails
 
86
                                return;
 
87
                        }
 
88
 
 
89
                        // wait until export of this range finished
 
90
                        gtk_main_iteration();
 
91
 
 
92
                        while (spec.running){
 
93
                                if(gtk_events_pending()){
 
94
                                        gtk_main_iteration();
 
95
                                }else {
 
96
                                        usleep(10000);
 
97
                                }
 
98
                        }
 
99
 
 
100
                        current_range_marker_index++;
 
101
 
 
102
                        getSession().stop_export (spec);
 
103
                }
 
104
        }
 
105
 
 
106
        spec.running = false;
 
107
}
 
108
 
 
109
 
 
110
string
 
111
ExportRangeMarkersDialog::get_target_filepath(string path, string filename, string postfix)
 
112
{
 
113
        string target_path = path;
 
114
        if ((target_path.find_last_of ('/')) != string::npos) {
 
115
                target_path += '/';
 
116
        }
 
117
 
 
118
        string target_filepath = target_path + filename + postfix;
 
119
        struct stat statbuf;
 
120
 
 
121
        for(int counter=1; (stat (target_filepath.c_str(), &statbuf) == 0); counter++){
 
122
                // while file exists
 
123
                ostringstream scounter;
 
124
                scounter.flush();
 
125
                scounter << counter;
 
126
 
 
127
                target_filepath =
 
128
                        target_path + filename + "_" + scounter.str() + postfix;
 
129
        }
 
130
 
 
131
        return target_filepath;
 
132
}
 
133
 
 
134
bool
 
135
ExportRangeMarkersDialog::is_filepath_valid(string &filepath)
 
136
{
 
137
        // sanity check file name first
 
138
        struct stat statbuf;
 
139
 
 
140
        if (filepath.empty()) {
 
141
                // warning dialog
 
142
                string txt = _("Please enter a valid target directory.");
 
143
                MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
 
144
                msg.run();
 
145
                return false;
 
146
        }
 
147
 
 
148
        if ( (stat (filepath.c_str(), &statbuf) != 0) ||
 
149
                (!S_ISDIR (statbuf.st_mode)) ) {
 
150
                string txt = _("Please select an existing target directory. Files are not allowed!");
 
151
                MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
 
152
                msg.run();
 
153
                return false;
 
154
        }
 
155
 
 
156
        // directory needs to exist and be writable
 
157
        string dirpath = Glib::path_get_dirname (filepath);
 
158
        if (!exists_and_writable (dirpath)) {
 
159
                string txt = _("Cannot write file in: ") + dirpath;
 
160
                MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
 
161
                msg.run();
 
162
                return false;
 
163
        }
 
164
 
 
165
        return true;
 
166
}
 
167
 
 
168
void
 
169
ExportRangeMarkersDialog::init_progress_computing(Locations::LocationList& locations)
 
170
{
 
171
        // flush vector
 
172
        range_markers_durations_aggregated.resize(0);
 
173
 
 
174
        framecnt_t duration_before_current_location = 0;
 
175
        Locations::LocationList::iterator locationIter;
 
176
 
 
177
        for (locationIter = locations.begin(); locationIter != locations.end(); ++locationIter) {
 
178
                Location *currentLocation = (*locationIter);
 
179
 
 
180
                if(currentLocation->is_range_marker()){
 
181
                        range_markers_durations_aggregated.push_back (duration_before_current_location);
 
182
 
 
183
                        framecnt_t duration = currentLocation->end() - currentLocation->start();
 
184
 
 
185
                        range_markers_durations.push_back (duration);
 
186
                        duration_before_current_location += duration;
 
187
                }
 
188
        }
 
189
 
 
190
        total_duration = duration_before_current_location;
 
191
}
 
192
 
 
193
 
 
194
gint
 
195
ExportRangeMarkersDialog::progress_timeout ()
 
196
{
 
197
        double progress = 0.0;
 
198
 
 
199
        if (current_range_marker_index >= range_markers_durations.size()){
 
200
                progress = 1.0;
 
201
        } else{
 
202
                progress = ((double) range_markers_durations_aggregated[current_range_marker_index] +
 
203
                            (spec.progress * (double) range_markers_durations[current_range_marker_index])) /
 
204
                        (double) total_duration;
 
205
        }
 
206
 
 
207
        set_progress_fraction( progress );
 
208
        return TRUE;
 
209
}