~fmos/zim/features

« back to all changes in this revision

Viewing changes to zim/gui/__init__.py

  • Committer: Fabian Moser
  • Date: 2011-01-08 18:26:21 UTC
  • mfrom: (297.1.32 pyzim-trunk)
  • Revision ID: e-mail@fabianmoser.at-20110108182621-5k8ymh4s9b7lnfkf
Merged main branch and updated sidepane registration for the tag tree plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
from zim.index import LINK_DIR_BACKWARD
41
41
from zim.config import data_file, config_file, data_dirs, ListDict, value_is_coord
42
42
from zim.parsing import url_encode, URL_ENCODE_DATA, is_win32_share_re
43
 
from zim.history import History, HistoryRecord
 
43
from zim.history import History, HistoryPath
44
44
from zim.gui.pathbar import NamespacePathBar, RecentPathBar, HistoryPathBar
45
45
from zim.gui.pageindex import PageIndex
46
46
from zim.gui.pageview import PageView
47
47
from zim.gui.widgets import ui_environment, gtk_window_set_default_icon, \
48
48
        Button, MenuButton, \
49
49
        Window, Dialog, \
50
 
        ErrorDialog, QuestionDialog, FileDialog, ProgressBarDialog, MessageDialog
 
50
        ErrorDialog, QuestionDialog, FileDialog, ProgressBarDialog, MessageDialog, \
 
51
        PromptExistingFileDialog
51
52
from zim.gui.clipboard import Clipboard
52
53
from zim.gui.applications import ApplicationManager, CustomToolManager
53
54
 
258
259
        * close-page (page)
259
260
          Called when closing a page, typically just before a new page is opened
260
261
          and before closing the application
 
262
        * new-window (window)
 
263
          Called when a new window is created, can be used as a hook by plugins
261
264
        * preferences-changed
262
265
          Emitted after the user changed the preferences
263
266
          (typically triggered by the preferences dialog)
