Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

/home/vlg/develop/gwavmerger/src/Config.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              Config.cpp
00004 //------------------------------------------------------------------------------
00005 // $Id: Config.cpp,v 1.6 2003/02/07 05:15:08 vlg Exp $
00006 //------------------------------------------------------------------------------
00007 //  Copyright (c) 2001-2003 by Vladislav Grinchenko
00008 //
00009 //  This program is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU General Public License
00011 //  as published by the Free Software Foundation; either version
00012 //  2 of the License, or (at your option) any later version.
00013 //------------------------------------------------------------------------------
00014 // 01/12/2002 VLG  Created
00015 //------------------------------------------------------------------------------
00016 
00017 #include <unistd.h>             // getcwd(3)
00018 #include <limits.h>             // PATH_MAX
00019 #include <libgen.h>             // basename(3), dirname(3)
00020 #include <string.h>             // strcpy(3)
00021 #include <stdio.h>              // sprintf(3)
00022 #include <sys/types.h>          // stat(3)
00023 #include <sys/stat.h>           // stat(3)
00024 
00025 #include <sstream>
00026 using namespace std;
00027 
00028 #include "Config.h"
00029 
00030 #include <gtkmm/dialog.h>
00031 #include <libgnome/libgnome.h>
00032 
00033 #include "gWavMerger-main.h"
00034 #include "gWavMerger.h"
00035 
00036 using namespace ASSA;
00037 
00038 /*******************************************************************************
00039  Constructor
00040 *******************************************************************************/
00041 
00042 Config::Config () :
00043     m_proj_name ("MyProject.gwm"),
00044     m_dont_save_project (false),
00045     m_A_prefix ("a"),
00046     m_B_prefix ("b"),
00047     m_A_dir ("A"),
00048     m_B_dir ("B"),
00049     m_pre_delay ("2x"),
00050     m_post_delay ("2x")
00051 {
00052     trace("Config::Config");
00053 
00054     // Always start with the current directory as pathname
00055     char* ptr = NULL;
00056     ptr = new char [PATH_MAX+1];
00057     Assert_exit (getcwd (ptr, PATH_MAX) != NULL);
00058     m_path_name = ptr;
00059     delete [] ptr;
00060 
00061     // Load history from ~/.gnome/gwavmerger configuration file
00062     load_config ();
00063 }
00064 
00065 /*******************************************************************************
00066 *******************************************************************************/
00067 
00068 Config::~Config ()
00069 {
00070     trace("Config::~Config");
00071     dump ();
00072 
00073     if (!m_dont_save_project) {
00074         save_project ();
00075     }
00076 
00077     // Save history to ~/.gnome/gwavmerger configuration file.
00078     save_config ();
00079 }
00080 
00090 int 
00091 
00092 Config::load_project (const string& fname_)
00093 {
00094     trace("Config::load_project");
00095 
00096     DL((TRACE,"Loading config from \"%s\"\n", fname_.c_str ()));
00097     int idx = 1;
00098     struct stat file_stat;
00099 
00100     if (stat (fname_.c_str (), &file_stat) < 0 ||
00101         S_ISREG (file_stat.st_mode) == false) // invalid project file
00102     {
00103         // Test to see if file exists, and if it doesn't, show
00104         // modal error dialog and return 0
00105         string msg ("Invalid project file:\n");
00106         msg += fname_;
00107         Gtk::MessageDialog md_error (msg, MESSAGE_ERROR);
00108         return -1;
00109     }
00110     /* Given the full file name, split it into dirname and basename
00111      *
00112      * From man dirname(3):
00113      *   "Both dirname and basename may modify the contents of path, 
00114      *    so if you need to  preserve  the  pathname string, 
00115      *    copies should be passed to these functions.  
00116      *    Furthermore, dirname and basename may return  pointers  to  
00117      *    statically  allocated  memory which may overwritten by subsequent 
00118      *    calls."
00119      */
00120     char s [PATH_MAX];
00121     strcpy (s, fname_.c_str ());
00122     set_proj_name (basename (s)); // 's' might be modified!
00123 
00124     strcpy (s, fname_.c_str ());
00125     set_proj_path (dirname  (s));
00126 
00127     string base ("=" + m_path_name + "/" + m_proj_name + "=/Project");
00128     string key;
00129     char* val;
00130 
00131     key = base + "/project_name";
00132     val = gnome_config_get_string (key.c_str ());
00133     if (val != 0) {
00134         m_proj_name = val;
00135         g_free (val);
00136     }
00137 
00138     key = base + "/A_prefix";
00139     val = gnome_config_get_string (key.c_str ());
00140     if (val != 0) {
00141         m_A_prefix = val;
00142         g_free (val);
00143     }
00144 
00145     key = base + "/B_prefix";
00146     val = gnome_config_get_string (key.c_str ());
00147     if (val != 0) {
00148         m_B_prefix = val;
00149         g_free (val);
00150     }
00151 
00152     key = base + "/A_dir";
00153     val = gnome_config_get_string (key.c_str ());
00154     if (val != 0) {
00155         m_A_dir = val;
00156         g_free (val);
00157     }
00158 
00159     key = base + "/B_dir";
00160     val = gnome_config_get_string (key.c_str ());
00161     if (val != 0) {
00162         m_B_dir = val;
00163         g_free (val);
00164     }
00165 
00166     key = base + "/pre_delay";
00167     val = gnome_config_get_string (key.c_str ());
00168     if (val != 0) {
00169         m_pre_delay = val;
00170         g_free (val);
00171     }
00172 
00173     key = base + "/post_delay";
00174     val = gnome_config_get_string (key.c_str ());
00175     if (val != 0) {
00176         m_post_delay = val;
00177         g_free (val);
00178     }
00179 
00180     dump ();
00181 
00182     MAINWINDOW->set_mw_name ();
00183     MAINWINDOW->reload_cb ();
00184 
00185     return 0;
00186 }
00187 
00188 
00192 int 
00193 
00194 Config::save_project ()
00195 {
00196     trace("Config::save_project");
00197     
00198     /* Project file name should have .gwm extension. 
00199      * If it doesn't have one we ought to add it.
00200      */
00201     string ext (".gwm");
00202     if (m_proj_name.find (ext) == string::npos) {
00203         m_proj_name += ext;
00204     }
00205     string base ("=" + m_path_name + "/" + m_proj_name + "=");
00206     string key;
00207 
00208     gnome_config_clean_file (base.c_str ());
00209     gnome_config_sync ();
00210 
00211     base += "/Project";
00212 
00213     DL((APP,"base = \"%s\"\n", base.c_str ()));
00214 
00226     key = base + "/project_name";
00227     gnome_config_set_string (key.c_str (), m_proj_name.c_str ());
00228     key = base + "/A_prefix";
00229     gnome_config_set_string (key.c_str (), m_A_prefix.c_str ());
00230     key = base + "/B_prefix";
00231     gnome_config_set_string (key.c_str (), m_B_prefix.c_str ());
00232     key = base + "/A_dir";
00233     gnome_config_set_string (key.c_str (), m_A_dir.c_str ());
00234     key = base + "/B_dir";
00235     gnome_config_set_string (key.c_str (), m_B_dir.c_str ());
00236     key = base + "/pre_delay";
00237     gnome_config_set_string (key.c_str (), m_pre_delay.c_str ());
00238     key = base + "/post_delay";
00239     gnome_config_set_string (key.c_str (), m_post_delay.c_str ());
00240 
00241     gnome_config_sync ();
00242     return 0;
00243 }
00244 
00245 /*******************************************************************************
00246 *******************************************************************************/
00247 void
00248 
00249 Config::dump () const
00250 {
00251     trace("Config::dump");
00252     DL((TRACE,"proj_name : \"%s\"\n", m_proj_name.c_str ()));
00253     DL((TRACE,"path_name : \"%s\"\n", m_path_name.c_str ()));
00254     DL((TRACE,"A_prefix  : \"%s\"\n", m_A_prefix.c_str ()));
00255     DL((TRACE,"B_prefix  : \"%s\"\n", m_B_prefix.c_str ()));
00256     DL((TRACE,"A_dir     : \"%s\"\n", m_A_dir.c_str ()));
00257     DL((TRACE,"B_dir     : \"%s\"\n", m_B_dir.c_str ()));
00258     DL((TRACE,"pre_delay : \"%s\"\n", m_pre_delay.c_str ()));
00259     DL((TRACE,"post_delay : \"%s\"\n", m_post_delay.c_str ()));
00260 
00261     dump_document_history ();
00262 }
00263 
00264 /*******************************************************************************
00265 *******************************************************************************/
00266 void
00267 
00268 Config::dump_document_history () const
00269 {
00270     if (m_history.size () == 0) {
00271         DL((APP,"Document history is empty\n"));
00272         return;
00273     }
00274     DL((APP,"=== Document history ===\n"));
00275     DHList_CIter cit = m_history.begin ();
00276     uint idx = 0;
00277     while (cit != m_history.end ()) {
00278         DL((APP,"[%d] \"%s\"\n", idx++, (*cit).c_str ()));
00279         cit++;
00280     }
00281     DL((APP,"====== End history =====\n"));
00282 }
00283 
00284 string
00285 
00286 Config::make_pathname (const string& type_, const string& name_, bool absolute_) const
00287 {
00288     string pname;
00289     if (absolute_) {
00290         pname = get_proj_path () + "/";
00291     }
00292     if (type_ == "A") {
00293         pname += get_A_dir () + "/" + get_A_prefix () + name_ + ".wav";
00294     }
00295     else if (type_ == "B") {
00296         pname += get_B_dir () + "/" + get_B_prefix () + name_ + ".wav";
00297     }
00298     else {
00299         DL((APP,"error: unknown type \"%s\"\n",type_.c_str ()));
00300         pname = "";
00301     }
00302     return pname;
00303 }
00304 
00305 
00306 string
00307 
00308 Config::make_pause_pathname (int type_, const string& name_) const
00309 {
00310     string pname (get_B_dir () + "/");
00311     pname += get_B_prefix () + name_;
00312     pname += (type_ == 0) ? "_pre_pause.wav" : "_post_pause.wav";
00313     return pname;
00314 }
00315 
00323 string
00324 
00325 Config::add_document_history ()
00326 {
00327     trace("Config::add_document_history");
00328 
00329     string fullpath;
00330     int hsz = 0;
00331 
00332     if (m_path_name.size () == 0) {
00333         fullpath = m_proj_name;
00334     }
00335     else {
00336         fullpath = m_path_name + '/' + m_proj_name;
00337     }
00338 
00339     if ((hsz = m_history.size ()) > 0) {
00340         for (int idx = 0; idx < hsz; idx++) {
00341             if (m_history [idx] == fullpath) {
00342                 m_history.erase (m_history.begin () + idx);
00343                 break;
00344             }
00345         }
00346     }
00347 
00348     m_history.push_front (fullpath);
00349     if (m_history.size () > 5) {
00350         m_history.pop_back ();
00351     } 
00352     dump_document_history ();
00353     return fullpath;
00354 }
00355 
00361 void
00362 
00363 Config::remove_document_history (const string& fullpath_)
00364 {
00365     trace("Config::remove_document_history");
00366 
00367     size_t hsz;
00368     if ((hsz = m_history.size ()) == 0) {
00369         return;
00370     }
00371     for (int idx = 0; idx < hsz; idx++) {
00372         if (m_history [idx] == fullpath_) {
00373             m_history.erase (m_history.begin () + idx);
00374             break;
00375         }
00376     }
00377 }
00378 
00394 void
00395 
00396 Config::save_config ()
00397 {
00398     trace("Config::save_config");
00399 
00400     string path ("/gwavmerger/History");
00401     string key;
00402     ostringstream ckey;
00403     int position = 0;
00404 
00405     gnome_config_clean_file (path.c_str ());
00406 
00407     if (m_history.size () != 0) {
00408         DHList_CIter cit = m_history.begin ();
00409         while (cit != m_history.end ()) {
00410             ckey.str ("");
00411             ckey  << path << "/" << position;
00412             DL((TRACE,"Saving\nhistory [%d] = <%s>\n", position,
00413                 ckey.str ().c_str (), (*cit).c_str ()));
00414             gnome_config_set_string (ckey.str ().c_str (), (*cit).c_str ());
00415             cit++;
00416             position++;
00417         }
00418     }
00419     path = "/gwavmerger/Default/jump";
00420     gnome_config_set_bool (path.c_str (), m_jump_next_row);
00421 
00422     gnome_config_sync ();
00423 }
00424 
00428 void
00429 
00430 Config::load_config ()
00431 {
00432     trace("Config::load_config");
00433 
00434     string path ("/gwavmerger/Default/jump");
00435     m_jump_next_row = gnome_config_get_bool (path.c_str ());
00436 
00437     path = "/gwavmerger/History";
00438     gpointer iterator = gnome_config_init_iterator (path.c_str ());
00439 
00440     if (iterator != 0) {
00441         DL((APP,"Scanning [History] section ...\n"));
00442         gchar* key = NULL;
00443         gchar* value = NULL;
00444         while ((iterator = gnome_config_iterator_next (iterator, &key, &value)))
00445         {
00446             if (key == 0 || value == 0) { // paranoid?
00447                 if (key)   g_free (key);
00448                 if (value) g_free (value);
00449                 continue;
00450             }
00451             if (strlen (value) != 0) {
00452                 m_history.push_front (value);
00453             }
00454             g_free (key); 
00455             g_free (value);
00456             key = value = NULL;
00457         }
00458         DL((APP,"Loaded total %d history items\n", m_history.size ()));
00459     }
00460     else {
00461         DL((APP,"Section [History] is not in ~/.gnome[2]/gwavmerger\n"));
00462     }
00463 }
00464 
00465 

Generated on Tue Feb 11 23:05:19 2003 for gwavmerger by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002