aboutsummaryrefslogtreecommitdiffstats
path: root/liveusb/gui.py
diff options
context:
space:
mode:
Diffstat (limited to 'liveusb/gui.py')
-rwxr-xr-xliveusb/gui.py270
1 files changed, 270 insertions, 0 deletions
diff --git a/liveusb/gui.py b/liveusb/gui.py
new file mode 100755
index 0000000..9de97e5
--- /dev/null
+++ b/liveusb/gui.py
@@ -0,0 +1,270 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © 2008 Red Hat, Inc. All rights reserved.
+# Copyright © 2008 Kushal Das <kushal@fedoraproject.org>
+# Copyright © 2009 Mandriva. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2. This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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 Street, Fifth
+# Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks that are
+# incorporated in the source code or documentation are not subject to the GNU
+# General Public License and may only be used or replicated with the express
+# permission of Red Hat, Inc.
+#
+# Author(s): Luke Macken <lmacken@redhat.com>
+# Kushal Das <kushal@fedoraproject.org>
+# Aurelien Lefebvre <alefebvre@mandriva.com>
+
+import os
+import sys
+import logging
+
+from datetime import datetime
+from PyQt4 import QtCore, QtGui
+
+from liveusb import LiveUSBCreator, LiveUSBError, LiveUSBInterface, _
+try:
+ import dbus.mainloop.qt
+ dbus.mainloop.qt.DBusQtMainLoop(set_as_default=True)
+except:
+ pass
+
+
+class LiveUSBApp(QtGui.QApplication):
+ """ Main application class """
+ def __init__(self, opts, args):
+ QtGui.QApplication.__init__(self, args)
+ self.mywindow = LiveUSBDialog(opts)
+ self.mywindow.show()
+ try:
+ self.exec_()
+ finally:
+ self.mywindow.terminate()
+
+
+
+class ProgressThread(QtCore.QThread):
+
+ def set_data(self):
+ self.emit(QtCore.SIGNAL("maxprogress(int)"), 100)
+ self.emit(QtCore.SIGNAL("progress(int)"), 0)
+
+ def run(self):
+ return
+
+ def update(self, value):
+ # Never update to 100%
+ if value > 99:
+ tunned_value = 99
+ else:
+ tunned_value = value
+ self.emit(QtCore.SIGNAL("progress(int)"), tunned_value)
+
+ def terminate(self):
+ self.emit(QtCore.SIGNAL("progress(int)"), 100)
+ QtCore.QThread.terminate(self)
+
+
+class LiveUSBThread(QtCore.QThread):
+
+ def __init__(self, live, progress, parent=None):
+ QtCore.QThread.__init__(self, parent)
+ self.progress = progress
+ self.parent = parent
+ self.live = live
+
+ def status(self, text):
+ self.emit(QtCore.SIGNAL("status(PyQt_PyObject)"), text)
+
+ def run(self):
+ handler = LiveUSBLogHandler(self.status)
+ self.live.log.addHandler(handler)
+ now = datetime.now()
+ try:
+ if not self.live.drive:
+ raise Exception("No drive selected")
+ if not self.live.iso:
+ raise Exception("No ISO selected")
+
+ # Setup the progress bar
+ self.progress.set_data()
+ self.progress.start()
+
+ self.live.build_disk(self.progress)
+
+ duration = str(datetime.now() - now).split('.')[0]
+ self.status(_("Complete! (%s)" % duration))
+ self.progress.terminate()
+
+ except LiveUSBError, e:
+ self.status(e.message)
+
+ except Exception, e:
+ self.status(_("LiveUSB creation failed!"))
+
+ def __del__(self):
+ self.wait()
+
+
+class LiveUSBLogHandler(logging.Handler):
+
+ def __init__(self, cb):
+ logging.Handler.__init__(self)
+ self.cb = cb
+
+ def emit(self, record):
+ if record.levelname in ('INFO', 'ERROR'):
+ self.cb(record.msg)
+
+
+class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface):
+ """ Our main dialog class """
+
+ def __init__(self, opts):
+ self.in_process = False
+ QtGui.QDialog.__init__(self)
+ LiveUSBInterface.__init__(self)
+ self.opts = opts
+ self.setupUi(self)
+ self.live = LiveUSBCreator(opts=opts)
+ self.populate_devices()
+ self.progress_thread = ProgressThread()
+ self.live_thread = LiveUSBThread(live=self.live,
+ progress=self.progress_thread,
+ parent=self)
+ self.connect_slots()
+ self.confirmed = False
+
+ # Intercept all liveusb INFO log messages, and display them in the gui
+ self.handler = LiveUSBLogHandler(lambda x: self.textEdit.append(x))
+ self.live.log.addHandler(self.handler)
+ if not self.opts.verbose:
+ self.live.log.removeHandler(self.live.handler)
+
+ def populate_devices(self, *args, **kw):
+ if self.in_process:
+ return
+ self.driveBox.clear()
+ self.textEdit.clear()
+ try:
+ self.live.detect_removable_drives()
+ for device, info in self.live.drives.items():
+ driveInfo = info['name']
+ if info.has_key('model') and info['model']:
+ driveInfo += " - %s" % info['model']
+ if info.has_key('capacity') and info['capacity']:
+ driveInfo += " (%s Mb)" % str(int(info['capacity'])/1000000)
+ self.driveBox.addItem(driveInfo)
+ self.check_startbutton_state()
+ except LiveUSBError, e:
+ self.textEdit.setPlainText(e.message)
+ self.check_startbutton_state()
+
+ def connect_slots(self):
+ self.connect(self.isoBttn, QtCore.SIGNAL("clicked()"), self.selectfile)
+ self.connect(self.startButton, QtCore.SIGNAL("clicked()"), self.begin)
+ self.connect(self.live_thread, QtCore.SIGNAL("status(PyQt_PyObject)"),
+ self.status)
+ self.connect(self.live_thread, QtCore.SIGNAL("finished()"),
+ lambda: self.enable_widgets(True))
+ self.connect(self.live_thread, QtCore.SIGNAL("terminated()"),
+ lambda: self.enable_widgets(True))
+ self.connect(self.live_thread, QtCore.SIGNAL("progress(int)"),
+ self.progress)
+ self.connect(self.live_thread, QtCore.SIGNAL("maxprogress(int)"),
+ self.maxprogress)
+ self.connect(self.progress_thread, QtCore.SIGNAL("progress(int)"),
+ self.progress)
+ self.connect(self.progress_thread, QtCore.SIGNAL("maxprogress(int)"),
+ self.maxprogress)
+ if hasattr(self, 'refreshDevicesButton'):
+ self.connect(self.refreshDevicesButton, QtCore.SIGNAL("clicked()"),
+ self.populate_devices)
+
+ # If we have access to HAL & DBus, intercept some useful signals
+ if hasattr(self.live, 'hal'):
+ self.live.hal.connect_to_signal('DeviceAdded',
+ self.populate_devices)
+ self.live.hal.connect_to_signal('DeviceRemoved',
+ self.populate_devices)
+
+ def progress(self, value):
+ self.progressBar.setValue(value)
+
+ def maxprogress(self, value):
+ self.progressBar.setMaximum(value)
+
+ def status(self, text):
+ if isinstance(text, Exception):
+ text = text.message
+ self.textEdit.append(text)
+
+ def enable_widgets(self, enabled=True):
+ if(enabled == False):
+ self.startButton.setEnabled(enabled)
+ else:
+ self.check_startbutton_state()
+ self.driveBox.setEnabled(enabled)
+ self.isoBttn.setEnabled(enabled)
+ if hasattr(self, 'refreshDevicesButton'):
+ self.refreshDevicesButton.setEnabled(enabled)
+ self.in_process = not enabled
+
+ def get_selected_drive(self):
+ return str(self.driveBox.currentText()).split()[0]
+
+ def begin(self):
+ """ Begin the liveusb creation process.
+
+ This method is called when the "Create LiveUSB" button is clicked.
+ """
+
+ r = QtGui.QMessageBox.warning(self, _("Warning"), _("All the data on the USB stick are going to be eaten"), QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel);
+ if(r == QtGui.QMessageBox.Cancel):
+ return;
+
+ self.enable_widgets(False)
+ self.live.drive = self.get_selected_drive()
+
+
+ # Remove the log handler, because our live thread will register its own
+ self.live.log.removeHandler(self.handler)
+
+ self.live_thread.start()
+
+ def selectfile(self):
+ isofile = QtGui.QFileDialog.getOpenFileName(self, _("Select Live ISO"),
+ "..", "ISO (*.iso)" )
+ if isofile:
+ try:
+ self.live.set_iso(isofile)
+
+ except Exception, e:
+ self.live.log.error(e.message.encode('utf8'))
+ self.status(_("Unable to encode the filename of your livecd. "
+ "You may have better luck if you move your ISO "
+ "to the root of your drive (ie: C:\)"))
+
+
+ if not self.live.is_hybrid(self.live.iso):
+ self.status(_("The selected iso isn't hybrid"))
+ self.live.iso = None
+ else:
+ self.status("Iso " + _("selected"))
+ self.check_startbutton_state()
+
+ def check_startbutton_state(self):
+ if self.live.drives != {} and self.live.iso:
+ self.startButton.setEnabled(True)
+ else:
+ self.startButton.setEnabled(False)
+
+ def terminate(self):
+ """ Terminate any processes that we have spawned """
+ self.live.terminate()