Skip to content

DocumentWindow

Usage

A DocumentWindow is the same as a toga.MainWindow, except that it is bound to a toga.Document instance, exposed as the toga.DocumentWindow.doc attribute.

Instances of toga.DocumentWindow should be created as part of the create() method of an implementation of toga.Document.

Reference

Bases: MainWindow

Source code in core/src/toga/documents.py
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
class DocumentWindow(MainWindow):
    def __init__(self, doc: Document, *args, **kwargs):
        """Create a new document Window.

        A document window is a MainWindow (so it will have a menu bar, and *can* have a
        toolbar), bound to a document instance.

        In addition to the required `doc` argument, accepts the same arguments as
        [`Window`][toga.Window].

        The default `on_close` handler will use the document's modification status to
        determine if the document has been modified. It will allow the window to close
        if the document is fully saved, or the user explicitly declines the opportunity
        to save.

        :param doc: The document being managed by this window
        """
        self._doc = doc
        if "on_close" not in kwargs:
            kwargs["on_close"] = self._confirm_close

        super().__init__(*args, **kwargs)

    @property
    def doc(self) -> Document:
        """The document displayed by this window."""
        return self._doc

    @property
    def _default_title(self) -> str:
        return self.doc.title

    async def _confirm_close(self, window, **kwargs):
        if self.doc.modified:
            if await self.dialog(
                toga.QuestionDialog(
                    "Save changes?",
                    (
                        "This document has unsaved changes. Do you want to save these "
                        "changes?"
                    ),
                )
            ):
                return await self.save()
        return True

    async def _commit(self):
        # Get the window into a state where new content could be opened.
        # Used by the open method on GTK/Linux to ensure the current document
        # has been saved before closing this window and opening a replacement.
        return await self._confirm_close(self)

    def _close(self):
        # When then window is closed, remove the document it is managing from the app's
        # list of managed documents.
        self._app.documents._remove(self.doc)
        super()._close()

    async def save(self):
        """Save the document associated with this window.

        If the document associated with a window hasn't been saved before, the user will
        be prompted to provide a filename.

        :returns: True if the save was successful; False if the save was aborted, or the
            document type doesn't define a [`Document.write()`][toga.Document.write]
            method.
        """
        if self.doc._writable():
            if self.doc.path:
                # Document has been saved previously; save using that filename.
                self.doc.save()
                return True
            else:
                return await self.save_as()
        return False

    async def save_as(self):
        """Save the document associated with this window under a new filename.

        The default implementation will prompt the user for a new filename, then save
        the document with that new filename.

        :returns: True if the save was successful; False if the save was aborted, or the
            document type doesn't define a [`Document.write()`][toga.Document.write]
            method.
        """
        if self.doc._writable():
            suggested_path = (
                self.doc.path if self.doc.path else f"Untitled.{self.doc.extensions[0]}"
            )
            new_path = await self.dialog(
                dialogs.SaveFileDialog("Save as...", suggested_path)
            )
            # If a filename has been returned, save using that filename.
            # If there isn't a filename, the save was cancelled.
            if new_path:
                self.doc.save(new_path)
                return True

        return False

doc property

The document displayed by this window.

__init__(doc, *args, **kwargs)

Create a new document Window.

A document window is a MainWindow (so it will have a menu bar, and can have a toolbar), bound to a document instance.

In addition to the required doc argument, accepts the same arguments as Window.

The default on_close handler will use the document's modification status to determine if the document has been modified. It will allow the window to close if the document is fully saved, or the user explicitly declines the opportunity to save.

:param doc: The document being managed by this window

Source code in core/src/toga/documents.py
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
def __init__(self, doc: Document, *args, **kwargs):
    """Create a new document Window.

    A document window is a MainWindow (so it will have a menu bar, and *can* have a
    toolbar), bound to a document instance.

    In addition to the required `doc` argument, accepts the same arguments as
    [`Window`][toga.Window].

    The default `on_close` handler will use the document's modification status to
    determine if the document has been modified. It will allow the window to close
    if the document is fully saved, or the user explicitly declines the opportunity
    to save.

    :param doc: The document being managed by this window
    """
    self._doc = doc
    if "on_close" not in kwargs:
        kwargs["on_close"] = self._confirm_close

    super().__init__(*args, **kwargs)

save() async

Save the document associated with this window.

If the document associated with a window hasn't been saved before, the user will be prompted to provide a filename.

:returns: True if the save was successful; False if the save was aborted, or the document type doesn't define a Document.write() method.

Source code in core/src/toga/documents.py
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
async def save(self):
    """Save the document associated with this window.

    If the document associated with a window hasn't been saved before, the user will
    be prompted to provide a filename.

    :returns: True if the save was successful; False if the save was aborted, or the
        document type doesn't define a [`Document.write()`][toga.Document.write]
        method.
    """
    if self.doc._writable():
        if self.doc.path:
            # Document has been saved previously; save using that filename.
            self.doc.save()
            return True
        else:
            return await self.save_as()
    return False

save_as() async

Save the document associated with this window under a new filename.

The default implementation will prompt the user for a new filename, then save the document with that new filename.

:returns: True if the save was successful; False if the save was aborted, or the document type doesn't define a Document.write() method.

Source code in core/src/toga/documents.py
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
async def save_as(self):
    """Save the document associated with this window under a new filename.

    The default implementation will prompt the user for a new filename, then save
    the document with that new filename.

    :returns: True if the save was successful; False if the save was aborted, or the
        document type doesn't define a [`Document.write()`][toga.Document.write]
        method.
    """
    if self.doc._writable():
        suggested_path = (
            self.doc.path if self.doc.path else f"Untitled.{self.doc.extensions[0]}"
        )
        new_path = await self.dialog(
            dialogs.SaveFileDialog("Save as...", suggested_path)
        )
        # If a filename has been returned, save using that filename.
        # If there isn't a filename, the save was cancelled.
        if new_path:
            self.doc.save(new_path)
            return True

    return False