static void StrVecTest() { StrVec v; v.Append(str::Dup(_T("foo"))); v.Append(str::Dup(_T("bar"))); TCHAR *s = v.Join(); assert(v.Count() == 2); assert(str::Eq(_T("foobar"), s)); free(s); s = v.Join(_T(";")); assert(v.Count() == 2); assert(str::Eq(_T("foo;bar"), s)); free(s); v.Append(str::Dup(_T("glee"))); s = v.Join(_T("_ _")); assert(v.Count() == 3); assert(str::Eq(_T("foo_ _bar_ _glee"), s)); free(s); v.Sort(); s = v.Join(); assert(str::Eq(_T("barfooglee"), s)); free(s); { StrVec v2(v); assert(str::Eq(v2.At(1), _T("foo"))); v2.Append(str::Dup(_T("nobar"))); assert(str::Eq(v2.At(3), _T("nobar"))); v2 = v; assert(v2.Count() == 3 && v2.At(0) != v.At(0)); assert(str::Eq(v2.At(1), _T("foo"))); assert(&v2.At(2) == v2.AtPtr(2) && str::Eq(*v2.AtPtr(2), _T("glee"))); } { StrVec v2; size_t count = v2.Split(_T("a,b,,c,"), _T(",")); assert(count == 5 && v2.Find(_T("c")) == 3); assert(v2.Find(_T("")) == 2 && v2.Find(_T(""), 3) == 4 && v2.Find(_T(""), 5) == -1); assert(v2.Find(_T("B")) == -1 && v2.FindI(_T("B")) == 1); ScopedMem<TCHAR> joined(v2.Join(_T(";"))); assert(str::Eq(joined, _T("a;b;;c;"))); } { StrVec v2; size_t count = v2.Split(_T("a,b,,c,"), _T(","), true); assert(count == 3 && v2.Find(_T("c")) == 2); ScopedMem<TCHAR> joined(v2.Join(_T(";"))); assert(str::Eq(joined, _T("a;b;c"))); ScopedMem<TCHAR> last(v2.Pop()); assert(v2.Count() == 2 && str::Eq(last, _T("c"))); } }
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!"); } }
void CopySelectionToClipboard(WindowInfo *win) { if (!win->selectionOnPage) return; CrashIf(win->selectionOnPage->Count() == 0); if (win->selectionOnPage->Count() == 0) return; CrashIf(!win->dm || !win->dm->engine); if (!win->dm || !win->dm->engine) return; if (!OpenClipboard(NULL)) return; EmptyClipboard(); if (!win->dm->engine->IsCopyingTextAllowed()) ShowNotification(win, _TR("Copying text was denied (copying as image only)")); else if (!win->dm->engine->IsImageCollection()) { ScopedMem<TCHAR> selText; bool isTextSelection = win->dm->textSelection->result.len > 0; if (isTextSelection) { selText.Set(win->dm->textSelection->ExtractText(_T("\r\n"))); } else { StrVec selections; for (size_t i = 0; i < win->selectionOnPage->Count(); i++) { SelectionOnPage *selOnPage = &win->selectionOnPage->At(i); TCHAR *text = win->dm->GetTextInRegion(selOnPage->pageNo, selOnPage->rect); if (text) selections.Push(text); } selText.Set(selections.Join()); } // don't copy empty text if (!str::IsEmpty(selText.Get())) CopyTextToClipboard(selText, true); if (isTextSelection) { // don't also copy the first line of a text selection as an image CloseClipboard(); return; } } /* also copy a screenshot of the current selection to the clipboard */ SelectionOnPage *selOnPage = &win->selectionOnPage->At(0); RenderedBitmap * bmp = win->dm->engine->RenderBitmap(selOnPage->pageNo, win->dm->ZoomReal(), win->dm->Rotation(), &selOnPage->rect, Target_Export); if (bmp) CopyImageToClipboard(bmp->GetBitmap(), true); delete bmp; CloseClipboard(); }
TCHAR *CbxEngineImpl::GetProperty(DocumentProperty prop) { switch (prop) { case Prop_Title: return propTitle ? str::Dup(propTitle) : NULL; case Prop_Author: return propAuthors.Count() ? propAuthors.Join(_T(", ")) : NULL; case Prop_CreationDate: return propDate ? str::Dup(propDate) : NULL; case Prop_ModificationDate: return propModDate ? str::Dup(propModDate) : NULL; case Prop_CreatorApp: return propCreator ? str::Dup(propCreator) : NULL; // TODO: replace with Prop_Summary case Prop_Subject: return propSummary ? str::Dup(propSummary) : NULL; default: return NULL; } }