273
276
        __gsignals__ = {
274
277
                'open-page': (gobject.SIGNAL_RUN_LAST, None, (object, object)),
275
278
                'close-page': (gobject.SIGNAL_RUN_LAST, None, (object,)),
 
279
                'new-window': (gobject.SIGNAL_RUN_LAST, None, (object,)),
276
280
                'preferences-changed': (gobject.SIGNAL_RUN_LAST, None, ()),
277
281
                'readonly-changed': (gobject.SIGNAL_RUN_LAST, None, ()),
278
282
                'quit': (gobject.SIGNAL_RUN_LAST, None, ()),
333
337
                        if not self.preferences['GtkInterface'].get(type):
334
338
                                default = manager.get_default_helper(type)
335
339
                                if default:
336
 
                                        self.preferences['GtkInterface'].setdefault(type, default.key)
 
340
                                        self.preferences['GtkInterface'][type] = default.key
337
341
                                else:
 
342
                                        self.preferences['GtkInterface'][type] = None
338
343
                                        logger.warn('No helper application defined for %s', type)
339
344
 
340
345
                self.mainwindow = MainWindow(self, fullscreen, geometry)
671
676
                config file. Each preference is a tuple consisting of:
672
677
 
673
678
                * the key in the config file
674
 
                * an option type (see Dialog.add_fields() for more details)
 
679
                * an option type (see InputForm() for more details)
675
680
                * a category (the tab in which the option will be shown)
676
681
                * a label to show in the dialog
677
682
                * a default value
685
690
                                register.setdefault(category, [])
686
691
                                register[category].append((section, key, type, label))
687
692
 
 
693
 
 
694
        def register_new_window(self, window):
 
695
                '''Called by windows and dialog to register themselves with
 
696
                the application. Used e.g. by plugins that want to add some
 
697
                widget to specific windows.
 
698
                '''
 
699
                #~ print 'WINDOW:', window
 
700
                self.emit('new-window', window)
 
701
 
 
702
        def do_new_window(self, window):
 
703
                pass # TODO: keep register of pageviews
 
704
 
688
705
        def get_path_context(self):
689
706
                '''Returns the current 'context' for actions that want a path to start
690
707
                with. Asks the mainwindow for a selected page, defaults to the
793
810
        def open_page(self, path=None):
794
811
                '''Emit the open-page signal. The argument 'path' can either be a Page
795
812
                or a Path object. If 'page' is None a dialog is shown
796
 
                to specify the page. If 'path' is a HistoryRecord we assume that this
 
813
                to specify the page. If 'path' is a HistoryPath we assume that this
797
814
                call is the result of a history action and the page is not added to
798
815
                the history. The original path object is given as the second argument
799
816
                in the signal, so handlers can inspect how this method was called.
831
848
                parent = self.actiongroup.get_action('open_page_parent')
832
849
                child = self.actiongroup.get_action('open_page_child')
833
850
 
834
 
                if isinstance(path, HistoryRecord):
 
851
                if isinstance(path, HistoryPath):
835
852
                        historyrecord = path
836
853
                        self.history.set_current(path)
837
854
                        back.set_sensitive(not path.is_first)
949
966
                        if '\n' in name:
950
967
                                name, _ = name.split('\n', 1)
951
968
                        name = self.notebook.cleanup_pathname(name.replace(':', ''), purge=True)
 
969
                elif isinstance(name, Path):
 
970
                        name = name.name
 
971
                        name = self.notebook.cleanup_pathname(name, purge=True)
952
972
                else:
953
973
                        name = self.notebook.cleanup_pathname(name, purge=True)
 
974
 
954
975
                path = self.notebook.resolve_path(name)
955
976
                page = self.notebook.get_new_page(path)
956
 
                page.parse('plain', text)
 
977
                page.parse('wiki', text) # FIXME format hard coded
957
978
                self.notebook.store_page(page)
958
979
                if open_page:
959
980
                        self.open_page(page)
961
982
 
962
983
        def append_text_to_page(self, name, text):
963
984
                '''Append text to an (exising) page'''
 
985
                if isinstance(name, Path):
 
986
                        name = name.name
964
987
                path = self.notebook.resolve_path(name)
965
988
                page = self.notebook.get_page(path)
966
 
                page.parse('plain', text, append=True)
 
989
                page.parse('wiki', text, append=True) # FIXME format hard coded
967
990
                self.notebook.store_page(page)
968
991
 
969
992
        def open_new_window(self, page=None):
1157
1180
                self.open_page(self.notebook.get_page(self.page))
1158
1181
 
1159
1182
        def attach_file(self, path=None):
 
1183
                '''Show the AttachFileDialog'''
1160
1184
                AttachFileDialog(self, path=path).run()
1161
1185
 
 
1186
        def do_attach_file(self, path, file, force_overwrite=False):
 
1187
                '''Callback for AttachFileDialog and InsertImageDialog
 
1188
                When 'force_overwrite' is False the user will be prompted in
 
1189
                case the new file has the same name as an existing attachment.
 
1190
                Returns the (new) filename or None when the action was canceled.
 
1191
                '''
 
1192
                namechanged = False
 
1193
                dir = self.notebook.get_attachments_dir(path)
 
1194
                if dir is None:
 
1195
                        raise Error, '%s does not have an attachments dir' % path
 
1196
 
 
1197
                dest = dir.file(file.basename)
 
1198
                if dest.exists() and not force_overwrite:
 
1199
                        dialog = PromptExistingFileDialog(self, dest)
 
1200
                        dest = dialog.run()
 
1201
                        if dest is None:
 
1202
                                return None     # dialog was cancelled
 
1203
 
 
1204
                file.copyto(dest)
 
1205
                return dest
 
1206
 
1162
1207
        def open_file(self, file):
1163
1208
                '''Open either a File or a Dir in the file browser'''
1164
1209
                assert isinstance(file, (File, Dir))
1524
1569
                        return True # Do not destroy - let close() handle it
1525
1570
                self.connect('delete-event', do_delete_event)
1526
1571
 
1527
 
                vbox = gtk.VBox()
1528
 
                self.add(vbox)
 
1572
                # setup the window layout
 
1573
                from zim.gui.widgets import TOP, BOTTOM, TOP_PANE, LEFT_PANE
1529
1574
 
1530
1575
                # setup menubar and toolbar
1531
1576
                self.add_accel_group(ui.uimanager.get_accel_group())
1532
1577
                self.menubar = ui.uimanager.get_widget('/menubar')
1533
1578
                self.toolbar = ui.uimanager.get_widget('/toolbar')
1534
1579
                self.toolbar.connect('popup-context-menu', self.do_toolbar_popup)
1535
 
                vbox.pack_start(self.menubar, False)
1536
 
                vbox.pack_start(self.toolbar, False)
 
1580
                self.add_bar(self.menubar, TOP)
 
1581
                self.add_bar(self.toolbar, TOP)
1537
1582
 
1538
 
                # split window in side pane and editor
1539
 
                self.hpane = gtk.HPaned()
1540
 
                self.hpane.set_position(175)
1541
 
                vbox.add(self.hpane)
1542
 
                self.sidepane = gtk.Notebook()
1543
 
                self.hpane.add1(self.sidepane)
 
1583
                self.sidepane = self._zim_window_left # FIXME - get rid of sidepane attribute
1544
1584
 
1545
1585
                self.sidepane.connect('key-press-event',
1546
1586
                        lambda o, event: event.keyval == KEYVAL_ESC
1547
1587
                                and self.toggle_sidepane())
1548
1588
 
1549
1589
                self.pageindex = PageIndex(ui)
1550
 
                self.sidepane.append_page(self.pageindex, None)
1551
 
 
1552
 
                vbox2 = gtk.VBox()
1553
 
                self.hpane.add2(vbox2)
 
1590
                self.add_tab(_('Index'), self.pageindex, LEFT_PANE)
 
1591
 
 
1592
                def check_focus_sidepane(window, widget):
 
1593
                        focus = widget == self.pageindex
 
1594
                                # FIXME - what if we have more widgets in side pane ?
 
1595
                        if not focus:
 
1596
                                self.on_sidepane_lost_focus()
 
1597
 
 
1598
                self.connect('set-focus', check_focus_sidepane)
1554
1599
 
1555
1600
                self.pathbar = None
1556
1601
                self.pathbar_box = gtk.HBox() # FIXME other class for this ?
1557
1602
                self.pathbar_box.set_border_width(3)
1558
 
                vbox2.pack_start(self.pathbar_box, False)
 
1603
                self.add_widget(self.pathbar_box, TOP_PANE, TOP)
1559
1604
 
1560
1605
                self.pageview = PageView(ui)
1561
1606
                self.pageview.view.connect_after(
1562
1607
                        'toggle-overwrite', self.do_textview_toggle_overwrite)
1563
 
                vbox2.add(self.pageview)
 
1608
                self.add(self.pageview)
1564
1609
 
1565
1610
                # create statusbar
1566
1611
                hbox = gtk.HBox(spacing=0)
1567
 
                vbox.pack_start(hbox, False, True, False)
 
1612
                self.add_bar(hbox, BOTTOM)
1568
1613
 
1569
1614
                self.statusbar = gtk.Statusbar()
1570
1615
                if ui_environment['platform'] == 'maemo':
1652
1697
                group = gtk.AccelGroup()
1653
1698
                group.connect_group( # <Alt><Space>
1654
1699
                        space, gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE,
1655
 
                        self.do_switch_focus)
 
1700
                        self.toggle_focus_sidepane)
