# 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"))