aboutsummaryrefslogtreecommitdiffstats
path: root/lvc/widgets/dialogs.py
diff options
context:
space:
mode:
Diffstat (limited to 'lvc/widgets/dialogs.py')
-rw-r--r--lvc/widgets/dialogs.py276
1 files changed, 276 insertions, 0 deletions
diff --git a/lvc/widgets/dialogs.py b/lvc/widgets/dialogs.py
new file mode 100644
index 0000000..b6b2b70
--- /dev/null
+++ b/lvc/widgets/dialogs.py
@@ -0,0 +1,276 @@
+# @Base: Miro - an RSS based video player application
+# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
+# Participatory Culture Foundation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# In addition, as a special exception, the copyright holders give
+# permission to link the code of portions of this program with the OpenSSL
+# library.
+#
+# You must obey the GNU General Public License in all respects for all of
+# the code used other than OpenSSL. If you modify file(s) with this
+# exception, you may extend this exception to your version of the file(s),
+# but you are not obligated to do so. If you do not wish to do so, delete
+# this exception statement from your version. If you delete this exception
+# statement from all source files in the program, then also delete it here.
+
+"""``miro.frontends.widgets.dialogs`` -- Dialog boxes for the Widget
+frontend.
+
+The difference between this module and rundialog.py is that rundialog
+handles dialog boxes that are coming from the backend code. This
+model handles dialogs that we create from the frontend
+
+One big difference is that we don't have to be as general about
+dialogs, so they can present a somewhat nicer API. One important
+difference is that all of the dialogs run modally.
+"""
+
+from lvc.widgets import widgetset
+from lvc.widgets import widgetutil
+
+class DialogButton(object):
+ def __init__(self, text):
+ self._text = text
+ def __eq__(self, other):
+ return isinstance(other, DialogButton) and self.text == other.text
+ def __str__(self):
+ return "DialogButton(%r)" % self.text
+ @property
+ def text(self):
+ return unicode(self._text)
+
+BUTTON_OK = DialogButton("OK")
+BUTTON_APPLY = DialogButton("Apply")
+BUTTON_CLOSE = DialogButton("Close")
+BUTTON_CANCEL = DialogButton("Cancel")
+BUTTON_DONE = DialogButton("Done")
+BUTTON_YES = DialogButton("Yes")
+BUTTON_NO = DialogButton("No")
+BUTTON_QUIT = DialogButton("Quit")
+BUTTON_CONTINUE = DialogButton("Continue")
+BUTTON_IGNORE = DialogButton("Ignore")
+BUTTON_IMPORT_FILES = DialogButton("Import Files")
+BUTTON_SUBMIT_REPORT = DialogButton("Submit Crash Report")
+BUTTON_MIGRATE = DialogButton("Migrate")
+BUTTON_DONT_MIGRATE = DialogButton("Don't Migrate")
+BUTTON_DOWNLOAD = DialogButton("Download")
+BUTTON_REMOVE_ENTRY = DialogButton("Remove Entry")
+BUTTON_DELETE_FILE = DialogButton("Delete File")
+BUTTON_DELETE_FILES = DialogButton("Delete Files")
+BUTTON_KEEP_VIDEOS = DialogButton("Keep Videos")
+BUTTON_DELETE_VIDEOS = DialogButton("Delete Videos")
+BUTTON_CREATE = DialogButton("Create")
+BUTTON_CREATE_FEED = DialogButton("Create Podcast")
+BUTTON_CREATE_FOLDER = DialogButton("Create Folder")
+BUTTON_CHOOSE_NEW_FOLDER = DialogButton("Choose New Folder")
+BUTTON_ADD_FOLDER = DialogButton("Add Folder")
+BUTTON_ADD = DialogButton("Add")
+BUTTON_ADD_INTO_NEW_FOLDER = DialogButton("Add Into New Folder")
+BUTTON_KEEP = DialogButton("Keep")
+BUTTON_DELETE = DialogButton("Delete")
+BUTTON_REMOVE = DialogButton("Remove")
+BUTTON_NOT_NOW = DialogButton("Not Now")
+BUTTON_CLOSE_TO_TRAY = DialogButton("Close to Tray")
+BUTTON_LAUNCH_MIRO = DialogButton("Launch Miro")
+BUTTON_DOWNLOAD_ANYWAY = DialogButton("Download Anyway")
+BUTTON_OPEN_IN_EXTERNAL_BROWSER = DialogButton(
+ "Open in External Browser")
+BUTTON_DONT_INSTALL = DialogButton("Don't Install")
+BUTTON_SUBSCRIBE = DialogButton("Subscribe")
+BUTTON_STOP_WATCHING = DialogButton("Stop Watching")
+BUTTON_RETRY = DialogButton("Retry")
+BUTTON_START_FRESH = DialogButton("Start Fresh")
+BUTTON_INCLUDE_DATABASE = DialogButton("Include Database")
+BUTTON_DONT_INCLUDE_DATABASE = DialogButton(
+ "Don't Include Database")
+
+WARNING_MESSAGE = 0
+INFO_MESSAGE = 1
+CRITICAL_MESSAGE = 2
+
+
+class ProgressDialog(widgetset.Dialog):
+ def __init__(self, title):
+ widgetset.Dialog.__init__(self, title, description='')
+ self.progress_bar = widgetset.ProgressBar()
+ self.label = widgetset.Label()
+ self.label.set_size(1.2)
+ self.vbox = widgetset.VBox(spacing=6)
+ self.vbox.pack_end(widgetutil.align_center(self.label))
+ self.vbox.pack_end(self.progress_bar)
+ self.set_extra_widget(self.vbox)
+
+ def update(self, description, progress):
+ self.label.set_text(description)
+ if progress >= 0:
+ self.progress_bar.set_progress(progress)
+ self.progress_bar.stop_pulsing()
+ else:
+ self.progress_bar.start_pulsing()
+
+class DBUpgradeProgressDialog(widgetset.Dialog):
+ def __init__(self, title, text):
+ widgetset.Dialog.__init__(self, title)
+ self.progress_bar = widgetset.ProgressBar()
+ self.top_label = widgetset.Label()
+ self.top_label.set_text(text)
+ self.top_label.set_wrap(True)
+ self.top_label.set_size_request(350, -1)
+ self.label = widgetset.Label()
+ self.vbox = widgetset.VBox(spacing=6)
+ self.vbox.pack_end(widgetutil.align_center(self.label))
+ self.vbox.pack_end(self.progress_bar)
+ self.vbox.pack_end(widgetutil.pad(self.top_label, bottom=6))
+ self.set_extra_widget(self.vbox)
+
+ def update(self, stage, stage_progress, progress):
+ self.label.set_text(stage)
+ self.progress_bar.set_progress(progress)
+
+def show_about():
+ window = widgetset.AboutDialog()
+ set_transient_for_main(window)
+ try:
+ window.run()
+ finally:
+ window.destroy()
+
+def show_message(title, description, alert_type=INFO_MESSAGE,
+ transient_for=None):
+ """Display a message to the user and wait for them to click OK"""
+ window = widgetset.AlertDialog(title, description, alert_type)
+ _set_transient_for(window, transient_for)
+ try:
+ window.add_button(BUTTON_OK.text)
+ window.run()
+ finally:
+ window.destroy()
+
+def show_choice_dialog(title, description, choices, transient_for=None):
+ """Display a message to the user and wait for them to choose an option.
+ Returns the button object chosen."""
+ window = widgetset.Dialog(title, description)
+ try:
+ for mem in choices:
+ window.add_button(mem.text)
+ response = window.run()
+ return choices[response]
+ finally:
+ window.destroy()
+
+def ask_for_string(title, description, initial_text=None, transient_for=None):
+ """Ask the user to enter a string in a TextEntry box.
+
+ description - textual description with newlines
+ initial_text - None, string or callable to pre-populate the entry box
+
+ Returns the value entered, or None if the user clicked cancel
+ """
+ window = widgetset.Dialog(title, description)
+ try:
+ window.add_button(BUTTON_OK.text)
+ window.add_button(BUTTON_CANCEL.text)
+ entry = widgetset.TextEntry()
+ entry.set_activates_default(True)
+ if initial_text:
+ if callable(initial_text):
+ initial_text = initial_text()
+ entry.set_text(initial_text)
+ window.set_extra_widget(entry)
+ response = window.run()
+ if response == 0:
+ return entry.get_text()
+ else:
+ return None
+ finally:
+ window.destroy()
+
+def ask_for_choice(title, description, choices):
+ """Ask the user to enter a string in a TextEntry box.
+
+ :param title: title for the window
+ :param description: textual description with newlines
+ :param choices: list of labels for choices
+ Returns the index of the value chosen, or None if the user clicked cancel
+ """
+ window = widgetset.Dialog(title, description)
+ try:
+ window.add_button(BUTTON_OK.text)
+ window.add_button(BUTTON_CANCEL.text)
+ menu = widgetset.OptionMenu(choices)
+ window.set_extra_widget(menu)
+ response = window.run()
+ if response == 0:
+ return menu.get_selected()
+ else:
+ return None
+ finally:
+ window.destroy()
+
+def ask_for_open_pathname(title, initial_filename=None, filters=[],
+ transient_for=None, select_multiple=False):
+ """Returns the file pathname or None.
+ """
+ window = widgetset.FileOpenDialog(title)
+ _set_transient_for(window, transient_for)
+ try:
+ if initial_filename:
+ window.set_filename(initial_filename)
+
+ if filters:
+ window.add_filters(filters)
+
+ if select_multiple:
+ window.set_select_multiple(select_multiple)
+
+ response = window.run()
+ if response == 0:
+ if select_multiple:
+ return window.get_filenames()
+ else:
+ return window.get_filename()
+ finally:
+ window.destroy()
+
+def ask_for_save_pathname(title, initial_filename=None, transient_for=None):
+ """Returns the file pathname or None.
+ """
+ window = widgetset.FileSaveDialog(title)
+ _set_transient_for(window, transient_for)
+ try:
+ if initial_filename:
+ window.set_filename(initial_filename)
+ response = window.run()
+ if response == 0:
+ return window.get_filename()
+ finally:
+ window.destroy()
+
+def ask_for_directory(title, initial_directory=None, transient_for=None):
+ """Returns the directory pathname or None.
+ """
+ window = widgetset.DirectorySelectDialog(title)
+ _set_transient_for(window, transient_for)
+ try:
+ if initial_directory:
+ window.set_directory(initial_directory)
+
+ response = window.run()
+ if response == 0:
+ return window.get_directory()
+ finally:
+ window.destroy()