45 qRegisterMetaType<CxeImageDataItem::State>(); |
45 qRegisterMetaType<CxeImageDataItem::State>(); |
46 qRegisterMetaType<CxeError::Id>(); |
46 qRegisterMetaType<CxeError::Id>(); |
47 // Init mState |
47 // Init mState |
48 initializeStates(); |
48 initializeStates(); |
49 setInitialState(state); |
49 setInitialState(state); |
50 // Init delayer variables |
50 |
51 //mDelayedDelete = false; |
51 CX_DEBUG_EXIT_FUNCTION(); |
52 //mDelayedRename = false; |
52 } |
53 //mDelayedFileName = NULL; |
53 |
54 |
54 /*! |
55 CX_DEBUG_EXIT_FUNCTION(); |
55 * Destructor. |
56 } |
56 */ |
57 |
|
58 CxeImageDataItemSymbian::~CxeImageDataItemSymbian() |
57 CxeImageDataItemSymbian::~CxeImageDataItemSymbian() |
59 { |
58 { |
60 CX_DEBUG_ENTER_FUNCTION(); |
59 CX_DEBUG_ENTER_FUNCTION(); |
61 |
60 closeHandles(); |
62 // Close file |
61 CX_DEBUG_EXIT_FUNCTION(); |
63 mFile.Close(); |
62 } |
64 |
63 |
65 // Close file system |
64 /*! |
66 mFs.Close(); |
65 * Save the data now. |
67 |
66 * @return Status code. |
68 CX_DEBUG_EXIT_FUNCTION(); |
67 */ |
69 } |
68 CxeError::Id CxeImageDataItemSymbian::save() |
70 |
69 { |
71 /* |
70 CX_DEBUG_ENTER_FUNCTION(); |
72 void CxeImageDataItemSymbian::deleteImage() |
71 |
73 { |
72 CxeError::Id status(CxeError::None); |
74 CX_DEBUG_ENTER_FUNCTION(); |
73 try { |
75 |
74 setState(CxeImageDataItem::Saving); |
76 int err = KErrNone; |
75 trySave(); |
77 |
76 setState(CxeImageDataItem::Saved); |
78 //! @todo: make this function return a KErrNotReady if below |
77 } catch (const std::exception &e) { |
79 if ( mState != CxeImageDataItem::Idle ) |
78 closeHandles(); |
80 { |
79 status = CxeErrorHandlingSymbian::map(qt_symbian_exception2Error(e)); |
81 CX_DEBUG(("Error: This data item has no data...")); |
80 setState(CxeImageDataItem::SaveFailed); |
82 CX_DEBUG_ASSERT(0); // panics |
|
83 return; |
|
84 } |
|
85 |
|
86 // do delete or delayed delete |
|
87 if (( mState == CxeImageDataItem::Waiting ) || ( mState == CxeImageDataItem::Saving )) |
|
88 { |
|
89 // we are currently saving, so we have to delete later |
|
90 CX_DEBUG(("delayed delete")); |
|
91 mDelayedDelete = true; |
|
92 } |
|
93 else |
|
94 { |
|
95 // delete now |
|
96 CX_DEBUG(("deleting now...")); |
|
97 err = KErrNotFound; |
|
98 |
|
99 |
|
100 //! @todo: this is horrible for performance... there is no need to create multiple server sessions |
|
101 RFs fs; |
|
102 TInt connectError = fs.Connect(); |
|
103 BaflUtils ba; |
|
104 if( !connectError && ba.FileExists( fs, *mPath ) ) |
|
105 { |
|
106 err = KErrNone; |
|
107 ba.DeleteFile( fs, *mPath ); |
|
108 } |
|
109 fs.Close(); |
|
110 } |
|
111 |
|
112 CX_DEBUG(("err: %d", err)); |
|
113 |
|
114 CX_DEBUG_EXIT_FUNCTION(); |
|
115 //return err; //! @todo |
|
116 } |
81 } |
117 |
82 |
118 void CxeImageDataItemSymbian::renameImage( const TDesC& newPath ) |
83 emit imageSaved(status, mPath, mId); |
119 { |
84 |
120 CX_DEBUG_ENTER_FUNCTION(); |
85 CX_DEBUG_EXIT_FUNCTION(); |
121 |
86 return status; |
122 int err = KErrNone; |
87 } |
123 |
88 |
124 //! @todo: make this function return a KErrNotReady if below |
89 /*! |
125 if ( mState != CxeImageDataItem::Idle ) |
90 * Helper method for trying to save the data. |
126 { |
91 * If any error is encountered during the saving process, exception is thrown. |
127 CX_DEBUG(("Error: This data item has no data...")); |
92 */ |
128 CX_DEBUG_ASSERT(0); // panics |
93 void CxeImageDataItemSymbian::trySave() |
129 return; |
94 { |
130 } |
95 CX_DEBUG_ENTER_FUNCTION(); |
131 |
96 OstTrace0(camerax_performance, CXEIMAGEDATAITEMSYMBIAN_SAVE_IN, "msg: e_CX_IMAGEDATAITEM_SAVE 1"); |
132 // do rename or delayed rename |
97 |
133 if (( mState == CxeImageDataItem::Waiting ) || ( mState == CxeImageDataItem::Saving )) |
98 CX_DEBUG(("CxeImageDataItemSymbian - Starting to save [%s]", qPrintable(mPath))); |
134 { |
99 |
135 // we are currently saving, so we have to rename later |
100 // Check we have the path set. |
136 CX_DEBUG(("delayed rename")); |
101 if (mPath.isEmpty()) { |
137 mDelayedRename = true; |
102 CX_DEBUG(("CxeImageDataItemSymbian - Filename not set!")); |
138 |
103 qt_symbian_throwIfError(KErrArgument); |
139 TRAP( err, |
|
140 mDelayedFileName = HBufC::NewL( newPath.Length() ); |
|
141 mDelayedFileName->Des().Append( newPath ); |
|
142 ); |
|
143 } |
|
144 else |
|
145 { |
|
146 // rename now |
|
147 CX_DEBUG(("delayed rename")); |
|
148 err = KErrNotFound; |
|
149 RFs fs; |
|
150 TInt connectError = fs.Connect(); |
|
151 BaflUtils ba; |
|
152 if( !connectError && ba.FileExists( fs, *mPath ) ) |
|
153 { |
|
154 err = KErrNone; |
|
155 ba.RenameFile( fs, *mPath, newPath ); |
|
156 } |
|
157 fs.Close(); |
|
158 } |
|
159 |
|
160 CX_DEBUG(("err: %d", err)); |
|
161 |
|
162 CX_DEBUG_EXIT_FUNCTION(); |
|
163 //return err; //! @todo |
|
164 } |
104 } |
165 */ |
|
166 |
|
167 CxeError::Id CxeImageDataItemSymbian::save() |
|
168 { |
|
169 CX_DEBUG_ENTER_FUNCTION(); |
|
170 |
|
171 mError = KErrNone; |
|
172 |
|
173 CX_DEBUG(( "Starting to save %s", mPath.toAscii().constData() )); |
|
174 |
|
175 if (mPath.isEmpty()) { |
|
176 CX_DEBUG(("Filename not set !")); |
|
177 mError = KErrArgument; |
|
178 } |
|
179 |
105 |
180 TPtrC16 filename; |
106 TPtrC16 filename; |
181 |
107 filename.Set(reinterpret_cast<const TUint16*>(mPath.utf16())); |
182 if (!mError) { |
108 // Init |
183 filename.Set(reinterpret_cast<const TUint16*>(mPath.utf16())); |
109 CX_DEBUG(("CxeImageDataItemSymbian - connect to RFs..")); |
184 // Init |
110 qt_symbian_throwIfError(mFs.Connect()); |
185 mError = mFs.Connect(); |
|
186 CX_DEBUG(("mFsSession.Connect mError=%d", mError)); |
|
187 } |
|
188 |
111 |
189 // Get drive number |
112 // Get drive number |
190 TInt drive = 0; |
113 TInt drive = 0; |
191 if (!mError) { |
114 CX_DEBUG(("CxeImageDataItemSymbian - Get drive number..")); |
192 mError = RFs::CharToDrive(filename[0], drive); |
115 qt_symbian_throwIfError(RFs::CharToDrive(filename[0], drive)); |
193 CX_DEBUG(("CharToDrive mError=%d", mError)); |
116 |
|
117 // Check disk has space |
|
118 bool fullDisk = checkDiskSpace(&mFs, mData.size(), drive); |
|
119 if (fullDisk) { |
|
120 CX_DEBUG(("CxeImageDataItemSymbian - Disk is full!")); |
|
121 qt_symbian_throwIfError(KErrDiskFull); |
194 } |
122 } |
195 |
123 |
196 // Check disk space |
|
197 if (!mError) { |
|
198 TBool fullDisk = EFalse; |
|
199 fullDisk = checkDiskSpace(&mFs, mData.size(), drive); |
|
200 if (fullDisk) { |
|
201 CX_DEBUG(("SysUtil::FullDisk")); |
|
202 mError = KErrDiskFull; |
|
203 } |
|
204 } |
|
205 |
|
206 // Attempt to create the file |
124 // Attempt to create the file |
207 if (!mError) { |
125 // Note: In sake of MDS not starting harvesting here, |
208 // Note: In sake of MDS not starting harvesting here, |
126 // do not use RFile::Replace. If harvesting is started now, |
209 // do not use RFile::Replace. If harvesting is started now, |
127 // our later call to harvest may be ignored and |
210 // our later call to harvest may be ignored and |
128 // file may be missing from "Captured" album. |
211 // file may be missing from "Captured" album. |
129 CX_DEBUG(("CxeImageDataItemSymbian - Create the file..")); |
212 mError = mFile.Create(mFs, filename, EFileWrite); |
130 qt_symbian_throwIfError(mFile.Create(mFs, filename, EFileWrite)); |
213 CX_DEBUG(("file.Create mError=%d", mError)); |
131 |
214 } |
132 // Write data to the file. |
215 |
133 CX_DEBUG(("CxeImageDataItemSymbian - Starting to write the file..")); |
216 // Write the file |
134 TPtrC8 data(reinterpret_cast<const TUint8*> (mData.constData()), mData.size()); |
217 if (!mError) { |
135 qt_symbian_throwIfError(mFile.Write(data)); // synchronous |
218 // Update state |
136 |
219 setState(CxeImageDataItem::Saving); |
137 // Flush all the data to file now. |
220 |
138 // This may take a while depending on buffer sizes and file server load. |
221 CX_DEBUG(("about to write to file")); |
139 OstTrace0(camerax_performance, CXEIMAGEDATAITEMSYMBIAN_FLUSH_1, "msg: e_CX_SAVE_FLUSH_FILE 1"); |
222 TPtrC8 data(reinterpret_cast<const TUint8*> (mData.constData()), mData.size()); |
140 qt_symbian_throwIfError(mFile.Flush()); |
223 mError = mFile.Write(data); // synchronous |
141 OstTrace0(camerax_performance, CXEIMAGEDATAITEMSYMBIAN_FLUSH_2, "msg: e_CX_SAVE_FLUSH_FILE 0"); |
224 saveCleanup(); |
142 |
225 CX_DEBUG(("file write completed")); |
143 // Close the file and server handles. |
226 } |
144 closeHandles(); |
227 |
145 CX_DEBUG(("CxeImageDataItemSymbian - Saving to file completed..")); |
228 mFile.Close(); //~400us |
146 |
229 mFs.Close(); //~450us |
147 OstTrace0(camerax_performance, CXEIMAGEDATAITEMSYMBIAN_SAVED, "msg: e_CX_SHOT_TO_SAVE 0"); |
230 OstTrace0(camerax_performance, CXEIMAGEDATAIMTEMSYMBIAN_SAVED, "msg: e_CX_SHOT_TO_SAVE 0"); |
148 OstTrace0(camerax_performance, CXEIMAGEDATAITEMSYMBIAN_SAVE_OUT, "msg: e_CX_IMAGEDATAITEM_SAVE 0"); |
231 |
149 CX_DEBUG_EXIT_FUNCTION(); |
232 if (mError == KErrNone) { |
150 } |
233 setState(CxeImageDataItem::Saved); |
151 |
234 } else { |
152 /*! |
235 setState(CxeImageDataItem::SaveFailed); |
|
236 } |
|
237 emit imageSaved(CxeErrorHandlingSymbian::map(mError), mPath, mId); |
|
238 |
|
239 CX_DEBUG(("mError: %d", mError)); |
|
240 CX_DEBUG_EXIT_FUNCTION(); |
|
241 return CxeErrorHandlingSymbian::map(mError); |
|
242 } |
|
243 |
|
244 /** |
|
245 * Get the id number of this data item. |
153 * Get the id number of this data item. |
246 */ |
154 */ |
247 int CxeImageDataItemSymbian::id() const |
155 int CxeImageDataItemSymbian::id() const |
248 { |
156 { |
249 return mId; |
157 return mId; |
250 } |
158 } |
251 |
159 |
252 /** |
160 /*! |
253 * Get the path of this data item. |
161 * Get the path of this data item. |
254 */ |
162 */ |
255 QString CxeImageDataItemSymbian::path() const |
163 QString CxeImageDataItemSymbian::path() const |
256 { |
164 { |
257 return mPath; |
165 return mPath; |
258 } |
166 } |
259 |
167 |
260 |
168 /*! |
261 int CxeImageDataItemSymbian::checkDiskSpace(RFs* aFs, |
169 * Check that there's enough space in the drive. |
|
170 * @param aFs File server session |
|
171 * @param aBytesToWrite Amount of bytes to be written. |
|
172 * @param aDrive Drive number. |
|
173 * @return True, if given amount of bytes can be written to the drive, false otherwise. |
|
174 */ |
|
175 bool CxeImageDataItemSymbian::checkDiskSpace(RFs* aFs, |
262 TInt aBytesToWrite, |
176 TInt aBytesToWrite, |
263 TInt aDrive) |
177 TInt aDrive) |
264 { |
178 { |
265 CX_DEBUG_ENTER_FUNCTION(); |
179 CX_DEBUG_ENTER_FUNCTION(); |
266 int value = CxeSysUtil::DiskSpaceBelowCriticalLevel( |
180 bool value = CxeSysUtil::DiskSpaceBelowCriticalLevel( |
267 aFs, |
181 aFs, |
268 aBytesToWrite, |
182 aBytesToWrite, |
269 aDrive ); |
183 aDrive ); |
270 return value; |
184 return value; |
271 } |
185 } |
272 |
186 |
273 void CxeImageDataItemSymbian::saveCleanup() |
187 /*! |
274 { |
188 * State of this item. |
275 CX_DEBUG_ENTER_FUNCTION(); |
189 * @return The state. |
276 |
190 */ |
277 CX_DEBUG_ASSERT( state() == CxeImageDataItem::Saving ); |
|
278 |
|
279 // Flush file. |
|
280 if (!mError) { |
|
281 CX_DEBUG(("flushing...")); |
|
282 mError = mFile.Flush(); |
|
283 CX_DEBUG(("flushed")); |
|
284 } |
|
285 |
|
286 |
|
287 /* |
|
288 // Delayed rename, if needed |
|
289 if (( !mError ) && ( mDelayedRename )) |
|
290 { |
|
291 CX_DEBUG(("doing delayed rename...")); |
|
292 mError = KErrNotFound; |
|
293 BaflUtils ba; |
|
294 if( ba.FileExists( mFs, *mPath ) ) |
|
295 { |
|
296 mError = KErrNone; |
|
297 TPtrC newPath = *mDelayedFileName; |
|
298 ba.RenameFile( mFs, *mPath, newPath ); |
|
299 } |
|
300 mDelayedRename = false; |
|
301 CX_DEBUG(("rename done, mError: %d", mError)); |
|
302 } |
|
303 |
|
304 // Delayed delete, if needed |
|
305 if (( !mError ) && ( mDelayedDelete )) |
|
306 { |
|
307 CX_DEBUG(("doing delayed delete...")); |
|
308 mError = KErrNotFound; |
|
309 BaflUtils ba; |
|
310 if( ba.FileExists( mFs, *mPath ) ) |
|
311 { |
|
312 mError = KErrNone; |
|
313 ba.DeleteFile( mFs, *mPath ); |
|
314 } |
|
315 mDelayedDelete = false; |
|
316 CX_DEBUG(("delete done, mError: %d", mError)); |
|
317 }*/ |
|
318 |
|
319 CX_DEBUG_EXIT_FUNCTION(); |
|
320 } |
|
321 |
|
322 CxeImageDataItem::State CxeImageDataItemSymbian::state() const |
191 CxeImageDataItem::State CxeImageDataItemSymbian::state() const |
323 { |
192 { |
324 return static_cast<CxeImageDataItem::State> (stateId()); |
193 return static_cast<CxeImageDataItem::State> (stateId()); |
325 } |
194 } |
326 |
195 |
|
196 /*! |
|
197 * Handle state change. |
|
198 */ |
327 void CxeImageDataItemSymbian::handleStateChanged(int newStateId, CxeError::Id error) |
199 void CxeImageDataItemSymbian::handleStateChanged(int newStateId, CxeError::Id error) |
328 { |
200 { |
329 emit stateChanged(static_cast<State> (newStateId), error); |
201 emit stateChanged(static_cast<State> (newStateId), error); |
330 } |
202 } |
331 |
203 |
332 |
204 /*! |
|
205 * Is location tagging enabled for this item. |
|
206 * @return True if location tagging is enabled, false otherwise. |
|
207 */ |
333 bool CxeImageDataItemSymbian::isLocationEnabled() const |
208 bool CxeImageDataItemSymbian::isLocationEnabled() const |
334 { |
209 { |
335 return mAddLocationInfo; |
210 return mAddLocationInfo; |
336 } |
211 } |
337 |
212 |
|
213 /*! |
|
214 * Init the state machine. |
|
215 */ |
338 void CxeImageDataItemSymbian::initializeStates() |
216 void CxeImageDataItemSymbian::initializeStates() |
339 { |
217 { |
340 // addState( id, name, allowed next states ) |
218 // addState( id, name, allowed next states ) |
341 addState(new CxeState(SavePending, "SavePending", Saving | SaveFailed)); |
219 addState(new CxeState(SavePending, "SavePending", Saving | SaveFailed)); |
342 addState(new CxeState(Saving, "Saving", Saved | SaveFailed)); |
220 addState(new CxeState(Saving, "Saving", Saved | SaveFailed)); |
343 addState(new CxeState(Saved, "Saved", 0)); |
221 addState(new CxeState(Saved, "Saved", 0)); |
344 addState(new CxeState(SaveFailed, "SaveFailed", 0)); |
222 addState(new CxeState(SaveFailed, "SaveFailed", 0)); |
345 } |
223 } |
|
224 |
|
225 /*! |
|
226 * Close the file server and file handles. |
|
227 */ |
|
228 void CxeImageDataItemSymbian::closeHandles() |
|
229 { |
|
230 mFile.Close(); |
|
231 mFs.Close(); |
|
232 } |
|
233 |
|
234 // end of file |