Exemple #1
0
void AddFavorite(WindowInfo* win) {
    TabInfo* tab = win->currentTab;
    CrashIf(!tab);
    int pageNo = win->currPageNo;
    ScopedMem<WCHAR> name;
    if (tab->ctrl->HasTocTree()) {
        // use the current ToC heading as default name
        DocTocItem* root = tab->ctrl->GetTocTree();
        DocTocItem* item = TocItemForPageNo(root, pageNo);
        if (item) {
            name.Set(str::Dup(item->title));
        }
        delete root;
    }
    ScopedMem<WCHAR> pageLabel(tab->ctrl->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(tab->filePath, pageNo, name, needsLabel ? pageLabel.Get() : nullptr);
    // expand newly added favorites by default
    DisplayState* fav = gFavorites.GetFavByFilePath(tab->filePath);
    if (fav && fav->favorites->Count() == 2) {
        win->expandedFavorites.Append(fav);
    }
    UpdateFavoritesTreeForAllWindows();
    prefs::Save();
}
Exemple #2
0
void DelFavorite(WindowInfo* win) {
    CrashIf(!win->currentTab);
    RememberFavTreeExpansionStateForAllWindows();
    gFavorites.Remove(win->currentTab->filePath, win->currPageNo);
    UpdateFavoritesTreeForAllWindows();
    prefs::Save();
}
Exemple #3
0
// refresh the preferences when a different SumatraPDF process saves them
// or if they are edited by the user using a text editor
bool Reload()
{
    ScopedMem<WCHAR> path(GetSettingsPath());
    if (!file::Exists(path))
        return false;

    // make sure that the settings file is readable - else wait
    // a short while to prevent accidental dataloss
    int tryAgainCount = 5;
    HANDLE h = file::OpenReadOnly(path);
    while (INVALID_HANDLE_VALUE == h && tryAgainCount-- > 0) {
        Sleep(200);
        h = file::OpenReadOnly(path);
    }
    if (INVALID_HANDLE_VALUE == h) {
        // prefer not reloading to resetting all settings
        return false;
    }

    ScopedHandle hScope(h);

    FILETIME time = file::GetModificationTime(path);
    if (FileTimeEq(time, gGlobalPrefs->lastPrefUpdate))
        return true;

    ScopedMem<char> uiLanguage(str::Dup(gGlobalPrefs->uiLanguage));
    bool showToolbar = gGlobalPrefs->showToolbar;
    bool invertColors = gGlobalPrefs->fixedPageUI.invertColors;

    gFileHistory.UpdateStatesSource(NULL);
    CleanUp();

    bool ok = Load();
    CrashAlwaysIf(!ok || !gGlobalPrefs);

    gGlobalPrefs->fixedPageUI.invertColors = invertColors;

    // TODO: about window doesn't have to be at position 0
    if (gWindows.Count() > 0 && gWindows.At(0)->IsAboutWindow()) {
        gWindows.At(0)->DeleteInfotip();
        gWindows.At(0)->staticLinks.Reset();
        gWindows.At(0)->RedrawAll(true);
    }

    if (!str::Eq(uiLanguage, gGlobalPrefs->uiLanguage))
        SetCurrentLanguageAndRefreshUi(gGlobalPrefs->uiLanguage);

    if (gGlobalPrefs->showToolbar != showToolbar)
        ShowOrHideToolbarGlobally();

    UpdateDocumentColors();
    UpdateFavoritesTreeForAllWindows();

    return true;
}
Exemple #4
0
static void OnFavTreeContextMenu(WindowInfo* win, PointI pt) {
    TVITEM item;
    if (pt.x != -1 || pt.y != -1) {
        TVHITTESTINFO ht = {0};
        ht.pt.x = pt.x;
        ht.pt.y = pt.y;

        MapWindowPoints(HWND_DESKTOP, win->hwndFavTree, &ht.pt, 1);
        TreeView_HitTest(win->hwndFavTree, &ht);
        if ((ht.flags & TVHT_ONITEM) == 0)
            return; // only display menu if over a node in tree

        TreeView_SelectItem(win->hwndFavTree, ht.hItem);
        item.hItem = ht.hItem;
    } else {
        item.hItem = TreeView_GetSelection(win->hwndFavTree);
        if (!item.hItem) {
            return;
        }
        RECT rcItem;
        if (TreeView_GetItemRect(win->hwndFavTree, item.hItem, &rcItem, TRUE)) {
            MapWindowPoints(win->hwndFavTree, HWND_DESKTOP, (POINT*)&rcItem, 2);
            pt.x = rcItem.left;
            pt.y = rcItem.bottom;
        } else {
            WindowRect rc(win->hwndFavTree);
            pt = rc.TL();
        }
    }

    item.mask = TVIF_PARAM;
    TreeView_GetItem(win->hwndFavTree, &item);
    Favorite* toDelete = (Favorite*)item.lParam;

    HMENU popup = BuildMenuFromMenuDef(menuDefFavContext, dimof(menuDefFavContext), CreatePopupMenu());

    INT cmd = TrackPopupMenu(popup, TPM_RETURNCMD | TPM_RIGHTBUTTON, pt.x, pt.y, 0, win->hwndFavTree, nullptr);
    DestroyMenu(popup);
    if (IDM_FAV_DEL == cmd) {
        RememberFavTreeExpansionStateForAllWindows();
        if (toDelete) {
            DisplayState* f = gFavorites.GetByFavorite(toDelete);
            gFavorites.Remove(f->filePath, toDelete->pageNo);
        } else {
            // toDelete == nullptr => this is a parent node signifying all bookmarks in a file
            item.hItem = TreeView_GetChild(win->hwndFavTree, item.hItem);
            item.mask = TVIF_PARAM;
            TreeView_GetItem(win->hwndFavTree, &item);
            toDelete = (Favorite*)item.lParam;
            DisplayState* f = gFavorites.GetByFavorite(toDelete);
            gFavorites.RemoveAllForFile(f->filePath);
        }
        UpdateFavoritesTreeForAllWindows();
        prefs::Save();

        // TODO: it would be nice to have a system for undo-ing things, like in Gmail,
        // so that we can do destructive operations without asking for permission via
        // invasive model dialog boxes but also allow reverting them if were done
        // by mistake
    }
}