18 |
*/ |
*/ |
19 |
|
|
20 |
#include <iostream> |
#include <iostream> |
21 |
|
#include <cstring> |
22 |
|
|
23 |
#include <gtkmm/filechooserdialog.h> |
#include <gtkmm/filechooserdialog.h> |
24 |
#include <gtkmm/messagedialog.h> |
#include <gtkmm/messagedialog.h> |
209 |
Gtk::Action::create("RemoveSample", Gtk::Stock::REMOVE), |
Gtk::Action::create("RemoveSample", Gtk::Stock::REMOVE), |
210 |
sigc::mem_fun(*this, &MainWindow::on_action_remove_sample) |
sigc::mem_fun(*this, &MainWindow::on_action_remove_sample) |
211 |
); |
); |
212 |
|
actionGroup->add( |
213 |
|
Gtk::Action::create("ReplaceAllSamplesInAllGroups", _("Replace All Samples In All Groups")), |
214 |
|
sigc::mem_fun(*this, &MainWindow::on_action_replace_all_samples_in_all_groups) |
215 |
|
); |
216 |
|
|
217 |
uiManager = Gtk::UIManager::create(); |
uiManager = Gtk::UIManager::create(); |
218 |
uiManager->insert_action_group(actionGroup); |
uiManager->insert_action_group(actionGroup); |
253 |
" <menuitem action='SampleProperties'/>" |
" <menuitem action='SampleProperties'/>" |
254 |
" <menuitem action='AddGroup'/>" |
" <menuitem action='AddGroup'/>" |
255 |
" <menuitem action='AddSample'/>" |
" <menuitem action='AddSample'/>" |
256 |
|
" <menuitem action='ReplaceAllSamplesInAllGroups' />" |
257 |
" <separator/>" |
" <separator/>" |
258 |
" <menuitem action='RemoveSample'/>" |
" <menuitem action='RemoveSample'/>" |
259 |
" </popup>" |
" </popup>" |
266 |
m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK); |
m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK); |
267 |
m_VBox.pack_start(m_HPaned); |
m_VBox.pack_start(m_HPaned); |
268 |
m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK); |
m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK); |
269 |
|
m_VBox.pack_start(m_RegionChooser.m_VirtKeybPropsBox, Gtk::PACK_SHRINK); |
270 |
m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK); |
m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK); |
271 |
m_VBox.pack_start(m_StatusBar, Gtk::PACK_SHRINK); |
m_VBox.pack_start(m_StatusBar, Gtk::PACK_SHRINK); |
272 |
|
|
753 |
filter.add_pattern("*.gig"); |
filter.add_pattern("*.gig"); |
754 |
dialog.set_filter(filter); |
dialog.set_filter(filter); |
755 |
|
|
756 |
if (Glib::path_is_absolute(filename)) { |
// set initial dir and filename of the Save As dialog |
757 |
dialog.set_filename(filename); |
// and prepare that initial filename as a copy of the gig |
758 |
} else if (current_dir != "") { |
{ |
759 |
dialog.set_current_folder(current_dir); |
std::string basename = Glib::path_get_basename(filename); |
760 |
|
std::string dir = Glib::path_get_dirname(filename); |
761 |
|
basename = std::string("copy_of_") + basename; |
762 |
|
Glib::ustring copyFileName = Glib::build_filename(dir, basename); |
763 |
|
if (Glib::path_is_absolute(filename)) { |
764 |
|
dialog.set_filename(copyFileName); |
765 |
|
} else { |
766 |
|
if (current_dir != "") dialog.set_current_folder(current_dir); |
767 |
|
} |
768 |
|
dialog.set_current_name(Glib::filename_display_basename(copyFileName)); |
769 |
} |
} |
770 |
dialog.set_current_name(Glib::filename_display_basename(filename)); |
|
771 |
|
// show warning in the dialog |
772 |
|
Gtk::HBox descriptionArea; |
773 |
|
descriptionArea.set_spacing(15); |
774 |
|
Gtk::Image warningIcon(Gtk::Stock::DIALOG_WARNING, Gtk::IconSize(Gtk::ICON_SIZE_DIALOG)); |
775 |
|
descriptionArea.pack_start(warningIcon, Gtk::PACK_SHRINK); |
776 |
|
warningIcon.show(); |
777 |
|
Gtk::Label description; |
778 |
|
description.set_markup( |
779 |
|
_("\n<b>CAUTION:</b> You <b>MUST</b> use the " |
780 |
|
"<span style=\"italic\">\"Save\"</span> dialog instead of " |
781 |
|
"<span style=\"italic\">\"Save As...\"</span> if you want to save " |
782 |
|
"to the same .gig file. Using " |
783 |
|
"<span style=\"italic\">\"Save As...\"</span> for writing to the " |
784 |
|
"same .gig file will end up in corrupted sample wave data!\n") |
785 |
|
); |
786 |
|
description.set_line_wrap(true); |
787 |
|
descriptionArea.pack_start(description, Gtk::PACK_SHRINK); |
788 |
|
description.show(); |
789 |
|
dialog.get_vbox()->pack_start(descriptionArea, Gtk::PACK_SHRINK); |
790 |
|
descriptionArea.show(); |
791 |
|
|
792 |
if (dialog.run() == Gtk::RESPONSE_OK) { |
if (dialog.run() == Gtk::RESPONSE_OK) { |
793 |
file_structure_to_be_changed_signal.emit(this->file); |
file_structure_to_be_changed_signal.emit(this->file); |
1528 |
} |
} |
1529 |
} |
} |
1530 |
|
|
1531 |
|
void MainWindow::on_action_replace_all_samples_in_all_groups() |
1532 |
|
{ |
1533 |
|
if (!file) return; |
1534 |
|
Gtk::FileChooserDialog dialog(*this, _("Select Folder"), |
1535 |
|
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); |
1536 |
|
Gtk::Label description( |
1537 |
|
_("This is a very specific function. It tries to replace all samples " |
1538 |
|
"in the current gig file by samples located in the directory chosen " |
1539 |
|
"by you above.\n\n" |
1540 |
|
"It works like this: For each sample in the gig file it tries to " |
1541 |
|
"find a sample file in the selected directory with the same name as " |
1542 |
|
"the sample in the gig file. Optionally you can add a filename " |
1543 |
|
"postfix below, which will be added to the filename expected to be " |
1544 |
|
"found. That is, assume you have a gig file with a sample called " |
1545 |
|
"'Snare', if you enter '.wav' below (like it's done by default), it " |
1546 |
|
"assumes to find a sample file called 'Snare.wav' and will replace " |
1547 |
|
"the sample in the gig file accordingly. If you don't need such a " |
1548 |
|
"postfix, blank the field below. Any gig sample where no " |
1549 |
|
"appropriate sample file could be found, will be reported and left " |
1550 |
|
"untouched.\n\n") |
1551 |
|
); |
1552 |
|
description.set_line_wrap(true); |
1553 |
|
Gtk::HBox entryArea; |
1554 |
|
Gtk::Label entryLabel( _("Add Filename Extension: "), Gtk::ALIGN_RIGHT); |
1555 |
|
Gtk::Entry postfixEntryBox; |
1556 |
|
postfixEntryBox.set_text(".wav"); |
1557 |
|
entryArea.pack_start(entryLabel); |
1558 |
|
entryArea.pack_start(postfixEntryBox); |
1559 |
|
dialog.get_vbox()->pack_start(description, Gtk::PACK_SHRINK); |
1560 |
|
dialog.get_vbox()->pack_start(entryArea, Gtk::PACK_SHRINK); |
1561 |
|
description.show(); |
1562 |
|
entryLabel.show(); |
1563 |
|
postfixEntryBox.show(); |
1564 |
|
entryArea.show(); |
1565 |
|
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); |
1566 |
|
dialog.add_button(_("Select"), Gtk::RESPONSE_OK); |
1567 |
|
dialog.set_select_multiple(false); |
1568 |
|
// fix label width (because Gtk by design doesn't |
1569 |
|
// know anything about the parent's size) |
1570 |
|
#if 0 //FIXME: doesn't work |
1571 |
|
int dialogW, dialogH, labelW, labelH; |
1572 |
|
dialog.get_size_request(dialogW, dialogH); |
1573 |
|
description.get_size_request(labelW, labelH); |
1574 |
|
std::cout << "dialog(" << dialogW << "," << dialogH << ")\nlabel(" << labelW << "," << labelH << ")\n" << std::flush; |
1575 |
|
description.set_size_request(dialogW, labelH); |
1576 |
|
#endif |
1577 |
|
if (dialog.run() == Gtk::RESPONSE_OK) |
1578 |
|
{ |
1579 |
|
Glib::ustring error_files; |
1580 |
|
Glib::ustring folder = dialog.get_filename(); |
1581 |
|
for (gig::Sample* sample = file->GetFirstSample(); |
1582 |
|
sample; sample = file->GetNextSample()) |
1583 |
|
{ |
1584 |
|
std::string filename = |
1585 |
|
folder + G_DIR_SEPARATOR_S + sample->pInfo->Name + |
1586 |
|
postfixEntryBox.get_text().raw(); |
1587 |
|
SF_INFO info; |
1588 |
|
info.format = 0; |
1589 |
|
SNDFILE* hFile = sf_open(filename.c_str(), SFM_READ, &info); |
1590 |
|
try |
1591 |
|
{ |
1592 |
|
if (!hFile) throw std::string("could not open file"); |
1593 |
|
int bitdepth; |
1594 |
|
switch (info.format & 0xff) { |
1595 |
|
case SF_FORMAT_PCM_S8: |
1596 |
|
case SF_FORMAT_PCM_16: |
1597 |
|
case SF_FORMAT_PCM_U8: |
1598 |
|
bitdepth = 16; |
1599 |
|
break; |
1600 |
|
case SF_FORMAT_PCM_24: |
1601 |
|
case SF_FORMAT_PCM_32: |
1602 |
|
case SF_FORMAT_FLOAT: |
1603 |
|
case SF_FORMAT_DOUBLE: |
1604 |
|
bitdepth = 24; |
1605 |
|
break; |
1606 |
|
default: |
1607 |
|
sf_close(hFile); |
1608 |
|
throw std::string("format not supported"); |
1609 |
|
} |
1610 |
|
SampleImportItem sched_item; |
1611 |
|
sched_item.gig_sample = sample; |
1612 |
|
sched_item.sample_path = filename; |
1613 |
|
m_SampleImportQueue.push_back(sched_item); |
1614 |
|
sf_close(hFile); |
1615 |
|
file_changed(); |
1616 |
|
} |
1617 |
|
catch (std::string what) |
1618 |
|
{ |
1619 |
|
if (error_files.size()) error_files += "\n"; |
1620 |
|
error_files += filename += " (" + what + ")"; |
1621 |
|
} |
1622 |
|
} |
1623 |
|
// show error message box when some file(s) could not be opened / added |
1624 |
|
if (error_files.size()) { |
1625 |
|
Glib::ustring txt = |
1626 |
|
_("Could not replace the following sample(s):\n") + error_files; |
1627 |
|
Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR); |
1628 |
|
msg.run(); |
1629 |
|
} |
1630 |
|
} |
1631 |
|
} |
1632 |
|
|
1633 |
void MainWindow::on_action_remove_sample() { |
void MainWindow::on_action_remove_sample() { |
1634 |
if (!file) return; |
if (!file) return; |
1635 |
Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection(); |
Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection(); |
1897 |
sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_note_off() { |
sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_note_off() { |
1898 |
return note_off_signal; |
return note_off_signal; |
1899 |
} |
} |
1900 |
|
|
1901 |
|
sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_keyboard_key_hit() { |
1902 |
|
return m_RegionChooser.signal_keyboard_key_hit(); |
1903 |
|
} |
1904 |
|
|
1905 |
|
sigc::signal<void, int/*key*/, int/*velocity*/>& MainWindow::signal_keyboard_key_released() { |
1906 |
|
return m_RegionChooser.signal_keyboard_key_released(); |
1907 |
|
} |