1656
1701
 
1657
1702
                if self.ui.preferences['GtkInterface']['toggle_on_ctrlspace']:
1658
1703
                        group.connect_group( # <Ctrl><Space>
1659
1704
                                space, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE,
1660
 
                                self.do_switch_focus)
 
1705
                                self.toggle_focus_sidepane)
1661
1706
 
1662
1707
                self.add_accel_group(group)
1663
1708
                self._switch_focus_accelgroup = group
1783
1828
                if show:
1784
1829
                        self.sidepane.set_no_show_all(False)
1785
1830
                        self.sidepane.show_all()
1786
 
                        self.hpane.set_position(self.uistate['sidepane_pos'])
 
1831
                        self._zim_window_left_pane.set_position(self.uistate['sidepane_pos'])
1787
1832
                        self.pageindex.grab_focus()
1788
1833
                else:
1789
 
                        self.uistate['sidepane_pos'] = self.hpane.get_position()
 
1834
                        self.uistate['sidepane_pos'] = self._zim_window_left_pane.get_position()
1790
1835
                        self.sidepane.hide_all()
1791
1836
                        self.sidepane.set_no_show_all(True)
1792
1837
                        self.pageview.grab_focus()
1794
1839
                self._sidepane_autoclose = False
1795
1840
                self.uistate['show_sidepane'] = show
1796
1841
 
1797
 
        def do_switch_focus(self, *a):
 
1842
        def toggle_focus_sidepane(self, *a):
 
1843
                '''Switch focus between the textview and the sidepane.
 
1844
                Automatically opens the sidepane if it is closed
 
1845
                (but sets a property to automatically close it again).
 
1846
                '''
1798
1847
                action = self.actiongroup.get_action('toggle_sidepane')
1799
1848
                if action.get_active():
1800
1849
                        # side pane open
1813
1862
 
1814
1863
                return True # we are called from an event handler
