Ejemplo n.º 1
0
 void CreateThumbnail(HtmlWindow *hw) {
     this->hw = hw;
     homeUrl.Set(str::conv::FromAnsi(doc->GetHomePath()));
     if (*homeUrl == '/')
         homeUrl.Set(str::Dup(homeUrl + 1));
     hw->NavigateToDataUrl(homeUrl);
 }
DocTocItem *MobiEngineImpl::GetTocTree()
{
    if (!tocReparsePoint)
        return NULL;

    EbookTocItem *root = NULL;
    ScopedMem<WCHAR> itemText;
    ScopedMem<WCHAR> itemLink;
    int itemLevel = 0;
    int idCounter = 0;

    // there doesn't seem to be a standard for Mobi ToCs, so we try to
    // determine the author's intentions by looking at commonly used tags
    HtmlPullParser parser(tocReparsePoint, str::Len(tocReparsePoint));
    HtmlToken *tok;
    while ((tok = parser.Next()) && !tok->IsError()) {
        if (itemLink && tok->IsText()) {
            ScopedMem<WCHAR> linkText(str::conv::FromHtmlUtf8(tok->s, tok->sLen));
            if (itemText)
                itemText.Set(str::Join(itemText, L" ", linkText));
            else
                itemText.Set(linkText.StealData());
        }
        else if (!tok->IsTag())
            continue;
        else if (Tag_Mbp_Pagebreak == tok->tag)
            break;
        else if (!itemLink && tok->IsStartTag() && Tag_A == tok->tag) {
            AttrInfo *attr = tok->GetAttrByName("filepos");
            if (!attr)
                attr = tok->GetAttrByName("href");
            if (attr)
                itemLink.Set(str::conv::FromHtmlUtf8(attr->val, attr->valLen));
        }
        else if (itemLink && tok->IsEndTag() && Tag_A == tok->tag) {
            PageDestination *dest = NULL;
            if (!itemText) {
                itemLink.Set(NULL);
                continue;
            }
            if (IsExternalUrl(itemLink))
                dest = new SimpleDest2(0, RectD(), itemLink.StealData());
            else
                dest = GetNamedDest(itemLink);
            EbookTocItem *item = new EbookTocItem(itemText.StealData(), dest);
            item->id = ++idCounter;
            item->open = itemLevel <= 2;
            AppendTocItem(root, item, itemLevel);
            itemLink.Set(NULL);
        }
        else if (Tag_Blockquote == tok->tag || Tag_Ul == tok->tag || Tag_Ol == tok->tag) {
            if (tok->IsStartTag())
                itemLevel++;
            else if (tok->IsEndTag() && itemLevel > 0)
                itemLevel--;
        }
    }

    return root;
}
Ejemplo n.º 3
0
bool ViewWithAcrobat(WindowInfo *win, const WCHAR *args)
{
    if (!CanViewWithAcrobat(win))
        return false;

    ScopedMem<WCHAR> exePath(GetAcrobatPath());
    if (!exePath)
        return false;

    if (!args)
        args = L"";

    ScopedMem<WCHAR> params;
    // Command line format for version 6 and later:
    //   /A "page=%d&zoom=%.1f,%d,%d&..." <filename>
    // see http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf#page=5
    //   /P <filename>
    // see http://www.adobe.com/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24
    // TODO: Also set zoom factor and scroll to current position?
    if (win->IsDocLoaded() && HIWORD(GetFileVersion(exePath)) >= 6)
        params.Set(str::Format(L"/A \"page=%d\" %s \"%s\"", win->ctrl->CurrentPageNo(), args, win->ctrl->FilePath()));
    else
        params.Set(str::Format(L"%s \"%s\"", args, win->loadedFilePath));

    return LaunchFile(exePath, params);
}
Ejemplo n.º 4
0
/* Caller needs to free() the result. */
WCHAR *AppGenDataFilename(WCHAR *fileName)
{
    ScopedMem<WCHAR> path;
    if (IsRunningInPortableMode()) {
        /* Use the same path as the binary */
        ScopedMem<WCHAR> exePath(GetExePath());
        if (exePath)
            path.Set(path::GetDir(exePath));
    } else {
        /* Use %APPDATA% */
        WCHAR dir[MAX_PATH];
        dir[0] = '\0';
        BOOL ok = SHGetSpecialFolderPath(NULL, dir, CSIDL_APPDATA, TRUE);
        if (ok) {
            path.Set(path::Join(dir, APP_NAME_STR));
            if (path && !dir::Create(path))
                path.Set(NULL);
        }
    }

    if (!path || !fileName)
        return NULL;

    return path::Join(path, fileName);
}
Ejemplo n.º 5
0
static void SetupCrashHandler()
{
    ScopedMem<WCHAR> symDir;
    ScopedMem<WCHAR> tmpDir(path::GetTempPath());
    if (tmpDir)
        symDir.Set(path::Join(tmpDir, L"SumatraPDF-symbols"));
    else
        symDir.Set(AppGenDataFilename(L"SumatraPDF-symbols"));
    ScopedMem<WCHAR> crashDumpPath(AppGenDataFilename(CRASH_DUMP_FILE_NAME));
    InstallCrashHandler(crashDumpPath, symDir);
}
Ejemplo n.º 6
0
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();

