1 # Software License: GPL
6 from functools import partial
8 from PyQt4.QtCore import *
9 from PyQt4.QtGui import *
11 from ui.pcsuiutils import *
12 from ui.tsuigeneralmethods import *
13 from ui.pcsapp import PcsApp
14 from backup.pcsbackuputils import *
16 from pcsbackuplistui import PCSBackupListUi
17 from pcspcbackupmanager import PcsPcBackupManager
18 from pcsdevicebackupmanager import PcsDeviceBackupManager
19 from pcsprogressdialog import PcsProgressDialog
20 from style.styleTabletSuite import *
26 _home_dir = os.path.expanduser("~")
27 _default_dir = _home_dir + "/.pcsuite/Backup"
30 class PcsBackupManagerUi(QDialog):
32 ''' Class that calls a Backup Pc Suite application
33 with a Table Viewer'''
35 def __init__(self, deviceInfo, windowManager, parent=None):
36 QDialog.__init__(self, parent)
37 self.deviceInfo = deviceInfo
38 self.windowManager = windowManager
40 self.setWindowIcon(QIcon(BACKUP_IMAGE))
41 self.setWindowTitle("%s Backup Manager" % APPLICATION_NAME)
42 self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
43 self._home_dir = os.path.expanduser("~")
44 self._default_dir = _home_dir + "/.pcsuite/Backup"
45 self.copyPath = self._default_dir
46 self.name_change = None
51 self.pcBackupManager = PcsPcBackupManager()
52 self.deviceBackupManager = PcsDeviceBackupManager(self.deviceInfo)
54 self.pcListView = PCSBackupListUi(self.pcBackupManager)
55 self.pcListView.setObjectName("ListView")
56 # "Update pc list view"
57 pcListViewSelectionModel = self.pcListView.selectionModel()
58 self.connect(pcListViewSelectionModel,
59 SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
60 self._updateButtonsState)
61 self.pcListView.updateBackupList()
63 self.deviceListView = PCSBackupListUi(self.deviceBackupManager)
64 self.deviceListView.setObjectName("ListView")
65 deviceListViewSelectionModel = self.deviceListView.selectionModel()
66 self.connect(deviceListViewSelectionModel,
67 SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
68 self._updateButtonsState)
69 # "Update device List view"
70 self.deviceListView.updateBackupList()
72 layout = QVBoxLayout()
73 menuLayout = self._menuButtons()
74 layout.addLayout(menuLayout, Qt.AlignTop)
75 wayLayout = self._wayLayout()
76 layout.addLayout(wayLayout, Qt.AlignLeft)
77 layout.addItem(QSpacerItem(0,3))
78 layout.addLayout(self._centerLayout(), Qt.AlignTop)
80 layout.addItem(QSpacerItem(0,15))
81 informationLayout = self._createInformationsLabel()
82 layout.addLayout(informationLayout)
83 layout.addItem(QSpacerItem(0,2))
84 self.setLayout(layout)
86 def _centerLayout(self):
88 layout = QVBoxLayout()
89 tabLayout = QVBoxLayout()
91 tab.setObjectName("managerTabs")
92 self.tabBar = QTabWidget()
93 self.tabBar.setTabBar(tab)
94 self.tabBar.setAttribute(Qt.WA_NoSystemBackground)
95 self.tabBar.setObjectName("tabBar")
96 self.tabBar.addTab(self.pcListView, "PC Backups")
97 self.tabBar.addTab(self.deviceListView, "Device Backups")
98 self.connect(self.tabBar, SIGNAL("currentChanged(int)"), self._updateButtonsState)
99 tabLayout.addWidget(self.tabBar)
100 layout.addLayout(tabLayout)
102 layout.addItem(QSpacerItem(0,5))
103 # Creates the buttons
104 buttonBox = QHBoxLayout()
105 self._buttonCopy = QPushButton("Copy")
106 self._buttonCopy.setDisabled(True)
107 self._buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
108 buttonBox.addWidget(self._buttonCopy)
109 self.connect (self._buttonCopy, SIGNAL("clicked()"), self._doCopyBackup)
111 self._buttonDelete = QPushButton("Delete")
112 self._buttonDelete.setDisabled(True)
113 buttonBox.addWidget(self._buttonDelete)
114 self._buttonDelete.setStyleSheet(DEFAULT_BUTTON_STYLE)
115 self.connect (self._buttonDelete, SIGNAL("clicked()"), self._doDeleteBackup)
117 self._buttonRename = QPushButton("Rename")
118 self._buttonRename.setDisabled(True)
119 buttonBox.addWidget(self._buttonRename)
120 self._buttonRename.setStyleSheet(DEFAULT_BUTTON_STYLE)
121 self.connect (self._buttonRename, SIGNAL("clicked()"), self._doRenameBackup)
123 self._buttonView = QPushButton("View")
124 self._buttonView.setDisabled(True)
125 buttonBox.addWidget(self._buttonView)
126 self._buttonView.setStyleSheet(DEFAULT_BUTTON_STYLE)
127 self.connect (self._buttonView, SIGNAL("clicked()"), self._doViewBackup)
129 self._buttonUpdate = QPushButton("Update")
130 self._buttonUpdate.setDisabled(False)
131 self._buttonUpdate.setVisible(False)
132 buttonBox.addWidget(self._buttonUpdate)
133 self._buttonUpdate.setStyleSheet(DEFAULT_BUTTON_STYLE)
134 self.connect (self._buttonUpdate, SIGNAL("clicked()"), self._doUpdateList)
136 layout.addLayout(buttonBox)
139 def _menuButtons(self):
140 infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE, self._newBackupDialog),
141 ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE_SELECTED),
142 ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
144 buttonsLayout = QHBoxLayout()
146 but = QPushButton(infList[i][0])
147 but.setStyleSheet(infList[i][1])
149 buttonsLayout.addWidget(but, Qt.AlignLeft)
150 self.connect(but, SIGNAL("clicked()"), infList[i][2])
152 buttonsLayout.addWidget(but)
153 buttonsLayout.setMargin(0)
156 def _newBackupDialog(self):
157 if(self.deviceInfo and self.deviceInfo.ip != None):
158 newBackup = self.windowManager.getNewBackup()
159 centralize(newBackup)
160 newBackup.setGeometry(self.geometry())
164 self._showNoDeviceFoundMessage()
166 def _restoreDialog(self):
167 if(self.deviceInfo and self.deviceInfo.ip != None):
168 restoreBackup = self.windowManager.getRestoreBackup()
169 centralize(restoreBackup)
170 restoreBackup.setGeometry(self.geometry())
174 self._showNoDeviceFoundMessage()
176 def _wayLayout(self):
177 self.barLayout = QHBoxLayout()
178 self.barLayout.setMargin(0)
179 spc = QSpacerItem(8, 0)
180 self.barLayout.addItem(spc)
181 main = QLabel("<font style='color: #333333'; size=2>Main</font>")
182 restore = QLabel("<font style='color: #FFFFFF'; size=2> Manage backups</font>")
183 spc = QSpacerItem(2, 0)
184 widgetList = [main, self._arrow(), restore]
186 for widget in widgetList:
187 self.barLayout.addWidget(widget, Qt.AlignLeft)
188 self.barLayout.addItem(spc)
190 self.barLayout.addItem(QSpacerItem(300, 0))
191 return self.barLayout
195 label.setPixmap(QPixmap(BLACK_ARROW))
198 def _createInformationsLabel(self):
201 self.infLabel = QLabel("<font style='color:"\
203 "Select the backup you wish to manipulate.</font>")
206 iconAlert.setPixmap(QPixmap(ICON_ALERT))
207 spc = QSpacerItem(15, 0)
209 hLay.addWidget(iconAlert)
210 hLay.addWidget(self.infLabel, Qt.AlignLeft)
214 def _doUpdateList(self):
215 self._currentBackupList().updateBackupList()
216 self._updateButtonsState(0)
218 def _execCopyDialogToDevice(self):
219 self._copyDialogToDevice = QDialog(self, Qt.FramelessWindowHint)
220 self._copyDialogToDevice.setObjectName("copyDialogToDevice")
222 self.rb1 = QRadioButton()
223 self.rb1.setText("External Memory Card")
224 self.rb2 = QRadioButton()
225 self.rb2.setText("Internal Memory Card")
227 layout = QVBoxLayout()
228 layout.addWidget(self.rb1)
229 layout.addWidget(self.rb2)
231 buttonCopy = QPushButton("Copy")
232 buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
233 self.connect(buttonCopy, SIGNAL("clicked()"), self._doCopyToDevice)
234 buttonCancel = QPushButton("Cancel")
235 buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
236 self.connect(buttonCancel, SIGNAL("clicked()"), self._copyDialogToDevice.close)
239 hlay.addWidget(buttonCancel)
240 hlay.addWidget(buttonCopy)
241 layout.addLayout(hlay)
242 self._copyDialogToDevice.setLayout(layout)
243 self._copyDialogToDevice.exec_()
245 def _execCopyDialogFromDevice(self):
246 self._copyDialogFromDevice = QDialog(self, Qt.FramelessWindowHint)
247 self._copyDialogFromDevice.setObjectName("copyDialogFromDevice")
249 hLayout = QHBoxLayout()
251 self.textField = QLineEdit(self)
252 buttonOpen = QPushButton()
253 buttonOpen.setObjectName("buttonBrowse")
254 self.connect(buttonOpen, SIGNAL("clicked()"), self._doBrowse)
255 copyPath = str(self._default_dir)
256 self.textField.setReadOnly(True)
257 self.textField.setText(self._default_dir)
258 hLayout.addWidget(self.textField)
259 hLayout.addWidget(buttonOpen)
261 message = QLabel("<font style='color: #333333'; size=2> Backup copy destination: </font>")
262 message.setFixedHeight(15)
264 layout = QVBoxLayout()
265 layout.addWidget(message)
266 layout.addLayout(hLayout)
268 buttonCopy = QPushButton("Copy")
269 buttonCopy.setStyleSheet(DEFAULT_BUTTON_STYLE)
270 self.connect(buttonCopy, SIGNAL("clicked()"), self._doCopyFromDevice)
271 buttonCancel = QPushButton("Cancel")
272 buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
273 self.connect(buttonCancel, SIGNAL("clicked()"), self._copyDialogFromDevice.close)
276 hlay.addWidget(buttonCancel)
277 hlay.addWidget(buttonCopy)
278 layout.addLayout(hlay)
279 self._copyDialogFromDevice.setLayout(layout)
280 self._copyDialogFromDevice.exec_()
282 def _doCopyBackup(self):
283 if self.tabBar.currentIndex() == 0:
284 self._execCopyDialogToDevice()
286 self._execCopyDialogFromDevice()
288 def doCopy(self, device_ip, backupName, ret, destinationPath):
289 self.copyThread = CopyBackupThread(self, device_ip, backupName, ret, destinationPath)
290 self.copyThread.start()
291 self._runCopyProgress()
293 self.connect(self.copyThread, SIGNAL("openFileError"), self._onOpenFileError)
294 self.connect(self.copyThread, SIGNAL("copyProgress"), self._updateProgress)
295 self.connect(self.copyThread, SIGNAL("copyDone"), self._onCopyDone)
297 def _doCopyToDevice(self):
298 self._copyDialogToDevice.close()
300 if self.rb1.isChecked():
302 selectedBackupList = self._currentBackupList().getSelectedBackupList()
303 for backup in selectedBackupList:
304 self.doCopy(self.deviceInfo.ip, str(backup).strip(), ret, "")
306 def _doCopyFromDevice(self):
307 self._copyDialogFromDevice.close()
308 if self.copyPath != "":
309 selectedBackupList = self._currentBackupList().getSelectedBackupList()
310 self.name_change = False
311 for backup in selectedBackupList:
312 self.pcBackupManager.loadBackups()
313 self.correct_name = self.pcBackupManager._verify_backup_name(str(backup).strip())
314 self.doCopy(self.deviceInfo.ip, str(backup).strip(), 0, self.copyPath)
315 if self.correct_name != backup:
316 self.name_change = True
318 def _showMessageCopyBackupDone(self):
319 if self.name_change == None or not self.name_change:
320 QMessageBox.information(self, "Copy Backup", "Backup(s) copied")
322 QMessageBox.information(sopenFileErrorelf, "Copy Backup",
323 "Backup copied with name: %s" % self.correct_name)
326 pathDialog = QFileDialog()
327 prompt = "Select the folder you wish to copy your backup(s):"
328 self.copyPath = pathDialog.getExistingDirectory(self, prompt, self._home_dir)
329 if(self.copyPath != ""):
330 self.textField.setText(self.copyPath)
332 def _doRenameBackup(self):
334 (newName, ok) = QInputDialog.getText(self, "Rename Backup", "New Backup Name:",
335 QLineEdit.Normal, QString(),
336 Qt.FramelessWindowHint)
339 newName = QString(str(newName).strip())
340 if not newName.isEmpty():
341 list = self._currentBackupList()
342 res = list.renameSelectedBackup(newName)
344 showMessageBox("Backup Renamed", "")
346 showMessageBox("Error while renaming the backup", "")
348 def _doDeleteBackup(self):
350 dialog = QMessageBox()
351 dialog.setText("Remove selected backup?")
352 dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
353 dialog.setWindowFlags(Qt.FramelessWindowHint)
354 dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
356 if ret == QMessageBox.Yes:
357 list = self._currentBackupList()
358 list.removeSelectedBackups()
359 showMessageBox("Backup Removed", "")
361 def _currentBackupList(self):
362 if self.tabBar.currentIndex() == 0:
363 self._buttonRename.setVisible(True)
364 self._buttonDelete.setVisible(True)
365 self._buttonView.setVisible(True)
366 self._buttonUpdate.setVisible(False)
367 return self.pcListView
369 self._buttonUpdate.setVisible(True)
370 self._buttonRename.setVisible(False)
371 self._buttonDelete.setVisible(False)
372 self._buttonView.setVisible(False)
373 return self.deviceListView
375 def _updateButtonsState(self, index):
376 list = self._currentBackupList()
377 selectionModel = list.selectionModel()
378 indexList = selectionModel.selectedRows()
380 if len(indexList) != 1:
381 self._buttonRename.setDisabled(True)
382 self._buttonView.setDisabled(True)
383 self._buttonCopy.setDisabled(True)
385 self._buttonRename.setEnabled(True)
386 self._buttonView.setEnabled(True)
387 self._buttonCopy.setEnabled(True)
389 if len(indexList) == 0:
390 self._buttonDelete.setDisabled(True)
391 # self._buttonCopy.setDisabled(True)
393 self._buttonDelete.setEnabled(True)
394 # self._buttonCopy.setEnabled(True)
397 def _doViewBackup(self):
398 list = self._currentBackupList()
399 backupManager = list.getBackupManager()
400 backupName = (str(list.getSelectedBackup())).strip()
401 if backupName == None:
404 dialog = QDialog(self, Qt.FramelessWindowHint)
405 dialog.setObjectName("viewDialog")
406 dialog.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
407 dialog.setWindowTitle("Backup Files")
408 dialog.setWindowIcon(QIcon(BACKUP_IMAGE))
410 layout = QVBoxLayout()
411 listWidget = QListWidget()
412 listWidget.setObjectName("viewList")
413 listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
416 backupContentList = backupManager.listBackupContent(backupName)
418 showMessageBox(self.openFileError, "Error while opening file")
421 for backupContent in backupContentList:
422 backup_button = QListWidgetItem()
423 backup_button.setText(backupContent)
424 listWidget.addItem(backup_button)
426 okButton = QPushButton("OK")
427 okButton.setStyleSheet(SMALL_DEFAULT_BUTTON_STYLE)
428 visible = partial(dialog.setVisible, False)
429 self.connect(okButton, SIGNAL("clicked()"), visible)
431 hLay.addItem(QSpacerItem(200,0))
432 hLay.addWidget(okButton)
434 layout.addWidget(listWidget)
435 layout.addLayout(hLay)
436 dialog.setLayout(layout)
439 def _runCopyProgress(self):
440 self._progressDialog = PcsProgressDialog(self)
441 self._progressDialog.setAction("copy")
442 self.connect(self._progressDialog.cancelButton, SIGNAL("clicked()"),
444 self._progressDialog.show()
446 def _updateProgress(self, information):
447 progress, self.numberOfFiles, self.totalSize = information
448 self._progressDialog.setProgress(progress)
450 def _onCopyDone(self):
451 self._progressDialog.updateInfo(self.totalSize, self.numberOfFiles)
452 self._progressDialog.progressDone()
453 self.pcListView.updateBackupList()
455 def _onCopyCancel(self):
456 if self.tabBar.currentIndex() == 0:
457 self.pcBackupManager.setCopyInProgress(False)
459 self.deviceBackupManager.setCopyInProgress(False)
460 self._progressDialog.progressCanceled()
462 def _onOpenFileError(self):
463 self._progressDialog.close()
464 showMessageBox(OPEN_FILE_ERROR, OPEN_FILE_ERROR_TITLE)
468 class CopyBackupThread(QThread):
469 def __init__(self, manager, deviceIp, backupName, ret, destinationPath ):
470 QThread.__init__(self)
471 self.uiManager = manager
472 self.deviceIp = deviceIp
473 self.backupName = backupName
474 self.memoryCard = ret
475 self.destinationPath = destinationPath
476 self.connect(self.uiManager.pcBackupManager, SIGNAL("copyProgress"),
478 self.connect(self.uiManager.deviceBackupManager, SIGNAL("copyProgress"),
481 def reEmit(self, inf):
482 self.emit(SIGNAL("copyProgress"), inf)
486 if self.uiManager.tabBar.currentIndex() == 0:
487 manager = self.uiManager.pcBackupManager
488 manager.copyBackupToDevice(self.deviceIp, self.backupName,
491 manager = self.uiManager.deviceBackupManager
492 manager.copyBackupFromDevice(self.backupName,
493 self.destinationPath)
496 self.emit(SIGNAL("openFileError"))
498 self.emit(SIGNAL("copyDone"))