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