Remove pages OK and Cancel dialog box

When the user asks to perform an irreversible action, such as removing a tab page, it's normal to ask for confirmation of the action. You're undoubtedly familiar with the standard Windows OK/Cancel dialog box, which gives the user the choice of whether to continue with the action or to abort.

This is actually our old friend the system message box.

In case you've forgotten, the most useful overload of Show is as follows:

MessageBox.Show(String, String,

MessageBoxButtons, MessageBoxIcon)

The two strings are the text and caption (body and title) of the message box.

When you used the message box to alert the user of errors loading or saving a file, you only had an OK button. You specified this by passing in MessageBoxButtons.OK.

You can create a message box with different buttons by providing a different member of the MessageBoxButtons enumeration in the call to Show. The possible options are listed in table 6.1.

Table 6.1 Members of the MessageBoxButtons enumeration for specifying the buttons on the system message

MessageBoxButtons enumeration member

Effect

AbortRetrylgnore OK

OKCancel

RetryCancel

YesNo

YesNoCancel

The message box contains Abort, Retry, and Ignore buttons.

The message box contains an OK button.

The message box contains OK and Cancel buttons.

The message box contains Retry and Cancel buttons.

The message box contains Yes and No buttons.

The message box contains Yes, No, and Cancel buttons.

You can tell which button the user selected by the return value of Show, which will be a member of the DialogResult enumeration. Every possible button has a corresponding member on DialogResult. Table 6.2 lists all the members.

Table 6.2 Members of the DialogResult enumeration for interpreting the return value of a dialog or message box

DialogResult enumeration member

Meaning

Abort

The dialog box return value is Abort (usually sent from a button labeled Abort).

Cancel

The dialog box return value is Cancel (usually sent from a button labeled Cancel).

Ignore

The dialog box return value is Ignore (usually sent from a button labeled Ignore).

No

The dialog box return value is No (usually sent from a button labeled No).

None

Nothing is returned from the dialog box. This means that the modal dialog box continues running.

OK

The dialog box return value is OK (usually sent from a button labeled OK).

Retry

The dialog box return value is Retry (usually sent from a button labeled Retry).

Yes

The dialog box return value is Yes (usually sent from a button labeled Yes).

For our use case, MessageBoxButtons.OkCancel seems like the right choice. Only MessageBoxIcon is left to choose; the options are displayed in table 6.3.

Table 6.3 Members of the MessageBoxIcon enumeration for specifying the icon in a message box

MessageBoxIcon enumeration member

Icon description

Asterisk

The message box contains a symbol consisting of a lowercase letter i in a circle.

Error

The message box contains a symbol consisting of a white X in a circle with a red background.

Exclamation

The message box contains a symbol consisting of an exclamation point in a triangle with a yellow background.

Hand

The message box contains a symbol consisting of a white X in a circle with a red background.

Information

The message box contains a symbol consisting of a lowercase letter i in a circle.

None

The message box contain no symbols.

Question

The message box contains a symbol consisting of a question mark in a circle.

Stop

The message box contains a symbol consisting of a white X in a circle with a red background.

Warning

The message box contains a symbol consisting of an exclamation point in a triangle with a yellow background.

Because we're asking a question, MessageBox.Question seems appropriate. Now that that's settled, you're ready to write RemoveCommand. Because you'll have several commands for working with tab pages and they'll all be short, let's put them in a module called tabcommands.py.

The full call to MessageBox.Show looks like the following:

result = MessageBox.Show("Are you sure?", "Delete Page" MessageBoxButtons.OKCancel, MessageBoxIcon.Question)

result will then either be DialogResult.OK or DialogResult.Cancel. Now that you know how to use the message box, you need to build the infrastructure that can act on the user's choice. THE CODE BEHIND

To fully implement a RemovePage command, there are three distinct steps:

1 Ask the user for confirmation.

2 Remove the currently visible tab.

3 Delete the corresponding page from the model.

Because the first step triggers the following two, you should implement those first. But before that, we need to avoid a potential bug.

There's always the possibility that the user will try and activate the command after there are no pages left. You need to ensure that this situation doesn't cause MultiDoc to crash. It's the controller's job to synchronize the model and the view, so the right place to implement this is in the tab controller.

It would be good to check whether there's at least one tab page before displaying the message box. You can tell whether a tab control has any pages in a couple of ways; the number of pages will be 0, and the SelectedIndex property will return -1. To check whether there are any pages, you can add a property hasPages to the tab controller. This wraps a simple function (a lambda) that checks SelectedIndex. It needs to return False if the result is -1; otherwise, True.

hasPages = property(lambda self: self.tabControl.SelectedIndex != -1)

To delete the current page, you need to delete the currently selected index from the document's list of pages. You also need to remove the current visible tab page from the TabPages collection.

Listing 6.4 shows the implementation of deletePage. Even though you intend to check hasPages before asking the user to confirm page deletion, you should still check inside this method. This method is now part of the public API of the TabController and should be safe against being called when there are no pages.

0 -1

Post a comment