1815
1864
 
 
1865
        def on_sidepane_lost_focus(self):
 
1866
                action = self.actiongroup.get_action('toggle_sidepane')
 
1867
                if self._sidepane_autoclose and action.get_active():
 
1868
                        # Sidepane open and should close automatic
 
1869
                        self.toggle_sidepane(show=False)
 
1870
 
1816
1871
        def set_pathbar(self, style):
1817
1872
                '''Set the pathbar. Style can be either PATHBAR_NONE,
1818
1873
                PATHBAR_RECENT, PATHBAR_HISTORY or PATHBAR_PATH.
2008
2063
                w, h = self.get_size()
2009
2064
                if not self._fullscreen:
2010
2065
                        self.uistate['windowsize'] = (w, h)
2011
 
                self.uistate['sidepane_pos'] = self.hpane.get_position()
 
2066
                self.uistate['sidepane_pos'] = self._zim_window_left_pane.get_position()
2012
2067
 
2013
2068
        def do_textview_toggle_overwrite(self, view):
2014
2069
                state = view.get_overwrite()
2172
2227
                ErrorDialog.run(self)
2173
2228
                gobject.source_remove(id)
2174
2229
 
2175
 
 
2176
2230
class OpenPageDialog(Dialog):
2177
2231
        '''Dialog to go to a specific page. Also known as the "Jump to" dialog.
2178
2232
        Prompts for a page name and navigate to that page on 'Ok'.
