--- /dev/null
+# 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("<font style='color: #333333'; size=2>Main</font>")
+ restore = QLabel("<font style='color: #FFFFFF'; size=2> Manage backups</font>")
+ 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("<font style='color:"\
+ "#333333'; size=2>"\
+ "Select the backup you wish to manipulate.</font>")
+ 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("<font style='color: #333333'; size=2> Backup copy destination: </font>")
+ 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"))
+
+
+
+