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

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

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

revision 2442 by persson, Sun Apr 14 07:29:59 2013 UTC revision 2464 by schoenebeck, Thu Sep 5 00:49:13 2013 UTC
# Line 128  MainWindow::MainWindow() : Line 128  MainWindow::MainWindow() :
128                           *this, &MainWindow::on_action_quit));                           *this, &MainWindow::on_action_quit));
129      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));      actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
130    
131      actionGroup->add(Gtk::Action::create("MenuView", _("_View")));  
132        actionGroup->add(Gtk::Action::create("MenuEdit", _("_Edit")));
133    
134      Glib::RefPtr<Gtk::ToggleAction> toggle_action =      Glib::RefPtr<Gtk::ToggleAction> toggle_action =
135            Gtk::ToggleAction::create("CopySampleUnity", _("Copy Sample's _Unity Note"), "ffaga");
136        toggle_action->set_active(true);
137        //FIXME: doesn't work, why?
138        toggle_action->set_tooltip(_("Used when dragging a sample to a region's sample reference field."));
139        actionGroup->add(toggle_action);
140    
141        toggle_action =
142            Gtk::ToggleAction::create("CopySampleTune", _("Copy Sample's _Fine Tune"));
143        toggle_action->set_active(true);
144        //FIXME: doesn't work, why?
145        toggle_action->set_tooltip(_("Used when dragging a sample to a region's sample reference field."));
146        actionGroup->add(toggle_action);
147    
148        toggle_action =
149            Gtk::ToggleAction::create("CopySampleLoop", _("Copy Sample's _Loop Points"));
150        toggle_action->set_active(true);
151        //FIXME: doesn't work, why?
152        toggle_action->set_tooltip(_("Used when dragging a sample to a region's sample reference field."));
153        actionGroup->add(toggle_action);
154    
155    
156        actionGroup->add(Gtk::Action::create("MenuView", _("_View")));
157        toggle_action =
158          Gtk::ToggleAction::create("Statusbar", _("_Statusbar"));          Gtk::ToggleAction::create("Statusbar", _("_Statusbar"));
159      toggle_action->set_active(true);      toggle_action->set_active(true);
160      actionGroup->add(toggle_action,      actionGroup->add(toggle_action,
# Line 196  MainWindow::MainWindow() : Line 221  MainWindow::MainWindow() :
221          "      <separator/>"          "      <separator/>"
222          "      <menuitem action='Quit'/>"          "      <menuitem action='Quit'/>"
223          "    </menu>"          "    </menu>"
224            "    <menu action='MenuEdit'>"
225            "      <menuitem action='CopySampleUnity'/>"
226            "      <menuitem action='CopySampleTune'/>"
227            "      <menuitem action='CopySampleLoop'/>"
228            "    </menu>"
229          "    <menu action='MenuInstrument'>"          "    <menu action='MenuInstrument'>"
230          "    </menu>"          "    </menu>"
231          "    <menu action='MenuView'>"          "    <menu action='MenuView'>"
# Line 545  void MainWindow::on_action_file_new() Line 575  void MainWindow::on_action_file_new()
575      gig::File* pFile = new gig::File;      gig::File* pFile = new gig::File;
576      // already add one new instrument by default      // already add one new instrument by default
577      gig::Instrument* pInstrument = pFile->AddInstrument();      gig::Instrument* pInstrument = pFile->AddInstrument();
578      pInstrument->pInfo->Name = _("Unnamed Instrument");      pInstrument->pInfo->Name = gig_from_utf8(_("Unnamed Instrument"));
579      // update GUI with that new gig::File      // update GUI with that new gig::File
580      load_gig(pFile, 0 /*no file name yet*/);      load_gig(pFile, 0 /*no file name yet*/);
581  }  }
# Line 1003  void PropDialog::set_info(DLS::Info* inf Line 1033  void PropDialog::set_info(DLS::Info* inf
1033  }  }
1034    
1035    
1036    void InstrumentProps::set_Name(const gig::String& name)
1037    {
1038        m->pInfo->Name = name;
1039    }
1040    
1041    void InstrumentProps::update_name()
1042    {
1043        update_model++;
1044        eName.set_value(m->pInfo->Name);
1045        update_model--;
1046    }
1047    
1048  void InstrumentProps::set_IsDrum(bool value)  void InstrumentProps::set_IsDrum(bool value)
1049  {  {
1050      m->IsDrum = value;      m->IsDrum = value;
# Line 1045  InstrumentProps::InstrumentProps() : Line 1087  InstrumentProps::InstrumentProps() :
1087            "\"keyswitching\" dimension")            "\"keyswitching\" dimension")
1088      );      );
1089    
1090        connect(eName, &InstrumentProps::set_Name);
1091      connect(eIsDrum, &InstrumentProps::set_IsDrum);      connect(eIsDrum, &InstrumentProps::set_IsDrum);
1092      connect(eMIDIBank, &InstrumentProps::set_MIDIBank);      connect(eMIDIBank, &InstrumentProps::set_MIDIBank);
1093      connect(eMIDIProgram, &InstrumentProps::set_MIDIProgram);      connect(eMIDIProgram, &InstrumentProps::set_MIDIProgram);
# Line 1057  InstrumentProps::InstrumentProps() : Line 1100  InstrumentProps::InstrumentProps() :
1100      connect(eDimensionKeyRangeLow, eDimensionKeyRangeHigh,      connect(eDimensionKeyRangeLow, eDimensionKeyRangeHigh,
1101              &gig::Instrument::DimensionKeyRange);              &gig::Instrument::DimensionKeyRange);
1102    
1103        eName.signal_value_changed().connect(sig_name_changed.make_slot());
1104    
1105      table.set_col_spacings(5);      table.set_col_spacings(5);
1106    
1107      table.add(eName);      table.add(eName);
# Line 1097  void InstrumentProps::set_instrument(gig Line 1142  void InstrumentProps::set_instrument(gig
1142      update(instrument);      update(instrument);
1143    
1144      update_model++;      update_model++;
1145        eName.set_value(instrument->pInfo->Name);
1146      eIsDrum.set_value(instrument->IsDrum);      eIsDrum.set_value(instrument->IsDrum);
1147      eMIDIBank.set_value(instrument->MIDIBank);      eMIDIBank.set_value(instrument->MIDIBank);
1148      eMIDIProgram.set_value(instrument->MIDIProgram);      eMIDIProgram.set_value(instrument->MIDIProgram);
# Line 1127  void MainWindow::load_gig(gig::File* gig Line 1173  void MainWindow::load_gig(gig::File* gig
1173      instrument_name_connection.block();      instrument_name_connection.block();
1174      for (gig::Instrument* instrument = gig->GetFirstInstrument() ; instrument ;      for (gig::Instrument* instrument = gig->GetFirstInstrument() ; instrument ;
1175           instrument = gig->GetNextInstrument()) {           instrument = gig->GetNextInstrument()) {
1176          Glib::ustring name(instrument->pInfo->Name);          Glib::ustring name(gig_to_utf8(instrument->pInfo->Name));
1177    
1178          Gtk::TreeModel::iterator iter = m_refTreeModel->append();          Gtk::TreeModel::iterator iter = m_refTreeModel->append();
1179          Gtk::TreeModel::Row row = *iter;          Gtk::TreeModel::Row row = *iter;
# Line 1143  void MainWindow::load_gig(gig::File* gig Line 1189  void MainWindow::load_gig(gig::File* gig
1189          if (group->Name != "") {          if (group->Name != "") {
1190              Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();              Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();
1191              Gtk::TreeModel::Row rowGroup = *iterGroup;              Gtk::TreeModel::Row rowGroup = *iterGroup;
1192              rowGroup[m_SamplesModel.m_col_name]   = group->Name.c_str();              rowGroup[m_SamplesModel.m_col_name]   = gig_to_utf8(group->Name);
1193              rowGroup[m_SamplesModel.m_col_group]  = group;              rowGroup[m_SamplesModel.m_col_group]  = group;
1194              rowGroup[m_SamplesModel.m_col_sample] = NULL;              rowGroup[m_SamplesModel.m_col_sample] = NULL;
1195              for (gig::Sample* sample = group->GetFirstSample();              for (gig::Sample* sample = group->GetFirstSample();
# Line 1151  void MainWindow::load_gig(gig::File* gig Line 1197  void MainWindow::load_gig(gig::File* gig
1197                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1198                      m_refSamplesTreeModel->append(rowGroup.children());                      m_refSamplesTreeModel->append(rowGroup.children());
1199                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1200                  rowSample[m_SamplesModel.m_col_name]   = sample->pInfo->Name.c_str();                  rowSample[m_SamplesModel.m_col_name] =
1201                        gig_to_utf8(sample->pInfo->Name);
1202                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1203                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1204              }              }
# Line 1163  void MainWindow::load_gig(gig::File* gig Line 1210  void MainWindow::load_gig(gig::File* gig
1210      // select the first instrument      // select the first instrument
1211      m_TreeView.get_selection()->select(Gtk::TreePath("0"));      m_TreeView.get_selection()->select(Gtk::TreePath("0"));
1212    
1213      gig::Instrument* instrument = get_instrument();      instr_props_set_instrument();
1214      if (instrument) {  }
1215    
1216    bool MainWindow::instr_props_set_instrument()
1217    {
1218        instrumentProps.signal_name_changed().clear();
1219    
1220        Gtk::TreeModel::const_iterator it =
1221            m_TreeView.get_selection()->get_selected();
1222        if (it) {
1223            Gtk::TreeModel::Row row = *it;
1224            gig::Instrument* instrument = row[m_Columns.m_col_instr];
1225    
1226          instrumentProps.set_instrument(instrument);          instrumentProps.set_instrument(instrument);
1227    
1228            // make sure instrument tree is updated when user changes the
1229            // instrument name in instrument properties window
1230            instrumentProps.signal_name_changed().connect(
1231                sigc::bind(
1232                    sigc::mem_fun(*this,
1233                                  &MainWindow::instr_name_changed_by_instr_props),
1234                    it));
1235        } else {
1236            instrumentProps.hide();
1237      }      }
1238        return it;
1239  }  }
1240    
1241  void MainWindow::show_instr_props()  void MainWindow::show_instr_props()
1242  {  {
1243      gig::Instrument* instrument = get_instrument();      if (instr_props_set_instrument()) {
     if (instrument)  
     {  
         instrumentProps.set_instrument(instrument);  
1244          instrumentProps.show();          instrumentProps.show();
1245          instrumentProps.deiconify();          instrumentProps.deiconify();
1246      }      }
1247  }  }
1248    
1249    void MainWindow::instr_name_changed_by_instr_props(Gtk::TreeModel::iterator& it)
1250    {
1251        Gtk::TreeModel::Row row = *it;
1252        Glib::ustring name = row[m_Columns.m_col_name];
1253    
1254        gig::Instrument* instrument = row[m_Columns.m_col_instr];
1255        Glib::ustring gigname(gig_to_utf8(instrument->pInfo->Name));
1256        if (gigname != name) {
1257            row[m_Columns.m_col_name] = gigname;
1258        }
1259    }
1260    
1261  void MainWindow::on_action_view_status_bar() {  void MainWindow::on_action_view_status_bar() {
1262      Gtk::CheckMenuItem* item =      Gtk::CheckMenuItem* item =
1263          dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuView/Statusbar"));          dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuView/Statusbar"));
# Line 1191  void MainWindow::on_action_view_status_b Line 1269  void MainWindow::on_action_view_status_b
1269      else                    m_StatusBar.hide();      else                    m_StatusBar.hide();
1270  }  }
1271    
1272    bool MainWindow::is_copy_samples_unity_note_enabled() const {
1273        Gtk::CheckMenuItem* item =
1274            dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuEdit/CopySampleUnity"));
1275        if (!item) {
1276            std::cerr << "/MenuBar/MenuEdit/CopySampleUnity == NULL\n";
1277            return true;
1278        }
1279        return item->get_active();
1280    }
1281    
1282    bool MainWindow::is_copy_samples_fine_tune_enabled() const {
1283        Gtk::CheckMenuItem* item =
1284            dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuEdit/CopySampleTune"));
1285        if (!item) {
1286            std::cerr << "/MenuBar/MenuEdit/CopySampleTune == NULL\n";
1287            return true;
1288        }
1289        return item->get_active();
1290    }
1291    
1292    bool MainWindow::is_copy_samples_loop_enabled() const {
1293        Gtk::CheckMenuItem* item =
1294            dynamic_cast<Gtk::CheckMenuItem*>(uiManager->get_widget("/MenuBar/MenuEdit/CopySampleLoop"));
1295        if (!item) {
1296            std::cerr << "/MenuBar/MenuEdit/CopySampleLoop == NULL\n";
1297            return true;
1298        }
1299        return item->get_active();
1300    }
1301    
1302  void MainWindow::on_button_release(GdkEventButton* button)  void MainWindow::on_button_release(GdkEventButton* button)
1303  {  {
1304      if (button->type == GDK_2BUTTON_PRESS) {      if (button->type == GDK_2BUTTON_PRESS) {
# Line 1276  void MainWindow::remove_instrument_from_ Line 1384  void MainWindow::remove_instrument_from_
1384  }  }
1385    
1386  void MainWindow::add_instrument(gig::Instrument* instrument) {  void MainWindow::add_instrument(gig::Instrument* instrument) {
1387      const char* name = instrument->pInfo->Name.c_str();      const Glib::ustring name(gig_to_utf8(instrument->pInfo->Name));
1388    
1389      // update instrument tree view      // update instrument tree view
1390      instrument_name_connection.block();      instrument_name_connection.block();
# Line 1298  void MainWindow::on_action_add_instrumen Line 1406  void MainWindow::on_action_add_instrumen
1406      if (!file) return;      if (!file) return;
1407      gig::Instrument* instrument = file->AddInstrument();      gig::Instrument* instrument = file->AddInstrument();
1408      __instrument_indexer++;      __instrument_indexer++;
1409      instrument->pInfo->Name =      instrument->pInfo->Name = gig_from_utf8(_("Unnamed Instrument ") +
1410          _("Unnamed Instrument ") + ToString(__instrument_indexer);                                              ToString(__instrument_indexer));
1411    
1412      add_instrument(instrument);      add_instrument(instrument);
1413  }  }
# Line 1319  void MainWindow::on_action_duplicate_ins Line 1427  void MainWindow::on_action_duplicate_ins
1427      // duplicate the orginal instrument      // duplicate the orginal instrument
1428      gig::Instrument* instrNew = file->AddDuplicateInstrument(instrOrig);      gig::Instrument* instrNew = file->AddDuplicateInstrument(instrOrig);
1429      instrNew->pInfo->Name =      instrNew->pInfo->Name =
1430          instrOrig->pInfo->Name + " (" + _("Copy") + ")";          instrOrig->pInfo->Name +
1431            gig_from_utf8(Glib::ustring(" (") + _("Copy") + ")");
1432    
1433      add_instrument(instrNew);      add_instrument(instrNew);
1434  }  }
# Line 1366  void MainWindow::on_action_remove_instru Line 1475  void MainWindow::on_action_remove_instru
1475                      Gtk::TreePath(ToString(index)));                      Gtk::TreePath(ToString(index)));
1476              }              }
1477  #endif  #endif
1478              instr = get_instrument();              instr_props_set_instrument();
             if (instr) {  
                 instrumentProps.set_instrument(instr);  
             } else {  
                 instrumentProps.hide();  
             }  
