Code

Added descriptions to Undo/Redo commands in the menus
[inkscape.git] / src / extension / dependency.cpp
1 /*
2  * Authors:
3  *   Ted Gould <ted@gould.cx>
4  *
5  * Copyright (C) 2004 Authors
6  *
7  * Released under GNU GPL, read the file 'COPYING' for more information
8  */
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
14 #include <glibmm/i18n.h>
15 #include "config.h"
16 #include "path-prefix.h"
17 #include "dependency.h"
18 #include "db.h"
20 namespace Inkscape {
21 namespace Extension {
23 // These strings are for XML attribute comparisons and should not be translated
24 gchar const * Dependency::_type_str[] = {
25     "executable",
26     "file",
27     "extension",
28     "plugin",
29 };
31 // These strings are for XML attribute comparisons and should not be translated
32 gchar const * Dependency::_location_str[] = {
33     "path",
34     "extensions",
35     "absolute",
36 };
38 /**
39     \brief   Create a dependency using an XML definition
40     \param   in_repr   XML definition of the dependency
42     This function mostly looks for the 'location' and 'type' attributes
43     and turns them into the enums of the same name.  This makes things
44     a little bit easier to use later.  Also, a pointer to the core
45     content is pulled out -- also to make things easier.
46 */
47 Dependency::Dependency (Inkscape::XML::Node * in_repr)
48 {
49     _type = TYPE_FILE;
50     _location = LOCATION_PATH;
51     _repr = in_repr;
52     _string = NULL;
53     _description = NULL;
55     Inkscape::GC::anchor(_repr);
57     const gchar * location = _repr->attribute("location");
58     for (int i = 0; i < LOCATION_CNT && location != NULL; i++) {
59         if (!strcmp(location, _location_str[i])) {
60             _location = (location_t)i;
61             break;
62         }
63     }
65     const gchar * type = _repr->attribute("type");
66     for (int i = 0; i < TYPE_CNT && type != NULL; i++) {
67         if (!strcmp(type, _type_str[i])) {
68             _type = (type_t)i;
69             break;
70         }
71     }
73     _string = sp_repr_children(_repr)->content();
75     _description = _repr->attribute("description");
76     if (_description == NULL)
77         _description = _repr->attribute("_description");
79     return;
80 }
82 /**
83     \brief   This depenency is not longer needed
85     Unreference the XML structure.
86 */
87 Dependency::~Dependency (void)
88 {
89     Inkscape::GC::release(_repr);
90 }
92 /**
93     \brief   Check if the dependency passes.
94     \return  Whether or not the dependency passes.
96     This function depends largely on all of the enums.  The first level
97     that is evaluted is the \c _type.
99     If the type is \c TYPE_EXTENSION then the id for the extension is
100     looked up in the database.  If the extension is found, and it is
101     not deactivated, the dependency passes.
103     If the type is \c TYPE_PLUGIN then the path for the plugin is found
104     using the Glib::Module routines.  When the path is found, then there
105     is a check to see if the file exists using the \c file_test function.
107     If the type is \c TYPE_EXECUTABLE or \c TYPE_FILE things are getting
108     even more interesting because now the \c _location variable is also
109     taken into account.  First, the difference between the two is that
110     the file test for \c TYPE_EXECUTABLE also tests to make sure the
111     file is executable, besides checking that it exists.
113     If the \c _location is \c LOCATION_EXTENSIONS then the \c INKSCAPE_EXTENSIONDIR
114     is put on the front of the string with \c build_filename.  Then the
115     appopriate filetest is run.
117     If the \c _location is \c LOCATION_ABSOLUTE then the file test is
118     run directly on the string.
120     If the \c _location is \c LOCATION_PATH or not specified then the
121     path is used to find the file.  Each entry in the path is stepped
122     through, attached to the string, and then tested.  If the file is
123     found then a TRUE is returned.  If we get all the way through the
124     path then a FALSE is returned, the command could not be found.
125 */
126 bool
127 Dependency::check (void) const
129     // std::cout << "Checking: " << *this << std::endl;
131     if (_string == NULL) return FALSE;
133     switch (_type) {
134         case TYPE_EXTENSION: {
135             Extension * myext = db.get(_string);
136             if (myext == NULL) return FALSE;
137             if (myext->deactivated()) return FALSE;
138             break;
139         }
140         case TYPE_PLUGIN: {
141             if (!Glib::Module::get_supported()) {
142                 return FALSE;
143             }
145             std::string path = Glib::Module::build_path(INKSCAPE_PLUGINDIR, _string);
146             if (!Glib::file_test(path, Glib::FILE_TEST_EXISTS))
147                 return FALSE;
148             break;
149         }
150         case TYPE_EXECUTABLE:
151         case TYPE_FILE: {
152             Glib::FileTest filetest = Glib::FILE_TEST_EXISTS;
153             if (_type == TYPE_EXECUTABLE) {
154                 filetest |= Glib::FILE_TEST_IS_EXECUTABLE;
155             }
157             std::string location(_string);
158             switch (_location) {
159                 case LOCATION_EXTENSIONS: {
160                     for (unsigned int i=0; i<Inkscape::Extension::Extension::search_path.size(); i++) {
161                         std::string temploc = Glib::build_filename(Inkscape::Extension::Extension::search_path[i], location);
162                         if (Glib::file_test(temploc, filetest)) {
163                             location = temploc;
164                             break;
165                         }
166                     }
167                 } /* PASS THROUGH!!! */
168                 case LOCATION_ABSOLUTE: {
169                     if (!Glib::file_test(location, filetest)) {
170                         // std::cout << "Failing on location: " << location << std::endl;
171                         return FALSE;
172                     }
173                     break;
174                 }
175                 /* The default case is to look in the path */
176                 case LOCATION_PATH:
177                 default: {
178                     gchar * path = g_strdup(g_getenv("PATH"));
180                     if (path == NULL) {
181                         /* There is no `PATH' in the environment.
182                            The default search path is the current directory */
183                         path = g_strdup(G_SEARCHPATH_SEPARATOR_S);
184                     }
186                     gchar * orig_path = path;
188                     for (; path != NULL;) {
189                         gchar * local_path;
190                         gchar * final_name;
192                         local_path = path;
193                         path = g_utf8_strchr(path, -1, G_SEARCHPATH_SEPARATOR);
194                         /* Not sure whether this is UTF8 happy, but it would seem
195                            like it considering that I'm searching (and finding)
196                            the ':' character */
197                         if (path != local_path && path != NULL) {
198                             path[0] = '\0';
199                             path++;
200                         } else {
201                             path = NULL;
202                         }
204                         if (local_path == '\0') {
205                             final_name = g_strdup(_string);
206                         } else {
207                             final_name = g_build_filename(local_path, _string, NULL);
208                         }
210                         if (Glib::file_test(final_name, filetest)) {
211                             g_free(final_name);
212                             g_free(orig_path);
213                             return TRUE;
214                         }
216                         g_free(final_name);
217                     }
219                     g_free(orig_path);
220                     return FALSE; /* Reverse logic in this one */
221                     break;
222                 }
223             } /* switch _location */
224             break;
225         } /* TYPE_FILE, TYPE_EXECUTABLE */
226         default:
227             return FALSE;
228     } /* switch _type */
230     return TRUE;
233 /**
234     \brief   Print out a dependency to a string.
235 */
236 std::ostream &
237 operator<< (std::ostream &out_file, const Dependency & in_dep)
239     out_file << _("Dependency::") << '\n';
240     out_file << _("  type: ") << _(in_dep._type_str[in_dep._type]) << '\n';
241     out_file << _("  location: ") << _(in_dep._location_str[in_dep._location]) << '\n';
242     out_file << _("  string: ") << in_dep._string << '\n';
244     if (in_dep._description != NULL) {
245         out_file << _("  description: ") << _(in_dep._description) << '\n';
246     }
248     out_file << std::flush;
250     return out_file;
253 } }  /* namespace Inkscape, Extension */
255 /*
256   Local Variables:
257   mode:c++
258   c-file-style:"stroustrup"
259   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
260   indent-tabs-mode:nil
261   fill-column:99
262   End:
263 */
264 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :