Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_06 / src / modules / lyr_std / import.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file import.cpp
3 **      \brief Image Import Layer Implementation
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 **
21 ** === N O T E S ===========================================================
22 **
23 ** ========================================================================= */
24
25 /* === H E A D E R S ======================================================= */
26
27 #ifdef USING_PCH
28 #       include "pch.h"
29 #else
30 #ifdef HAVE_CONFIG_H
31 #       include <config.h>
32 #endif
33
34 #include "import.h"
35 #include <synfig/string.h>
36 #include <synfig/time.h>
37 #include <synfig/context.h>
38 #include <synfig/paramdesc.h>
39 #include <synfig/renddesc.h>
40 #include <synfig/surface.h>
41 #include <synfig/value.h>
42 #include <synfig/valuenode.h>
43 #include <synfig/canvas.h>
44
45 #endif
46
47 using namespace synfig;
48 using namespace std;
49 using namespace etl;
50
51 /* === M A C R O S ========================================================= */
52
53 /* === G L O B A L S ======================================================= */
54
55 SYNFIG_LAYER_INIT(Import);
56 SYNFIG_LAYER_SET_NAME(Import,"import");
57 SYNFIG_LAYER_SET_LOCAL_NAME(Import,_("Import"));
58 SYNFIG_LAYER_SET_CATEGORY(Import,_("Other"));
59 SYNFIG_LAYER_SET_VERSION(Import,"0.1");
60 SYNFIG_LAYER_SET_CVS_ID(Import,"$Id$");
61
62 /* === P R O C E D U R E S ================================================= */
63
64 /* === M E T H O D S ======================================================= */
65
66 Import::Import()
67 {
68         time_offset=0;
69 }
70
71 Import::~Import()
72 {
73 }
74
75 void
76 Import::on_canvas_set()
77 {
78         if(get_canvas())set_param("filename",filename);
79 }
80
81 bool
82 Import::set_param(const String & param, const ValueBase &value)
83 {
84         try{
85         IMPORT(time_offset);
86         if(param=="filename" && value.same_as(filename))
87         {
88                 if(!get_canvas())
89                 {
90                         filename=value.get(filename);
91                         importer=0;
92                         surface.clear();
93                         return true;
94                 }
95
96                 String newfilename=value.get(string());
97                 String filename_with_path;
98
99                 // Get rid of any %20 crap
100                 {
101                         unsigned int n;
102                         while((n=newfilename.find("%20"))!=String::npos)
103                                 newfilename.replace(n,3," ");
104                 }
105
106                 //if(get_canvas()->get_file_path()==dirname(newfilename))
107                 //{
108                 //      synfig::info("Image seems to be in local directory. Adjusting path...");
109                 //      newfilename=basename(newfilename);
110                 //}
111
112 #ifndef WIN32
113                 if(is_absolute_path(newfilename))
114                 {
115                         string curpath(cleanup_path(absolute_path(get_canvas()->get_file_path())));
116                         while(basename(curpath)==".")curpath=dirname(curpath);
117
118                         newfilename=relative_path(curpath,newfilename);
119                         synfig::info("basename(curpath)=%s, Path adjusted to %s",basename(curpath).c_str(),newfilename.c_str());
120                 }
121 #endif
122
123                 if(filename.empty())
124                         filename=newfilename;
125
126                 if(newfilename.empty())
127                 {
128                         filename=newfilename;
129                         importer=0;
130                         surface.clear();
131                         return true;
132                 }
133
134                 // If we are already loaded, don't reload
135                 if(filename==newfilename && importer)
136                 {
137                         synfig::warning(strprintf(_("Filename seems to already be set to \"%s\" (%s)"),filename.c_str(),newfilename.c_str()));
138                         return true;
139                 }
140
141                 assert(get_canvas());
142
143                 if(is_absolute_path(newfilename))
144                         filename_with_path=newfilename;
145                 else
146                         filename_with_path=get_canvas()->get_file_path()+ETL_DIRECTORY_SEPERATOR+newfilename;
147
148                 handle<Importer> newimporter;
149
150                 newimporter=Importer::open(absolute_path(filename_with_path));
151
152                 if(!newimporter)
153                 {
154                         newimporter=Importer::open(get_canvas()->get_file_path()+ETL_DIRECTORY_SEPERATOR+basename(newfilename));
155                         if(!newimporter)
156                         {
157                                 synfig::error(strprintf("Unable to create an importer object with file \"%s\"",filename_with_path.c_str()));
158                                 surface.clear();
159                                 return false;
160                         }
161                 }
162
163                 surface.clear();
164                 if(!newimporter->get_frame(surface,Time(0)))
165                 {
166                         synfig::warning(strprintf("Unable to get frame from \"%s\"",filename_with_path.c_str()));
167                 }
168
169                 importer=newimporter;
170                 filename=newfilename;
171                 abs_filename=absolute_path(filename_with_path);
172
173                 return true;
174         }
175         } catch(...) { set_amount(0); return false; }
176
177         return Layer_Bitmap::set_param(param,value);
178 }
179
180 ValueBase
181 Import::get_param(const String & param)const
182 {
183         EXPORT(time_offset);
184
185         if(get_canvas())
186         {
187                 if(param=="filename")
188                 {
189                         string curpath(cleanup_path(absolute_path(get_canvas()->get_file_path())));
190                         return relative_path(curpath,abs_filename);
191                 }
192         }
193         else
194                 EXPORT(filename);
195
196         EXPORT_NAME();
197         EXPORT_VERSION();
198
199         return Layer_Bitmap::get_param(param);
200 }
201
202 Layer::Vocab
203 Import::get_param_vocab()const
204 {
205         Layer::Vocab ret(Layer_Bitmap::get_param_vocab());
206
207         ret.push_back(ParamDesc("filename")
208                 .set_local_name(_("Filename"))
209                 .set_description(_("File to import"))
210                 .set_hint("filename")
211         );
212         ret.push_back(ParamDesc("time_offset")
213                 .set_local_name(_("Time Offset"))
214         );
215
216         return ret;
217 }
218
219 void
220 Import::set_time(Context context, Time time)const
221 {
222         if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset);
223         //else surface.clear();
224         context.set_time(time);
225 }
226
227 void
228 Import::set_time(Context context, Time time, const Point &pos)const
229 {
230         if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset);
231         //else surface.clear();
232         context.set_time(time,pos);
233 }