static void LaunchWithSumatra(InstanceData *data, const char *url_utf8) { if (!file::Exists(data->filepath)) plogf("sp: NPP_StreamAsFile() error: file doesn't exist"); ScopedMem<TCHAR> url(str::conv::FromUtf8(url_utf8)); // escape quotation marks and backslashes for CmdLineParser.cpp's ParseQuoted if (str::FindChar(url, '"')) { StrVec parts; parts.Split(url, _T("\"")); url.Set(parts.Join(_T("%22"))); } if (str::EndsWith(url, _T("\\"))) { url[str::Len(url) - 1] = '\0'; url.Set(str::Join(url, _T("%5c"))); } ScopedMem<TCHAR> cmdLine(str::Format(_T("\"%s\" -plugin \"%s\" %d \"%s\""), data->exepath, url ? url : _T(""), (HWND)data->npwin->window, data->filepath)); data->hProcess = LaunchProcess(cmdLine); if (!data->hProcess) { plogf("sp: NPP_StreamAsFile() error: couldn't run SumatraPDF!"); data->message = _T("Error: Couldn't run SumatraPDF!"); } }
static bool SetupPluginMode(CommandLineInfo& i) { if (!IsWindow(i.hwndPluginParent) || i.fileNames.Count() == 0) return false; gPluginURL = i.pluginURL; if (!gPluginURL) gPluginURL = i.fileNames.At(0); assert(i.fileNames.Count() == 1); while (i.fileNames.Count() > 1) { free(i.fileNames.Pop()); } i.reuseInstance = i.exitOnPrint = false; // always display the toolbar when embedded (as there's no menubar in that case) gGlobalPrefs.toolbarVisible = true; // never allow esc as a shortcut to quit gGlobalPrefs.escToExit = false; // never show the sidebar by default gGlobalPrefs.tocVisible = false; if (DM_AUTOMATIC == gGlobalPrefs.defaultDisplayMode) { // if the user hasn't changed the default display mode, // display documents as single page/continuous/fit width // (similar to Adobe Reader, Google Chrome and how browsers display HTML) gGlobalPrefs.defaultDisplayMode = DM_CONTINUOUS; gGlobalPrefs.defaultZoom = ZOOM_FIT_WIDTH; } // extract some command line arguments from the URL's hash fragment where available // see http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf#nameddest=G4.1501531 if (i.pluginURL && str::FindChar(i.pluginURL, '#')) { ScopedMem<TCHAR> args(str::Dup(str::FindChar(i.pluginURL, '#') + 1)); str::TransChars(args, _T("#"), _T("&")); StrVec parts; parts.Split(args, _T("&"), true); for (size_t k = 0; k < parts.Count(); k++) { TCHAR *part = parts.At(k); int pageNo; if (str::StartsWithI(part, _T("page=")) && str::Parse(part + 4, _T("=%d%$"), &pageNo)) i.pageNumber = pageNo; else if (str::StartsWithI(part, _T("nameddest=")) && part[10]) str::ReplacePtr(&i.destName, part + 10); else if (!str::FindChar(part, '=') && part[0]) str::ReplacePtr(&i.destName, part); } } return true; }
// parses a list of page ranges such as 1,3-5,7- (i..e all but pages 2 and 6) // into an interable list (returns NULL on parsing errors) // caller must delete the result static bool ParsePageRanges(const TCHAR *ranges, Vec<PageRange>& result) { if (!ranges) return false; StrVec rangeList; rangeList.Split(ranges, _T(","), true); rangeList.SortNatural(); for (size_t i = 0; i < rangeList.Count(); i++) { int start, end; if (str::Parse(rangeList.At(i), _T("%d-%d%$"), &start, &end) && 0 < start && start <= end) result.Append(PageRange(start, end)); else if (str::Parse(rangeList.At(i), _T("%d-%$"), &start) && 0 < start) result.Append(PageRange(start, INT_MAX)); else if (str::Parse(rangeList.At(i), _T("%d%$"), &start) && 0 < start) result.Append(PageRange(start, start)); else return false; } return result.Count() > 0; }