00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #include "camtypes.h"
00105
00106 #include <string.h>
00107 #include <io.h>
00108 #include <fcntl.h>
00109 #include <sys\stat.h>
00110 #include "sgscanf.h"
00111
00112
00113
00114
00115
00116
00117
00118
00119 #include "progress.h"
00120
00121 #include "sglib.h"
00122
00123 #include "sgfonts.h"
00124 #include "sglcart.h"
00125 #include "sglfills.h"
00126 #include "sglbase.h"
00127 #include "sgindgen.h"
00128 #include "sgliboil.h"
00129
00130 #include "atminst.h"
00131
00132 #include "camnet.h"
00133 #include "pathnmex.h"
00134
00135 DECLARE_SOURCE("$Revision: 1282 $");
00136
00137 CC_IMPLEMENT_DYNCREATE(Library, ListItem)
00138
00139 #define new CAM_DEBUG_NEW
00140
00141 using namespace InetUtils;
00142
00143
00144 INT32 Library::MaxFieldCacheEntries = 25;
00145
00146
00147 BOOL Library::BackgroundRedraw = TRUE;
00148
00149
00150 BOOL Library::CacheIndexFile = TRUE;
00151
00152
00153 BOOL Library::RemoteIndexes = TRUE;
00154
00155
00156 String_256 Library::RemoteIndexLocation = "";
00157
00158
00159
00160 String_256 Library::URLBase = _T("");
00161
00162
00163
00164 BOOL Library::QuickIndex = TRUE;
00165
00166
00167
00168 Progress *Library::ProgressBar = NULL;
00169
00170
00171 #define FIELDCACHE
00172
00173
00174 #define DONT_REPORT_KNOWN_CLIPART_PROBLEMS
00175
00176
00177 #define SAVEINDEX
00178
00179
00180 String_256 Library::g_ClipartLibraryPath = TEXT("");
00181 String_256 Library::g_WebThemeLibraryPath = TEXT("");
00182 String_256 Library::g_FontLibraryPath = TEXT("");
00183 String_256 Library::g_FillsLibraryPath = TEXT("");
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 Library::Library()
00197 {
00198 ParentGallery = NULL;
00199 ParentGroup = NULL;
00200
00201 Title = NULL;
00202 IndexFile = NULL;
00203 Thumbnails = NULL;
00204 SubLibPath = NULL;
00205 SynonymFile = NULL;
00206
00207 ItemCount = 0;
00208 Type = SGLib_Blank;
00209
00210 FirstLineOffset = LastLineOffset = 0;
00211
00212 for(INT32 i=0; i<3; i++)
00213 {
00214 PreviewX[i] = 64;
00215 PreviewY[i] = 64;
00216 }
00217
00218
00219 #ifdef FIELDCACHE
00220 FieldCache = NULL;
00221 CacheInit(MaxFieldCacheEntries);
00222 #endif
00223
00224
00225
00226 CachedSubIndexBuf = NULL;
00227 CachedBufLength = 0;
00228
00229
00230 IndexDateStamp = 0;
00231
00232
00233 QuickIndexEnabled = FALSE;
00234 QuickIndexFile = NULL;
00235
00236
00237 ProgressBar = NULL;
00238
00239 m_nModified = 0;
00240 m_bIsWebLib = FALSE;
00241 m_lOldIndex = 0;
00242
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 Library::~Library()
00259 {
00260 TRACEUSER( "Richard", _T("~Library called\n"));
00261
00262
00263 if (ParentGallery != NULL)
00264 {
00265 ParentGallery->RemoveLibraryGroup(this);
00266 ParentGallery = NULL;
00267 }
00268
00269 if(Title != NULL)
00270 {
00271 delete Title;
00272 Title = NULL;
00273 }
00274
00275 if(IndexFile != NULL)
00276 {
00277 delete IndexFile;
00278 IndexFile = NULL;
00279 }
00280
00281 if(Thumbnails != NULL)
00282 {
00283 delete Thumbnails;
00284 Thumbnails = NULL;
00285 }
00286
00287 if(SubLibPath != NULL)
00288 {
00289 delete SubLibPath;
00290 SubLibPath = NULL;
00291 }
00292
00293 if(SynonymFile != NULL)
00294 {
00295 delete SynonymFile;
00296 SynonymFile = NULL;
00297 }
00298
00299
00300 #ifdef FIELDCACHE
00301 CacheKill();
00302 #endif
00303
00304
00305 if(CachedSubIndexBuf != NULL)
00306 {
00307 CCFree((void *)CachedSubIndexBuf);
00308 CachedSubIndexBuf = NULL;
00309 }
00310
00311 CachedBufLength = 0;
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 if(QuickIndexFile != NULL)
00325 delete QuickIndexFile;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 BOOL Library::FreeCachedIndexes(void)
00343 {
00344
00345 #ifdef FIELDCACHE
00346 CacheKill();
00347 #endif
00348
00349
00350 if(CachedSubIndexBuf != NULL)
00351 {
00352 CCFree((void *)CachedSubIndexBuf);
00353 CachedSubIndexBuf = NULL;
00354 CachedBufLength = 0;
00355 return TRUE;
00356 }
00357
00358 return FALSE;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 BOOL Library::ReCacheIndexes(void)
00377 {
00378
00379 if(ParentGroup != NULL && ParentGroup->IsVirtualised())
00380 return TRUE;
00381
00382
00383 #ifdef FIELDCACHE
00384 CacheKill();
00385 CacheInit(MaxFieldCacheEntries);
00386 #endif
00387
00388
00389 if(CachedSubIndexBuf == NULL && CacheIndexFile && IndexFile != NULL)
00390 {
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 if(CacheSubIndex(IndexFile))
00401 {
00402
00403 return ScanRestOfFile(CachedSubIndexBuf, FirstLineOffset, CachedBufLength, FALSE);
00404 }
00405 else
00406 {
00407 return FALSE;
00408 }
00409 }
00410
00411 return TRUE;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 BOOL Library::CacheSubIndex(PathName *IndexFile)
00441 {
00442 BOOL OpenedOK = FALSE;
00443
00444
00445 INT32 NewFileSize = 0;
00446
00447 if(QuickIndexEnabled)
00448 NewFileSize = SGLibOil::FileSize(QuickIndexFile);
00449 else
00450 NewFileSize = SGLibOil::FileSize(IndexFile);
00451
00452 if(NewFileSize == 0)
00453 return FALSE;
00454
00455 if(IndexDateStamp != 0 && IndexDateStamp != (UINT32)NewFileSize)
00456 return FALSE;
00457 IndexDateStamp = (UINT32)NewFileSize;
00458
00459 CachedBufLength = NewFileSize;
00460 CachedSubIndexBuf = (TCHAR *)CCMalloc(CachedBufLength + 4);
00461
00462 if(CachedSubIndexBuf != NULL)
00463 {
00464 CCDiskFile TmpDiskFile;
00465 TRY
00466 {
00467 if(QuickIndexEnabled)
00468 OpenedOK = TmpDiskFile.open(*QuickIndexFile, ios::in);
00469 else
00470 OpenedOK = TmpDiskFile.open(*IndexFile, ios::in);
00471
00472 if(!OpenedOK)
00473 {
00474 ERROR3("Couldn't open disk file for mem file");
00475 if(CachedSubIndexBuf != NULL)
00476 CCFree(CachedSubIndexBuf);
00477 CachedSubIndexBuf = NULL;
00478 CachedBufLength = 0;
00479 return FALSE;
00480 }
00481
00482 TmpDiskFile.read(CachedSubIndexBuf, CachedBufLength);
00483 TmpDiskFile.close();
00484 }
00485 CATCH(CFileException, e)
00486 {
00487 if(CachedSubIndexBuf != NULL)
00488 CCFree(CachedSubIndexBuf);
00489 CachedSubIndexBuf = NULL;
00490 CachedBufLength = 0;
00491 if(TmpDiskFile.isOpen())
00492 TmpDiskFile.close();
00493 return FALSE;
00494 }
00495 END_CATCH
00496 }
00497 else
00498 {
00499 CachedBufLength = 0;
00500 ERROR3("Couldn't allocate space for cached subindex file");
00501 return FALSE;
00502 }
00503 return TRUE;
00504
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 INT32 Library::Init(SuperGallery *ParentGal, PathName *Path, String_64 *SLTitle,
00547 StringBase *SubI, SGLibType SLType, BOOL Updated, BOOL AllowedToCreateVirtualised)
00548 {
00549 if(ParentGal == NULL || Path == NULL || SLTitle == NULL || SubI == NULL)
00550 {
00551 ERROR3("Library::Library - NULL parameters are illegal");
00552 return 0;
00553 }
00554
00555
00556
00557
00558 if(ProgressBar != NULL) ProgressBar->Update();
00559
00560
00561 if(!SetUpMembers(ParentGal, Path, SLTitle, SubI, SLType))
00562 return 0;
00563
00564
00565 if(SGLibGroup::LibraryVirtualisingEnabled && ParentGroup == NULL && AllowedToCreateVirtualised)
00566 {
00567 ParentGroup = (SGLibGroup *)ParentGallery->AddLibraryGroup(this, -1);
00568 ParentGroup->SetVirtualisedState(TRUE);
00569 return -1;
00570 }
00571
00572
00573 QuickIndexEnabled = SetupQuickIndexMembers(Path, TRUE);
00574
00575 CCLexFile *SubIndex = NULL;
00576 BOOL CachedSubIndex = FALSE;
00577 BOOL OpenedOK = FALSE;
00578 BOOL Retry = FALSE;
00579
00580
00581 BOOL Quiet = FALSE;
00582 LibraryGallery *LG = NULL;
00583 if(ParentGal->IsKindOf(CC_RUNTIME_CLASS(LibraryGallery)))
00584 LG = (LibraryGallery *)ParentGal;
00585 else
00586 {
00587 ERROR3("Library::Init called with a non-library gallery gallery");
00588 return 0;
00589 }
00590
00591
00592 do
00593 {
00594 Retry = FALSE;
00595
00596
00597 if(CacheIndexFile && !CachedSubIndex)
00598 CachedSubIndex = CacheSubIndex(IndexFile);
00599
00600 TRY
00601 {
00602
00603 SubIndex = new CCDiskFile(1024, FALSE, TRUE);
00604 if(SubIndex != NULL)
00605 {
00606 if(QuickIndexEnabled)
00607 OpenedOK = ((CCDiskFile *)SubIndex)->open(*QuickIndexFile, ios::in);
00608 else
00609 OpenedOK = ((CCDiskFile *)SubIndex)->open(*IndexFile, ios::in);
00610 }
00611 else
00612 {
00613 ERROR3("Library::Init SubIndex not created properly");
00614 return(0);
00615 }
00616 }
00617
00618 if(ProgressBar != NULL) ProgressBar->Update();
00619
00620 CATCH(CFileException, e)
00621 {
00622
00623
00624
00625
00626
00627
00628 if(SubIndex != NULL)
00629 {
00630 INT32 LastButtonPressed = 1;
00631
00632 Quiet = LG->GetQuietStatus();
00633
00634 if(!Quiet)
00635 {
00636 String_256 WarnMsg;
00637
00638 if(!SGLibGroup::LibraryVirtualisingEnabled)
00639 {
00640
00641 WarnMsg.MakeMsg(_R(IDS_LIBRARY_CANT_FIND_INDEX), (const TCHAR *)Path->GetFileName(FALSE));
00642 Error::SetError(0, WarnMsg, 0);
00643 LastButtonPressed = InformWarning(0, _R(IDS_CONTINUE), _R(IDS_RETRY), _R(IDS_QUIET), NULL, 2, 1);
00644 Retry = (LastButtonPressed == 2);
00645 Quiet = (LastButtonPressed == 3);
00646 }
00647 else
00648 {
00649
00650 WarnMsg.MakeMsg(_R(IDS_LIBRARY_CANT_FIND_INDEX_SKIP), (const TCHAR *)Path->GetFileName(FALSE));
00651 Error::SetError(0, WarnMsg, 0);
00652 LastButtonPressed = InformWarning(0, _R(IDS_SKIP), _R(IDS_RETRY), _R(IDS_QUIET), NULL, 2, 1);
00653 Retry = (LastButtonPressed == 2);
00654 Quiet = (LastButtonPressed == 3);
00655 }
00656
00657 LG->SetQuietStatus(Quiet);
00658 }
00659 if (SubIndex->isOpen())
00660 SubIndex->close();
00661 delete SubIndex;
00662 SubIndex = NULL;
00663 }
00664 Error::ClearError();
00665 if(!Retry)
00666 return 0;
00667 }
00668 END_CATCH
00669
00670
00671 if(Quiet && Retry)
00672 Retry = FALSE;
00673 } while(Retry);
00674
00675 if(ProgressBar != NULL) ProgressBar->Update();
00676
00677
00678 if (!SubIndex->InitLexer(TRUE))
00679 {
00680 ERROR3("Library::Init InitLexer failed");
00681 if(SubIndex->isOpen())
00682 SubIndex->close();
00683 delete SubIndex;
00684 return FALSE;
00685 }
00686
00687 SubIndex->SetWhitespace("");
00688 SubIndex->SetDelimiters(",");
00689 SubIndex->SetCommentMarker('#');
00690 SubIndex->SetStringDelimiters("");
00691
00692 if(OpenedOK)
00693 {
00694
00695 INT32 NumItems = ReadHeaderInfo(SubIndex);
00696
00697 if(ProgressBar != NULL) ProgressBar->Update();
00698
00699 if (NumItems > 0)
00700 {
00701
00702 ((LibraryGallery *)ParentGal)->RemoveSimilarLibraryGroups(SubLibPath, (String_256 *)SubI, TRUE, FALSE, this);
00703
00704
00705 ParentGroup = (SGLibGroup *)ParentGallery->AddLibraryGroup(this, NumItems);
00706 ParentGroup->SetVirtualisedState(FALSE);
00707
00708 if (ParentGroup == NULL)
00709 {
00710
00711 SubIndex->DeinitLexer();
00712
00713
00714 if(SubIndex->isOpen())
00715 SubIndex->close();
00716
00717
00718 delete SubIndex;
00719 return FALSE;
00720 }
00721
00722 if(ProgressBar != NULL) ProgressBar->Update();
00723
00724
00725 if(CachedSubIndexBuf == NULL)
00726 ScanRestOfFile(SubIndex);
00727 else
00728 ScanRestOfFile(CachedSubIndexBuf, FirstLineOffset, CachedBufLength);
00729
00730 if(ProgressBar != NULL) ProgressBar->Update();
00731
00732 #ifdef _DEBUG
00733 if(NumItems != ItemCount)
00734 {
00735 String_256 Warn;
00736 PathName Loc(IndexFile->GetLocation(FALSE));
00737 PathName Loc2(Loc.GetLocation(FALSE));
00738 String_256 FNameWarn(Loc2.GetFileName());
00739
00740 BOOL DoWarning = TRUE;
00741
00742 #ifdef DONT_REPORT_KNOWN_CLIPART_PROBLEMS
00743
00744 if((ItemCount == (NumItems - 1)) && FNameWarn == (String_256)"Studio")
00745 DoWarning = FALSE;
00746
00747
00748 if(ItemCount == 50 && NumItems == 48 && FNameWarn == (String_256)"Xara")
00749 DoWarning = FALSE;
00750 if(ItemCount == 329 && NumItems == 330 && FNameWarn == (String_256)"ANIMALS")
00751 DoWarning = FALSE;
00752 if(ItemCount == 470 && NumItems == 474 && FNameWarn == (String_256)"PEOPLE")
00753 DoWarning = FALSE;
00754 #endif
00755 if(DoWarning)
00756 {
00757 ERROR3_PF(("Dodgy checksum for '%s' index file. Header value should read %d.", (TCHAR *)FNameWarn, ItemCount));
00758 }
00759 }
00760 #endif
00761 }
00762 }
00763 else
00764 {
00765
00766 ERROR3("Library::Library couldn't open sub index file");
00767 }
00768
00769 if(ProgressBar != NULL) ProgressBar->Update();
00770
00771
00772 SubIndex->DeinitLexer();
00773
00774
00775 if(SubIndex->isOpen())
00776 SubIndex->close();
00777
00778
00779 delete SubIndex;
00780
00781
00782 Thumbnails = NULL;
00783
00784
00785
00786
00787
00788
00789
00790
00791 String_256 ThuF(IndexFile->GetLocation(FALSE));
00792 LibraryFile::TidyUpSubPath(&ThuF);
00793 SGLibOil::AppendSlashIfNotPresent(&ThuF);
00794
00795 ThuF += String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME));
00796 PathName ThumbPath(ThuF);
00797 if(!ThumbPath.IsValid())
00798 {
00799 ERROR3("Library::Init ThumbPath is invalid");
00800 return 0;
00801 }
00802
00803
00804
00805
00806 Thumbnails = new SGThumbs(&ThumbPath, SLType, SGThumb_Small);
00807
00808 return(ItemCount);
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 INT32 Library::CreateItems(void)
00833 {
00834
00835 if(ParentGroup != NULL && ParentGroup->IsVirtualised())
00836 {
00837 String_256 SubI;
00838 SubI = IndexFile->GetFileName();
00839 PathName pathOldIndex(IndexFile->GetPath());
00840 pathOldIndex.SetType(_T("old"));
00841 INT32 hOldIndex = _open(pathOldIndex.GetPath(), _O_RDONLY | _O_BINARY, _S_IREAD);
00842 if (hOldIndex != -1)
00843 {
00844 m_lOldIndex = _filelength(hOldIndex);
00845 _close(hOldIndex);
00846 }
00847 INT32 ItemCount = Init(ParentGallery, SubLibPath, Title, &SubI, Type);
00848 return ItemCount;
00849 }
00850
00851 return 0;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 BOOL Library::SetUpMembers(SuperGallery *ParentGal, PathName *Path, String_64 *SLTitle,
00876 StringBase *SubI, SGLibType SLType)
00877 {
00878 ERROR3IF(ParentGal == NULL || Path == NULL || SLTitle == NULL || SubI == NULL, "Library::SetUpMembers - NULL parameters are illegal");
00879
00880
00881
00882
00883 ParentGallery = ParentGal;
00884
00885
00886 ItemCount = 0;
00887
00888
00889 FieldString = "";
00890
00891
00892 Type = SLType;
00893
00894
00895
00896 if(Title == NULL)
00897 {
00898 Title = new String_64(*SLTitle);
00899 if (Title == NULL)
00900 return FALSE;
00901 }
00902
00903
00904 String_256 General(Path->GetPath(TRUE));
00905 General += String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME));
00906 General += TEXT("\\");
00907 General += *SubI;
00908
00909
00910
00911 if(IndexFile == NULL)
00912 {
00913 IndexFile = new PathName(General);
00914 if (IndexFile == NULL)
00915 return FALSE;
00916 }
00917
00918 if(!IndexFile->IsValid())
00919 {
00920 ERROR3("Library::SetUpMembers indexfile is invalid");
00921 return FALSE;
00922 }
00923
00924
00925 if(SubLibPath == NULL)
00926 {
00927 SubLibPath = new PathName(*Path);
00928 if(SubLibPath == NULL)
00929 return FALSE;
00930 }
00931
00932 if(!SubLibPath->IsValid())
00933 {
00934 ERROR3("Library::SetUpMembers SubLibPath is invalid");
00935 return FALSE;
00936 }
00937
00938
00939 FirstLineOffset = 0;
00940 LastLineOffset = 0;
00941
00942 return TRUE;
00943 }
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 BOOL Library::SetupQuickIndexMembers(PathName *Path, BOOL CheckTheyExist)
00968 {
00969 QuickIndexEnabled = FALSE;
00970
00971
00972
00973
00974
00975 if(Library::QuickIndex)
00976 {
00977
00978 PathName QuickPath(Path->GetPath());
00979 String_256 QuickPathLoc(QuickPath.GetLocation(FALSE));
00980 QuickPathLoc += TEXT("\\") + String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME)) + TEXT("\\");
00981 QuickPathLoc += Path->GetFileName(FALSE);
00982 QuickPathLoc += TEXT(".txt");
00983 QuickPath.SetPathName(QuickPathLoc);
00984
00985 if(CheckTheyExist && SGLibOil::FileExists(&QuickPath))
00986 {
00987 if(QuickIndexFile == NULL)
00988 {
00989 QuickIndexFile = new PathName(QuickPathLoc);
00990
00991 if(QuickIndexFile != NULL)
00992 QuickIndexEnabled = TRUE;
00993 }
00994 }
00995
00996 Error::ClearError();
00997 }
00998
00999 return QuickIndexEnabled;
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 INT32 Library::ReadHeaderInfo(CCLexFile *pSubIndex)
01024 {
01025 ERROR3IF(pSubIndex == NULL, "Library::ReadHeaderInfo - NULL params are illegal");
01026
01027 BOOL ok = TRUE;
01028 BOOL retok = TRUE;
01029 INT32 Items = 0;
01030
01031 LexTokenType TT = TOKEN_EOL;
01032 UINT32 NonGarbageLineNumber = 0;
01033 BOOL HitStart = FALSE;
01034 while(ok && retok && !HitStart)
01035 {
01036 if (!pSubIndex->GetToken()) break;
01037
01038
01039
01040 TT = pSubIndex->GetTokenType();
01041
01042 while (TT != TOKEN_NORMAL && ok)
01043 {
01044
01045 if(TT == TOKEN_COMMENT)
01046 {
01047
01048 if(camStrchr((TCHAR *) pSubIndex->GetTokenBuf(), _T(':')))
01049 {
01050
01051 String_256 TokenBufU(pSubIndex->GetTokenBuf());
01052 TokenBufU.toUpper();
01053
01054 INT32 Offset = TokenBufU.Sub(String_16(_R(IDS_LIBRARIES_INDEX_DESCRITION)));
01055
01056 if(Offset > -1 && Offset < 2)
01057 {
01058
01059 if(Title)
01060 {
01061 String_256 TokenBuf(pSubIndex->GetTokenBuf());
01062 TokenBuf.Right(Title, TokenBuf.Length() - (12 + Offset));
01063 LibraryFile::KillLeadingSpaces(Title);
01064 }
01065 }
01066 }
01067 }
01068
01069 ok = pSubIndex->GetToken();
01070 if(!ok) break;
01071 TT = pSubIndex->GetTokenType();
01072 ok = (TT != TOKEN_EOF);
01073 if(!ok) break;
01074 }
01075 if(!ok) break;
01076
01077 NonGarbageLineNumber++;
01078
01079 switch(NonGarbageLineNumber)
01080 {
01081 case 0:
01082 ERROR3("Library ReadHeader - Something nasty has happened");
01083 break;
01084
01085 case 1:
01086 Items = _ttoi(pSubIndex->GetTokenBuf());
01087 break;
01088
01089 case 2:
01090 {
01091 String_256 KPS;
01092 KPS = SubLibPath->GetPath(TRUE);
01093 KPS += String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME));
01094 KPS += TEXT("\\") + String_64(pSubIndex->GetTokenBuf());
01095 SynonymFile = new PathName(KPS);
01096
01097
01098 if(SynonymFile == NULL)
01099 {
01100 ERROR3("Library::ReadHeaderInfo not enough memory to create a SynonymFile path");
01101 break;
01102 }
01103
01104 if(!SynonymFile->IsValid())
01105 {
01106 ERROR3("Library::ReadHeaderInfo SynonymFile is invalid");
01107 break;
01108 }
01109 }
01110 break;
01111
01112 case 3:
01113 {
01114 for(INT32 i = 0; i < 3; i++)
01115 {
01116 PreviewX[i] = _ttoi((TCHAR *)pSubIndex->GetTokenBuf());
01117
01118 ok = pSubIndex->GetToken();
01119 if(!ok) break;
01120 TT = pSubIndex->GetTokenType();
01121 if(TT == TOKEN_EOL) break;
01122
01123 ok = pSubIndex->GetToken();
01124 if(!ok) break;
01125 TT = pSubIndex->GetTokenType();
01126 if(TT == TOKEN_EOL) break;
01127
01128 PreviewY[i] = _ttoi((TCHAR *)pSubIndex->GetTokenBuf());
01129
01130 ok = pSubIndex->GetToken();
01131 if(!ok) break;
01132 TT = pSubIndex->GetTokenType();
01133 if(TT == TOKEN_EOL) break;
01134
01135 ok = pSubIndex->GetToken();
01136 if(!ok) break;
01137 TT = pSubIndex->GetTokenType();
01138 if(TT == TOKEN_EOL) break;
01139
01140 }
01141 }
01142 break;
01143
01144 case 4:
01145 FieldString = pSubIndex->GetTokenBuf();
01146
01147
01148 ok = pSubIndex->GetLineToken();
01149 if(!ok) break;
01150
01151 TT = pSubIndex->GetTokenType();
01152 if(TT == TOKEN_LINE)
01153 FieldString += pSubIndex->GetTokenBuf();
01154 else
01155 {
01156 retok = FALSE;
01157 ERROR3("Library ReadHeader: Field line appears to be shorter than expected");
01158 }
01159
01160 break;
01161
01162
01163
01164 default:
01165
01166
01167 if(camStrchr((TCHAR *) pSubIndex->GetTokenBuf(), _T(':')))
01168 {
01169
01170 String_256 TokenBufU(pSubIndex->GetTokenBuf());
01171 TokenBufU.toUpper();
01172
01173
01174 INT32 Offset = TokenBufU.Sub(String_16(_R(IDS_LIBRARIES_INDEX_DESCRITION)));
01175 if(Offset > -1 && Offset < 2)
01176 {
01177
01178 if(Title)
01179 {
01180 String_256 TokenBuf(pSubIndex->GetTokenBuf());
01181 TokenBuf.Right(Title, TokenBuf.Length() - (12 + Offset));
01182 LibraryFile::KillLeadingSpaces(Title);
01183 }
01184 }
01185
01186
01187 Offset = TokenBufU.Sub(String_16(_R(IDS_LIBRARIES_INDEX_FILES)));
01188 if(Offset == 0)
01189 {
01190 TRACEUSER( "Richard", _T("Remote files in use\n"));
01191
01192
01193 if(!SubLibPath)
01194 SubLibPath = new PathName;
01195
01196 if(SubLibPath != NULL)
01197 {
01198 PathName OldPath(*SubLibPath);
01199 String_256 ThePath;
01200 String_256 TokenBuf(pSubIndex->GetTokenBuf());
01201 TokenBuf.Right(&ThePath, TokenBuf.Length() - (6 + Offset));
01202 LibraryFile::KillLeadingSpaces(&ThePath);
01203
01204 SubLibPath->SetPathName(ThePath);
01205 if(!SubLibPath->IsValid())
01206 {
01207 *SubLibPath = OldPath;
01208 }
01209 }
01210 }
01211 }
01212
01213
01214
01215 if(!camStrcmp((TCHAR *) pSubIndex->GetTokenBuf(), (TCHAR *)(String_16(_R(IDS_LIBRARIES_INDEX_START)))))
01216 {
01217
01218 do {
01219 ok = pSubIndex->GetToken();
01220 if(!ok) break;
01221 TT = pSubIndex->GetTokenType();
01222 } while (TT != TOKEN_EOF && TT != TOKEN_EOL && ok);
01223
01224
01225
01226 HitStart = TRUE;
01227 }
01228 break;
01229 }
01230
01231 if(!ok) break;
01232
01233
01234 TT = pSubIndex->GetTokenType();
01235
01236 while (TT != TOKEN_EOF && TT != TOKEN_EOL && TT != TOKEN_LINE && TT != TOKEN_COMMENT && ok)
01237 {
01238 ok = pSubIndex->GetToken();
01239 if(!ok) break;
01240 TT = pSubIndex->GetTokenType();
01241 ok = (TT != TOKEN_EOF);
01242 if(!ok) break;
01243 }
01244 }
01245
01246
01247 FirstLineOffset = (LibraryIndex) pSubIndex->tellIn();
01248
01249
01250 if(TT == TOKEN_EOF)
01251 return(0);
01252
01253 if (retok)
01254 return(Items);
01255
01256 return(0);
01257 }
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286 BOOL Library::ScanRestOfFile(TCHAR *CachedIndex, INT32 Start, INT32 Finish, BOOL AddItems)
01287 {
01288 if(CachedIndex == NULL)
01289 {
01290 ERROR3("Library::ScanRestOfFile - no cached index");
01291 return FALSE;
01292 }
01293
01294 if(Start >= Finish)
01295 {
01296 ERROR3("Library::ScanRestOfFile - nothing to scan");
01297 return FALSE;
01298 }
01299
01300 INT32 Offset = Start;
01301 INT32 NewItemOffset = 0;
01302
01303 INT32 LineCount = 0;
01304 ItemCount = 0;
01305
01306 TCHAR Ch = ' ';
01307 TCHAR NCh = ' ';
01308
01309
01310 const TCHAR CR = '\n';
01311 const TCHAR LF = '\r';
01312 const TCHAR REM = '#';
01313 const TCHAR SEP = ',';
01314 const TCHAR SPC = ' ';
01315
01316 #ifdef _DEBUG
01317
01318 INT32 CommaCount = 0;
01319 INT32 FieldCommaCount = 0;
01320 TCHAR *Buf = (TCHAR *)FieldString;
01321 INT32 Len = FieldString.Length();
01322 for(INT32 i = 0; i < Len; i++)
01323 if(Buf[i] == SEP)
01324 FieldCommaCount ++;
01325 #endif
01326
01327 BOOL ok = TRUE;
01328
01329 do {
01330
01331
01332 #ifdef _DEBUG
01333 CommaCount=0;
01334 #endif
01335
01336 Ch = CachedIndex[Offset];
01337 if((Ch == REM) || (Ch == CR) || (Ch == LF) || (Ch == SPC) || (Ch == SEP))
01338 NewItemOffset = 0;
01339 else
01340 NewItemOffset = Offset;
01341
01342
01343 do {
01344 Ch = CachedIndex[Offset];
01345
01346 #ifdef _DEBUG
01347
01348 if(Ch == SEP)
01349 CommaCount ++;
01350 #endif
01351
01352
01353 if(Ch == SEP || Ch == LF || Ch == CR)
01354 CachedIndex[Offset] = 0;
01355
01356 Offset ++;
01357
01358 } while ( (Offset < Finish) && (Ch != CR) && (Ch != LF));
01359
01360
01361 #ifdef _DEBUG
01362 if(CommaCount != FieldCommaCount && CommaCount != 0)
01363 {
01364 String_256 WarnMsg;
01365 String_32 Line;
01366
01367
01368 for(INT32 i=0; i<16; i++)
01369 ((TCHAR *)Line)[i] = *(CachedIndex + NewItemOffset + (i * sizeof(TCHAR)));
01370 ((TCHAR *)Line)[i] = 0;
01371
01372 BOOL DoCommaWarning = TRUE;
01373
01374 #ifdef DONT_REPORT_KNOWN_CLIPART_PROBLEMS
01375
01376 if(NewItemOffset == 4205 && Start == 154 && Finish == 4271 && Offset == 4242 && CommaCount == 4 && FieldCommaCount == 5)
01377 DoCommaWarning = FALSE;
01378 if(NewItemOffset == 4243 && Start == 154 && Finish == 4271 && Offset == 4270 && CommaCount == 4 && FieldCommaCount == 5)
01379 DoCommaWarning = FALSE;
01380 #endif
01381
01382 if(DoCommaWarning)
01383 {
01384 if(CommaCount > FieldCommaCount)
01385 wsprintf(WarnMsg, "Too many commas in line '%s' of '%s'", (TCHAR *)Line, (const TCHAR *)SubLibPath->GetPath());
01386 else
01387 wsprintf(WarnMsg, "Not enough commas in line '%s' of '%s'", (TCHAR *)Line, (const TCHAR *)SubLibPath->GetPath());
01388 ERROR3(WarnMsg);
01389 }
01390 }
01391 #endif
01392
01393
01394
01395
01396 if(NewItemOffset != 0)
01397 {
01398
01399
01400 if(AddItems)
01401 {
01402 BOOL bIsNew = (m_lOldIndex != 0 && NewItemOffset >= m_lOldIndex) || (m_nModified == FOLDER_NEW);
01403 ok = (ParentGallery->AddLibraryItem(ParentGroup, this, NewItemOffset, bIsNew) != NULL);
01404 }
01405
01406 if(ok)
01407 {
01408 ItemCount ++;
01409 LineCount ++;
01410 }
01411 }
01412
01413 NCh = CachedIndex[Offset];
01414
01415
01416 if ( ((Ch==LF) || (Ch==CR)) && ((NCh==LF) || (NCh==CR)) && (Offset < Finish) )
01417 Offset ++;
01418
01419 } while(Offset < Finish);
01420
01421 return (ItemCount > 0);
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443 BOOL Library::ScanRestOfFile(CCLexFile *pSubIndex)
01444 {
01445 ERROR3IF(pSubIndex == NULL, "Library::ScanRestOfFile - NULL params are illegal");
01446
01447 BOOL ok = TRUE;
01448 BOOL retok = TRUE;
01449
01450 LexTokenType TT;
01451 UINT32 LineCount = 0;
01452 ItemCount = 0;
01453 LibraryIndex LineOffset = 0;
01454
01455
01456 FirstLineOffset = (LibraryIndex) pSubIndex->tellIn();
01457
01458 while(ok && retok)
01459 {
01460
01461 LineOffset = (LibraryIndex) pSubIndex->tellIn();
01462
01463 if(!pSubIndex->GetToken()) break;
01464
01465
01466
01467
01468 TT = pSubIndex->GetTokenType();
01469 while (TT != TOKEN_NORMAL && ok)
01470 {
01471
01472 LineOffset = (LibraryIndex) pSubIndex->tellIn();
01473
01474 ok = pSubIndex->GetToken();
01475 if(!ok) break;
01476 TT = pSubIndex->GetTokenType();
01477 ok = (TT != TOKEN_EOF);
01478 if(!ok) break;
01479 }
01480 if(!ok) break;
01481
01482
01483
01484
01485 ok = (ParentGallery->AddLibraryItem(ParentGroup, this, LineOffset) != NULL);
01486
01487 if(ok) ItemCount ++;
01488 else break;
01489
01490
01491 TT = pSubIndex->GetTokenType();
01492
01493 while (TT != TOKEN_EOF && TT != TOKEN_EOL && TT != TOKEN_LINE && ok)
01494 {
01495
01496 LineOffset = (LibraryIndex) pSubIndex->tellIn();
01497
01498 ok = pSubIndex->GetToken();
01499 if(!ok) break;
01500 TT = pSubIndex->GetTokenType();
01501 ok = (TT != TOKEN_EOF);
01502 if(!ok) break;
01503 }
01504 }
01505
01506
01507 LastLineOffset = (LibraryIndex) pSubIndex->tellIn();
01508
01509 return (ItemCount > 0);
01510 }
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 void Library::GetLibraryTitle(StringBase *ReturnedTitle)
01530 {
01531 ERROR3IF(ReturnedTitle == NULL, "Library::GetLIbraryTitle - NULL Params are illegal");
01532
01533 if (Title == NULL)
01534 *ReturnedTitle = String_16(_R(IDS_LIBRARIES_UNAMED));
01535 else
01536 *ReturnedTitle = *Title;
01537 }
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 BOOL Library::GetFilename(LibraryIndex Offset, StringBase *File, BOOL FullPath)
01564 {
01565 ERROR3IF(File == NULL, "Library::GetFilename - NULL params are illegal");
01566
01567 if(!FullPath)
01568 {
01569
01570 return (GetSingleField(Offset, 1, File));
01571 }
01572
01573 String_256 Filename;
01574
01575
01576 if (!GetSingleField(Offset, 1, &Filename))
01577 return FALSE;
01578
01579
01580 *File = SubLibPath->GetPath(TRUE);
01581 *File += Filename;
01582
01583 return TRUE;
01584 }
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606 BOOL Library::GetFilename(LibraryIndex Offset, TCHAR **File)
01607 {
01608 ERROR3IF(File == NULL, "Library::GetFilename - NULL params are illegal");
01609
01610
01611 return (GetSingleField(Offset, 1, File));
01612 }
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 BOOL Library::GetTextname(LibraryIndex Offset, StringBase *Text)
01630 {
01631 ERROR3IF(Text == NULL, "Library::GetTextname - NULL params are illegal");
01632 return(GetSingleField(Offset, 2, Text));
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 BOOL Library::GetTextname(LibraryIndex Offset, TCHAR **Text)
01650 {
01651 ERROR3IF(Text == NULL, "Library::GetTextname - NULL params are illegal");
01652 return(GetSingleField(Offset, 2, Text));
01653 }
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671 UINT32 Library::GetID(LibraryIndex Offset)
01672 {
01673 String_8 Tmp;
01674 if (!GetSingleField(Offset, 3, &Tmp))
01675 return(0);
01676
01677 return((UINT32) _ttoi((TCHAR *)Tmp));
01678 }
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697 BOOL Library::GetTitle(LibraryIndex Offset, StringBase *Title)
01698 {
01699 ERROR3IF(Title == NULL, "Library::GetTitle - NULL params are illegal");
01700
01701 String_64 Tmp(_R(IDS_LIBRARIES_INDEX_ITEM_TITLE));
01702 if(!GotField(&Tmp))
01703 return FALSE;
01704
01705
01706 BOOL ok = GetSingleField(Offset, &Tmp, Title);
01707
01708
01709
01710
01711 if(Title->Length() == 0)
01712 ok = FALSE;
01713
01714 return ok;
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736 BOOL Library::GetTitle(LibraryIndex Offset, TCHAR **Title)
01737 {
01738 ERROR3IF(Title == NULL, "Library::GetFilename - NULL params are illegal");
01739
01740 String_64 Tmp(_R(IDS_LIBRARIES_INDEX_ITEM_TITLE));
01741 if(!GotField(&Tmp))
01742 return FALSE;
01743
01744
01745 BOOL ok = GetSingleField(Offset, &Tmp, Title);
01746
01747
01748
01749 if(camStrlen(*Title) == 0)
01750 ok = FALSE;
01751
01752 return ok;
01753 }
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778 BOOL Library::GetThumbnail(LibraryIndex Offset, SGThumbSize Size, BOOL Urgent,
01779 KernelBitmap **Thumbnail)
01780 {
01781 if (Thumbnails == NULL)
01782 return FALSE;
01783
01784 UINT32 ID = GetID(Offset);
01785 Thumbnails->SetSize(Size);
01786
01787
01788 PathName ActualFile;
01789 PathName *pActualFile = &ActualFile;
01790 String_256 TheFile;
01791
01792 if(!GetFilename(Offset, &TheFile, TRUE))
01793 pActualFile = NULL;
01794 else
01795 ActualFile.SetPathName(TheFile);
01796
01797 return(Thumbnails->GetThumbnail(ID, Urgent, Thumbnail, pActualFile));
01798 }
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813 void Library::KillAllThumbnails(void)
01814 {
01815 if (Thumbnails != NULL)
01816 Thumbnails->DeleteThumbnails();
01817 }
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842 BOOL Library::LocalPath2URL(String_256* pLocalPath)
01843 {
01844
01845
01846
01847
01848
01849
01850 String_256 strLocalPath(*pLocalPath);
01851 String_256 strURL(_T("http://xara.xaraonline.com/XaraX2/Resources/"));
01852 if (strURL.Length() == 0)
01853 {
01854 ERROR3("URL base string is empty");
01855 return FALSE;
01856 }
01857 String_256 strWebFilesDir(GetStringField(Type, _R(IDS_CACHEDIR)));
01858 strWebFilesDir += _T("\\");
01859 strLocalPath.toLower();
01860 strWebFilesDir.toLower();
01861 strURL += camStrstr((TCHAR*) strLocalPath, (TCHAR*) strWebFilesDir + String_256(_R(IDS_CACHEPATH)).Length());
01862 strURL.toLower();
01863
01864 TCHAR* pBackSlash = NULL;
01865 while (pBackSlash = camStrchr((TCHAR*) strURL, _T('\\')))
01866 *pBackSlash = _T('/');
01867
01868 WCHAR wchURL[INTERNET_MAX_PATH_LENGTH];
01869 MultiByteToWideChar(CP_ACP, 0, (TCHAR*) strURL, -1, wchURL, INTERNET_MAX_PATH_LENGTH);
01870 BOOL bIsValid = (IsValidURL(NULL, wchURL, 0) == S_OK) ? TRUE : FALSE;
01871 if (bIsValid)
01872 {
01873 *pLocalPath = strURL;
01874 return TRUE;
01875 }
01876 else
01877 {
01878 ERROR3("Conversion resulted in an invalid URL");
01879 return FALSE;
01880 }
01881 }
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 BOOL Library::GetSingleField(LibraryIndex Offset, UINT32 Count, StringBase *Field)
01906 {
01907 ERROR3IF(Field == NULL, "Library::GetSingleField - NULL Params are illegal");
01908
01909 #ifdef FIELDCACHE
01910
01911 if(CacheGet(Offset, Count, Field))
01912 return TRUE;
01913 #endif
01914
01915
01916 BOOL GotField = FALSE;
01917
01918
01919 if(CachedSubIndexBuf != NULL)
01920 {
01921 GotField = GetSingleFieldFromMemory(Offset, Count, Field);
01922 }
01923
01924
01925 if(!GotField)
01926 {
01927 GotField = GetSingleFieldFromDisk(Offset, Count, Field);
01928 }
01929
01930
01931 if(!GotField)
01932 *Field = TEXT("");
01933 #ifdef FIELDCACHE
01934 else
01935 {
01936
01937 LibraryFile::KillLeadingSpaces(Field);
01938 CachePut(Offset, Count, Field);
01939 }
01940 #endif
01941
01942 return GotField;
01943 }
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 BOOL Library::GetSingleField(LibraryIndex Offset, UINT32 Count, TCHAR **Field)
01970 {
01971 ERROR3IF(Field == NULL, "Library::GetSingleField - NULL Params are illegal");
01972
01973
01974 BOOL GotField = FALSE;
01975
01976
01977 if(CachedSubIndexBuf != NULL)
01978 {
01979
01980 GotField = GetSingleFieldFromMemory(Offset, Count, Field);
01981 }
01982
01983 return GotField;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009 BOOL Library::GetSingleFieldFromMemory(LibraryIndex Offset, UINT32 Count, StringBase *Field)
02010 {
02011 ERROR3IF(Field == NULL, "Library::GetSingleField - NULL Params are illegal");
02012 ERROR3IF(Offset > CachedBufLength, "Library::GetSingleField - given out of range offset");
02013 ERROR3IF(CachedSubIndexBuf == NULL, "Library::GetSingleField - called with null index buffer");
02014
02015 #if 0
02016
02017 TCHAR *Start = CachedSubIndexBuf + Offset;
02018 TCHAR *Finish = CachedSubIndexBuf + CachedBufLength;
02019
02020 if(Count == 1)
02021 {
02022 *Field = Start;
02023 return TRUE;
02024 }
02025 else
02026 {
02027
02028 const TCHAR SPC = ' ';
02029
02030 TCHAR Ch = *Start;
02031 UINT32 FieldCount = 1;
02032
02033
02034 while(Count > FieldCount && Start < Finish)
02035 {
02036 if(Ch == 0)
02037 FieldCount ++;
02038 Start += sizeof(TCHAR);
02039 Ch = *Start;
02040 }
02041
02042 if(Count == FieldCount)
02043 {
02044
02045 Ch = *Start;
02046 while(Ch == SPC && Ch != 0 && Start < Finish)
02047 {
02048 Start += sizeof(TCHAR);
02049 Ch = *Start;
02050 }
02051
02052
02053 *Field = Start;
02054 return TRUE;
02055 }
02056 else
02057 return FALSE;
02058 }
02059
02060 return FALSE;
02061 #endif
02062
02063 TCHAR *Fld;
02064 BOOL ok = GetSingleFieldFromMemory(Offset, Count, &Fld);
02065 *Field = Fld;
02066
02067 return ok;
02068 }
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 BOOL Library::GetSingleFieldFromMemory(LibraryIndex Offset, UINT32 Count, TCHAR **Field)
02091 {
02092 ERROR3IF(Field == NULL, "Library::GetSingleField - NULL Params are illegal");
02093 ERROR3IF(Offset > CachedBufLength, "Library::GetSingleField - given out of range offset");
02094 ERROR3IF(CachedSubIndexBuf == NULL, "Library::GetSingleField - called with null index buffer");
02095
02096
02097 TCHAR *Start = CachedSubIndexBuf + Offset;
02098 TCHAR *Finish = CachedSubIndexBuf + CachedBufLength;
02099
02100 if(Count == 1)
02101 {
02102 *Field = Start;
02103 return TRUE;
02104 }
02105 else
02106 {
02107
02108 const TCHAR SPC = ' ';
02109
02110 TCHAR Ch = *Start;
02111 UINT32 FieldCount = 1;
02112
02113
02114 while(Count > FieldCount && Start < Finish)
02115 {
02116 if(Ch == 0) FieldCount ++;
02117 Start += sizeof(TCHAR);
02118 Ch = *Start;
02119 }
02120
02121 if(Count == FieldCount)
02122 {
02123
02124 Ch = *Start;
02125 while(Ch == SPC && Ch != 0 && Start < Finish)
02126 {
02127 Start += sizeof(TCHAR);
02128 Ch = *Start;
02129 }
02130
02131
02132 *Field = Start;
02133 return TRUE;
02134 }
02135 else
02136 return FALSE;
02137 }
02138
02139 return FALSE;
02140 }
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161 BOOL Library::GetSingleFieldFromDisk(LibraryIndex Offset, UINT32 Count, StringBase *Field)
02162 {
02163 ERROR3IF(Field == NULL, "Library::GetSingleField - NULL Params are illegal");
02164
02165 BOOL ok = TRUE;
02166 BOOL OpenedOK = TRUE;
02167 CCLexFile *SubIndex = NULL;
02168
02169
02170 SubIndex = new CCDiskFile;
02171
02172
02173 if(SubIndex != NULL)
02174 OpenedOK = ((CCDiskFile *)SubIndex)->open(*IndexFile, ios::in);
02175
02176 if(SubIndex == NULL)
02177 {
02178 ERROR3("Library::Init Disk SubIndex not created properly");
02179 return FALSE;
02180 }
02181
02182 if(!OpenedOK)
02183 {
02184 ERROR3("Library::Init Disk SubIndex not opened properly");
02185 delete SubIndex;
02186 return FALSE;
02187 }
02188
02189
02190 if (!SubIndex->InitLexer(TRUE))
02191 {
02192 ERROR3("Library::GetSingleField InitLexer failed");
02193 if(SubIndex->isOpen())
02194 SubIndex->close();
02195 delete SubIndex;
02196 return FALSE;
02197 }
02198
02199 SubIndex->SetWhitespace("");
02200 SubIndex->SetDelimiters(",");
02201 SubIndex->SetCommentMarker('#');
02202 SubIndex->SetStringDelimiters("");
02203
02204 SubIndex->seekIn(Offset);
02205
02206 String_256 Token;
02207 LexTokenType TT = TOKEN_EOL;
02208
02209 LibraryIndex FOffset;
02210 ok = SubIndex->GetToken();
02211 TT = SubIndex->GetTokenType();
02212
02213 FOffset = (LibraryIndex) SubIndex->tellIn();
02214
02215 if(FOffset != Offset)
02216 ERROR3("Lexer didn't seek properly");
02217
02218 while(Offset > FOffset && ok && TT != EOF)
02219 {
02220 ok = SubIndex->GetToken();
02221 FOffset = (LibraryIndex) SubIndex->tellIn();
02222 TT = SubIndex->GetTokenType();
02223 if (TT == TOKEN_EOF) ok = FALSE;
02224 }
02225
02226 if(!ok)
02227 {
02228 ERROR3("Library::GetSingleField Line past end of file");
02229
02230
02231 if(SubIndex->isOpen())
02232 SubIndex->close();
02233 delete SubIndex;
02234
02235 return FALSE;
02236 }
02237
02238
02239
02240 while(ok && TT != TOKEN_NORMAL)
02241 {
02242 ok = SubIndex->GetToken();
02243
02244 if (ok)
02245 {
02246 TT = SubIndex->GetTokenType();
02247 if (TT == TOKEN_EOF)
02248 ok = FALSE;
02249 }
02250 }
02251
02252 if (ok)
02253 {
02254 UINT32 i = 1;
02255
02256
02257 while(Count > i && ok)
02258 {
02259 Token = SubIndex->GetTokenBuf();
02260 LibraryFile::KillLeadingSpaces(&Token);
02261
02262 if (Token == String_8(",") )
02263 i++;
02264
02265 ok = SubIndex->GetToken();
02266 }
02267
02268
02269 if (ok)
02270 {
02271 Token = SubIndex->GetTokenBuf();
02272 LibraryFile::KillLeadingSpaces(&Token);
02273
02274 if (Token == String_8(",") )
02275 *Field = TEXT("");
02276 else
02277 *Field = Token;
02278 }
02279 }
02280
02281
02282 SubIndex->DeinitLexer();
02283
02284
02285 if(SubIndex->isOpen())
02286 SubIndex->close();
02287
02288
02289 delete SubIndex;
02290
02291 return ok;
02292 }
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321 BOOL Library::GetSingleField(LibraryIndex Offset, String_64 *FieldName, StringBase *Field)
02322 {
02323 ERROR3IF(FieldName == NULL || Field == NULL, "Library::GetSingleField given nulls");
02324
02325 if(!GotField(FieldName))
02326 {
02327 *Field = TEXT("");
02328 return FALSE;
02329 }
02330
02331 INT32 Count = FindField(FieldName);
02332
02333 return (Count > 0 && GetSingleField(Offset, Count, Field));
02334 }
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363 BOOL Library::GetSingleField(LibraryIndex Offset, String_64 *FieldName, TCHAR **Field)
02364 {
02365 ERROR3IF(FieldName == NULL || Field == NULL, "Library::GetSingleField given nulls");
02366
02367 if(!GotField(FieldName))
02368 return FALSE;
02369
02370 INT32 Count = FindField(FieldName);
02371
02372 return (Count > 0 && GetSingleField(Offset, Count, Field));
02373 }
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390 INT32 Library::FindField(String_64 *FieldName)
02391 {
02392 ERROR3IF(FieldName == NULL, "Library::FindField given nulls");
02393
02394 INT32 Pos = FieldString.Sub(*FieldName);
02395
02396 if(Pos != -1)
02397 {
02398
02399 String_256 Left;
02400 FieldString.Left(&Left, Pos);
02401 const TCHAR BrkChar = ',';
02402
02403
02404 INT32 Count = 0;
02405 TCHAR *Buf = (TCHAR *)Left;
02406 INT32 Len = Left.Length();
02407 for(INT32 i = 0; i < Len; i++)
02408 if(Buf[i] == BrkChar)
02409 Count ++;
02410
02411
02412 Count ++;
02413
02414 return Count;
02415 }
02416
02417 return 0;
02418 }
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436 BOOL Library::GotField(String_64 *FieldName)
02437 {
02438 return (FieldString.Sub(*FieldName) != -1);
02439 }
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459 BOOL Library::CacheInit(INT32 Entries)
02460 {
02461 if(Entries == 0)
02462 FieldCache = NULL;
02463 else
02464 if(FieldCache == NULL)
02465 FieldCache = (SGFieldCache *)CCMalloc(sizeof(SGFieldCache) * Entries);
02466
02467 if(FieldCache == NULL)
02468 {
02469 FieldCacheEntries = 0;
02470 ERROR3("Library::CacheInit - Not enough memory for a field cache - reduce the Fields in the ini file");
02471 return FALSE;
02472 }
02473 else
02474 {
02475 FieldCacheEntries = Entries;
02476
02477 SGFieldCache Dummy;
02478 Dummy.Offset = 0;
02479 Dummy.Count = 0;
02480 Dummy.Field = NULL;
02481
02482 for(INT32 i=0; i<Entries; i++)
02483 {
02484 FieldCache[i] = Dummy;
02485 }
02486 }
02487 return TRUE;
02488 }
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506 BOOL Library::CacheKill(void)
02507 {
02508 TRACEUSER( "Richard", _T("Cache Kill\n"));
02509
02510 if(FieldCache != NULL)
02511 {
02512 for(INT32 i=0; i<FieldCacheEntries; i++)
02513 {
02514 if(FieldCache[i].Field != NULL)
02515 {
02516 CCFree(FieldCache[i].Field);
02517 FieldCache[i].Field = NULL;
02518 }
02519 }
02520 FieldCacheEntries = 0;
02521
02522 CCFree(FieldCache);
02523 FieldCache = NULL;
02524 }
02525
02526 return TRUE;
02527 }
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550 INT32 Library::CacheHashFunction(LibraryIndex Offset, UINT32 Count)
02551 {
02552 return ((Count + Offset) % FieldCacheEntries);
02553 }
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572 BOOL Library::CachePut(LibraryIndex Offset, UINT32 Count, StringBase *Field)
02573 {
02574 TRACEUSER( "Richard", _T("Cache Put\n"));
02575
02576
02577 if(FieldCache != NULL)
02578 {
02579 SGFieldCache OurEntry;
02580 OurEntry.Offset = Offset;
02581 OurEntry.Count = Count;
02582 OurEntry.Field = (TCHAR *)CCMalloc((Field->Length()+1) * sizeof(TCHAR));
02583 if(OurEntry.Field == NULL)
02584 {
02585 ERROR3("Library::GetSingleField can't allocate enough string space in field buffer");
02586 return FALSE;
02587 }
02588 else
02589 {
02590 camStrcpy(OurEntry.Field, (TCHAR *)*Field);
02591 }
02592
02593 SGFieldCache *plc = &FieldCache[CacheHashFunction(Offset, Count)];
02594
02595 if(plc->Field != NULL)
02596 {
02597 CCFree(plc->Field);
02598 plc->Field = NULL;
02599
02600 }
02601
02602 *plc = OurEntry;
02603
02604 return TRUE;
02605 }
02606 return FALSE;
02607 }
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625 BOOL Library::CacheGet(LibraryIndex Offset, UINT32 Count, StringBase *Field)
02626 {
02627 #if 0
02628
02629 if(FieldCache != NULL)
02630 {
02631 INT32 Occupancy = 0;
02632 for(INT32 i=0; i<FieldCacheEntries; i++)
02633 {
02634 if(FieldCache[i].Field != NULL) Occupancy++;
02635 }
02636 TRACEUSER( "Richard", _T("Hash usage %d out of %d - %d%%\n"), Occupancy, FieldCacheEntries, (100 * Occupancy / FieldCacheEntries));
02637 }
02638 #endif
02639
02640
02641 SGFieldCache OurEntry;
02642 if(FieldCache != NULL)
02643 {
02644 OurEntry = FieldCache[CacheHashFunction(Offset, Count)];
02645
02646 if(OurEntry.Offset == Offset && OurEntry.Count == Count && OurEntry.Field != NULL)
02647 {
02648 String_256 tmpstr(OurEntry.Field);
02649 *Field = tmpstr;
02650 return TRUE;
02651 }
02652 }
02653
02654
02655
02656 return FALSE;
02657 }
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677 BOOL Library::SaveIndexInDisplayedOrder(PathName *IndexPathName, BOOL NewIDs)
02678 {
02679 #ifdef SAVEINDEX
02680
02681 CCDiskFile *IndexPath = new CCDiskFile(1024, TRUE, FALSE);
02682 ERROR2IF(IndexPath == NULL, FALSE, "Null index file allocated");
02683
02684 if(!IndexPath->open(*IndexPathName, ios::out))
02685 {
02686 ERROR3("Can't create new index file");
02687 delete IndexPath;
02688 return FALSE;
02689 }
02690
02691
02692 IndexPath->write(CachedSubIndexBuf, (UINT32)FirstLineOffset);
02693
02694
02695 BOOL ok = TRUE;
02696
02697
02698 INT32 Count = 0;
02699
02700 SGDisplayNode *Item = ParentGroup;
02701
02702
02703 if(Item != NULL)
02704 Item = Item->GetChild();
02705
02706
02707 while (Item != NULL)
02708 {
02709 if(Item->IsKindOf(CC_RUNTIME_CLASS(SGLibDisplayItem)))
02710 {
02711 Count++;
02712
02713 SGLibDisplayItem *LibItem = (SGLibDisplayItem *) Item;
02714
02715 LibraryIndex Offset = LibItem->GetDisplayedLibraryIndex();
02716 String_64 Field;
02717
02718 TCHAR FieldStringBuffer[256];
02719 TCHAR *FieldStringDone = (TCHAR *)FieldStringBuffer;
02720 camStrcpy(FieldStringDone, (TCHAR *)FieldString);
02721
02722 BOOL MoreFields = TRUE;
02723
02724
02725 while(MoreFields)
02726 {
02727
02728
02729 TCHAR *Comma = camStrchr(FieldStringDone, _T(','));
02730 if(Comma != NULL)
02731 *Comma = 0;
02732 else
02733 MoreFields = FALSE;
02734
02735
02736 while(FieldStringDone[0] == ' ')
02737 FieldStringDone += sizeof(TCHAR);
02738
02739
02740 String_64 FieldStringToUse(FieldStringDone);
02741
02742 if(NewIDs && (FieldStringToUse == String_64(_R(IDS_LIBRARIES_INDEX_ITEM_ID))))
02743 wsprintf(Field, "%d", Count);
02744 else
02745 ok = GetSingleField(Offset, &FieldStringToUse, &Field);
02746
02747 ERROR3IF(!ok, "Problems getting a field");
02748
02749
02750 IndexPath->write((TCHAR *)Field, (UINT32)Field.Length() * sizeof(TCHAR));
02751
02752
02753 if(Comma != NULL)
02754 {
02755 IndexPath->write((TCHAR *)",", sizeof(TCHAR) * 1);
02756 FieldStringDone += ((camStrlen(FieldStringDone)+1) * sizeof(TCHAR));
02757 }
02758 else
02759 IndexPath->write((TCHAR *)"\r\n", sizeof(TCHAR) * 2);
02760 }
02761 }
02762
02763 Item = Item->GetNext();
02764 }
02765
02766
02767 IndexPath->close();
02768 delete IndexPath;
02769
02770 ERROR3IF(Count != ItemCount, "Wrong number of items in group -> bad !");
02771
02772 return TRUE;
02773 #endif
02774 return FALSE;
02775 }
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796 BOOL Library::InitLibPrefs(void)
02797 {
02798
02799 static BOOL AlreadyCalled = FALSE;
02800 if(AlreadyCalled) return FALSE;
02801 AlreadyCalled = TRUE;
02802
02803 #ifndef EXCLUDE_GALS
02804
02805 GetApplication()->DeclareSection(TEXT("Libraries"), 12);
02806
02807
02808 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("ClipArt"), &LibClipartSGallery::ClipartPath);
02809 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("WebTheme"), &LibClipartSGallery::WebThemePath);
02810
02811 #ifndef STANDALONE
02812
02813
02814 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Font"), &FontsSGallery::DefaultLibraryPath);
02815
02816 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Texture"), &LibFillsSGallery::DefaultLibraryPath);
02817 #endif
02818
02819
02820 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("ClipartDisplayMode"), &LibClipartSGallery::DefaultDisplayMode, 0, 2);
02821 #ifndef STANDALONE
02822
02823
02824 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("FontDisplayMode"), &FontsSGallery::DefaultDisplayMode, 0, 4);
02825
02826 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("FillDisplayMode"), &LibFillsSGallery::DefaultDisplayMode, 0, 2);
02827 #endif //WEBSTER
02828
02829 #ifdef _DEBUG
02830
02831 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("CacheIndexFiles"), &Library::CacheIndexFile, 0, 1);
02832 #endif
02833
02834
02835 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("BackgroundRedraw"), &Library::BackgroundRedraw, 0, 1);
02836
02837
02838 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Thumbnails"), &SGThumbs::MaxThumbnails, 1, 100);
02839
02840
02841 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("FieldCache"), &Library::MaxFieldCacheEntries, 1, 1000);
02842
02843
02844 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("UseOldIndexesWhenCreating"), &GenerateIndexFile::UseOldIndexes, 0, 1);
02845
02846
02847 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("UseDocCommentsWhenCreating"), &GenerateIndexFile::UseDocComments, 0, 1);
02848
02849
02850 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("AskAboutRemoving"), &LibraryGallery::AskAboutRemoving, 0, 1);
02851
02852
02853 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("RemoteIndexes"), &Library::RemoteIndexes, 0, 1);
02854
02855
02856 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("RemoteIndexLocation"), &Library::RemoteIndexLocation);
02857
02858
02859 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Enhancements"), &LibClipartSGallery::DoSounds);
02860
02861
02862 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Explorer"), &SGLibOil::UseExplorerForAdd);
02863
02864
02865 #ifdef _DEBUG
02866 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("QuickIndexes"), &Library::QuickIndex, 0, 1);
02867 #endif
02868
02869
02870 GetApplication()->DeclarePref(TEXT("Libraries"), TEXT("Virtualising"), &SGLibGroup::LibraryVirtualisingEnabled, 0, 1);
02871
02872
02873
02874 #ifndef STANDALONE
02875
02876 GetApplication()->DeclareSection(TEXT("FontGallery"), 3);
02877
02878
02879 GetApplication()->DeclarePref(TEXT("FontGallery"), TEXT("LargeInstalledDisplayString"), &FontsSGallery::LargeDisplayString);
02880
02881
02882 GetApplication()->DeclarePref(TEXT("FontGallery"), TEXT("DeleteFilesOnDeinstall"), &FontsSGallery::DeleteTTFandFOTfiles, 0, 1);
02883
02884
02885 GetApplication()->DeclarePref(TEXT("FontGallery"), TEXT("DisableATMAliases"), &ATMInstall::DisableATMAliases, 0, 1);
02886 #endif \\STANDALONE
02887
02888 #endif
02889 return TRUE;
02890 }
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906 BOOL Library::CacheLibPrefs(void)
02907 {
02908
02909
02910
02911 Camelot.GetPrefDirect(TEXT("Libraries"), TEXT("ClipArt"), &g_ClipartLibraryPath);
02912 Camelot.GetPrefDirect(TEXT("Libraries"), TEXT("WebTheme"), &g_WebThemeLibraryPath);
02913 Camelot.GetPrefDirect(TEXT("Libraries"), TEXT("Font"), &g_FontLibraryPath);
02914 Camelot.GetPrefDirect(TEXT("Libraries"), TEXT("Texture"), &g_FillsLibraryPath);
02915
02916
02917
02918
02919
02920 return TRUE;
02921 }
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937 BOOL Library::RestoreLibPrefs(void)
02938 {
02939
02940
02941 const TCHAR * pClipPath = g_ClipartLibraryPath;
02942 const TCHAR * pWebPath = g_WebThemeLibraryPath;
02943 const TCHAR * pFontPath = g_FontLibraryPath;
02944 const TCHAR * pFillsPath = g_FillsLibraryPath;
02945
02946
02947 if (!g_ClipartLibraryPath.IsEmpty())
02948 Camelot.SetPrefDirect(TEXT("Libraries"), TEXT("ClipArt"), pClipPath);
02949 if (!g_WebThemeLibraryPath.IsEmpty())
02950 Camelot.SetPrefDirect(TEXT("Libraries"), TEXT("WebTheme"), pWebPath);
02951 if (!g_FontLibraryPath.IsEmpty())
02952 Camelot.SetPrefDirect(TEXT("Libraries"), TEXT("Font"), pFontPath);
02953 if (!g_FillsLibraryPath.IsEmpty())
02954 Camelot.SetPrefDirect(TEXT("Libraries"), TEXT("Texture"), pFillsPath);
02955
02956
02957
02958
02959
02960 return TRUE;
02961 }