/[svn]/gigedit/trunk/src/mainwindow.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/mainwindow.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1075 by schoenebeck, Tue Mar 6 01:17:03 2007 UTC revision 1085 by schoenebeck, Thu Mar 8 19:18:23 2007 UTC
# Line 27  Line 27 
27  #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6  #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6
28  #define ABOUT_DIALOG  #define ABOUT_DIALOG
29  #include <gtkmm/aboutdialog.h>  #include <gtkmm/aboutdialog.h>
30    #include <gtkmm/messagedialog.h>
31  #endif  #endif
32    
33    #include <stdio.h>
34    #include <sndfile.h>
35    
36  #define _(String) gettext(String)  #define _(String) gettext(String)
37    
38    template<class T> inline std::string ToString(T o) {
39        std::stringstream ss;
40        ss << o;
41        return ss.str();
42    }
43    
44  bool update_gui;  bool update_gui;
45    
46  uint8_t& access_UnityNote(gig::DimensionRegion* dimreg)  uint8_t& access_UnityNote(gig::DimensionRegion* dimreg)
# Line 523  MainWindow::MainWindow() : Line 533  MainWindow::MainWindow() :
533      m_TreeView.signal_button_press_event().connect_notify(      m_TreeView.signal_button_press_event().connect_notify(
534          sigc::mem_fun(*this, &MainWindow::on_button_release));          sigc::mem_fun(*this, &MainWindow::on_button_release));
535    
536      // Add the TreeView, inside a ScrolledWindow, with the button underneath:      // Add the TreeView tab, inside a ScrolledWindow, with the button underneath:
537      m_ScrolledWindow.add(m_TreeView);      m_ScrolledWindow.add(m_TreeViewNotebook);
538      m_ScrolledWindow.set_size_request(400, 600);      m_ScrolledWindow.set_size_request(400, 600);
539      m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);      m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
540    
# Line 783  MainWindow::MainWindow() : Line 793  MainWindow::MainWindow() :
793      m_HPaned.add2(m_Notebook);      m_HPaned.add2(m_Notebook);
794    
795    
796        m_TreeViewNotebook.append_page(m_TreeViewSamples, "Samples");
797        m_TreeViewNotebook.append_page(m_TreeView, "Instruments");
798    
799    
800      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
801    
802      actionGroup->add(Gtk::Action::create("MenuFile", _("_File")));      actionGroup->add(Gtk::Action::create("MenuFile", _("_File")));
# Line 826  MainWindow::MainWindow() : Line 840  MainWindow::MainWindow() :
840                       sigc::mem_fun(                       sigc::mem_fun(
841                           *this, &MainWindow::on_action_help_about));                           *this, &MainWindow::on_action_help_about));
842  #endif  #endif
843      action = Gtk::Action::create("Remove", "Ta bort");      action = Gtk::Action::create("Remove", Gtk::Stock::REMOVE);
844      actionGroup->add(action,      actionGroup->add(action,
845                       sigc::mem_fun(                       sigc::mem_fun(
846                           *this, &MainWindow::hide));                           *this, &MainWindow::hide));
847    
848        // sample right-click popup actions
849        actionGroup->add(
850            Gtk::Action::create("SampleProperties", Gtk::Stock::PROPERTIES),
851            sigc::mem_fun(*this, &MainWindow::on_action_sample_properties)
852        );
853        actionGroup->add(
854            Gtk::Action::create("AddGroup", _("Add _Group")),
855            sigc::mem_fun(*this, &MainWindow::on_action_add_group)
856        );
857        actionGroup->add(
858            Gtk::Action::create("AddSample", _("Add _Sample(s)")),
859            sigc::mem_fun(*this, &MainWindow::on_action_add_sample)
860        );
861        actionGroup->add(
862            Gtk::Action::create("RemoveSample", Gtk::Stock::REMOVE),
863            sigc::mem_fun(*this, &MainWindow::on_action_remove_sample)
864        );
865    
866      uiManager = Gtk::UIManager::create();      uiManager = Gtk::UIManager::create();
867      uiManager->insert_action_group(actionGroup);      uiManager->insert_action_group(actionGroup);
868      // add_accel_group(uiManager->get_accel_group());      // add_accel_group(uiManager->get_accel_group());
# Line 861  MainWindow::MainWindow() : Line 893  MainWindow::MainWindow() :
893          "    <menuitem action='InstrProperties'/>"          "    <menuitem action='InstrProperties'/>"
894          "    <menuitem action='Remove'/>"          "    <menuitem action='Remove'/>"
895          "  </popup>"          "  </popup>"
896            "  <popup name='SamplePopupMenu'>"
897            "    <menuitem action='SampleProperties'/>"
898            "    <menuitem action='AddGroup'/>"
899            "    <menuitem action='AddSample'/>"
900            "    <separator/>"
901            "    <menuitem action='RemoveSample'/>"
902            "  </popup>"
903          "</ui>";          "</ui>";
904      uiManager->add_ui_from_string(ui_info);      uiManager->add_ui_from_string(ui_info);
905    
# Line 886  MainWindow::MainWindow() : Line 925  MainWindow::MainWindow() :
925      m_TreeView.append_column("Instrument", m_Columns.m_col_name);      m_TreeView.append_column("Instrument", m_Columns.m_col_name);
926      m_TreeView.set_headers_visible(false);      m_TreeView.set_headers_visible(false);
927    
928        // create samples treeview (including its data model)
929        m_refSamplesTreeModel = Gtk::TreeStore::create(m_SamplesModel);
930        m_TreeViewSamples.set_model(m_refSamplesTreeModel);
931        m_TreeViewSamples.append_column("Samples", m_SamplesModel.m_col_name);
932        m_TreeViewSamples.set_headers_visible(false);
933        m_TreeViewSamples.signal_button_press_event().connect_notify(
934            sigc::mem_fun(*this, &MainWindow::on_sample_treeview_button_release)
935        );
936    
937      file = 0;      file = 0;
938    
939      show_all_children();      show_all_children();
# Line 1255  void MainWindow::on_action_file_open() Line 1303  void MainWindow::on_action_file_open()
1303          instrument_menu->get_submenu()->items().clear();          instrument_menu->get_submenu()->items().clear();
1304    
1305          m_refTreeModel->clear();          m_refTreeModel->clear();
1306            m_refSamplesTreeModel->clear();
1307          if (file) delete file;          if (file) delete file;
1308    
1309          // getInfo(dialog.get_filename().c_str(), *this);          // getInfo(dialog.get_filename().c_str(), *this);
# Line 1510  void MainWindow::load_gig(gig::File* gig Line 1559  void MainWindow::load_gig(gig::File* gig
1559      }      }
1560      instrument_menu->show();      instrument_menu->show();
1561      instrument_menu->get_submenu()->show_all_children();      instrument_menu->get_submenu()->show_all_children();
1562    
1563        for (gig::Group* group = gig->GetFirstGroup(); group; group = gig->GetNextGroup()) {
1564            Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();
1565            Gtk::TreeModel::Row rowGroup = *iterGroup;
1566            rowGroup[m_SamplesModel.m_col_name]   = group->Name.c_str();
1567            rowGroup[m_SamplesModel.m_col_group]  = group;
1568            rowGroup[m_SamplesModel.m_col_sample] = NULL;
1569            for (gig::Sample* sample = group->GetFirstSample(); sample; sample = group->GetNextSample()) {
1570                Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(rowGroup.children());
1571                Gtk::TreeModel::Row rowSample = *iterSample;
1572                rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();
1573                rowSample[m_SamplesModel.m_col_sample] = sample;
1574                rowSample[m_SamplesModel.m_col_group]  = NULL;
1575            }
1576        }
1577  }  }
1578    
1579  void MainWindow::on_button_release(GdkEventButton* button)  void MainWindow::on_button_release(GdkEventButton* button)
# Line 1535  void MainWindow::on_button_release(GdkEv Line 1599  void MainWindow::on_button_release(GdkEv
1599  void MainWindow::on_instrument_selection_change(int index) {  void MainWindow::on_instrument_selection_change(int index) {
1600      m_RegionChooser.set_instrument(file->GetInstrument(index));      m_RegionChooser.set_instrument(file->GetInstrument(index));
1601  }  }
1602    
1603    void MainWindow::on_sample_treeview_button_release(GdkEventButton* button) {
1604        if (button->type == GDK_BUTTON_PRESS && button->button == 3) {
1605            Gtk::Menu* sample_popup =
1606                dynamic_cast<Gtk::Menu*>(uiManager->get_widget("/SamplePopupMenu"));
1607            // update enabled/disabled state of sample popup items
1608            Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
1609            Gtk::TreeModel::iterator it = sel->get_selected();
1610            bool group_selected  = false;
1611            bool sample_selected = false;
1612            if (it) {
1613                Gtk::TreeModel::Row row = *it;
1614                group_selected  = row[m_SamplesModel.m_col_group];
1615                sample_selected = row[m_SamplesModel.m_col_sample];
1616            }
1617            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/SampleProperties"))->set_sensitive(group_selected || sample_selected);
1618            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddSample"))->set_sensitive(group_selected || sample_selected);
1619            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/AddGroup"))->set_sensitive(file);
1620            dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/SamplePopupMenu/RemoveSample"))->set_sensitive(group_selected || sample_selected);
1621            // show sample popup
1622            sample_popup->popup(button->button, button->time);
1623        }
1624    }
1625    
1626    void MainWindow::on_action_sample_properties() {
1627         //TODO: show a dialog where the selected sample's properties can be edited
1628    }
1629    
1630    void MainWindow::on_action_add_group() {
1631        static int __sample_indexer = 0;
1632        if (!file) return;
1633        gig::Group* group = file->AddGroup();
1634        group->Name = "Unnamed Group";
1635        if (__sample_indexer) group->Name += " " + ToString(__sample_indexer);
1636        __sample_indexer++;
1637        // update sample tree view
1638        Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();
1639        Gtk::TreeModel::Row rowGroup = *iterGroup;
1640        rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();
1641        rowGroup[m_SamplesModel.m_col_sample] = NULL;
1642        rowGroup[m_SamplesModel.m_col_group] = group;
1643    }
1644    
1645    void MainWindow::on_action_add_sample() {
1646        if (!file) return;
1647        // get selected group
1648        Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
1649        Gtk::TreeModel::iterator it = sel->get_selected();
1650        if (!it) return;
1651        Gtk::TreeModel::Row row = *it;
1652        gig::Group* group = row[m_SamplesModel.m_col_group];
1653        if (!group) { // not a group, but a sample is selected (probably)
1654            gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1655            if (!sample) return;
1656            it = row.parent(); // resolve parent (that is the sample's group)
1657            if (!it) return;
1658            row = *it;
1659            group = row[m_SamplesModel.m_col_group];
1660            if (!group) return;
1661        }
1662        // show 'browse for file' dialog
1663        Gtk::FileChooserDialog dialog(*this, _("Add Sample(s)"));
1664        dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1665        dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1666        dialog.set_select_multiple(true);
1667        Gtk::FileFilter soundfilter; // matches all file types supported by libsndfile (yet to do ;-)
1668        soundfilter.add_pattern("*.wav");
1669        soundfilter.set_name("Sound Files");
1670        Gtk::FileFilter allpassfilter; // matches every file
1671        allpassfilter.add_pattern("*.*");
1672        allpassfilter.set_name("All Files");
1673        dialog.add_filter(soundfilter);
1674        dialog.add_filter(allpassfilter);
1675        if (dialog.run() == Gtk::RESPONSE_OK) {
1676            Glib::ustring error_files;
1677            Glib::SListHandle<Glib::ustring> filenames = dialog.get_filenames();
1678            for (Glib::SListHandle<Glib::ustring>::iterator iter = filenames.begin(); iter != filenames.end(); ++iter) {
1679                printf("Adding sample %s\n",(*iter).c_str());
1680                // use libsndfile to retrieve file informations
1681                SF_INFO info;
1682                info.format = 0;
1683                SNDFILE* hFile = sf_open((*iter).c_str(), SFM_READ, &info);
1684                try {
1685                    if (!hFile) throw std::string("could not open file");
1686                    int bitdepth;
1687                    switch (info.format & 0xff) {
1688                        case SF_FORMAT_PCM_S8:
1689                            bitdepth = 8;
1690                            break;
1691                        case SF_FORMAT_PCM_16:
1692                            bitdepth = 16;
1693                            break;
1694                        case SF_FORMAT_PCM_24:
1695                            bitdepth = 24;
1696                            break;
1697                        case SF_FORMAT_PCM_32:
1698                            bitdepth = 32;
1699                            break;
1700                        default:
1701                            sf_close(hFile); // close sound file
1702                            throw std::string("format not supported"); // unsupported subformat (yet?)
1703                    }
1704                    // add a new sample to the .gig file
1705                    gig::Sample* sample = file->AddSample();
1706                    sample->pInfo->Name = (*iter).raw();
1707                    sample->Channels = info.channels;
1708                    sample->BitDepth = bitdepth;
1709                    sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
1710                    sample->SamplesPerSecond = info.samplerate;
1711                    // schedule resizing the sample (which will be done physically when File::Save() is called)
1712                    sample->Resize(info.frames);
1713                    // add sample to the tree view
1714                    Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(row.children());
1715                    Gtk::TreeModel::Row rowSample = *iterSample;
1716                    rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();
1717                    rowSample[m_SamplesModel.m_col_sample] = sample;
1718                    rowSample[m_SamplesModel.m_col_group]  = NULL;
1719                    // close sound file
1720                    sf_close(hFile);
1721                } catch (std::string what) { // remember the files that made trouble (and their cause)
1722                    if (error_files.size()) error_files += "\n";
1723                    error_files += *iter += " (" + what + ")";
1724                }
1725            }
1726            // show error message box when some file(s) could not be opened / added
1727            if (error_files.size()) {
1728                Glib::ustring txt = "Could not add the following sample(s):\n" + error_files;
1729                Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
1730                msg.run();
1731            }
1732        }
1733    }
1734    
1735    void MainWindow::on_action_remove_sample() {
1736        if (!file) return;
1737        Glib::RefPtr<Gtk::TreeSelection> sel = m_TreeViewSamples.get_selection();
1738        Gtk::TreeModel::iterator it = sel->get_selected();
1739        if (it) {
1740            Gtk::TreeModel::Row row = *it;
1741            gig::Group* group   = row[m_SamplesModel.m_col_group];
1742            gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1743            try {
1744                // remove group or sample from the gig file
1745                if (group) {
1746                    file->DeleteGroup(group);
1747                } else if (sample) {
1748                    file->DeleteSample(sample);
1749                }
1750                // remove respective row(s) from samples tree view
1751                m_refSamplesTreeModel->erase(it);
1752            } catch (RIFF::Exception e) {
1753                Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1754                msg.run();
1755            }
1756        }
1757    }

Legend:
Removed from v.1075  
changed lines
  Added in v.1085

  ViewVC Help
Powered by ViewVC