# Software License: GPL
import os
import sys
from functools import partial
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from ui.pcsuiutils import *
from ui.tsuigeneralmethods import *
from ui.pcsapp import PcsApp
from backup.pcsbackuputils import *
from pcsbackuplistui import PCSBackupListUi
from pcspcbackupmanager import PcsPcBackupManager
from pcsdevicebackupmanager import PcsDeviceBackupManager
from pcsprogressdialog import PcsProgressDialog
from style.styleTabletSuite import *
COPY_BUTTON_ID = 0
DELETE_BUTTON_ID = 1
RENAME_BUTTON_ID = 2
VIEW_BUTTON_ID = 3
_home_dir = os.path.expanduser("~")
_default_dir = _home_dir + "/.pcsuite/Backup"
class PcsBackupManagerUi(QDialog):
''' Class that calls a Backup Pc Suite application
with a Table Viewer'''
def __init__(self, deviceInfo, windowManager, parent=None):
QDialog.__init__(self, parent)
self.deviceInfo = deviceInfo
self.windowManager = windowManager
self.setWindowIcon(QIcon(BACKUP_IMAGE))
self.setWindowTitle("%s Backup Manager" % APPLICATION_NAME)
self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
self._home_dir = os.path.expanduser("~")
self._default_dir = _home_dir + "/.pcsuite/Backup"
self.copyPath = self._default_dir
self.name_change = None
self._setupUi()
def _setupUi(self):
# Creates the lists
self.pcBackupManager = PcsPcBackupManager()
self.deviceBackupManager = PcsDeviceBackupManager(self.deviceInfo)
self.pcListView = PCSBackupListUi(self.pcBackupManager)
self.pcListView.setObjectName("ListView")
# "Update pc list view"
pcListViewSelectionModel = self.pcListView.selectionModel()
self.connect(pcListViewSelectionModel,
SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
self._updateButtonsState)
self.pcListView.updateBackupList()
self.deviceListView = PCSBackupListUi(self.deviceBackupManager)
self.deviceListView.setObjectName("ListView")
deviceListViewSelectionModel = self.deviceListView.selectionModel()
self.connect(deviceListViewSelectionModel,
SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
self._updateButtonsState)
# "Update device List view"
self.deviceListView.updateBackupList()
layout = QVBoxLayout()
menuLayout = self._menuButtons()
layout.addLayout(menuLayout, Qt.AlignTop)
wayLayout = self._wayLayout()
layout.addLayout(wayLayout, Qt.AlignLeft)
layout.addItem(QSpacerItem(0,3))
layout.addLayout(self._centerLayout(), Qt.AlignTop)
layout.addItem(QSpacerItem(0,15))
informationLayout = self._createInformationsLabel()
layout.addLayout(informationLayout)
layout.addItem(QSpacerItem(0,2))
self.setLayout(layout)
def _centerLayout(self):
# Creates the tabs
layout = QVBoxLayout()
tabLayout = QVBoxLayout()
tab = QTabBar()
tab.setObjectName("managerTabs")
self.tabBar = QTabWidget()
self.tabBar.setTabBar(tab)
self.tabBar.setAttribute(Qt.WA_NoSystemBackground)
self.tabBar.setObjectName("tabBar")
self.tabBar.addTab(self.pcListView, "PC Backups")
self.tabBar.addTab(self.deviceListView, "Device Backups")
self.connect(self.tabBar, SIGNAL("currentChanged(int)"), self._updateButtonsState)
tabLayout.addWidget(self.tabBar)
layout.addLayout(tabLayout)
#Spacer
layout.addItem(QSpacerItem(0,5))
# Creates the buttons
buttonBox = QHBoxLayout()
self._buttonCopy = QPushButton("Copy")
self._buttonCopy.setDisabled(True)
self._buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
buttonBox.addWidget(self._buttonCopy)
self.connect (self._buttonCopy, SIGNAL("clicked()"), self._doCopyBackup)
self._buttonDelete = QPushButton("Delete")
self._buttonDelete.setDisabled(True)
buttonBox.addWidget(self._buttonDelete)
self._buttonDelete.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect (self._buttonDelete, SIGNAL("clicked()"), self._doDeleteBackup)
self._buttonRename = QPushButton("Rename")
self._buttonRename.setDisabled(True)
buttonBox.addWidget(self._buttonRename)
self._buttonRename.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect (self._buttonRename, SIGNAL("clicked()"), self._doRenameBackup)
self._buttonView = QPushButton("View")
self._buttonView.setDisabled(True)
buttonBox.addWidget(self._buttonView)
self._buttonView.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect (self._buttonView, SIGNAL("clicked()"), self._doViewBackup)
self._buttonUpdate = QPushButton("Update")
self._buttonUpdate.setDisabled(False)
self._buttonUpdate.setVisible(False)
buttonBox.addWidget(self._buttonUpdate)
self._buttonUpdate.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect (self._buttonUpdate, SIGNAL("clicked()"), self._doUpdateList)
layout.addLayout(buttonBox)
return layout
def _menuButtons(self):
infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE, self._newBackupDialog),
("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE_SELECTED),
("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
buttonsLayout = QHBoxLayout()
for i in range(3):
but = QPushButton(infList[i][0])
but.setStyleSheet(infList[i][1])
if i <> 1:
buttonsLayout.addWidget(but, Qt.AlignLeft)
self.connect(but, SIGNAL("clicked()"), infList[i][2])
else:
buttonsLayout.addWidget(but)
buttonsLayout.setMargin(0)
return buttonsLayout
def _newBackupDialog(self):
if(self.deviceInfo and self.deviceInfo.ip != None):
newBackup = self.windowManager.getNewBackup()
centralize(newBackup)
newBackup.setGeometry(self.geometry())
newBackup.show()
self.close()
else:
self._showNoDeviceFoundMessage()
def _restoreDialog(self):
if(self.deviceInfo and self.deviceInfo.ip != None):
restoreBackup = self.windowManager.getRestoreBackup()
centralize(restoreBackup)
restoreBackup.setGeometry(self.geometry())
restoreBackup.show()
self.close()
else:
self._showNoDeviceFoundMessage()
def _wayLayout(self):
self.barLayout = QHBoxLayout()
self.barLayout.setMargin(0)
spc = QSpacerItem(8, 0)
self.barLayout.addItem(spc)
main = QLabel("Main")
restore = QLabel(" Manage backups")
spc = QSpacerItem(2, 0)
widgetList = [main, self._arrow(), restore]
for widget in widgetList:
self.barLayout.addWidget(widget, Qt.AlignLeft)
self.barLayout.addItem(spc)
self.barLayout.addItem(QSpacerItem(300, 0))
return self.barLayout
def _arrow(self):
label = QLabel()
label.setPixmap(QPixmap(BLACK_ARROW))
return label
def _createInformationsLabel(self):
hLay = QHBoxLayout()
self.infLabel = QLabel(""\
"Select the backup you wish to manipulate.")
iconAlert = QLabel()
hLay.setMargin(0)
iconAlert.setPixmap(QPixmap(ICON_ALERT))
spc = QSpacerItem(15, 0)
hLay.addItem(spc)
hLay.addWidget(iconAlert)
hLay.addWidget(self.infLabel, Qt.AlignLeft)
return hLay
def _doUpdateList(self):
self._currentBackupList().updateBackupList()
self._updateButtonsState(0)
def _execCopyDialogToDevice(self):
self._copyDialogToDevice = QDialog(self, Qt.FramelessWindowHint)
self._copyDialogToDevice.setObjectName("copyDialogToDevice")
self.rb1 = QRadioButton()
self.rb1.setText("External Memory Card")
self.rb2 = QRadioButton()
self.rb2.setText("Internal Memory Card")
layout = QVBoxLayout()
layout.addWidget(self.rb1)
layout.addWidget(self.rb2)
buttonCopy = QPushButton("Copy")
buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect(buttonCopy, SIGNAL("clicked()"), self._doCopyToDevice)
buttonCancel = QPushButton("Cancel")
buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect(buttonCancel, SIGNAL("clicked()"), self._copyDialogToDevice.close)
hlay = QHBoxLayout()
hlay.addWidget(buttonCancel)
hlay.addWidget(buttonCopy)
layout.addLayout(hlay)
self._copyDialogToDevice.setLayout(layout)
self._copyDialogToDevice.exec_()
def _execCopyDialogFromDevice(self):
self._copyDialogFromDevice = QDialog(self, Qt.FramelessWindowHint)
self._copyDialogFromDevice.setObjectName("copyDialogFromDevice")
hLayout = QHBoxLayout()
hLayout.setMargin(0)
self.textField = QLineEdit(self)
buttonOpen = QPushButton()
buttonOpen.setObjectName("buttonBrowse")
self.connect(buttonOpen, SIGNAL("clicked()"), self._doBrowse)
copyPath = str(self._default_dir)
self.textField.setReadOnly(True)
self.textField.setText(self._default_dir)
hLayout.addWidget(self.textField)
hLayout.addWidget(buttonOpen)
message = QLabel(" Backup copy destination: ")
message.setFixedHeight(15)
layout = QVBoxLayout()
layout.addWidget(message)
layout.addLayout(hLayout)
buttonCopy = QPushButton("Copy")
buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect(buttonCopy, SIGNAL("clicked()"), self._doCopyFromDevice)
buttonCancel = QPushButton("Cancel")
buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
self.connect(buttonCancel, SIGNAL("clicked()"), self._copyDialogFromDevice.close)
hlay = QHBoxLayout()
hlay.addWidget(buttonCancel)
hlay.addWidget(buttonCopy)
layout.addLayout(hlay)
self._copyDialogFromDevice.setLayout(layout)
self._copyDialogFromDevice.exec_()
def _doCopyBackup(self):
if self.tabBar.currentIndex() == 0:
self._execCopyDialogToDevice()
else:
self._execCopyDialogFromDevice()
def doCopy(self, device_ip, backupName, ret, destinationPath):
self.copyThread = CopyBackupThread(self, device_ip, backupName, ret, destinationPath)
self.copyThread.start()
self._runCopyProgress()
self.connect(self.copyThread, SIGNAL("openFileError"), self._onOpenFileError)
self.connect(self.copyThread, SIGNAL("copyProgress"), self._updateProgress)
self.connect(self.copyThread, SIGNAL("copyDone"), self._onCopyDone)
def _doCopyToDevice(self):
self._copyDialogToDevice.close()
ret = 1
if self.rb1.isChecked():
ret = 0
selectedBackupList = self._currentBackupList().getSelectedBackupList()
for backup in selectedBackupList:
self.doCopy(self.deviceInfo.ip, str(backup).strip(), ret, "")
def _doCopyFromDevice(self):
self._copyDialogFromDevice.close()
if self.copyPath != "":
selectedBackupList = self._currentBackupList().getSelectedBackupList()
self.name_change = False
for backup in selectedBackupList:
self.pcBackupManager.loadBackups()
self.correct_name = self.pcBackupManager._verify_backup_name(str(backup).strip())
self.doCopy(self.deviceInfo.ip, str(backup).strip(), 0, self.copyPath)
if self.correct_name != backup:
self.name_change = True
def _showMessageCopyBackupDone(self):
if self.name_change == None or not self.name_change:
QMessageBox.information(self, "Copy Backup", "Backup(s) copied")
else:
QMessageBox.information(sopenFileErrorelf, "Copy Backup",
"Backup copied with name: %s" % self.correct_name)
def _doBrowse(self):
pathDialog = QFileDialog()
prompt = "Select the folder you wish to copy your backup(s):"
self.copyPath = pathDialog.getExistingDirectory(self, prompt, self._home_dir)
if(self.copyPath != ""):
self.textField.setText(self.copyPath)
def _doRenameBackup(self):
res = False
(newName, ok) = QInputDialog.getText(self, "Rename Backup", "New Backup Name:",
QLineEdit.Normal, QString(),
Qt.FramelessWindowHint)
if ok:
if newName:
newName = QString(str(newName).strip())
if not newName.isEmpty():
list = self._currentBackupList()
res = list.renameSelectedBackup(newName)
if res:
showMessageBox("Backup Renamed", "")
else:
showMessageBox("Error while renaming the backup", "")
def _doDeleteBackup(self):
dialog = QMessageBox()
dialog.setText("Remove selected backup?")
dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
dialog.setWindowFlags(Qt.FramelessWindowHint)
dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
ret = dialog.exec_()
if ret == QMessageBox.Yes:
list = self._currentBackupList()
list.removeSelectedBackups()
showMessageBox("Backup Removed", "")
def _currentBackupList(self):
if self.tabBar.currentIndex() == 0:
self._buttonRename.setVisible(True)
self._buttonDelete.setVisible(True)
self._buttonView.setVisible(True)
self._buttonUpdate.setVisible(False)
return self.pcListView
else:
self._buttonUpdate.setVisible(True)
self._buttonRename.setVisible(False)
self._buttonDelete.setVisible(False)
self._buttonView.setVisible(False)
return self.deviceListView
def _updateButtonsState(self, index):
list = self._currentBackupList()
selectionModel = list.selectionModel()
indexList = selectionModel.selectedRows()
if len(indexList) != 1:
self._buttonRename.setDisabled(True)
self._buttonView.setDisabled(True)
self._buttonCopy.setDisabled(True)
else:
self._buttonRename.setEnabled(True)
self._buttonView.setEnabled(True)
self._buttonCopy.setEnabled(True)
if len(indexList) == 0:
self._buttonDelete.setDisabled(True)
# self._buttonCopy.setDisabled(True)
else:
self._buttonDelete.setEnabled(True)
# self._buttonCopy.setEnabled(True)
def _doViewBackup(self):
list = self._currentBackupList()
backupManager = list.getBackupManager()
backupName = (str(list.getSelectedBackup())).strip()
if backupName == None:
return False
dialog = QDialog(self, Qt.FramelessWindowHint)
dialog.setObjectName("viewDialog")
dialog.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
dialog.setWindowTitle("Backup Files")
dialog.setWindowIcon(QIcon(BACKUP_IMAGE))
layout = QVBoxLayout()
listWidget = QListWidget()
listWidget.setObjectName("viewList")
listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
try:
backupContentList = backupManager.listBackupContent(backupName)
except IOError:
showMessageBox(self.openFileError, "Error while opening file")
return False
for backupContent in backupContentList:
backup_button = QListWidgetItem()
backup_button.setText(backupContent)
listWidget.addItem(backup_button)
okButton = QPushButton("OK")
okButton.setStyleSheet(SMALL_DEFAULT_BUTTON_STYLE)
visible = partial(dialog.setVisible, False)
self.connect(okButton, SIGNAL("clicked()"), visible)
hLay = QHBoxLayout()
hLay.addItem(QSpacerItem(200,0))
hLay.addWidget(okButton)
layout.addWidget(listWidget)
layout.addLayout(hLay)
dialog.setLayout(layout)
dialog.show()
def _runCopyProgress(self):
self._progressDialog = PcsProgressDialog(self)
self._progressDialog.setAction("copy")
self.connect(self._progressDialog.cancelButton, SIGNAL("clicked()"),
self._onCopyCancel)
self._progressDialog.show()
def _updateProgress(self, information):
progress, self.numberOfFiles, self.totalSize = information
self._progressDialog.setProgress(progress)
def _onCopyDone(self):
self._progressDialog.updateInfo(self.totalSize, self.numberOfFiles)
self._progressDialog.progressDone()
self.pcListView.updateBackupList()
def _onCopyCancel(self):
if self.tabBar.currentIndex() == 0:
self.pcBackupManager.setCopyInProgress(False)
else:
self.deviceBackupManager.setCopyInProgress(False)
self._progressDialog.progressCanceled()
def _onOpenFileError(self):
self._progressDialog.close()
showMessageBox(OPEN_FILE_ERROR, OPEN_FILE_ERROR_TITLE)
class CopyBackupThread(QThread):
def __init__(self, manager, deviceIp, backupName, ret, destinationPath ):
QThread.__init__(self)
self.uiManager = manager
self.deviceIp = deviceIp
self.backupName = backupName
self.memoryCard = ret
self.destinationPath = destinationPath
self.connect(self.uiManager.pcBackupManager, SIGNAL("copyProgress"),
self.reEmit)
self.connect(self.uiManager.deviceBackupManager, SIGNAL("copyProgress"),
self.reEmit)
def reEmit(self, inf):
self.emit(SIGNAL("copyProgress"), inf)
def run(self):
try:
if self.uiManager.tabBar.currentIndex() == 0:
manager = self.uiManager.pcBackupManager
manager.copyBackupToDevice(self.deviceIp, self.backupName,
self.memoryCard)
else:
manager = self.uiManager.deviceBackupManager
manager.copyBackupFromDevice(self.backupName,
self.destinationPath)
except IOError:
self.emit(SIGNAL("openFileError"))
return
self.emit(SIGNAL("copyDone"))