2179
2233
        '''
2180
2234
 
2181
 
        def __init__(self, ui, namespace=None):
 
2235
        def __init__(self, ui):
2182
2236
                Dialog.__init__(self, ui, _('Jump to'), # T: Dialog title
2183
2237
                        button=(None, gtk.STOCK_JUMP_TO),
2184
 
                        path_context = ui.page,
2185
 
                        fields=[('name', 'page', _('Jump to Page'), None)] # T: Label for page input
 
2238
                )
 
2239
 
 
2240
                self.add_form(
 
2241
                        [('page', 'page', _('Jump to Page'), ui.page)] # T: Label for page input
2186
2242
                )
2187
2243
 
2188
2244
        def do_response_ok(self):
2189
 
                path = self.get_field('name')
 
2245
                path = self.form['page']
2190
2246
                if path:
2191
2247
                        self.ui.open_page(path)
2192
2248
                        return True
2209
2265
                                'Please note that linking to a non-existing page\n'
2210
2266
                                'also creates a new page automatically.'),
2211
2267
                        # T: Dialog text in 'new page' dialog
2212
 
                        path_context=path,
2213
 
                        fields=[
2214
 
                                #~ ('namespace', 'namespace', _('Namespace'), path.parent), # T: Input label
2215
 
                                ('name', 'page', _('Page Name'), None), # T: Input label
2216
 
                        ],
2217
2268
                        help=':Help:Pages'
2218
2269
                )
2219
2270
 
 
2271
                self.add_form([
 
2272
                        ('page', 'page', _('Page Name'), (path or ui.page)), # T: Input label
 
2273
                ] )
 
2274
 
2220
2275
                if subpage:
2221
 
                        self.inputs['name'].force_child = True
2222
 
 
2223
 
                #~ if subpage:
2224
 
                        #~ self.inputs['name'].force_child = True
2225
 
                        #~ self.inputs['namespace'].set_path(path)
2226
 
                        #~ self.inputs['namespace'].set_sensitive(False)
2227
 
 
2228
 
                #~ self.inputs['name'].grab_focus()
2229
 
 
2230
 
                # FIXME using namespace here need integration between pagename
2231
 
                # and namespace widget
 
2276
                        self.form.widgets['page'].force_child = True
2232
2277
 
2233
2278
        def do_response_ok(self):
2234
 
                path = self.get_field('name')
 
2279
                path = self.form['page']
2235
2280
                if path:
2236
2281
                        page = self.ui.notebook.get_page(path)
2237
2282
                        if page.hascontent or page.haschildren:
2238
 
                                ErrorDialog(self, _('Page exists')+': %s' % page.name).run() # T: error message
2239
 
                                return False
 
2283
                                raise Error, _('Page exists')+': %s' % page.name
2240
2284
 
2241
2285
                        template = self.ui.notebook.get_template(page)
2242
2286
                        tree = template.process_to_parsetree(self.ui.notebook, page)
2316
2360
                        raise AssertionError, 'Could not save page'
2317
2361
                        # assert statement could be optimized away
2318
2362
 
2319
 
                i = self.ui.notebook.index.n_list_links_to_tree(
2320
 
                                        self.path, zim.index.LINK_DIR_BACKWARD )
2321
 
 
2322
2363
                self.vbox.add(gtk.Label(_('Move page "%s"') % self.path.name))
2323
2364
                        # T: Heading in 'move page' dialog - %s is the page name
2324
 
                linkslabel = ngettext(
 
2365
 
 
2366
                indexpath = self.ui.notebook.index.lookup_path(self.path)
 
2367
                if indexpath:
 
2368
                        i = self.ui.notebook.index.n_list_links_to_tree(
 
2369
                                        indexpath, zim.index.LINK_DIR_BACKWARD )
 
2370
                else:
 
2371
                        i = 0
 
2372
 
 
2373
                label = ngettext(
2325
2374
                        'Update %i page linking to this page',
2326
2375
                        'Update %i pages linking to this page', i) % i
2327
2376
                        # T: label in MovePage dialog - %i is number of backlinks
2328
2377
                        # TODO update lable to reflect that links can also be to child pages
2329
2378
                self.context_page = self.path.parent
2330
 
                self.add_fields([
 
2379
                self.add_form([
2331
2380
                        ('parent', 'namespace', _('Namespace'), self.context_page),
2332
2381
                                # T: Input label for namespace to move a file to
2333
 
                        ('links', 'bool', linkslabel, True),
 
2382
                        ('update', 'bool', label),
2334
2383
                                # T: option in 'move page' dialog
2335
2384
                ])
2336
2385
 
2337
2386
                if i == 0:
2338
 
                        self.inputs['links'].set_active(False)
2339
 
                        self.inputs['links'].set_sensitive(False)
 
2387
                        self.form['update'] = False
 
2388
                        self.form.widgets['update'].set_sensitive(False)
 
2389
                else:
 
2390
                        self.form['update'] = True
2340
2391
 
2341
2392
        def do_response_ok(self):
2342
 
                parent = self.get_field('parent')
2343
 
                links = self.get_field('links')
 
2393
                parent = self.form['parent']
 
2394
                update = self.form['update']
2344
2395
                newpath = parent + self.path.basename
2345
2396
                self.hide() # hide this dialog before showing the progressbar
2346
 
                ok = self.ui.do_move_page(self.path, newpath, update_links=links)
 
2397
                ok = self.ui.do_move_page(self.path, newpath, update)
2347
2398
                if ok:
2348
2399
                        return True
2349
2400
                else:
2364
2415
                page = self.ui.notebook.get_page(self.path)
2365
2416
                existing = (page.hascontent or page.haschildren)
2366
2417
 
2367
 
                i = self.ui.notebook.index.n_list_links_to_tree(
2368
 
                                        self.path, zim.index.LINK_DIR_BACKWARD )
2369
 
 
2370
2418
                self.vbox.add(gtk.Label(_('Rename page "%s"') % self.path.name))
2371
2419
                        # T: label in 'rename page' dialog - %s is the page name
2372
 
                linkslabel = ngettext(
 
2420
 
 
2421
                indexpath = self.ui.notebook.index.lookup_path(self.path)
 
2422
                if indexpath:
 
2423
                        i = self.ui.notebook.index.n_list_links_to_tree(
 
2424
                                        indexpath, zim.index.LINK_DIR_BACKWARD )
 
2425
                else:
 
2426
                        i = 0
 
2427
 
 
2428
                label = ngettext(
2373
2429
                        'Update %i page linking to this page',
2374
2430
                        'Update %i pages linking to this page', i) % i
2375
2431
                        # T: label in MovePage dialog - %i is number of backlinks
2376
 
                        # TODO update lable to reflect that links can also be to child pages
2377
 
                self.add_fields([
2378
 
                        ('name', 'string', _('Name'), self.path.basename),
 
2432
                        # TODO update label to reflect that links can also be to child pages
 
2433
 
 
2434
                self.add_form([
 
2435
                        ('name', 'string', _('Name')),
2379
2436
                                # T: Input label in the 'rename page' dialog for the new name
2380
 
                        ('head', 'bool', _('Update the heading of this page'), existing),
2381
 
                                # T: Option in the 'rename page' dialog
2382
 
                        ('links', 'bool', linkslabel, True),
2383
 
                                # T: Option in the 'rename page' dialog
2384
 
                ])
 
2437
                        ('head', 'bool', _('Update the heading of this page')),
 
2438
                                # T: Option in the 'rename page' dialog
 
2439
                        ('update', 'bool', label),
 
2440
                                # T: Option in the 'rename page' dialog
 
2441
                ], {
 
2442
                        'name': self.path.basename,
 
2443
                        'head': existing,
 
2444
                        'update': True,
 
2445
                })
2385
2446
 
2386
2447
                if not existing:
2387
 
                        self.inputs['head'].set_active(False)
2388
 
                        self.inputs['head'].set_sensitive(False)
 
2448
                        self.form['head'] = False
 
2449
                        self.form.widgets['head'].set_sensitive(False)
2389
2450
 
2390
2451
                if i == 0:
2391
 
                        self.inputs['links'].set_active(False)
2392
 
                        self.inputs['links'].set_sensitive(False)
 
2452
                        self.form['update'] = False
 
2453
                        self.form.widgets['update'].set_sensitive(False)
2393
2454
 
2394
2455
        def do_response_ok(self):
2395
 
                name = self.get_field('name')
2396
 
                head = self.get_field('head')
2397
 
                links = self.get_field('links')
 
2456
                name = self.form['name']
 
2457
                head = self.form['head']
 
2458
                update = self.form['update']
2398
2459
                self.hide() # hide this dialog before showing the progressbar
2399
 
                ok = self.ui.do_rename_page(
2400
 
                        self.path, newbasename=name, update_heading=head, update_links=links)
 
2460
                ok = self.ui.do_rename_page(self.path, name, head, update)
2401
2461
                if ok:
2402
2462
                        return True
2403
2463
                else:
2432
2492
                label.set_markup('<b>'+short+'</b>\n\n'+long)
2433
2493
                vbox.pack_start(label, False)
2434
2494
 
2435
 
                i = self.ui.notebook.index.n_list_links_to_tree(
2436
 
                                        self.path, zim.index.LINK_DIR_BACKWARD )
2437
 
                linkslabel = ngettext(
 
2495
                indexpath = self.ui.notebook.index.lookup_path(self.path)
 
2496
                if indexpath:
 
2497
                        i = self.ui.notebook.index.n_list_links_to_tree(
 
2498
                                        indexpath, zim.index.LINK_DIR_BACKWARD )
 
2499
                else:
 
2500
                        i = 0
 
2501
 
 
2502
                label = ngettext(
2438
2503
                        'Remove links from %i page linking to this page',
2439
2504
                        'Remove links from %i pages linking to this page', i) % i
2440
2505
                        # T: label in DeletePage dialog - %i is number of backlinks
2441
2506
                        # TODO update lable to reflect that links can also be to child pages
2442
 
                self.links_checkbox = gtk.CheckButton(label=linkslabel)
 
2507
                self.links_checkbox = gtk.CheckButton(label=label)
2443
2508
                vbox.pack_start(self.links_checkbox, False)
2444
2509
 
2445
2510
                if i == 0:
2459
2524
                try:
2460
2525
                        self.ui.notebook.delete_page(self.path, update_links, callback)
2461
2526
                except Exception, error:
2462
 
                        ErrorDialog(self, error).run()
2463
2527
                        dialog.destroy()
2464
 
                        return False
 
2528
                        raise
2465
2529
                else:
2466
2530
                        dialog.destroy()
2467
2531
                        return True
2479
2543
                        self.path = path
2480
2544
                assert self.path, 'Need a page here'
2481
2545
 
2482
 
                self.dir = self.ui.notebook.get_attachments_dir(self.path)
2483
 
                if self.dir is None:
 
2546
                dir = self.ui.notebook.get_attachments_dir(self.path)
 
2547
                if dir is None:
2484
2548
                        ErrorDialog(_('Page "%s" does not have a folder for attachments') % self.path)
2485
2549
                                # T: Error dialog - %s is the full page name
2486
2550
                        raise Exception, 'Page "%s" does not have a folder for attachments' % self.path
2502
2566
                        # Similar code in zim.gui.InsertImageDialog
2503
2567
 
2504
2568
                for file in files:
2505
 
                        file.copyto(self.dir)
2506
 
                        file = self.dir.file(file.basename)
 
2569
                        file = self.ui.do_attach_file(self.path, file)
 
2570
                        if file is None:
 
2571
                                return False # Cancelled overwrite dialog
 
2572
 
2507
2573
                        pageview = self.ui.mainwindow.pageview
2508
2574
                        if self.uistate['insert_attached_images'] and file.isimage():
2509
2575
                                try: