Merge lp:~plprgt/zim/bookmarksbar-update into lp:~jaap.karssenberg/zim/pyzim
- bookmarksbar-update
- Merge into pyzim
Proposed by
Pl
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 851 | ||||
Proposed branch: | lp:~plprgt/zim/bookmarksbar-update | ||||
Merge into: | lp:~jaap.karssenberg/zim/pyzim | ||||
Diff against target: |
790 lines (+351/-259) 3 files modified
data/manual/Plugins/BookmarksBar.txt (+3/-2) tests/bookmarksbar.py (+287/-225) zim/plugins/bookmarksbar.py (+61/-32) |
||||
To merge this branch: | bzr merge lp:~plprgt/zim/bookmarksbar-update | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jaap Karssenberg | Pending | ||
Review via email: mp+307016@code.launchpad.net |
Commit message
Description of the change
A small update to the BookmarksBar plugin.
The main changes:
- A new option to change maximum number of bookmarks is available from the plugin settings.
- If a bookmark has a special name it will not be changed after setting this bookmark to another page.
- If an open page has a corresponding bookmark it will be selected in the bar.
- Tests for the plugin are updated.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/manual/Plugins/BookmarksBar.txt' |
2 | --- data/manual/Plugins/BookmarksBar.txt 2015-09-24 09:50:39 +0000 |
3 | +++ data/manual/Plugins/BookmarksBar.txt 2016-09-28 12:26:36 +0000 |
4 | @@ -11,6 +11,7 @@ |
5 | ===== Plugin options ===== |
6 | The option **Save bookmarks** allows to save and load bookmarks and their names between different sessions. If it is unchecked all bookmarks will be automatically deleted after closing the program. |
7 | The option **Add new bookmarks to the beginning of the bar** allows to choose the place where new bookmarks will be added. If checked all new bookmarks will be added to the beginning of the bar, if unchecked bookmarks will be added to the end of the bar. |
8 | +It is possible to set the maximum number of bookmarks in the interval from 5 to 20. |
9 | |
10 | ===== Basic operations ===== |
11 | To show/hide the bar with bookmarks press **Bookmarks** button in the toolbar or press **<F4>** on keyboard. |
12 | @@ -24,7 +25,7 @@ |
13 | **Remove All** to delete all bookmarks from the bar, |
14 | **Open in New Window** to open the bookmark in a new window, |
15 | **Copy** to mark the bookmark for following "Paste", |
16 | -**Paste** to transfer the marked bookmark to the new position, |
17 | +**Paste** to transfer the marked bookmark to the new position. The position will be determined by coordinates of the mouse click which was made to invoke the popup menu, |
18 | **Set New Name** to set a new name to the bookmark. The name is taken from the clipboard (if the name is too long, the plugin will take only first 25 symbols), |
19 | **Back to Original Name** to return the bookmark to its default name. This option will appear only if the bookmark is renamed, |
20 | **Set to Current Page** to change the bookmark into a bookmark of the currently opened page. |
21 | @@ -36,6 +37,6 @@ |
22 | ===== Restrictions ===== |
23 | Only existing pages (which have content or have sub-pages) can be added as bookmarks. If a page is deleted from the notebook its bookmark also will be deleted. |
24 | No duplicate bookmarks are allowed in the bar, though there can be different bookmarks with identical names. |
25 | -The number of bookmarks is limited to 15. |
26 | + |
27 | |
28 | |
29 | |
30 | === modified file 'tests/bookmarksbar.py' |
31 | --- tests/bookmarksbar.py 2015-09-24 12:33:11 +0000 |
32 | +++ tests/bookmarksbar.py 2016-09-28 12:26:36 +0000 |
33 | @@ -1,225 +1,287 @@ |
34 | -# -*- coding: utf-8 -*- |
35 | - |
36 | -# Copyright 2015 Pavel_M <plprgt@gmail.com>. |
37 | -# This is the test for BookmarksBar plugin. |
38 | -# BookmarksBar is the plugin for Zim program |
39 | -# by Jaap Karssenberg <jaap.karssenberg@gmail.com>. |
40 | - |
41 | - |
42 | -import tests |
43 | -import gtk |
44 | - |
45 | -from zim.notebook import Path |
46 | -from zim.plugins.bookmarksbar import * |
47 | -from zim.config import ConfigDict |
48 | -from zim.gui.clipboard import Clipboard |
49 | - |
50 | -import logging |
51 | -logger = logging.getLogger('zim.plugins.bookmarksbar') |
52 | - |
53 | - |
54 | -class TestBookmarksBar(tests.TestCase): |
55 | - |
56 | - def setUp(self): |
57 | - self.notebook = tests.new_notebook() |
58 | - self.index = self.notebook.index |
59 | - |
60 | - def runTest(self): |
61 | - '''There is one long test.''' |
62 | - |
63 | - ui = MockUI() |
64 | - ui.notebook = self.notebook |
65 | - ui.page = Path('Test:foo') |
66 | - uistate = ConfigDict() |
67 | - self.assertTrue(self.notebook.get_page(ui.page).exists()) |
68 | - |
69 | - PATHS = ('Parent:Daughter:Granddaughter', |
70 | - 'Test:tags', 'Test:foo', 'Books') |
71 | - LEN_PATHS = len(PATHS) |
72 | - PATHS_NAMES = {PATHS[0]:'name 1', PATHS[1]:'name 2', PATHS[2]:'name 3'} |
73 | - |
74 | - # Check correctness of reading uistate. |
75 | - uistate.setdefault('bookmarks', []) |
76 | - uistate.setdefault('bookmarks_names', {}) |
77 | - |
78 | - uistate['bookmarks'] = list(PATHS) |
79 | - uistate['bookmarks_names'] = dict(PATHS_NAMES) |
80 | - Bar = BookmarkBar(ui, uistate, get_page_func = lambda: '') |
81 | - self.assertTrue(Bar.paths == list(PATHS)) |
82 | - self.assertTrue(Bar.paths_names == PATHS_NAMES) |
83 | - |
84 | - uistate['bookmarks'] = [] |
85 | - uistate['bookmarks_names'] = {} |
86 | - Bar = BookmarkBar(ui, uistate, get_page_func = lambda: '') |
87 | - self.assertTrue(Bar.paths == []) |
88 | - self.assertTrue(Bar.paths_names == {}) |
89 | - |
90 | - # Add paths to the beginning of the bar. |
91 | - for i, path in enumerate(PATHS): |
92 | - Bar._add_new(path, add_bookmarks_to_beginning = True) |
93 | - self.assertTrue(len(Bar.paths) == i + 1) |
94 | - self.assertTrue(Bar.paths == list(reversed(PATHS))) |
95 | - |
96 | - # Add paths to the end of the bar. |
97 | - Bar.paths = [] |
98 | - for i, path in enumerate(PATHS): |
99 | - Bar._add_new(path, add_bookmarks_to_beginning = False) |
100 | - self.assertTrue(len(Bar.paths) == i + 1) |
101 | - self.assertTrue(Bar.paths == list(PATHS)) |
102 | - |
103 | - # Check that the same path can't be added to the bar. |
104 | - Bar._add_new(PATHS[0]) |
105 | - Bar._add_new(PATHS[1]) |
106 | - self.assertTrue(Bar.paths == list(PATHS)) |
107 | - |
108 | - # Delete paths from the bar. |
109 | - for i, button in enumerate(Bar.container.get_children()[2:]): |
110 | - path = button.zim_path |
111 | - self.assertTrue(path in Bar.paths) |
112 | - Bar.delete(button.zim_path) |
113 | - self.assertTrue(len(Bar.paths) == LEN_PATHS - i - 1) |
114 | - self.assertTrue(path not in Bar.paths) |
115 | - self.assertTrue(Bar.paths == []) |
116 | - |
117 | - # Check short page names. |
118 | - uistate['show_full_page_name'] = False |
119 | - for path in PATHS: |
120 | - Bar._add_new(path) |
121 | - self.assertTrue(Bar.paths == list(PATHS)) |
122 | - for i, button in enumerate(Bar.container.get_children()[2:]): |
123 | - self.assertTrue(PATHS[i] == button.zim_path) |
124 | - self.assertTrue(Path(PATHS[i]).basename == button.get_label()) |
125 | - uistate['show_full_page_name'] = True |
126 | - |
127 | - # Delete all bookmarks from the bar. |
128 | - Bar.delete_all() |
129 | - self.assertTrue(Bar.paths == []) |
130 | - |
131 | - # Check restriction of max bookmarks in the bar. |
132 | - pagelist = set(self.index.list_pages(None)) |
133 | - _enhanced_pagelist = set() |
134 | - for page in pagelist: |
135 | - _enhanced_pagelist.update( set(self.index.list_pages(page)) ) |
136 | - if len(_enhanced_pagelist) > MAX_BOOKMARKS: |
137 | - break |
138 | - pagelist.update(_enhanced_pagelist) |
139 | - self.assertTrue(len(pagelist) > MAX_BOOKMARKS) |
140 | - pagelist = list(pagelist) |
141 | - for page in pagelist: |
142 | - Bar._add_new(page.name) |
143 | - self.assertTrue(len(Bar.paths) == MAX_BOOKMARKS) |
144 | - self.assertTrue(Bar.paths == [a.name for a in pagelist[:MAX_BOOKMARKS]]) |
145 | - Bar.delete_all() |
146 | - |
147 | - # Check 'save' option in preferences. |
148 | - for i, path in enumerate(PATHS): |
149 | - Bar.on_preferences_changed({'save':False, 'add_bookmarks_to_beginning':False}) |
150 | - Bar._add_new(path) |
151 | - self.assertTrue(uistate['bookmarks'] == []) |
152 | - Bar.on_preferences_changed({'save':True, 'add_bookmarks_to_beginning':False}) |
153 | - self.assertTrue(uistate['bookmarks'] == list(PATHS[:i+1])) |
154 | - self.assertTrue(uistate['bookmarks'] == list(PATHS)) |
155 | - |
156 | - # Check changing a bookmark. |
157 | - self.assertTrue('Test' not in Bar.paths) |
158 | - self.assertTrue('Books' in Bar.paths) |
159 | - Bar.change_bookmark('Books', 'Books') |
160 | - self.assertTrue(Bar.paths == list(PATHS)) |
161 | - _b_paths = [a for a in Bar.paths if a != 'Books'] |
162 | - Bar.change_bookmark('Books', 'Test') |
163 | - self.assertTrue('Test' in Bar.paths) |
164 | - self.assertTrue('Books' not in Bar.paths) |
165 | - _e_paths = [a for a in Bar.paths if a != 'Test'] |
166 | - self.assertTrue(_b_paths == _e_paths) |
167 | - |
168 | - Bar.change_bookmark('Test', 'Books') |
169 | - self.assertTrue(Bar.paths == list(PATHS)) |
170 | - |
171 | - # Check deleting a bookmark after deleting a page in the notebook. |
172 | - self.assertTrue(len(Bar.paths) == LEN_PATHS) |
173 | - for i, path in enumerate(PATHS): |
174 | - self.assertTrue(path in Bar.paths) |
175 | - self.notebook.delete_page(Path(path)) |
176 | - self.assertTrue(path not in Bar.paths) |
177 | - self.assertTrue(len(Bar.paths) == LEN_PATHS - i - 1) |
178 | - self.assertTrue(Bar.paths == []) |
179 | - |
180 | - # Check reordering bookmarks. |
181 | - PATHS_2 = ('1','2','3','4','5') |
182 | - PATHS_NAMES_2 = {PATHS_2[0]:'11', PATHS_2[1]:'22', PATHS_2[2]:'33'} |
183 | - |
184 | - Bar.paths = list(PATHS_2) |
185 | - Bar.move_bookmark(PATHS_2[2], PATHS_2[2], 'left') |
186 | - self.assertTrue(Bar.paths == list(PATHS_2)) |
187 | - Bar.move_bookmark(PATHS_2[3], PATHS_2[3], 'right') |
188 | - self.assertTrue(Bar.paths == list(PATHS_2)) |
189 | - Bar.move_bookmark('3', '1', 'left') |
190 | - self.assertTrue(Bar.paths == ['3','1','2','4','5']) |
191 | - Bar.move_bookmark('5', '1', 'left') |
192 | - self.assertTrue(Bar.paths == ['3','5','1','2','4']) |
193 | - Bar.move_bookmark('5', '1', 'right') |
194 | - self.assertTrue(Bar.paths == ['3','1','5','2','4']) |
195 | - Bar.move_bookmark('3', '4', 'right') |
196 | - self.assertTrue(Bar.paths == ['1','5','2','4','3']) |
197 | - Bar.move_bookmark('5', '4', '-') |
198 | - self.assertTrue(Bar.paths == ['1','5','2','4','3']) |
199 | - |
200 | - # CHECK RENAMING |
201 | - # Check rename_bookmark and save options. |
202 | - Bar.paths = list(PATHS_2) |
203 | - button = gtk.Button(label = PATHS_2[0], use_underline = False) |
204 | - button.zim_path = PATHS_2[0] |
205 | - Bar.on_preferences_changed({'save':True, 'add_bookmarks_to_beginning':False}) |
206 | - Bar._reload_bar() |
207 | - |
208 | - def rename_check(label, path, paths_names, path_names_uistate): |
209 | - self.assertTrue(button.get_label() == label) |
210 | - self.assertTrue(button.zim_path == path) |
211 | - self.assertTrue(Bar.paths_names == paths_names) |
212 | - self.assertTrue(uistate['bookmarks_names'] == path_names_uistate) |
213 | - |
214 | - rename_check(PATHS_2[0], PATHS_2[0], {}, {}) |
215 | - Clipboard.set_text('new name') |
216 | - Bar.rename_bookmark(button) |
217 | - rename_check('new name', PATHS_2[0], {PATHS_2[0]:'new name'}, {PATHS_2[0]:'new name'}) |
218 | - Bar.on_preferences_changed({'save':False, 'add_bookmarks_to_beginning':False}) |
219 | - rename_check('new name', PATHS_2[0], {PATHS_2[0]:'new name'}, {}) |
220 | - Bar.on_preferences_changed({'save':True, 'add_bookmarks_to_beginning':False}) |
221 | - rename_check('new name', PATHS_2[0], {PATHS_2[0]:'new name'}, {PATHS_2[0]:'new name'}) |
222 | - Bar.rename_bookmark(button) |
223 | - rename_check(PATHS_2[0], PATHS_2[0], {}, {}) |
224 | - |
225 | - # Check delete with renaming. |
226 | - Bar.on_preferences_changed({'save':True, 'add_bookmarks_to_beginning':False}) |
227 | - paths_names_copy = dict(PATHS_NAMES_2) |
228 | - Bar.paths_names = dict(PATHS_NAMES_2) |
229 | - for key in PATHS_NAMES_2: |
230 | - Bar.delete(key) |
231 | - del paths_names_copy[key] |
232 | - self.assertTrue(Bar.paths_names == paths_names_copy) |
233 | - self.assertTrue(uistate['bookmarks_names'] == Bar.paths_names) |
234 | - |
235 | - # Check delete all with renaming. |
236 | - Bar.paths_names = dict(PATHS_NAMES_2) |
237 | - Bar.delete_all() |
238 | - self.assertTrue(Bar.paths_names == {}) |
239 | - self.assertTrue(uistate['bookmarks_names'] == {}) |
240 | - |
241 | - # Check change bookmark with renaming. |
242 | - Bar.paths = list(PATHS_2) |
243 | - Bar.paths_names = dict(PATHS_NAMES_2) |
244 | - paths_names_copy = dict(PATHS_NAMES_2) |
245 | - paths_names_copy.pop(PATHS_2[0], None) |
246 | - Bar.change_bookmark(PATHS_2[0], 'new path') |
247 | - self.assertTrue(Bar.paths_names == paths_names_copy) |
248 | - self.assertTrue(Bar.paths == ['new path'] + list(PATHS_2[1:])) |
249 | - |
250 | - # Check that paths and paths_names didn't change in the process. |
251 | - self.assertTrue(PATHS_2 == ('1','2','3','4','5')) |
252 | - self.assertTrue(PATHS_NAMES_2 == {PATHS_2[0]:'11', PATHS_2[1]:'22', PATHS_2[2]:'33'}) |
253 | - |
254 | - |
255 | -class MockUI(tests.MockObject): |
256 | - page = None |
257 | - notebook = None |
258 | - |
259 | +# -*- coding: utf-8 -*- |
260 | + |
261 | +# Copyright 2015-2016 Pavel_M <plprgt@gmail.com>, |
262 | +# released under the GNU GPL version 3. |
263 | + |
264 | +# This is the test for BookmarksBar plugin. |
265 | +# BookmarksBar is the plugin for Zim program |
266 | +# by Jaap Karssenberg <jaap.karssenberg@gmail.com>. |
267 | + |
268 | + |
269 | +import tests |
270 | +import gtk |
271 | + |
272 | +from zim.notebook import Path |
273 | +from zim.plugins.bookmarksbar import * |
274 | +from zim.config import ConfigDict |
275 | +from zim.gui.clipboard import Clipboard |
276 | + |
277 | +import logging |
278 | +logger = logging.getLogger('zim.plugins.bookmarksbar') |
279 | + |
280 | + |
281 | +class TestBookmarksBar(tests.TestCase): |
282 | + |
283 | + @classmethod |
284 | + def setUpClass(cls): |
285 | + cls.notebook = tests.new_notebook() |
286 | + cls.index = cls.notebook.index |
287 | + cls.ui = MockUI() |
288 | + cls.ui.notebook = cls.notebook |
289 | + cls.ui.page = Path('Test:foo') |
290 | + |
291 | + |
292 | + def setUp(self): |
293 | + self.PATHS = ('Parent:Daughter:Granddaughter', |
294 | + 'Test:tags', 'Test:foo', 'Books') |
295 | + self.LEN_PATHS = len(self.PATHS) |
296 | + self.PATHS_NAMES = {self.PATHS[0]:'name 1', self.PATHS[1]:'name 2', self.PATHS[2]:'name 3'} |
297 | + |
298 | + self.uistate = ConfigDict() |
299 | + self.uistate.setdefault('bookmarks', []) |
300 | + self.uistate.setdefault('bookmarks_names', {}) |
301 | + self.uistate.setdefault('show_full_page_name', True) |
302 | + |
303 | + |
304 | + def testGeneral(self): |
305 | + '''Test general functions: add, delete bookmarks.''' |
306 | + |
307 | + self.assertTrue(self.notebook.get_page(self.ui.page).exists()) |
308 | + |
309 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
310 | + Bar.max_bookmarks = 15 # set maximum number of bookmarks |
311 | + |
312 | + # Add paths to the beginning of the bar. |
313 | + for i, path in enumerate(self.PATHS): |
314 | + Bar._add_new(path, add_bookmarks_to_beginning = True) |
315 | + self.assertEqual(len(Bar.paths), i + 1) |
316 | + self.assertTrue(Bar.paths == list(reversed(self.PATHS))) |
317 | + |
318 | + # Add paths to the end of the bar. |
319 | + Bar.paths = [] |
320 | + for i, path in enumerate(self.PATHS): |
321 | + Bar._add_new(path, add_bookmarks_to_beginning = False) |
322 | + self.assertEqual(len(Bar.paths), i + 1) |
323 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
324 | + |
325 | + # Check that the same path can't be added to the bar. |
326 | + Bar._add_new(self.PATHS[0]) |
327 | + Bar._add_new(self.PATHS[1]) |
328 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
329 | + |
330 | + # Delete paths from the bar. |
331 | + for i, button in enumerate(Bar.container.get_children()[2:]): |
332 | + path = button.zim_path |
333 | + self.assertTrue(path in Bar.paths) |
334 | + Bar.delete(button.zim_path) |
335 | + self.assertEqual(len(Bar.paths), self.LEN_PATHS - i - 1) |
336 | + self.assertTrue(path not in Bar.paths) |
337 | + self.assertEqual(Bar.paths, []) |
338 | + |
339 | + # Delete all bookmarks from the bar. |
340 | + Bar.delete_all() |
341 | + self.assertEqual(Bar.paths, []) |
342 | + |
343 | + |
344 | + def testDeletePages(self): |
345 | + '''Check deleting a bookmark after deleting a page in the notebook.''' |
346 | + |
347 | + notebook = tests.new_notebook() |
348 | + ui = MockUI() |
349 | + ui.notebook = notebook |
350 | + self.uistate['bookmarks'] = list(self.PATHS) |
351 | + |
352 | + Bar = BookmarkBar(ui, self.uistate, get_page_func = lambda: '') |
353 | + for i, path in enumerate(self.PATHS): |
354 | + self.assertTrue(path in Bar.paths) |
355 | + notebook.delete_page(Path(path)) |
356 | + self.assertTrue(path not in Bar.paths) |
357 | + self.assertEqual(len(Bar.paths), self.LEN_PATHS - i - 1) |
358 | + self.assertEqual(Bar.paths, []) |
359 | + |
360 | + |
361 | + def testFunctions(self): |
362 | + '''Test bookmark functions: changing, reordering, ranaming.''' |
363 | + |
364 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
365 | + Bar.max_bookmarks = 15 # set maximum number of bookmarks |
366 | + |
367 | + # Check changing a bookmark. |
368 | + for i, path in enumerate(self.PATHS): |
369 | + Bar._add_new(path, add_bookmarks_to_beginning = False) |
370 | + |
371 | + self.assertTrue('Test' not in Bar.paths) |
372 | + self.assertTrue('Books' in Bar.paths) |
373 | + Bar.change_bookmark('Books', 'Books') |
374 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
375 | + Bar.change_bookmark('Books', 'Test') |
376 | + self.assertTrue('Test' in Bar.paths) |
377 | + self.assertTrue('Books' not in Bar.paths) |
378 | + _result = [a if a != 'Books' else 'Test' for a in self.PATHS] |
379 | + self.assertEqual(Bar.paths, _result) |
380 | + |
381 | + Bar.change_bookmark('Test', 'Books') |
382 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
383 | + |
384 | + # Check reordering bookmarks. |
385 | + new_paths = ('1','2','3','4','5') |
386 | + |
387 | + Bar.paths = list(new_paths) |
388 | + Bar.move_bookmark(new_paths[2], new_paths[2], 'left') |
389 | + self.assertEqual(Bar.paths, list(new_paths)) |
390 | + Bar.move_bookmark(new_paths[3], new_paths[3], 'right') |
391 | + self.assertEqual(Bar.paths, list(new_paths)) |
392 | + Bar.move_bookmark('3', '1', 'left') |
393 | + self.assertEqual(Bar.paths, ['3','1','2','4','5']) |
394 | + Bar.move_bookmark('5', '1', 'left') |
395 | + self.assertEqual(Bar.paths, ['3','5','1','2','4']) |
396 | + Bar.move_bookmark('5', '1', 'right') |
397 | + self.assertEqual(Bar.paths, ['3','1','5','2','4']) |
398 | + Bar.move_bookmark('3', '4', 'right') |
399 | + self.assertEqual(Bar.paths, ['1','5','2','4','3']) |
400 | + Bar.move_bookmark('5', '4', '-') |
401 | + self.assertEqual(Bar.paths, ['1','5','2','4','3']) |
402 | + |
403 | + # Check rename_bookmark and save options. |
404 | + preferences_changed = lambda save: Bar.on_preferences_changed({'save': save, |
405 | + 'add_bookmarks_to_beginning': False, |
406 | + 'max_bookmarks': 15}) |
407 | + |
408 | + new_path_names = {new_paths[0]:'11', new_paths[1]:'22', new_paths[2]:'33'} |
409 | + Bar.paths = list(new_paths) |
410 | + preferences_changed(True) |
411 | + Bar._reload_bar() |
412 | + |
413 | + def rename_check(label, path, paths_names, path_names_uistate): |
414 | + self.assertEqual(button.get_label(), label) |
415 | + self.assertEqual(button.zim_path, path) |
416 | + self.assertEqual(Bar.paths_names, paths_names) |
417 | + self.assertEqual(self.uistate['bookmarks_names'], path_names_uistate) |
418 | + |
419 | + button = gtk.Button(label = new_paths[0], use_underline = False) |
420 | + button.zim_path = new_paths[0] |
421 | + rename_check(new_paths[0], new_paths[0], {}, {}) |
422 | + |
423 | + Clipboard.set_text('new name') |
424 | + Bar.rename_bookmark(button) |
425 | + rename_check('new name', new_paths[0], {new_paths[0]:'new name'}, {new_paths[0]:'new name'}) |
426 | + preferences_changed(False) |
427 | + rename_check('new name', new_paths[0], {new_paths[0]:'new name'}, {}) |
428 | + preferences_changed(True) |
429 | + rename_check('new name', new_paths[0], {new_paths[0]:'new name'}, {new_paths[0]:'new name'}) |
430 | + Bar.rename_bookmark(button) |
431 | + rename_check(new_paths[0], new_paths[0], {}, {}) |
432 | + |
433 | + # Check delete with renaming. |
434 | + preferences_changed(True) |
435 | + paths_names_copy = dict(new_path_names) |
436 | + Bar.paths_names = dict(new_path_names) |
437 | + for key in new_path_names: |
438 | + Bar.delete(key) |
439 | + del paths_names_copy[key] |
440 | + self.assertEqual(Bar.paths_names, paths_names_copy) |
441 | + self.assertEqual(self.uistate['bookmarks_names'], Bar.paths_names) |
442 | + |
443 | + # Check delete all with renaming. |
444 | + Bar.paths_names = dict(new_path_names) |
445 | + Bar.delete_all() |
446 | + self.assertEqual(Bar.paths_names, {}) |
447 | + self.assertEqual(self.uistate['bookmarks_names'], {}) |
448 | + |
449 | + # Check change bookmark with renaming. |
450 | + new_path_names = {new_paths[0]:'11', new_paths[1]:'22', new_paths[2]:'33'} |
451 | + |
452 | + Bar.paths = list(new_paths) |
453 | + Bar.paths_names = dict(new_path_names) |
454 | + paths_names_copy = dict(new_path_names) |
455 | + _name = paths_names_copy.pop(new_paths[0]) |
456 | + paths_names_copy['new path'] = _name |
457 | + Bar.change_bookmark(new_paths[0], 'new path') |
458 | + self.assertEqual(Bar.paths_names, paths_names_copy) |
459 | + self.assertEqual(Bar.paths, ['new path'] + list(new_paths[1:])) |
460 | + |
461 | + |
462 | + def testPreferences(self): |
463 | + '''Check preferences: full/short page names, save option, |
464 | + max number of bookmarks.''' |
465 | + |
466 | + # Check short page names. |
467 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
468 | + self.uistate['show_full_page_name'] = False |
469 | + for path in self.PATHS: |
470 | + Bar._add_new(path) |
471 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
472 | + for i, button in enumerate(Bar.container.get_children()[2:]): |
473 | + self.assertEqual(self.PATHS[i], button.zim_path) |
474 | + self.assertEqual(Path(self.PATHS[i]).basename, button.get_label()) |
475 | + |
476 | + # Show full page names. |
477 | + Bar.toggle_show_full_page_name() |
478 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
479 | + for i, button in enumerate(Bar.container.get_children()[2:]): |
480 | + self.assertEqual(self.PATHS[i], button.zim_path) |
481 | + self.assertEqual(self.PATHS[i], button.get_label()) |
482 | + |
483 | + # Check save option. |
484 | + self.uistate['bookmarks'] = list(self.PATHS) |
485 | + self.uistate['bookmarks_names'] = dict(self.PATHS_NAMES) |
486 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
487 | + self.assertEqual(Bar.paths, list(self.PATHS)) |
488 | + self.assertEqual(Bar.paths_names, self.PATHS_NAMES) |
489 | + |
490 | + self.uistate['bookmarks'] = [] |
491 | + self.uistate['bookmarks_names'] = {} |
492 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
493 | + self.assertEqual(Bar.paths, []) |
494 | + self.assertEqual(Bar.paths_names, {}) |
495 | + |
496 | + # Get pages to check max number of bookmarks. |
497 | + pagelist = set(self.index.list_pages(None)) |
498 | + _enhanced_pagelist = set() |
499 | + for page in pagelist: |
500 | + _enhanced_pagelist.update( set(self.index.list_pages(page)) ) |
501 | + if len(_enhanced_pagelist) > 20: |
502 | + break |
503 | + pagelist.update(_enhanced_pagelist) |
504 | + pagelist = [a.name for a in pagelist if a.exists()] |
505 | + self.assertTrue(len(pagelist) > 20) |
506 | + |
507 | + def preferences_changed(save, max_b): |
508 | + Bar.on_preferences_changed({ |
509 | + 'save': save, |
510 | + 'add_bookmarks_to_beginning': False, |
511 | + 'max_bookmarks': max_b}) |
512 | + |
513 | + # Check that more than max bookmarks can be loaded at start. |
514 | + self.uistate['bookmarks'] = pagelist |
515 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
516 | + self.assertEqual(pagelist, Bar.paths) |
517 | + preferences_changed(True, 5) |
518 | + self.assertEqual(pagelist, Bar.paths) |
519 | + self.assertEqual(pagelist, self.uistate['bookmarks']) |
520 | + |
521 | + # Set maximum number of bookmarks. |
522 | + self.uistate['bookmarks'] = [] |
523 | + Bar = BookmarkBar(self.ui, self.uistate, get_page_func = lambda: '') |
524 | + for max_bookmarks in (5, 10, 15, 20): |
525 | + preferences_changed(False, max_bookmarks) |
526 | + for page in pagelist: |
527 | + Bar._add_new(page) |
528 | + self.assertEqual(len(Bar.paths), max_bookmarks) |
529 | + self.assertEqual(Bar.paths, pagelist[:max_bookmarks]) |
530 | + Bar.delete_all() |
531 | + |
532 | + # Check 'save' option in preferences. |
533 | + for i, path in enumerate(self.PATHS): |
534 | + preferences_changed(False, 15) |
535 | + Bar._add_new(path) |
536 | + self.assertEqual(self.uistate['bookmarks'], []) |
537 | + preferences_changed(True, 15) |
538 | + self.assertEqual(self.uistate['bookmarks'], list(self.PATHS[:i+1])) |
539 | + self.assertEqual(self.uistate['bookmarks'], list(self.PATHS)) |
540 | + |
541 | + |
542 | +class MockUI(tests.MockObject): |
543 | + page = None |
544 | + notebook = None |
545 | + |
546 | |
547 | === modified file 'zim/plugins/bookmarksbar.py' |
548 | --- zim/plugins/bookmarksbar.py 2015-10-08 18:31:40 +0000 |
549 | +++ zim/plugins/bookmarksbar.py 2016-09-28 12:26:36 +0000 |
550 | @@ -1,6 +1,7 @@ |
551 | # -*- coding: utf-8 -*- |
552 | |
553 | -# Copyright 2015 Pavel_M <plprgt@gmail.com>. |
554 | +# Copyright 2015-2016 Pavel_M <plprgt@gmail.com>, |
555 | +# released under the GNU GPL version 3. |
556 | # This plugin is for Zim program by Jaap Karssenberg <jaap.karssenberg@gmail.com>. |
557 | # |
558 | # This plugin uses an icon from Tango Desktop Project (http://tango.freedesktop.org/) |
559 | @@ -21,9 +22,6 @@ |
560 | import logging |
561 | logger = logging.getLogger('zim.plugins.bookmarksbar') |
562 | |
563 | -# Constant for max number of bookmarks in the bar. |
564 | -MAX_BOOKMARKS = 15 |
565 | - |
566 | # Keyboard shortcut constants. |
567 | BM_TOGGLE_BAR_KEY ='F4' |
568 | BM_ADD_BOOKMARK_KEY ='<alt>1' |
569 | @@ -40,6 +38,7 @@ |
570 | |
571 | plugin_preferences = ( |
572 | # key, type, label, default |
573 | + ('max_bookmarks', 'int', _('Maximum number of bookmarks'), 15, (5, 20)), # T: plugin preference |
574 | ('save', 'bool', _('Save bookmarks'), True), # T: preferences option |
575 | ('add_bookmarks_to_beginning', 'bool', _('Add new bookmarks to the beginning of the bar'), False), # T: preferences option |
576 | ) |
577 | @@ -70,7 +69,7 @@ |
578 | def __init__(self, plugin, window): |
579 | WindowExtension.__init__(self, plugin, window) |
580 | self.widget = BookmarkBar(self.window.ui, self.uistate, |
581 | - self.window.pageview.get_page) |
582 | + self.window.pageview.get_page) |
583 | self.widget.show_all() |
584 | |
585 | # Add a new option to the Index popup menu. |
586 | @@ -149,10 +148,12 @@ |
587 | self.uistate = uistate |
588 | self.save_flag = False # if True save bookmarks in config |
589 | self.add_bookmarks_to_beginning = False # add new bookmarks to the end of the bar |
590 | + self.max_bookmarks = False # maximum number of bookmarks |
591 | self._get_page = get_page_func # function to get current page |
592 | |
593 | # Create button to add new bookmarks. |
594 | self.plus_button = IconsButton(gtk.STOCK_ADD, gtk.STOCK_REMOVE, relief = False) |
595 | + self.plus_button.set_tooltip_text(_('Add bookmark/Show settings')) |
596 | self.plus_button.connect('clicked', lambda o: self.add_new_page()) |
597 | self.plus_button.connect('button-release-event', self.do_plus_button_popup_menu) |
598 | self.pack_start(self.plus_button, expand = False) |
599 | @@ -164,7 +165,7 @@ |
600 | # Toggle between full/short page names. |
601 | self.uistate.setdefault('show_full_page_name', False) |
602 | |
603 | - # Save path to use later in Cut/Paste menu. |
604 | + # Save path to use later in Copy/Paste menu. |
605 | self._saved_bookmark = None |
606 | |
607 | self.paths = [] # list of bookmarks as string objects |
608 | @@ -173,7 +174,8 @@ |
609 | # Add pages from config to the bar. |
610 | for path in self.uistate['bookmarks']: |
611 | page = self.ui.notebook.get_page(Path(path)) |
612 | - self.add_new_page(page, reload_bar = False) |
613 | + if page.exists() and (page.name not in self.paths): |
614 | + self.paths.append(page.name) |
615 | |
616 | self.paths_names = {} # dict of changed names of bookmarks |
617 | self.uistate.setdefault('bookmarks_names', {}) |
618 | @@ -189,46 +191,46 @@ |
619 | except: |
620 | logger.error('BookmarksBar: Error while loading path_names.') |
621 | |
622 | - self._reload_bar() |
623 | + # Look for new pages to mark corresponding bookmarks in the bar. |
624 | + self.connectto(self.ui, 'open-page', self.on_open_page) |
625 | |
626 | # Delete a bookmark if a page is deleted. |
627 | self.connectto(self.ui.notebook.index, 'page-deleted', |
628 | lambda obj, path: self.delete(path.name)) |
629 | |
630 | - def add_new_page(self, page = None, reload_bar = True): |
631 | + def on_open_page(self, ui, page, path): |
632 | + '''If a page is present as a bookmark than select it.''' |
633 | + pagename = page.name |
634 | + for button in self.container.get_children()[2:]: |
635 | + if button.zim_path == pagename: |
636 | + button.set_active(True) |
637 | + else: |
638 | + button.set_active(False) |
639 | + |
640 | + def add_new_page(self, page = None): |
641 | ''' |
642 | Add new page as bookmark to the bar. |
643 | :param page: L{Page}, if None takes currently opened page, |
644 | - :reload_bar: if True reload the bar. |
645 | ''' |
646 | if not page: |
647 | page = self._get_page() |
648 | |
649 | if page.exists(): |
650 | - return self._add_new(page.name, self.add_bookmarks_to_beginning, reload_bar) |
651 | - |
652 | - def _add_new(self, path, add_bookmarks_to_beginning = False, reload_bar = True): |
653 | + return self._add_new(page.name, self.add_bookmarks_to_beginning) |
654 | + |
655 | + def _add_new(self, path, add_bookmarks_to_beginning = False): |
656 | '''Add bookmark to the bar. |
657 | :param path: path as a string object |
658 | :param add_bookmarks_to_beginning: bool, |
659 | add new bookmarks to the beginning of the bar, |
660 | - :reload_bar: if True reload the bar. |
661 | ''' |
662 | if path in self.paths: |
663 | logger.debug('BookmarksBar: path is already in the bar.') |
664 | - |
665 | - # Temporary change icon for plus_button to show |
666 | - # that bookmark is already in the bar. |
667 | - def _change_icon(): |
668 | - '''Function to be called only once.''' |
669 | - self.plus_button.change_state() |
670 | - return False |
671 | - self.plus_button.change_state() |
672 | - gobject.timeout_add(300, _change_icon) |
673 | + self.plus_button.blink() |
674 | return False |
675 | |
676 | # Limit max number of bookmarks. |
677 | - if len(self.paths) >= MAX_BOOKMARKS: |
678 | + if self.max_bookmarks and (len(self.paths) >= self.max_bookmarks): |
679 | logger.debug('BookmarksBar: max number of bookmarks is achieved.') |
680 | return False |
681 | |
682 | @@ -238,7 +240,7 @@ |
683 | else: |
684 | self.paths.append(path) |
685 | |
686 | - if reload_bar: self._reload_bar() |
687 | + self._reload_bar() |
688 | |
689 | def delete(self, path): |
690 | ''' |
691 | @@ -284,8 +286,13 @@ |
692 | |
693 | if new_path and (new_path not in self.paths) and (new_path != old_path): |
694 | self.paths[self.paths.index(old_path)] = new_path |
695 | - self.paths_names.pop(old_path, None) |
696 | + name = self.paths_names.pop(old_path, None) |
697 | + if name: |
698 | + self.paths_names[new_path] = name |
699 | + |
700 | self._reload_bar() |
701 | + else: |
702 | + self.plus_button.blink() |
703 | |
704 | def move_bookmark(self, first, second, direction): |
705 | ''' |
706 | @@ -350,7 +357,7 @@ |
707 | def do_bookmarks_popup_menu(self, button, event): |
708 | '''Handler for button-release-event, triggers popup menu for bookmarks.''' |
709 | if event.button != 3: |
710 | - return False |
711 | + return False |
712 | |
713 | path = button.zim_path |
714 | |
715 | @@ -371,13 +378,12 @@ |
716 | (_('Remove'), lambda o: self.delete(path)), # T: menu item |
717 | (_('Remove All'), lambda o: self.delete_all(True)), # T: menu item |
718 | ('separator', ''), |
719 | - (_('Open in New Window'), lambda o: self.ui.open_new_window(Path(path))), # T: menu item |
720 | - ('separator', ''), |
721 | ('gtk-copy', lambda o: set_save_bookmark(path)), |
722 | ('gtk-paste', lambda o: self.move_bookmark(self._saved_bookmark, path, direction)), |
723 | ('separator', ''), |
724 | + (_('Open in New Window'), lambda o: self.ui.open_new_window(Path(path))), # T: menu item |
725 | + ('separator', ''), |
726 | (rename_button_text, lambda o: self.rename_bookmark(button)), |
727 | - ('separator', ''), |
728 | (_('Set to Current Page'), lambda o: self.change_bookmark(path)) ) # T: menu item |
729 | |
730 | for name, func in main_menu_items: |
731 | @@ -412,6 +418,10 @@ |
732 | self.uistate['bookmarks'] = [] |
733 | self.uistate['bookmarks_names'] = {} |
734 | |
735 | + if self.max_bookmarks != preferences['max_bookmarks']: |
736 | + self.max_bookmarks = preferences['max_bookmarks'] |
737 | + self._reload_bar() # to update plus_button |
738 | + |
739 | def _get_short_page_name(self, name): |
740 | ''' |
741 | Function to return short name for the page. |
742 | @@ -430,6 +440,12 @@ |
743 | for button in self.container.get_children()[2:]: |
744 | self.container.remove(button) |
745 | |
746 | + page = self._get_page() |
747 | + if page: |
748 | + pagename = page.name |
749 | + else: |
750 | + pagename = None |
751 | + |
752 | for path in self.paths: |
753 | if path in self.paths_names: |
754 | name = self.paths_names[path] |
755 | @@ -437,16 +453,19 @@ |
756 | name = self._get_short_page_name(path) |
757 | else: |
758 | name = path |
759 | - button = gtk.Button(label = name, use_underline = False) |
760 | + button = gtk.ToggleButton(label = name, use_underline = False) |
761 | button.set_tooltip_text(path) |
762 | button.zim_path = path |
763 | + if path == pagename: |
764 | + button.set_active(True) |
765 | + |
766 | button.connect('clicked', self.on_bookmark_clicked) |
767 | button.connect('button-release-event', self.do_bookmarks_popup_menu) |
768 | button.show() |
769 | self.container.add(button) |
770 | |
771 | # 'Disable' plus_button if max bookmarks is reached. |
772 | - if len(self.paths) >= MAX_BOOKMARKS: |
773 | + if self.max_bookmarks and (len(self.paths) >= self.max_bookmarks): |
774 | self.plus_button.change_state(False) |
775 | else: |
776 | self.plus_button.change_state(True) |
777 | @@ -501,3 +520,13 @@ |
778 | self._enabled_state = not self._enabled_state |
779 | self.show_all() |
780 | |
781 | + def blink(self): |
782 | + '''Quickly change an icon to show |
783 | + that bookmark can't be added/changed.''' |
784 | + |
785 | + def change_icon(): |
786 | + '''Function to be called only once.''' |
787 | + self.change_state() |
788 | + return False |
789 | + self.change_state() |
790 | + gobject.timeout_add(300, change_icon) |