1479          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1480              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);              Gtk::MessageDialog msg(*this, e.Message.c_str(), false, Gtk::MESSAGE_ERROR);
1481              msg.run();              msg.run();
# Line 1391  void MainWindow::on_action_add_group() { Line 1495  void MainWindow::on_action_add_group() {
1495      static int __sample_indexer = 0;      static int __sample_indexer = 0;
1496      if (!file) return;      if (!file) return;
1497      gig::Group* group = file->AddGroup();      gig::Group* group = file->AddGroup();
1498      group->Name = _("Unnamed Group");      group->Name = gig_from_utf8(_("Unnamed Group"));
1499      if (__sample_indexer) group->Name += " " + ToString(__sample_indexer);      if (__sample_indexer) group->Name += " " + ToString(__sample_indexer);
1500      __sample_indexer++;      __sample_indexer++;
1501      // update sample tree view      // update sample tree view
1502      Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();      Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();
1503      Gtk::TreeModel::Row rowGroup = *iterGroup;      Gtk::TreeModel::Row rowGroup = *iterGroup;
1504      rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();      rowGroup[m_SamplesModel.m_col_name] = gig_to_utf8(group->Name);
1505      rowGroup[m_SamplesModel.m_col_sample] = NULL;      rowGroup[m_SamplesModel.m_col_sample] = NULL;
1506      rowGroup[m_SamplesModel.m_col_group] = group;      rowGroup[m_SamplesModel.m_col_group] = group;
1507      file_changed();      file_changed();
# Line 1506  void MainWindow::on_action_add_sample() Line 1610  void MainWindow::on_action_add_sample()
1610                          break;                          break;
1611                      }                      }
1612                  }                  }
1613                  sample->pInfo->Name = filename;                  sample->pInfo->Name = gig_from_utf8(filename);
1614                  sample->Channels = info.channels;                  sample->Channels = info.channels;
1615                  sample->BitDepth = bitdepth;                  sample->BitDepth = bitdepth;
1616                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;                  sample->FrameSize = bitdepth / 8/*1 byte are 8 bits*/ * info.channels;
# Line 1557  void MainWindow::on_action_add_sample() Line 1661  void MainWindow::on_action_add_sample()
1661                  Gtk::TreeModel::iterator iterSample =                  Gtk::TreeModel::iterator iterSample =
1662                      m_refSamplesTreeModel->append(row.children());                      m_refSamplesTreeModel->append(row.children());
1663                  Gtk::TreeModel::Row rowSample = *iterSample;                  Gtk::TreeModel::Row rowSample = *iterSample;
1664                  rowSample[m_SamplesModel.m_col_name]   = filename;                  rowSample[m_SamplesModel.m_col_name] =
1665                        gig_to_utf8(sample->pInfo->Name);
1666                  rowSample[m_SamplesModel.m_col_sample] = sample;                  rowSample[m_SamplesModel.m_col_sample] = sample;
1667                  rowSample[m_SamplesModel.m_col_group]  = NULL;                  rowSample[m_SamplesModel.m_col_group]  = NULL;
1668                  // close sound file                  // close sound file
# Line 1628  void MainWindow::on_action_replace_all_s Line 1733  void MainWindow::on_action_replace_all_s
1733               sample; sample = file->GetNextSample())               sample; sample = file->GetNextSample())
1734          {          {
1735              std::string filename =              std::string filename =
1736                  folder + G_DIR_SEPARATOR_S + sample->pInfo->Name +                  folder + G_DIR_SEPARATOR_S +
1737                  postfixEntryBox.get_text().raw();                  Glib::filename_from_utf8(gig_to_utf8(sample->pInfo->Name) +
1738                                             postfixEntryBox.get_text());
1739              SF_INFO info;              SF_INFO info;
1740              info.format = 0;              info.format = 0;
1741              SNDFILE* hFile = sf_open(filename.c_str(), SFM_READ, &info);              SNDFILE* hFile = sf_open(filename.c_str(), SFM_READ, &info);
# Line 1663  void MainWindow::on_action_replace_all_s Line 1769  void MainWindow::on_action_replace_all_s
1769              catch (std::string what)              catch (std::string what)
1770              {              {
1771                  if (!error_files.empty()) error_files += "\n";                  if (!error_files.empty()) error_files += "\n";
1772                      error_files += filename += " (" + what + ")";                  error_files += Glib::filename_to_utf8(filename) +
1773                        " (" + what + ")";
1774              }              }
1775          }          }
1776          // show error message box when some file(s) could not be opened / added          // show error message box when some file(s) could not be opened / added
# Line 1688  void MainWindow::on_action_remove_sample Line 1795  void MainWindow::on_action_remove_sample
1795          try {          try {
1796              // remove group or sample from the gig file              // remove group or sample from the gig file
1797              if (group) {              if (group) {
1798                  // temporarily remember the samples that bolong to                  // temporarily remember the samples that belong to
1799                  // that group (we need that to clean the queue)                  // that group (we need that to clean the queue)
1800                  std::list<gig::Sample*> members;                  std::list<gig::Sample*> members;
1801                  for (gig::Sample* pSample = group->GetFirstSample();                  for (gig::Sample* pSample = group->GetFirstSample();
# Line 1814  void MainWindow::on_sample_label_drop_dr Line 1921  void MainWindow::on_sample_label_drop_dr
1921              channels_changed = true;              channels_changed = true;
1922              region_changed();              region_changed();
1923          }          }
1924          dimreg_edit.set_sample(sample);          dimreg_edit.set_sample(
1925                sample,
1926                is_copy_samples_unity_note_enabled(),
1927                is_copy_samples_fine_tune_enabled(),
1928                is_copy_samples_loop_enabled()
1929            );
1930    
1931          if (sample->Channels == 2 && !stereo_dimension) {          if (sample->Channels == 2 && !stereo_dimension) {
1932              // add samplechannel dimension              // add samplechannel dimension
# Line 1857  void MainWindow::sample_name_changed(con Line 1969  void MainWindow::sample_name_changed(con
1969      Glib::ustring name  = row[m_SamplesModel.m_col_name];      Glib::ustring name  = row[m_SamplesModel.m_col_name];
1970      gig::Group* group   = row[m_SamplesModel.m_col_group];      gig::Group* group   = row[m_SamplesModel.m_col_group];
1971      gig::Sample* sample = row[m_SamplesModel.m_col_sample];      gig::Sample* sample = row[m_SamplesModel.m_col_sample];
1972        gig::String gigname(gig_from_utf8(name));
1973      if (group) {      if (group) {
1974          if (group->Name != name) {          if (group->Name != gigname) {
1975              group->Name = name;              group->Name = gigname;
1976              printf("group name changed\n");              printf("group name changed\n");
1977              file_changed();              file_changed();
1978          }          }
1979      } else if (sample) {      } else if (sample) {
1980          if (sample->pInfo->Name != name.raw()) {          if (sample->pInfo->Name != gigname) {
1981              sample->pInfo->Name = name.raw();              sample->pInfo->Name = gigname;
1982              printf("sample name changed\n");              printf("sample name changed\n");
1983              file_changed();              file_changed();
1984          }          }
# Line 1893  void MainWindow::instrument_name_changed Line 2006  void MainWindow::instrument_name_changed
2006    
2007      // change name in gig      // change name in gig
2008      gig::Instrument* instrument = row[m_Columns.m_col_instr];      gig::Instrument* instrument = row[m_Columns.m_col_instr];
2009      if (instrument && instrument->pInfo->Name != name.raw()) {      gig::String gigname(gig_from_utf8(name));
2010          instrument->pInfo->Name = name.raw();      if (instrument && instrument->pInfo->Name != gigname) {
2011            instrument->pInfo->Name = gigname;
2012    
2013            // change name in the instrument properties window
2014            if (instrumentProps.get_instrument() == instrument) {
2015                instrumentProps.update_name();
2016            }
2017    
2018          file_changed();          file_changed();
2019      }      }
2020  }  }

Legend:
Removed from v.2442  
changed lines
  Added in v.2464

  ViewVC Help
Powered by ViewVC