// extract ComicBookInfo metadata // cf. http://code.google.com/p/comicbookinfo/ bool CbxEngineImpl::Visit(const char *path, const char *value, json::DataType type) { if (json::Type_String == type && str::Eq(path, "/ComicBookInfo/1.0/title")) propTitle.Set(str::conv::FromUtf8(value)); else if (json::Type_Number == type && str::Eq(path, "/ComicBookInfo/1.0/publicationYear")) propDate.Set(str::Format(L"%s/%d", propDate ? propDate : L"", atoi(value))); else if (json::Type_Number == type && str::Eq(path, "/ComicBookInfo/1.0/publicationMonth")) propDate.Set(str::Format(L"%d%s", atoi(value), propDate ? propDate : L"")); else if (json::Type_String == type && str::Eq(path, "/appID")) propCreator.Set(str::conv::FromUtf8(value)); else if (json::Type_String == type && str::Eq(path, "/lastModified")) propModDate.Set(str::conv::FromUtf8(value)); else if (json::Type_String == type && str::Eq(path, "/X-summary")) propSummary.Set(str::conv::FromUtf8(value)); else if (str::StartsWith(path, "/ComicBookInfo/1.0/credits[")) { int idx = -1; const char *prop = str::Parse(path, "/ComicBookInfo/1.0/credits[%d]/", &idx); if (prop) { if (json::Type_String == type && str::Eq(prop, "person")) propAuthorTmp.Set(str::conv::FromUtf8(value)); else if (json::Type_Bool == type && str::Eq(prop, "primary") && propAuthorTmp && propAuthors.Find(propAuthorTmp) == -1) { propAuthors.Append(propAuthorTmp.StealData()); } } return true; } // stop parsing once we have all desired information return !propTitle || propAuthors.Count() == 0 || !propCreator || !propDate || str::FindChar(propDate, '/') <= propDate; }
static void ParseCommandLine(WCHAR *cmdLine) { WStrVec argList; ParseCmdLine(cmdLine, argList); #define is_arg(param) str::EqI(arg + 1, TEXT(param)) #define is_arg_with_param(param) (is_arg(param) && i < argList.Count() - 1) // skip the first arg (exe path) for (size_t i = 1; i < argList.Count(); i++) { WCHAR *arg = argList.At(i); if ('-' != *arg && '/' != *arg) continue; if (is_arg("s")) gGlobalData.silent = true; else if (is_arg_with_param("d")) str::ReplacePtr(&gGlobalData.installDir, argList.At(++i)); #ifndef BUILD_UNINSTALLER else if (is_arg("register")) gGlobalData.registerAsDefault = true; else if (is_arg_with_param("opt")) { WCHAR *opts = argList.At(++i); str::ToLower(opts); str::TransChars(opts, L" ;", L",,"); WStrVec optlist; optlist.Split(opts, L",", true); if (optlist.Find(L"plugin") != -1) gGlobalData.installBrowserPlugin = true; if (optlist.Find(L"pdffilter") != -1) gGlobalData.installPdfFilter = true; if (optlist.Find(L"pdfpreviewer") != -1) gGlobalData.installPdfPreviewer = true; } #endif else if (is_arg("h") || is_arg("help") || is_arg("?")) gGlobalData.showUsageAndQuit = true; #ifdef ENABLE_CRASH_TESTING else if (is_arg("crash")) { // will induce crash when 'Install' button is pressed // for testing crash handling gForceCrash = true; } #endif } }
static WCHAR *FormatPdfFileStructure(Doc doc) { ScopedMem<WCHAR> fstruct(doc.GetProperty(Prop_PdfFileStructure)); if (str::IsEmpty(fstruct.Get())) return NULL; WStrVec parts; parts.Split(fstruct, L",", true); WStrVec props; if (parts.Find(L"linearized") != -1) props.Push(str::Dup(_TR("Fast Web View"))); if (parts.Find(L"tagged") != -1) props.Push(str::Dup(_TR("Tagged PDF"))); if (parts.Find(L"PDFX") != -1) props.Push(str::Dup(L"PDF/X (ISO 15930)")); if (parts.Find(L"PDFA1") != -1) props.Push(str::Dup(L"PDF/A (ISO 19005)")); if (parts.Find(L"PDFE1") != -1) props.Push(str::Dup(L"PDF/E (ISO 24517)")); return props.Join(L", "); }
// verify that all registry entries that need to be set in order to associate // Sumatra with .pdf files exist and have the right values bool IsExeAssociatedWithPdfExtension() { // this one doesn't have to exist but if it does, it must be APP_NAME_STR ScopedMem<WCHAR> tmp(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, L"Progid")); if (tmp && !str::Eq(tmp, APP_NAME_STR)) return false; // this one doesn't have to exist but if it does, it must be APP_NAME_STR.exe tmp.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, L"Application")); if (tmp && !str::EqI(tmp, APP_NAME_STR L".exe")) return false; // this one doesn't have to exist but if it does, it must be APP_NAME_STR tmp.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", L"Progid")); if (tmp && !str::Eq(tmp, APP_NAME_STR)) return false; // HKEY_CLASSES_ROOT\.pdf default key must exist and be equal to APP_NAME_STR tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, L".pdf", NULL)); if (!str::Eq(tmp, APP_NAME_STR)) return false; // HKEY_CLASSES_ROOT\SumatraPDF\shell\open default key must be: open tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, APP_NAME_STR L"\\shell", NULL)); if (!str::EqI(tmp, L"open")) return false; // HKEY_CLASSES_ROOT\SumatraPDF\shell\open\command default key must be: "${exe_path}" "%1" tmp.Set(ReadRegStr(HKEY_CLASSES_ROOT, APP_NAME_STR L"\\shell\\open\\command", NULL)); if (!tmp) return false; WStrVec argList; ParseCmdLine(tmp, argList); ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath || !argList.Find(L"%1") || !str::Find(tmp, L"\"%1\"")) return false; return path::IsSame(exePath, argList.At(0)); }
// removes thumbnails that don't belong to any frequently used item in file history void CleanUpThumbnailCache(FileHistory& fileHistory) { ScopedMem<WCHAR> thumbsPath(AppGenDataFilename(THUMBNAILS_DIR_NAME)); if (!thumbsPath) return; ScopedMem<WCHAR> pattern(path::Join(thumbsPath, L"*.png")); WStrVec files; WIN32_FIND_DATA fdata; HANDLE hfind = FindFirstFile(pattern, &fdata); if (INVALID_HANDLE_VALUE == hfind) return; do { if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) files.Append(str::Dup(fdata.cFileName)); } while (FindNextFile(hfind, &fdata)); FindClose(hfind); Vec<DisplayState *> list; fileHistory.GetFrequencyOrder(list); for (size_t i = 0; i < list.Count() && i < FILE_HISTORY_MAX_FREQUENT * 2; i++) { ScopedMem<WCHAR> bmpPath(GetThumbnailPath(list.At(i)->filePath)); if (!bmpPath) continue; int idx = files.Find(path::GetBaseName(bmpPath)); if (idx != -1) { CrashIf(idx < 0 || files.Count() <= (size_t)idx); WCHAR *fileName = files.At(idx); files.RemoveAt(idx); free(fileName); } } for (size_t i = 0; i < files.Count(); i++) { ScopedMem<WCHAR> bmpPath(path::Join(thumbsPath, files.At(i))); file::Delete(bmpPath); } }