#ifndef DISABLE_DOCUMENT_RESTRICTIONS
    if (!win->dm->engine->AllowsCopyingText())
        ShowNotification(win, _TR("Copying text was denied (copying as image only)"));
    else
#endif
    if (!win->dm->engine->IsImageCollection()) {
        ScopedMem<WCHAR> selText;
        bool isTextSelection = win->dm->textSelection->result.len > 0;
        if (isTextSelection) {
            selText.Set(win->dm->textSelection->ExtractText(L"\r\n"));
        }
        else {
            WStrVec selections;
            for (size_t i = 0; i < win->selectionOnPage->Count(); i++) {
                SelectionOnPage *selOnPage = &win->selectionOnPage->At(i);
                WCHAR *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();
}
Ejemplo n.º 7
0
// Find a record corresponding to the given source file, line number and optionally column number.
// (at the moment the column parameter is ignored)
//
// If there are several *consecutively declared* records for the same line then they are all returned.
// The list of records is added to the vector 'records'
//
// If there is no record for that line, the record corresponding to the nearest line is selected
// (within a range of EPSILON_LINE)
//
// The function returns PDFSYNCERR_SUCCESS if a matching record was found.
UINT Pdfsync::SourceToRecord(const WCHAR* srcfilename, UINT line, UINT col, Vec<size_t> &records)
{
    if (!srcfilename)
        return PDFSYNCERR_INVALID_ARGUMENT;

    ScopedMem<WCHAR> srcfilepath;
    // convert the source file to an absolute path
    if (PathIsRelative(srcfilename))
        srcfilepath.Set(PrependDir(srcfilename));
    else
        srcfilepath.Set(str::Dup(srcfilename));
    if (!srcfilepath)
        return PDFSYNCERR_OUTOFMEMORY;

    // find the source file entry
    size_t isrc;
    for (isrc = 0; isrc < srcfiles.Count(); isrc++)
        if (path::IsSame(srcfilepath, srcfiles.At(isrc)))
            break;
    if (isrc == srcfiles.Count())
        return PDFSYNCERR_UNKNOWN_SOURCEFILE;

    if (fileIndex.At(isrc).start == fileIndex.At(isrc).end)
        return PDFSYNCERR_NORECORD_IN_SOURCEFILE; // there is not any record declaration for that particular source file

    // look for sections belonging to the specified file
    // starting with the first section that is declared within the scope of the file.
    UINT min_distance = EPSILON_LINE; // distance to the closest record
    size_t lineIx = (size_t)-1; // closest record-line index

    for (size_t isec = fileIndex.At(isrc).start; isec < fileIndex.At(isrc).end; isec++) {
        // does this section belong to the desired file?
        if (lines.At(isec).file != isrc)
            continue;

        UINT d = abs((int)lines.At(isec).line - (int)line);
        if (d < min_distance) {
            min_distance = d;
            lineIx = isec;
            if (0 == d)
                break; // We have found a record for the requested line!
        }
    }
    if (lineIx == (size_t)-1)
        return PDFSYNCERR_NORECORD_FOR_THATLINE;

    // we read all the consecutive records until we reach a record belonging to another line
    for (size_t i = lineIx; i < lines.Count() && lines.At(i).line == lines.At(lineIx).line; i++)
        records.Push(lines.At(i).record);

    return PDFSYNCERR_SUCCESS;
}
Ejemplo n.º 8
0
// Detect TeX editors installed on the system and construct the
// corresponding inverse search commands.
//
// Parameters:
//      hwndCombo   -- (optional) handle to a combo list that will be filled with the list of possible inverse search commands.
// Returns:
//      the inverse search command of the first detected editor (the caller needs to free() the result).
WCHAR *AutoDetectInverseSearchCommands(HWND hwndCombo)
{
    WCHAR *firstEditor = NULL;
    WStrList foundExes;

    for (int i = 0; i < dimof(editor_rules); i++) {
        ScopedMem<WCHAR> path(ReadRegStr(editor_rules[i].RegRoot, editor_rules[i].RegKey, editor_rules[i].RegValue));
        if (!path)
            continue;

        ScopedMem<WCHAR> exePath;
        if (editor_rules[i].Type == SiblingPath) {
            // remove file part
            ScopedMem<WCHAR> dir(path::GetDir(path));
            exePath.Set(path::Join(dir, editor_rules[i].BinaryFilename));
        }
        else if (editor_rules[i].Type == BinaryDir)
            exePath.Set(path::Join(path, editor_rules[i].BinaryFilename));
        else // if (editor_rules[i].Type == BinaryPath)
            exePath.Set(path.StealData());
        // don't show duplicate entries
        if (foundExes.FindI(exePath) != -1)
            continue;
        // don't show inexistent paths (and don't try again for them)
        if (!file::Exists(exePath)) {
            foundExes.Append(exePath.StealData());
            continue;
        }

        ScopedMem<WCHAR> editorCmd(str::Format(L"\"%s\" %s", exePath, editor_rules[i].InverseSearchArgs));

        if (!hwndCombo) {
            // no need to fill a combo box: return immeditately after finding an editor.
            return editorCmd.StealData();
        }

        ComboBox_AddString(hwndCombo, editorCmd);
        if (!firstEditor)
            firstEditor = editorCmd.StealData();
        foundExes.Append(exePath.StealData());
    }

    // Fall back to notepad as a default handler
    if (!firstEditor) {
        firstEditor = str::Dup(L"notepad %f");
        if (hwndCombo)
            ComboBox_AddString(hwndCombo, firstEditor);
    }
    return firstEditor;
}
Ejemplo n.º 9
0
WCHAR *ChmDoc::GetProperty(DocumentProperty prop)
{
    ScopedMem<WCHAR> result;
    if (Prop_Title == prop && title)
        result.Set(ToStr(title));
    else if (Prop_CreatorApp == prop && creator)
        result.Set(ToStr(creator));
    // TODO: shouldn't it be up to the front-end to normalize whitespace?
    if (result) {
        // TODO: original code called str::RemoveChars(result, "\n\r\t")
        str::NormalizeWS(result);
    }
    return result.StealData();
}
Ejemplo n.º 10
0
void RenderDocument(BaseEngine *engine, const WCHAR *renderPath)
{
    for (int pageNo = 1; pageNo <= engine->PageCount(); pageNo++) {
        RenderedBitmap *bmp = engine->RenderBitmap(pageNo, 1.0, 0);
        size_t len = 0;
        ScopedMem<unsigned char> data;
        if (bmp && str::EndsWithI(renderPath, L".bmp"))
            data.Set(SerializeBitmap(bmp->GetBitmap(), &len));
        else if (bmp)
            data.Set(tga::SerializeBitmap(bmp->GetBitmap(), &len));
        ScopedMem<WCHAR> pageBmpPath(str::Format(renderPath, pageNo));
        file::WriteAll(pageBmpPath, data, len);
        delete bmp;
    }
}
Ejemplo n.º 11
0
// Show the result of a PDF forward-search synchronization (initiated by a DDE command)
void ShowForwardSearchResult(WindowInfo *win, const WCHAR *fileName, UINT line, UINT col, UINT ret, UINT page, Vec<RectI> &rects)
{
    win->fwdSearchMark.rects.Reset();
    const PageInfo *pi = win->dm->GetPageInfo(page);
    if ((ret == PDFSYNCERR_SUCCESS) && (rects.Count() > 0) && (NULL != pi)) {
        // remember the position of the search result for drawing the rect later on
        win->fwdSearchMark.rects = rects;
        win->fwdSearchMark.page = page;
        win->fwdSearchMark.show = true;
        win->fwdSearchMark.hideStep = 0;
        if (!gUserPrefs->forwardSearch.highlightPermanent)
            SetTimer(win->hwndCanvas, HIDE_FWDSRCHMARK_TIMER_ID, HIDE_FWDSRCHMARK_DELAY_IN_MS, NULL);

        // Scroll to show the overall highlighted zone
        int pageNo = page;
        RectI overallrc = rects.At(0);
        for (size_t i = 1; i < rects.Count(); i++)
            overallrc = overallrc.Union(rects.At(i));
        TextSel res = { 1, &pageNo, &overallrc };
        if (!win->dm->PageVisible(page))
            win->dm->GoToPage(page, 0, true);
        if (!win->dm->ShowResultRectToScreen(&res))
            win->RepaintAsync();
        if (IsIconic(win->hwndFrame))
            ShowWindowAsync(win->hwndFrame, SW_RESTORE);
        return;
    }

    ScopedMem<WCHAR> buf;
    if (ret == PDFSYNCERR_SYNCFILE_NOTFOUND)
        ShowNotification(win, _TR("No synchronization file found"));
    else if (ret == PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED)
        ShowNotification(win, _TR("Synchronization file cannot be opened"));
    else if (ret == PDFSYNCERR_INVALID_PAGE_NUMBER)
        buf.Set(str::Format(_TR("Page number %u inexistant"), page));
    else if (ret == PDFSYNCERR_NO_SYNC_AT_LOCATION)
        ShowNotification(win, _TR("No synchronization info at this position"));
    else if (ret == PDFSYNCERR_UNKNOWN_SOURCEFILE)
        buf.Set(str::Format(_TR("Unknown source file (%s)"), fileName));
    else if (ret == PDFSYNCERR_NORECORD_IN_SOURCEFILE)
        buf.Set(str::Format(_TR("Source file %s has no synchronization point"), fileName));
    else if (ret == PDFSYNCERR_NORECORD_FOR_THATLINE)
        buf.Set(str::Format(_TR("No result found around line %u in file %s"), line, fileName));
    else if (ret == PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD)
        buf.Set(str::Format(_TR("No result found around line %u in file %s"), line, fileName));
    if (buf)
        ShowNotification(win, buf);
}
Ejemplo n.º 12
0
static bool ExtractSignature(const char *hexSignature, const void *data, size_t& dataLen, ScopedMem<BYTE>& signature, size_t& signatureLen)
{
    // verify hexSignature format - must be either
    // * a string starting with "sha1:" followed by the signature (and optionally whitespace and further content)
    // * NULL, then the signature must be found on the last line of non-binary data, starting at " Signature sha1:"
    if (str::StartsWith(hexSignature, "sha1:"))
        hexSignature += 5;
    else if (!hexSignature) {
        if (dataLen < 20 || memchr(data, 0, dataLen))
            return false;
        const char *lastLine = (const char *)data + dataLen - 1;
        while (lastLine > data && *(lastLine - 1) != '\n')
            lastLine--;
        if (lastLine == data || !str::Find(lastLine, " Signature sha1:"))
            return false;
        dataLen = lastLine - (const char *)data;
        hexSignature = str::Find(lastLine, " Signature sha1:") + 16;
    }
    else
        return false;

    str::Str<BYTE> signatureBytes;
    for (const char *c = hexSignature; *c && !str::IsWs(*c); c += 2) {
        int val;
        if (1 != sscanf_s(c, "%02x", &val))
            return false;
        signatureBytes.Append((BYTE)val);
    }
    signatureLen = signatureBytes.Size();
    signature.Set(signatureBytes.StealData());
    return true;
}
Ejemplo n.º 13
0
static void AppendFavMenuItems(HMENU m, DisplayState *f, UINT& idx, bool combined, bool isCurrent)
{
    for (size_t i = 0; i < f->favorites->Count(); i++) {
        if (i >= MAX_FAV_MENUS)
            return;
        Favorite *fn = f->favorites->At(i);
        fn->menuId = idx++;
        ScopedMem<WCHAR> s;
        if (combined)
            s.Set(FavCompactReadableName(f, fn, isCurrent));
        else
            s.Set(FavReadableName(fn));
        s.Set(win::menu::ToSafeString(s));
        AppendMenu(m, MF_STRING, (UINT_PTR)fn->menuId, s);
    }
}
Ejemplo n.º 14
0
void AddFavorite(WindowInfo *win)
{
    int pageNo = win->currPageNo;
    ScopedMem<WCHAR> name;
    if (win->dm->HasTocTree()) {
        // use the current ToC heading as default name
        DocTocItem *root = win->dm->engine->GetTocTree();
        DocTocItem *item = TocItemForPageNo(root, pageNo);
        if (item)
            name.Set(str::Dup(item->title));
        delete root;
    }
    ScopedMem<WCHAR> pageLabel(win->dm->engine->GetPageLabel(pageNo));

    bool shouldAdd = Dialog_AddFavorite(win->hwndFrame, pageLabel, name);
    if (!shouldAdd)
        return;

    ScopedMem<WCHAR> plainLabel(str::Format(L"%d", pageNo));
    bool needsLabel = !str::Eq(plainLabel, pageLabel);

    RememberFavTreeExpansionStateForAllWindows();
    gFavorites.AddOrReplace(win->loadedFilePath, pageNo, name, needsLabel ? pageLabel.Get() : NULL);
    // expand newly added favorites by default
    DisplayState *fav = gFavorites.GetFavByFilePath(win->loadedFilePath);
    CrashIf(!fav || win->expandedFavorites.Contains(fav));
    if (fav && fav->favorites->Count() == 2)
        win->expandedFavorites.Append(fav);
    UpdateFavoritesTreeForAllWindows();
    prefs::Save();
}
Ejemplo n.º 15
0
/* Caller needs to free() the result. */
WCHAR *AppGenDataFilename(const WCHAR *fileName)
{
    ScopedMem<WCHAR> path;
    /* Use %APPDATA% */
    path.Set(GetSpecialFolder(CSIDL_APPDATA, true));
    if (path) {
        path.Set(path::Join(path, APP_NAME_STR));
        if (path && !dir::Create(path))
            path.Set(NULL);
    }

    if (!path || !fileName)
        return NULL;

    return path::Join(path, fileName);
}
Ejemplo n.º 16
0
// caller must free() the result
char *Escape(WCHAR *string, bool keepString=false)
{
    ScopedMem<WCHAR> freeOnReturn;
    if (!keepString)
        freeOnReturn.Set(string);

    if (str::IsEmpty(string))
        return NULL;

    if (!str::FindChar(string, '<') && !str::FindChar(string, '&') && !str::FindChar(string, '"'))
        return str::conv::ToUtf8(string);

    str::Str<WCHAR> escaped(256);
    for (WCHAR *s = string; *s; s++) {
        switch (*s) {
        case '&': escaped.Append(L"&amp;"); break;
        case '<': escaped.Append(L"&lt;"); break;
        case '>': escaped.Append(L"&gt;"); break;
        case '"': escaped.Append(L"&quot;"); break;
        case '\'': escaped.Append(L"&amp;"); break;
        default: escaped.Append(*s); break;
        }
    }
    return str::conv::ToUtf8(escaped.Get());
}
Ejemplo n.º 17
0
unsigned char *ChmDoc::GetData(const char *fileName, size_t *lenOut)
{
    ScopedMem<char> fileNameTmp;
    if (!str::StartsWith(fileName, "/")) {
        fileNameTmp.Set(str::Join("/", fileName));
        fileName = fileNameTmp;
    } else if (str::StartsWith(fileName, "///")) {
        fileName += 2;
    }

    struct chmUnitInfo info;
    int res = chm_resolve_object(chmHandle, fileName, &info);
    if (CHM_RESOLVE_SUCCESS != res)
        return NULL;
    size_t len = (size_t)info.length;
    if (len > 128 * 1024 * 1024) {
        // don't allow anything above 128 MB
        return NULL;
    }

    // +1 for 0 terminator for C string compatibility
    ScopedMem<unsigned char> data((unsigned char *)malloc(len + 1));
    if (!data)
        return NULL;
    if (!chm_retrieve_object(chmHandle, &info, data.Get(), 0, len))
        return NULL;
    data[len] = '\0';

    if (lenOut)
        *lenOut = len;
    return data.StealData();
}
Ejemplo n.º 18
0
int Pdfsync::DocToSource(UINT pageNo, PointI pt, ScopedMem<WCHAR>& filename, UINT *line, UINT *col)
{
    if (IsIndexDiscarded())
        if (RebuildIndex() != PDFSYNCERR_SUCCESS)
            return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;

    // find the entry in the index corresponding to this page
    if (pageNo <= 0 || pageNo >= sheetIndex.Count() || pageNo > (UINT)engine->PageCount())
        return PDFSYNCERR_INVALID_PAGE_NUMBER;

    // PdfSync coordinates are y-inversed
    RectI mbox = engine->PageMediabox(pageNo).Round();
    pt.y = mbox.dy - pt.y;

    // distance to the closest pdf location (in the range <PDFSYNC_EPSILON_SQUARE)
    UINT closest_xydist = UINT_MAX;
    UINT selected_record = UINT_MAX;
    // If no record is found within a distance^2 of PDFSYNC_EPSILON_SQUARE
    // (selected_record == -1) then we pick up the record that is closest
    // vertically to the hit-point.
    UINT closest_ydist = UINT_MAX; // vertical distance between the hit point and the vertically-closest record
    UINT closest_xdist = UINT_MAX; // horizontal distance between the hit point and the vertically-closest record
    UINT closest_ydist_record = UINT_MAX; // vertically-closest record

    // read all the sections of 'p' declarations for this pdf sheet
    for (size_t i = sheetIndex.At(pageNo); i < points.Count() && points.At(i).page == pageNo; i++) {
        // check whether it is closer than the closest point found so far
        UINT dx = abs(pt.x - (int)SYNC_TO_PDF_COORDINATE(points.At(i).x));
        UINT dy = abs(pt.y - (int)SYNC_TO_PDF_COORDINATE(points.At(i).y));
        UINT dist = dx * dx + dy * dy;
        if (dist < PDFSYNC_EPSILON_SQUARE && dist < closest_xydist) {
            selected_record = points.At(i).record;
            closest_xydist = dist;
        }
        else if ((closest_xydist == UINT_MAX) && dy < PDFSYNC_EPSILON_Y &&
                 (dy < closest_ydist || (dy == closest_ydist && dx < closest_xdist))) {
            closest_ydist_record = points.At(i).record;
            closest_ydist = dy;
            closest_xdist = dx;
        }
    }

    if (selected_record == UINT_MAX)
        selected_record = closest_ydist_record;
    if (selected_record == UINT_MAX)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION; // no record was found close enough to the hit point

    // We have a record number, we need to find its declaration ('l ...') in the syncfile
    PdfsyncLine cmp; cmp.record = selected_record;
    PdfsyncLine *found = (PdfsyncLine *)bsearch(&cmp, lines.LendData(), lines.Count(), sizeof(PdfsyncLine), cmpLineRecords);
    assert(found);
    if (!found)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION;

    filename.Set(str::Dup(srcfiles.At(found->file)));
    *line = found->line;
    *col = found->column;

    return PDFSYNCERR_SUCCESS;
}
Ejemplo n.º 19
0
// 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;
}
DocTocItem *Fb2EngineImpl::GetTocTree()
{
    EbookTocItem *root = NULL;
    ScopedMem<WCHAR> itemText;
    int titleCount = 0;
    bool inTitle = false;
    int level = 0;

    size_t xmlLen;
    const char *xmlData = doc->GetTextData(&xmlLen);
    HtmlPullParser parser(xmlData, xmlLen);
    HtmlToken *tok;
    while ((tok = parser.Next()) && !tok->IsError()) {
        if (tok->IsStartTag() && Tag_Section == tok->tag)
            level++;
        else if (tok->IsEndTag() && Tag_Section == tok->tag && level > 0)
            level--;
        else if (tok->IsStartTag() && Tag_Title == tok->tag) {
            inTitle = true;
            titleCount++;
        }
        else if (tok->IsEndTag() && Tag_Title == tok->tag) {
            if (itemText)
                str::NormalizeWS(itemText);
            if (!str::IsEmpty(itemText.Get())) {
                ScopedMem<WCHAR> name(str::Format(TEXT(FB2_TOC_ENTRY_MARK) L"%d", titleCount));
                PageDestination *dest = GetNamedDest(name);
                EbookTocItem *item = new EbookTocItem(itemText.StealData(), dest);
                item->id = titleCount;
                item->open = level <= 2;
                AppendTocItem(root, item, level);
            }
            inTitle = false;
        }
        else if (inTitle && tok->IsText()) {
            ScopedMem<WCHAR> text(str::conv::FromHtmlUtf8(tok->s, tok->sLen));
            if (str::IsEmpty(itemText.Get()))
                itemText.Set(text.StealData());
            else
                itemText.Set(str::Join(itemText, L" ", text));
        }
    }

    return root;
}
Ejemplo n.º 21
0
int SyncTex::DocToSource(UINT pageNo, PointI pt, ScopedMem<WCHAR>& filename, UINT *line, UINT *col)
{
    if (IsIndexDiscarded()) {
        if (RebuildIndex() != PDFSYNCERR_SUCCESS)
            return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED;
    }
    CrashIf(!this->scanner);

    // Coverity: at this point, this->scanner->flags.has_parsed == 1 and thus
    // synctex_scanner_parse never gets the chance to freeing the scanner
    if (synctex_edit_query(this->scanner, pageNo, (float)pt.x, (float)pt.y) <= 0)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION;

    synctex_node_t node = synctex_next_result(this->scanner);
    if (!node)
        return PDFSYNCERR_NO_SYNC_AT_LOCATION;

    const char *name = synctex_scanner_get_name(this->scanner, synctex_node_tag(node));
    if (!name)
        return PDFSYNCERR_UNKNOWN_SOURCEFILE;

    bool isUtf8 = true;
    filename.Set(str::conv::FromUtf8(name));
TryAgainAnsi:
    if (!filename)
        return PDFSYNCERR_OUTOFMEMORY;

    // undecorate the filepath: replace * by space and / by \ 
    str::TransChars(filename, L"*/", L" \\");
    // Convert the source filepath to an absolute path
    if (PathIsRelative(filename))
        filename.Set(PrependDir(filename));

    // recent SyncTeX versions encode in UTF-8 instead of ANSI
    if (isUtf8 && !file::Exists(filename)) {
        isUtf8 = false;
        filename.Set(str::conv::FromAnsi(name));
        goto TryAgainAnsi;
    }

    *line = synctex_node_line(node);
    *col = synctex_node_column(node);

    return PDFSYNCERR_SUCCESS;
}
Ejemplo n.º 22
0
/* Returns true, if a Registry entry indicates that this executable has been
   created by an installer (and should be updated through an installer) */
bool HasBeenInstalled()
{
    ScopedMem<WCHAR> installedPath;
    // cf. GetInstallationDir() in installer\Installer.cpp
    installedPath.Set(ReadRegStr(HKEY_CURRENT_USER, REG_PATH_UNINST, L"InstallLocation"));
    if (!installedPath)
        installedPath.Set(ReadRegStr(HKEY_LOCAL_MACHINE, REG_PATH_UNINST, L"InstallLocation"));
    if (!installedPath)
        return false;

    ScopedMem<WCHAR> exePath(GetExePath());
    if (!exePath)
        return false;

    if (!str::EndsWithI(installedPath, L".exe"))
        installedPath.Set(path::Join(installedPath, path::GetBaseName(exePath)));
    return path::IsSame(installedPath, exePath);
}
 RemoteHtmlDest(const WCHAR *relativeURL) : SimpleDest2(0, RectD()) {
     const WCHAR *id = str::FindChar(relativeURL, '#');
     if (id) {
         value.Set(str::DupN(relativeURL, id - relativeURL));
         name.Set(str::Dup(id));
     }
     else
         value.Set(str::Dup(relativeURL));
 }
Ejemplo n.º 24
0
static void AppendFavMenuItems(HMENU m, FileFavs *f, UINT& idx, bool combined, bool isCurrent)
{
    size_t items = f->favNames.Count();
    if (items > MAX_FAV_MENUS) {
        items = MAX_FAV_MENUS;
    }
    for (size_t i = 0; i < items; i++) {
        FavName *fn = f->favNames.At(i);
        fn->menuId = idx++;
        ScopedMem<TCHAR> s;
        if (combined)
            s.Set(FavCompactReadableName(f, fn, isCurrent));
        else
            s.Set(FavReadableName(fn));
        s.Set(win::menu::ToSafeString(s));
        AppendMenu(m, MF_STRING, (UINT_PTR)fn->menuId, s);
    }
}
Ejemplo n.º 25
0
void ChmDoc::FixPathCodepage(ScopedMem<char>& path, UINT& fileCP)
{
    if (!path || HasData(path))
        return;

    ScopedMem<char> utf8Path(ToUtf8((unsigned char *)path.Get()));
    if (HasData(utf8Path)) {
        path.Set(utf8Path.StealData());
        fileCP = codepage;
    }
    else if (fileCP != codepage) {
        utf8Path.Set(ToUtf8((unsigned char *)path.Get(), fileCP));
        if (HasData(utf8Path)) {
            path.Set(utf8Path.StealData());
            codepage = fileCP;
        }
    }
}
Ejemplo n.º 26
0
bool IsRunningInPortableMode()
{
    // cache the result so that it will be consistent during the lifetime of the process
    static int sCacheIsPortable = -1; // -1 == uninitialized, 0 == installed, 1 == portable
    if (sCacheIsPortable != -1)
        return sCacheIsPortable != 0;
    sCacheIsPortable = 1;

    ScopedMem<WCHAR> exePath(GetExePath());
    if (!exePath)
        return true;

    // if we can't get a path, assume we're not running from "Program Files"
    ScopedMem<WCHAR> installedPath;
    // cf. GetInstallationDir() in installer\Installer.cpp
    installedPath.Set(ReadRegStr(HKEY_CURRENT_USER, REG_PATH_UNINST, L"InstallLocation"));
    if (!installedPath)
        installedPath.Set(ReadRegStr(HKEY_LOCAL_MACHINE, REG_PATH_UNINST, L"InstallLocation"));
    if (installedPath) {
        if (!str::EndsWithI(installedPath.Get(), L".exe"))
            installedPath.Set(path::Join(installedPath.Get(), path::GetBaseName(exePath)));
        if (path::IsSame(installedPath, exePath)) {
            sCacheIsPortable = 0;
            return false;
        }
    }

    ScopedMem<WCHAR> programFilesDir(GetSpecialFolder(CSIDL_PROGRAM_FILES));
    if (!programFilesDir)
        return true;

    // check if one of the exePath's parent directories is "Program Files"
    // (or a junction to it)
    WCHAR *baseName;
    while ((baseName = (WCHAR*)path::GetBaseName(exePath)) > exePath) {
        baseName[-1] = '\0';
        if (path::IsSame(programFilesDir, exePath)) {
            sCacheIsPortable = 0;
            return false;
        }
    }

    return true;
}
Ejemplo n.º 27
0
bool ViewWithHtmlHelp(WindowInfo *win, const WCHAR *args)
{
    if (!CanViewWithHtmlHelp(win))
        return false;

    ScopedMem<WCHAR> exePath(GetHtmlHelpPath());
    if (!exePath)
        return false;

    if (!args)
        args = L"";

    ScopedMem<WCHAR> params;
    if (win->IsDocLoaded())
        params.Set(str::Format(L"%s \"%s\"", args, win->ctrl->FilePath()));
    else
        params.Set(str::Format(L"%s \"%s\"", args, win->loadedFilePath));
    return LaunchFile(exePath, params);
}
void ChmFormatter::HandleTagPagebreak(HtmlToken *t)
{
    AttrInfo *attr = t->GetAttrByName("page_path");
    if (!attr || pagePath)
        ForceNewPage();
    if (attr) {
        RectF bbox(0, currY, pageDx, 0);
        currPage->instructions.Append(DrawInstr::Anchor(attr->val, attr->valLen, bbox));
        pagePath.Set(str::DupN(attr->val, attr->valLen));
    }
}
Ejemplo n.º 29
0
bool ViewWithPDFXChange(WindowInfo *win, const WCHAR *args)
{
    if (!CanViewWithPDFXChange(win))
        return false;

    ScopedMem<WCHAR> exePath(GetPDFXChangePath());
    if (!exePath)
        return false;
    if (!args)
        args = L"";

    // PDFXChange cmd-line format:
    // [/A "param=value [&param2=value ..."] [PDF filename]
    // /A params: page=<page number>
    ScopedMem<WCHAR> params;
    if (win->IsDocLoaded())
        params.Set(str::Format(L"%s /A \"page=%d\" \"%s\"", args, win->ctrl->CurrentPageNo(), win->ctrl->FilePath()));
    else
        params.Set(str::Format(L"%s \"%s\"", args, win->loadedFilePath));
    return LaunchFile(exePath, params);
}
Ejemplo n.º 30
0
    PrintData(BaseEngine *engine, PRINTER_INFO_2 *printerInfo, DEVMODE *devMode,
              Vec<PRINTPAGERANGE>& ranges, Print_Advanced_Data& advData,
              int rotation=0, Vec<SelectionOnPage> *sel=NULL) :
        engine(NULL), advData(advData), rotation(rotation)
    {
        if (engine)
            this->engine = engine->Clone();

        if (printerInfo) {
            driverName.Set(str::Dup(printerInfo->pDriverName));
            printerName.Set(str::Dup(printerInfo->pPrinterName));
            portName.Set(str::Dup(printerInfo->pPortName));
        }
        if (devMode)
            this->devMode.Set((LPDEVMODE)memdup(devMode, devMode->dmSize + devMode->dmDriverExtra));

        if (!sel)
            this->ranges = ranges;
        else
            this->sel = *sel;
    }