Dont use win32com for adding to recent docs

This commit is contained in:
Kovid Goyal 2019-06-11 12:06:12 +05:30
parent 8de0ac6022
commit 0f3b2e2329
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 101 additions and 8 deletions

View File

@ -161,7 +161,7 @@
{ {
"name": "winutil", "name": "winutil",
"only": "windows", "only": "windows",
"sources": "calibre/utils/windows/winutil.c", "sources": "calibre/utils/windows/winutil.c calibre/utils/windows/winutilpp.cpp",
"libraries": "shell32 wininet advapi32", "libraries": "shell32 wininet advapi32",
"cflags": "/X" "cflags": "/X"
}, },

View File

@ -127,6 +127,9 @@ def find_tests(which_tests=None):
a(find_tests()) a(find_tests())
from calibre.ebooks.compression.palmdoc import find_tests from calibre.ebooks.compression.palmdoc import find_tests
a(find_tests()) a(find_tests())
if iswindows:
from calibre.utils.windows.wintest import find_tests
a(find_tests())
a(unittest.defaultTestLoader.loadTestsFromTestCase(TestImports)) a(unittest.defaultTestLoader.loadTestsFromTestCase(TestImports))
if ok('dbcli'): if ok('dbcli'):

View File

@ -1380,11 +1380,5 @@ def set_app_uid(val):
def add_to_recent_docs(path): def add_to_recent_docs(path):
from win32com.shell import shell, shellcon
path = unicode_type(path)
app_id = get_app_uid() app_id = get_app_uid()
if app_id is None: plugins['winutil'][0].add_to_recent_docs(unicode_type(path), app_id)
shell.SHAddToRecentDocs(shellcon.SHARD_PATHW, path)
else:
item = shell.SHCreateItemFromParsingName(path, None, shell.IID_IShellItem)
shell.SHAddToRecentDocs(shellcon.SHARD_APPIDINFO, (item, app_id))

View File

View File

@ -0,0 +1,28 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
import os
import unittest
from polyglot.builtins import unicode_type
class TestWinutil(unittest.TestCase):
def setUp(self):
from calibre.constants import plugins
self.winutil = plugins['winutil'][0]
def tearDown(self):
del self.winutil
def test_add_to_recent_docs(self):
path = unicode_type(os.path.abspath(__file__))
self.winutil.add_to_recent_docs(path, None)
self.winutil.add_to_recent_docs(path, 'some-app-uid')
def find_tests():
return unittest.defaultTestLoader.loadTestsFromTestCase(TestWinutil)

View File

@ -375,6 +375,7 @@ winutil_strftime(PyObject *self, PyObject *args)
} }
static char winutil_doc[] = "Defines utility methods to interface with windows."; static char winutil_doc[] = "Defines utility methods to interface with windows.";
extern PyObject *add_to_recent_docs(PyObject *self, PyObject *args);
static PyMethodDef winutil_methods[] = { static PyMethodDef winutil_methods[] = {
{"special_folder_path", winutil_folder_path, METH_VARARGS, {"special_folder_path", winutil_folder_path, METH_VARARGS,
@ -442,6 +443,10 @@ be a unicode string. Returns unicode strings."
"move_file()\n\nRename the specified file." "move_file()\n\nRename the specified file."
}, },
{"add_to_recent_docs", (PyCFunction)add_to_recent_docs, METH_VARARGS,
"add_to_recent_docs()\n\nAdd a path to the recent documents list"
},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View File

@ -0,0 +1,63 @@
/*
* winutil.cpp
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#define UNICODE
#include <Windows.h>
#include <combaseapi.h>
#include <shlobj.h>
#include <atlbase.h> // for CComPtr
#include <Python.h>
static inline int
py_to_wchar(PyObject *obj, wchar_t **output) {
if (!PyUnicode_Check(obj)) {
if (obj == Py_None) { *output = NULL; return 1; }
PyErr_SetString(PyExc_TypeError, "unicode object expected");
return 0;
}
#if PY_MAJOR_VERSION < 3
*output = PyUnicode_AS_UNICODE(obj);
#else
*output = PyUnicode_AsWideCharString(obj, NULL);
#endif
return 1;
}
static inline void
free_wchar_buffer(wchar_t **buf) {
#if PY_MAJOR_VERSION >= 3
PyMem_Free(*buf);
#endif
*buf = NULL;
}
extern "C" {
PyObject *
add_to_recent_docs(PyObject *self, PyObject *args) {
wchar_t *path, *app_id;
if (!PyArg_ParseTuple(args, "O&O&", py_to_wchar, &path, py_to_wchar, &app_id)) return NULL;
if (app_id) {
CComPtr<IShellItem> item;
HRESULT hr = SHCreateItemFromParsingName(path, NULL, IID_PPV_ARGS(&item));
if (SUCCEEDED(hr)) {
SHARDAPPIDINFO info;
info.psi = item;
info.pszAppID = app_id;
SHAddToRecentDocs(SHARD_APPIDINFO, &info);
}
} else {
SHAddToRecentDocs(SHARD_PATHW, path);
}
free_wchar_buffer(&path); free_wchar_buffer(&app_id);
Py_RETURN_NONE;
}
}