00001 #ifndef Impala_Core_Database_DataDocument_h
00002 #define Impala_Core_Database_DataDocument_h
00003
00004 #include "Util/DatabaseReadString.h"
00005 #include "Util/DatabaseWriteString.h"
00006 #include "Core/Array/Arrays.h"
00007 #include "Core/Database/RawDataSet.h"
00008 #include "Core/Table/TableIds.h"
00009 #include "Persistency/KeywordListRepository.h"
00010
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Database
00016 {
00017
00018
00019 enum DocLevel
00020 {
00021 LEVEL_NONE = 0,
00022 LEVEL_DIR = 1,
00023 LEVEL_FILE = 2,
00024 LEVEL_SHOT = 3,
00025 LEVEL_FRAME = 4
00026 };
00027
00028
00029 class DataDocument
00030 {
00031 public:
00032 typedef Geometry::Rectangle Rectangle;
00033 typedef Core::Table::TableIds TableIds;
00034
00035 DataDocument(RawDataSet* dataSet)
00036 {
00037 mDataSet = dataSet;
00038 mCurFileId = -1;
00039 mCurDirId = -1;
00040 mThumbScale = 0.5;
00041 }
00042
00043
00044
00045 bool
00046 HasCurFile()
00047 {
00048 return mCurFileId != -1;
00049 }
00050
00051 bool
00052 HasCurDir()
00053 {
00054 if (HasCurFile())
00055 return true;
00056 return mCurDirId != -1;
00057 }
00058
00059 int
00060 CurFileId()
00061 {
00062 return mCurFileId;
00063 }
00064
00065 int
00066 CurDirId()
00067 {
00068 if (HasCurFile())
00069 return mDataSet->GetDirIdOfFile(CurFileId());
00070 return mCurDirId;
00071 }
00072
00073 int
00074 GetFileOfDir(int fileIdx, int dirId)
00075 {
00076 if (!mDataSet->HasFiles())
00077 return -1;
00078 if (dirId == -1)
00079 {
00080 if (!HasCurDir())
00081 return -1;
00082 dirId = CurDirId();
00083 }
00084 return mDataSet->GetFirstFileId(dirId) + fileIdx;
00085 }
00086
00087
00088 TableIds*
00089 GetFilesOfDir(int dirId)
00090 {
00091 if (dirId == -1)
00092 {
00093 if (!HasCurDir())
00094 return 0;
00095 dirId = CurDirId();
00096 }
00097 int first = mDataSet->GetFirstFileId(dirId);
00098 int nr = mDataSet->GetNrFiles(dirId);
00099 TableIds* table = new TableIds(nr);
00100 for (int i=0 ; i<nr ; i++)
00101 table->Add(first + i);
00102 return table;
00103 }
00104
00105 RawDataSet*
00106 GetDataSet()
00107 {
00108 return mDataSet;
00109 }
00110
00111
00112
00113 virtual bool
00114 HasCursor()
00115 {
00116 return HasCurFile();
00117 }
00118
00119 virtual DocLevel
00120 CursorToDir(int dirId)
00121 {
00122 GotoDir(dirId);
00123 return LEVEL_DIR;
00124 }
00125
00126 virtual DocLevel
00127 CursorToFile(int fileId)
00128 {
00129 GotoFile(fileId);
00130 return LEVEL_FILE;
00131 }
00132
00133 #if 0
00134 virtual DocLevel
00135 CursorPageUp()
00136 {
00137 if (GotoPrevDir())
00138 return LEVEL_DIR;
00139 return LEVEL_NONE;
00140 }
00141
00142 virtual DocLevel
00143 CursorPageDown()
00144 {
00145 if (GotoNextDir())
00146 return LEVEL_DIR;
00147 return LEVEL_NONE;
00148 }
00149
00150 virtual DocLevel
00151 CursorLeft()
00152 {
00153 if (GotoPrevFile())
00154 return LEVEL_FILE;
00155 return LEVEL_NONE;
00156 }
00157
00158 virtual DocLevel
00159 CursorRight()
00160 {
00161 if (GotoNextFile())
00162 return LEVEL_FILE;
00163 return LEVEL_NONE;
00164 }
00165
00166 virtual DocLevel
00167 CursorUp()
00168 {
00169 return LEVEL_NONE;
00170 }
00171
00172 virtual DocLevel
00173 CursorDown()
00174 {
00175 return LEVEL_NONE;
00176 }
00177 #endif // #if 0
00178 virtual DocLevel
00179 CursorPrevDir()
00180 {
00181 if (GotoPrevDir())
00182 return LEVEL_DIR;
00183 return LEVEL_NONE;
00184 }
00185
00186 virtual DocLevel
00187 CursorNextDir()
00188 {
00189 if (GotoNextDir())
00190 return LEVEL_DIR;
00191 return LEVEL_NONE;
00192 }
00193
00194 virtual DocLevel
00195 CursorPrevFile()
00196 {
00197 if (GotoPrevFile())
00198 return LEVEL_FILE;
00199 return LEVEL_NONE;
00200 }
00201
00202 virtual DocLevel
00203 CursorNextFile()
00204 {
00205 if (GotoNextFile())
00206 return LEVEL_FILE;
00207 return LEVEL_NONE;
00208 }
00209
00210 virtual DocLevel
00211 CursorPrevShot()
00212 {
00213 return LEVEL_NONE;
00214 }
00215
00216 virtual DocLevel
00217 CursorNextShot()
00218 {
00219 return LEVEL_NONE;
00220 }
00221
00222 virtual bool
00223 HasBookmarks() = 0;
00224
00225 virtual DocLevel
00226 CursorToBookmark(int idx) = 0;
00227
00228 virtual DocLevel
00229 CursorNextBookmark() = 0;
00230
00231 virtual DocLevel
00232 CursorPrevBookmark() = 0;
00233
00234
00235
00236 virtual Core::Array::Array2dVec3UInt8*
00237 VisualAtCursor(bool thumbnail)
00238 {
00239 return 0;
00240 }
00241
00242
00243
00244 void
00245 SetRect(Rectangle r)
00246 {
00247 mRect = r;
00248 mRect.CheckSize();
00249 }
00250
00251 void
00252 SetRect(Rectangle r, double scale)
00253 {
00254 mRect = r / scale;
00255 mRect.CheckSize();
00256 }
00257
00258 void
00259 SetRectThumb(Rectangle r)
00260 {
00261 SetRect(r, mThumbScale);
00262 }
00263
00264 Rectangle
00265 GetRect()
00266 {
00267 return mRect;
00268 }
00269
00270 Rectangle
00271 GetRect(double scale)
00272 {
00273 return mRect * scale;
00274 }
00275
00276 Rectangle
00277 GetRectThumb()
00278 {
00279 return GetRect(mThumbScale);
00280 }
00281
00282 void
00283 SetThumbScale(double scale)
00284 {
00285 mThumbScale = scale;
00286 }
00287
00288 double
00289 GetThumbScale()
00290 {
00291 return mThumbScale;
00292 }
00293
00294
00295
00296 void
00297 SetConcept(String concept)
00298 {
00299 mConcept = concept;
00300 AddConcept(concept);
00301 }
00302
00303 void
00304 SetConcept(int idx)
00305 {
00306 mConcept = mConcepts[idx];
00307 }
00308
00309 String
00310 GetConcept()
00311 {
00312 return mConcept;
00313 }
00314
00315 int
00316 GetConceptIdx()
00317 {
00318 for (int i=0 ; i<mConcepts.size() ; i++)
00319 if (mConcepts[i] == mConcept)
00320 return i;
00321 return -1;
00322 }
00323
00324 bool
00325 HasConcepts()
00326 {
00327 return mConcepts.size() > 0;
00328 }
00329
00330 int
00331 NrConcepts()
00332 {
00333 return mConcepts.size();
00334 }
00335
00336 String
00337 GetConcept(int i)
00338 {
00339 return mConcepts[i];
00340 }
00341
00342 void
00343 AddConcept(String concept)
00344 {
00345 if (concept.empty())
00346 return;
00347 for (int i=0 ; i<mConcepts.size() ; i++)
00348 if (mConcepts[i] == concept)
00349 return;
00350 int j = 2;
00351 mConcepts.push_back(concept);
00352 }
00353
00354 void
00355 LoadConcepts(String fileName)
00356 {
00357 mConcepts.clear();
00358 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00359 Util::DatabaseReadStrings(mConcepts, fileName, mDataSet->GetDatabase());
00360 #else // REPOSITORY_USED
00361 Persistency::KeywordListLocator loc(mDataSet->GetLocator(), fileName);
00362 mConcepts = *(Persistency::KeywordListRepository().Get(loc));
00363 #endif // REPOSITORY_USED
00364 }
00365
00366 void
00367 SaveConcepts(String fileName)
00368 {
00369 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00370 Util::DatabaseWriteString(fileName, mDataSet->GetDatabase(),
00371 mConcepts.begin(), mConcepts.end());
00372 #else // REPOSITORY_USED
00373 Persistency::KeywordListLocator loc(mDataSet->GetLocator(), fileName);
00374 Persistency::KeywordListRepository().Add(loc, &mConcepts);
00375 #endif // REPOSITORY_USED
00376 }
00377
00378
00379
00380 virtual void
00381 Clear()
00382 {
00383 GotoFile(-1);
00384 mRect = Rectangle();
00385 }
00386
00387 protected:
00388
00389 void
00390 GotoFile(int fileId)
00391 {
00392 ILOG_DEBUG("fileId = " << fileId);
00393 mCurFileId = fileId;
00394 }
00395
00396 void
00397 GotoDir(int dirId)
00398 {
00399 if (mDataSet->HasFiles())
00400 GotoFile(mDataSet->GetFirstFileId(dirId));
00401 else
00402 mCurDirId = dirId;
00403 }
00404
00405 void
00406 GotoFileOfDir(int fileIdx, int dirId)
00407 {
00408 int dst = GetFileOfDir(fileIdx, dirId);
00409 if (dst != -1)
00410 GotoFile(dst);
00411 }
00412
00413 bool
00414 GotoPrevFile(bool withinDir = true)
00415 {
00416 return TryFileMove(mCurFileId - 1, withinDir);
00417 }
00418
00419 bool
00420 GotoNextFile(bool withinDir = true)
00421 {
00422 return TryFileMove(mCurFileId + 1, withinDir);
00423 }
00424
00425
00426 int
00427 GetPrevFile(int steps = 1)
00428 {
00429 return GetFileMove(mCurFileId, -1, steps);
00430 }
00431
00432
00433 int
00434 GetNextFile(int steps = 1)
00435 {
00436 return GetFileMove(mCurFileId, 1, steps);
00437 }
00438
00439 bool
00440 GotoPrevDir()
00441 {
00442 return TryDirMove(-1);
00443 }
00444
00445 bool
00446 GotoNextDir()
00447 {
00448 return TryDirMove(1);
00449 }
00450
00451 bool
00452 TryFileMove(int newFile, bool withinDir)
00453 {
00454 if ((newFile < 0) || (newFile >= mDataSet->NrFiles()))
00455 return false;
00456 if (!HasCurFile())
00457 return false;
00458 if (withinDir && (! SameDir(mCurFileId, newFile)))
00459 return false;
00460 GotoFile(newFile);
00461 return true;
00462 }
00463
00464 int
00465 GetFileMove(int oldFile, int dir, int steps)
00466 {
00467 int newFile = oldFile + dir;
00468 if ((newFile < 0) || (newFile >= mDataSet->NrFiles()))
00469 return -1;
00470 if (! SameDir(mCurFileId, newFile))
00471 return -1;
00472 if (--steps <= 0)
00473 return newFile;
00474 return GetFileMove(newFile, dir, steps);
00475 }
00476
00477 bool
00478 TryDirMove(int inc)
00479 {
00480 if (!HasCurFile())
00481 return false;
00482 int subset = mDataSet->GetDirIdOfFile(mCurFileId) + inc;
00483 if ((subset < 0) || (subset >= mDataSet->NrDirs()))
00484 return false;
00485 int newFile = mDataSet->GetFirstFileId(subset);
00486 GotoFile(newFile);
00487 return true;
00488 }
00489
00490 bool
00491 SameDir(int fileId1, int fileId2)
00492 {
00493 return (mDataSet->GetDirIdOfFile(fileId1) ==
00494 mDataSet->GetDirIdOfFile(fileId2));
00495 }
00496
00497 RawDataSet* mDataSet;
00498 int mCurFileId;
00499 int mCurDirId;
00500
00501 Rectangle mRect;
00502 double mThumbScale;
00503
00504 String mConcept;
00505 Core::Table::KeywordList mConcepts;
00506
00507 ILOG_VAR_DEC;
00508 };
00509
00510 ILOG_VAR_INIT(DataDocument, Impala.Core.Database);
00511
00512 }
00513 }
00514 }
00515
00516 #endif