diff --git a/pygtktalog/dialogs.py b/pygtktalog/dialogs.py new file mode 100644 index 0000000..fcab0a9 --- /dev/null +++ b/pygtktalog/dialogs.py @@ -0,0 +1,99 @@ +""" + Project: pyGTKtalog + Description: Simple dialogs for interact with user + Type: helper + Author: Roman 'gryf' Dobosz, gryf73@gmail.com + Created: 2009-05-12 +""" +import gtk + + +class Dialog(object): + """Show simple dialog for questions + if "OK" button pressed, return "True" + "Cancel" button return "False" + """ + + def __init__(self, dialog_type, message, secondary_msg="", title=""): + """Initialize some defaults""" + self.dialog = None + self.buttons = gtk.BUTTONS_OK + self.ok_default = False + self.message = message + self.secondary_msg = secondary_msg + self.type = dialog_type + self.title = title + + def run(self): + """Show the dialog""" + if self.dialog is None: + self.__create_dialog() + + # Change default/focus from cancel/no to ok/yes. Suitable only for + # Question dialog. + # Ofcourse, if something changes in the future, this could break + # things. + if self.ok_default: + button = self.dialog.get_children()[0].get_children()[2] + button.get_children()[self.ok_default].grab_default() + + retval = self.dialog.run() + self.dialog.destroy() + if retval == gtk.RESPONSE_OK or retval == gtk.RESPONSE_YES: + return True + return False + + def __create_dialog(self): + """Create MessageDialog widgt""" + if self.type == gtk.MESSAGE_QUESTION and \ + self.buttons not in (gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL): + self.buttons = gtk.BUTTONS_YES_NO + + self.dialog = gtk.MessageDialog(buttons=self.buttons, type=self.type, + message_format=self.message) + self.dialog.format_secondary_text(self.secondary_msg) + self.dialog.set_title(self.title) + + +def yesno(message, secondarymsg="", title="", default=False): + """Question with yes-no buttons. Returns False on 'no', True on 'yes'""" + dialog = Dialog(gtk.MESSAGE_QUESTION, message, secondarymsg, title) + dialog.buttons = gtk.BUTTONS_YES_NO + dialog.ok_default = default + return dialog.run() + +def okcancel(message, secondarymsg="", title="", default=False): + """Question with ok-cancel buttons. Returns False on 'cancel', True on + 'ok'""" + dialog = Dialog(gtk.MESSAGE_QUESTION, message, secondarymsg, title) + dialog.buttons = gtk.BUTTONS_OK_CANCEL + dialog.ok_default = default + return dialog.run() + +def info(message, secondarymsg="", title="", button=gtk.BUTTONS_OK): + """Info dialog. Button defaults to gtk.BUTTONS_OK, but can be changed with + gtk.BUTTONS_CANCEL, gtk.BUTTONS_CLOSE or gtk.BUTTONS_NONE. + Always returns True.""" + dialog = Dialog(gtk.MESSAGE_INFO, message, secondarymsg, title) + dialog.buttons = button + dialog.run() + return True + +def warn(message, secondarymsg="", title="", button=gtk.BUTTONS_OK): + """Warning dialog. Button defaults to gtk.BUTTONS_OK, but can be changed + with gtk.BUTTONS_CANCEL, gtk.BUTTONS_CLOSE or gtk.BUTTONS_NONE. + Always returns True.""" + dialog = Dialog(gtk.MESSAGE_WARNING, message, secondarymsg, title) + dialog.buttons = button + dialog.run() + return True + +def error(message, secondarymsg="", title="", button=gtk.BUTTONS_OK): + """Error dialog. Button defaults to gtk.BUTTONS_OK, but can be changed with + gtk.BUTTONS_CANCEL, gtk.BUTTONS_CLOSE or gtk.BUTTONS_NONE. + Always returns True.""" + dialog = Dialog(gtk.MESSAGE_ERROR, message, secondarymsg, title) + dialog.buttons = button + dialog.run() + return True + diff --git a/test/unit/dialogs_test.py b/test/unit/dialogs_test.py new file mode 100644 index 0000000..5dfed2e --- /dev/null +++ b/test/unit/dialogs_test.py @@ -0,0 +1,77 @@ +""" + Project: pyGTKtalog + Description: Test simple dialogs + Type: test + Author: Roman 'gryf' Dobosz, gryf73@gmail.com + Created: 2009-05-19 +""" +import unittest +import os + +import gtk + +from pygtktalog.dialogs import Dialog, yesno, okcancel, info, warn, error + + +class MessageDialogMock(gtk.MessageDialog): + """Mock class for MessageDialog, which shouldn't be displayed in a test""" + + def run(self): + """Carefull! only for MESSAGE_INFO return value is RESPONSE_OK!""" + if self.get_property('message-type') == gtk.MESSAGE_INFO: + return gtk.RESPONSE_OK + else: + return gtk.RESPONSE_CANCEL + +class TestDialog(unittest.TestCase): + """Tests for Dialog class""" + + def test_dialog_create(self): + """Test dialog creation and run method""" + # overwrite MessageDialog class in gtk module + gtk.MessageDialog = MessageDialogMock + dialog = Dialog(gtk.MESSAGE_INFO, 'msg', 'secondarymsg', 'title') + self.assertTrue(dialog.buttons == gtk.BUTTONS_OK, "dialog should have" + " gtk.BUTTONS_OK") + self.assertTrue(dialog.run(), "dialog should return True") + + dialog = Dialog(gtk.MESSAGE_QUESTION, 'msg', 'secondarymsg', 'title') + self.assertFalse(dialog.run(), "dialog should return False") + # NOTE: dialog should be run before test against buttons attribute + self.assertTrue(dialog.buttons == gtk.BUTTONS_YES_NO, + "dialog should have gtk.BUTTONS_YES_NO") + + dialog = Dialog(gtk.MESSAGE_QUESTION, 'msg', 'secondarymsg', 'title') + dialog.buttons = gtk.BUTTONS_OK + dialog.ok_default = True + self.assertFalse(dialog.run(), "dialog should return True") + + def test_error(self): + """Test error function""" + result = error('msg', 'secondarymsg', 'title') + self.assertTrue(result, "Should return True") + + def test_warn(self): + """Test warn function""" + result = warn('msg', 'secondarymsg', 'title') + self.assertTrue(result, "Should return True") + + def test_info(self): + """Test info function""" + result = info('msg', 'secondarymsg', 'title') + self.assertTrue(result, "Should return True") + + def test_yesno(self): + """Test yesno function""" + result = yesno('msg', 'secondarymsg', 'title') + self.assertFalse(result, "Should return False") + + def test_okcancel(self): + """Test yesno function""" + result = okcancel('msg', 'secondarymsg', 'title') + self.assertFalse(result, "Should return False") + + +if __name__ == "__main__": + os.chdir(os.path.join(os.path.abspath(os.path.dirname(__file__)), "../")) + unittest.main()