Code

Fix image transform when there is no rotate or scale
[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  */
11 extern "C" {           // glib-2.4 needs this
12 #include <libintl.h>
13 }
15 #include <glibmm/i18n.h>
17 #include "config.h"
18 #include "path-prefix.h"
20 #include "dependency.h"
21 #include "db.h"
23 namespace Inkscape {
24 namespace Extension {
26 // These strings are for XML attribute comparisons and should not be translated
27 gchar const * Dependency::_type_str[] = {
28     "executable",
29     "file",
30     "extension",
31     "plugin",
32 };
34 // These strings are for XML attribute comparisons and should not be translated
35 gchar const * Dependency::_location_str[] = {
36     "path",
37     "extensions",
38     "absolute",
39 };
41 /**
42     \brief   Create a dependency using an XML definition
43     \param   in_repr   XML definition of the dependency
45     This function mostly looks for the 'location' and 'type' attributes
46     and turns them into the enums of the same name.  This makes things
47     a little bit easier to use later.  Also, a pointer to the core
48     content is pulled out -- also to make things easier.
49 */
50 Dependency::Dependency (Inkscape::XML::Node * in_repr)
51 {
52     _type = TYPE_FILE;
53     _location = LOCATION_PATH;
54     _repr = in_repr;
55     _string = NULL;
56     _description = NULL;
58     Inkscape::GC::anchor(_repr);
60     const gchar * location = _repr->attribute("location");
61     for (int i = 0; i < LOCATION_CNT && location != NULL; i++) {
62         if (!strcmp(location, _location_str[i])) {
63             _location = (location_t)i;
64             break;
65         }
66     }
68     const gchar * type = _repr->attribute("type");
69     for (int i = 0; i < TYPE_CNT && type != NULL; i++) {
70         if (!strcmp(type, _type_str[i])) {
71             _type = (type_t)i;
72             break;
73         }
74     }
76     _string = sp_repr_children(_repr)->content();
78     _description = _repr->attribute("description");
79     if (_description == NULL)
80         _description = _repr->attribute("_description");
82     return;
83 }
85 /**
86     \brief   This depenency is not longer needed
88     Unreference the XML structure.
89 */
90 Dependency::~Dependency (void)
91 {
92     Inkscape::GC::release(_repr);
93 }
95 /**
96     \brief   Check if the dependency passes.
97     \return  Whether or not the dependency passes.
99     This function depends largely on all of the enums.  The first level
100     that is evaluted is the \c _type.
102     If the type is \c TYPE_EXTENSION then the id for the extension is
103     looked up in the database.  If the extension is found, and it is
104     not deactivated, the dependency passes.
106     If the type is \c TYPE_PLUGIN then the path for the plugin is found
107     using the Glib::Module routines.  When the path is found, then there
108     is a check to see if the file exists using the \c file_test function.
110     If the type is \c TYPE_EXECUTABLE or \c TYPE_FILE things are getting
111     even more interesting because now the \c _location variable is also
112     taken into account.  First, the difference between the two is that
113     the file test for \c TYPE_EXECUTABLE also tests to make sure the
114     file is executable, besides checking that it exists.
116     If the \c _location is \c LOCATION_EXTENSIONS then the \c INKSCAPE_EXTENSIONDIR
117     is put on the front of the string with \c build_filename.  Then the
118     appopriate filetest is run.
120     If the \c _location is \c LOCATION_ABSOLUTE then the file test is
121     run directly on the string.
123     If the \c _location is \c LOCATION_PATH or not specified then the
124     path is used to find the file.  Each entry in the path is stepped
125     through, attached to the string, and then tested.  If the file is
126     found then a TRUE is returned.  If we get all the way through the
127     path then a FALSE is returned, the command could not be found.
128 */
129 bool
130 Dependency::check (void) const
132     // std::cout << "Checking: " << *this << std::endl;
134     if (_string == NULL) return FALSE;
136     switch (_type) {
137         case TYPE_EXTENSION: {
138             Extension * myext = db.get(_string);
139             if (myext == NULL) return FALSE;
140             if (myext->deactivated()) return FALSE;
141             break;
142         }
143         case TYPE_PLUGIN: {
144             if (!Glib::Module::get_supported()) {
145                 return FALSE;
146             }
148             std::string path = Glib::Module::build_path(INKSCAPE_PLUGINDIR, _string);
149             if (!Glib::file_test(path, Glib::FILE_TEST_EXISTS))
150                 return FALSE;
151             break;
152         }
153         case TYPE_EXECUTABLE:
154         case TYPE_FILE: {
155             Glib::FileTest filetest = Glib::FILE_TEST_EXISTS;
156             if (_type == TYPE_EXECUTABLE) {
157                 filetest |= Glib::FILE_TEST_IS_EXECUTABLE;
158             }
160             std::string location(_string);
161             switch (_location) {
162                 case LOCATION_EXTENSIONS: {
163                     for (unsigned int i=0; i<Inkscape::Extension::Extension::search_path.size(); i++) {
164                         std::string temploc = Glib::build_filename(Inkscape::Extension::Extension::search_path[i], location);
165                         if (Glib::file_test(temploc, filetest)) {
166                             location = temploc;
167                             break;
168                         }
169                     }
170                 } /* PASS THROUGH!!! */
171                 case LOCATION_ABSOLUTE: {
172                     if (!Glib::file_test(location, filetest)) {
173                         // std::cout << "Failing on location: " << location << std::endl;
174                         return FALSE;
175                     }
176                     break;
177                 }
178                 /* The default case is to look in the path */
179                 case LOCATION_PATH:
180                 default: {
181                     gchar * path = g_strdup(g_getenv("PATH"));
183                     if (path == NULL) {
184                         /* There is no `PATH' in the environment.
185                            The default search path is the current directory */
186                         path = g_strdup(G_SEARCHPATH_SEPARATOR_S);
187                     }
189                     gchar * orig_path = path;
191                     for (; path != NULL;) {
192                         gchar * local_path;
193                         gchar * final_name;
195                         local_path = path;
196                         path = g_utf8_strchr(path, -1, G_SEARCHPATH_SEPARATOR);
197                         /* Not sure whether this is UTF8 happy, but it would seem
198                            like it considering that I'm searching (and finding)
199                            the ':' character */
200                         if (path != local_path && path != NULL) {
201                             path[0] = '\0';
202                             path++;
203                         } else {
204                             path = NULL;
205                         }
207                         if (local_path == '\0') {
208                             final_name = g_strdup(_string);
209                         } else {
210                             final_name = g_build_filename(local_path, _string, NULL);
211                         }
213                         if (Glib::file_test(final_name, filetest)) {
214                             g_free(final_name);
215                             g_free(orig_path);
216                             return TRUE;
217                         }
219                         g_free(final_name);
220                     }
222                     g_free(orig_path);
223                     return FALSE; /* Reverse logic in this one */
224                     break;
225                 }
226             } /* switch _location */
227             break;
228         } /* TYPE_FILE, TYPE_EXECUTABLE */
229         default:
230             return FALSE;
231     } /* switch _type */
233     return TRUE;
236 /**
237     \brief   Print out a dependency to a string.
238 */
239 std::ostream &
240 operator<< (std::ostream &out_file, const Dependency & in_dep)
242     out_file << _("Dependency::") << '\n';
243     out_file << _("  type: ") << _(in_dep._type_str[in_dep._type]) << '\n';
244     out_file << _("  location: ") << _(in_dep._location_str[in_dep._location]) << '\n';
245     out_file << _("  string: ") << in_dep._string << '\n';
247     if (in_dep._description != NULL) {
248         out_file << _("  description: ") << _(in_dep._description) << '\n';
249     }
251     out_file << std::flush;
253     return out_file;
256 } }  /* namespace Inkscape, Extension */
258 /*
259   Local Variables:
260   mode:c++
261   c-file-style:"stroustrup"
262   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
263   indent-tabs-mode:nil
264   fill-column:99
265   End:
266 */
267 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :