Initial commit (Vesion 0.1)
authorOtacilio Freitas de Lacerda <otacilio@otacilio-3N.(none)>
Fri, 9 Oct 2009 13:12:23 +0000 (10:12 -0300)
committerOtacilio Freitas de Lacerda <otacilio@otacilio-3N.(none)>
Fri, 9 Oct 2009 13:12:23 +0000 (10:12 -0300)
427 files changed:
debian/.svn/all-wcprops [new file with mode: 0644]
debian/.svn/dir-prop-base [new file with mode: 0644]
debian/.svn/entries [new file with mode: 0644]
debian/.svn/format [new file with mode: 0644]
debian/.svn/prop-base/rules.svn-base [new file with mode: 0644]
debian/.svn/text-base/changelog.svn-base [new file with mode: 0644]
debian/.svn/text-base/compat.svn-base [new file with mode: 0644]
debian/.svn/text-base/control.svn-base [new file with mode: 0644]
debian/.svn/text-base/copyright.svn-base [new file with mode: 0644]
debian/.svn/text-base/docs.svn-base [new file with mode: 0644]
debian/.svn/text-base/rules.svn-base [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/rules [new file with mode: 0755]
fonts/.svn/all-wcprops [new file with mode: 0644]
fonts/.svn/entries [new file with mode: 0644]
fonts/.svn/format [new file with mode: 0644]
fonts/.svn/prop-base/BROWA.TTF.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_compressed.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_compressed_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_condensed.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_condensed_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_extended.ttf.svn-base [new file with mode: 0644]
fonts/.svn/prop-base/pf_tempesta_seven_extended_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/BROWA.TTF.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_compressed.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_compressed_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_condensed.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_condensed_bold.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_extended.ttf.svn-base [new file with mode: 0644]
fonts/.svn/text-base/pf_tempesta_seven_extended_bold.ttf.svn-base [new file with mode: 0644]
fonts/BROWA.TTF [new file with mode: 0644]
fonts/pf_tempesta_seven.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_bold.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_compressed.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_compressed_bold.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_condensed.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_condensed_bold.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_extended.ttf [new file with mode: 0644]
fonts/pf_tempesta_seven_extended_bold.ttf [new file with mode: 0644]
img/.svn/all-wcprops [new file with mode: 0644]
img/.svn/dir-prop-base [new file with mode: 0644]
img/.svn/entries [new file with mode: 0644]
img/.svn/format [new file with mode: 0644]
img/.svn/prop-base/N800.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/N800_backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/N800_file.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/N810.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/N810_backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/N810_file.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/arrow.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/back_arrow_off.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/back_arrow_on.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/backup_default_button.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/backup_default_button_clicked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/backup_name_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/backup_name_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/battery_bar.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_backup0.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_geral0.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_geral2.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_manager.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bg_restore.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/black_arrow.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/browse_button.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bt_next.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/bt_next_clicked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/button_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/button_bg_clicked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/button_with_icon_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/button_with_icon_bg_clicked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/checkbox_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/checkbox_checked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/checkbox_unchecked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/copy_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/default_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_backup_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_checkbox_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_file_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_memory.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_name_border_backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_name_border_checkbox.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_name_border_file.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/device_selection_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/disconnected.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/disconnected_backup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/forward_arrow_off.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/forward_arrow_on.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/icon-alert-ref.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/icon-ref-managebackups.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/icon-ref-newbackup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/icon-ref-restorebackups.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/icon-ref-settings.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/ip_list_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/large_arrow_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/large_arrow_image.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/lista.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/memory_bar.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/path_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/path_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/pc_file_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/pc_image.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/pc_name_border_file.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_chunk.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_chunk_dialog.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_connecting_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/progress_bar_dialog_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/scroll_base_h.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/scroll_base_v.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/scroll_handle_h.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/scroll_handle_v.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_default_button.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_default_button_clicked.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_icon-ref-managebackups.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_icon-ref-newbackup.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_icon-ref-restorebackups.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/small_icon-ref-settings.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/ssh.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/tab_bg_1.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/tab_bg_2.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/tab_bg_3.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/table_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/tabletSuite_logo.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/tabletsuite.desktop.svn-base [new file with mode: 0644]
img/.svn/prop-base/view_bg.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/view_border.png.svn-base [new file with mode: 0644]
img/.svn/prop-base/white_arrow.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N800.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N800_backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N800_file.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N810.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N810_backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/N810_file.png.svn-base [new file with mode: 0644]
img/.svn/text-base/arrow.png.svn-base [new file with mode: 0644]
img/.svn/text-base/back_arrow_off.png.svn-base [new file with mode: 0644]
img/.svn/text-base/back_arrow_on.png.svn-base [new file with mode: 0644]
img/.svn/text-base/backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/backup_default_button.png.svn-base [new file with mode: 0644]
img/.svn/text-base/backup_default_button_clicked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/backup_name_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/backup_name_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/battery_bar.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_backup0.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_geral0.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_geral2.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_manager.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bg_restore.png.svn-base [new file with mode: 0644]
img/.svn/text-base/black_arrow.png.svn-base [new file with mode: 0644]
img/.svn/text-base/browse_button.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bt_next.png.svn-base [new file with mode: 0644]
img/.svn/text-base/bt_next_clicked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/button_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/button_bg_clicked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/button_with_icon_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/button_with_icon_bg_clicked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/checkbox_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/checkbox_checked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/checkbox_unchecked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/copy_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/default_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_backup_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_checkbox_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_file_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_memory.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_name_border_backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_name_border_checkbox.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_name_border_file.png.svn-base [new file with mode: 0644]
img/.svn/text-base/device_selection_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/disconnected.png.svn-base [new file with mode: 0644]
img/.svn/text-base/disconnected_backup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/forward_arrow_off.png.svn-base [new file with mode: 0644]
img/.svn/text-base/forward_arrow_on.png.svn-base [new file with mode: 0644]
img/.svn/text-base/icon-alert-ref.png.svn-base [new file with mode: 0644]
img/.svn/text-base/icon-ref-managebackups.png.svn-base [new file with mode: 0644]
img/.svn/text-base/icon-ref-newbackup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/icon-ref-restorebackups.png.svn-base [new file with mode: 0644]
img/.svn/text-base/icon-ref-settings.png.svn-base [new file with mode: 0644]
img/.svn/text-base/ip_list_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/large_arrow_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/large_arrow_image.png.svn-base [new file with mode: 0644]
img/.svn/text-base/lista.png.svn-base [new file with mode: 0644]
img/.svn/text-base/memory_bar.png.svn-base [new file with mode: 0644]
img/.svn/text-base/path_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/path_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/pc_file_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/pc_image.png.svn-base [new file with mode: 0644]
img/.svn/text-base/pc_name_border_file.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_chunk.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_chunk_dialog.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_connecting_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/progress_bar_dialog_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/scroll_base_h.png.svn-base [new file with mode: 0644]
img/.svn/text-base/scroll_base_v.png.svn-base [new file with mode: 0644]
img/.svn/text-base/scroll_handle_h.png.svn-base [new file with mode: 0644]
img/.svn/text-base/scroll_handle_v.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_default_button.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_default_button_clicked.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_icon-ref-managebackups.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_icon-ref-newbackup.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_icon-ref-restorebackups.png.svn-base [new file with mode: 0644]
img/.svn/text-base/small_icon-ref-settings.png.svn-base [new file with mode: 0644]
img/.svn/text-base/ssh.png.svn-base [new file with mode: 0644]
img/.svn/text-base/tab_bg_1.png.svn-base [new file with mode: 0644]
img/.svn/text-base/tab_bg_2.png.svn-base [new file with mode: 0644]
img/.svn/text-base/tab_bg_3.png.svn-base [new file with mode: 0644]
img/.svn/text-base/table_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/tabletSuite_logo.png.svn-base [new file with mode: 0644]
img/.svn/text-base/tabletsuite.desktop.svn-base [new file with mode: 0644]
img/.svn/text-base/view_bg.png.svn-base [new file with mode: 0644]
img/.svn/text-base/view_border.png.svn-base [new file with mode: 0644]
img/.svn/text-base/white_arrow.png.svn-base [new file with mode: 0644]
img/N800.png [new file with mode: 0644]
img/N800_backup.png [new file with mode: 0644]
img/N800_file.png [new file with mode: 0644]
img/N810.png [new file with mode: 0644]
img/N810_backup.png [new file with mode: 0644]
img/N810_file.png [new file with mode: 0644]
img/arrow.png [new file with mode: 0755]
img/back_arrow_off.png [new file with mode: 0755]
img/back_arrow_on.png [new file with mode: 0755]
img/backup.png [new file with mode: 0644]
img/backup_default_button.png [new file with mode: 0644]
img/backup_default_button_clicked.png [new file with mode: 0644]
img/backup_name_bg.png [new file with mode: 0644]
img/backup_name_border.png [new file with mode: 0644]
img/battery_bar.png [new file with mode: 0644]
img/bg_backup.png [new file with mode: 0644]
img/bg_backup0.png [new file with mode: 0644]
img/bg_geral0.png [new file with mode: 0644]
img/bg_geral2.png [new file with mode: 0644]
img/bg_manager.png [new file with mode: 0644]
img/bg_restore.png [new file with mode: 0644]
img/black_arrow.png [new file with mode: 0644]
img/browse_button.png [new file with mode: 0644]
img/bt_next.png [new file with mode: 0644]
img/bt_next_clicked.png [new file with mode: 0644]
img/button_bg.png [new file with mode: 0644]
img/button_bg_clicked.png [new file with mode: 0644]
img/button_with_icon_bg.png [new file with mode: 0644]
img/button_with_icon_bg_clicked.png [new file with mode: 0644]
img/checkbox_border.png [new file with mode: 0644]
img/checkbox_checked.png [new file with mode: 0644]
img/checkbox_unchecked.png [new file with mode: 0644]
img/copy_border.png [new file with mode: 0644]
img/default_bg.png [new file with mode: 0644]
img/device_backup_border.png [new file with mode: 0644]
img/device_checkbox_border.png [new file with mode: 0644]
img/device_file_border.png [new file with mode: 0644]
img/device_memory.png [new file with mode: 0644]
img/device_name_border_backup.png [new file with mode: 0644]
img/device_name_border_checkbox.png [new file with mode: 0644]
img/device_name_border_file.png [new file with mode: 0644]
img/device_selection_bg.png [new file with mode: 0644]
img/disconnected.png [new file with mode: 0644]
img/disconnected_backup.png [new file with mode: 0644]
img/forward_arrow_off.png [new file with mode: 0755]
img/forward_arrow_on.png [new file with mode: 0755]
img/icon-alert-ref.png [new file with mode: 0644]
img/icon-ref-managebackups.png [new file with mode: 0644]
img/icon-ref-newbackup.png [new file with mode: 0644]
img/icon-ref-restorebackups.png [new file with mode: 0644]
img/icon-ref-settings.png [new file with mode: 0644]
img/ip_list_border.png [new file with mode: 0644]
img/large_arrow_border.png [new file with mode: 0644]
img/large_arrow_image.png [new file with mode: 0644]
img/lista.png [new file with mode: 0644]
img/memory_bar.png [new file with mode: 0644]
img/path_bg.png [new file with mode: 0644]
img/path_border.png [new file with mode: 0644]
img/pc_file_border.png [new file with mode: 0644]
img/pc_image.png [new file with mode: 0644]
img/pc_name_border_file.png [new file with mode: 0644]
img/progress_bar_bg.png [new file with mode: 0644]
img/progress_bar_border.png [new file with mode: 0644]
img/progress_bar_chunk.png [new file with mode: 0644]
img/progress_bar_chunk_dialog.png [new file with mode: 0644]
img/progress_bar_connecting_bg.png [new file with mode: 0644]
img/progress_bar_dialog_bg.png [new file with mode: 0644]
img/scroll_base_h.png [new file with mode: 0644]
img/scroll_base_v.png [new file with mode: 0644]
img/scroll_handle_h.png [new file with mode: 0644]
img/scroll_handle_v.png [new file with mode: 0644]
img/small_default_button.png [new file with mode: 0644]
img/small_default_button_clicked.png [new file with mode: 0644]
img/small_icon-ref-managebackups.png [new file with mode: 0644]
img/small_icon-ref-newbackup.png [new file with mode: 0644]
img/small_icon-ref-restorebackups.png [new file with mode: 0644]
img/small_icon-ref-settings.png [new file with mode: 0644]
img/ssh.png [new file with mode: 0644]
img/tab_bg_1.png [new file with mode: 0644]
img/tab_bg_2.png [new file with mode: 0644]
img/tab_bg_3.png [new file with mode: 0644]
img/table_border.png [new file with mode: 0644]
img/tabletSuite_logo.png [new file with mode: 0644]
img/tabletsuite.desktop [new file with mode: 0755]
img/view_bg.png [new file with mode: 0644]
img/view_border.png [new file with mode: 0644]
img/white_arrow.png [new file with mode: 0755]
setup.py [new file with mode: 0755]
src/.svn/all-wcprops [new file with mode: 0644]
src/.svn/dir-prop-base [new file with mode: 0644]
src/.svn/entries [new file with mode: 0644]
src/.svn/format [new file with mode: 0644]
src/.svn/prop-base/pcsutils.py.svn-base [new file with mode: 0644]
src/.svn/prop-base/tabletsuite.py.svn-base [new file with mode: 0644]
src/.svn/text-base/__init__.py.svn-base [new file with mode: 0644]
src/.svn/text-base/battery.py.svn-base [new file with mode: 0644]
src/.svn/text-base/pcsdeviceinfo.py.svn-base [new file with mode: 0644]
src/.svn/text-base/pcsdevicemanager.py.svn-base [new file with mode: 0644]
src/.svn/text-base/pcsdeviceutils.py.svn-base [new file with mode: 0644]
src/.svn/text-base/pcsutils.py.svn-base [new file with mode: 0644]
src/.svn/text-base/settings.py.svn-base [new file with mode: 0644]
src/.svn/text-base/tabletsuite.py.svn-base [new file with mode: 0644]
src/__init__.py [new file with mode: 0644]
src/backup/.svn/all-wcprops [new file with mode: 0644]
src/backup/.svn/dir-prop-base [new file with mode: 0644]
src/backup/.svn/entries [new file with mode: 0644]
src/backup/.svn/format [new file with mode: 0644]
src/backup/.svn/prop-base/pcsbackuplocation.py.svn-base [new file with mode: 0644]
src/backup/.svn/prop-base/pcsbackuputils.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/__init__.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackup.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupinfo.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackuplistui.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackuplocation.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupmanager.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupmanagerui.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupparser.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackuputils.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupwizard.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsbackupxml.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcscheckboxwizard.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsdevicebackupmanager.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsopenfilewizard.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcspcbackupmanager.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsprogressdialog.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsprogresswizard.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsrestorebackupui.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcsrestoredialog.py.svn-base [new file with mode: 0644]
src/backup/.svn/text-base/pcswindowmanager.py.svn-base [new file with mode: 0644]
src/backup/__init__.py [new file with mode: 0644]
src/backup/pcsbackup.py [new file with mode: 0644]
src/backup/pcsbackupinfo.py [new file with mode: 0644]
src/backup/pcsbackuplistui.py [new file with mode: 0644]
src/backup/pcsbackuplocation.py [new file with mode: 0644]
src/backup/pcsbackupmanager.py [new file with mode: 0644]
src/backup/pcsbackupmanagerui.py [new file with mode: 0644]
src/backup/pcsbackupparser.py [new file with mode: 0644]
src/backup/pcsbackuputils.py [new file with mode: 0755]
src/backup/pcsbackupwizard.py [new file with mode: 0644]
src/backup/pcsbackupxml.py [new file with mode: 0644]
src/backup/pcscheckboxwizard.py [new file with mode: 0644]
src/backup/pcsdevicebackupmanager.py [new file with mode: 0644]
src/backup/pcsopenfilewizard.py [new file with mode: 0644]
src/backup/pcspcbackupmanager.py [new file with mode: 0644]
src/backup/pcsprogressdialog.py [new file with mode: 0644]
src/backup/pcsprogresswizard.py [new file with mode: 0644]
src/backup/pcsrestorebackupui.py [new file with mode: 0644]
src/backup/pcsrestoredialog.py [new file with mode: 0644]
src/backup/pcswindowmanager.py [new file with mode: 0644]
src/battery.py [new file with mode: 0644]
src/pcsdeviceinfo.py [new file with mode: 0644]
src/pcsdevicemanager.py [new file with mode: 0644]
src/pcsdeviceutils.py [new file with mode: 0644]
src/pcsuite/.svn/all-wcprops [new file with mode: 0644]
src/pcsuite/.svn/dir-prop-base [new file with mode: 0644]
src/pcsuite/.svn/entries [new file with mode: 0644]
src/pcsuite/.svn/format [new file with mode: 0644]
src/pcsuite/.svn/text-base/__init__.py.svn-base [new file with mode: 0644]
src/pcsuite/.svn/text-base/pcsuite.py.svn-base [new file with mode: 0644]
src/pcsuite/__init__.py [new file with mode: 0644]
src/pcsuite/pcsuite.py [new file with mode: 0644]
src/pcsutils.py [new file with mode: 0755]
src/plugins/.svn/all-wcprops [new file with mode: 0644]
src/plugins/.svn/entries [new file with mode: 0644]
src/plugins/.svn/format [new file with mode: 0644]
src/settings.py [new file with mode: 0644]
src/style/.svn/all-wcprops [new file with mode: 0644]
src/style/.svn/entries [new file with mode: 0644]
src/style/.svn/format [new file with mode: 0644]
src/style/.svn/text-base/__init__.py.svn-base [new file with mode: 0644]
src/style/.svn/text-base/styleTabletSuite.py.svn-base [new file with mode: 0644]
src/style/__init__.py [new file with mode: 0644]
src/style/styleTabletSuite.py [new file with mode: 0644]
src/tabletsuite.py [new file with mode: 0644]
src/ui/.svn/all-wcprops [new file with mode: 0644]
src/ui/.svn/dir-prop-base [new file with mode: 0644]
src/ui/.svn/entries [new file with mode: 0644]
src/ui/.svn/format [new file with mode: 0644]
src/ui/.svn/text-base/__init__.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsapp.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsapplicationlist.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsbutton.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcscustombuttons.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsdeviceinfoviewer.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsdeviceviewer.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsdevicewidget.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsmenu.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/pcsuiutils.py.svn-base [new file with mode: 0644]
src/ui/.svn/text-base/tsuigeneralmethods.py.svn-base [new file with mode: 0644]
src/ui/__init__.py [new file with mode: 0644]
src/ui/pcsapp.py [new file with mode: 0644]
src/ui/pcsapplicationlist.py [new file with mode: 0644]
src/ui/pcsbutton.py [new file with mode: 0644]
src/ui/pcscustombuttons.py [new file with mode: 0644]
src/ui/pcsdeviceinfoviewer.py [new file with mode: 0644]
src/ui/pcsdeviceviewer.py [new file with mode: 0644]
src/ui/pcsdevicewidget.py [new file with mode: 0644]
src/ui/pcsmenu.py [new file with mode: 0644]
src/ui/pcsuiutils.py [new file with mode: 0644]
src/ui/tsuigeneralmethods.py [new file with mode: 0644]
tabletsuite [new file with mode: 0644]
welcome [deleted file]

diff --git a/debian/.svn/all-wcprops b/debian/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..73104a5
--- /dev/null
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/pc-suite/!svn/ver/650/trunk/tabletsuite/debian
+END
+control
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/svn/pc-suite/!svn/ver/650/trunk/tabletsuite/debian/control
+END
+compat
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/debian/compat
+END
+changelog
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/649/trunk/tabletsuite/debian/changelog
+END
+copyright
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/debian/copyright
+END
+docs
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/debian/docs
+END
+rules
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/debian/rules
+END
diff --git a/debian/.svn/dir-prop-base b/debian/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/debian/.svn/entries b/debian/.svn/entries
new file mode 100644 (file)
index 0000000..c99fd2d
--- /dev/null
@@ -0,0 +1,232 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/debian
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-09-29T15:40:22.681741Z
+650
+otacilio
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+control
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+3f11fa51870d30106bcaba2287c59637
+2009-09-29T15:40:22.681741Z
+650
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+397
+\f
+compat
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+84bc3da1b3e33a18e8d5e1bdd7a18d7a
+2009-07-30T18:46:46.398336Z
+495
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2
+\f
+changelog
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+1b9dbce6d0ba853bfec1ac3ed6bb8e2d
+2009-09-28T17:26:29.361774Z
+649
+melunko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+156
+\f
+copyright
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+dee7a3d70eedde5d9959617122de4083
+2009-07-30T18:46:46.398336Z
+495
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+696
+\f
+docs
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-07-30T18:46:46.398336Z
+495
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+rules
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+bb04c0b837f042492f69dd6a707c39df
+2009-08-04T13:54:03.919326Z
+505
+otacilio
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+169
+\f
diff --git a/debian/.svn/format b/debian/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/debian/.svn/prop-base/rules.svn-base b/debian/.svn/prop-base/rules.svn-base
new file mode 100644 (file)
index 0000000..869ac71
--- /dev/null
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/debian/.svn/text-base/changelog.svn-base b/debian/.svn/text-base/changelog.svn-base
new file mode 100644 (file)
index 0000000..e839256
--- /dev/null
@@ -0,0 +1,5 @@
+tablet-suite (0.1) unstable; urgency=low
+
+  * Initial release
+
+ -- Otacilio Freitas de Lacerda <otaciliolacerda@gmail.com>  Thu, 30 Jul 2009 13:26:51 -0300
diff --git a/debian/.svn/text-base/compat.svn-base b/debian/.svn/text-base/compat.svn-base
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/debian/.svn/text-base/control.svn-base b/debian/.svn/text-base/control.svn-base
new file mode 100644 (file)
index 0000000..cf01246
--- /dev/null
@@ -0,0 +1,13 @@
+Source: tablet-suite
+Section: python
+Priority: optional
+Maintainer: Otacilio Freitas de Lacerda <otaciliolacerda@gmail.com>
+Build-Depends: cdbs, debhelper (>= 7), python2.6
+Standards-Version: 3.8.0
+
+Package: tablet-suite
+Architecture: all
+Depends: sshfs, python-qt4, python2.6, openssh-client, python-paramiko
+Description: <TabletSuite Alpha>
+ <.
+ This package contains the tablet-suite project.>
diff --git a/debian/.svn/text-base/copyright.svn-base b/debian/.svn/text-base/copyright.svn-base
new file mode 100644 (file)
index 0000000..f382bbc
--- /dev/null
@@ -0,0 +1,24 @@
+This package was debianized by Otacilio Freitas de Lacerda <otacilio@unknown> on
+Thu, 30 Jul 2009 13:26:51 -0300.
+
+It was downloaded from <url://example.com>
+
+Upstream Author(s):
+
+    <put author's name and email here>
+    <likewise for another author>
+
+Copyright:
+
+    <Copyright (C) YYYY Name OfAuthor>
+    <likewise for another author>
+
+License:
+
+    <Put the license of the package here indented by 4 spaces>
+
+The Debian packaging is copyright 2009, Otacilio Freitas de Lacerda <otacilio@unknown> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
diff --git a/debian/.svn/text-base/docs.svn-base b/debian/.svn/text-base/docs.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/debian/.svn/text-base/rules.svn-base b/debian/.svn/text-base/rules.svn-base
new file mode 100644 (file)
index 0000000..329bb2a
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/python-distutils.mk
+include /usr/share/cdbs/1/rules/simple-patchsys.mk
+
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..e839256
--- /dev/null
@@ -0,0 +1,5 @@
+tablet-suite (0.1) unstable; urgency=low
+
+  * Initial release
+
+ -- Otacilio Freitas de Lacerda <otaciliolacerda@gmail.com>  Thu, 30 Jul 2009 13:26:51 -0300
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..cf01246
--- /dev/null
@@ -0,0 +1,13 @@
+Source: tablet-suite
+Section: python
+Priority: optional
+Maintainer: Otacilio Freitas de Lacerda <otaciliolacerda@gmail.com>
+Build-Depends: cdbs, debhelper (>= 7), python2.6
+Standards-Version: 3.8.0
+
+Package: tablet-suite
+Architecture: all
+Depends: sshfs, python-qt4, python2.6, openssh-client, python-paramiko
+Description: <TabletSuite Alpha>
+ <.
+ This package contains the tablet-suite project.>
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..f382bbc
--- /dev/null
@@ -0,0 +1,24 @@
+This package was debianized by Otacilio Freitas de Lacerda <otacilio@unknown> on
+Thu, 30 Jul 2009 13:26:51 -0300.
+
+It was downloaded from <url://example.com>
+
+Upstream Author(s):
+
+    <put author's name and email here>
+    <likewise for another author>
+
+Copyright:
+
+    <Copyright (C) YYYY Name OfAuthor>
+    <likewise for another author>
+
+License:
+
+    <Put the license of the package here indented by 4 spaces>
+
+The Debian packaging is copyright 2009, Otacilio Freitas de Lacerda <otacilio@unknown> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..329bb2a
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/python-distutils.mk
+include /usr/share/cdbs/1/rules/simple-patchsys.mk
+
diff --git a/fonts/.svn/all-wcprops b/fonts/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..1a92acc
--- /dev/null
@@ -0,0 +1,59 @@
+K 25
+svn:wc:ra_dav:version-url
+V 50
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts
+END
+pf_tempesta_seven.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven.ttf
+END
+pf_tempesta_seven_bold.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_bold.ttf
+END
+pf_tempesta_seven_extended.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_extended.ttf
+END
+pf_tempesta_seven_extended_bold.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_extended_bold.ttf
+END
+pf_tempesta_seven_condensed.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_condensed.ttf
+END
+pf_tempesta_seven_condensed_bold.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 87
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_condensed_bold.ttf
+END
+BROWA.TTF
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/BROWA.TTF
+END
+pf_tempesta_seven_compressed.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_compressed.ttf
+END
+pf_tempesta_seven_compressed_bold.ttf
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/svn/pc-suite/!svn/ver/632/trunk/tabletsuite/fonts/pf_tempesta_seven_compressed_bold.ttf
+END
diff --git a/fonts/.svn/entries b/fonts/.svn/entries
new file mode 100644 (file)
index 0000000..252b795
--- /dev/null
@@ -0,0 +1,334 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/fonts
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-09-15T18:22:54.599315Z
+632
+amaury
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+pf_tempesta_seven.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+9f70908a87757dce7c6e692cd9b6dacb
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22176
+\f
+pf_tempesta_seven_bold.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+31fbb55b275dbdededfc430f50ad9354
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21780
+\f
+pf_tempesta_seven_extended.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+07b0d01caeb4f8a81ae384119e1c182d
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22464
+\f
+pf_tempesta_seven_extended_bold.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8e2f92fc5a949a2cca42e28d019f5681
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22160
+\f
+pf_tempesta_seven_condensed.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+18f38e87a9c2dfd026026d8922d5ce9e
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21616
+\f
+pf_tempesta_seven_condensed_bold.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+6b38585aac6b3b3a37e218faa4f06ae7
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21160
+\f
+BROWA.TTF
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+558e1f7c26d9405ac41942266ebac11d
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+80392
+\f
+pf_tempesta_seven_compressed.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+ff7b35bf8a97fbb416e5d475a6cff55f
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+20396
+\f
+pf_tempesta_seven_compressed_bold.ttf
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8cc607fb27e7fdc770eea5c45dc9d823
+2009-09-15T18:22:54.599315Z
+632
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+20796
+\f
diff --git a/fonts/.svn/format b/fonts/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/fonts/.svn/prop-base/BROWA.TTF.svn-base b/fonts/.svn/prop-base/BROWA.TTF.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_bold.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_compressed.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_compressed.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_compressed_bold.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_compressed_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_condensed.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_condensed.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_condensed_bold.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_condensed_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_extended.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_extended.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/prop-base/pf_tempesta_seven_extended_bold.ttf.svn-base b/fonts/.svn/prop-base/pf_tempesta_seven_extended_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/fonts/.svn/text-base/BROWA.TTF.svn-base b/fonts/.svn/text-base/BROWA.TTF.svn-base
new file mode 100644 (file)
index 0000000..dfd6ef5
Binary files /dev/null and b/fonts/.svn/text-base/BROWA.TTF.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven.ttf.svn-base
new file mode 100644 (file)
index 0000000..90c96f3
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_bold.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..8069c6f
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_bold.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_compressed.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_compressed.ttf.svn-base
new file mode 100644 (file)
index 0000000..f40e35c
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_compressed.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_compressed_bold.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_compressed_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..c208390
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_compressed_bold.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_condensed.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_condensed.ttf.svn-base
new file mode 100644 (file)
index 0000000..4d25500
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_condensed.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_condensed_bold.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_condensed_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..8f0203f
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_condensed_bold.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_extended.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_extended.ttf.svn-base
new file mode 100644 (file)
index 0000000..94dbe8e
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_extended.ttf.svn-base differ
diff --git a/fonts/.svn/text-base/pf_tempesta_seven_extended_bold.ttf.svn-base b/fonts/.svn/text-base/pf_tempesta_seven_extended_bold.ttf.svn-base
new file mode 100644 (file)
index 0000000..e3d8ff1
Binary files /dev/null and b/fonts/.svn/text-base/pf_tempesta_seven_extended_bold.ttf.svn-base differ
diff --git a/fonts/BROWA.TTF b/fonts/BROWA.TTF
new file mode 100644 (file)
index 0000000..dfd6ef5
Binary files /dev/null and b/fonts/BROWA.TTF differ
diff --git a/fonts/pf_tempesta_seven.ttf b/fonts/pf_tempesta_seven.ttf
new file mode 100644 (file)
index 0000000..90c96f3
Binary files /dev/null and b/fonts/pf_tempesta_seven.ttf differ
diff --git a/fonts/pf_tempesta_seven_bold.ttf b/fonts/pf_tempesta_seven_bold.ttf
new file mode 100644 (file)
index 0000000..8069c6f
Binary files /dev/null and b/fonts/pf_tempesta_seven_bold.ttf differ
diff --git a/fonts/pf_tempesta_seven_compressed.ttf b/fonts/pf_tempesta_seven_compressed.ttf
new file mode 100644 (file)
index 0000000..f40e35c
Binary files /dev/null and b/fonts/pf_tempesta_seven_compressed.ttf differ
diff --git a/fonts/pf_tempesta_seven_compressed_bold.ttf b/fonts/pf_tempesta_seven_compressed_bold.ttf
new file mode 100644 (file)
index 0000000..c208390
Binary files /dev/null and b/fonts/pf_tempesta_seven_compressed_bold.ttf differ
diff --git a/fonts/pf_tempesta_seven_condensed.ttf b/fonts/pf_tempesta_seven_condensed.ttf
new file mode 100644 (file)
index 0000000..4d25500
Binary files /dev/null and b/fonts/pf_tempesta_seven_condensed.ttf differ
diff --git a/fonts/pf_tempesta_seven_condensed_bold.ttf b/fonts/pf_tempesta_seven_condensed_bold.ttf
new file mode 100644 (file)
index 0000000..8f0203f
Binary files /dev/null and b/fonts/pf_tempesta_seven_condensed_bold.ttf differ
diff --git a/fonts/pf_tempesta_seven_extended.ttf b/fonts/pf_tempesta_seven_extended.ttf
new file mode 100644 (file)
index 0000000..94dbe8e
Binary files /dev/null and b/fonts/pf_tempesta_seven_extended.ttf differ
diff --git a/fonts/pf_tempesta_seven_extended_bold.ttf b/fonts/pf_tempesta_seven_extended_bold.ttf
new file mode 100644 (file)
index 0000000..e3d8ff1
Binary files /dev/null and b/fonts/pf_tempesta_seven_extended_bold.ttf differ
diff --git a/img/.svn/all-wcprops b/img/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..be3e401
--- /dev/null
@@ -0,0 +1,527 @@
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/svn/pc-suite/!svn/ver/643/trunk/tabletsuite/img
+END
+checkbox_checked.png
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/checkbox_checked.png
+END
+scroll_handle_v.png
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/610/trunk/tabletsuite/img/scroll_handle_v.png
+END
+scroll_base_h.png
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/610/trunk/tabletsuite/img/scroll_base_h.png
+END
+ip_list_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/591/trunk/tabletsuite/img/ip_list_border.png
+END
+progress_bar_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/progress_bar_bg.png
+END
+backup_name_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/backup_name_border.png
+END
+large_arrow_image.png
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/large_arrow_image.png
+END
+small_default_button.png
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/svn/pc-suite/!svn/ver/591/trunk/tabletsuite/img/small_default_button.png
+END
+progress_bar_connecting_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/svn/pc-suite/!svn/ver/612/trunk/tabletsuite/img/progress_bar_connecting_bg.png
+END
+scroll_base_v.png
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/610/trunk/tabletsuite/img/scroll_base_v.png
+END
+progress_bar_chunk.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/609/trunk/tabletsuite/img/progress_bar_chunk.png
+END
+view_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/600/trunk/tabletsuite/img/view_bg.png
+END
+bg_geral0.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bg_geral0.png
+END
+table_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/table_border.png
+END
+bg_geral2.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bg_geral2.png
+END
+progress_bar_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/progress_bar_border.png
+END
+N810_file.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N810_file.png
+END
+N800.png
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N800.png
+END
+small_default_button_clicked.png
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/svn/pc-suite/!svn/ver/591/trunk/tabletsuite/img/small_default_button_clicked.png
+END
+disconnected_backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/624/trunk/tabletsuite/img/disconnected_backup.png
+END
+white_arrow.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/white_arrow.png
+END
+device_file_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_file_border.png
+END
+bg_restore.png
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bg_restore.png
+END
+icon-ref-restorebackups.png
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/icon-ref-restorebackups.png
+END
+default_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/610/trunk/tabletsuite/img/default_bg.png
+END
+browse_button.png
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/browse_button.png
+END
+bg_backup0.png
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bg_backup0.png
+END
+pc_name_border_file.png
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/pc_name_border_file.png
+END
+pc_file_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/pc_file_border.png
+END
+checkbox_unchecked.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/checkbox_unchecked.png
+END
+icon-ref-settings.png
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/icon-ref-settings.png
+END
+large_arrow_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/large_arrow_border.png
+END
+device_checkbox_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_checkbox_border.png
+END
+device_name_border_checkbox.png
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_name_border_checkbox.png
+END
+disconnected.png
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/disconnected.png
+END
+backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/backup.png
+END
+back_arrow_on.png
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/back_arrow_on.png
+END
+view_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/600/trunk/tabletsuite/img/view_border.png
+END
+icon-alert-ref.png
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/icon-alert-ref.png
+END
+tabletsuite.desktop
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/643/trunk/tabletsuite/img/tabletsuite.desktop
+END
+N800_backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N800_backup.png
+END
+forward_arrow_on.png
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/forward_arrow_on.png
+END
+N810_backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N810_backup.png
+END
+lista.png
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/lista.png
+END
+bg_backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bg_backup.png
+END
+icon-ref-newbackup.png
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/icon-ref-newbackup.png
+END
+device_backup_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_backup_border.png
+END
+N810.png
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N810.png
+END
+arrow.png
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/arrow.png
+END
+device_name_border_file.png
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_name_border_file.png
+END
+tab_bg_1.png
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/tab_bg_1.png
+END
+tab_bg_2.png
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/tab_bg_2.png
+END
+progress_bar_chunk_dialog.png
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/svn/pc-suite/!svn/ver/609/trunk/tabletsuite/img/progress_bar_chunk_dialog.png
+END
+tab_bg_3.png
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/tab_bg_3.png
+END
+icon-ref-managebackups.png
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/icon-ref-managebackups.png
+END
+pc_image.png
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/614/trunk/tabletsuite/img/pc_image.png
+END
+progress_bar_dialog_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/609/trunk/tabletsuite/img/progress_bar_dialog_bg.png
+END
+device_name_border_backup.png
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_name_border_backup.png
+END
+checkbox_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/checkbox_border.png
+END
+button_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/button_bg.png
+END
+small_icon-ref-restorebackups.png
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/small_icon-ref-restorebackups.png
+END
+N800_file.png
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/608/trunk/tabletsuite/img/N800_file.png
+END
+button_with_icon_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/button_with_icon_bg.png
+END
+black_arrow.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/black_arrow.png
+END
+small_icon-ref-settings.png
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/small_icon-ref-settings.png
+END
+memory_bar.png
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/memory_bar.png
+END
+ssh.png
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/ssh.png
+END
+battery_bar.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/battery_bar.png
+END
+button_bg_clicked.png
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/button_bg_clicked.png
+END
+bt_next.png
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bt_next.png
+END
+path_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/path_bg.png
+END
+backup_default_button.png
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/backup_default_button.png
+END
+back_arrow_off.png
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/back_arrow_off.png
+END
+button_with_icon_bg_clicked.png
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/button_with_icon_bg_clicked.png
+END
+tabletSuite_logo.png
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/tabletSuite_logo.png
+END
+copy_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/copy_border.png
+END
+small_icon-ref-newbackup.png
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/small_icon-ref-newbackup.png
+END
+forward_arrow_off.png
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/forward_arrow_off.png
+END
+device_selection_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/600/trunk/tabletsuite/img/device_selection_bg.png
+END
+backup_name_bg.png
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/backup_name_bg.png
+END
+scroll_handle_h.png
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/610/trunk/tabletsuite/img/scroll_handle_h.png
+END
+bt_next_clicked.png
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/bt_next_clicked.png
+END
+backup_default_button_clicked.png
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/backup_default_button_clicked.png
+END
+bg_manager.png
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/596/trunk/tabletsuite/img/bg_manager.png
+END
+device_memory.png
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/device_memory.png
+END
+path_border.png
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/img/path_border.png
+END
+small_icon-ref-managebackups.png
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/svn/pc-suite/!svn/ver/626/trunk/tabletsuite/img/small_icon-ref-managebackups.png
+END
diff --git a/img/.svn/dir-prop-base b/img/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/img/.svn/entries b/img/.svn/entries
new file mode 100644 (file)
index 0000000..71bb608
--- /dev/null
@@ -0,0 +1,2986 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/img
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-09-24T18:11:29.733195Z
+643
+otacilio
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+checkbox_checked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+a01bf9fbe352b626b8e5b3484c9e645e
+2009-08-13T17:08:11.546686Z
+550
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+822
+\f
+scroll_handle_v.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+cfbffd47da519d20e6c645586e1be0fc
+2009-09-09T16:10:10.046818Z
+610
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3103
+\f
+scroll_base_h.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+23e767ca7a1bf2a2158e52837f6e415b
+2009-09-09T16:10:10.046818Z
+610
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+844
+\f
+progress_bar_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+342126781b58ecf007b3faad2568af64
+2009-08-21T18:19:06.773534Z
+573
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3756
+\f
+ip_list_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+eaca0b8358ab0e84df410a39886c9d6f
+2009-09-03T16:03:51.683671Z
+591
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4841
+\f
+backup_name_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+78844d8e12b99fab3f63869565651301
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3410
+\f
+large_arrow_image.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+2957d2a0847d5844f5a130b40d11271a
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5609
+\f
+progress_bar_connecting_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+00f570e8e6010180c9bd53f241fae029
+2009-09-10T20:35:15.948790Z
+612
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3699
+\f
+small_default_button.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+13644f0774d460563f934c46e2cd8056
+2009-09-03T16:03:51.683671Z
+591
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3443
+\f
+scroll_base_v.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+3230dc7d26417d0b4d968c9a6f2c71c5
+2009-09-09T16:10:10.046818Z
+610
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3597
+\f
+progress_bar_chunk.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+f9a64d04eb7eae7900af543bedf374be
+2009-09-08T17:01:54.301655Z
+609
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3279
+\f
+bg_geral0.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+91111ff0319924d279c47e55423dec94
+2009-07-28T18:31:05.094742Z
+476
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+79464
+\f
+view_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+6d46d6caa3a6ca58e35094b664a39a6b
+2009-09-03T22:08:31.931352Z
+600
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3281
+\f
+bg_geral2.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+e6e8a6c49810a752be37c0e22f753781
+2009-07-16T17:37:19.503117Z
+437
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+52909
+\f
+table_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+aec2ba53080f3ffa7ee774e73211b8f5
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4887
+\f
+progress_bar_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d888d82dcd05b6055888ba810fa25799
+2009-08-21T18:19:06.773534Z
+573
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3273
+\f
+N810_file.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+de0f0760975780acd73d91f857d05426
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10288
+\f
+N800.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8ed3e9ce544ea2f26a4dbd7657122398
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6231
+\f
+small_default_button_clicked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+a1fa5275ce8a0ec5e68d25b3e9f02883
+2009-09-03T16:03:51.683671Z
+591
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3579
+\f
+disconnected_backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+7414015bc4afd729f9b54b05ea9c04f7
+2009-09-14T19:20:21.821743Z
+624
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21287
+\f
+white_arrow.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+690dc22ed876c3436a427891a9115362
+2009-07-29T09:45:01.027130Z
+482
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2817
+\f
+device_file_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+4211e9d5c31659da6d66dad550c9d646
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4224
+\f
+bg_restore.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+460acdb041c97f3b866c48bd01e6dcc4
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+62107
+\f
+icon-ref-restorebackups.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+06caf36fbbacfa1e892c62e6ad6cd104
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4633
+\f
+default_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+562028809d59ea75c5bb4fc2face91b7
+2009-09-09T16:10:10.046818Z
+610
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2396
+\f
+browse_button.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+850dd65278e2b1ab21ad0a9bd34e6c31
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3991
+\f
+bg_backup0.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+71b7252b3021dd09f8ec587549118893
+2009-08-11T16:36:01.916949Z
+539
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+48940
+\f
+pc_name_border_file.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+cafe36896b8b58e92d5d351b0c153720
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3468
+\f
+pc_file_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+20068b0940926d1110879ab4a59fb44f
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4230
+\f
+checkbox_unchecked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+118a0f804bcc4d7e90be766910bbc51c
+2009-08-13T17:08:11.546686Z
+550
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+688
+\f
+icon-ref-settings.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+1a0d9597956dda69c405967db13fed7c
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5214
+\f
+large_arrow_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+0f34a62a541a7caa7aa2f1d4b1d9b112
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6248
+\f
+disconnected.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+ff9a15db496d8dae6461766710d6686d
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12211
+\f
+device_name_border_checkbox.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+bd2ca576ffc5981ec2323064d2dadb65
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3324
+\f
+device_checkbox_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+cf98ab9a0bb3870789b4853bd1957667
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4304
+\f
+backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+870aca33c4343973c09b83e3dfe45ab4
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4657
+\f
+back_arrow_on.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d259ebab223ef56773733ce28676fb3e
+2009-07-29T12:18:32.451141Z
+490
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2954
+\f
+icon-alert-ref.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+36c02dce8980394a63d0716986846db4
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3604
+\f
+view_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+07c9e5b9c933aab32c52d83369f1749b
+2009-09-03T22:08:31.931352Z
+600
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4512
+\f
+forward_arrow_on.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+972f112af726e4cc1048c4957987df5c
+2009-07-29T12:18:32.451141Z
+490
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2950
+\f
+N800_backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+3a755c3c2d6016b103280e1dfac404c3
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10860
+\f
+tabletsuite.desktop
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+57206ed9fbe3ad7e9f6035587fc0a20d
+2009-09-24T18:11:29.733195Z
+643
+otacilio
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+269
+\f
+N810_backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+f42fa915e09e712f6904561390845c73
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19137
+\f
+lista.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+21abea4315d51598bc9493ba74507eb5
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3363
+\f
+bg_backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+929064a3d451a8c7e72c8e211401db87
+2009-08-07T19:29:53.557169Z
+529
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+74676
+\f
+icon-ref-newbackup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+207b1bdc88279b56c6755a3841021208
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4895
+\f
+device_backup_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+afb641c1d2d237b8be0b564ed6c979c1
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4792
+\f
+N810.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+24f08a897165cee8770aee6a05e0ed65
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12356
+\f
+arrow.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+690dc22ed876c3436a427891a9115362
+2009-07-28T17:43:56.280909Z
+474
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2817
+\f
+device_name_border_file.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d425373982afaea21744991e30f584fe
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3399
+\f
+tab_bg_1.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+5cd4e834dcd5137cf36f48552cb30ef6
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11985
+\f
+progress_bar_chunk_dialog.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8201eaae0da8f4f292365a716b4d527a
+2009-09-08T17:01:54.301655Z
+609
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3228
+\f
+tab_bg_2.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+e822a037236b010e3285fd7c6b0026c2
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10955
+\f
+tab_bg_3.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+53bb3b054aa1ae191d9a3caf0f3d5cb8
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7825
+\f
+icon-ref-managebackups.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+1d823eb2520527d96b65d79292c3bfdb
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5154
+\f
+pc_image.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8aef2711997e0be150bfb960d4b22f3d
+2009-09-10T22:40:29.655655Z
+614
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6196
+\f
+progress_bar_dialog_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+4a2c3ade46963dee17dcf765773e9274
+2009-09-08T17:01:54.301655Z
+609
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3903
+\f
+device_name_border_backup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+845b4976344776d80ab27ef9baf073d4
+2009-08-10T18:42:02.033426Z
+532
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3487
+\f
+button_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8f7e66a13a3d77964b89ecc60062fd8b
+2009-08-05T16:55:19.618241Z
+511
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5430
+\f
+checkbox_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+335ed6a4799668bd6d0e2e84f69c6f62
+2009-08-12T10:13:12.305172Z
+544
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3953
+\f
+N800_file.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+de991fbf0dde3cf6b7bfa3f5bc1dbdad
+2009-09-08T14:59:55.898571Z
+608
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5012
+\f
+small_icon-ref-restorebackups.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+822f5e0ed76fb0bb47a8d2f90f375469
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3725
+\f
+black_arrow.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+03e716d26ee1913272983b9cfcc199f8
+2009-07-29T09:45:01.027130Z
+482
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2824
+\f
+button_with_icon_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d4ffa3fe7a2f3e2eba14b66936411a85
+2009-08-10T11:25:57.599617Z
+531
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3896
+\f
+small_icon-ref-settings.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+1140c565d18d21a1efd190bc1a2ec8dc
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4242
+\f
+memory_bar.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+35fa29ba1087512051d27bf08766942c
+2009-07-27T10:04:31.020564Z
+466
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3563
+\f
+ssh.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+40dfa113ff4dbf710d29e9c965f94e97
+2009-07-02T12:53:33.231762Z
+373
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3437
+\f
+battery_bar.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+23a300c76eb873d8b2f35a037151a0b7
+2009-07-27T10:04:31.020564Z
+466
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3659
+\f
+button_bg_clicked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+b4331208b1129b52d060a67e9f812335
+2009-08-05T16:55:19.618241Z
+511
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4360
+\f
+bt_next.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+0ea17926855c030924cd0375de12cbe6
+2009-08-11T18:11:13.211844Z
+540
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3705
+\f
+path_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+2e9149e73f319bd8c29b46e4f68bd29b
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3856
+\f
+backup_default_button.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+507a2a81d9894d081cd48286cabc08be
+2009-08-27T20:31:13.838494Z
+579
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3604
+\f
+back_arrow_off.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+e08a8e19f58dcc1ae9993676fa2d2273
+2009-07-29T12:18:32.451141Z
+490
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2954
+\f
+button_with_icon_bg_clicked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+1ca5a51cd91b76b1d00ed4f75e4ddbd5
+2009-08-10T11:25:57.599617Z
+531
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4141
+\f
+tabletSuite_logo.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+1a1166670a4205cfd08c1befc674c2bb
+2009-08-18T15:36:29.586124Z
+570
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7324
+\f
+copy_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+e92a79031af207d5615413f878bcaa27
+2009-08-13T17:08:11.546686Z
+550
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4924
+\f
+small_icon-ref-newbackup.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+cf9ba7641b827a058912d9379915ecad
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4003
+\f
+forward_arrow_off.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+3379a96302f63597c319c50a264933a8
+2009-07-29T12:18:32.451141Z
+490
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2950
+\f
+device_selection_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+63b1ba933149d0ffcb6e17edefa09c70
+2009-09-03T22:08:31.931352Z
+600
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5927
+\f
+backup_name_bg.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+abfde4ac92d9205f446eef12a951f024
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3909
+\f
+scroll_handle_h.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+25c1fa8f802f15ba9575b98a6f645346
+2009-09-09T16:10:10.046818Z
+610
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+446
+\f
+bt_next_clicked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+ff7a184854f8fc2301f35393d62102f5
+2009-08-11T18:11:13.211844Z
+540
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3836
+\f
+backup_default_button_clicked.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+df78c1f41a82b17a499c603b5fd4f381
+2009-08-27T20:31:13.838494Z
+579
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3732
+\f
+bg_manager.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+460acdb041c97f3b866c48bd01e6dcc4
+2009-09-03T21:14:33.964127Z
+596
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+62107
+\f
+device_memory.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+ead62093235e632745d327a6e05fb890
+2009-07-27T10:04:31.020564Z
+466
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3715
+\f
+path_border.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+e2bf32a0e2b5b49abd45777ddb597fd0
+2009-08-13T19:38:57.115054Z
+551
+pauloouriques
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3412
+\f
+small_icon-ref-managebackups.png
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+35938d68793a64ddc63691a22bbbb912
+2009-09-15T12:07:49.302204Z
+626
+amaury
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4022
+\f
diff --git a/img/.svn/format b/img/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/img/.svn/prop-base/N800.png.svn-base b/img/.svn/prop-base/N800.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/N800_backup.png.svn-base b/img/.svn/prop-base/N800_backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/N800_file.png.svn-base b/img/.svn/prop-base/N800_file.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/N810.png.svn-base b/img/.svn/prop-base/N810.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/N810_backup.png.svn-base b/img/.svn/prop-base/N810_backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/N810_file.png.svn-base b/img/.svn/prop-base/N810_file.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/arrow.png.svn-base b/img/.svn/prop-base/arrow.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/back_arrow_off.png.svn-base b/img/.svn/prop-base/back_arrow_off.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/back_arrow_on.png.svn-base b/img/.svn/prop-base/back_arrow_on.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/backup.png.svn-base b/img/.svn/prop-base/backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/backup_default_button.png.svn-base b/img/.svn/prop-base/backup_default_button.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/backup_default_button_clicked.png.svn-base b/img/.svn/prop-base/backup_default_button_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/backup_name_bg.png.svn-base b/img/.svn/prop-base/backup_name_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/backup_name_border.png.svn-base b/img/.svn/prop-base/backup_name_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/battery_bar.png.svn-base b/img/.svn/prop-base/battery_bar.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_backup.png.svn-base b/img/.svn/prop-base/bg_backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_backup0.png.svn-base b/img/.svn/prop-base/bg_backup0.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_geral0.png.svn-base b/img/.svn/prop-base/bg_geral0.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_geral2.png.svn-base b/img/.svn/prop-base/bg_geral2.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_manager.png.svn-base b/img/.svn/prop-base/bg_manager.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bg_restore.png.svn-base b/img/.svn/prop-base/bg_restore.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/black_arrow.png.svn-base b/img/.svn/prop-base/black_arrow.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/browse_button.png.svn-base b/img/.svn/prop-base/browse_button.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bt_next.png.svn-base b/img/.svn/prop-base/bt_next.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/bt_next_clicked.png.svn-base b/img/.svn/prop-base/bt_next_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/button_bg.png.svn-base b/img/.svn/prop-base/button_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/button_bg_clicked.png.svn-base b/img/.svn/prop-base/button_bg_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/button_with_icon_bg.png.svn-base b/img/.svn/prop-base/button_with_icon_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/button_with_icon_bg_clicked.png.svn-base b/img/.svn/prop-base/button_with_icon_bg_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/checkbox_border.png.svn-base b/img/.svn/prop-base/checkbox_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/checkbox_checked.png.svn-base b/img/.svn/prop-base/checkbox_checked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/checkbox_unchecked.png.svn-base b/img/.svn/prop-base/checkbox_unchecked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/copy_border.png.svn-base b/img/.svn/prop-base/copy_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/default_bg.png.svn-base b/img/.svn/prop-base/default_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_backup_border.png.svn-base b/img/.svn/prop-base/device_backup_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_checkbox_border.png.svn-base b/img/.svn/prop-base/device_checkbox_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_file_border.png.svn-base b/img/.svn/prop-base/device_file_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_memory.png.svn-base b/img/.svn/prop-base/device_memory.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_name_border_backup.png.svn-base b/img/.svn/prop-base/device_name_border_backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_name_border_checkbox.png.svn-base b/img/.svn/prop-base/device_name_border_checkbox.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_name_border_file.png.svn-base b/img/.svn/prop-base/device_name_border_file.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/device_selection_bg.png.svn-base b/img/.svn/prop-base/device_selection_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/disconnected.png.svn-base b/img/.svn/prop-base/disconnected.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/disconnected_backup.png.svn-base b/img/.svn/prop-base/disconnected_backup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/forward_arrow_off.png.svn-base b/img/.svn/prop-base/forward_arrow_off.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/forward_arrow_on.png.svn-base b/img/.svn/prop-base/forward_arrow_on.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/icon-alert-ref.png.svn-base b/img/.svn/prop-base/icon-alert-ref.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/icon-ref-managebackups.png.svn-base b/img/.svn/prop-base/icon-ref-managebackups.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/icon-ref-newbackup.png.svn-base b/img/.svn/prop-base/icon-ref-newbackup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/icon-ref-restorebackups.png.svn-base b/img/.svn/prop-base/icon-ref-restorebackups.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/icon-ref-settings.png.svn-base b/img/.svn/prop-base/icon-ref-settings.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/ip_list_border.png.svn-base b/img/.svn/prop-base/ip_list_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/large_arrow_border.png.svn-base b/img/.svn/prop-base/large_arrow_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/large_arrow_image.png.svn-base b/img/.svn/prop-base/large_arrow_image.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/lista.png.svn-base b/img/.svn/prop-base/lista.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/memory_bar.png.svn-base b/img/.svn/prop-base/memory_bar.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/path_bg.png.svn-base b/img/.svn/prop-base/path_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/path_border.png.svn-base b/img/.svn/prop-base/path_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/pc_file_border.png.svn-base b/img/.svn/prop-base/pc_file_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/pc_image.png.svn-base b/img/.svn/prop-base/pc_image.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/pc_name_border_file.png.svn-base b/img/.svn/prop-base/pc_name_border_file.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_bg.png.svn-base b/img/.svn/prop-base/progress_bar_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_border.png.svn-base b/img/.svn/prop-base/progress_bar_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_chunk.png.svn-base b/img/.svn/prop-base/progress_bar_chunk.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_chunk_dialog.png.svn-base b/img/.svn/prop-base/progress_bar_chunk_dialog.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_connecting_bg.png.svn-base b/img/.svn/prop-base/progress_bar_connecting_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/progress_bar_dialog_bg.png.svn-base b/img/.svn/prop-base/progress_bar_dialog_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/scroll_base_h.png.svn-base b/img/.svn/prop-base/scroll_base_h.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/scroll_base_v.png.svn-base b/img/.svn/prop-base/scroll_base_v.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/scroll_handle_h.png.svn-base b/img/.svn/prop-base/scroll_handle_h.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/scroll_handle_v.png.svn-base b/img/.svn/prop-base/scroll_handle_v.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_default_button.png.svn-base b/img/.svn/prop-base/small_default_button.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_default_button_clicked.png.svn-base b/img/.svn/prop-base/small_default_button_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_icon-ref-managebackups.png.svn-base b/img/.svn/prop-base/small_icon-ref-managebackups.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_icon-ref-newbackup.png.svn-base b/img/.svn/prop-base/small_icon-ref-newbackup.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_icon-ref-restorebackups.png.svn-base b/img/.svn/prop-base/small_icon-ref-restorebackups.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/small_icon-ref-settings.png.svn-base b/img/.svn/prop-base/small_icon-ref-settings.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/ssh.png.svn-base b/img/.svn/prop-base/ssh.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/tab_bg_1.png.svn-base b/img/.svn/prop-base/tab_bg_1.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/tab_bg_2.png.svn-base b/img/.svn/prop-base/tab_bg_2.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/tab_bg_3.png.svn-base b/img/.svn/prop-base/tab_bg_3.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/table_border.png.svn-base b/img/.svn/prop-base/table_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/tabletSuite_logo.png.svn-base b/img/.svn/prop-base/tabletSuite_logo.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/tabletsuite.desktop.svn-base b/img/.svn/prop-base/tabletsuite.desktop.svn-base
new file mode 100644 (file)
index 0000000..8d28d86
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/img/.svn/prop-base/view_bg.png.svn-base b/img/.svn/prop-base/view_bg.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/view_border.png.svn-base b/img/.svn/prop-base/view_border.png.svn-base
new file mode 100644 (file)
index 0000000..5e9587e
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/prop-base/white_arrow.png.svn-base b/img/.svn/prop-base/white_arrow.png.svn-base
new file mode 100644 (file)
index 0000000..dbc918b
--- /dev/null
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/img/.svn/text-base/N800.png.svn-base b/img/.svn/text-base/N800.png.svn-base
new file mode 100644 (file)
index 0000000..48df145
Binary files /dev/null and b/img/.svn/text-base/N800.png.svn-base differ
diff --git a/img/.svn/text-base/N800_backup.png.svn-base b/img/.svn/text-base/N800_backup.png.svn-base
new file mode 100644 (file)
index 0000000..43fbb85
Binary files /dev/null and b/img/.svn/text-base/N800_backup.png.svn-base differ
diff --git a/img/.svn/text-base/N800_file.png.svn-base b/img/.svn/text-base/N800_file.png.svn-base
new file mode 100644 (file)
index 0000000..edfa13b
Binary files /dev/null and b/img/.svn/text-base/N800_file.png.svn-base differ
diff --git a/img/.svn/text-base/N810.png.svn-base b/img/.svn/text-base/N810.png.svn-base
new file mode 100644 (file)
index 0000000..0a869b6
Binary files /dev/null and b/img/.svn/text-base/N810.png.svn-base differ
diff --git a/img/.svn/text-base/N810_backup.png.svn-base b/img/.svn/text-base/N810_backup.png.svn-base
new file mode 100644 (file)
index 0000000..02c60e8
Binary files /dev/null and b/img/.svn/text-base/N810_backup.png.svn-base differ
diff --git a/img/.svn/text-base/N810_file.png.svn-base b/img/.svn/text-base/N810_file.png.svn-base
new file mode 100644 (file)
index 0000000..fb7d138
Binary files /dev/null and b/img/.svn/text-base/N810_file.png.svn-base differ
diff --git a/img/.svn/text-base/arrow.png.svn-base b/img/.svn/text-base/arrow.png.svn-base
new file mode 100644 (file)
index 0000000..4dbf148
Binary files /dev/null and b/img/.svn/text-base/arrow.png.svn-base differ
diff --git a/img/.svn/text-base/back_arrow_off.png.svn-base b/img/.svn/text-base/back_arrow_off.png.svn-base
new file mode 100644 (file)
index 0000000..48c68a8
Binary files /dev/null and b/img/.svn/text-base/back_arrow_off.png.svn-base differ
diff --git a/img/.svn/text-base/back_arrow_on.png.svn-base b/img/.svn/text-base/back_arrow_on.png.svn-base
new file mode 100644 (file)
index 0000000..99d8986
Binary files /dev/null and b/img/.svn/text-base/back_arrow_on.png.svn-base differ
diff --git a/img/.svn/text-base/backup.png.svn-base b/img/.svn/text-base/backup.png.svn-base
new file mode 100644 (file)
index 0000000..b5dc1fd
Binary files /dev/null and b/img/.svn/text-base/backup.png.svn-base differ
diff --git a/img/.svn/text-base/backup_default_button.png.svn-base b/img/.svn/text-base/backup_default_button.png.svn-base
new file mode 100644 (file)
index 0000000..eded036
Binary files /dev/null and b/img/.svn/text-base/backup_default_button.png.svn-base differ
diff --git a/img/.svn/text-base/backup_default_button_clicked.png.svn-base b/img/.svn/text-base/backup_default_button_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..45b0e71
Binary files /dev/null and b/img/.svn/text-base/backup_default_button_clicked.png.svn-base differ
diff --git a/img/.svn/text-base/backup_name_bg.png.svn-base b/img/.svn/text-base/backup_name_bg.png.svn-base
new file mode 100644 (file)
index 0000000..6ec151a
Binary files /dev/null and b/img/.svn/text-base/backup_name_bg.png.svn-base differ
diff --git a/img/.svn/text-base/backup_name_border.png.svn-base b/img/.svn/text-base/backup_name_border.png.svn-base
new file mode 100644 (file)
index 0000000..76baec9
Binary files /dev/null and b/img/.svn/text-base/backup_name_border.png.svn-base differ
diff --git a/img/.svn/text-base/battery_bar.png.svn-base b/img/.svn/text-base/battery_bar.png.svn-base
new file mode 100644 (file)
index 0000000..b2b632f
Binary files /dev/null and b/img/.svn/text-base/battery_bar.png.svn-base differ
diff --git a/img/.svn/text-base/bg_backup.png.svn-base b/img/.svn/text-base/bg_backup.png.svn-base
new file mode 100644 (file)
index 0000000..701d70d
Binary files /dev/null and b/img/.svn/text-base/bg_backup.png.svn-base differ
diff --git a/img/.svn/text-base/bg_backup0.png.svn-base b/img/.svn/text-base/bg_backup0.png.svn-base
new file mode 100644 (file)
index 0000000..da7b3c0
Binary files /dev/null and b/img/.svn/text-base/bg_backup0.png.svn-base differ
diff --git a/img/.svn/text-base/bg_geral0.png.svn-base b/img/.svn/text-base/bg_geral0.png.svn-base
new file mode 100644 (file)
index 0000000..506b9a7
Binary files /dev/null and b/img/.svn/text-base/bg_geral0.png.svn-base differ
diff --git a/img/.svn/text-base/bg_geral2.png.svn-base b/img/.svn/text-base/bg_geral2.png.svn-base
new file mode 100644 (file)
index 0000000..6a49225
Binary files /dev/null and b/img/.svn/text-base/bg_geral2.png.svn-base differ
diff --git a/img/.svn/text-base/bg_manager.png.svn-base b/img/.svn/text-base/bg_manager.png.svn-base
new file mode 100644 (file)
index 0000000..11c0671
Binary files /dev/null and b/img/.svn/text-base/bg_manager.png.svn-base differ
diff --git a/img/.svn/text-base/bg_restore.png.svn-base b/img/.svn/text-base/bg_restore.png.svn-base
new file mode 100644 (file)
index 0000000..11c0671
Binary files /dev/null and b/img/.svn/text-base/bg_restore.png.svn-base differ
diff --git a/img/.svn/text-base/black_arrow.png.svn-base b/img/.svn/text-base/black_arrow.png.svn-base
new file mode 100644 (file)
index 0000000..536644d
Binary files /dev/null and b/img/.svn/text-base/black_arrow.png.svn-base differ
diff --git a/img/.svn/text-base/browse_button.png.svn-base b/img/.svn/text-base/browse_button.png.svn-base
new file mode 100644 (file)
index 0000000..990e6d4
Binary files /dev/null and b/img/.svn/text-base/browse_button.png.svn-base differ
diff --git a/img/.svn/text-base/bt_next.png.svn-base b/img/.svn/text-base/bt_next.png.svn-base
new file mode 100644 (file)
index 0000000..48297fe
Binary files /dev/null and b/img/.svn/text-base/bt_next.png.svn-base differ
diff --git a/img/.svn/text-base/bt_next_clicked.png.svn-base b/img/.svn/text-base/bt_next_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..8a747c8
Binary files /dev/null and b/img/.svn/text-base/bt_next_clicked.png.svn-base differ
diff --git a/img/.svn/text-base/button_bg.png.svn-base b/img/.svn/text-base/button_bg.png.svn-base
new file mode 100644 (file)
index 0000000..fe8f537
Binary files /dev/null and b/img/.svn/text-base/button_bg.png.svn-base differ
diff --git a/img/.svn/text-base/button_bg_clicked.png.svn-base b/img/.svn/text-base/button_bg_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..97fbdb3
Binary files /dev/null and b/img/.svn/text-base/button_bg_clicked.png.svn-base differ
diff --git a/img/.svn/text-base/button_with_icon_bg.png.svn-base b/img/.svn/text-base/button_with_icon_bg.png.svn-base
new file mode 100644 (file)
index 0000000..cf6fc2c
Binary files /dev/null and b/img/.svn/text-base/button_with_icon_bg.png.svn-base differ
diff --git a/img/.svn/text-base/button_with_icon_bg_clicked.png.svn-base b/img/.svn/text-base/button_with_icon_bg_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..8ceb603
Binary files /dev/null and b/img/.svn/text-base/button_with_icon_bg_clicked.png.svn-base differ
diff --git a/img/.svn/text-base/checkbox_border.png.svn-base b/img/.svn/text-base/checkbox_border.png.svn-base
new file mode 100644 (file)
index 0000000..ae4ae02
Binary files /dev/null and b/img/.svn/text-base/checkbox_border.png.svn-base differ
diff --git a/img/.svn/text-base/checkbox_checked.png.svn-base b/img/.svn/text-base/checkbox_checked.png.svn-base
new file mode 100644 (file)
index 0000000..6774a97
Binary files /dev/null and b/img/.svn/text-base/checkbox_checked.png.svn-base differ
diff --git a/img/.svn/text-base/checkbox_unchecked.png.svn-base b/img/.svn/text-base/checkbox_unchecked.png.svn-base
new file mode 100644 (file)
index 0000000..10576e9
Binary files /dev/null and b/img/.svn/text-base/checkbox_unchecked.png.svn-base differ
diff --git a/img/.svn/text-base/copy_border.png.svn-base b/img/.svn/text-base/copy_border.png.svn-base
new file mode 100644 (file)
index 0000000..d5e140c
Binary files /dev/null and b/img/.svn/text-base/copy_border.png.svn-base differ
diff --git a/img/.svn/text-base/default_bg.png.svn-base b/img/.svn/text-base/default_bg.png.svn-base
new file mode 100644 (file)
index 0000000..b96ca03
Binary files /dev/null and b/img/.svn/text-base/default_bg.png.svn-base differ
diff --git a/img/.svn/text-base/device_backup_border.png.svn-base b/img/.svn/text-base/device_backup_border.png.svn-base
new file mode 100644 (file)
index 0000000..44b2c65
Binary files /dev/null and b/img/.svn/text-base/device_backup_border.png.svn-base differ
diff --git a/img/.svn/text-base/device_checkbox_border.png.svn-base b/img/.svn/text-base/device_checkbox_border.png.svn-base
new file mode 100644 (file)
index 0000000..e6793cc
Binary files /dev/null and b/img/.svn/text-base/device_checkbox_border.png.svn-base differ
diff --git a/img/.svn/text-base/device_file_border.png.svn-base b/img/.svn/text-base/device_file_border.png.svn-base
new file mode 100644 (file)
index 0000000..3043002
Binary files /dev/null and b/img/.svn/text-base/device_file_border.png.svn-base differ
diff --git a/img/.svn/text-base/device_memory.png.svn-base b/img/.svn/text-base/device_memory.png.svn-base
new file mode 100644 (file)
index 0000000..8164cbd
Binary files /dev/null and b/img/.svn/text-base/device_memory.png.svn-base differ
diff --git a/img/.svn/text-base/device_name_border_backup.png.svn-base b/img/.svn/text-base/device_name_border_backup.png.svn-base
new file mode 100644 (file)
index 0000000..9e233d4
Binary files /dev/null and b/img/.svn/text-base/device_name_border_backup.png.svn-base differ
diff --git a/img/.svn/text-base/device_name_border_checkbox.png.svn-base b/img/.svn/text-base/device_name_border_checkbox.png.svn-base
new file mode 100644 (file)
index 0000000..5dbf5f9
Binary files /dev/null and b/img/.svn/text-base/device_name_border_checkbox.png.svn-base differ
diff --git a/img/.svn/text-base/device_name_border_file.png.svn-base b/img/.svn/text-base/device_name_border_file.png.svn-base
new file mode 100644 (file)
index 0000000..3f0ee83
Binary files /dev/null and b/img/.svn/text-base/device_name_border_file.png.svn-base differ
diff --git a/img/.svn/text-base/device_selection_bg.png.svn-base b/img/.svn/text-base/device_selection_bg.png.svn-base
new file mode 100644 (file)
index 0000000..e6d525f
Binary files /dev/null and b/img/.svn/text-base/device_selection_bg.png.svn-base differ
diff --git a/img/.svn/text-base/disconnected.png.svn-base b/img/.svn/text-base/disconnected.png.svn-base
new file mode 100644 (file)
index 0000000..ed10736
Binary files /dev/null and b/img/.svn/text-base/disconnected.png.svn-base differ
diff --git a/img/.svn/text-base/disconnected_backup.png.svn-base b/img/.svn/text-base/disconnected_backup.png.svn-base
new file mode 100644 (file)
index 0000000..edab272
Binary files /dev/null and b/img/.svn/text-base/disconnected_backup.png.svn-base differ
diff --git a/img/.svn/text-base/forward_arrow_off.png.svn-base b/img/.svn/text-base/forward_arrow_off.png.svn-base
new file mode 100644 (file)
index 0000000..4cb19bf
Binary files /dev/null and b/img/.svn/text-base/forward_arrow_off.png.svn-base differ
diff --git a/img/.svn/text-base/forward_arrow_on.png.svn-base b/img/.svn/text-base/forward_arrow_on.png.svn-base
new file mode 100644 (file)
index 0000000..48c5e9e
Binary files /dev/null and b/img/.svn/text-base/forward_arrow_on.png.svn-base differ
diff --git a/img/.svn/text-base/icon-alert-ref.png.svn-base b/img/.svn/text-base/icon-alert-ref.png.svn-base
new file mode 100644 (file)
index 0000000..c6494d9
Binary files /dev/null and b/img/.svn/text-base/icon-alert-ref.png.svn-base differ
diff --git a/img/.svn/text-base/icon-ref-managebackups.png.svn-base b/img/.svn/text-base/icon-ref-managebackups.png.svn-base
new file mode 100644 (file)
index 0000000..e610e38
Binary files /dev/null and b/img/.svn/text-base/icon-ref-managebackups.png.svn-base differ
diff --git a/img/.svn/text-base/icon-ref-newbackup.png.svn-base b/img/.svn/text-base/icon-ref-newbackup.png.svn-base
new file mode 100644 (file)
index 0000000..fae0e89
Binary files /dev/null and b/img/.svn/text-base/icon-ref-newbackup.png.svn-base differ
diff --git a/img/.svn/text-base/icon-ref-restorebackups.png.svn-base b/img/.svn/text-base/icon-ref-restorebackups.png.svn-base
new file mode 100644 (file)
index 0000000..2ff5139
Binary files /dev/null and b/img/.svn/text-base/icon-ref-restorebackups.png.svn-base differ
diff --git a/img/.svn/text-base/icon-ref-settings.png.svn-base b/img/.svn/text-base/icon-ref-settings.png.svn-base
new file mode 100644 (file)
index 0000000..2227abf
Binary files /dev/null and b/img/.svn/text-base/icon-ref-settings.png.svn-base differ
diff --git a/img/.svn/text-base/ip_list_border.png.svn-base b/img/.svn/text-base/ip_list_border.png.svn-base
new file mode 100644 (file)
index 0000000..9a099fc
Binary files /dev/null and b/img/.svn/text-base/ip_list_border.png.svn-base differ
diff --git a/img/.svn/text-base/large_arrow_border.png.svn-base b/img/.svn/text-base/large_arrow_border.png.svn-base
new file mode 100644 (file)
index 0000000..f6b955f
Binary files /dev/null and b/img/.svn/text-base/large_arrow_border.png.svn-base differ
diff --git a/img/.svn/text-base/large_arrow_image.png.svn-base b/img/.svn/text-base/large_arrow_image.png.svn-base
new file mode 100644 (file)
index 0000000..7e2db57
Binary files /dev/null and b/img/.svn/text-base/large_arrow_image.png.svn-base differ
diff --git a/img/.svn/text-base/lista.png.svn-base b/img/.svn/text-base/lista.png.svn-base
new file mode 100644 (file)
index 0000000..376f33e
Binary files /dev/null and b/img/.svn/text-base/lista.png.svn-base differ
diff --git a/img/.svn/text-base/memory_bar.png.svn-base b/img/.svn/text-base/memory_bar.png.svn-base
new file mode 100644 (file)
index 0000000..c0d0305
Binary files /dev/null and b/img/.svn/text-base/memory_bar.png.svn-base differ
diff --git a/img/.svn/text-base/path_bg.png.svn-base b/img/.svn/text-base/path_bg.png.svn-base
new file mode 100644 (file)
index 0000000..ac7d1af
Binary files /dev/null and b/img/.svn/text-base/path_bg.png.svn-base differ
diff --git a/img/.svn/text-base/path_border.png.svn-base b/img/.svn/text-base/path_border.png.svn-base
new file mode 100644 (file)
index 0000000..b978d66
Binary files /dev/null and b/img/.svn/text-base/path_border.png.svn-base differ
diff --git a/img/.svn/text-base/pc_file_border.png.svn-base b/img/.svn/text-base/pc_file_border.png.svn-base
new file mode 100644 (file)
index 0000000..5d87a65
Binary files /dev/null and b/img/.svn/text-base/pc_file_border.png.svn-base differ
diff --git a/img/.svn/text-base/pc_image.png.svn-base b/img/.svn/text-base/pc_image.png.svn-base
new file mode 100644 (file)
index 0000000..09693c6
Binary files /dev/null and b/img/.svn/text-base/pc_image.png.svn-base differ
diff --git a/img/.svn/text-base/pc_name_border_file.png.svn-base b/img/.svn/text-base/pc_name_border_file.png.svn-base
new file mode 100644 (file)
index 0000000..a37d5b2
Binary files /dev/null and b/img/.svn/text-base/pc_name_border_file.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_bg.png.svn-base b/img/.svn/text-base/progress_bar_bg.png.svn-base
new file mode 100644 (file)
index 0000000..6193ec7
Binary files /dev/null and b/img/.svn/text-base/progress_bar_bg.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_border.png.svn-base b/img/.svn/text-base/progress_bar_border.png.svn-base
new file mode 100644 (file)
index 0000000..252ead2
Binary files /dev/null and b/img/.svn/text-base/progress_bar_border.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_chunk.png.svn-base b/img/.svn/text-base/progress_bar_chunk.png.svn-base
new file mode 100644 (file)
index 0000000..b8c8b60
Binary files /dev/null and b/img/.svn/text-base/progress_bar_chunk.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_chunk_dialog.png.svn-base b/img/.svn/text-base/progress_bar_chunk_dialog.png.svn-base
new file mode 100644 (file)
index 0000000..bde0ce5
Binary files /dev/null and b/img/.svn/text-base/progress_bar_chunk_dialog.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_connecting_bg.png.svn-base b/img/.svn/text-base/progress_bar_connecting_bg.png.svn-base
new file mode 100644 (file)
index 0000000..942f14b
Binary files /dev/null and b/img/.svn/text-base/progress_bar_connecting_bg.png.svn-base differ
diff --git a/img/.svn/text-base/progress_bar_dialog_bg.png.svn-base b/img/.svn/text-base/progress_bar_dialog_bg.png.svn-base
new file mode 100644 (file)
index 0000000..0123b36
Binary files /dev/null and b/img/.svn/text-base/progress_bar_dialog_bg.png.svn-base differ
diff --git a/img/.svn/text-base/scroll_base_h.png.svn-base b/img/.svn/text-base/scroll_base_h.png.svn-base
new file mode 100644 (file)
index 0000000..e1a9c7c
Binary files /dev/null and b/img/.svn/text-base/scroll_base_h.png.svn-base differ
diff --git a/img/.svn/text-base/scroll_base_v.png.svn-base b/img/.svn/text-base/scroll_base_v.png.svn-base
new file mode 100644 (file)
index 0000000..d6066c8
Binary files /dev/null and b/img/.svn/text-base/scroll_base_v.png.svn-base differ
diff --git a/img/.svn/text-base/scroll_handle_h.png.svn-base b/img/.svn/text-base/scroll_handle_h.png.svn-base
new file mode 100644 (file)
index 0000000..ed561e4
Binary files /dev/null and b/img/.svn/text-base/scroll_handle_h.png.svn-base differ
diff --git a/img/.svn/text-base/scroll_handle_v.png.svn-base b/img/.svn/text-base/scroll_handle_v.png.svn-base
new file mode 100644 (file)
index 0000000..3a2ad73
Binary files /dev/null and b/img/.svn/text-base/scroll_handle_v.png.svn-base differ
diff --git a/img/.svn/text-base/small_default_button.png.svn-base b/img/.svn/text-base/small_default_button.png.svn-base
new file mode 100644 (file)
index 0000000..8d4017c
Binary files /dev/null and b/img/.svn/text-base/small_default_button.png.svn-base differ
diff --git a/img/.svn/text-base/small_default_button_clicked.png.svn-base b/img/.svn/text-base/small_default_button_clicked.png.svn-base
new file mode 100644 (file)
index 0000000..a304368
Binary files /dev/null and b/img/.svn/text-base/small_default_button_clicked.png.svn-base differ
diff --git a/img/.svn/text-base/small_icon-ref-managebackups.png.svn-base b/img/.svn/text-base/small_icon-ref-managebackups.png.svn-base
new file mode 100644 (file)
index 0000000..f9ffe78
Binary files /dev/null and b/img/.svn/text-base/small_icon-ref-managebackups.png.svn-base differ
diff --git a/img/.svn/text-base/small_icon-ref-newbackup.png.svn-base b/img/.svn/text-base/small_icon-ref-newbackup.png.svn-base
new file mode 100644 (file)
index 0000000..97d8166
Binary files /dev/null and b/img/.svn/text-base/small_icon-ref-newbackup.png.svn-base differ
diff --git a/img/.svn/text-base/small_icon-ref-restorebackups.png.svn-base b/img/.svn/text-base/small_icon-ref-restorebackups.png.svn-base
new file mode 100644 (file)
index 0000000..23e2534
Binary files /dev/null and b/img/.svn/text-base/small_icon-ref-restorebackups.png.svn-base differ
diff --git a/img/.svn/text-base/small_icon-ref-settings.png.svn-base b/img/.svn/text-base/small_icon-ref-settings.png.svn-base
new file mode 100644 (file)
index 0000000..abc454c
Binary files /dev/null and b/img/.svn/text-base/small_icon-ref-settings.png.svn-base differ
diff --git a/img/.svn/text-base/ssh.png.svn-base b/img/.svn/text-base/ssh.png.svn-base
new file mode 100644 (file)
index 0000000..d4ce558
Binary files /dev/null and b/img/.svn/text-base/ssh.png.svn-base differ
diff --git a/img/.svn/text-base/tab_bg_1.png.svn-base b/img/.svn/text-base/tab_bg_1.png.svn-base
new file mode 100644 (file)
index 0000000..f5de942
Binary files /dev/null and b/img/.svn/text-base/tab_bg_1.png.svn-base differ
diff --git a/img/.svn/text-base/tab_bg_2.png.svn-base b/img/.svn/text-base/tab_bg_2.png.svn-base
new file mode 100644 (file)
index 0000000..0c376ea
Binary files /dev/null and b/img/.svn/text-base/tab_bg_2.png.svn-base differ
diff --git a/img/.svn/text-base/tab_bg_3.png.svn-base b/img/.svn/text-base/tab_bg_3.png.svn-base
new file mode 100644 (file)
index 0000000..2188df2
Binary files /dev/null and b/img/.svn/text-base/tab_bg_3.png.svn-base differ
diff --git a/img/.svn/text-base/table_border.png.svn-base b/img/.svn/text-base/table_border.png.svn-base
new file mode 100644 (file)
index 0000000..a4bae53
Binary files /dev/null and b/img/.svn/text-base/table_border.png.svn-base differ
diff --git a/img/.svn/text-base/tabletSuite_logo.png.svn-base b/img/.svn/text-base/tabletSuite_logo.png.svn-base
new file mode 100644 (file)
index 0000000..57b8571
Binary files /dev/null and b/img/.svn/text-base/tabletSuite_logo.png.svn-base differ
diff --git a/img/.svn/text-base/tabletsuite.desktop.svn-base b/img/.svn/text-base/tabletsuite.desktop.svn-base
new file mode 100644 (file)
index 0000000..1262354
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env xdg-open
+[Desktop Entry]
+Name=TabletSuite
+Comment=TabletSuite Application
+Version=0.0.1
+Exec=tabletsuite
+Icon=/usr/share/tabletsuite/tabletSuite_logo.png
+Type=Application
+Terminal=false
+Categories=Application;
+StartupNotify=false
+Name[en_US]=tabletsuite
diff --git a/img/.svn/text-base/view_bg.png.svn-base b/img/.svn/text-base/view_bg.png.svn-base
new file mode 100644 (file)
index 0000000..4a9743d
Binary files /dev/null and b/img/.svn/text-base/view_bg.png.svn-base differ
diff --git a/img/.svn/text-base/view_border.png.svn-base b/img/.svn/text-base/view_border.png.svn-base
new file mode 100644 (file)
index 0000000..b289586
Binary files /dev/null and b/img/.svn/text-base/view_border.png.svn-base differ
diff --git a/img/.svn/text-base/white_arrow.png.svn-base b/img/.svn/text-base/white_arrow.png.svn-base
new file mode 100644 (file)
index 0000000..4dbf148
Binary files /dev/null and b/img/.svn/text-base/white_arrow.png.svn-base differ
diff --git a/img/N800.png b/img/N800.png
new file mode 100644 (file)
index 0000000..48df145
Binary files /dev/null and b/img/N800.png differ
diff --git a/img/N800_backup.png b/img/N800_backup.png
new file mode 100644 (file)
index 0000000..43fbb85
Binary files /dev/null and b/img/N800_backup.png differ
diff --git a/img/N800_file.png b/img/N800_file.png
new file mode 100644 (file)
index 0000000..edfa13b
Binary files /dev/null and b/img/N800_file.png differ
diff --git a/img/N810.png b/img/N810.png
new file mode 100644 (file)
index 0000000..0a869b6
Binary files /dev/null and b/img/N810.png differ
diff --git a/img/N810_backup.png b/img/N810_backup.png
new file mode 100644 (file)
index 0000000..02c60e8
Binary files /dev/null and b/img/N810_backup.png differ
diff --git a/img/N810_file.png b/img/N810_file.png
new file mode 100644 (file)
index 0000000..fb7d138
Binary files /dev/null and b/img/N810_file.png differ
diff --git a/img/arrow.png b/img/arrow.png
new file mode 100755 (executable)
index 0000000..4dbf148
Binary files /dev/null and b/img/arrow.png differ
diff --git a/img/back_arrow_off.png b/img/back_arrow_off.png
new file mode 100755 (executable)
index 0000000..48c68a8
Binary files /dev/null and b/img/back_arrow_off.png differ
diff --git a/img/back_arrow_on.png b/img/back_arrow_on.png
new file mode 100755 (executable)
index 0000000..99d8986
Binary files /dev/null and b/img/back_arrow_on.png differ
diff --git a/img/backup.png b/img/backup.png
new file mode 100644 (file)
index 0000000..b5dc1fd
Binary files /dev/null and b/img/backup.png differ
diff --git a/img/backup_default_button.png b/img/backup_default_button.png
new file mode 100644 (file)
index 0000000..eded036
Binary files /dev/null and b/img/backup_default_button.png differ
diff --git a/img/backup_default_button_clicked.png b/img/backup_default_button_clicked.png
new file mode 100644 (file)
index 0000000..45b0e71
Binary files /dev/null and b/img/backup_default_button_clicked.png differ
diff --git a/img/backup_name_bg.png b/img/backup_name_bg.png
new file mode 100644 (file)
index 0000000..6ec151a
Binary files /dev/null and b/img/backup_name_bg.png differ
diff --git a/img/backup_name_border.png b/img/backup_name_border.png
new file mode 100644 (file)
index 0000000..76baec9
Binary files /dev/null and b/img/backup_name_border.png differ
diff --git a/img/battery_bar.png b/img/battery_bar.png
new file mode 100644 (file)
index 0000000..b2b632f
Binary files /dev/null and b/img/battery_bar.png differ
diff --git a/img/bg_backup.png b/img/bg_backup.png
new file mode 100644 (file)
index 0000000..701d70d
Binary files /dev/null and b/img/bg_backup.png differ
diff --git a/img/bg_backup0.png b/img/bg_backup0.png
new file mode 100644 (file)
index 0000000..da7b3c0
Binary files /dev/null and b/img/bg_backup0.png differ
diff --git a/img/bg_geral0.png b/img/bg_geral0.png
new file mode 100644 (file)
index 0000000..506b9a7
Binary files /dev/null and b/img/bg_geral0.png differ
diff --git a/img/bg_geral2.png b/img/bg_geral2.png
new file mode 100644 (file)
index 0000000..6a49225
Binary files /dev/null and b/img/bg_geral2.png differ
diff --git a/img/bg_manager.png b/img/bg_manager.png
new file mode 100644 (file)
index 0000000..11c0671
Binary files /dev/null and b/img/bg_manager.png differ
diff --git a/img/bg_restore.png b/img/bg_restore.png
new file mode 100644 (file)
index 0000000..11c0671
Binary files /dev/null and b/img/bg_restore.png differ
diff --git a/img/black_arrow.png b/img/black_arrow.png
new file mode 100644 (file)
index 0000000..536644d
Binary files /dev/null and b/img/black_arrow.png differ
diff --git a/img/browse_button.png b/img/browse_button.png
new file mode 100644 (file)
index 0000000..990e6d4
Binary files /dev/null and b/img/browse_button.png differ
diff --git a/img/bt_next.png b/img/bt_next.png
new file mode 100644 (file)
index 0000000..48297fe
Binary files /dev/null and b/img/bt_next.png differ
diff --git a/img/bt_next_clicked.png b/img/bt_next_clicked.png
new file mode 100644 (file)
index 0000000..8a747c8
Binary files /dev/null and b/img/bt_next_clicked.png differ
diff --git a/img/button_bg.png b/img/button_bg.png
new file mode 100644 (file)
index 0000000..fe8f537
Binary files /dev/null and b/img/button_bg.png differ
diff --git a/img/button_bg_clicked.png b/img/button_bg_clicked.png
new file mode 100644 (file)
index 0000000..97fbdb3
Binary files /dev/null and b/img/button_bg_clicked.png differ
diff --git a/img/button_with_icon_bg.png b/img/button_with_icon_bg.png
new file mode 100644 (file)
index 0000000..cf6fc2c
Binary files /dev/null and b/img/button_with_icon_bg.png differ
diff --git a/img/button_with_icon_bg_clicked.png b/img/button_with_icon_bg_clicked.png
new file mode 100644 (file)
index 0000000..8ceb603
Binary files /dev/null and b/img/button_with_icon_bg_clicked.png differ
diff --git a/img/checkbox_border.png b/img/checkbox_border.png
new file mode 100644 (file)
index 0000000..ae4ae02
Binary files /dev/null and b/img/checkbox_border.png differ
diff --git a/img/checkbox_checked.png b/img/checkbox_checked.png
new file mode 100644 (file)
index 0000000..6774a97
Binary files /dev/null and b/img/checkbox_checked.png differ
diff --git a/img/checkbox_unchecked.png b/img/checkbox_unchecked.png
new file mode 100644 (file)
index 0000000..10576e9
Binary files /dev/null and b/img/checkbox_unchecked.png differ
diff --git a/img/copy_border.png b/img/copy_border.png
new file mode 100644 (file)
index 0000000..d5e140c
Binary files /dev/null and b/img/copy_border.png differ
diff --git a/img/default_bg.png b/img/default_bg.png
new file mode 100644 (file)
index 0000000..b96ca03
Binary files /dev/null and b/img/default_bg.png differ
diff --git a/img/device_backup_border.png b/img/device_backup_border.png
new file mode 100644 (file)
index 0000000..44b2c65
Binary files /dev/null and b/img/device_backup_border.png differ
diff --git a/img/device_checkbox_border.png b/img/device_checkbox_border.png
new file mode 100644 (file)
index 0000000..e6793cc
Binary files /dev/null and b/img/device_checkbox_border.png differ
diff --git a/img/device_file_border.png b/img/device_file_border.png
new file mode 100644 (file)
index 0000000..3043002
Binary files /dev/null and b/img/device_file_border.png differ
diff --git a/img/device_memory.png b/img/device_memory.png
new file mode 100644 (file)
index 0000000..8164cbd
Binary files /dev/null and b/img/device_memory.png differ
diff --git a/img/device_name_border_backup.png b/img/device_name_border_backup.png
new file mode 100644 (file)
index 0000000..9e233d4
Binary files /dev/null and b/img/device_name_border_backup.png differ
diff --git a/img/device_name_border_checkbox.png b/img/device_name_border_checkbox.png
new file mode 100644 (file)
index 0000000..5dbf5f9
Binary files /dev/null and b/img/device_name_border_checkbox.png differ
diff --git a/img/device_name_border_file.png b/img/device_name_border_file.png
new file mode 100644 (file)
index 0000000..3f0ee83
Binary files /dev/null and b/img/device_name_border_file.png differ
diff --git a/img/device_selection_bg.png b/img/device_selection_bg.png
new file mode 100644 (file)
index 0000000..e6d525f
Binary files /dev/null and b/img/device_selection_bg.png differ
diff --git a/img/disconnected.png b/img/disconnected.png
new file mode 100644 (file)
index 0000000..ed10736
Binary files /dev/null and b/img/disconnected.png differ
diff --git a/img/disconnected_backup.png b/img/disconnected_backup.png
new file mode 100644 (file)
index 0000000..edab272
Binary files /dev/null and b/img/disconnected_backup.png differ
diff --git a/img/forward_arrow_off.png b/img/forward_arrow_off.png
new file mode 100755 (executable)
index 0000000..4cb19bf
Binary files /dev/null and b/img/forward_arrow_off.png differ
diff --git a/img/forward_arrow_on.png b/img/forward_arrow_on.png
new file mode 100755 (executable)
index 0000000..48c5e9e
Binary files /dev/null and b/img/forward_arrow_on.png differ
diff --git a/img/icon-alert-ref.png b/img/icon-alert-ref.png
new file mode 100644 (file)
index 0000000..c6494d9
Binary files /dev/null and b/img/icon-alert-ref.png differ
diff --git a/img/icon-ref-managebackups.png b/img/icon-ref-managebackups.png
new file mode 100644 (file)
index 0000000..e610e38
Binary files /dev/null and b/img/icon-ref-managebackups.png differ
diff --git a/img/icon-ref-newbackup.png b/img/icon-ref-newbackup.png
new file mode 100644 (file)
index 0000000..fae0e89
Binary files /dev/null and b/img/icon-ref-newbackup.png differ
diff --git a/img/icon-ref-restorebackups.png b/img/icon-ref-restorebackups.png
new file mode 100644 (file)
index 0000000..2ff5139
Binary files /dev/null and b/img/icon-ref-restorebackups.png differ
diff --git a/img/icon-ref-settings.png b/img/icon-ref-settings.png
new file mode 100644 (file)
index 0000000..2227abf
Binary files /dev/null and b/img/icon-ref-settings.png differ
diff --git a/img/ip_list_border.png b/img/ip_list_border.png
new file mode 100644 (file)
index 0000000..9a099fc
Binary files /dev/null and b/img/ip_list_border.png differ
diff --git a/img/large_arrow_border.png b/img/large_arrow_border.png
new file mode 100644 (file)
index 0000000..f6b955f
Binary files /dev/null and b/img/large_arrow_border.png differ
diff --git a/img/large_arrow_image.png b/img/large_arrow_image.png
new file mode 100644 (file)
index 0000000..7e2db57
Binary files /dev/null and b/img/large_arrow_image.png differ
diff --git a/img/lista.png b/img/lista.png
new file mode 100644 (file)
index 0000000..376f33e
Binary files /dev/null and b/img/lista.png differ
diff --git a/img/memory_bar.png b/img/memory_bar.png
new file mode 100644 (file)
index 0000000..c0d0305
Binary files /dev/null and b/img/memory_bar.png differ
diff --git a/img/path_bg.png b/img/path_bg.png
new file mode 100644 (file)
index 0000000..ac7d1af
Binary files /dev/null and b/img/path_bg.png differ
diff --git a/img/path_border.png b/img/path_border.png
new file mode 100644 (file)
index 0000000..b978d66
Binary files /dev/null and b/img/path_border.png differ
diff --git a/img/pc_file_border.png b/img/pc_file_border.png
new file mode 100644 (file)
index 0000000..5d87a65
Binary files /dev/null and b/img/pc_file_border.png differ
diff --git a/img/pc_image.png b/img/pc_image.png
new file mode 100644 (file)
index 0000000..09693c6
Binary files /dev/null and b/img/pc_image.png differ
diff --git a/img/pc_name_border_file.png b/img/pc_name_border_file.png
new file mode 100644 (file)
index 0000000..a37d5b2
Binary files /dev/null and b/img/pc_name_border_file.png differ
diff --git a/img/progress_bar_bg.png b/img/progress_bar_bg.png
new file mode 100644 (file)
index 0000000..6193ec7
Binary files /dev/null and b/img/progress_bar_bg.png differ
diff --git a/img/progress_bar_border.png b/img/progress_bar_border.png
new file mode 100644 (file)
index 0000000..252ead2
Binary files /dev/null and b/img/progress_bar_border.png differ
diff --git a/img/progress_bar_chunk.png b/img/progress_bar_chunk.png
new file mode 100644 (file)
index 0000000..b8c8b60
Binary files /dev/null and b/img/progress_bar_chunk.png differ
diff --git a/img/progress_bar_chunk_dialog.png b/img/progress_bar_chunk_dialog.png
new file mode 100644 (file)
index 0000000..bde0ce5
Binary files /dev/null and b/img/progress_bar_chunk_dialog.png differ
diff --git a/img/progress_bar_connecting_bg.png b/img/progress_bar_connecting_bg.png
new file mode 100644 (file)
index 0000000..942f14b
Binary files /dev/null and b/img/progress_bar_connecting_bg.png differ
diff --git a/img/progress_bar_dialog_bg.png b/img/progress_bar_dialog_bg.png
new file mode 100644 (file)
index 0000000..0123b36
Binary files /dev/null and b/img/progress_bar_dialog_bg.png differ
diff --git a/img/scroll_base_h.png b/img/scroll_base_h.png
new file mode 100644 (file)
index 0000000..e1a9c7c
Binary files /dev/null and b/img/scroll_base_h.png differ
diff --git a/img/scroll_base_v.png b/img/scroll_base_v.png
new file mode 100644 (file)
index 0000000..d6066c8
Binary files /dev/null and b/img/scroll_base_v.png differ
diff --git a/img/scroll_handle_h.png b/img/scroll_handle_h.png
new file mode 100644 (file)
index 0000000..ed561e4
Binary files /dev/null and b/img/scroll_handle_h.png differ
diff --git a/img/scroll_handle_v.png b/img/scroll_handle_v.png
new file mode 100644 (file)
index 0000000..3a2ad73
Binary files /dev/null and b/img/scroll_handle_v.png differ
diff --git a/img/small_default_button.png b/img/small_default_button.png
new file mode 100644 (file)
index 0000000..8d4017c
Binary files /dev/null and b/img/small_default_button.png differ
diff --git a/img/small_default_button_clicked.png b/img/small_default_button_clicked.png
new file mode 100644 (file)
index 0000000..a304368
Binary files /dev/null and b/img/small_default_button_clicked.png differ
diff --git a/img/small_icon-ref-managebackups.png b/img/small_icon-ref-managebackups.png
new file mode 100644 (file)
index 0000000..f9ffe78
Binary files /dev/null and b/img/small_icon-ref-managebackups.png differ
diff --git a/img/small_icon-ref-newbackup.png b/img/small_icon-ref-newbackup.png
new file mode 100644 (file)
index 0000000..97d8166
Binary files /dev/null and b/img/small_icon-ref-newbackup.png differ
diff --git a/img/small_icon-ref-restorebackups.png b/img/small_icon-ref-restorebackups.png
new file mode 100644 (file)
index 0000000..23e2534
Binary files /dev/null and b/img/small_icon-ref-restorebackups.png differ
diff --git a/img/small_icon-ref-settings.png b/img/small_icon-ref-settings.png
new file mode 100644 (file)
index 0000000..abc454c
Binary files /dev/null and b/img/small_icon-ref-settings.png differ
diff --git a/img/ssh.png b/img/ssh.png
new file mode 100644 (file)
index 0000000..d4ce558
Binary files /dev/null and b/img/ssh.png differ
diff --git a/img/tab_bg_1.png b/img/tab_bg_1.png
new file mode 100644 (file)
index 0000000..f5de942
Binary files /dev/null and b/img/tab_bg_1.png differ
diff --git a/img/tab_bg_2.png b/img/tab_bg_2.png
new file mode 100644 (file)
index 0000000..0c376ea
Binary files /dev/null and b/img/tab_bg_2.png differ
diff --git a/img/tab_bg_3.png b/img/tab_bg_3.png
new file mode 100644 (file)
index 0000000..2188df2
Binary files /dev/null and b/img/tab_bg_3.png differ
diff --git a/img/table_border.png b/img/table_border.png
new file mode 100644 (file)
index 0000000..a4bae53
Binary files /dev/null and b/img/table_border.png differ
diff --git a/img/tabletSuite_logo.png b/img/tabletSuite_logo.png
new file mode 100644 (file)
index 0000000..57b8571
Binary files /dev/null and b/img/tabletSuite_logo.png differ
diff --git a/img/tabletsuite.desktop b/img/tabletsuite.desktop
new file mode 100755 (executable)
index 0000000..1262354
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env xdg-open
+[Desktop Entry]
+Name=TabletSuite
+Comment=TabletSuite Application
+Version=0.0.1
+Exec=tabletsuite
+Icon=/usr/share/tabletsuite/tabletSuite_logo.png
+Type=Application
+Terminal=false
+Categories=Application;
+StartupNotify=false
+Name[en_US]=tabletsuite
diff --git a/img/view_bg.png b/img/view_bg.png
new file mode 100644 (file)
index 0000000..4a9743d
Binary files /dev/null and b/img/view_bg.png differ
diff --git a/img/view_border.png b/img/view_border.png
new file mode 100644 (file)
index 0000000..b289586
Binary files /dev/null and b/img/view_border.png differ
diff --git a/img/white_arrow.png b/img/white_arrow.png
new file mode 100755 (executable)
index 0000000..4dbf148
Binary files /dev/null and b/img/white_arrow.png differ
diff --git a/setup.py b/setup.py
new file mode 100755 (executable)
index 0000000..86371ef
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+from subprocess import *
+import os
+import glob
+
+dist = setup(name='tabletsuite',
+    version='0.0.1',
+    maintainer='Otacilio Lacerda',
+    maintainer_email='otaciliolacerda@gmail.com',
+    description='TabletSuite application',
+    long_description='',
+    license='GNU GPL',
+    platforms='all',
+    scripts=['tabletsuite'],
+    packages=['src', 'src/backup', 'src/pcsuite', 'src/ui', 'src/style'],
+    data_files=[('share/tabletsuite', glob.glob("img/*")),
+                ('share/applications', ['img/tabletsuite.desktop']),
+                ('share/fonts/extras', glob.glob('fonts/*'))],
+)
diff --git a/src/.svn/all-wcprops b/src/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..cd218cf
--- /dev/null
@@ -0,0 +1,53 @@
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/svn/pc-suite/!svn/ver/653/trunk/tabletsuite/src
+END
+battery.py
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/svn/pc-suite/!svn/ver/617/trunk/tabletsuite/src/battery.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/__init__.py
+END
+pcsdevicemanager.py
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/642/trunk/tabletsuite/src/pcsdevicemanager.py
+END
+settings.py
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/settings.py
+END
+pcsdeviceinfo.py
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/pcsdeviceinfo.py
+END
+tabletsuite.py
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/tabletsuite.py
+END
+pcsdeviceutils.py
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/643/trunk/tabletsuite/src/pcsdeviceutils.py
+END
+pcsutils.py
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/pc-suite/!svn/ver/611/trunk/tabletsuite/src/pcsutils.py
+END
diff --git a/src/.svn/dir-prop-base b/src/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/.svn/entries b/src/.svn/entries
new file mode 100644 (file)
index 0000000..f231a9d
--- /dev/null
@@ -0,0 +1,315 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-10-06T17:00:03.678569Z
+653
+pauloouriques
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+style
+dir
+\f
+plugins
+dir
+\f
+battery.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+9e4cc0a1ebba665c2fe12b76ba889647
+2009-09-14T12:56:51.357750Z
+617
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1811
+\f
+backup
+dir
+\f
+__init__.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-03-29T21:16:15.145020Z
+24
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+pcsdevicemanager.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+c759b16ea11f886c17310a1daa147d15
+2009-09-24T17:39:24.743743Z
+642
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4001
+\f
+settings.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+a624870d9c3018ae79cfc67d37fa1abf
+2009-06-23T17:46:40.723124Z
+346
+melunko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1158
+\f
+pcsdeviceinfo.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+027acaec3db77d7c557936ef39ae9e75
+2009-07-08T15:53:48.428567Z
+394
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+417
+\f
+pcsuite
+dir
+\f
+tabletsuite.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+0e1bae3cfc483abe88238c96c4ac1798
+2009-09-03T11:08:46.919187Z
+588
+otacilio
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+775
+\f
+ui
+dir
+\f
+pcsdeviceutils.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+99e1f832b7dab66b04bd0742b4f90423
+2009-09-24T18:11:29.733195Z
+643
+otacilio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5128
+\f
+pcsutils.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+6bac19aba73e3f938e4cdb3aea339c13
+2009-09-10T18:11:56.305145Z
+611
+nicholas
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4727
+\f
diff --git a/src/.svn/format b/src/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/.svn/prop-base/pcsutils.py.svn-base b/src/.svn/prop-base/pcsutils.py.svn-base
new file mode 100644 (file)
index 0000000..869ac71
--- /dev/null
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/src/.svn/prop-base/tabletsuite.py.svn-base b/src/.svn/prop-base/tabletsuite.py.svn-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/.svn/text-base/__init__.py.svn-base b/src/.svn/text-base/__init__.py.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/.svn/text-base/battery.py.svn-base b/src/.svn/text-base/battery.py.svn-base
new file mode 100644 (file)
index 0000000..0404ab0
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+# Ainda continua sendo o codigo do cara, apenas retirei as partes que nao nos interessa.
+# Ainda tem que ver se pode usar o codigo, ou seja, olhar a licensa. 
+# Deve ser istalado no dispositivo
+# Otacilio Lacerda
+
+import dbus
+import dbus.service
+import dbus.glib
+import gobject
+
+percent_left = -1
+charging = False
+
+loop = gobject.MainLoop()
+
+class Request(dbus.service.Object): 
+    def __init__(self, bus_name):
+        dbus.service.Object.__init__(self, bus_name, '/com/nokia/bme/request')
+
+    @dbus.service.signal('com.nokia.bme.request')
+    def timeleft_info_req(self):
+        pass
+
+    @dbus.service.signal('com.nokia.bme.request')
+    def status_info_req(self):
+        pass
+
+def timeleft_handler(idle_time, active_time):
+    global percent_left
+    percent_left = min(100, 100.0 * idle_time / 15000)
+    loop.quit()
+
+def charging_on_handler():
+    global charging
+    charging = True
+    loop.quit()
+
+def charging_off_handler():
+    global charging
+    charging = False
+    loop.quit()
+
+def getBatteryState(request):
+    global percent_left
+    global charging
+
+    request.status_info_req()
+    loop.run()
+
+    if charging:
+        return -1
+    request.timeleft_info_req()
+    loop.run()
+    return percent_left
+
+if __name__ == "__main__":
+
+    bus = dbus.SystemBus(private = True)
+    bus.add_signal_receiver(timeleft_handler, 'battery_timeleft')
+    bus.add_signal_receiver(charging_on_handler, 'charger_charging_on')
+    bus.add_signal_receiver(charging_on_handler, 'battery_full')
+    bus.add_signal_receiver(charging_off_handler, 'charger_charging_off')
+    bus_name = dbus.service.BusName('com.nokia.bme.request', bus)
+    request = Request(bus_name)
+
+    percent = getBatteryState(request)
+    if percent < 0:
+        print '-1'
+    else:
+        print '%.1f' % (percent)
+
diff --git a/src/.svn/text-base/pcsdeviceinfo.py.svn-base b/src/.svn/text-base/pcsdeviceinfo.py.svn-base
new file mode 100644 (file)
index 0000000..5e913eb
--- /dev/null
@@ -0,0 +1,15 @@
+# low_device_info module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+
+class PcsDeviceInfo:
+
+    def __init__(self):
+        self.ip = ""
+        self.storage = 0 # list memory data (FIXME: document the array information
+        self.battery = 0
+        self.model = ""
+        self.name = ""
+        self.hostname = ""
+        self.system = ""
+        self.charging = False
+        self.ossoBackup = ""        
diff --git a/src/.svn/text-base/pcsdevicemanager.py.svn-base b/src/.svn/text-base/pcsdevicemanager.py.svn-base
new file mode 100644 (file)
index 0000000..a63160f
--- /dev/null
@@ -0,0 +1,131 @@
+# low_device_manager module 
+# Authors: Nicholas Alexander && Otacilio Lacerda
+# Module responsible for management of devices informations. 
+
+import pickle
+import os
+
+from PyQt4.QtCore import *
+
+import pcsutils as utils
+from pcsdeviceinfo import PcsDeviceInfo
+from pcsdeviceutils import *
+from ui.tsuigeneralmethods import showMessageBox
+
+USER_HOST = 'root'
+HOME = os.path.expanduser("~")
+DEVICES_FILE = os.path.join(HOME, ".pcsuite/devices/.ip_list")
+
+
+class PcsDeviceManager(QObject):
+    """Class responsible for devices management such as adding and removing
+    devices, get batery, memory and name informations and saving Device objects.
+
+    The DeviceManager holds a list of Devices objects and can save and load this
+    list on a file and retrieve information about each Device.
+
+    """
+    _currentIp = None
+    def __init__(self):
+        QObject.__init__(self)
+        self._deviceList = []
+        
+        # FIXME: initialize this in another place
+        utils.initDirs()
+        self.loadDevices()
+
+        self._currentIp = None
+
+    def _batteryException(self):
+        errorMessage = "Could not get device battery status, check if " +\
+            "python is installed on your device. To get information about " + \
+            "python installation visit: " +\
+            "http://pymaemo.garage.maemo.org/installation.html"
+        showMessageBox(errorMessage,
+                              "Error while collecting device information")
+
+    def _addDevice(self, deviceIp):
+        """Add a new device to list connecting to it in the process.
+    
+        Arguments:
+        host_ip -- The IP of the device to connect.
+        
+        """
+        self.loadDevices()
+                    
+        deviceInfo = PcsDeviceInfo()
+        deviceInfo.ip = deviceIp
+        (deviceInfo.name, deviceInfo.system,
+         deviceInfo.ossoBackup) = queryProductInformation(deviceIp) 
+        if deviceInfo.name == "NO INFORMATION":
+            return "connectException"
+        try:
+            deviceInfo.battery = float(queryDeviceBattery(deviceIp))
+        except:
+            return "batteryException"
+    
+        if deviceInfo.battery < 0:
+            deviceInfo.charging = True
+            
+        deviceInfo.storage = queryDeviceStorage(deviceIp)
+        
+        if self.getDevice(deviceIp) != None:
+            return deviceInfo
+        
+        self._deviceList.append(deviceInfo)
+        self.saveDevices()
+        return deviceInfo
+
+    def removeDevice(self, deviceIp):
+        """Remove a Device from list.
+
+        Arguments:
+        device_ip -- The IP  of the device to remove
+
+        """
+        deviceInfo = self.getDevice(deviceIp)
+        if deviceInfo != -1:
+            self._deviceList.remove(deviceInfo)
+            self.saveDevices()
+            return 1
+        else:
+            raise Exception("No device with that ip was found")
+
+    def getDevices(self):
+        """Returns a list with the IP address of all devices in the object's 
+        devices list.
+        
+        """
+        ips = []
+        for deviceInfo in self._deviceList:
+            ips.append(deviceInfo.ip)
+        return ips
+
+    def saveDevices(self):
+        """Save the list of Device objects in DEVICES_FILE file."""
+        obj = self._deviceList
+        file = open(DEVICES_FILE, "w")
+        pickle.dump(obj, file)
+        file.close()
+
+    def loadDevices(self):
+        """Loads the list of Device objects from DEVICES_FILE path if possible."""
+
+        if os.path.exists(DEVICES_FILE):
+            file = open(DEVICES_FILE)
+            self._deviceList = pickle.load(file)
+            file.close()
+
+    def getDevice(self, ip):
+        # Returns the Device object with the provided ip
+        for deviceInfo in self._deviceList:
+            if deviceInfo.ip == ip:
+                return deviceInfo
+        return None
+
+    def setCurrentDevice (self, ip):
+        self._currentIp = ip
+        
+    def getCurrentDevice(self):
+        return self.getDevice(self._currentIp)
+    
diff --git a/src/.svn/text-base/pcsdeviceutils.py.svn-base b/src/.svn/text-base/pcsdeviceutils.py.svn-base
new file mode 100644 (file)
index 0000000..efe8da0
--- /dev/null
@@ -0,0 +1,155 @@
+# low_backup module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+
+import commands
+import os
+
+BATTERY = os.environ['BATTERY_PATH'] + 'battery.py'
+EXECUTE = "./"
+USER_HOST = "root"
+
+def queryProductInformation(deviceIp):
+    """ Update device name by getting device product name and os version
+    informations.
+
+    Use osso-product-info command to get the device and device OS short
+    names and set each to it correspondent attribute.
+
+    """
+
+    info = commands.getoutput("ssh -l %s %s osso-product-info" %
+                                        (USER_HOST, deviceIp))
+
+    deviceName = _extractOssoInfo(info, "shortName")
+    deviceOs = _extractOssoInfo(info, "shortOS")
+    ossoVersion = _extractOssoInfo(info, "ossoVersion")
+    if deviceName != -1 and deviceOs != -1:
+        deviceName = deviceName.strip("'")
+        deviceOs = deviceOs.strip("'")
+    else:
+        deviceName = "NO INFORMATION"
+        deviceOs = "NO INFORMATION"
+
+    return (deviceName, deviceOs, ossoVersion)
+
+def queryDeviceStorage(deviceIp):
+    """Returns a list of tuples, each tuple representing a memory status.
+
+    Tuples are in this format: (total, used)
+
+    Returns:
+        mem_infos -- List with all tuples holding memory info
+
+    """
+    info = commands.getoutput("ssh -l root %s df" %
+                              deviceIp).splitlines()
+    mem_infos = [-1, -1, -1]
+    for line in info:
+        if line.find("/dev/mtdblock4") != -1:
+            if line[-1] == "/":
+                total_used = _get_memory(line, "/dev/mtdblock4")
+                mem_infos.pop(0)
+                mem_infos.insert(0, total_used)
+        
+        elif line.find("/media/mmc1") != -1:
+            total_used = _get_memory(line, "/dev/mmcblk0p1")
+            mem_infos.pop(1)
+            mem_infos.insert(1, total_used)
+        
+        elif line.find("/media/mmc2") != -1:
+            total_used = _get_memory(line, "/dev/mmcblk1p1")
+            mem_infos.pop(2)
+            mem_infos.insert(2, total_used)
+    return mem_infos
+
+def queryDeviceBattery(deviceIp):
+    """Return device current battery status in a string.
+
+    This method runs a python script in the device that returns the battery
+    status, this status is represented by one string with the percentage of
+    battery current charge or the number -1 case battery is charging.
+
+    Returns:
+    text -- Text with the battery status
+
+    """
+
+    # Calls script that returns device battery status    
+    os.system("scp %s %s@%s:/tmp" % (BATTERY, USER_HOST, deviceIp))
+    battery_status = commands.getoutput("ssh -l %s %s /usr/bin/python \
+                                        /tmp/battery.py" % (USER_HOST, 
+                                                            deviceIp))
+    return battery_status
+
+def _get_memory(line, path):
+    """Retrieve and return total and used memory information from the given 
+    line using the memory path to retrieve the right information.
+
+    This function is to be used with a line of the return of a df command.
+
+    Arguments:
+    line -- The line where the memory information is
+    path -- The path in the begining of the line
+
+    Returns:
+    total -- Total memory
+    used -- Amount of used memory
+
+    """
+    number_of_infos = 0
+    i = len(path) + 1
+    while number_of_infos < 2:
+        char = line[i]
+        if char != " ":
+            start = i
+            end = line.find(" ", start + 1)
+            if number_of_infos == 0:
+                total = line[start: end]
+            elif number_of_infos == 1:
+                used = line[start: end]
+            i = end
+            number_of_infos += 1
+        i += 1
+    return total, used
+
+def _extractOssoInfo(osso_string, info_type="name"):
+    """Read the osso-product-info command return string and extract the
+    needed info depeding on info_type argument.
+
+    Arguments:
+    osso_string -- The string returned by osso-product-info command
+    info_type -- the kind of information to b extracted, can be:
+        name - returns device full name (default)
+        OS - returns device OS full name
+        shortName - returns device short name
+        shortOS - returns device short OS name
+
+    Returns:
+    info -- String with the needed information
+    -1 -- Case the information couldn't be found in the given string
+
+    """
+    detailed_type = ""
+    if info_type == "shortName":
+        detailed_type = "OSSO_PRODUCT_NAME"
+    elif info_type == "shortOS":
+        detailed_type = "OSSO_PRODUCT_RELEASE_NAME"
+    elif info_type == "name":
+        detailed_type = "OSSO_PRODUCT_FULL_NAME"
+    elif info_type == "OS":
+        detailed_type = "OSSO_PRODUCT_RELEASE_FULL_NAME"
+    elif info_type == "ossoVersion":
+        detailed_type = "OSSO_VERSION"
+    else:
+        detailed_type = "OSSO_PRODUCT_FULL_NAME"
+
+    types_list = osso_string.splitlines()
+    info = -1
+    for type_line in types_list:
+        if type_line.startswith(detailed_type):
+            # The second argument is the information itself since informations
+            # are displayed like: OSSO_PRODUCT_RELEASE_NAME='OS 2008'
+            info = type_line.split("=")[1]
+
+    return info
diff --git a/src/.svn/text-base/pcsutils.py.svn-base b/src/.svn/text-base/pcsutils.py.svn-base
new file mode 100644 (file)
index 0000000..7d8a930
--- /dev/null
@@ -0,0 +1,165 @@
+import os.path
+
+import commands
+import os
+import pwd
+import settings
+import socket
+import sys
+
+import paramiko
+
+from backup.pcsbackuputils import createFolder
+
+sshPath = os.path.expanduser('~/.ssh/') 
+known_hosts = os.path.join(sshPath, 'known_hosts')
+log_file = os.path.expanduser('~/.pcsuite/.ssh_log')
+user = 'root'
+keyName = 'rsa_key'
+
+def create_route(host, port=22):
+    # Verify Auth with privateKey
+    try:
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(15)
+        sock.connect((host, port))
+        sock.close()
+        return True
+    except:
+        print 'No route to host'
+        return False
+
+def verify_exist_keys(host, port=22):
+    try:    
+        transport = _create_transport(host, port)
+    except:
+        return False
+    try:
+        getKey = paramiko.RSAKey.from_private_key_file(sshPath + keyName)
+        transport.start_client()
+        transport.auth_publickey(user, getKey)
+        if transport.is_authenticated():
+            transport.close()
+            return True
+    except:
+        # 'Error in auth with publickey, try with password...'
+        return False
+    return False
+
+def keyExchange(host, passwd, port=22):
+    if not os.path.exists(sshPath):
+        createFolder(sshPath)
+
+    # Clean cached keys in ssh-agent
+    os.system('ssh-add -d')    
+
+    try:
+        transport = _create_transport(host, port)
+    except:
+        transport.close()
+        return False
+
+    if not _add_host_fingerprint(host):
+        transport.close()
+        return False
+
+    if not _authenticate(user, passwd, transport):
+        transport.close()
+        return False
+    
+    if not _add_key_to_host(host, transport):
+        transport.close()
+        return False
+
+    transport.stop_thread()
+    transport.close()
+    return True
+
+def initDirs():
+    settings.makeDirs()
+
+def _create_transport(host, port):
+    # Create a transport and initiate client mode
+    try:
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(15)
+        sock.connect((host, port))
+    except Exception, msg:
+        print 'Connect failed: ' + str(msg)
+        raise Exception('Error while create sockets.')
+    transport = paramiko.Transport(sock)
+    return transport
+
+def _add_host_fingerprint(host):
+    if not os.path.exists(known_hosts):
+        os.system('touch %s' %known_hosts)
+    if os.system('ssh-keyscan -t rsa %s >> %s' %(host, known_hosts)) != 0:
+        return False
+    return True
+
+def _generate_keys():
+    # Generate public and private RSAKey
+    keyFile = os.path.join(sshPath, keyName)
+    if not os.path.exists(keyFile):
+        privateKey = paramiko.RSAKey.generate(2048)
+        privateKey.write_private_key_file(keyFile)
+        login = pwd.getpwuid(os.geteuid())[0]
+        publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
+                                    privateKey.get_base64(),
+                                    login , socket.gethostname())
+        try:
+            keyFile = open(keyFile + '.pub','w')
+            keyFile.write(publicKey)
+            keyFile.close()
+        except:
+            print 'Error while save the public key'
+            raise Exception()
+    else:
+        try:
+            privateKey = paramiko.RSAKey.from_private_key_file(keyFile)
+            login = pwd.getpwuid(os.geteuid())[0]
+            publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
+                                        privateKey.get_base64(),
+                                    login , socket.gethostname())
+        except:
+            print 'Error while read the private key'
+            raise Exception()
+    return publicKey
+
+def _authenticate(user, passwd, transport):
+    # Try Auth with password
+    try:
+        transport.start_client()
+        transport.auth_password(user, passwd)
+    except:
+        print 'Verify user or password.'
+        return False
+    if not transport.is_authenticated():
+        print 'Authentication fail'
+        return False
+
+    try:
+        exception = transport.get_exception()
+        if exception:
+            raise exception
+    except Exception, msg:
+        print 'Error in connection: ' + str(msg)
+        return False
+    return True
+
+def _add_key_to_host(host, transport):
+    # Add publickey in host
+    if not transport.is_active():
+        print 'Channel is not active'
+        return False
+    
+    paramiko.util.log_to_file(log_file, 10)
+    channel = transport.open_session()
+    try:
+        channel.exec_command('mkdir -p ~/.ssh; echo %s >> .ssh/authorized_keys' % (_generate_keys()))
+    except Exception, msg:
+        print 'Error while generate or add the keys.'
+        channel.close()
+        return False
+    channel.close()
+    return True
diff --git a/src/.svn/text-base/settings.py.svn-base b/src/.svn/text-base/settings.py.svn-base
new file mode 100644 (file)
index 0000000..d5b0325
--- /dev/null
@@ -0,0 +1,36 @@
+import os
+import os.path
+
+class Settings:
+    def __init__(self):
+        self.home = os.path.expanduser("~")
+        self.default_folder = os.path.join(self.home, ".pcsuite")
+        self.devices_folder = os.path.join(self.default_folder,
+                                        "devices")
+        self.backup_config_path = os.path.join(self.default_folder, "config")
+        self.backup_folder = os.path.join(self.default_folder, "Backup")
+
+    def initalize(self):
+
+        """Check the existence of required project folders, creating
+        them if needed. Also gives execution permission to all scripts.
+
+        """
+
+        # This is checking if the default folder exists too, because
+        # if it doesn't exist the mount_point won't exist either
+        if not os.path.exists(self.devices_folder):
+            os.makedirs(self.devices_folder)
+        if not os.path.exists(self.backup_config_path):
+            os.makedirs(self.backup_config_path)
+        if not os.path.exists(self.backup_folder):
+            os.makedirs(self.backup_folder)
+
+def makeDirs():
+    s = Settings()
+    s.initalize()
+
+if __name__ == "__main__":
+    makeDirs()
+    
+
diff --git a/src/.svn/text-base/tabletsuite.py.svn-base b/src/.svn/text-base/tabletsuite.py.svn-base
new file mode 100644 (file)
index 0000000..531c1e8
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+    
+import sys, os
+import optparse
+from PyQt4.QtGui import *
+
+parser = optparse.OptionParser(usage="%prog [options] [project-file]")
+parser.add_option("-l", "--local-dirs", action="store_true", dest="use_local_dirs",
+                help="Use files from the local directory tree")
+
+(options, args) = parser.parse_args()
+if options.use_local_dirs:
+    PATHS = {"IMAGE_PATH" : os.pardir + "/img/",
+             "BATTERY_PATH" : "./"}
+else:
+    PATHS = {"IMAGE_PATH" : "/usr/share/tabletsuite/",
+             "BATTERY_PATH" : "/usr/lib/python2.6/site-packages/src/"}
+
+for var, path in PATHS.iteritems():
+    os.environ.setdefault(var, path)
+
+
+from pcsuite.pcsuite import PCSuite
+
+app = QApplication(sys.argv)
+ps = PCSuite()
+ps.show()    
+        
+app.exec_()
diff --git a/src/__init__.py b/src/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/backup/.svn/all-wcprops b/src/backup/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..b3ad112
--- /dev/null
@@ -0,0 +1,125 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/svn/pc-suite/!svn/ver/653/trunk/tabletsuite/src/backup
+END
+pcsopenfilewizard.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcsopenfilewizard.py
+END
+pcsbackupparser.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/backup/pcsbackupparser.py
+END
+pcspcbackupmanager.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcspcbackupmanager.py
+END
+pcsprogressdialog.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/639/trunk/tabletsuite/src/backup/pcsprogressdialog.py
+END
+pcsprogresswizard.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/636/trunk/tabletsuite/src/backup/pcsprogresswizard.py
+END
+pcsbackupxml.py
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/620/trunk/tabletsuite/src/backup/pcsbackupxml.py
+END
+pcsbackupwizard.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/653/trunk/tabletsuite/src/backup/pcsbackupwizard.py
+END
+pcsbackuputils.py
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcsbackuputils.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/backup/__init__.py
+END
+pcsbackupmanagerui.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/pc-suite/!svn/ver/652/trunk/tabletsuite/src/backup/pcsbackupmanagerui.py
+END
+pcsbackuplocation.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/backup/pcsbackuplocation.py
+END
+pcsbackuplistui.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/backup/pcsbackuplistui.py
+END
+pcsbackupmanager.py
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcsbackupmanager.py
+END
+pcswindowmanager.py
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/630/trunk/tabletsuite/src/backup/pcswindowmanager.py
+END
+pcsrestoredialog.py
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/pc-suite/!svn/ver/606/trunk/tabletsuite/src/backup/pcsrestoredialog.py
+END
+pcsbackup.py
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/652/trunk/tabletsuite/src/backup/pcsbackup.py
+END
+pcscheckboxwizard.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/pc-suite/!svn/ver/641/trunk/tabletsuite/src/backup/pcscheckboxwizard.py
+END
+pcsrestorebackupui.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcsrestorebackupui.py
+END
+pcsdevicebackupmanager.py
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/backup/pcsdevicebackupmanager.py
+END
+pcsbackupinfo.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/backup/pcsbackupinfo.py
+END
diff --git a/src/backup/.svn/dir-prop-base b/src/backup/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/backup/.svn/entries b/src/backup/.svn/entries
new file mode 100644 (file)
index 0000000..7857140
--- /dev/null
@@ -0,0 +1,708 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src/backup
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-10-06T17:00:03.678569Z
+653
+pauloouriques
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+pcsopenfilewizard.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+bd7d89e9e75d7a71828842740bf96bc9
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9749
+\f
+pcsbackupparser.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+cb732e14b18419973e32171f4ab44586
+2009-08-20T18:08:50.977477Z
+571
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4071
+\f
+pcspcbackupmanager.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+ce87348b076ca74e6cb7c6453cae7683
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19153
+\f
+pcsprogressdialog.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+8f8ede17cf9c329d29af777bae73a556
+2009-09-18T09:51:12.321968Z
+639
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4432
+\f
+pcsprogresswizard.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+3982df75bf944d1b5b8eb49df76460f7
+2009-09-17T14:38:23.185224Z
+636
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9496
+\f
+pcsbackupxml.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+cfc2951c78dbc548e271022d230fa645
+2009-09-14T16:31:07.677300Z
+620
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3174
+\f
+pcsbackupwizard.py
+file
+
+
+
+
+2009-10-08T18:25:37.000000Z
+3171ca50afa16f0dcaf44c048cfa62c6
+2009-10-06T17:00:03.678569Z
+653
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6759
+\f
+pcsbackuputils.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+9f9b1db376f86057eb1dac85a386e05c
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5583
+\f
+__init__.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-03-30T19:44:37.661351Z
+26
+amaury
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+pcsbackupmanagerui.py
+file
+
+
+
+
+2009-10-08T18:25:37.000000Z
+9c5a36ddecd9d79d7d7988c6b8fd673a
+2009-10-05T11:14:02.602311Z
+652
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19623
+\f
+pcsbackuplocation.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+dd0ceb1377ef5b46c6dc79c44dcee7ba
+2009-06-23T16:10:35.956172Z
+345
+melunko
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+337
+\f
+pcsbackuplistui.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+313275d8fa5de6a6a67dcc3a0b75bf7a
+2009-08-27T10:01:51.549755Z
+577
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3915
+\f
+pcsbackupmanager.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+d61dc11dd6cfdfe3d2eec0b7ebd3a643
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6801
+\f
+pcswindowmanager.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+8f77ded896d07d7f62d101b3f70ba23d
+2009-09-15T17:59:33.111110Z
+630
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1279
+\f
+pcsrestoredialog.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+44f071048e2ac8dd3e4944866fa857c4
+2009-09-08T13:49:13.253249Z
+606
+amaury
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7658
+\f
+pcsbackup.py
+file
+
+
+
+
+2009-10-08T18:25:37.000000Z
+6b5f22c2382885b7cd8d0f3d468c2597
+2009-10-05T11:14:02.602311Z
+652
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4784
+\f
+pcscheckboxwizard.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+c7bce3b7fe62f58f2c84b72690008619
+2009-09-24T16:33:15.553218Z
+641
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11024
+\f
+pcsrestorebackupui.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+6229aa92dec31b2d6350a936e4f05849
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+16050
+\f
+pcsdevicebackupmanager.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+a6eca97d9d73c00c79d1afa06a79c98d
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3340
+\f
+pcsbackupinfo.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+227e4c627b4f06fb55da1e3d9e59ec4d
+2009-08-12T12:26:15.094255Z
+548
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2055
+\f
diff --git a/src/backup/.svn/format b/src/backup/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/backup/.svn/prop-base/pcsbackuplocation.py.svn-base b/src/backup/.svn/prop-base/pcsbackuplocation.py.svn-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/backup/.svn/prop-base/pcsbackuputils.py.svn-base b/src/backup/.svn/prop-base/pcsbackuputils.py.svn-base
new file mode 100644 (file)
index 0000000..869ac71
--- /dev/null
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/src/backup/.svn/text-base/__init__.py.svn-base b/src/backup/.svn/text-base/__init__.py.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/backup/.svn/text-base/pcsbackup.py.svn-base b/src/backup/.svn/text-base/pcsbackup.py.svn-base
new file mode 100644 (file)
index 0000000..92d5f2a
--- /dev/null
@@ -0,0 +1,124 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsapp import PcsApp
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+from ui.pcsbutton import *
+from ui.tsuigeneralmethods import *
+
+from ui.pcscustombuttons import PcsCustomButton as customButton
+
+from pcswindowmanager import *
+
+class PcsBackup(PcsApp):
+    
+    def __init__(self, deviceInfo, parent=None):
+        PcsApp.__init__(self, parent)
+        self.deviceInfo = deviceInfo
+        
+        if (self.deviceInfo != None):
+            self.windowManager = PcsWindowManager(self.deviceInfo, self)
+        
+        self.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self.setWindowTitle("%s Backup" % APPLICATION_NAME)
+
+        self.hLayout = QHBoxLayout()
+        self.hLayout.setMargin(8)
+        self.vLayout = QVBoxLayout()
+        
+        spc = QSpacerItem(0,50)
+        self.optionsLayout = QVBoxLayout()
+        self.optionsLayout.addItem(spc)
+        self._addButtons()
+        self.optionsLayout.addItem(spc)
+        
+        self.deviceWidget = PcsDeviceWidget(1)
+        self.deviceWidget.addBorder()
+        self.deviceWidget.addDeviceName()
+        self.deviceWidget.setDeviceInfo(self.deviceInfo)
+        
+        self.optionsBorderLayout = QGridLayout()
+        self.optionsBorderLabel = QLabel()
+        self.optionsBorderLabel.setFixedSize(208, 205)
+        self.optionsBorderLabel.setPixmap(QPixmap(DEVICE_BACKUP_BORDER))
+        self.optionsBorderLayout.addWidget(self.optionsBorderLabel, 0, 0, Qt.AlignCenter)
+        self.optionsBorderLayout.addLayout(self.optionsLayout, 0, 0, Qt.AlignCenter)
+        self.hLayout.addLayout(self.optionsBorderLayout)
+        self.hLayout.addWidget(self.deviceWidget)
+        
+        #FIXE ME
+        l1 = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        self.vLayout.addItem(TOP_SPACER)
+        self.vLayout.addWidget(l1)
+        self.vLayout.addLayout(self.hLayout)
+        informationLayout = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        information = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Select an action.</font>")
+        informationLayout.addItem(spc)
+        informationLayout.addWidget(iconAlert)
+        informationLayout.addWidget(information, Qt.AlignLeft)
+        self.vLayout.addLayout(informationLayout)
+        self.vLayout.setMargin(8)
+        self.setLayout(self.vLayout)
+        
+    def openBackupWizard(self):
+
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backup_wizard = self.windowManager.getNewBackup()
+            centralize(backup_wizard)
+            backup_wizard.setGeometry(self.geometry())
+            backup_wizard.exec_()
+            self.setVisible(False)
+            self.setGeometry(backup_wizard.geometry())
+        else:
+            showMessageBox("No devices were found.", "")
+
+    def openBackupManagerDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.show()
+            self.setVisible(False)
+        else:
+            showMessageBox("No devices were found.", "")
+            
+    def openRestoreBackupDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            restoreBackup = self.windowManager.getRestoreBackup()
+            centralize(restoreBackup)
+            restoreBackup.show()
+            self.setVisible(False)
+        else:
+            showMessageBox("No devices were found.", "")
+        
+    def _addButtons(self):
+        infList = [("New Backup       ", ICON_NEW_BACKUP), 
+                   ("Manage Backups", ICON_MANAGER_BACKUP),
+                   ("Restore Backups  ", ICON_RESTORE_BACKUP)]
+        buttonsList = []
+        for inf in infList:
+            buttonOptions = PcsButton(inf[0])
+            buttonOptions.setStyleSheet("background-image\
+            :url("+ BUTTON_WITH_ICON_BG +");\
+             qproperty-icon:url("+inf[1]+");\
+             min-height:50px; min-width:188px;\
+             max-height:50px; max-width:188px;\
+             qproperty-iconSize: 43px 36px")
+            self.optionsLayout.addWidget(buttonOptions)
+            buttonsList.append(buttonOptions)
+            
+        self.connect(buttonsList[0], SIGNAL("clicked()"),
+                     self.openBackupWizard)
+        self.connect(buttonsList[1], SIGNAL("clicked()"),
+                    self.openBackupManagerDialog)
+        self.connect(buttonsList[2], SIGNAL("clicked()"),
+                      self.openRestoreBackupDialog) 
diff --git a/src/backup/.svn/text-base/pcsbackupinfo.py.svn-base b/src/backup/.svn/text-base/pcsbackupinfo.py.svn-base
new file mode 100644 (file)
index 0000000..a76e11e
--- /dev/null
@@ -0,0 +1,73 @@
+import time
+from datetime import datetime
+
+class PcsBackupInfo:
+    """Class that represents a backup
+
+    Attributes:
+    _name -- Backup name
+    path -- Backup directory path
+    date -- Date when backup was created
+    _comment -- Any comment about backup
+    size -- Backup file size
+    files_number = total number of backup files
+    _time = time object was created in seconds since epoch
+
+    """
+
+    def __init__(self, name, path, size, comment=""):
+        """Initialize object attributes."""
+        self._name = name
+        self.path = path
+        self._time = time.time()
+        self.date = datetime.fromtimestamp(self._time).replace(microsecond=0)
+        self.size = size
+        self.files_number = 0
+        self._comment = comment
+        self.fromDevice = False
+
+    def getPath(self):
+        """Return object path."""
+        return self.path
+
+    def getName(self):
+        """Return object name."""
+        return self._name
+
+    def getDate(self):
+        """Return object creation date."""
+        return self.date
+
+    def getComment(self):
+        """Return object _comment attribute."""
+        return self._comment
+
+    def getSize(self):
+        """Return object file size."""
+        return self.size
+    
+    def getTime(self):
+        """ Returns the object creation time in seconds since epoch. """
+        return self._time
+    
+    def getFilesNumber(self):
+        """ Return number of files this backup holds. """
+        return self.files_number
+
+    def setComment(self, new_comment):
+        """Set object _comment attribute to the given string"""
+        self._comment = new_comment
+
+    def setName(self, new_name):
+        """Set object name to a new name"""
+        self._name = new_name
+        
+    def setDate(self, newDate):
+        self.date = newDate
+    
+    def setFilesNumber(self, number_of_files):
+        """ Set number of files this backup holds to number_of_files ."""
+        self.files_number = number_of_files
+        
+    def setAtDevice(self, bool=False):
+        self.fromDevice = bool
diff --git a/src/backup/.svn/text-base/pcsbackuplistui.py.svn-base b/src/backup/.svn/text-base/pcsbackuplistui.py.svn-base
new file mode 100644 (file)
index 0000000..daca374
--- /dev/null
@@ -0,0 +1,110 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PCSBackupListUi(QTableView):
+    
+    ''' Class that creates a table, where the backups will be shown '''
+    
+    def __init__(self, backupManager):
+        super(PCSBackupListUi, self).__init__()
+        
+        self.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
+        self.setAlternatingRowColors(True)
+        self.setShowGrid(False)
+        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.model = QStandardItemModel()
+        self.setModel(self.model)
+        
+        hHeader = QHeaderView(Qt.Horizontal)
+        hHeader.setObjectName("listHeader")
+        hHeader.setAttribute(Qt.WA_NoSystemBackground)
+        hHeader.setStretchLastSection(True)
+        hHeader.setResizeMode(QHeaderView.ResizeToContents)
+        hHeader.setMinimumSectionSize(100)
+
+        hHeader.setClickable(False)
+
+        self.setHorizontalHeader(hHeader)
+        
+        vHeader = QHeaderView(Qt.Vertical)
+        vHeader.setVisible(False)
+        self.setVerticalHeader(vHeader)
+        self._backupManager = backupManager
+        
+    def updateBackupList(self):
+        self.model.clear()
+        self.model.setHorizontalHeaderItem(0, QStandardItem("NAME"))
+        self.model.setHorizontalHeaderItem(1, QStandardItem("SIZE"))
+        self.model.setHorizontalHeaderItem(2, QStandardItem("DATE"))
+
+        backupList = self._backupManager.getBackupList()
+        for backupInfo in backupList:
+            name = backupInfo.getName()
+            date = str(backupInfo.getDate())
+            size = self._formatBackupSize(backupInfo.getSize())
+            backupData = [QStandardItem(name), QStandardItem(size), QStandardItem(date)]
+            self.model.appendRow(backupData)
+
+    def removeSelectedBackups(self):
+        selectionModel = self.selectionModel()
+        indexList = selectionModel.selectedRows()
+        for index in reversed(sorted(indexList)):
+            if index.isValid():
+                row = index.row()
+                data = self.model.itemData(index)
+                backupName = data[0].toString()
+                if self._backupManager.removeBackup((str(backupName).strip())):
+                    self.model.removeRow(row)
+        self.updateBackupList()
+
+    def renameSelectedBackup (self, newName):
+        #!!!!!!! getSelectedBackup
+        backupName = (str(self.getSelectedBackup())).strip()
+        if backupName != None:
+            if self._backupManager.renameBackup(backupName, newName):
+                self.updateBackupList()
+                return True
+        
+        return False
+    
+    def getSelectedBackup(self):
+        list = self.getSelectedBackupList()
+        if list and len(list) > 0:
+            return list[0]
+        
+        return None
+    
+    def getSelectedBackupList(self):
+        selectionModel = self.selectionModel()
+        indexList = selectionModel.selectedRows()
+        backupList = []
+        for index in indexList:
+            if index.isValid():
+                row = index.row()
+                data = self.model.itemData(index)
+                backupList.append(data[0].toString())
+        return backupList
+
+    def getBackupManager(self):
+        return self._backupManager
+            
+    def _formatBackupSize(self, size):
+        """ Return a string with a more suited size and byte multiple for the
+        received size.
+        
+        Attributes:
+            String/Float/Int size - size in bytes or string representing it.
+        
+        """
+        size = float(size)
+        multiples = ["B", "KB", "MB", "GB"]
+        divisions = 0
+        while size > 1000 and divisions <= 3:
+            size = size / 1024.
+            divisions += 1
+            
+        return "%.1f %s" % (size, multiples[divisions])
diff --git a/src/backup/.svn/text-base/pcsbackuplocation.py.svn-base b/src/backup/.svn/text-base/pcsbackuplocation.py.svn-base
new file mode 100644 (file)
index 0000000..ab5d942
--- /dev/null
@@ -0,0 +1,11 @@
+# Class Backup_Category holds osso-backup .conf files informations
+
+class PcsBackupLocation:
+    """Backup_Location class.
+    Used for holding location attributes from parsed osso-backup xml files.
+
+    """
+    def __init__(self, type, category, path):
+        self.category = category
+        self.type = type
+        self.path = path
diff --git a/src/backup/.svn/text-base/pcsbackupmanager.py.svn-base b/src/backup/.svn/text-base/pcsbackupmanager.py.svn-base
new file mode 100644 (file)
index 0000000..92a5cc7
--- /dev/null
@@ -0,0 +1,168 @@
+import os
+
+from PyQt4.QtCore import *
+from zipfile import *
+
+import pcsbackuputils as utils
+
+
+HOME = os.path.expanduser("~")
+USER_HOST = "root"
+DEVICES_POINT = "%s/.pcsuite/devices/" % HOME
+
+
+class PcsBackupManager(QObject):
+
+    def __init__(self):
+        QObject.__init__(self)
+        self._backupList = []
+
+    def loadBackups(self):
+        return False
+
+    def saveBackups(self):
+        return False
+
+    def getBackupList(self):
+        return None
+    
+    def createBackup(self, backup_name, path, host_ip, categories, comment=""):
+        return False
+
+    def removeBackup(self, backup_name):
+        return False
+
+    def getBackupInfo(self, backupName):
+        return None
+    
+    def renameBackup(self, backupName, newName):
+        return False
+    
+    def changeBackupComment(self, backupName, new_comment):
+        return False
+    
+    def listBackupContent(self, backupName):
+        content = []
+        backupInfo = self.getBackupInfo(backupName)
+        backupPath = backupInfo.getPath()
+        fullPath = os.path.join(str(backupPath), str(backupName))
+        
+        for entry in os.listdir(fullPath):
+            if entry.endswith(".zip"):
+                zipfile = utils.openZip(os.path.join(fullPath, entry), "r")
+                for member in zipfile.namelist():
+                    folders = member.split("/")
+                    memberName = "../" + "/".join([folders[-2], folders[-1]])
+                    content.append(memberName)
+        return content
+    
+    def restoreBackup(self, backupInfo, host_ip, categories):
+        """ Restore a PC backup to device with given IP address.
+        
+        Attributes:
+        String backupInfo - Object representing the backup
+        String host_ip - IP address of device.
+        Dictionary categories - dictionary with categories as keys and with
+                            value True if that category should be restored.
+                            
+        """
+        self.setRestoreInProgress(True)
+        # Set restore needed paths
+        devicePath = os.path.join(DEVICES_POINT, "%s" % host_ip)
+        mountPath = os.path.join(devicePath, "Root" )
+        tempPath = os.path.join(mountPath, "tmp/paths")
+        restScriptsPath = ("/etc/osso-backup/restore.d/always")
+        try:
+            utils.mountDevice(USER_HOST, host_ip, mountPath)
+            # Get backup location depending from backup source
+            if backupInfo == None:
+                return False
+            if backupInfo.fromDevice:
+                backup_path = backupInfo.getPath()
+            else:
+                backup_path = os.path.join(str(backupInfo.getPath()), 
+                                           str(backupInfo.getName()))
+            # Get backup files list for each category and write it on a file
+            # that will be needed by restore scripts.
+            pathsDictonary = utils.getBackupFilesPath(backup_path)
+            if utils.writeBackupFilesPath(pathsDictonary, tempPath) == False:
+                return False
+            # --- Initialize restore progress ---
+            currentSize = 0
+            # Get total number of files to restore
+            numberOfFiles = 0
+            for categ in pathsDictonary:
+                for file in pathsDictonary[categ]:
+                    numberOfFiles += 1
+            # Get size of all categories being restored
+            totalSize = 0
+            for file in os.listdir(backup_path):
+                if file.endswith(".zip"):
+                    categ = file[:-4]
+                    if categories[categ]:
+                        catPath = os.path.join(backup_path, file)
+                        zip = utils.openZip(catPath)
+                        for member in zip.namelist():
+                            totalSize += zip.getinfo(member).file_size
+            # Extract zip files to device
+            for entry in os.listdir(backup_path):
+                category = entry[:-4]
+                if entry.endswith(".zip") and categories[category]:
+                    zipPath = os.path.join(backup_path, entry)
+                    zip = utils.openZip(zipPath)
+                    # Update restore progress, extract current f print "member %s: %.2f" % (member, zip.getinfo(member).file_size)ile and emit
+                    # progress sinal
+                    for member in zip.namelist():
+                        if not self.restoreInProgress:
+                            return 0
+                        percentage = "%.1f" % self.computePercentage(totalSize,
+                                                                currentSize)
+                        
+                        status = (percentage, category, numberOfFiles, totalSize)
+                        self.emit(SIGNAL("restoreProgress"), status)
+                        zip.extract(member, devicePath)
+                        currentSize += zip.getinfo(member).file_size
+                    percentage = "%.1f" % ((currentSize / float(totalSize)) * 100)
+                    status = (percentage, category, numberOfFiles, totalSize)
+                    self.emit(SIGNAL("restoreProgress"), status)
+                    zip.close()
+            # Execute restore scripts
+            os.system("ssh %s@%s ..%s/*.sh %s" % (USER_HOST, host_ip, 
+                                                  restScriptsPath, tempPath))
+            self.setRestoreInProgress(False)
+            # --- Restore finished ---
+        finally:
+            utils.unmountDevice(mountPath)
+            
+    
+    def computePercentage(self, totalSize, currentSize):
+        if totalSize == 0:
+            percentage = 100
+        else:
+            percentage = (currentSize / float(totalSize)) * 100
+            if percentage > 100:
+                percentage = 100
+        return percentage
+    
+    def copy(self, sourcePath, destinationPath):
+        numberOfFiles = 0
+        for entry in os.listdir(sourcePath):
+            zipPath = os.path.join(sourcePath, entry)
+            if zipPath.endswith(".zip"):
+                zip = utils.openZip(zipPath)
+                numberOfFiles += len(zip.namelist())
+        totalSize = float(utils.getSize(sourcePath))
+        currentSize = 0
+        self.emit(SIGNAL("copyProgress"), ("0.00", numberOfFiles, totalSize))
+        for entry in os.listdir(sourcePath):
+            if not self.copyInProgress:
+                utils.removePath(destinationPath)
+                return 0
+            entryPath = os.path.join(sourcePath, entry)
+            utils.copy(entryPath, destinationPath)
+            currentSize += utils.getSize(entryPath)
+            progress = "%.2f" % ((currentSize / totalSize) * 100)
+            self.emit(SIGNAL("copyProgress"), (progress, numberOfFiles,
+                                                    totalSize))
+            
+    
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsbackupmanagerui.py.svn-base b/src/backup/.svn/text-base/pcsbackupmanagerui.py.svn-base
new file mode 100644 (file)
index 0000000..2fdc32b
--- /dev/null
@@ -0,0 +1,502 @@
+# 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"))
+        
+        
+        
+        
diff --git a/src/backup/.svn/text-base/pcsbackupparser.py.svn-base b/src/backup/.svn/text-base/pcsbackupparser.py.svn-base
new file mode 100644 (file)
index 0000000..c950a6e
--- /dev/null
@@ -0,0 +1,115 @@
+# Module used to parse osso-backup xml conf files, retrieving categories and
+# backup paths information
+
+import os.path
+import xml.dom
+import xml.dom.minidom
+
+from pcsbackuplocation import *
+
+
+class PcsBackupParser:
+    """Holds a list of Backup_location objects
+
+    Can parse .conf xml files with osso-backup format at the given path with
+    fill_locations_list, creating Backup_location objects based on type,
+    category and path of each location inside each xml file and then holding
+    all objects in the locations_list attribute.
+
+    """
+    def __init__(self):
+        self.locationsDict = {}
+        
+    def getLocationsDict(self):
+        return self.locationsDict
+        
+    def addLocation(self, location):
+        """Add a location to locations_list attribute of theis class.
+
+        Arguments:
+        location -- the location object to be added
+
+        """
+        category = location.category
+        if category in self.locationsDict.keys():
+            self.locationsDict[category].append(location)
+        else:
+            self.locationsDict[category] = [location]
+
+    def fillLocationsDict(self, path):
+        """Add all locations that can be found inside xml files of the given
+        path.
+
+        This method reads all .conf files inside the directory path given and
+        puts on its locations_list attribute all the Backup_location objects
+        created with the informations returned from the files parsing.
+
+        Arguments:
+        path -- Path of directory containing files to parse
+
+        """
+        for file in os.listdir(path):
+            if file.endswith(".conf"):
+                locations = self.locationsFromFile(os.path.join(path, file))
+                for location in locations:
+                    self.addLocation(location)
+
+    def locationsFromFile(self, xml_file):
+        """Return a list with all locations objects inside the given file.
+
+        The file is parsed and all informations retrieved from it are used to
+        create Backup_location objects and these objects are appended to a list
+        that is returned to caller.
+
+        Arguments:
+        xml_file -- File to parse
+
+        Returns:
+        locations -- List with all Backup_location objects created from file
+
+        """
+        locations_map = self._parser(xml_file)
+        locations = []
+        number_of_locations = len(locations_map["types"])
+        for i in range(number_of_locations):
+            type = locations_map["types"][i]
+            category = locations_map["categories"][i]
+            path = locations_map["paths"][i]
+            path = self._fixPath(path)
+            new_loc = PcsBackupLocation(type, category, path)
+            locations.append(new_loc)
+        return locations
+    
+
+    def _parser(self, xml_file):
+        # Parses the xml_file, divide each location element information on a
+        # dictonary with key to respective information.
+        # Dictonary format:
+        # { "types": list of types in order of location appereance,
+        #   "categories": list of categories ordered like types
+        #   "paths" list of install paths in the same order as the others }
+        dom = xml.dom.minidom.parse(xml_file)
+        types = []
+        categories = []
+        paths = []
+        for node in dom.getElementsByTagName("location"):
+            type = node.getAttribute("type")
+            category = node.getAttribute("category")
+            path = node.childNodes[0].data.strip()
+            types.append(type)
+            categories.append(category)
+            paths.append(path)
+
+        location_map = {"types": types, "categories": categories, "paths": paths}
+        return location_map
+
+    def _fixPath(self, path):
+        # Fix any file path containing device specific constants, modifying
+        # them to its values
+        modifications = {"$HOME":"/home/user", "$USER":"user"}
+        for key in modifications.keys():
+            path = path.replace(key, modifications[key])
+        if not path.startswith("/"):
+            path = "/".join(path)
+        return path
+
diff --git a/src/backup/.svn/text-base/pcsbackuputils.py.svn-base b/src/backup/.svn/text-base/pcsbackuputils.py.svn-base
new file mode 100644 (file)
index 0000000..8dfa7fe
--- /dev/null
@@ -0,0 +1,184 @@
+
+from pcsbackupinfo import *
+import zipfile
+import os
+import xml.dom.minidom
+
+
+def copyOssoBackupConfigFiles(destination, mountPath):    
+    """ Copy all osso-backup .conf files to the given path. The device must be
+    already mounted in the mountPath.
+    
+    Attributes:
+    - String mountPath - Path of the folder where the device is mounted
+    - String destination - Destination folder path where config files should be
+            copied to.
+            
+    """
+    os.system("cp %s/etc/osso-backup/applications/*.conf %s" %
+        (mountPath, destination))
+          
+     
+def mountDevice(user, ip, path):
+    # Mount device file system using sshfs in the given path
+    try:
+        if not os.path.exists(path):
+            createFolder(path)
+        os.system('sshfs %s@%s:/ %s' % (user, ip, path))
+    except:
+        raise Exception("Error while mounting device file system")
+
+
+def unmountDevice(path):
+    try:
+        os.system('fusermount -uz %s' % path)
+    except:
+        raise Exception("Error while unmounting device file system")
+        
+        
+def createFolder(complete_path):
+    if not os.path.exists(complete_path):
+        os.makedirs(complete_path)
+
+    # FIXME
+    return True
+
+
+def removePath(complete_path):
+    for entry in os.listdir(complete_path):
+        if os.path.isdir(entry):
+            removePath(os.path.join(complete_path, entry))
+        else:
+            os.remove(os.path.join(complete_path, entry))
+    os.rmdir(complete_path)
+   
+    
+def getDeviceBackupList(mountPoint):
+    """This function return a list of backupInfo objects for each backup found
+    in the mount point.
+    
+    """
+    deviceBackups = []
+    mmc1 = '%s/media/mmc1/backups' % mountPoint
+    mmc2 = '%s/media/mmc2/backups' % mountPoint
+    
+    if os.path.exists(mmc1):
+        deviceBackups += _getDeviceBackupsInfo(mmc1)
+    if os.path.exists(mmc2):
+        deviceBackups += _getDeviceBackupsInfo(mmc2)
+        
+    return deviceBackups
+        
+        
+def copy(original, destination):
+    original = original.replace(" ", "\ ")
+    destination = destination.replace(" ", "\ ")
+    createFolder(destination)
+    os.system("cp %s %s" % (original, destination))
+
+
+def getSize(path):
+    if not os.path.exists(path):
+        return False
+    if os.path.isdir(path):
+        files_and_folders = os.listdir(path)
+        sum_size = 0
+        for entry in files_and_folders:
+            if os.path.isdir(os.path.join(path, entry)):
+                sum_size += getSize(os.path.join(path, entry))
+            else:
+                try:
+                    sum_size += os.stat(os.path.join(path, entry)).st_size
+                except:
+                    sum_size += 1
+        return sum_size
+    else:
+        return os.stat(path).st_size
+
+        
+def getBackupFilesPath(backupPath):
+    dic = {}
+    for entry in os.listdir(backupPath):
+        if entry.endswith(".zip"):
+            zip = openZip(os.path.join(backupPath, entry))
+            dic[entry.replace(".zip", "")] = zip.namelist()
+    return dic
+
+
+def getBackupCategories(backupInfo):
+    backupPath = str(backupInfo.path)
+    if not backupInfo.fromDevice:
+        backupPath = os.path.join(backupPath, str(backupInfo._name))
+    categoriesList = []
+    for entry in os.listdir(backupPath):
+        if entry.endswith(".zip"):
+            categoriesList.append(entry.replace(".zip", ""))
+    return categoriesList
+
+
+def writeBackupFilesPath(paths_dictionary, file_path):
+    try:
+        file = open(file_path, "w")
+    except:
+        return False
+    for category in paths_dictionary.keys():
+        file.write("[" + category + "]\n")
+        for path in paths_dictionary[category]:
+            file.write(path + "\n")
+    
+    file.close()
+    
+def openZip(zipPath, mode="r"):
+    """ Open a .zip file using python ZipFile library.
+        
+        Attributes:
+            String zipPath - The directory path to the file
+            String mode - "w" to open file for writting.
+                        "a" to open file for appending.
+                        "r" to open file for reading.
+                
+    """
+    try:
+        zip = zipfile.ZipFile(zipPath, mode)
+        return zip
+    except zipfile.BadZipfile, msg:
+        raise IOError("Problem while opening %s: %s" % (zipPath, msg))
+    except:
+        raise
+
+def closeZip(zipfile):
+    zipfile.close()
+    
+def zip(zipfile, path):
+    # Compress the file in the given path to the zipfile
+    try:
+        zipfile.write(path.encode('UTF'))
+        return True
+    except:
+        return False
+    
+def rebootDevice(deviceIp):
+    return os.system("ssh root@%s reboot" % deviceIp) == 0
+    
+
+def _parseMetadata(metadata_path):
+    document = xml.dom.minidom.parse(metadata_path)
+    node = document.getElementsByTagName("size")[0]
+    size = int(str(node.firstChild.nodeValue))
+    node = document.getElementsByTagName("timestamp")[0]
+    objDate = datetime.fromtimestamp(float(str(node.firstChild.nodeValue)))
+    return size, str(objDate)
+
+def _getDeviceBackupsInfo(memoryCardPath):
+    deviceBackups = []
+    for backup in os.listdir(memoryCardPath):
+        temporaryFolder = os.path.join(memoryCardPath, backup)
+        if os.path.isdir(temporaryFolder):
+            metadataPath = os.path.join(temporaryFolder,'backup.metadata')
+            if os.path.exists(metadataPath):
+                size, date = _parseMetadata(metadataPath)
+                backupInfo = PcsBackupInfo(backup, temporaryFolder, size)
+                backupInfo.setDate(date)
+                deviceBackups.append(backupInfo)
+    return deviceBackups
+        
diff --git a/src/backup/.svn/text-base/pcsbackupwizard.py.svn-base b/src/backup/.svn/text-base/pcsbackupwizard.py.svn-base
new file mode 100644 (file)
index 0000000..bd16fc5
--- /dev/null
@@ -0,0 +1,180 @@
+from time import sleep
+import threading
+
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+
+from pcsprogresswizard import *
+from pcscheckboxwizard import *
+from pcsopenfilewizard import *
+from pcspcbackupmanager import *
+from pcsdevicemanager import *
+
+class PcsBackupWizard(QWizard):
+    
+    ''' Class that creates a wizard responsible for doing backup '''
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizard.__init__(self, parent)
+        self.windowManager = windowManager
+        self.deviceInfo = deviceInfo
+        stylesheet = '''QWizard{background-image:url('''+ BACKUP_BG + ''')};'''
+        self.setStyleSheet(stylesheet)       
+        self.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self.setWindowTitle("%s Backup" % APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH,WINDOW_HEIGHT)
+        
+        self.setButtonLayout([])
+        self.setWizardStyle(4)
+        
+        self.checkboxPage = PcsCheckboxWizard(self.deviceInfo, windowManager, self)
+        self.addPage(self.checkboxPage)
+        
+        self.chooseFilePage = PcsOpenFileWizard(self.deviceInfo, windowManager, self)
+        self.connect(self.chooseFilePage.finishButton, SIGNAL("clicked()"), 
+                     self.noNameTest)
+        self.addPage(self.chooseFilePage)
+        
+        self.progressWizard = PcsProgressWizard(self.deviceInfo,self, windowManager, self)
+        self.connect(self.progressWizard.cancelButton, SIGNAL("clicked()"), 
+                     self._confirmsCancel)
+        self.connect(self.progressWizard.doneButton, SIGNAL("clicked()"), self._done)
+        self.connect(self.progressWizard, SIGNAL("destroyed()"), self.test)
+        self.addPage(self.progressWizard)
+    
+    def test(self):
+        print "entrou caraiiiiii"
+    
+    def noNameTest(self):
+        if(str(self.chooseFilePage.getBackupName()).strip() == ""):
+            message = "Your backup name can't be blank."
+            showMessageBox(message, "Backup name blank")
+        else:
+            self.doNewBackup()
+            self.next()
+    
+    def _done(self):
+        self.done(0)
+        self.progressWizard._resetPage()
+        self.chooseFilePage._resetPage()
+    
+    def doNewBackup(self):
+        
+        hostIp = self.deviceInfo.ip
+        backupName = self.chooseFilePage.getBackupName()
+        backupPath = self.chooseFilePage.getPath()
+        categories = self.checkboxPage.getCategories()
+        self.backupManager = PcsPcBackupManager()
+        self.backupManager.loadBackups()
+        comments = ""
+        
+        self._updateThread = UpdateBackupProgress(backupName, backupPath, 
+                                                  hostIp,categories, comments, 
+                                                  self.backupManager, 
+                                                  self.progressWizard)
+        self.connect(self._updateThread, SIGNAL("backupFinished"),
+                      self._onBackupDone)        
+        self.connect(self._updateThread, SIGNAL("backupCanceled"),
+                      self._onBackupCancel)
+        self.connect(self._updateThread, SIGNAL("backupNameChanged"),
+                      self._onBackupNameChanged)
+        self.connect(self._updateThread, SIGNAL("backupProgress"),
+                      self._updateCategoriesAndProgress)
+        
+        self._updateThread.start()
+        
+    def _updateCategoriesAndProgress(self, information):
+        progress, category = information
+        self.progressWizard.setProgress(progress)
+        self.progressWizard.setCategory(category)
+        
+        
+    def _onBackupDone(self, info):
+        self.progressWizard.updateInfo(info[0], info[1])
+        self.progressWizard.progressDone()
+        self.windowManager.getBackupManager().pcListView.updateBackupList()
+
+    def _onBackupNameChanged(self, correct_name):
+        """
+        Check if backup name was changed and show message case positive.
+        """
+        nameChangeMessage = "Backup with same name was found in" + \
+                                    " backup list, Backup name changed to %s" \
+                                     % correct_name
+        showMessageBox(nameChangeMessage, "Backup name changed")
+    
+    def _confirmsCancel(self):
+        """
+        Confirms the backup canceling.
+        """
+        dialog = QMessageBox()
+        dialog.setText("Do you really want cancel this backup?")
+        dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+        dialog.setWindowFlags(Qt.FramelessWindowHint)
+        dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
+        ret = dialog.exec_()
+        if ret == QMessageBox.Yes:
+            self._onBackupCancel()
+    
+    def _onBackupCancel(self):
+        """
+        Stops current backup process in backup manager.
+        Also, shows a message box informing about canceling.
+        
+        """
+        self.progressWizard.progressCanceled()
+        self.backupManager.setBackupInProgress(False)
+        
+    def setVisible (self, visible):
+        if(visible == False):
+            self.emit("")
+                
+        
+class UpdateBackupProgress(QThread):
+    
+    def __init__(self, backupName, path, hostIp, categories, comment, 
+                 backupManager, progressWizard):
+        QThread.__init__(self)
+
+        self.backupName = backupName
+        self.path = path
+        self.hostIp = hostIp
+        self.categories = categories
+        self.comment = comment
+        self.backupManager = backupManager
+        
+        
+    def run(self):
+        self._backupFlag = True
+        
+        self.correctName = self.backupManager._verify_backup_name(self.backupName)
+        self.nameChanged = self.correctName != self.backupName
+        
+        self.connect(self.backupManager, SIGNAL("backupProgress"), self._reEmitSignal)
+        self.connect(self.backupManager, SIGNAL("backupDone"), self._onBackupDone)
+        res = self.backupManager.createBackup(self.correctName, self.path,
+                                         self.hostIp, self.categories, 
+                                         self.comment)
+        
+        while (self._backupFlag):
+            sleep(0.1)
+            
+    def _reEmitSignal(self, informations):
+        self.emit(SIGNAL("backupProgress"), informations)
+    
+    def _onBackupDone(self, res, info):
+        self._backupFlag = False
+        # If backup was not canceled, emit done signal
+        if res != 0:
+            if self.nameChanged:
+                self.emit(SIGNAL("backupNameChanged"), self.correctName)
+            self.emit(SIGNAL("backupFinished"), info)
+        else:
+            self.emit(SIGNAL("backupCanceled"))
+
+        
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsbackupxml.py.svn-base b/src/backup/.svn/text-base/pcsbackupxml.py.svn-base
new file mode 100644 (file)
index 0000000..0bf3905
--- /dev/null
@@ -0,0 +1,87 @@
+'''
+@author: Nicholas Alexander
+
+Created on 07/07/2009
+
+Module with functions used to create backup metadata xml file with same format
+as osso-backup metadata.
+
+'''
+import os
+
+import xml.dom.minidom
+
+from backup.pcsbackuputils import getSize
+from pcsdevicemanager import PcsDeviceManager
+
+
+def createXml(backup_info, filesByCategory, host_ip):
+    doc = xml.dom.minidom.Document()
+    root = doc.createElement("backup-metadata")
+    doc.appendChild(root)
+    _appendSizeNode(backup_info, doc, root)
+    _appendFilesNumberNode(backup_info, doc, root)
+    _appendTimeNode(backup_info, doc, root)
+    _appendProtectedNode(doc, root)
+    _appendDeviceInfoNode(doc, root, host_ip)
+    backupFullPath = os.path.join(backup_info.getPath(), backup_info.getName())
+    _appendCategoriesNode(doc, root, filesByCategory, backupFullPath)
+    metadata_path = os.path.join(backupFullPath, "backup.metadata")
+    file = open(metadata_path, "w")
+    doc.writexml(file)
+    file.close()
+
+
+
+def _appendSizeNode(backupInfo, document, node):
+    sizeNode = document.createElement("size")
+    size = document.createTextNode(str(backupInfo.getSize()))
+    sizeNode.appendChild(size)
+    node.appendChild(sizeNode)
+    
+def _appendFilesNumberNode(backupInfo, document, node):
+    filesNode = document.createElement("number-of-files")
+    files = document.createTextNode(str(backupInfo.getFilesNumber()))
+    filesNode.appendChild(files)
+    node.appendChild(filesNode)
+    
+def _appendTimeNode(backupInfo, document, node):
+    timeNode = document.createElement("timestamp")
+    time = document.createTextNode(str(int(backupInfo.getTime())))
+    timeNode.appendChild(time)
+    node.appendChild(timeNode)
+
+def _appendProtectedNode(document, node):
+    protectedNode = document.createElement("protected")
+    protected = document.createTextNode("false")
+    protectedNode.appendChild(protected)
+    node.appendChild(protectedNode)
+    
+def _appendDeviceInfoNode(document, node, hostIp):
+    deviceManager = PcsDeviceManager()
+    deviceManager.loadDevices()
+    device = deviceManager.getDevice(hostIp)
+    versionNode = document.createElement("device-version")
+    version = document.createTextNode(device.ossoBackup)
+    versionNode.appendChild(version)
+    node.appendChild(versionNode)
+    
+def _appendCategoriesNode(document, node, filesByCategory, backupPath):
+    categories = document.createElement("categories")
+    for category in filesByCategory.keys():
+        categoryPath = os.path.join(backupPath, "%s.zip" % category)
+        size = getSize(categoryPath)
+        if size == False:
+            continue
+        categoryNode = document.createElement("%s" % category)
+        categorySize = document.createElement("size")
+        categoryFiles = document.createElement("number-of-files")
+        filesText = document.createTextNode(str(filesByCategory[category]))
+        sizeText = document.createTextNode(str(size))
+        categorySize.appendChild(sizeText)
+        categoryFiles.appendChild(filesText)
+        categoryNode.appendChild(categorySize)
+        categoryNode.appendChild(categoryFiles)
+        categories.appendChild(categoryNode)
+    node.appendChild(categories)
+        
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcscheckboxwizard.py.svn-base b/src/backup/.svn/text-base/pcscheckboxwizard.py.svn-base
new file mode 100644 (file)
index 0000000..7745894
--- /dev/null
@@ -0,0 +1,292 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsbutton import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcscustombuttons import PcsCustomButton as customButton
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+
+class PcsCheckboxWizard(QWizardPage):
+       
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        self.deviceInfo = deviceInfo
+        self.windowManager = windowManager
+        
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.layout.setSpacing(0)
+        buttonsLayout = self._menuButtons()
+        self.layout.addLayout(buttonsLayout)
+        self.layout.addItem(QSpacerItem(0, 8))
+        wayLayout = self._wayLayout()
+        self.layout.addLayout(wayLayout)
+
+        self.layout.addItem(QSpacerItem(0, 10))
+
+        self.hlayout = QHBoxLayout()
+        self.hlayout.setMargin(0)
+        
+        self.vertical = QVBoxLayout()
+        self.vertical.setMargin(0)
+        self.vertical.setSpacing(0)
+        self.create_vertical_components()
+        self.hlayout.addLayout(self.vertical)
+        self.hlayout.setMargin(0)
+        self.hlayout.setSpacing(0)
+        
+        self.create_checkbox_frame()
+#        self.hlayout.addItem(QSpacerItem(30, 0))
+        self.layout.addLayout(self.hlayout)
+        
+        self.layout.addItem(QSpacerItem(0, 35))
+        informationLayout = QHBoxLayout()
+        informationLayout.setMargin(0)
+        spc = QSpacerItem(10, 0)
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        information = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Select the types of file you wish to backup.</font>")
+        informationLayout.addItem(spc)
+        informationLayout.addWidget(iconAlert)
+        informationLayout.addWidget(information, Qt.AlignLeft)
+
+        self.layout.addLayout(informationLayout)
+        
+        self.setLayout(self.layout)
+        self.map_checked = {self.documents.name: False,
+                            self.emails.name: False, self.media.name: False,
+                            self.contacts.name: False, 
+                            self.bookmarks.name: False,
+                            self.settings.name: False, 
+                            self.applications.name: False}
+        self.enableNext = QLineEdit()
+        self.registerField("enableNext*", self.enableNext)
+    
+    def _wayLayout(self):
+        barLayout = QHBoxLayout()
+        barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow = self._arrow()
+        arrow2 = self._arrow()
+        spc = QSpacerItem(5, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #FFFFFF'; size=2>Files</font>")
+        widgetList = [main, arrow, newBackup, arrow2, files]
+        for widget in widgetList:
+            barLayout.addWidget(widget, Qt.AlignLeft)
+            barLayout.addItem(spc)
+        barLayout.addItem(QSpacerItem(300, 0))
+        return barLayout
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label
+            
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout   
+    
+    def _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.wizard().geometry())
+            backupManager.show()
+            self.wizard().close()
+            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.wizard().geometry())
+            restoreBackup.show()
+            self.wizard().close()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    def _goNextPage(self):
+        if self.empty_map():
+            return False
+        else:
+            self.wizard().next()
+    
+    
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def create_checkbox_frame(self):
+        layout = QVBoxLayout()
+        l = QLabel()
+        l.setPixmap(QPixmap(COPY_BORDER))
+       
+        self.frame = QScrollArea(self)
+        self.frame.setWidgetResizable(True)
+        widget = QWidget(self.frame)
+        widget.setStyleSheet("QWidget{background: transparent;}")
+        self.grid = QGridLayout()
+        self.grid.setSpacing(0)
+        self.createCheckboxPanel()
+        widget.setLayout(self.grid)
+        self.frame.setWidget(widget)
+        layout.addItem(QSpacerItem(0,25))
+        layout.addWidget(self.frame)
+        self.hlayout.addLayout(layout)
+        
+    
+    def empty_map(self):
+        for index in self.map_checked.keys():
+            if self.map_checked[index]:
+                return False
+        return True
+        
+    def createCheckboxPanel(self):
+        #Add Checkboxes
+#        self.add_select_all()
+        self.add_documents()
+        self.add_emails()
+        self.add_media()
+        self.add_contacts()
+        self.add_bookmarks()
+        self.add_settings()
+        self.add_applications()            
+        
+#    def add_select_all(self):
+#        self.select_all = QCheckBox("Select All")
+#        self.connect(self.select_all, SIGNAL("stateChanged(int)"), 
+#                     self.select_all_func)
+#        self.grid.addWidget(self.select_all, 0, 0, Qt.AlignTop)          
+#    
+    def add_documents(self):
+        self.documents = QCheckBox("Documents")
+        self.documents.name = "documents"
+        callback = partial(self.select_func, self.documents)
+        self.connect(self.documents, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.documents, 1, 0, Qt.AlignTop)
+    
+    def add_emails(self):
+        self.emails = QCheckBox("Emails")
+        self.emails.name = "emails"
+        callback = partial(self.select_func, self.emails)
+        self.connect(self.emails, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.emails, 2, 0, Qt.AlignTop)
+    
+    def add_media(self):
+        self.media = QCheckBox("Media")
+        self.media.name = "media"
+        callback = partial(self.select_func, self.media)
+        self.connect(self.media, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.media, 3, 0, Qt.AlignTop)
+    
+    def add_contacts(self):
+        self.contacts = QCheckBox("Contacts")
+        self.contacts.name = "contacts"
+        callback = partial(self.select_func, self.contacts)
+        self.connect(self.contacts, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.contacts, 4, 0, Qt.AlignTop)
+    
+    def add_bookmarks(self):
+        self.bookmarks = QCheckBox("Bookmarks")
+        self.bookmarks.name = "bookmarks"
+        callback = partial(self.select_func, self.bookmarks)
+        self.connect(self.bookmarks, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.bookmarks, 5, 0, Qt.AlignTop)
+        
+    def add_settings(self):
+        self.settings = QCheckBox("Settings")
+        self.settings.name = "settings"
+        callback = partial(self.select_func, self.settings)
+        self.connect(self.settings, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.settings, 6, 0, Qt.AlignTop)
+
+    def add_applications(self):
+        self.applications = QCheckBox("Applications")
+        self.applications.name = "applications"
+        callback = partial(self.select_func, self.applications)
+        self.connect(self.applications, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.applications, 7, 0, Qt.AlignTop)
+
+#    def select_all_func(self):
+#        checked = self.select_all.isChecked()
+#        list = self.map_checked.keys()
+#        for element in list:
+#            self.map_checked[element] = checked
+#        for i in range(1,8):
+#            self.grid.itemAtPosition(i, 0).widget().setChecked(checked)
+#        
+    def select_func(self, checkbox):
+        checked = checkbox.isChecked()
+        self.map_checked[checkbox.name] = checked
+        if not checked:
+            list = []
+            for i in range(1,8):
+                item = self.grid.itemAtPosition(i, 0).widget()
+#                if item == self.select_all:
+#                    pass
+                if item.isChecked():
+                    list.append(item)
+#            self.select_all.setChecked(False)
+            for element in list:
+                element.setChecked(True)         
+        if self.empty_map():
+            self.enableNext.setText("")
+        else:
+            self.enableNext.setText("Next Button Enabled")
+            
+    def getCategories(self):
+        return self.map_checked
+        
+    def create_vertical_components(self):
+        deviceWidget = PcsDeviceWidget(2)
+        deviceWidget.setImage(DEVICE_DISCONNECTED)
+        deviceWidget.addBorder()
+        deviceWidget.addDeviceName()
+        deviceWidget.setDeviceInfo(self.deviceInfo)
+        self.vertical.addWidget(deviceWidget, Qt.AlignTop)
+        self.nextButton = QPushButton()
+        self.nextButton.setText("Next")
+        self.nextButton.setStyleSheet(BACKUP_BUTTON_STYLE)
+        self.connect(self.nextButton, SIGNAL("clicked()"), self._goNextPage)
+        self.vertical.addItem(QSpacerItem(0, 20))
+        buttonLayout = QHBoxLayout()
+        buttonLayout.addItem(QSpacerItem(5,0))
+        buttonLayout.addWidget(self.nextButton, Qt.AlignCenter)
+        self.vertical.addLayout(buttonLayout)
+        self.vertical.addItem(QSpacerItem(0,10))
+        
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsdevicebackupmanager.py.svn-base b/src/backup/.svn/text-base/pcsdevicebackupmanager.py.svn-base
new file mode 100644 (file)
index 0000000..095bfd7
--- /dev/null
@@ -0,0 +1,102 @@
+
+from pcsbackupmanager import *
+from pcspcbackupmanager import PcsPcBackupManager
+from pcsbackupinfo import PcsBackupInfo
+import pcsbackuputils as utils
+
+
+class PcsDeviceBackupManager(PcsBackupManager):
+
+
+    def __init__(self, deviceInfo):
+        PcsBackupManager.__init__(self)
+        self._backupList = []
+        self._deviceInfo = deviceInfo
+        self.restoreInProgress = False
+        self.copyInProgress = False
+
+    def loadBackups(self):
+        
+        # FIXME, error handling is wrong!! return list of PcsBackupInfo
+        try:
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % self._deviceInfo.ip)
+            utils.mountDevice(USER_HOST, self._deviceInfo.ip, mountPoint)
+            
+            self._backupList = utils.getDeviceBackupList(mountPoint)
+            return True
+
+        except Exception, x:
+            print str(x)
+        finally:
+            utils.unmountDevice(mountPoint)  
+            
+        return False          
+    def getBackupList(self):
+        self.loadBackups()
+        for backup in self._backupList:
+            backup.setAtDevice(True)
+        return self._backupList
+    
+    def copyBackupFromDevice(self, backupName, destinationPath):
+        try:
+            self.loadBackups()
+            device_backups = self.getBackupList()
+            
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % self._deviceInfo.ip)
+            utils.mountDevice(USER_HOST, self._deviceInfo.ip, mountPoint)
+    
+            # Search complete_path
+            completePath = ''
+            for backup in device_backups:
+                if backupName == backup.getName():
+                    completePath = backup.getPath()
+                    break
+            if completePath == '':
+                raise Exception("Backup not found.")
+            
+            pcBackupManager = PcsPcBackupManager()
+            pcBackupManager.loadBackups()
+            correctName = pcBackupManager._verify_backup_name(backupName)
+            destination = os.path.join(destinationPath, correctName)
+            
+            self.setCopyInProgress(True)
+            if self.copy(completePath, destination) == 0:
+                return 0
+            self.setCopyInProgress(False)
+            
+            backup_size = utils.getSize(destination)
+            backup = PcsBackupInfo(correctName, destinationPath, backup_size, 
+                                   'Copied from device')
+            backup.setAtDevice(False)
+            pcBackupManager._backupList.append(backup)
+            pcBackupManager.saveBackups()
+            
+        finally:
+            utils.unmountDevice(mountPoint)
+            
+            
+    def startBackupRestore(self, backupInfo, categories):
+        device_ip = self._deviceInfo.ip
+        return self.restoreBackup(backupInfo, device_ip, categories)
+    
+    
+    def setCopyInProgress(self, status):
+        self.copyInProgress = status
+        
+        
+    def setRestoreInProgress(self, status):
+        self.restoreInProgress = status
+        
+
+    def getBackupInfo(self, backupName):
+        self.loadBackups()
+        for backupInfo in self._backupList:
+            if backupInfo.getName() == backupName:
+                backupInfo.setAtDevice(True)
+                return backupInfo
+            
+        return None
+    
+            
+        
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsopenfilewizard.py.svn-base b/src/backup/.svn/text-base/pcsopenfilewizard.py.svn-base
new file mode 100644 (file)
index 0000000..313aac4
--- /dev/null
@@ -0,0 +1,264 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+import os
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+from style.styleTabletSuite import *
+
+
+class PcsOpenFileWizard(QWizardPage):
+    
+    _home_dir = os.path.expanduser("~")
+    _default_dir = _home_dir + "/.pcsuite/Backup"
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        
+        self.path = self._default_dir
+        self.file_name = "Backup"
+        self.deviceInfo = deviceInfo
+        self.windowManager = windowManager
+        
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.hLayout = QHBoxLayout()
+        self.hLayout.setMargin(0)
+        self.vLayout = QVBoxLayout()
+        self.vLayout.setMargin(0)
+        
+        wayLayout = self._wayLayout()
+        
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        spc = QSpacerItem(0, 12)
+        self.vLayout.addLayout(wayLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        self.vLayout.addItem(spc)
+        spc2 = QSpacerItem(350, 0)
+        self.finishButton = QPushButton("Finish")
+        self.finishButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.finishButton.setShortcut(Qt.Key_Return)
+        self.hLayout.addItem(spc2)
+        self.hLayout.addWidget(self.finishButton)
+        self.vLayout.addLayout(self.hLayout)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    def _wayLayout(self):
+        barLayout = QHBoxLayout()
+        barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow = self._arrow()
+        arrow2 = self._arrow()
+        arrow3 = self._arrow()
+        spc = QSpacerItem(2, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #333333'; size=2>Files</font>")
+        folder = QLabel("<font style='color: #FFFFFF'; size=2>Folder</font>")
+        widgetList = [main, arrow, newBackup, arrow2, files, arrow3, folder]
+        for widget in widgetList:
+            barLayout.addWidget(widget, Qt.AlignLeft)
+            barLayout.addItem(spc)
+        barLayout.addItem(QSpacerItem(300, 0))
+        return barLayout
+    
+    def _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.wizard().geometry())
+            backupManager.show()
+            self.wizard().close()
+            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.wizard().geometry())
+            restoreBackup.show()
+            self.wizard().close()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label   
+     
+    def _createDeviceWidget(self):
+        deviceWidget = PcsDeviceWidget(3)
+        deviceWidget.addBorder()
+        deviceWidget.addDeviceName()
+        deviceWidget.setDeviceInfo(self.deviceInfo)
+
+        return deviceWidget
+    
+    def _createInformationsLabel(self):
+        hLay = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        infLabel = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Do backup from Device to your PC.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(infLabel, Qt.AlignLeft)
+        
+        
+        return hLay
+
+    def _createCenterLayout(self):
+        hLay = QHBoxLayout()
+        hLay.setMargin(0)
+        vLay = QVBoxLayout()
+        vLay.setMargin(0)
+        hLayWithSpacer = QHBoxLayout()
+        hLayWithSpacer.setMargin(0)
+        spc = QSpacerItem(62, 0)
+        
+        deviceWidget = self._createDeviceWidget()
+        arrowLabel = self._createArrowLabel()
+        pcLabel = self._createPcLabel()
+        pathField = self._createPathField()
+        nameField = self._createBackupNameField()
+        
+        hLay.addWidget(deviceWidget, Qt.AlignVCenter)
+        hLay.addLayout(arrowLabel, Qt.AlignVCenter)
+        hLay.addLayout(pcLabel, Qt.AlignVCenter)
+        
+        vLay.addLayout(nameField)
+        vLay.addLayout(hLay)
+        vLay.addLayout(pathField)
+        
+        hLayWithSpacer.addItem(spc)
+        hLayWithSpacer.addLayout(vLay)
+        hLayWithSpacer.addItem(spc)
+        
+        return hLayWithSpacer
+
+    def _createArrowLabel(self):
+        arrowLayout = QGridLayout()
+        arrowLabel = QLabel()
+        arrowLabel.setPixmap(QPixmap(LARGE_ARROW_IMAGE))
+        borderArrowLabel = QLabel()
+        borderArrowLabel.setFixedSize(42, 65)
+        borderArrowLabel.setPixmap(QPixmap(LARGE_ARROW_BORDER))
+        arrowLayout.addWidget(arrowLabel, 0, 0, Qt.AlignCenter)
+        arrowLayout.addWidget(borderArrowLabel, 0, 0, Qt.AlignCenter)
+        return arrowLayout
+
+    def _createPcLabel(self):
+        gridLay = QGridLayout()
+        pcLabelLayout = QGridLayout()
+        pcLabel = QLabel()
+        pcLabel.setPixmap(QPixmap(PC_IMAGE))
+        pcBorder = QLabel()
+        pcBorder.setFixedSize(112, 127)
+        pcBorder.setPixmap(QPixmap(PC_BORDER_FILE))
+        nameLabel = QLabel("PC")
+        nameBorder = QLabel()
+        nameBorder.setPixmap(QPixmap(PC_NAME_BORDER_FILE))
+        nameBorder.setFixedSize(92, 26)
+        gridLay.addWidget(pcLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addWidget(nameLabel, 1, 0, Qt.AlignCenter)
+        gridLay.addWidget(nameBorder, 1, 0, Qt.AlignCenter)
+        pcLabelLayout.addLayout(gridLay, 0, 0, Qt.AlignCenter)
+        pcLabelLayout.addWidget(pcBorder, 0, 0, Qt.AlignCenter)
+        return pcLabelLayout
+
+    def _createPathField(self):
+        pathLayout = QHBoxLayout()
+        self.pathField = QLineEdit()
+        self.pathField.setReadOnly(True)
+        self.pathField.setText(self._default_dir)
+        self.pathField.setObjectName("pathField")
+        buttonBrowse = QPushButton()
+        buttonBrowse.setObjectName("buttonBrowse")
+        self.connect(buttonBrowse, SIGNAL("clicked()"), self._openFileDialog)
+        pathLayout.addWidget(self.pathField)
+        pathLayout.addWidget(buttonBrowse)
+        
+        borderLabel = QLabel()
+        borderLabel.setPixmap(QPixmap(PATH_BG))
+        borderLabel.setFixedSize(304, 40)
+        gridLay = QGridLayout()
+        gridLay.addWidget(borderLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addLayout(pathLayout, 0, 0, Qt.AlignCenter)
+        
+        return gridLay
+        
+    def _createBackupNameField(self):
+        label = QLabel("Backup Name:")
+        backupNameLayout = QHBoxLayout()
+        backupNameLayout.addWidget(label)
+        self.backupNameField = QLineEdit()
+        self.backupNameField.setObjectName("backupNameField")
+        self.backupNameField.setText("Backup")
+        backupNameLayout.addWidget(self.backupNameField, 
+                                          Qt.AlignHCenter)
+        borderLabel = QLabel()
+        borderLabel.setPixmap(QPixmap(BACKUP_NAME_BG))
+        borderLabel.setFixedSize(304, 40)
+        gridLay = QGridLayout()
+        gridLay.addWidget(borderLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addLayout(backupNameLayout, 0, 0, Qt.AlignCenter)
+        
+        return gridLay
+      
+    def _openFileDialog(self):
+        pathDialog = QFileDialog()
+        prompt = "Select the folder you wish to save your backup"
+        self.path = pathDialog.getExistingDirectory(self, prompt, 
+                                                     self._default_dir)
+        if self.path != "":
+            self.pathField.setText(self.path)
+        
+    def _resetPage(self):
+        self.path = self._default_dir
+        self.pathField.setText(self._default_dir)
+        self.backupNameField.setText("Backup")
+    
+    def getBackupName(self):
+        return str(self.backupNameField.text())
+    
+    def getPath(self):
+        return str(self.pathField.text())
+    
diff --git a/src/backup/.svn/text-base/pcspcbackupmanager.py.svn-base b/src/backup/.svn/text-base/pcspcbackupmanager.py.svn-base
new file mode 100644 (file)
index 0000000..35bcfe3
--- /dev/null
@@ -0,0 +1,475 @@
+# low_backup_manager module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+# Backup_manager class:
+#    Class responsible for backup functions like creating and removing backups
+
+import os.path
+import os
+import zlib
+import pickle
+
+from PyQt4.QtCore import *
+from zipfile import *
+
+from pcsbackupparser import *
+from pcsbackupinfo import *
+from pcsbackupmanager import *
+from pcsbackupxml import *
+
+import pcsbackuputils as utils
+
+HOME = os.path.expanduser("~")
+BACKUP_FILES_PATH = os.path.join(HOME, ".pcsuite/Backup")
+DEFAULT_CONFIG_PATH = "%s/.pcsuite/config" % HOME
+BACKUPS_FILE = os.path.join(HOME, ".pcsuite/Backup/.backups")
+
+
+class PcsPcBackupManager(PcsBackupManager):
+
+    def __init__(self):
+        PcsBackupManager.__init__(self)
+        self._backupList = []
+        self.backupInProgress = False
+        self.restoreInProgress = False
+        self.copyInProgress = False
+        
+        self.myDocsPath = "Root/home/user/MyDocs/"
+        self.backupPath = ""
+        self.currentCategory = ""
+        self.totalSize = 0
+
+    def loadBackups(self):
+        # 'XX Loading the backup list available in the PC'
+        try:
+            if os.path.exists(BACKUPS_FILE):
+                file = open(BACKUPS_FILE)
+                self._backupList = pickle.load(file)
+                file.close()
+        except IOError:
+            print "IOError while loading the PC backups"
+            # FIXME
+            #raise Exception("Error while reading backups")
+            return False
+        
+        return True
+        
+    def saveBackups(self):
+        # 'XX Saving the backup list in the config file'
+        try:
+            obj = self._backupList
+            file = open(BACKUPS_FILE, "w")     
+            pickle.dump(obj, file)
+            file.close()
+        except:
+            #raise Exception("Error while saving backups")
+            return False
+        
+        return True
+
+    def getBackupList(self):
+        """Return a list with the name of all done backups. """
+        self.loadBackups()
+        return self._backupList[:]
+    
+    def createBackup(self, backup_name, path, host_ip, categories, comment=""):
+        self.backupThread = NewBackupThread(self, backup_name, path, host_ip, 
+                                            categories, comment)
+        self.backupThread.start()
+        
+
+    def renameBackup(self, backupName, newName):
+        self.loadBackups()
+
+        backupInfo = self.getBackupInfo(backupName)
+        if backupInfo != None:
+            try:
+                old = os.path.join(str(backupInfo.getPath()), str(backupName))
+                new = os.path.join(str(backupInfo.getPath()), str(newName))
+                os.rename(old, new)
+                backupInfo.setName(newName)
+            except:
+                print "Error while changing backup name"
+                return False
+        else:
+            # "Backup not found"
+            return False
+            
+        self.saveBackups()
+        return True
+    
+    def removeBackup(self, backupName):
+        """
+            Remove a backup from pc and from _backupList.
+        """
+        self.loadBackups()
+        backupInfo = self.getBackupInfo(backupName)
+        completePath = os.path.join(str(backupInfo.getPath()), 
+                                    str(backupInfo.getName()))
+        if os.path.exists(completePath):
+            utils.removePath(completePath)
+        self._backupList.remove(backupInfo)
+        self.saveBackups()
+        
+        return True
+    
+    def copyBackupToDevice(self, deviceIp, backupName, memoryStick):
+        """ Copy a backup in the PC to some memory card inside the chosen device.
+            
+            Attributes:
+            String deviceIp - String with ip address of device.
+            String backupName - Name of backup to be copied.
+            Int memoryStick - Integer representing which memory stick backup
+                                should be copied to.
+                                0 - Removable memory stick
+                                1 - Internal memory stick
+        """
+        try:
+            self.loadBackups()
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % deviceIp)
+            utils.mountDevice(USER_HOST, deviceIp, mountPoint)
+            
+            backup = self.getBackupInfo(backupName)
+            backupPath = os.path.join(str(backup.getPath()), str(backupName))
+            if memoryStick != 0 and memoryStick != 1:
+                return -1
+            destination = os.path.join(mountPoint, 'media/mmc%s' % 
+                                       (memoryStick+1), 'backups', backupName)
+            
+            self.setCopyInProgress(True)
+            if self.copy(backupPath, destination) == 0:
+                return 0
+            self.setCopyInProgress(False)
+        finally:
+            utils.unmountDevice(mountPoint)
+
+    
+    def getBackupInfo(self, backupName):
+        for backupInfo in self._backupList:
+            if backupInfo.getName() == backupName:
+                return backupInfo
+        return None
+    
+    def startBackupRestore(self, backupInfo, device_ip, categories):
+        return self.restoreBackup(backupInfo, device_ip, categories)
+    
+    def setCopyInProgress(self, status):
+        self.copyInProgress = status
+    
+    def setBackupInProgress(self, status):
+        self.backupInProgress = status
+        
+        
+    def setRestoreInProgress(self, status):
+        self.restoreInProgress = status
+        
+    # FIXME: rewrite this method. Add error handling, some more reliable code
+    def _runCreateBackup(self, backup_name, path, host_ip, categories, comment=""):
+        """Create a backup and add it to _backupList.
+
+        Backup all files and directories of categories chosen. The device
+        system file is mounted on PC and them files are compressed in a zip
+        format. All zip files from each category are saved in the given path.
+
+        Arguments:
+        backup_name -- Backup's name. This name will be the name of the backup
+            folder.
+        path -- Location to save Backup file
+        host_ip -- The device IP address.
+        categories -- A python dictonary where the keys are the categories from
+            osso-backup, and the value can be either True or False, to identify
+            which categories to backup.
+        comment -- Any comment about the backup. It will be saved in Backup
+            object.
+            
+        """
+           
+        backupInfo = None
+        self.setBackupInProgress(True)
+        self.currentCategory = ""
+         
+        try:
+            # Mount device folders
+            self.loadBackups()
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % host_ip)
+            utils.mountDevice(USER_HOST, host_ip, mountPoint)
+            
+            # Create backup folder in the given path
+            self.backupPath = os.path.join(str(path), backup_name)
+            self._createBackupFolder(self.backupPath)
+            
+            # Copying osso-backup configuration files to TabletSuite folder and
+            # parsing backup information from these files.
+            # ( Information = which paths should be in each backup category)
+            utils.copyOssoBackupConfigFiles(DEFAULT_CONFIG_PATH, mountPoint)
+            xmlParser = PcsBackupParser()
+            xmlParser.fillLocationsDict(DEFAULT_CONFIG_PATH)
+            backupItemDict = xmlParser.getLocationsDict()
+            
+            # Changing work directory to ease file search. Keeping previous
+            # folder to come back after backup process.
+            current_dir = os.getcwd()
+            workPath = DEVICES_POINT + str(host_ip)
+            os.chdir(workPath)
+
+            # Computing total size that this backup will have.
+            self.totalSize = self._getTotalSize(backupItemDict, categories)
+            
+            
+            # Start backup process. Create backup of paths for each locations
+            # category
+            self.backedUpNumber = 0
+            filesByCategory = {}
+            for category in backupItemDict.keys():
+                self.currentCategory = category
+                
+                for backupItem in backupItemDict[category]:
+                    self._emitProgress()
+                    # If current backupInfo category is valid and it's value is 
+                    # True in categories dictionary, add it to current backup. 
+                    if (category in categories) and (categories[category]):
+                        categoryFilesNumber = 0
+                        categoryFile = os.path.join(self.backupPath, 
+                                                    category + '.zip')
+
+                        if os.path.exists(categoryFile):
+                            zipfile = utils.openZip(categoryFile, 'a')
+                        else:
+                            zipfile = utils.openZip(categoryFile, 'w')
+
+                        objPath = backupItem.path.replace('/','Root/',1)
+                        backupFolder = os.path.join(workPath, objPath)
+                        categoryFilesNumber = self.zipFolder(backupFolder,
+                                                              zipfile, objPath,
+                                                               category)
+                        if categoryFilesNumber == -1:
+                            os.chdir(current_dir)
+                            return 0
+                        self.backedUpNumber += categoryFilesNumber
+                        self._emitProgress()
+                        
+                        # Update the filesByCategory dictionary with the 
+                        # current number of files from current category that 
+                        # were already copied.
+                        self._updateCategoryCount(filesByCategory, category, 
+                                                  categoryFilesNumber)
+                        utils.closeZip(zipfile)
+                        # If category had no file to copy remove its folder
+                        if int(utils.getSize(categoryFile) == 0):
+                            os.remove(categoryFile)
+            
+                
+            # Copying media files from device user folder if media category is
+            # True in categories dictionary.
+            if ("media" in categories) and (categories["media"]):
+                self.currentCategory = "media"
+                result = self._backupMedias(workPath)
+                if result == -1:
+                    os.chdir(current_dir)
+                    return 0
+                # Update backup files number count
+                self.backedUpNumber += result
+                self._updateCategoryCount(filesByCategory, "media", result)
+                zipPath = os.path.join(self.backupPath,'media.zip')
+                if int(utils.getSize(zipPath) == 0):
+                    os.remove(zipPath)
+            
+            
+            # Copying documents files from device user folder if documents
+            # category is True in categories dictionary.
+            if ("documents" in categories) and (categories["documents"]):
+                self.currentCategory = "documents"
+                result = self._backupDocuments(workPath)
+                # Update backup files number count
+                self.backedUpNumber += result
+                if result == -1:
+                    os.chdir(current_dir)
+                    return 0
+                self._updateCategoryCount(filesByCategory, "documents", 
+                                          result)
+                zipPath = os.path.join(self.backupPath, 'documents.zip')
+                if int(utils.getSize(zipPath) == 0):
+                    os.remove(zipPath)          
+                
+                
+            # Change to previous work directory
+            os.chdir(current_dir)
+           
+            if self.backedUpNumber == 0:
+                utils.removePath(self.backupPath)
+                return -1
+            
+            # Create Backup Object, add it to this manager backup list and save
+            # the list in the backup file.
+            backup_size = utils.getSize(self.backupPath)
+            backupInfo = PcsBackupInfo(backup_name, path, backup_size, comment)
+            backupInfo.setFilesNumber(self.backedUpNumber)
+            self._backupList.append(backupInfo)
+            self.saveBackups()
+            
+            createXml(backupInfo, filesByCategory, host_ip)
+            self.setBackupInProgress(False)
+        finally:
+            utils.unmountDevice(mountPoint)
+            
+        return backupInfo
+    
+    
+    def _backupDocuments(self, workPath):
+        """ Create backup of documents files in user folder. """
+        categoryFilesNumber = 0
+        destinationPath = os.path.join(self.backupPath,'documents.zip')
+        if os.path.exists(destinationPath):
+            zipfile = utils.openZip(destinationPath, 'a')
+        else:
+            zipfile = utils.openZip(destinationPath, 'w')
+            
+        docsPath = os.path.join(self.myDocsPath, ".documents")
+        
+        if os.path.exists(docsPath):
+            backupPath = os.path.join(workPath, docsPath)
+            categoryFilesNumber = self.zipFolder(backupPath, zipfile, docsPath,
+                                                 "documents")
+            
+        utils.closeZip(zipfile)
+        return categoryFilesNumber
+           
+                    
+    def _backupMedias(self, workPath):
+        """ Create backup of media files in user folder. """
+        categoryFilesNumber = 0
+        destinationPath = os.path.join(self.backupPath,'media.zip')
+        if os.path.exists(destinationPath):
+            zipfile = utils.openZip(destinationPath, 'a')
+        else:
+            zipfile = utils.openZip(destinationPath, 'w')
+            
+        userFilesPath = self.myDocsPath
+        if os.path.exists(os.path.join(userFilesPath)):
+            for folder in os.listdir(userFilesPath):
+                if folder != '.documents':
+                    objPath = os.path.join(userFilesPath, folder)
+                    backupDir = os.path.join(workPath, objPath)
+                    result = self.zipFolder(backupDir, zipfile,
+                                                         objPath, "media")
+                    if result != -1:
+                        categoryFilesNumber += result
+                    else:
+                        return result
+                    
+        utils.closeZip(zipfile)
+        return categoryFilesNumber
+    
+                    
+    def _createBackupFolder(self, newBackupPath):
+        if not utils.createFolder(newBackupPath):
+            return False
+    
+    
+    def _emitProgress(self):
+        currentSize = utils.getSize(self.backupPath) 
+        percentage = self.computePercentage(self.totalSize, currentSize)
+        self.emit(SIGNAL("backupProgress"), (percentage, self.currentCategory))
+    
+    
+    def _getTotalSize(self, backupFileDict, categories):
+        size = 0
+        for category in backupFileDict.keys():
+            for backupItem in backupFileDict[category]:
+                if (category in categories) and (categories[category]):
+                    objPath = backupItem.path.replace('/','Root/',1)
+                    size += utils.getSize(objPath)
+        
+        if categories["documents"]:
+            size += utils.getSize(os.path.join(self.myDocsPath,
+                                                     ".documents"))
+        if categories["media"]:
+            for folder in os.listdir(self.myDocsPath):                
+                if folder != '.documents':
+                    objPath = os.path.join(self.myDocsPath, folder)
+                    size += utils.getSize(objPath)
+        return size
+    
+    def _updateCategoryCount(self, filesByCategory, category, backed_up_number):
+        if str(category) not in filesByCategory.keys():
+            filesByCategory[category] = backed_up_number
+        else:
+            filesByCategory[category] += backed_up_number
+    
+            
+    def _verify_backup_name(self, backup_name):
+        """ Check if already exists any backup with the given name inside the
+        pc backup list. In case there is one, this function will return another
+        name to be set as the new backup name, else it will return the same 
+        name that was given.
+        
+        """
+        if self.getBackupInfo(backup_name) != None:
+            counter = 1
+            new_name = backup_name + "%02d" % counter
+            while(self.getBackupInfo(new_name)) != None:
+                counter += 1
+                new_name = backup_name + "%02d" % counter
+            
+            backup_name = new_name
+        return backup_name
+    
+    def zipFolder(self, path, zipfile, obj_path, category):
+        # Compress the folder from the given path, with all directories and
+        #   files inside it
+        # zipfile: The ZipFile object to append the folder
+        # obj_path: The ZipFile path
+        count = 0
+        self._emitProgress()
+        if os.path.exists(path):
+            if os.path.isdir(path):
+                files = os.listdir(path)
+                for node in files:
+                    if os.path.isdir(os.path.join(path, node)):
+                        zipCount = self.zipFolder(os.path.join(path, node), zipfile,
+                                            os.path.join(obj_path, node), category)
+                        if zipCount == -1:
+                            return -1
+                        else:
+                            count += zipCount
+                    else:
+                        # Check if backup was canceled and return -1 case positive
+                        if not self.backupInProgress:
+                            utils.removePath(self.backupPath)
+                            return -1
+
+                        if utils.zip(zipfile, os.path.join(obj_path, node)):
+                            count += 1
+                            self._emitProgress()
+            else:
+                # Check if backup was canceled and return -1 case positive
+                if not self.backupInProgress:
+                    utils.removePath(self.backupPath)
+                    return -1
+                
+                if utils.zip(zipfile, obj_path):
+                    count += 1
+                    self._emitProgress()
+        return count
+    
+
+
+class NewBackupThread(QThread):
+    def __init__(self, manager, backupName, path, hostIp, categories, comment):
+        QThread.__init__(self)
+        
+        self.manager = manager
+        self.backupName = backupName
+        self.path = path
+        self.hostIp = hostIp
+        self.categories = categories
+        self.comment = comment
+    
+    def run(self):
+        ret = self.manager._runCreateBackup (self.backupName, self.path,
+                                             self.hostIp, self.categories,
+                                             str(self.comment))
+        self.manager.emit(SIGNAL("backupDone"), ret, 
+                          (self.manager.totalSize, self.manager.backedUpNumber))    
+
+
+        
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsprogressdialog.py.svn-base b/src/backup/.svn/text-base/pcsprogressdialog.py.svn-base
new file mode 100644 (file)
index 0000000..cf9038f
--- /dev/null
@@ -0,0 +1,117 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from style.styleTabletSuite import *
+from ui.pcsuiutils import *
+
+class PcsProgressDialog(QDialog):
+       
+    def __init__(self, parent = None):
+        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
+        self.cancelButton = QPushButton("Cancel")
+        self.doneButton = QPushButton("Done")
+        self.connect(self.doneButton, SIGNAL("clicked()"), self.close)
+        self.actionLabel = QLabel("Action...")
+        self.categoryLabel = QLabel("")  
+        self.progressReport = QLabel("") 
+        self.setLayout(self._insertLayout())
+        
+        
+    def setAction(self, action):
+        self.action = action
+        if action == "copy":
+            message = "Copying..."
+            
+        elif action == "restore":
+            message = "Restoring..."
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                       "#333333'; size=2>"\
+                                       +str(action).capitalize()+
+                                       " in progress...</font>")
+        
+        self.actionLabel.setText('''<font style=color:
+                                black; size=3>
+                                '''+ message +'''</font>''')
+    
+    def _insertLayout(self):
+        vLay = QVBoxLayout()
+        vLay.addWidget(self.actionLabel)
+        vLay.addLayout(self._createCenterLayout())
+        return vLay
+    
+    def _createCenterLayout(self):
+        
+        bgLabel = QLabel()
+        bgLabel.setPixmap(QPixmap(PROGRESS_BAR_DIALOG_BG))
+        grid = QGridLayout()
+        
+        self.progressBar = QProgressBar()
+        self.progressBar.setObjectName("progressBarDialog")
+        self.progressBar.setValue(0)
+        self.progressBar.setTextVisible(False)
+        
+        grid.addWidget(bgLabel, 0, 0, Qt.AlignCenter)
+        grid.addWidget(self.progressBar, 0, 0, Qt.AlignCenter)
+
+        self.cancelButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.cancelButton.setShortcut(Qt.Key_Return)
+        self.doneButton.setVisible(False)
+        self.doneButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        
+        gridLayout = QGridLayout()
+        gridLayout.setSpacing(3)
+        gridLayout.addWidget(self.categoryLabel, 0, 0, Qt.AlignRight)
+        gridLayout.addLayout(grid, 1, 0)
+        gridLayout.addWidget(self.progressReport, 2, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.cancelButton, 3, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.doneButton, 3, 0, Qt.AlignRight)
+        
+        return gridLayout
+    
+    def progressCanceled(self):
+        self.progressDone(True)
+    
+    def progressDone(self, cancel=False):
+        self.cancelButton.setVisible(False)
+        self.doneButton.setVisible(True)
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2>"+\
+                                    str(self.action).capitalize()
+                                    +" finished.</font>")
+        if not cancel:
+            totalSize =  "%.2f" % (self.totalSize/(1024.0**2))
+        
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2>"\
+                                        + str(self.numberOfFiles) +\
+                                        " Files - " + totalSize + " MB</font>")
+        else:
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2> Canceled")
+            self.categoryLabel.setText("")
+            self.progressBar.setValue(100)
+            
+    def updateInfo(self, totalSize, numberOfFiles):
+        self.totalSize = totalSize
+        self.numberOfFiles = numberOfFiles
+    
+    def setProgress(self, progress):
+        self.progressBar.setValue(float(progress))
+        
+        self.progressReport.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    + progress +\
+                                    "% Complete</font>")  
+        
+    def setCategory(self, catogory):
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2> Category name: "\
+                                   + catogory +"</font>")
+    
+    
+    
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsprogresswizard.py.svn-base b/src/backup/.svn/text-base/pcsprogresswizard.py.svn-base
new file mode 100644 (file)
index 0000000..6afb6af
--- /dev/null
@@ -0,0 +1,237 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+from style.styleTabletSuite import *
+
+
+class PcsProgressWizard(QWizardPage):
+    
+    def __init__(self, deviceInfo, wizard, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        self.windowManager = windowManager
+        self.deviceInfo = deviceInfo
+        self.wizard = wizard
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.cancelButton = QPushButton("Cancel")
+        self.doneButton = QPushButton("Done")
+        self.completeReportButton = QPushButton("View Complete Report")
+        self.lockMenuButtons = True        
+        self._insertLayout()
+        
+    def _insertLayout(self, name = ""):
+        self.vLayout = QVBoxLayout()
+        self.vLayout.setMargin(0)
+        self.wayLayout = self._wayLayout(name)
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self.wayLayout, Qt.AlignLeft)
+        spc = QSpacerItem(0, 68)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manager Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    def _wayLayout(self, name = ""):
+        self.barLayout = QHBoxLayout()
+        self.barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow1 = self._arrow()
+        arrow2 = self._arrow()
+        arrow3 = self._arrow()
+        arrow4 = self._arrow()
+        spc = QSpacerItem(2, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #333333'; size=2>Files</font>")
+        folder = QLabel("<font style='color: #333333'; size=2>Folder</font>")
+        if name != "":
+            loading = QLabel("<font style='color: #333333'; size=2>loading</font>")
+        else:
+            loading = QLabel("<font style='color: #FFFFFF'; size=2>loading</font>")   
+        widgetList = [main, self._arrow(), newBackup, self._arrow(), files,
+                      self._arrow(), folder, self._arrow(), loading]
+        for widget in widgetList:
+            self.barLayout.addWidget(widget, Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+        if name != "":
+            newLabel = QLabel("<font style='color: #FFFFFF'; size=2>"+ name +"</font>")
+            self.barLayout.addWidget(self._arrow(), Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+            self.barLayout.addWidget(newLabel, Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+            
+        self.barLayout.addItem(QSpacerItem(300, 0))
+        return self.barLayout
+    
+    def _manageDialog(self):
+        if self.lockMenuButtons == False:
+            if(self.deviceInfo and self.deviceInfo.ip != None):
+                backupManager = self.windowManager.getBackupManager()
+                centralize(backupManager)
+                backupManager.setGeometry(self.wizard.geometry())
+                backupManager.show()
+                self.close()
+                self.wizard.close()
+                self.lockMenuButtons = True
+                self._resetPage()
+            else:
+                self._showNoDeviceFoundMessage()
+        
+    def _restoreDialog(self):
+        if self.lockMenuButtons == False:
+            if(self.deviceInfo and self.deviceInfo.ip != None):
+                restoreBackup = self.windowManager.getRestoreBackup()
+                centralize(restoreBackup)
+                restoreBackup.setGeometry(self.wizard.geometry())
+                restoreBackup.show()
+                self.wizard.close()
+                self.close()
+                self.lockMenuButtons = True
+                self._resetPage()
+            else:
+                self._showNoDeviceFoundMessage()
+        
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label
+        
+    def _createInformationsLabel(self):
+        hLay = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        self.infLabel = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Do backup from Device to your PC.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(self.infLabel, Qt.AlignLeft)
+        
+        return hLay
+    
+    def _resetPage(self):
+        self.lockMenuButtons = True
+        self.cancelButton.setVisible(True)
+        self.doneButton.setVisible(False)
+        self.progressBar.setValue(0)
+        self.progressReport.setText("")
+        self.categoryLabel.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    "Backup starting...</font>")
+    
+    def _createCenterLayout(self):
+        gridLayout = QGridLayout()
+        gridLayout.setMargin(27)
+        
+        self.categoryLabel = QLabel("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    "Backup starting...</font>")  
+        
+        bgLabel = QLabel()
+        bgLabel.setPixmap(QPixmap(PROGRESS_BAR_BG))
+        grid = QGridLayout()
+        
+        self.progressBar = QProgressBar()
+        self.progressBar.setObjectName("progressBarWizard")
+        self.progressBar.setValue(0)
+        self.progressBar.setTextVisible(False)
+        
+        grid.addWidget(bgLabel, 0, 0, Qt.AlignCenter)
+        grid.addWidget(self.progressBar, 0, 0, Qt.AlignCenter)
+        
+        self.progressReport = QLabel("")  
+        
+        self.cancelButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.cancelButton.setShortcut(Qt.Key_Return)
+        self.doneButton.setVisible(False)
+        self.doneButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+#        self.completeReportButton.setStyleSheet()
+        
+        gridLayout.setSpacing(3)
+        gridLayout.addWidget(self.categoryLabel, 0, 0, Qt.AlignRight)
+        gridLayout.addLayout(grid, 1, 0)
+        gridLayout.addWidget(self.progressReport, 2, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.cancelButton, 3, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.doneButton, 3, 0, Qt.AlignRight)
+        
+        return gridLayout
+    
+    def progressCanceled(self):
+        self.progressDone(True)
+    
+    def progressDone(self, cancel=False):
+        self.lockMenuButtons = False
+        self.cancelButton.setVisible(False)
+        self.doneButton.setVisible(True)
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2>"\
+                                   "Backup finished.</font>")
+        if not cancel:
+            totalSize =  "%.2f" % (self.totalSize/(1024.0**2))
+        
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2>"\
+                                        + str(self.backedUpNumber) +\
+                                        " Files - " + totalSize + " MB</font>")
+        else:
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2> Canceled")
+            self.categoryLabel.setText("")
+            self.progressBar.setValue(100)
+            
+            
+        self.infLabel.setText("<font style='color:"\
+                              "#333333'; size=2>"\
+                              "Select an action</font>")
+        
+    def updateInfo(self, totalSize, backedUpNumber):
+        self.totalSize = totalSize
+        self.backedUpNumber = backedUpNumber
+    
+    def setProgress(self, progress):
+        self.progressBar.setValue(progress)
+        
+        self.progressReport.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    + str(int(progress))+\
+                                    "% Complete</font>")  
+        
+    def setCategory(self, category):
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2> Category name: "\
+                                   + category +"</font>")
+        
+    
\ No newline at end of file
diff --git a/src/backup/.svn/text-base/pcsrestorebackupui.py.svn-base b/src/backup/.svn/text-base/pcsrestorebackupui.py.svn-base
new file mode 100644 (file)
index 0000000..dc9733a
--- /dev/null
@@ -0,0 +1,412 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from functools import partial 
+
+from ui.pcsuiutils import *
+from ui.tsuigeneralmethods import *
+
+from style.styleTabletSuite import *
+
+from backup.pcsbackupmanager import PcsBackupManager, DEVICES_POINT, USER_HOST
+from backup.pcspcbackupmanager import PcsPcBackupManager
+from backup.pcsdevicebackupmanager import PcsDeviceBackupManager
+from pcsbackuplistui import PCSBackupListUi
+from pcsprogressdialog import PcsProgressDialog
+from pcsrestoredialog import PcsRestoreDialog
+from pcsbackuputils import *
+
+
+class PcsRestoreBackupUi(QDialog):
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        super(PcsRestoreBackupUi, self).__init__(parent)
+        self.deviceInfo = deviceInfo
+        
+        self.windowManager = windowManager
+        self.pcBackupManager = PcsPcBackupManager()
+        self.deviceBackupManager = PcsDeviceBackupManager(self.deviceInfo)
+        self.deviceListView = PCSBackupListUi(self.deviceBackupManager)
+        
+        self._buttonRestoreI = QPushButton("Restore")
+        self.connect (self._buttonRestoreI, SIGNAL("clicked()"), self._openRestoreBackup)
+        self._buttonRestoreII = QPushButton("Restore")
+        self.connect (self._buttonRestoreII, SIGNAL("clicked()"), self._openRestoreBackup)
+        self._buttonView = QPushButton("View")
+        self.connect (self._buttonView, SIGNAL("clicked()"), self._doViewBackup)
+        
+        self.pcListView = PCSBackupListUi(self.pcBackupManager)
+        
+        self.setWindowTitle("%s Restore Backup" % APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+        self.vLayout = QVBoxLayout()
+        
+        self._insertLayout()
+    
+    def _createCenterLayout(self):
+        self.deviceListView.updateBackupList()
+        tab = QTabBar()
+        tab.setObjectName("restoreTabs")
+        self.tabBar = QTabWidget()
+        self.tabBar.setTabBar(tab)
+        self.tabBar.setAttribute(Qt.WA_NoSystemBackground)
+        self.tabBar.setObjectName("tabBar")
+        self.tabBar.addTab(self._createPcListViewWidget(), "PC Backups")
+        self.tabBar.addTab(self._createDeviceListViewWidget(), "Device Backups")
+        self.connect(self.tabBar, SIGNAL("currentChanged(int)"), 
+                     self._updateButtonsState)
+        
+        layout = QVBoxLayout()
+        layout.addWidget(self.tabBar)
+        
+        return layout
+    
+    def _createButtons(self, pcFlag = False):
+        buttonBox = QHBoxLayout()
+        self._buttonRestoreI.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonRestoreI.setDisabled(True)
+        self._buttonRestoreII.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonRestoreII.setDisabled(True)
+        self._buttonView.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonView.setDisabled(True)
+        
+        if pcFlag:
+            buttonBox.addWidget(self._buttonView)
+            buttonBox.addWidget(self._buttonRestoreI)
+        else:
+            buttonBox.addWidget(self._buttonRestoreII)
+        
+        return buttonBox
+    
+    def _createPcListViewWidget(self):
+        self.pcListView.setObjectName("ListView")
+        pcListViewSelectionModel = self.pcListView.selectionModel()
+        self.connect(pcListViewSelectionModel, 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
+                     self._updateButtonsState)
+        
+        self.pcListView.updateBackupList()
+        
+        panel = QWidget()
+        panel.setAttribute(Qt.WA_NoSystemBackground)
+        panel.setObjectName("DeviceListPanel")
+        vLay = QVBoxLayout()
+        
+        vLay.addWidget(self.pcListView)
+        vLay.addLayout(self._createButtons(True))
+        panel.setLayout(vLay)
+        
+        return panel
+    
+    def _createDeviceListViewWidget(self):
+        self.deviceListView.setObjectName("ListView")
+        deviceListViewSelectionModel = self.deviceListView.selectionModel()
+        self.connect(deviceListViewSelectionModel, 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), 
+                     self._updateButtonsState)
+        
+        self.deviceListView.updateBackupList()
+        
+        panel = QWidget()
+        panel.setAttribute(Qt.WA_NoSystemBackground)
+        panel.setObjectName("DeviceListPanel")
+        vLay = QVBoxLayout()
+        
+        vLay.addWidget(self.deviceListView)
+        vLay.addLayout(self._createButtons())
+        panel.setLayout(vLay)
+        
+        return panel
+        
+        
+    def _insertLayout(self):
+        
+        self.vLayout.setMargin(0)
+        self.wayLayout = self._wayLayout()
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 6)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        spc = QSpacerItem(0, 5)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self.wayLayout, Qt.AlignLeft)
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        spc = QSpacerItem(0, 8)
+        self.vLayout.addItem(spc)
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE, self._newBackupDialog), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE_SELECTED)]
+        
+        buttonsLayout = QHBoxLayout()
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 2:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    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> Restore 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 _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.geometry())
+            backupManager.show()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    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 _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    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 restore.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        spc = QSpacerItem(15, 0)
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(self.infLabel, Qt.AlignLeft)
+        
+        return hLay
+
+    def _updateButtonsState(self, index):
+        list = self._currentBackupList()
+        selectionModel = list.selectionModel()
+        indexList = selectionModel.selectedRows()
+        
+        if len(indexList) <> 1:
+            self._buttonView.setDisabled(True)
+            self._buttonRestoreI.setDisabled(True)
+            self._buttonRestoreII.setDisabled(True)
+        else:
+            self._buttonView.setEnabled(True)
+            self._buttonRestoreI.setEnabled(True)
+            self._buttonRestoreII.setEnabled(True)
+
+    def _currentBackupList(self):
+        if self.tabBar.currentIndex() == 0:
+            return self.pcListView
+        else:
+            return self.deviceListView
+        
+        
+    def doRestoreBackup(self, categories):
+        if self._currentBackupList() == self.pcListView:
+            manager = self.pcBackupManager
+        else:
+            manager = self.deviceBackupManager
+            
+        self.restoreBackupThread = RestoreBackupThread(self, manager, categories)
+        self.restoreBackupThread.start()
+        self._runRestoreProgress()
+        self.connect(self.restoreBackupThread, SIGNAL("restoreProgress"), 
+                     self._updateCategoriesAndProgress)
+        self.connect(self.restoreBackupThread, SIGNAL("restoreDone"), 
+                     self._onRestodeDone)
+        self.connect(self.restoreBackupThread, SIGNAL("openFileError"),
+                     self._onOpenFileError)
+
+    def _openRestoreBackup(self):
+        backup = self._currentBackupList().getSelectedBackup()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.loadBackups()
+            backupInfo = self.pcBackupManager.getBackupInfo(str(backup))
+        else:
+            self.deviceBackupManager.loadBackups()
+            backupInfo = self.deviceBackupManager.getBackupInfo(str(backup))
+            
+        host_ip = self.deviceInfo.ip
+        devicePath = os.path.join(DEVICES_POINT, "%s" % host_ip)
+        mountPath = os.path.join(devicePath, "Root" )
+        mountDevice(USER_HOST, host_ip, mountPath)
+        list = getBackupCategories(backupInfo)
+        unmountDevice(mountPath)
+        
+        self.restoreDialog = PcsRestoreDialog(self.deviceInfo, list, self)
+        self.connect(self.restoreDialog.buttonCancel, SIGNAL("clicked()"),
+                     self.restoreDialog.close)
+        
+        self.connect(self.restoreDialog.buttonOk, SIGNAL("clicked()"),
+                     self._doRestoreAndCloseDialog)
+        self.restoreDialog.exec_()
+        
+    
+    def _doRestoreAndCloseDialog(self):
+        categories = self.restoreDialog.getCategories()
+        self.restoreDialog.close()
+        self.doRestoreBackup(categories)
+        
+    def _doRestoreBackup(self, categories):
+        selectedBackups = self._currentBackupList().getSelectedBackupList()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.loadBackups()
+            for backup in selectedBackups:
+                backupInfo = self.pcBackupManager.getBackupInfo(str(backup))
+                ip = self.deviceBackupManager._deviceInfo.ip
+                self.emit(SIGNAL("restoreStarted"))
+                result = self.pcBackupManager.startBackupRestore(backupInfo, ip,
+                                                       categories)
+                if result == False or result == 0:
+                    return result
+        else:
+            self.deviceBackupManager.loadBackups()
+            for backup in selectedBackups:
+                backupInfo = self.deviceBackupManager.getBackupInfo(str(backup))
+                self.emit(SIGNAL("restoreStarted"))
+                result = self.deviceBackupManager.startBackupRestore(backupInfo, 
+                                                          categories)
+                if result == False or result == 0:
+                    return result
+        return True
+
+    def showRestoreMessage(self, done):
+        if done != 0:
+            self._progressDialog.cancel()  
+            ip = self.deviceBackupManager._deviceInfo.ip
+            if done:
+                doneMessage = "Restore done. Your device will be rebooted now"
+                showMessageBox(doneMessage, "Restore successfully Done")
+                rebootDevice(ip)
+            else:
+                showMessageBox("An error occurred while restoring backup",
+                                 "Restore error")
+              
+    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()
+        layout.setMargin(10)
+        listWidget = QListWidget()
+        listWidget.setObjectName("viewList")
+        listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
+
+        backupContentList = backupManager.listBackupContent(backupName)
+        if not backupContentList:
+            showMessageBox("Could not open backup files", "Error")
+            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 _runRestoreProgress(self):
+        self._progressDialog = PcsProgressDialog(self)
+        self._progressDialog.setAction("restore")
+        self.connect(self._progressDialog.cancelButton, SIGNAL("clicked()"),
+                      self._onRestoreCancel)
+        
+        self._progressDialog.show()
+    
+    def _updateCategoriesAndProgress(self, information):
+        progress, category, self.numberOfFiles, self.totalSize = information
+        
+        self._progressDialog.setProgress(progress)
+        self._progressDialog.setCategory(category)
+    
+    def _onRestodeDone(self):
+        self._progressDialog.updateInfo(self.totalSize, self.numberOfFiles)
+        self._progressDialog.progressDone()
+    
+    def _onRestoreCancel(self):
+        self._progressDialog.progressCanceled()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.setRestoreInProgress(False)
+        else:
+            self.deviceBackupManager.setRestoreInProgress(False)
+            
+    def _onOpenFileError(self):
+        self._progressDialog.close()
+        showMessageBox(OPEN_FILE_ERROR, OPEN_FILE_ERROR_TITLE)
+    
+class RestoreBackupThread(QThread):
+    def __init__(self, restoreBackup, manager,  categories):
+        QThread.__init__(self)
+        self.restoreBackup = restoreBackup
+        self.categories = categories
+        self.connect(manager, SIGNAL("restoreProgress"), self._reEmitSignal)
+    
+    def _reEmitSignal(self, informations):
+        self.emit(SIGNAL("restoreProgress"), informations)
+
+    def run(self):
+        try:
+            done = self.restoreBackup._doRestoreBackup(self.categories)
+        except IOError:
+            self.emit(SIGNAL("openFileError"))
+            return
+        self.emit(SIGNAL("restoreDone"))
+    
diff --git a/src/backup/.svn/text-base/pcsrestoredialog.py.svn-base b/src/backup/.svn/text-base/pcsrestoredialog.py.svn-base
new file mode 100644 (file)
index 0000000..dbef514
--- /dev/null
@@ -0,0 +1,199 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from style.styleTabletSuite import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+
+class PcsRestoreDialog(QDialog):
+       
+    def __init__(self, deviceInfo, categoriesList, parent = None):
+        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
+        self.setWindowTitle("%s Restore Backup" % APPLICATION_NAME)
+        self.setFixedSize(200, 300)
+        self.deviceInfo = deviceInfo
+        self.categories = categoriesList
+        self.validPositions = []
+        self.validCategories = []
+        
+        self.layout = QVBoxLayout()
+        
+        self.labelLayout = QHBoxLayout()  
+        spc = QSpacerItem(15, 0)
+        self.labelLayout.addItem(spc)
+        label = QLabel("Which categories you want to restore?")
+        label.setWordWrap(True)
+        self.labelLayout.addWidget(label)
+        self.labelLayout.setMargin(0)
+        self.layout.addLayout(self.labelLayout)
+             
+#        self.grid = QGridLayout()
+#        self.create_dialog()
+#        self.grid.setMargin(0)
+#        self.layout.addLayout(self.grid)
+        self.create_checkbox_frame()
+        
+        self.buttonLayout = QHBoxLayout()
+        self.create_buttons()
+        self.buttonLayout.setMargin(0)
+        self.layout.addLayout(self.buttonLayout)
+        
+        self.setLayout(self.layout)
+        self.map_checked = {self.documents.name: False,
+                            self.emails.name: False, self.media.name: False,
+                            self.contacts.name: False, 
+                            self.bookmarks.name: False,
+                            self.settings.name: False, 
+                            self.applications.name: False}
+    
+    def empty_map(self):
+        for index in self.map_checked.keys():
+            if self.map_checked[index]:
+                return False
+        return True
+    
+    def create_buttons(self):
+        self.buttonOk = QPushButton("Ok")
+        self.buttonOk.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.buttonLayout.addWidget(self.buttonOk)
+        
+        self.buttonCancel = QPushButton("Cancel")
+        self.buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.buttonLayout.addWidget(self.buttonCancel)
+    
+    def create_checkbox_frame(self):
+        layout = QVBoxLayout()
+        l = QLabel()
+        l.setPixmap(QPixmap(COPY_BORDER))
+       
+        self.frame = QScrollArea(self)
+        self.frame.setObjectName("restoreScroll")
+        self.frame.setWidgetResizable(True)
+        widget = QWidget(self.frame)
+        widget.setStyleSheet("QWidget{background: transparent;}")
+        self.grid = QGridLayout()
+        self.grid.setSpacing(0)
+        self.create_dialog()
+        widget.setLayout(self.grid)
+        self.frame.setWidget(widget)
+        layout.addWidget(self.frame)
+        self.layout.addLayout(layout)
+        
+    def create_dialog(self):
+        #Add Checkboxes
+#        self.add_select_all()
+        self.add_documents()
+        self.add_emails()
+        self.add_media()
+        self.add_contacts()
+        self.add_bookmarks()
+        self.add_settings()
+        self.add_applications()            
+        
+#    def add_select_all(self):
+#        self.select_all = QCheckBox("Select All")
+#        self.connect(self.select_all, SIGNAL("stateChanged(int)"), 
+#                     self.select_all_func)
+#        self.validPositions.append((1,0))
+#        self.grid.addWidget(self.select_all, 1, 0, Qt.AlignTop)          
+#    
+    def add_documents(self):
+        self.documents = QCheckBox("Documents")
+        self.documents.name = "documents"
+        callback = partial(self.select_func, self.documents)
+        self.connect(self.documents, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "documents" in self.categories:
+            self.validPositions.append((2, 0))
+            self.grid.addWidget(self.documents, 2, 0, Qt.AlignTop)
+    
+    def add_emails(self):
+        self.emails = QCheckBox("Emails")
+        self.emails.name = "emails"
+        callback = partial(self.select_func, self.emails)
+        self.connect(self.emails, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "emails" in self.categories:
+            self.validPositions.append((3, 0))
+            self.grid.addWidget(self.emails, 3, 0, Qt.AlignTop)
+    
+    def add_media(self):
+        self.media = QCheckBox("Media")
+        self.media.name = "media"
+        callback = partial(self.select_func, self.media)
+        self.connect(self.media, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "media" in self.categories:
+            self.validPositions.append((4, 0))
+            self.grid.addWidget(self.media, 4, 0, Qt.AlignTop)
+    
+    def add_contacts(self):
+        self.contacts = QCheckBox("Contacts")
+        self.contacts.name = "contacts"
+        callback = partial(self.select_func, self.contacts)
+        self.connect(self.contacts, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "contacts" in self.categories:
+            self.validPositions.append((5, 0))
+            self.grid.addWidget(self.contacts, 5, 0, Qt.AlignTop)
+    
+    def add_bookmarks(self):
+        self.bookmarks = QCheckBox("Bookmarks")
+        self.bookmarks.name = "bookmarks"
+        callback = partial(self.select_func, self.bookmarks)
+        self.connect(self.bookmarks, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "bookmarks" in self.categories:
+            self.validPositions.append((6, 0))
+            self.grid.addWidget(self.bookmarks, 6, 0, Qt.AlignTop)
+        
+    def add_settings(self):
+        self.settings = QCheckBox("Settings")
+        self.settings.name = "settings"
+        callback = partial(self.select_func, self.settings)
+        self.connect(self.settings, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "settings" in self.categories:
+            self.validPositions.append((7, 0))
+            self.grid.addWidget(self.settings, 7, 0, Qt.AlignTop)
+
+    def add_applications(self):
+        self.applications = QCheckBox("Applications")
+        self.applications.name = "applications"
+        callback = partial(self.select_func, self.applications)
+        self.connect(self.applications, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "applications" in self.categories:
+            self.validPositions.append((8, 0))
+            self.grid.addWidget(self.applications, 8, 0, Qt.AlignTop)
+
+#    def select_all_func(self):
+#        checked = self.select_all.isChecked()
+#        list = self.map_checked.keys()
+#        for element in list:
+#            self.map_checked[element] = checked
+#        for tuple in self.validPositions:
+#            self.grid.itemAtPosition(tuple[0], tuple[1]).widget().setChecked(checked)
+#        
+    def select_func(self, checkbox):
+        checked = checkbox.isChecked()
+        self.map_checked[checkbox.name] = checked
+        if not checked:
+            list = []
+            for tuple in self.validPositions:
+                item = self.grid.itemAtPosition(tuple[0], tuple[1]).widget()
+#                if item == self.select_all:
+#                    pass
+                if item.isChecked():
+                    list.append(item)
+#            self.select_all.setChecked(False)
+            for element in list:
+                element.setChecked(True)         
+            
+    def getCategories(self):
+        return self.map_checked
+        
diff --git a/src/backup/.svn/text-base/pcswindowmanager.py.svn-base b/src/backup/.svn/text-base/pcswindowmanager.py.svn-base
new file mode 100644 (file)
index 0000000..a0aa565
--- /dev/null
@@ -0,0 +1,36 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from pcsbackupwizard import PcsBackupWizard
+from pcsrestorebackupui import PcsRestoreBackupUi
+from pcsbackupmanagerui import PcsBackupManagerUi
+
+class PcsWindowManager:
+    class _impl:
+        def __init__(self, deviceInfo, parent = None):
+            self.__newBackup = PcsBackupWizard(deviceInfo, self, parent)
+            self.__restoreBackup = PcsRestoreBackupUi(deviceInfo, self, parent)
+            self.__backupManager = PcsBackupManagerUi(deviceInfo, self, parent)
+            
+        def getNewBackup(self):
+            return self.__newBackup
+        
+        def getRestoreBackup(self):
+            return self.__restoreBackup
+            
+        def getBackupManager(self):
+            return self.__backupManager
+        
+    __instance = None
+
+    def __init__(self, deviceInfo = None, parent = None):
+        if PcsWindowManager.__instance is None:
+            PcsWindowManager.__instance = PcsWindowManager._impl(deviceInfo, parent)
+        self.__dict__['Singleton_instance'] = PcsWindowManager.__instance
+
+    def __getattr__(self, attr):
+        return getattr(self.__instance, attr)
+
+    def __setattr__(self, attr, value):
+        return setattr(self.__instance, attr, value)
+        
\ No newline at end of file
diff --git a/src/backup/__init__.py b/src/backup/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/backup/pcsbackup.py b/src/backup/pcsbackup.py
new file mode 100644 (file)
index 0000000..92d5f2a
--- /dev/null
@@ -0,0 +1,124 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsapp import PcsApp
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+from ui.pcsbutton import *
+from ui.tsuigeneralmethods import *
+
+from ui.pcscustombuttons import PcsCustomButton as customButton
+
+from pcswindowmanager import *
+
+class PcsBackup(PcsApp):
+    
+    def __init__(self, deviceInfo, parent=None):
+        PcsApp.__init__(self, parent)
+        self.deviceInfo = deviceInfo
+        
+        if (self.deviceInfo != None):
+            self.windowManager = PcsWindowManager(self.deviceInfo, self)
+        
+        self.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self.setWindowTitle("%s Backup" % APPLICATION_NAME)
+
+        self.hLayout = QHBoxLayout()
+        self.hLayout.setMargin(8)
+        self.vLayout = QVBoxLayout()
+        
+        spc = QSpacerItem(0,50)
+        self.optionsLayout = QVBoxLayout()
+        self.optionsLayout.addItem(spc)
+        self._addButtons()
+        self.optionsLayout.addItem(spc)
+        
+        self.deviceWidget = PcsDeviceWidget(1)
+        self.deviceWidget.addBorder()
+        self.deviceWidget.addDeviceName()
+        self.deviceWidget.setDeviceInfo(self.deviceInfo)
+        
+        self.optionsBorderLayout = QGridLayout()
+        self.optionsBorderLabel = QLabel()
+        self.optionsBorderLabel.setFixedSize(208, 205)
+        self.optionsBorderLabel.setPixmap(QPixmap(DEVICE_BACKUP_BORDER))
+        self.optionsBorderLayout.addWidget(self.optionsBorderLabel, 0, 0, Qt.AlignCenter)
+        self.optionsBorderLayout.addLayout(self.optionsLayout, 0, 0, Qt.AlignCenter)
+        self.hLayout.addLayout(self.optionsBorderLayout)
+        self.hLayout.addWidget(self.deviceWidget)
+        
+        #FIXE ME
+        l1 = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        self.vLayout.addItem(TOP_SPACER)
+        self.vLayout.addWidget(l1)
+        self.vLayout.addLayout(self.hLayout)
+        informationLayout = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        information = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Select an action.</font>")
+        informationLayout.addItem(spc)
+        informationLayout.addWidget(iconAlert)
+        informationLayout.addWidget(information, Qt.AlignLeft)
+        self.vLayout.addLayout(informationLayout)
+        self.vLayout.setMargin(8)
+        self.setLayout(self.vLayout)
+        
+    def openBackupWizard(self):
+
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backup_wizard = self.windowManager.getNewBackup()
+            centralize(backup_wizard)
+            backup_wizard.setGeometry(self.geometry())
+            backup_wizard.exec_()
+            self.setVisible(False)
+            self.setGeometry(backup_wizard.geometry())
+        else:
+            showMessageBox("No devices were found.", "")
+
+    def openBackupManagerDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.show()
+            self.setVisible(False)
+        else:
+            showMessageBox("No devices were found.", "")
+            
+    def openRestoreBackupDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            restoreBackup = self.windowManager.getRestoreBackup()
+            centralize(restoreBackup)
+            restoreBackup.show()
+            self.setVisible(False)
+        else:
+            showMessageBox("No devices were found.", "")
+        
+    def _addButtons(self):
+        infList = [("New Backup       ", ICON_NEW_BACKUP), 
+                   ("Manage Backups", ICON_MANAGER_BACKUP),
+                   ("Restore Backups  ", ICON_RESTORE_BACKUP)]
+        buttonsList = []
+        for inf in infList:
+            buttonOptions = PcsButton(inf[0])
+            buttonOptions.setStyleSheet("background-image\
+            :url("+ BUTTON_WITH_ICON_BG +");\
+             qproperty-icon:url("+inf[1]+");\
+             min-height:50px; min-width:188px;\
+             max-height:50px; max-width:188px;\
+             qproperty-iconSize: 43px 36px")
+            self.optionsLayout.addWidget(buttonOptions)
+            buttonsList.append(buttonOptions)
+            
+        self.connect(buttonsList[0], SIGNAL("clicked()"),
+                     self.openBackupWizard)
+        self.connect(buttonsList[1], SIGNAL("clicked()"),
+                    self.openBackupManagerDialog)
+        self.connect(buttonsList[2], SIGNAL("clicked()"),
+                      self.openRestoreBackupDialog) 
diff --git a/src/backup/pcsbackupinfo.py b/src/backup/pcsbackupinfo.py
new file mode 100644 (file)
index 0000000..a76e11e
--- /dev/null
@@ -0,0 +1,73 @@
+import time
+from datetime import datetime
+
+class PcsBackupInfo:
+    """Class that represents a backup
+
+    Attributes:
+    _name -- Backup name
+    path -- Backup directory path
+    date -- Date when backup was created
+    _comment -- Any comment about backup
+    size -- Backup file size
+    files_number = total number of backup files
+    _time = time object was created in seconds since epoch
+
+    """
+
+    def __init__(self, name, path, size, comment=""):
+        """Initialize object attributes."""
+        self._name = name
+        self.path = path
+        self._time = time.time()
+        self.date = datetime.fromtimestamp(self._time).replace(microsecond=0)
+        self.size = size
+        self.files_number = 0
+        self._comment = comment
+        self.fromDevice = False
+
+    def getPath(self):
+        """Return object path."""
+        return self.path
+
+    def getName(self):
+        """Return object name."""
+        return self._name
+
+    def getDate(self):
+        """Return object creation date."""
+        return self.date
+
+    def getComment(self):
+        """Return object _comment attribute."""
+        return self._comment
+
+    def getSize(self):
+        """Return object file size."""
+        return self.size
+    
+    def getTime(self):
+        """ Returns the object creation time in seconds since epoch. """
+        return self._time
+    
+    def getFilesNumber(self):
+        """ Return number of files this backup holds. """
+        return self.files_number
+
+    def setComment(self, new_comment):
+        """Set object _comment attribute to the given string"""
+        self._comment = new_comment
+
+    def setName(self, new_name):
+        """Set object name to a new name"""
+        self._name = new_name
+        
+    def setDate(self, newDate):
+        self.date = newDate
+    
+    def setFilesNumber(self, number_of_files):
+        """ Set number of files this backup holds to number_of_files ."""
+        self.files_number = number_of_files
+        
+    def setAtDevice(self, bool=False):
+        self.fromDevice = bool
diff --git a/src/backup/pcsbackuplistui.py b/src/backup/pcsbackuplistui.py
new file mode 100644 (file)
index 0000000..daca374
--- /dev/null
@@ -0,0 +1,110 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PCSBackupListUi(QTableView):
+    
+    ''' Class that creates a table, where the backups will be shown '''
+    
+    def __init__(self, backupManager):
+        super(PCSBackupListUi, self).__init__()
+        
+        self.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
+        self.setAlternatingRowColors(True)
+        self.setShowGrid(False)
+        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.model = QStandardItemModel()
+        self.setModel(self.model)
+        
+        hHeader = QHeaderView(Qt.Horizontal)
+        hHeader.setObjectName("listHeader")
+        hHeader.setAttribute(Qt.WA_NoSystemBackground)
+        hHeader.setStretchLastSection(True)
+        hHeader.setResizeMode(QHeaderView.ResizeToContents)
+        hHeader.setMinimumSectionSize(100)
+
+        hHeader.setClickable(False)
+
+        self.setHorizontalHeader(hHeader)
+        
+        vHeader = QHeaderView(Qt.Vertical)
+        vHeader.setVisible(False)
+        self.setVerticalHeader(vHeader)
+        self._backupManager = backupManager
+        
+    def updateBackupList(self):
+        self.model.clear()
+        self.model.setHorizontalHeaderItem(0, QStandardItem("NAME"))
+        self.model.setHorizontalHeaderItem(1, QStandardItem("SIZE"))
+        self.model.setHorizontalHeaderItem(2, QStandardItem("DATE"))
+
+        backupList = self._backupManager.getBackupList()
+        for backupInfo in backupList:
+            name = backupInfo.getName()
+            date = str(backupInfo.getDate())
+            size = self._formatBackupSize(backupInfo.getSize())
+            backupData = [QStandardItem(name), QStandardItem(size), QStandardItem(date)]
+            self.model.appendRow(backupData)
+
+    def removeSelectedBackups(self):
+        selectionModel = self.selectionModel()
+        indexList = selectionModel.selectedRows()
+        for index in reversed(sorted(indexList)):
+            if index.isValid():
+                row = index.row()
+                data = self.model.itemData(index)
+                backupName = data[0].toString()
+                if self._backupManager.removeBackup((str(backupName).strip())):
+                    self.model.removeRow(row)
+        self.updateBackupList()
+
+    def renameSelectedBackup (self, newName):
+        #!!!!!!! getSelectedBackup
+        backupName = (str(self.getSelectedBackup())).strip()
+        if backupName != None:
+            if self._backupManager.renameBackup(backupName, newName):
+                self.updateBackupList()
+                return True
+        
+        return False
+    
+    def getSelectedBackup(self):
+        list = self.getSelectedBackupList()
+        if list and len(list) > 0:
+            return list[0]
+        
+        return None
+    
+    def getSelectedBackupList(self):
+        selectionModel = self.selectionModel()
+        indexList = selectionModel.selectedRows()
+        backupList = []
+        for index in indexList:
+            if index.isValid():
+                row = index.row()
+                data = self.model.itemData(index)
+                backupList.append(data[0].toString())
+        return backupList
+
+    def getBackupManager(self):
+        return self._backupManager
+            
+    def _formatBackupSize(self, size):
+        """ Return a string with a more suited size and byte multiple for the
+        received size.
+        
+        Attributes:
+            String/Float/Int size - size in bytes or string representing it.
+        
+        """
+        size = float(size)
+        multiples = ["B", "KB", "MB", "GB"]
+        divisions = 0
+        while size > 1000 and divisions <= 3:
+            size = size / 1024.
+            divisions += 1
+            
+        return "%.1f %s" % (size, multiples[divisions])
diff --git a/src/backup/pcsbackuplocation.py b/src/backup/pcsbackuplocation.py
new file mode 100644 (file)
index 0000000..ab5d942
--- /dev/null
@@ -0,0 +1,11 @@
+# Class Backup_Category holds osso-backup .conf files informations
+
+class PcsBackupLocation:
+    """Backup_Location class.
+    Used for holding location attributes from parsed osso-backup xml files.
+
+    """
+    def __init__(self, type, category, path):
+        self.category = category
+        self.type = type
+        self.path = path
diff --git a/src/backup/pcsbackupmanager.py b/src/backup/pcsbackupmanager.py
new file mode 100644 (file)
index 0000000..92a5cc7
--- /dev/null
@@ -0,0 +1,168 @@
+import os
+
+from PyQt4.QtCore import *
+from zipfile import *
+
+import pcsbackuputils as utils
+
+
+HOME = os.path.expanduser("~")
+USER_HOST = "root"
+DEVICES_POINT = "%s/.pcsuite/devices/" % HOME
+
+
+class PcsBackupManager(QObject):
+
+    def __init__(self):
+        QObject.__init__(self)
+        self._backupList = []
+
+    def loadBackups(self):
+        return False
+
+    def saveBackups(self):
+        return False
+
+    def getBackupList(self):
+        return None
+    
+    def createBackup(self, backup_name, path, host_ip, categories, comment=""):
+        return False
+
+    def removeBackup(self, backup_name):
+        return False
+
+    def getBackupInfo(self, backupName):
+        return None
+    
+    def renameBackup(self, backupName, newName):
+        return False
+    
+    def changeBackupComment(self, backupName, new_comment):
+        return False
+    
+    def listBackupContent(self, backupName):
+        content = []
+        backupInfo = self.getBackupInfo(backupName)
+        backupPath = backupInfo.getPath()
+        fullPath = os.path.join(str(backupPath), str(backupName))
+        
+        for entry in os.listdir(fullPath):
+            if entry.endswith(".zip"):
+                zipfile = utils.openZip(os.path.join(fullPath, entry), "r")
+                for member in zipfile.namelist():
+                    folders = member.split("/")
+                    memberName = "../" + "/".join([folders[-2], folders[-1]])
+                    content.append(memberName)
+        return content
+    
+    def restoreBackup(self, backupInfo, host_ip, categories):
+        """ Restore a PC backup to device with given IP address.
+        
+        Attributes:
+        String backupInfo - Object representing the backup
+        String host_ip - IP address of device.
+        Dictionary categories - dictionary with categories as keys and with
+                            value True if that category should be restored.
+                            
+        """
+        self.setRestoreInProgress(True)
+        # Set restore needed paths
+        devicePath = os.path.join(DEVICES_POINT, "%s" % host_ip)
+        mountPath = os.path.join(devicePath, "Root" )
+        tempPath = os.path.join(mountPath, "tmp/paths")
+        restScriptsPath = ("/etc/osso-backup/restore.d/always")
+        try:
+            utils.mountDevice(USER_HOST, host_ip, mountPath)
+            # Get backup location depending from backup source
+            if backupInfo == None:
+                return False
+            if backupInfo.fromDevice:
+                backup_path = backupInfo.getPath()
+            else:
+                backup_path = os.path.join(str(backupInfo.getPath()), 
+                                           str(backupInfo.getName()))
+            # Get backup files list for each category and write it on a file
+            # that will be needed by restore scripts.
+            pathsDictonary = utils.getBackupFilesPath(backup_path)
+            if utils.writeBackupFilesPath(pathsDictonary, tempPath) == False:
+                return False
+            # --- Initialize restore progress ---
+            currentSize = 0
+            # Get total number of files to restore
+            numberOfFiles = 0
+            for categ in pathsDictonary:
+                for file in pathsDictonary[categ]:
+                    numberOfFiles += 1
+            # Get size of all categories being restored
+            totalSize = 0
+            for file in os.listdir(backup_path):
+                if file.endswith(".zip"):
+                    categ = file[:-4]
+                    if categories[categ]:
+                        catPath = os.path.join(backup_path, file)
+                        zip = utils.openZip(catPath)
+                        for member in zip.namelist():
+                            totalSize += zip.getinfo(member).file_size
+            # Extract zip files to device
+            for entry in os.listdir(backup_path):
+                category = entry[:-4]
+                if entry.endswith(".zip") and categories[category]:
+                    zipPath = os.path.join(backup_path, entry)
+                    zip = utils.openZip(zipPath)
+                    # Update restore progress, extract current f print "member %s: %.2f" % (member, zip.getinfo(member).file_size)ile and emit
+                    # progress sinal
+                    for member in zip.namelist():
+                        if not self.restoreInProgress:
+                            return 0
+                        percentage = "%.1f" % self.computePercentage(totalSize,
+                                                                currentSize)
+                        
+                        status = (percentage, category, numberOfFiles, totalSize)
+                        self.emit(SIGNAL("restoreProgress"), status)
+                        zip.extract(member, devicePath)
+                        currentSize += zip.getinfo(member).file_size
+                    percentage = "%.1f" % ((currentSize / float(totalSize)) * 100)
+                    status = (percentage, category, numberOfFiles, totalSize)
+                    self.emit(SIGNAL("restoreProgress"), status)
+                    zip.close()
+            # Execute restore scripts
+            os.system("ssh %s@%s ..%s/*.sh %s" % (USER_HOST, host_ip, 
+                                                  restScriptsPath, tempPath))
+            self.setRestoreInProgress(False)
+            # --- Restore finished ---
+        finally:
+            utils.unmountDevice(mountPath)
+            
+    
+    def computePercentage(self, totalSize, currentSize):
+        if totalSize == 0:
+            percentage = 100
+        else:
+            percentage = (currentSize / float(totalSize)) * 100
+            if percentage > 100:
+                percentage = 100
+        return percentage
+    
+    def copy(self, sourcePath, destinationPath):
+        numberOfFiles = 0
+        for entry in os.listdir(sourcePath):
+            zipPath = os.path.join(sourcePath, entry)
+            if zipPath.endswith(".zip"):
+                zip = utils.openZip(zipPath)
+                numberOfFiles += len(zip.namelist())
+        totalSize = float(utils.getSize(sourcePath))
+        currentSize = 0
+        self.emit(SIGNAL("copyProgress"), ("0.00", numberOfFiles, totalSize))
+        for entry in os.listdir(sourcePath):
+            if not self.copyInProgress:
+                utils.removePath(destinationPath)
+                return 0
+            entryPath = os.path.join(sourcePath, entry)
+            utils.copy(entryPath, destinationPath)
+            currentSize += utils.getSize(entryPath)
+            progress = "%.2f" % ((currentSize / totalSize) * 100)
+            self.emit(SIGNAL("copyProgress"), (progress, numberOfFiles,
+                                                    totalSize))
+            
+    
\ No newline at end of file
diff --git a/src/backup/pcsbackupmanagerui.py b/src/backup/pcsbackupmanagerui.py
new file mode 100644 (file)
index 0000000..2fdc32b
--- /dev/null
@@ -0,0 +1,502 @@
+# 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"))
+        
+        
+        
+        
diff --git a/src/backup/pcsbackupparser.py b/src/backup/pcsbackupparser.py
new file mode 100644 (file)
index 0000000..c950a6e
--- /dev/null
@@ -0,0 +1,115 @@
+# Module used to parse osso-backup xml conf files, retrieving categories and
+# backup paths information
+
+import os.path
+import xml.dom
+import xml.dom.minidom
+
+from pcsbackuplocation import *
+
+
+class PcsBackupParser:
+    """Holds a list of Backup_location objects
+
+    Can parse .conf xml files with osso-backup format at the given path with
+    fill_locations_list, creating Backup_location objects based on type,
+    category and path of each location inside each xml file and then holding
+    all objects in the locations_list attribute.
+
+    """
+    def __init__(self):
+        self.locationsDict = {}
+        
+    def getLocationsDict(self):
+        return self.locationsDict
+        
+    def addLocation(self, location):
+        """Add a location to locations_list attribute of theis class.
+
+        Arguments:
+        location -- the location object to be added
+
+        """
+        category = location.category
+        if category in self.locationsDict.keys():
+            self.locationsDict[category].append(location)
+        else:
+            self.locationsDict[category] = [location]
+
+    def fillLocationsDict(self, path):
+        """Add all locations that can be found inside xml files of the given
+        path.
+
+        This method reads all .conf files inside the directory path given and
+        puts on its locations_list attribute all the Backup_location objects
+        created with the informations returned from the files parsing.
+
+        Arguments:
+        path -- Path of directory containing files to parse
+
+        """
+        for file in os.listdir(path):
+            if file.endswith(".conf"):
+                locations = self.locationsFromFile(os.path.join(path, file))
+                for location in locations:
+                    self.addLocation(location)
+
+    def locationsFromFile(self, xml_file):
+        """Return a list with all locations objects inside the given file.
+
+        The file is parsed and all informations retrieved from it are used to
+        create Backup_location objects and these objects are appended to a list
+        that is returned to caller.
+
+        Arguments:
+        xml_file -- File to parse
+
+        Returns:
+        locations -- List with all Backup_location objects created from file
+
+        """
+        locations_map = self._parser(xml_file)
+        locations = []
+        number_of_locations = len(locations_map["types"])
+        for i in range(number_of_locations):
+            type = locations_map["types"][i]
+            category = locations_map["categories"][i]
+            path = locations_map["paths"][i]
+            path = self._fixPath(path)
+            new_loc = PcsBackupLocation(type, category, path)
+            locations.append(new_loc)
+        return locations
+    
+
+    def _parser(self, xml_file):
+        # Parses the xml_file, divide each location element information on a
+        # dictonary with key to respective information.
+        # Dictonary format:
+        # { "types": list of types in order of location appereance,
+        #   "categories": list of categories ordered like types
+        #   "paths" list of install paths in the same order as the others }
+        dom = xml.dom.minidom.parse(xml_file)
+        types = []
+        categories = []
+        paths = []
+        for node in dom.getElementsByTagName("location"):
+            type = node.getAttribute("type")
+            category = node.getAttribute("category")
+            path = node.childNodes[0].data.strip()
+            types.append(type)
+            categories.append(category)
+            paths.append(path)
+
+        location_map = {"types": types, "categories": categories, "paths": paths}
+        return location_map
+
+    def _fixPath(self, path):
+        # Fix any file path containing device specific constants, modifying
+        # them to its values
+        modifications = {"$HOME":"/home/user", "$USER":"user"}
+        for key in modifications.keys():
+            path = path.replace(key, modifications[key])
+        if not path.startswith("/"):
+            path = "/".join(path)
+        return path
+
diff --git a/src/backup/pcsbackuputils.py b/src/backup/pcsbackuputils.py
new file mode 100755 (executable)
index 0000000..8dfa7fe
--- /dev/null
@@ -0,0 +1,184 @@
+
+from pcsbackupinfo import *
+import zipfile
+import os
+import xml.dom.minidom
+
+
+def copyOssoBackupConfigFiles(destination, mountPath):    
+    """ Copy all osso-backup .conf files to the given path. The device must be
+    already mounted in the mountPath.
+    
+    Attributes:
+    - String mountPath - Path of the folder where the device is mounted
+    - String destination - Destination folder path where config files should be
+            copied to.
+            
+    """
+    os.system("cp %s/etc/osso-backup/applications/*.conf %s" %
+        (mountPath, destination))
+          
+     
+def mountDevice(user, ip, path):
+    # Mount device file system using sshfs in the given path
+    try:
+        if not os.path.exists(path):
+            createFolder(path)
+        os.system('sshfs %s@%s:/ %s' % (user, ip, path))
+    except:
+        raise Exception("Error while mounting device file system")
+
+
+def unmountDevice(path):
+    try:
+        os.system('fusermount -uz %s' % path)
+    except:
+        raise Exception("Error while unmounting device file system")
+        
+        
+def createFolder(complete_path):
+    if not os.path.exists(complete_path):
+        os.makedirs(complete_path)
+
+    # FIXME
+    return True
+
+
+def removePath(complete_path):
+    for entry in os.listdir(complete_path):
+        if os.path.isdir(entry):
+            removePath(os.path.join(complete_path, entry))
+        else:
+            os.remove(os.path.join(complete_path, entry))
+    os.rmdir(complete_path)
+   
+    
+def getDeviceBackupList(mountPoint):
+    """This function return a list of backupInfo objects for each backup found
+    in the mount point.
+    
+    """
+    deviceBackups = []
+    mmc1 = '%s/media/mmc1/backups' % mountPoint
+    mmc2 = '%s/media/mmc2/backups' % mountPoint
+    
+    if os.path.exists(mmc1):
+        deviceBackups += _getDeviceBackupsInfo(mmc1)
+    if os.path.exists(mmc2):
+        deviceBackups += _getDeviceBackupsInfo(mmc2)
+        
+    return deviceBackups
+        
+        
+def copy(original, destination):
+    original = original.replace(" ", "\ ")
+    destination = destination.replace(" ", "\ ")
+    createFolder(destination)
+    os.system("cp %s %s" % (original, destination))
+
+
+def getSize(path):
+    if not os.path.exists(path):
+        return False
+    if os.path.isdir(path):
+        files_and_folders = os.listdir(path)
+        sum_size = 0
+        for entry in files_and_folders:
+            if os.path.isdir(os.path.join(path, entry)):
+                sum_size += getSize(os.path.join(path, entry))
+            else:
+                try:
+                    sum_size += os.stat(os.path.join(path, entry)).st_size
+                except:
+                    sum_size += 1
+        return sum_size
+    else:
+        return os.stat(path).st_size
+
+        
+def getBackupFilesPath(backupPath):
+    dic = {}
+    for entry in os.listdir(backupPath):
+        if entry.endswith(".zip"):
+            zip = openZip(os.path.join(backupPath, entry))
+            dic[entry.replace(".zip", "")] = zip.namelist()
+    return dic
+
+
+def getBackupCategories(backupInfo):
+    backupPath = str(backupInfo.path)
+    if not backupInfo.fromDevice:
+        backupPath = os.path.join(backupPath, str(backupInfo._name))
+    categoriesList = []
+    for entry in os.listdir(backupPath):
+        if entry.endswith(".zip"):
+            categoriesList.append(entry.replace(".zip", ""))
+    return categoriesList
+
+
+def writeBackupFilesPath(paths_dictionary, file_path):
+    try:
+        file = open(file_path, "w")
+    except:
+        return False
+    for category in paths_dictionary.keys():
+        file.write("[" + category + "]\n")
+        for path in paths_dictionary[category]:
+            file.write(path + "\n")
+    
+    file.close()
+    
+def openZip(zipPath, mode="r"):
+    """ Open a .zip file using python ZipFile library.
+        
+        Attributes:
+            String zipPath - The directory path to the file
+            String mode - "w" to open file for writting.
+                        "a" to open file for appending.
+                        "r" to open file for reading.
+                
+    """
+    try:
+        zip = zipfile.ZipFile(zipPath, mode)
+        return zip
+    except zipfile.BadZipfile, msg:
+        raise IOError("Problem while opening %s: %s" % (zipPath, msg))
+    except:
+        raise
+
+def closeZip(zipfile):
+    zipfile.close()
+    
+def zip(zipfile, path):
+    # Compress the file in the given path to the zipfile
+    try:
+        zipfile.write(path.encode('UTF'))
+        return True
+    except:
+        return False
+    
+def rebootDevice(deviceIp):
+    return os.system("ssh root@%s reboot" % deviceIp) == 0
+    
+
+def _parseMetadata(metadata_path):
+    document = xml.dom.minidom.parse(metadata_path)
+    node = document.getElementsByTagName("size")[0]
+    size = int(str(node.firstChild.nodeValue))
+    node = document.getElementsByTagName("timestamp")[0]
+    objDate = datetime.fromtimestamp(float(str(node.firstChild.nodeValue)))
+    return size, str(objDate)
+
+def _getDeviceBackupsInfo(memoryCardPath):
+    deviceBackups = []
+    for backup in os.listdir(memoryCardPath):
+        temporaryFolder = os.path.join(memoryCardPath, backup)
+        if os.path.isdir(temporaryFolder):
+            metadataPath = os.path.join(temporaryFolder,'backup.metadata')
+            if os.path.exists(metadataPath):
+                size, date = _parseMetadata(metadataPath)
+                backupInfo = PcsBackupInfo(backup, temporaryFolder, size)
+                backupInfo.setDate(date)
+                deviceBackups.append(backupInfo)
+    return deviceBackups
+        
diff --git a/src/backup/pcsbackupwizard.py b/src/backup/pcsbackupwizard.py
new file mode 100644 (file)
index 0000000..bd16fc5
--- /dev/null
@@ -0,0 +1,180 @@
+from time import sleep
+import threading
+
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+
+from pcsprogresswizard import *
+from pcscheckboxwizard import *
+from pcsopenfilewizard import *
+from pcspcbackupmanager import *
+from pcsdevicemanager import *
+
+class PcsBackupWizard(QWizard):
+    
+    ''' Class that creates a wizard responsible for doing backup '''
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizard.__init__(self, parent)
+        self.windowManager = windowManager
+        self.deviceInfo = deviceInfo
+        stylesheet = '''QWizard{background-image:url('''+ BACKUP_BG + ''')};'''
+        self.setStyleSheet(stylesheet)       
+        self.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self.setWindowTitle("%s Backup" % APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH,WINDOW_HEIGHT)
+        
+        self.setButtonLayout([])
+        self.setWizardStyle(4)
+        
+        self.checkboxPage = PcsCheckboxWizard(self.deviceInfo, windowManager, self)
+        self.addPage(self.checkboxPage)
+        
+        self.chooseFilePage = PcsOpenFileWizard(self.deviceInfo, windowManager, self)
+        self.connect(self.chooseFilePage.finishButton, SIGNAL("clicked()"), 
+                     self.noNameTest)
+        self.addPage(self.chooseFilePage)
+        
+        self.progressWizard = PcsProgressWizard(self.deviceInfo,self, windowManager, self)
+        self.connect(self.progressWizard.cancelButton, SIGNAL("clicked()"), 
+                     self._confirmsCancel)
+        self.connect(self.progressWizard.doneButton, SIGNAL("clicked()"), self._done)
+        self.connect(self.progressWizard, SIGNAL("destroyed()"), self.test)
+        self.addPage(self.progressWizard)
+    
+    def test(self):
+        print "entrou caraiiiiii"
+    
+    def noNameTest(self):
+        if(str(self.chooseFilePage.getBackupName()).strip() == ""):
+            message = "Your backup name can't be blank."
+            showMessageBox(message, "Backup name blank")
+        else:
+            self.doNewBackup()
+            self.next()
+    
+    def _done(self):
+        self.done(0)
+        self.progressWizard._resetPage()
+        self.chooseFilePage._resetPage()
+    
+    def doNewBackup(self):
+        
+        hostIp = self.deviceInfo.ip
+        backupName = self.chooseFilePage.getBackupName()
+        backupPath = self.chooseFilePage.getPath()
+        categories = self.checkboxPage.getCategories()
+        self.backupManager = PcsPcBackupManager()
+        self.backupManager.loadBackups()
+        comments = ""
+        
+        self._updateThread = UpdateBackupProgress(backupName, backupPath, 
+                                                  hostIp,categories, comments, 
+                                                  self.backupManager, 
+                                                  self.progressWizard)
+        self.connect(self._updateThread, SIGNAL("backupFinished"),
+                      self._onBackupDone)        
+        self.connect(self._updateThread, SIGNAL("backupCanceled"),
+                      self._onBackupCancel)
+        self.connect(self._updateThread, SIGNAL("backupNameChanged"),
+                      self._onBackupNameChanged)
+        self.connect(self._updateThread, SIGNAL("backupProgress"),
+                      self._updateCategoriesAndProgress)
+        
+        self._updateThread.start()
+        
+    def _updateCategoriesAndProgress(self, information):
+        progress, category = information
+        self.progressWizard.setProgress(progress)
+        self.progressWizard.setCategory(category)
+        
+        
+    def _onBackupDone(self, info):
+        self.progressWizard.updateInfo(info[0], info[1])
+        self.progressWizard.progressDone()
+        self.windowManager.getBackupManager().pcListView.updateBackupList()
+
+    def _onBackupNameChanged(self, correct_name):
+        """
+        Check if backup name was changed and show message case positive.
+        """
+        nameChangeMessage = "Backup with same name was found in" + \
+                                    " backup list, Backup name changed to %s" \
+                                     % correct_name
+        showMessageBox(nameChangeMessage, "Backup name changed")
+    
+    def _confirmsCancel(self):
+        """
+        Confirms the backup canceling.
+        """
+        dialog = QMessageBox()
+        dialog.setText("Do you really want cancel this backup?")
+        dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+        dialog.setWindowFlags(Qt.FramelessWindowHint)
+        dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
+        ret = dialog.exec_()
+        if ret == QMessageBox.Yes:
+            self._onBackupCancel()
+    
+    def _onBackupCancel(self):
+        """
+        Stops current backup process in backup manager.
+        Also, shows a message box informing about canceling.
+        
+        """
+        self.progressWizard.progressCanceled()
+        self.backupManager.setBackupInProgress(False)
+        
+    def setVisible (self, visible):
+        if(visible == False):
+            self.emit("")
+                
+        
+class UpdateBackupProgress(QThread):
+    
+    def __init__(self, backupName, path, hostIp, categories, comment, 
+                 backupManager, progressWizard):
+        QThread.__init__(self)
+
+        self.backupName = backupName
+        self.path = path
+        self.hostIp = hostIp
+        self.categories = categories
+        self.comment = comment
+        self.backupManager = backupManager
+        
+        
+    def run(self):
+        self._backupFlag = True
+        
+        self.correctName = self.backupManager._verify_backup_name(self.backupName)
+        self.nameChanged = self.correctName != self.backupName
+        
+        self.connect(self.backupManager, SIGNAL("backupProgress"), self._reEmitSignal)
+        self.connect(self.backupManager, SIGNAL("backupDone"), self._onBackupDone)
+        res = self.backupManager.createBackup(self.correctName, self.path,
+                                         self.hostIp, self.categories, 
+                                         self.comment)
+        
+        while (self._backupFlag):
+            sleep(0.1)
+            
+    def _reEmitSignal(self, informations):
+        self.emit(SIGNAL("backupProgress"), informations)
+    
+    def _onBackupDone(self, res, info):
+        self._backupFlag = False
+        # If backup was not canceled, emit done signal
+        if res != 0:
+            if self.nameChanged:
+                self.emit(SIGNAL("backupNameChanged"), self.correctName)
+            self.emit(SIGNAL("backupFinished"), info)
+        else:
+            self.emit(SIGNAL("backupCanceled"))
+
+        
\ No newline at end of file
diff --git a/src/backup/pcsbackupxml.py b/src/backup/pcsbackupxml.py
new file mode 100644 (file)
index 0000000..0bf3905
--- /dev/null
@@ -0,0 +1,87 @@
+'''
+@author: Nicholas Alexander
+
+Created on 07/07/2009
+
+Module with functions used to create backup metadata xml file with same format
+as osso-backup metadata.
+
+'''
+import os
+
+import xml.dom.minidom
+
+from backup.pcsbackuputils import getSize
+from pcsdevicemanager import PcsDeviceManager
+
+
+def createXml(backup_info, filesByCategory, host_ip):
+    doc = xml.dom.minidom.Document()
+    root = doc.createElement("backup-metadata")
+    doc.appendChild(root)
+    _appendSizeNode(backup_info, doc, root)
+    _appendFilesNumberNode(backup_info, doc, root)
+    _appendTimeNode(backup_info, doc, root)
+    _appendProtectedNode(doc, root)
+    _appendDeviceInfoNode(doc, root, host_ip)
+    backupFullPath = os.path.join(backup_info.getPath(), backup_info.getName())
+    _appendCategoriesNode(doc, root, filesByCategory, backupFullPath)
+    metadata_path = os.path.join(backupFullPath, "backup.metadata")
+    file = open(metadata_path, "w")
+    doc.writexml(file)
+    file.close()
+
+
+
+def _appendSizeNode(backupInfo, document, node):
+    sizeNode = document.createElement("size")
+    size = document.createTextNode(str(backupInfo.getSize()))
+    sizeNode.appendChild(size)
+    node.appendChild(sizeNode)
+    
+def _appendFilesNumberNode(backupInfo, document, node):
+    filesNode = document.createElement("number-of-files")
+    files = document.createTextNode(str(backupInfo.getFilesNumber()))
+    filesNode.appendChild(files)
+    node.appendChild(filesNode)
+    
+def _appendTimeNode(backupInfo, document, node):
+    timeNode = document.createElement("timestamp")
+    time = document.createTextNode(str(int(backupInfo.getTime())))
+    timeNode.appendChild(time)
+    node.appendChild(timeNode)
+
+def _appendProtectedNode(document, node):
+    protectedNode = document.createElement("protected")
+    protected = document.createTextNode("false")
+    protectedNode.appendChild(protected)
+    node.appendChild(protectedNode)
+    
+def _appendDeviceInfoNode(document, node, hostIp):
+    deviceManager = PcsDeviceManager()
+    deviceManager.loadDevices()
+    device = deviceManager.getDevice(hostIp)
+    versionNode = document.createElement("device-version")
+    version = document.createTextNode(device.ossoBackup)
+    versionNode.appendChild(version)
+    node.appendChild(versionNode)
+    
+def _appendCategoriesNode(document, node, filesByCategory, backupPath):
+    categories = document.createElement("categories")
+    for category in filesByCategory.keys():
+        categoryPath = os.path.join(backupPath, "%s.zip" % category)
+        size = getSize(categoryPath)
+        if size == False:
+            continue
+        categoryNode = document.createElement("%s" % category)
+        categorySize = document.createElement("size")
+        categoryFiles = document.createElement("number-of-files")
+        filesText = document.createTextNode(str(filesByCategory[category]))
+        sizeText = document.createTextNode(str(size))
+        categorySize.appendChild(sizeText)
+        categoryFiles.appendChild(filesText)
+        categoryNode.appendChild(categorySize)
+        categoryNode.appendChild(categoryFiles)
+        categories.appendChild(categoryNode)
+    node.appendChild(categories)
+        
\ No newline at end of file
diff --git a/src/backup/pcscheckboxwizard.py b/src/backup/pcscheckboxwizard.py
new file mode 100644 (file)
index 0000000..7745894
--- /dev/null
@@ -0,0 +1,292 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsbutton import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcscustombuttons import PcsCustomButton as customButton
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+
+class PcsCheckboxWizard(QWizardPage):
+       
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        self.deviceInfo = deviceInfo
+        self.windowManager = windowManager
+        
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.layout.setSpacing(0)
+        buttonsLayout = self._menuButtons()
+        self.layout.addLayout(buttonsLayout)
+        self.layout.addItem(QSpacerItem(0, 8))
+        wayLayout = self._wayLayout()
+        self.layout.addLayout(wayLayout)
+
+        self.layout.addItem(QSpacerItem(0, 10))
+
+        self.hlayout = QHBoxLayout()
+        self.hlayout.setMargin(0)
+        
+        self.vertical = QVBoxLayout()
+        self.vertical.setMargin(0)
+        self.vertical.setSpacing(0)
+        self.create_vertical_components()
+        self.hlayout.addLayout(self.vertical)
+        self.hlayout.setMargin(0)
+        self.hlayout.setSpacing(0)
+        
+        self.create_checkbox_frame()
+#        self.hlayout.addItem(QSpacerItem(30, 0))
+        self.layout.addLayout(self.hlayout)
+        
+        self.layout.addItem(QSpacerItem(0, 35))
+        informationLayout = QHBoxLayout()
+        informationLayout.setMargin(0)
+        spc = QSpacerItem(10, 0)
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        information = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Select the types of file you wish to backup.</font>")
+        informationLayout.addItem(spc)
+        informationLayout.addWidget(iconAlert)
+        informationLayout.addWidget(information, Qt.AlignLeft)
+
+        self.layout.addLayout(informationLayout)
+        
+        self.setLayout(self.layout)
+        self.map_checked = {self.documents.name: False,
+                            self.emails.name: False, self.media.name: False,
+                            self.contacts.name: False, 
+                            self.bookmarks.name: False,
+                            self.settings.name: False, 
+                            self.applications.name: False}
+        self.enableNext = QLineEdit()
+        self.registerField("enableNext*", self.enableNext)
+    
+    def _wayLayout(self):
+        barLayout = QHBoxLayout()
+        barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow = self._arrow()
+        arrow2 = self._arrow()
+        spc = QSpacerItem(5, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #FFFFFF'; size=2>Files</font>")
+        widgetList = [main, arrow, newBackup, arrow2, files]
+        for widget in widgetList:
+            barLayout.addWidget(widget, Qt.AlignLeft)
+            barLayout.addItem(spc)
+        barLayout.addItem(QSpacerItem(300, 0))
+        return barLayout
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label
+            
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout   
+    
+    def _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.wizard().geometry())
+            backupManager.show()
+            self.wizard().close()
+            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.wizard().geometry())
+            restoreBackup.show()
+            self.wizard().close()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    def _goNextPage(self):
+        if self.empty_map():
+            return False
+        else:
+            self.wizard().next()
+    
+    
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def create_checkbox_frame(self):
+        layout = QVBoxLayout()
+        l = QLabel()
+        l.setPixmap(QPixmap(COPY_BORDER))
+       
+        self.frame = QScrollArea(self)
+        self.frame.setWidgetResizable(True)
+        widget = QWidget(self.frame)
+        widget.setStyleSheet("QWidget{background: transparent;}")
+        self.grid = QGridLayout()
+        self.grid.setSpacing(0)
+        self.createCheckboxPanel()
+        widget.setLayout(self.grid)
+        self.frame.setWidget(widget)
+        layout.addItem(QSpacerItem(0,25))
+        layout.addWidget(self.frame)
+        self.hlayout.addLayout(layout)
+        
+    
+    def empty_map(self):
+        for index in self.map_checked.keys():
+            if self.map_checked[index]:
+                return False
+        return True
+        
+    def createCheckboxPanel(self):
+        #Add Checkboxes
+#        self.add_select_all()
+        self.add_documents()
+        self.add_emails()
+        self.add_media()
+        self.add_contacts()
+        self.add_bookmarks()
+        self.add_settings()
+        self.add_applications()            
+        
+#    def add_select_all(self):
+#        self.select_all = QCheckBox("Select All")
+#        self.connect(self.select_all, SIGNAL("stateChanged(int)"), 
+#                     self.select_all_func)
+#        self.grid.addWidget(self.select_all, 0, 0, Qt.AlignTop)          
+#    
+    def add_documents(self):
+        self.documents = QCheckBox("Documents")
+        self.documents.name = "documents"
+        callback = partial(self.select_func, self.documents)
+        self.connect(self.documents, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.documents, 1, 0, Qt.AlignTop)
+    
+    def add_emails(self):
+        self.emails = QCheckBox("Emails")
+        self.emails.name = "emails"
+        callback = partial(self.select_func, self.emails)
+        self.connect(self.emails, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.emails, 2, 0, Qt.AlignTop)
+    
+    def add_media(self):
+        self.media = QCheckBox("Media")
+        self.media.name = "media"
+        callback = partial(self.select_func, self.media)
+        self.connect(self.media, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.media, 3, 0, Qt.AlignTop)
+    
+    def add_contacts(self):
+        self.contacts = QCheckBox("Contacts")
+        self.contacts.name = "contacts"
+        callback = partial(self.select_func, self.contacts)
+        self.connect(self.contacts, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.contacts, 4, 0, Qt.AlignTop)
+    
+    def add_bookmarks(self):
+        self.bookmarks = QCheckBox("Bookmarks")
+        self.bookmarks.name = "bookmarks"
+        callback = partial(self.select_func, self.bookmarks)
+        self.connect(self.bookmarks, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.bookmarks, 5, 0, Qt.AlignTop)
+        
+    def add_settings(self):
+        self.settings = QCheckBox("Settings")
+        self.settings.name = "settings"
+        callback = partial(self.select_func, self.settings)
+        self.connect(self.settings, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.settings, 6, 0, Qt.AlignTop)
+
+    def add_applications(self):
+        self.applications = QCheckBox("Applications")
+        self.applications.name = "applications"
+        callback = partial(self.select_func, self.applications)
+        self.connect(self.applications, SIGNAL("stateChanged(int)"), 
+                     callback)
+        self.grid.addWidget(self.applications, 7, 0, Qt.AlignTop)
+
+#    def select_all_func(self):
+#        checked = self.select_all.isChecked()
+#        list = self.map_checked.keys()
+#        for element in list:
+#            self.map_checked[element] = checked
+#        for i in range(1,8):
+#            self.grid.itemAtPosition(i, 0).widget().setChecked(checked)
+#        
+    def select_func(self, checkbox):
+        checked = checkbox.isChecked()
+        self.map_checked[checkbox.name] = checked
+        if not checked:
+            list = []
+            for i in range(1,8):
+                item = self.grid.itemAtPosition(i, 0).widget()
+#                if item == self.select_all:
+#                    pass
+                if item.isChecked():
+                    list.append(item)
+#            self.select_all.setChecked(False)
+            for element in list:
+                element.setChecked(True)         
+        if self.empty_map():
+            self.enableNext.setText("")
+        else:
+            self.enableNext.setText("Next Button Enabled")
+            
+    def getCategories(self):
+        return self.map_checked
+        
+    def create_vertical_components(self):
+        deviceWidget = PcsDeviceWidget(2)
+        deviceWidget.setImage(DEVICE_DISCONNECTED)
+        deviceWidget.addBorder()
+        deviceWidget.addDeviceName()
+        deviceWidget.setDeviceInfo(self.deviceInfo)
+        self.vertical.addWidget(deviceWidget, Qt.AlignTop)
+        self.nextButton = QPushButton()
+        self.nextButton.setText("Next")
+        self.nextButton.setStyleSheet(BACKUP_BUTTON_STYLE)
+        self.connect(self.nextButton, SIGNAL("clicked()"), self._goNextPage)
+        self.vertical.addItem(QSpacerItem(0, 20))
+        buttonLayout = QHBoxLayout()
+        buttonLayout.addItem(QSpacerItem(5,0))
+        buttonLayout.addWidget(self.nextButton, Qt.AlignCenter)
+        self.vertical.addLayout(buttonLayout)
+        self.vertical.addItem(QSpacerItem(0,10))
+        
\ No newline at end of file
diff --git a/src/backup/pcsdevicebackupmanager.py b/src/backup/pcsdevicebackupmanager.py
new file mode 100644 (file)
index 0000000..095bfd7
--- /dev/null
@@ -0,0 +1,102 @@
+
+from pcsbackupmanager import *
+from pcspcbackupmanager import PcsPcBackupManager
+from pcsbackupinfo import PcsBackupInfo
+import pcsbackuputils as utils
+
+
+class PcsDeviceBackupManager(PcsBackupManager):
+
+
+    def __init__(self, deviceInfo):
+        PcsBackupManager.__init__(self)
+        self._backupList = []
+        self._deviceInfo = deviceInfo
+        self.restoreInProgress = False
+        self.copyInProgress = False
+
+    def loadBackups(self):
+        
+        # FIXME, error handling is wrong!! return list of PcsBackupInfo
+        try:
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % self._deviceInfo.ip)
+            utils.mountDevice(USER_HOST, self._deviceInfo.ip, mountPoint)
+            
+            self._backupList = utils.getDeviceBackupList(mountPoint)
+            return True
+
+        except Exception, x:
+            print str(x)
+        finally:
+            utils.unmountDevice(mountPoint)  
+            
+        return False          
+    def getBackupList(self):
+        self.loadBackups()
+        for backup in self._backupList:
+            backup.setAtDevice(True)
+        return self._backupList
+    
+    def copyBackupFromDevice(self, backupName, destinationPath):
+        try:
+            self.loadBackups()
+            device_backups = self.getBackupList()
+            
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % self._deviceInfo.ip)
+            utils.mountDevice(USER_HOST, self._deviceInfo.ip, mountPoint)
+    
+            # Search complete_path
+            completePath = ''
+            for backup in device_backups:
+                if backupName == backup.getName():
+                    completePath = backup.getPath()
+                    break
+            if completePath == '':
+                raise Exception("Backup not found.")
+            
+            pcBackupManager = PcsPcBackupManager()
+            pcBackupManager.loadBackups()
+            correctName = pcBackupManager._verify_backup_name(backupName)
+            destination = os.path.join(destinationPath, correctName)
+            
+            self.setCopyInProgress(True)
+            if self.copy(completePath, destination) == 0:
+                return 0
+            self.setCopyInProgress(False)
+            
+            backup_size = utils.getSize(destination)
+            backup = PcsBackupInfo(correctName, destinationPath, backup_size, 
+                                   'Copied from device')
+            backup.setAtDevice(False)
+            pcBackupManager._backupList.append(backup)
+            pcBackupManager.saveBackups()
+            
+        finally:
+            utils.unmountDevice(mountPoint)
+            
+            
+    def startBackupRestore(self, backupInfo, categories):
+        device_ip = self._deviceInfo.ip
+        return self.restoreBackup(backupInfo, device_ip, categories)
+    
+    
+    def setCopyInProgress(self, status):
+        self.copyInProgress = status
+        
+        
+    def setRestoreInProgress(self, status):
+        self.restoreInProgress = status
+        
+
+    def getBackupInfo(self, backupName):
+        self.loadBackups()
+        for backupInfo in self._backupList:
+            if backupInfo.getName() == backupName:
+                backupInfo.setAtDevice(True)
+                return backupInfo
+            
+        return None
+    
+            
+        
\ No newline at end of file
diff --git a/src/backup/pcsopenfilewizard.py b/src/backup/pcsopenfilewizard.py
new file mode 100644 (file)
index 0000000..313aac4
--- /dev/null
@@ -0,0 +1,264 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+import os
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+from style.styleTabletSuite import *
+
+
+class PcsOpenFileWizard(QWizardPage):
+    
+    _home_dir = os.path.expanduser("~")
+    _default_dir = _home_dir + "/.pcsuite/Backup"
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        
+        self.path = self._default_dir
+        self.file_name = "Backup"
+        self.deviceInfo = deviceInfo
+        self.windowManager = windowManager
+        
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.hLayout = QHBoxLayout()
+        self.hLayout.setMargin(0)
+        self.vLayout = QVBoxLayout()
+        self.vLayout.setMargin(0)
+        
+        wayLayout = self._wayLayout()
+        
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        spc = QSpacerItem(0, 12)
+        self.vLayout.addLayout(wayLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        self.vLayout.addItem(spc)
+        spc2 = QSpacerItem(350, 0)
+        self.finishButton = QPushButton("Finish")
+        self.finishButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.finishButton.setShortcut(Qt.Key_Return)
+        self.hLayout.addItem(spc2)
+        self.hLayout.addWidget(self.finishButton)
+        self.vLayout.addLayout(self.hLayout)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    def _wayLayout(self):
+        barLayout = QHBoxLayout()
+        barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow = self._arrow()
+        arrow2 = self._arrow()
+        arrow3 = self._arrow()
+        spc = QSpacerItem(2, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #333333'; size=2>Files</font>")
+        folder = QLabel("<font style='color: #FFFFFF'; size=2>Folder</font>")
+        widgetList = [main, arrow, newBackup, arrow2, files, arrow3, folder]
+        for widget in widgetList:
+            barLayout.addWidget(widget, Qt.AlignLeft)
+            barLayout.addItem(spc)
+        barLayout.addItem(QSpacerItem(300, 0))
+        return barLayout
+    
+    def _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.wizard().geometry())
+            backupManager.show()
+            self.wizard().close()
+            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.wizard().geometry())
+            restoreBackup.show()
+            self.wizard().close()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label   
+     
+    def _createDeviceWidget(self):
+        deviceWidget = PcsDeviceWidget(3)
+        deviceWidget.addBorder()
+        deviceWidget.addDeviceName()
+        deviceWidget.setDeviceInfo(self.deviceInfo)
+
+        return deviceWidget
+    
+    def _createInformationsLabel(self):
+        hLay = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        infLabel = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Do backup from Device to your PC.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(infLabel, Qt.AlignLeft)
+        
+        
+        return hLay
+
+    def _createCenterLayout(self):
+        hLay = QHBoxLayout()
+        hLay.setMargin(0)
+        vLay = QVBoxLayout()
+        vLay.setMargin(0)
+        hLayWithSpacer = QHBoxLayout()
+        hLayWithSpacer.setMargin(0)
+        spc = QSpacerItem(62, 0)
+        
+        deviceWidget = self._createDeviceWidget()
+        arrowLabel = self._createArrowLabel()
+        pcLabel = self._createPcLabel()
+        pathField = self._createPathField()
+        nameField = self._createBackupNameField()
+        
+        hLay.addWidget(deviceWidget, Qt.AlignVCenter)
+        hLay.addLayout(arrowLabel, Qt.AlignVCenter)
+        hLay.addLayout(pcLabel, Qt.AlignVCenter)
+        
+        vLay.addLayout(nameField)
+        vLay.addLayout(hLay)
+        vLay.addLayout(pathField)
+        
+        hLayWithSpacer.addItem(spc)
+        hLayWithSpacer.addLayout(vLay)
+        hLayWithSpacer.addItem(spc)
+        
+        return hLayWithSpacer
+
+    def _createArrowLabel(self):
+        arrowLayout = QGridLayout()
+        arrowLabel = QLabel()
+        arrowLabel.setPixmap(QPixmap(LARGE_ARROW_IMAGE))
+        borderArrowLabel = QLabel()
+        borderArrowLabel.setFixedSize(42, 65)
+        borderArrowLabel.setPixmap(QPixmap(LARGE_ARROW_BORDER))
+        arrowLayout.addWidget(arrowLabel, 0, 0, Qt.AlignCenter)
+        arrowLayout.addWidget(borderArrowLabel, 0, 0, Qt.AlignCenter)
+        return arrowLayout
+
+    def _createPcLabel(self):
+        gridLay = QGridLayout()
+        pcLabelLayout = QGridLayout()
+        pcLabel = QLabel()
+        pcLabel.setPixmap(QPixmap(PC_IMAGE))
+        pcBorder = QLabel()
+        pcBorder.setFixedSize(112, 127)
+        pcBorder.setPixmap(QPixmap(PC_BORDER_FILE))
+        nameLabel = QLabel("PC")
+        nameBorder = QLabel()
+        nameBorder.setPixmap(QPixmap(PC_NAME_BORDER_FILE))
+        nameBorder.setFixedSize(92, 26)
+        gridLay.addWidget(pcLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addWidget(nameLabel, 1, 0, Qt.AlignCenter)
+        gridLay.addWidget(nameBorder, 1, 0, Qt.AlignCenter)
+        pcLabelLayout.addLayout(gridLay, 0, 0, Qt.AlignCenter)
+        pcLabelLayout.addWidget(pcBorder, 0, 0, Qt.AlignCenter)
+        return pcLabelLayout
+
+    def _createPathField(self):
+        pathLayout = QHBoxLayout()
+        self.pathField = QLineEdit()
+        self.pathField.setReadOnly(True)
+        self.pathField.setText(self._default_dir)
+        self.pathField.setObjectName("pathField")
+        buttonBrowse = QPushButton()
+        buttonBrowse.setObjectName("buttonBrowse")
+        self.connect(buttonBrowse, SIGNAL("clicked()"), self._openFileDialog)
+        pathLayout.addWidget(self.pathField)
+        pathLayout.addWidget(buttonBrowse)
+        
+        borderLabel = QLabel()
+        borderLabel.setPixmap(QPixmap(PATH_BG))
+        borderLabel.setFixedSize(304, 40)
+        gridLay = QGridLayout()
+        gridLay.addWidget(borderLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addLayout(pathLayout, 0, 0, Qt.AlignCenter)
+        
+        return gridLay
+        
+    def _createBackupNameField(self):
+        label = QLabel("Backup Name:")
+        backupNameLayout = QHBoxLayout()
+        backupNameLayout.addWidget(label)
+        self.backupNameField = QLineEdit()
+        self.backupNameField.setObjectName("backupNameField")
+        self.backupNameField.setText("Backup")
+        backupNameLayout.addWidget(self.backupNameField, 
+                                          Qt.AlignHCenter)
+        borderLabel = QLabel()
+        borderLabel.setPixmap(QPixmap(BACKUP_NAME_BG))
+        borderLabel.setFixedSize(304, 40)
+        gridLay = QGridLayout()
+        gridLay.addWidget(borderLabel, 0, 0, Qt.AlignCenter)
+        gridLay.addLayout(backupNameLayout, 0, 0, Qt.AlignCenter)
+        
+        return gridLay
+      
+    def _openFileDialog(self):
+        pathDialog = QFileDialog()
+        prompt = "Select the folder you wish to save your backup"
+        self.path = pathDialog.getExistingDirectory(self, prompt, 
+                                                     self._default_dir)
+        if self.path != "":
+            self.pathField.setText(self.path)
+        
+    def _resetPage(self):
+        self.path = self._default_dir
+        self.pathField.setText(self._default_dir)
+        self.backupNameField.setText("Backup")
+    
+    def getBackupName(self):
+        return str(self.backupNameField.text())
+    
+    def getPath(self):
+        return str(self.pathField.text())
+    
diff --git a/src/backup/pcspcbackupmanager.py b/src/backup/pcspcbackupmanager.py
new file mode 100644 (file)
index 0000000..35bcfe3
--- /dev/null
@@ -0,0 +1,475 @@
+# low_backup_manager module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+# Backup_manager class:
+#    Class responsible for backup functions like creating and removing backups
+
+import os.path
+import os
+import zlib
+import pickle
+
+from PyQt4.QtCore import *
+from zipfile import *
+
+from pcsbackupparser import *
+from pcsbackupinfo import *
+from pcsbackupmanager import *
+from pcsbackupxml import *
+
+import pcsbackuputils as utils
+
+HOME = os.path.expanduser("~")
+BACKUP_FILES_PATH = os.path.join(HOME, ".pcsuite/Backup")
+DEFAULT_CONFIG_PATH = "%s/.pcsuite/config" % HOME
+BACKUPS_FILE = os.path.join(HOME, ".pcsuite/Backup/.backups")
+
+
+class PcsPcBackupManager(PcsBackupManager):
+
+    def __init__(self):
+        PcsBackupManager.__init__(self)
+        self._backupList = []
+        self.backupInProgress = False
+        self.restoreInProgress = False
+        self.copyInProgress = False
+        
+        self.myDocsPath = "Root/home/user/MyDocs/"
+        self.backupPath = ""
+        self.currentCategory = ""
+        self.totalSize = 0
+
+    def loadBackups(self):
+        # 'XX Loading the backup list available in the PC'
+        try:
+            if os.path.exists(BACKUPS_FILE):
+                file = open(BACKUPS_FILE)
+                self._backupList = pickle.load(file)
+                file.close()
+        except IOError:
+            print "IOError while loading the PC backups"
+            # FIXME
+            #raise Exception("Error while reading backups")
+            return False
+        
+        return True
+        
+    def saveBackups(self):
+        # 'XX Saving the backup list in the config file'
+        try:
+            obj = self._backupList
+            file = open(BACKUPS_FILE, "w")     
+            pickle.dump(obj, file)
+            file.close()
+        except:
+            #raise Exception("Error while saving backups")
+            return False
+        
+        return True
+
+    def getBackupList(self):
+        """Return a list with the name of all done backups. """
+        self.loadBackups()
+        return self._backupList[:]
+    
+    def createBackup(self, backup_name, path, host_ip, categories, comment=""):
+        self.backupThread = NewBackupThread(self, backup_name, path, host_ip, 
+                                            categories, comment)
+        self.backupThread.start()
+        
+
+    def renameBackup(self, backupName, newName):
+        self.loadBackups()
+
+        backupInfo = self.getBackupInfo(backupName)
+        if backupInfo != None:
+            try:
+                old = os.path.join(str(backupInfo.getPath()), str(backupName))
+                new = os.path.join(str(backupInfo.getPath()), str(newName))
+                os.rename(old, new)
+                backupInfo.setName(newName)
+            except:
+                print "Error while changing backup name"
+                return False
+        else:
+            # "Backup not found"
+            return False
+            
+        self.saveBackups()
+        return True
+    
+    def removeBackup(self, backupName):
+        """
+            Remove a backup from pc and from _backupList.
+        """
+        self.loadBackups()
+        backupInfo = self.getBackupInfo(backupName)
+        completePath = os.path.join(str(backupInfo.getPath()), 
+                                    str(backupInfo.getName()))
+        if os.path.exists(completePath):
+            utils.removePath(completePath)
+        self._backupList.remove(backupInfo)
+        self.saveBackups()
+        
+        return True
+    
+    def copyBackupToDevice(self, deviceIp, backupName, memoryStick):
+        """ Copy a backup in the PC to some memory card inside the chosen device.
+            
+            Attributes:
+            String deviceIp - String with ip address of device.
+            String backupName - Name of backup to be copied.
+            Int memoryStick - Integer representing which memory stick backup
+                                should be copied to.
+                                0 - Removable memory stick
+                                1 - Internal memory stick
+        """
+        try:
+            self.loadBackups()
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % deviceIp)
+            utils.mountDevice(USER_HOST, deviceIp, mountPoint)
+            
+            backup = self.getBackupInfo(backupName)
+            backupPath = os.path.join(str(backup.getPath()), str(backupName))
+            if memoryStick != 0 and memoryStick != 1:
+                return -1
+            destination = os.path.join(mountPoint, 'media/mmc%s' % 
+                                       (memoryStick+1), 'backups', backupName)
+            
+            self.setCopyInProgress(True)
+            if self.copy(backupPath, destination) == 0:
+                return 0
+            self.setCopyInProgress(False)
+        finally:
+            utils.unmountDevice(mountPoint)
+
+    
+    def getBackupInfo(self, backupName):
+        for backupInfo in self._backupList:
+            if backupInfo.getName() == backupName:
+                return backupInfo
+        return None
+    
+    def startBackupRestore(self, backupInfo, device_ip, categories):
+        return self.restoreBackup(backupInfo, device_ip, categories)
+    
+    def setCopyInProgress(self, status):
+        self.copyInProgress = status
+    
+    def setBackupInProgress(self, status):
+        self.backupInProgress = status
+        
+        
+    def setRestoreInProgress(self, status):
+        self.restoreInProgress = status
+        
+    # FIXME: rewrite this method. Add error handling, some more reliable code
+    def _runCreateBackup(self, backup_name, path, host_ip, categories, comment=""):
+        """Create a backup and add it to _backupList.
+
+        Backup all files and directories of categories chosen. The device
+        system file is mounted on PC and them files are compressed in a zip
+        format. All zip files from each category are saved in the given path.
+
+        Arguments:
+        backup_name -- Backup's name. This name will be the name of the backup
+            folder.
+        path -- Location to save Backup file
+        host_ip -- The device IP address.
+        categories -- A python dictonary where the keys are the categories from
+            osso-backup, and the value can be either True or False, to identify
+            which categories to backup.
+        comment -- Any comment about the backup. It will be saved in Backup
+            object.
+            
+        """
+           
+        backupInfo = None
+        self.setBackupInProgress(True)
+        self.currentCategory = ""
+         
+        try:
+            # Mount device folders
+            self.loadBackups()
+            mountPoint = os.path.join(DEVICES_POINT, "%s/Root" % host_ip)
+            utils.mountDevice(USER_HOST, host_ip, mountPoint)
+            
+            # Create backup folder in the given path
+            self.backupPath = os.path.join(str(path), backup_name)
+            self._createBackupFolder(self.backupPath)
+            
+            # Copying osso-backup configuration files to TabletSuite folder and
+            # parsing backup information from these files.
+            # ( Information = which paths should be in each backup category)
+            utils.copyOssoBackupConfigFiles(DEFAULT_CONFIG_PATH, mountPoint)
+            xmlParser = PcsBackupParser()
+            xmlParser.fillLocationsDict(DEFAULT_CONFIG_PATH)
+            backupItemDict = xmlParser.getLocationsDict()
+            
+            # Changing work directory to ease file search. Keeping previous
+            # folder to come back after backup process.
+            current_dir = os.getcwd()
+            workPath = DEVICES_POINT + str(host_ip)
+            os.chdir(workPath)
+
+            # Computing total size that this backup will have.
+            self.totalSize = self._getTotalSize(backupItemDict, categories)
+            
+            
+            # Start backup process. Create backup of paths for each locations
+            # category
+            self.backedUpNumber = 0
+            filesByCategory = {}
+            for category in backupItemDict.keys():
+                self.currentCategory = category
+                
+                for backupItem in backupItemDict[category]:
+                    self._emitProgress()
+                    # If current backupInfo category is valid and it's value is 
+                    # True in categories dictionary, add it to current backup. 
+                    if (category in categories) and (categories[category]):
+                        categoryFilesNumber = 0
+                        categoryFile = os.path.join(self.backupPath, 
+                                                    category + '.zip')
+
+                        if os.path.exists(categoryFile):
+                            zipfile = utils.openZip(categoryFile, 'a')
+                        else:
+                            zipfile = utils.openZip(categoryFile, 'w')
+
+                        objPath = backupItem.path.replace('/','Root/',1)
+                        backupFolder = os.path.join(workPath, objPath)
+                        categoryFilesNumber = self.zipFolder(backupFolder,
+                                                              zipfile, objPath,
+                                                               category)
+                        if categoryFilesNumber == -1:
+                            os.chdir(current_dir)
+                            return 0
+                        self.backedUpNumber += categoryFilesNumber
+                        self._emitProgress()
+                        
+                        # Update the filesByCategory dictionary with the 
+                        # current number of files from current category that 
+                        # were already copied.
+                        self._updateCategoryCount(filesByCategory, category, 
+                                                  categoryFilesNumber)
+                        utils.closeZip(zipfile)
+                        # If category had no file to copy remove its folder
+                        if int(utils.getSize(categoryFile) == 0):
+                            os.remove(categoryFile)
+            
+                
+            # Copying media files from device user folder if media category is
+            # True in categories dictionary.
+            if ("media" in categories) and (categories["media"]):
+                self.currentCategory = "media"
+                result = self._backupMedias(workPath)
+                if result == -1:
+                    os.chdir(current_dir)
+                    return 0
+                # Update backup files number count
+                self.backedUpNumber += result
+                self._updateCategoryCount(filesByCategory, "media", result)
+                zipPath = os.path.join(self.backupPath,'media.zip')
+                if int(utils.getSize(zipPath) == 0):
+                    os.remove(zipPath)
+            
+            
+            # Copying documents files from device user folder if documents
+            # category is True in categories dictionary.
+            if ("documents" in categories) and (categories["documents"]):
+                self.currentCategory = "documents"
+                result = self._backupDocuments(workPath)
+                # Update backup files number count
+                self.backedUpNumber += result
+                if result == -1:
+                    os.chdir(current_dir)
+                    return 0
+                self._updateCategoryCount(filesByCategory, "documents", 
+                                          result)
+                zipPath = os.path.join(self.backupPath, 'documents.zip')
+                if int(utils.getSize(zipPath) == 0):
+                    os.remove(zipPath)          
+                
+                
+            # Change to previous work directory
+            os.chdir(current_dir)
+           
+            if self.backedUpNumber == 0:
+                utils.removePath(self.backupPath)
+                return -1
+            
+            # Create Backup Object, add it to this manager backup list and save
+            # the list in the backup file.
+            backup_size = utils.getSize(self.backupPath)
+            backupInfo = PcsBackupInfo(backup_name, path, backup_size, comment)
+            backupInfo.setFilesNumber(self.backedUpNumber)
+            self._backupList.append(backupInfo)
+            self.saveBackups()
+            
+            createXml(backupInfo, filesByCategory, host_ip)
+            self.setBackupInProgress(False)
+        finally:
+            utils.unmountDevice(mountPoint)
+            
+        return backupInfo
+    
+    
+    def _backupDocuments(self, workPath):
+        """ Create backup of documents files in user folder. """
+        categoryFilesNumber = 0
+        destinationPath = os.path.join(self.backupPath,'documents.zip')
+        if os.path.exists(destinationPath):
+            zipfile = utils.openZip(destinationPath, 'a')
+        else:
+            zipfile = utils.openZip(destinationPath, 'w')
+            
+        docsPath = os.path.join(self.myDocsPath, ".documents")
+        
+        if os.path.exists(docsPath):
+            backupPath = os.path.join(workPath, docsPath)
+            categoryFilesNumber = self.zipFolder(backupPath, zipfile, docsPath,
+                                                 "documents")
+            
+        utils.closeZip(zipfile)
+        return categoryFilesNumber
+           
+                    
+    def _backupMedias(self, workPath):
+        """ Create backup of media files in user folder. """
+        categoryFilesNumber = 0
+        destinationPath = os.path.join(self.backupPath,'media.zip')
+        if os.path.exists(destinationPath):
+            zipfile = utils.openZip(destinationPath, 'a')
+        else:
+            zipfile = utils.openZip(destinationPath, 'w')
+            
+        userFilesPath = self.myDocsPath
+        if os.path.exists(os.path.join(userFilesPath)):
+            for folder in os.listdir(userFilesPath):
+                if folder != '.documents':
+                    objPath = os.path.join(userFilesPath, folder)
+                    backupDir = os.path.join(workPath, objPath)
+                    result = self.zipFolder(backupDir, zipfile,
+                                                         objPath, "media")
+                    if result != -1:
+                        categoryFilesNumber += result
+                    else:
+                        return result
+                    
+        utils.closeZip(zipfile)
+        return categoryFilesNumber
+    
+                    
+    def _createBackupFolder(self, newBackupPath):
+        if not utils.createFolder(newBackupPath):
+            return False
+    
+    
+    def _emitProgress(self):
+        currentSize = utils.getSize(self.backupPath) 
+        percentage = self.computePercentage(self.totalSize, currentSize)
+        self.emit(SIGNAL("backupProgress"), (percentage, self.currentCategory))
+    
+    
+    def _getTotalSize(self, backupFileDict, categories):
+        size = 0
+        for category in backupFileDict.keys():
+            for backupItem in backupFileDict[category]:
+                if (category in categories) and (categories[category]):
+                    objPath = backupItem.path.replace('/','Root/',1)
+                    size += utils.getSize(objPath)
+        
+        if categories["documents"]:
+            size += utils.getSize(os.path.join(self.myDocsPath,
+                                                     ".documents"))
+        if categories["media"]:
+            for folder in os.listdir(self.myDocsPath):                
+                if folder != '.documents':
+                    objPath = os.path.join(self.myDocsPath, folder)
+                    size += utils.getSize(objPath)
+        return size
+    
+    def _updateCategoryCount(self, filesByCategory, category, backed_up_number):
+        if str(category) not in filesByCategory.keys():
+            filesByCategory[category] = backed_up_number
+        else:
+            filesByCategory[category] += backed_up_number
+    
+            
+    def _verify_backup_name(self, backup_name):
+        """ Check if already exists any backup with the given name inside the
+        pc backup list. In case there is one, this function will return another
+        name to be set as the new backup name, else it will return the same 
+        name that was given.
+        
+        """
+        if self.getBackupInfo(backup_name) != None:
+            counter = 1
+            new_name = backup_name + "%02d" % counter
+            while(self.getBackupInfo(new_name)) != None:
+                counter += 1
+                new_name = backup_name + "%02d" % counter
+            
+            backup_name = new_name
+        return backup_name
+    
+    def zipFolder(self, path, zipfile, obj_path, category):
+        # Compress the folder from the given path, with all directories and
+        #   files inside it
+        # zipfile: The ZipFile object to append the folder
+        # obj_path: The ZipFile path
+        count = 0
+        self._emitProgress()
+        if os.path.exists(path):
+            if os.path.isdir(path):
+                files = os.listdir(path)
+                for node in files:
+                    if os.path.isdir(os.path.join(path, node)):
+                        zipCount = self.zipFolder(os.path.join(path, node), zipfile,
+                                            os.path.join(obj_path, node), category)
+                        if zipCount == -1:
+                            return -1
+                        else:
+                            count += zipCount
+                    else:
+                        # Check if backup was canceled and return -1 case positive
+                        if not self.backupInProgress:
+                            utils.removePath(self.backupPath)
+                            return -1
+
+                        if utils.zip(zipfile, os.path.join(obj_path, node)):
+                            count += 1
+                            self._emitProgress()
+            else:
+                # Check if backup was canceled and return -1 case positive
+                if not self.backupInProgress:
+                    utils.removePath(self.backupPath)
+                    return -1
+                
+                if utils.zip(zipfile, obj_path):
+                    count += 1
+                    self._emitProgress()
+        return count
+    
+
+
+class NewBackupThread(QThread):
+    def __init__(self, manager, backupName, path, hostIp, categories, comment):
+        QThread.__init__(self)
+        
+        self.manager = manager
+        self.backupName = backupName
+        self.path = path
+        self.hostIp = hostIp
+        self.categories = categories
+        self.comment = comment
+    
+    def run(self):
+        ret = self.manager._runCreateBackup (self.backupName, self.path,
+                                             self.hostIp, self.categories,
+                                             str(self.comment))
+        self.manager.emit(SIGNAL("backupDone"), ret, 
+                          (self.manager.totalSize, self.manager.backedUpNumber))    
+
+
+        
\ No newline at end of file
diff --git a/src/backup/pcsprogressdialog.py b/src/backup/pcsprogressdialog.py
new file mode 100644 (file)
index 0000000..cf9038f
--- /dev/null
@@ -0,0 +1,117 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from style.styleTabletSuite import *
+from ui.pcsuiutils import *
+
+class PcsProgressDialog(QDialog):
+       
+    def __init__(self, parent = None):
+        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
+        self.cancelButton = QPushButton("Cancel")
+        self.doneButton = QPushButton("Done")
+        self.connect(self.doneButton, SIGNAL("clicked()"), self.close)
+        self.actionLabel = QLabel("Action...")
+        self.categoryLabel = QLabel("")  
+        self.progressReport = QLabel("") 
+        self.setLayout(self._insertLayout())
+        
+        
+    def setAction(self, action):
+        self.action = action
+        if action == "copy":
+            message = "Copying..."
+            
+        elif action == "restore":
+            message = "Restoring..."
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                       "#333333'; size=2>"\
+                                       +str(action).capitalize()+
+                                       " in progress...</font>")
+        
+        self.actionLabel.setText('''<font style=color:
+                                black; size=3>
+                                '''+ message +'''</font>''')
+    
+    def _insertLayout(self):
+        vLay = QVBoxLayout()
+        vLay.addWidget(self.actionLabel)
+        vLay.addLayout(self._createCenterLayout())
+        return vLay
+    
+    def _createCenterLayout(self):
+        
+        bgLabel = QLabel()
+        bgLabel.setPixmap(QPixmap(PROGRESS_BAR_DIALOG_BG))
+        grid = QGridLayout()
+        
+        self.progressBar = QProgressBar()
+        self.progressBar.setObjectName("progressBarDialog")
+        self.progressBar.setValue(0)
+        self.progressBar.setTextVisible(False)
+        
+        grid.addWidget(bgLabel, 0, 0, Qt.AlignCenter)
+        grid.addWidget(self.progressBar, 0, 0, Qt.AlignCenter)
+
+        self.cancelButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.cancelButton.setShortcut(Qt.Key_Return)
+        self.doneButton.setVisible(False)
+        self.doneButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        
+        gridLayout = QGridLayout()
+        gridLayout.setSpacing(3)
+        gridLayout.addWidget(self.categoryLabel, 0, 0, Qt.AlignRight)
+        gridLayout.addLayout(grid, 1, 0)
+        gridLayout.addWidget(self.progressReport, 2, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.cancelButton, 3, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.doneButton, 3, 0, Qt.AlignRight)
+        
+        return gridLayout
+    
+    def progressCanceled(self):
+        self.progressDone(True)
+    
+    def progressDone(self, cancel=False):
+        self.cancelButton.setVisible(False)
+        self.doneButton.setVisible(True)
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2>"+\
+                                    str(self.action).capitalize()
+                                    +" finished.</font>")
+        if not cancel:
+            totalSize =  "%.2f" % (self.totalSize/(1024.0**2))
+        
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2>"\
+                                        + str(self.numberOfFiles) +\
+                                        " Files - " + totalSize + " MB</font>")
+        else:
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2> Canceled")
+            self.categoryLabel.setText("")
+            self.progressBar.setValue(100)
+            
+    def updateInfo(self, totalSize, numberOfFiles):
+        self.totalSize = totalSize
+        self.numberOfFiles = numberOfFiles
+    
+    def setProgress(self, progress):
+        self.progressBar.setValue(float(progress))
+        
+        self.progressReport.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    + progress +\
+                                    "% Complete</font>")  
+        
+    def setCategory(self, catogory):
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2> Category name: "\
+                                   + catogory +"</font>")
+    
+    
+    
\ No newline at end of file
diff --git a/src/backup/pcsprogresswizard.py b/src/backup/pcsprogresswizard.py
new file mode 100644 (file)
index 0000000..6afb6af
--- /dev/null
@@ -0,0 +1,237 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from pcsbackupmanagerui import *
+from pcsrestorebackupui import *
+from style.styleTabletSuite import *
+
+
+class PcsProgressWizard(QWizardPage):
+    
+    def __init__(self, deviceInfo, wizard, windowManager, parent = None):
+        QWizardPage.__init__(self, parent)
+        self.windowManager = windowManager
+        self.deviceInfo = deviceInfo
+        self.wizard = wizard
+        self.layout = QVBoxLayout()
+        self.layout.setMargin(0)
+        self.cancelButton = QPushButton("Cancel")
+        self.doneButton = QPushButton("Done")
+        self.completeReportButton = QPushButton("View Complete Report")
+        self.lockMenuButtons = True        
+        self._insertLayout()
+        
+    def _insertLayout(self, name = ""):
+        self.vLayout = QVBoxLayout()
+        self.vLayout.setMargin(0)
+        self.wayLayout = self._wayLayout(name)
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self.wayLayout, Qt.AlignLeft)
+        spc = QSpacerItem(0, 68)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE_SELECTED), 
+                   ("Manager Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE, self._restoreDialog)]
+        buttonsLayout = QHBoxLayout()
+        buttonsLayout.setMargin(0)
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 0:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    def _wayLayout(self, name = ""):
+        self.barLayout = QHBoxLayout()
+        self.barLayout.setMargin(0)
+        main = QLabel("<font style='color: #333333'; size=2>Main</font>")
+        arrow1 = self._arrow()
+        arrow2 = self._arrow()
+        arrow3 = self._arrow()
+        arrow4 = self._arrow()
+        spc = QSpacerItem(2, 0)
+        newBackup = QLabel("<font style='color: #333333'; size=2> New Backup</font>")
+        files = QLabel("<font style='color: #333333'; size=2>Files</font>")
+        folder = QLabel("<font style='color: #333333'; size=2>Folder</font>")
+        if name != "":
+            loading = QLabel("<font style='color: #333333'; size=2>loading</font>")
+        else:
+            loading = QLabel("<font style='color: #FFFFFF'; size=2>loading</font>")   
+        widgetList = [main, self._arrow(), newBackup, self._arrow(), files,
+                      self._arrow(), folder, self._arrow(), loading]
+        for widget in widgetList:
+            self.barLayout.addWidget(widget, Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+        if name != "":
+            newLabel = QLabel("<font style='color: #FFFFFF'; size=2>"+ name +"</font>")
+            self.barLayout.addWidget(self._arrow(), Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+            self.barLayout.addWidget(newLabel, Qt.AlignLeft)
+            self.barLayout.addItem(spc)
+            
+        self.barLayout.addItem(QSpacerItem(300, 0))
+        return self.barLayout
+    
+    def _manageDialog(self):
+        if self.lockMenuButtons == False:
+            if(self.deviceInfo and self.deviceInfo.ip != None):
+                backupManager = self.windowManager.getBackupManager()
+                centralize(backupManager)
+                backupManager.setGeometry(self.wizard.geometry())
+                backupManager.show()
+                self.close()
+                self.wizard.close()
+                self.lockMenuButtons = True
+                self._resetPage()
+            else:
+                self._showNoDeviceFoundMessage()
+        
+    def _restoreDialog(self):
+        if self.lockMenuButtons == False:
+            if(self.deviceInfo and self.deviceInfo.ip != None):
+                restoreBackup = self.windowManager.getRestoreBackup()
+                centralize(restoreBackup)
+                restoreBackup.setGeometry(self.wizard.geometry())
+                restoreBackup.show()
+                self.wizard.close()
+                self.close()
+                self.lockMenuButtons = True
+                self._resetPage()
+            else:
+                self._showNoDeviceFoundMessage()
+        
+    def _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    def _arrow(self):
+        label = QLabel()
+        label.setPixmap(QPixmap(BLACK_ARROW))
+        return label
+        
+    def _createInformationsLabel(self):
+        hLay = QHBoxLayout()
+        spc = QSpacerItem(10, 0)
+        self.infLabel = QLabel("<font style='color:"\
+                             "#333333'; size=2>"\
+                             "Do backup from Device to your PC.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(self.infLabel, Qt.AlignLeft)
+        
+        return hLay
+    
+    def _resetPage(self):
+        self.lockMenuButtons = True
+        self.cancelButton.setVisible(True)
+        self.doneButton.setVisible(False)
+        self.progressBar.setValue(0)
+        self.progressReport.setText("")
+        self.categoryLabel.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    "Backup starting...</font>")
+    
+    def _createCenterLayout(self):
+        gridLayout = QGridLayout()
+        gridLayout.setMargin(27)
+        
+        self.categoryLabel = QLabel("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    "Backup starting...</font>")  
+        
+        bgLabel = QLabel()
+        bgLabel.setPixmap(QPixmap(PROGRESS_BAR_BG))
+        grid = QGridLayout()
+        
+        self.progressBar = QProgressBar()
+        self.progressBar.setObjectName("progressBarWizard")
+        self.progressBar.setValue(0)
+        self.progressBar.setTextVisible(False)
+        
+        grid.addWidget(bgLabel, 0, 0, Qt.AlignCenter)
+        grid.addWidget(self.progressBar, 0, 0, Qt.AlignCenter)
+        
+        self.progressReport = QLabel("")  
+        
+        self.cancelButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.cancelButton.setShortcut(Qt.Key_Return)
+        self.doneButton.setVisible(False)
+        self.doneButton.setStyleSheet(DEFAULT_BUTTON_STYLE)
+#        self.completeReportButton.setStyleSheet()
+        
+        gridLayout.setSpacing(3)
+        gridLayout.addWidget(self.categoryLabel, 0, 0, Qt.AlignRight)
+        gridLayout.addLayout(grid, 1, 0)
+        gridLayout.addWidget(self.progressReport, 2, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.cancelButton, 3, 0, Qt.AlignRight)
+        gridLayout.addWidget(self.doneButton, 3, 0, Qt.AlignRight)
+        
+        return gridLayout
+    
+    def progressCanceled(self):
+        self.progressDone(True)
+    
+    def progressDone(self, cancel=False):
+        self.lockMenuButtons = False
+        self.cancelButton.setVisible(False)
+        self.doneButton.setVisible(True)
+        
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2>"\
+                                   "Backup finished.</font>")
+        if not cancel:
+            totalSize =  "%.2f" % (self.totalSize/(1024.0**2))
+        
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2>"\
+                                        + str(self.backedUpNumber) +\
+                                        " Files - " + totalSize + " MB</font>")
+        else:
+            self.progressReport.setText("<font style='color:"\
+                                        "#333333'; size=2> Canceled")
+            self.categoryLabel.setText("")
+            self.progressBar.setValue(100)
+            
+            
+        self.infLabel.setText("<font style='color:"\
+                              "#333333'; size=2>"\
+                              "Select an action</font>")
+        
+    def updateInfo(self, totalSize, backedUpNumber):
+        self.totalSize = totalSize
+        self.backedUpNumber = backedUpNumber
+    
+    def setProgress(self, progress):
+        self.progressBar.setValue(progress)
+        
+        self.progressReport.setText("<font style='color:"\
+                                    "#333333'; size=2>"\
+                                    + str(int(progress))+\
+                                    "% Complete</font>")  
+        
+    def setCategory(self, category):
+        self.categoryLabel.setText("<font style='color:"\
+                                   "#333333'; size=2> Category name: "\
+                                   + category +"</font>")
+        
+    
\ No newline at end of file
diff --git a/src/backup/pcsrestorebackupui.py b/src/backup/pcsrestorebackupui.py
new file mode 100644 (file)
index 0000000..dc9733a
--- /dev/null
@@ -0,0 +1,412 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from functools import partial 
+
+from ui.pcsuiutils import *
+from ui.tsuigeneralmethods import *
+
+from style.styleTabletSuite import *
+
+from backup.pcsbackupmanager import PcsBackupManager, DEVICES_POINT, USER_HOST
+from backup.pcspcbackupmanager import PcsPcBackupManager
+from backup.pcsdevicebackupmanager import PcsDeviceBackupManager
+from pcsbackuplistui import PCSBackupListUi
+from pcsprogressdialog import PcsProgressDialog
+from pcsrestoredialog import PcsRestoreDialog
+from pcsbackuputils import *
+
+
+class PcsRestoreBackupUi(QDialog):
+    
+    def __init__(self, deviceInfo, windowManager, parent = None):
+        super(PcsRestoreBackupUi, self).__init__(parent)
+        self.deviceInfo = deviceInfo
+        
+        self.windowManager = windowManager
+        self.pcBackupManager = PcsPcBackupManager()
+        self.deviceBackupManager = PcsDeviceBackupManager(self.deviceInfo)
+        self.deviceListView = PCSBackupListUi(self.deviceBackupManager)
+        
+        self._buttonRestoreI = QPushButton("Restore")
+        self.connect (self._buttonRestoreI, SIGNAL("clicked()"), self._openRestoreBackup)
+        self._buttonRestoreII = QPushButton("Restore")
+        self.connect (self._buttonRestoreII, SIGNAL("clicked()"), self._openRestoreBackup)
+        self._buttonView = QPushButton("View")
+        self.connect (self._buttonView, SIGNAL("clicked()"), self._doViewBackup)
+        
+        self.pcListView = PCSBackupListUi(self.pcBackupManager)
+        
+        self.setWindowTitle("%s Restore Backup" % APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+        self.vLayout = QVBoxLayout()
+        
+        self._insertLayout()
+    
+    def _createCenterLayout(self):
+        self.deviceListView.updateBackupList()
+        tab = QTabBar()
+        tab.setObjectName("restoreTabs")
+        self.tabBar = QTabWidget()
+        self.tabBar.setTabBar(tab)
+        self.tabBar.setAttribute(Qt.WA_NoSystemBackground)
+        self.tabBar.setObjectName("tabBar")
+        self.tabBar.addTab(self._createPcListViewWidget(), "PC Backups")
+        self.tabBar.addTab(self._createDeviceListViewWidget(), "Device Backups")
+        self.connect(self.tabBar, SIGNAL("currentChanged(int)"), 
+                     self._updateButtonsState)
+        
+        layout = QVBoxLayout()
+        layout.addWidget(self.tabBar)
+        
+        return layout
+    
+    def _createButtons(self, pcFlag = False):
+        buttonBox = QHBoxLayout()
+        self._buttonRestoreI.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonRestoreI.setDisabled(True)
+        self._buttonRestoreII.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonRestoreII.setDisabled(True)
+        self._buttonView.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self._buttonView.setDisabled(True)
+        
+        if pcFlag:
+            buttonBox.addWidget(self._buttonView)
+            buttonBox.addWidget(self._buttonRestoreI)
+        else:
+            buttonBox.addWidget(self._buttonRestoreII)
+        
+        return buttonBox
+    
+    def _createPcListViewWidget(self):
+        self.pcListView.setObjectName("ListView")
+        pcListViewSelectionModel = self.pcListView.selectionModel()
+        self.connect(pcListViewSelectionModel, 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
+                     self._updateButtonsState)
+        
+        self.pcListView.updateBackupList()
+        
+        panel = QWidget()
+        panel.setAttribute(Qt.WA_NoSystemBackground)
+        panel.setObjectName("DeviceListPanel")
+        vLay = QVBoxLayout()
+        
+        vLay.addWidget(self.pcListView)
+        vLay.addLayout(self._createButtons(True))
+        panel.setLayout(vLay)
+        
+        return panel
+    
+    def _createDeviceListViewWidget(self):
+        self.deviceListView.setObjectName("ListView")
+        deviceListViewSelectionModel = self.deviceListView.selectionModel()
+        self.connect(deviceListViewSelectionModel, 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), 
+                     self._updateButtonsState)
+        
+        self.deviceListView.updateBackupList()
+        
+        panel = QWidget()
+        panel.setAttribute(Qt.WA_NoSystemBackground)
+        panel.setObjectName("DeviceListPanel")
+        vLay = QVBoxLayout()
+        
+        vLay.addWidget(self.deviceListView)
+        vLay.addLayout(self._createButtons())
+        panel.setLayout(vLay)
+        
+        return panel
+        
+        
+    def _insertLayout(self):
+        
+        self.vLayout.setMargin(0)
+        self.wayLayout = self._wayLayout()
+        buttonLayout = self._menuButtons()
+        spc = QSpacerItem(0, 6)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(buttonLayout, Qt.AlignTop)
+        spc = QSpacerItem(0, 5)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self.wayLayout, Qt.AlignLeft)
+        spc = QSpacerItem(0, 3)
+        self.vLayout.addItem(spc)
+        self.vLayout.addLayout(self._createCenterLayout(), Qt.AlignVCenter)
+        
+        self.vLayout.addLayout(self._createInformationsLabel(), Qt.AlignVCenter)
+        spc = QSpacerItem(0, 8)
+        self.vLayout.addItem(spc)
+        self.setLayout(self.vLayout)
+
+    def _menuButtons(self):
+        infList = [("New Backup", SMALL_ICON_NEW_BACKUP_STYLE, self._newBackupDialog), 
+                   ("Manage Backup", SMALL_ICON_MANAGER_BACKUP_STYLE, self._manageDialog),
+                   ("Restore Backup", SMALL_ICON_RESTORE_BACKUP_STYLE_SELECTED)]
+        
+        buttonsLayout = QHBoxLayout()
+        for i in range(3):
+            but = QPushButton(infList[i][0])
+            but.setStyleSheet(infList[i][1])
+            if i <> 2:
+                buttonsLayout.addWidget(but, Qt.AlignLeft)
+                self.connect(but, SIGNAL("clicked()"), infList[i][2])
+            else:
+                buttonsLayout.addWidget(but)
+        return buttonsLayout    
+    
+    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> Restore 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 _manageDialog(self):
+        if(self.deviceInfo and self.deviceInfo.ip != None):
+            backupManager = self.windowManager.getBackupManager()
+            centralize(backupManager)
+            backupManager.setGeometry(self.geometry())
+            backupManager.show()
+            self.close()
+        else:
+            self._showNoDeviceFoundMessage()
+    
+    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 _showNoDeviceFoundMessage(self):
+        inf = QMessageBox(self)
+        inf.setWindowTitle("Connect a device.")
+        inf.setText("No devices were found.")
+        inf.show()
+    
+    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 restore.</font>")
+        iconAlert = QLabel()
+        iconAlert.setPixmap(QPixmap(ICON_ALERT))
+        spc = QSpacerItem(15, 0)
+        hLay.addItem(spc)
+        hLay.addWidget(iconAlert)
+        hLay.addWidget(self.infLabel, Qt.AlignLeft)
+        
+        return hLay
+
+    def _updateButtonsState(self, index):
+        list = self._currentBackupList()
+        selectionModel = list.selectionModel()
+        indexList = selectionModel.selectedRows()
+        
+        if len(indexList) <> 1:
+            self._buttonView.setDisabled(True)
+            self._buttonRestoreI.setDisabled(True)
+            self._buttonRestoreII.setDisabled(True)
+        else:
+            self._buttonView.setEnabled(True)
+            self._buttonRestoreI.setEnabled(True)
+            self._buttonRestoreII.setEnabled(True)
+
+    def _currentBackupList(self):
+        if self.tabBar.currentIndex() == 0:
+            return self.pcListView
+        else:
+            return self.deviceListView
+        
+        
+    def doRestoreBackup(self, categories):
+        if self._currentBackupList() == self.pcListView:
+            manager = self.pcBackupManager
+        else:
+            manager = self.deviceBackupManager
+            
+        self.restoreBackupThread = RestoreBackupThread(self, manager, categories)
+        self.restoreBackupThread.start()
+        self._runRestoreProgress()
+        self.connect(self.restoreBackupThread, SIGNAL("restoreProgress"), 
+                     self._updateCategoriesAndProgress)
+        self.connect(self.restoreBackupThread, SIGNAL("restoreDone"), 
+                     self._onRestodeDone)
+        self.connect(self.restoreBackupThread, SIGNAL("openFileError"),
+                     self._onOpenFileError)
+
+    def _openRestoreBackup(self):
+        backup = self._currentBackupList().getSelectedBackup()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.loadBackups()
+            backupInfo = self.pcBackupManager.getBackupInfo(str(backup))
+        else:
+            self.deviceBackupManager.loadBackups()
+            backupInfo = self.deviceBackupManager.getBackupInfo(str(backup))
+            
+        host_ip = self.deviceInfo.ip
+        devicePath = os.path.join(DEVICES_POINT, "%s" % host_ip)
+        mountPath = os.path.join(devicePath, "Root" )
+        mountDevice(USER_HOST, host_ip, mountPath)
+        list = getBackupCategories(backupInfo)
+        unmountDevice(mountPath)
+        
+        self.restoreDialog = PcsRestoreDialog(self.deviceInfo, list, self)
+        self.connect(self.restoreDialog.buttonCancel, SIGNAL("clicked()"),
+                     self.restoreDialog.close)
+        
+        self.connect(self.restoreDialog.buttonOk, SIGNAL("clicked()"),
+                     self._doRestoreAndCloseDialog)
+        self.restoreDialog.exec_()
+        
+    
+    def _doRestoreAndCloseDialog(self):
+        categories = self.restoreDialog.getCategories()
+        self.restoreDialog.close()
+        self.doRestoreBackup(categories)
+        
+    def _doRestoreBackup(self, categories):
+        selectedBackups = self._currentBackupList().getSelectedBackupList()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.loadBackups()
+            for backup in selectedBackups:
+                backupInfo = self.pcBackupManager.getBackupInfo(str(backup))
+                ip = self.deviceBackupManager._deviceInfo.ip
+                self.emit(SIGNAL("restoreStarted"))
+                result = self.pcBackupManager.startBackupRestore(backupInfo, ip,
+                                                       categories)
+                if result == False or result == 0:
+                    return result
+        else:
+            self.deviceBackupManager.loadBackups()
+            for backup in selectedBackups:
+                backupInfo = self.deviceBackupManager.getBackupInfo(str(backup))
+                self.emit(SIGNAL("restoreStarted"))
+                result = self.deviceBackupManager.startBackupRestore(backupInfo, 
+                                                          categories)
+                if result == False or result == 0:
+                    return result
+        return True
+
+    def showRestoreMessage(self, done):
+        if done != 0:
+            self._progressDialog.cancel()  
+            ip = self.deviceBackupManager._deviceInfo.ip
+            if done:
+                doneMessage = "Restore done. Your device will be rebooted now"
+                showMessageBox(doneMessage, "Restore successfully Done")
+                rebootDevice(ip)
+            else:
+                showMessageBox("An error occurred while restoring backup",
+                                 "Restore error")
+              
+    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()
+        layout.setMargin(10)
+        listWidget = QListWidget()
+        listWidget.setObjectName("viewList")
+        listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
+
+        backupContentList = backupManager.listBackupContent(backupName)
+        if not backupContentList:
+            showMessageBox("Could not open backup files", "Error")
+            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 _runRestoreProgress(self):
+        self._progressDialog = PcsProgressDialog(self)
+        self._progressDialog.setAction("restore")
+        self.connect(self._progressDialog.cancelButton, SIGNAL("clicked()"),
+                      self._onRestoreCancel)
+        
+        self._progressDialog.show()
+    
+    def _updateCategoriesAndProgress(self, information):
+        progress, category, self.numberOfFiles, self.totalSize = information
+        
+        self._progressDialog.setProgress(progress)
+        self._progressDialog.setCategory(category)
+    
+    def _onRestodeDone(self):
+        self._progressDialog.updateInfo(self.totalSize, self.numberOfFiles)
+        self._progressDialog.progressDone()
+    
+    def _onRestoreCancel(self):
+        self._progressDialog.progressCanceled()
+        if self._currentBackupList() == self.pcListView:
+            self.pcBackupManager.setRestoreInProgress(False)
+        else:
+            self.deviceBackupManager.setRestoreInProgress(False)
+            
+    def _onOpenFileError(self):
+        self._progressDialog.close()
+        showMessageBox(OPEN_FILE_ERROR, OPEN_FILE_ERROR_TITLE)
+    
+class RestoreBackupThread(QThread):
+    def __init__(self, restoreBackup, manager,  categories):
+        QThread.__init__(self)
+        self.restoreBackup = restoreBackup
+        self.categories = categories
+        self.connect(manager, SIGNAL("restoreProgress"), self._reEmitSignal)
+    
+    def _reEmitSignal(self, informations):
+        self.emit(SIGNAL("restoreProgress"), informations)
+
+    def run(self):
+        try:
+            done = self.restoreBackup._doRestoreBackup(self.categories)
+        except IOError:
+            self.emit(SIGNAL("openFileError"))
+            return
+        self.emit(SIGNAL("restoreDone"))
+    
diff --git a/src/backup/pcsrestoredialog.py b/src/backup/pcsrestoredialog.py
new file mode 100644 (file)
index 0000000..dbef514
--- /dev/null
@@ -0,0 +1,199 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from style.styleTabletSuite import *
+from ui.pcsdevicewidget import PcsDeviceWidget
+from ui.pcsuiutils import *
+
+class PcsRestoreDialog(QDialog):
+       
+    def __init__(self, deviceInfo, categoriesList, parent = None):
+        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
+        self.setWindowTitle("%s Restore Backup" % APPLICATION_NAME)
+        self.setFixedSize(200, 300)
+        self.deviceInfo = deviceInfo
+        self.categories = categoriesList
+        self.validPositions = []
+        self.validCategories = []
+        
+        self.layout = QVBoxLayout()
+        
+        self.labelLayout = QHBoxLayout()  
+        spc = QSpacerItem(15, 0)
+        self.labelLayout.addItem(spc)
+        label = QLabel("Which categories you want to restore?")
+        label.setWordWrap(True)
+        self.labelLayout.addWidget(label)
+        self.labelLayout.setMargin(0)
+        self.layout.addLayout(self.labelLayout)
+             
+#        self.grid = QGridLayout()
+#        self.create_dialog()
+#        self.grid.setMargin(0)
+#        self.layout.addLayout(self.grid)
+        self.create_checkbox_frame()
+        
+        self.buttonLayout = QHBoxLayout()
+        self.create_buttons()
+        self.buttonLayout.setMargin(0)
+        self.layout.addLayout(self.buttonLayout)
+        
+        self.setLayout(self.layout)
+        self.map_checked = {self.documents.name: False,
+                            self.emails.name: False, self.media.name: False,
+                            self.contacts.name: False, 
+                            self.bookmarks.name: False,
+                            self.settings.name: False, 
+                            self.applications.name: False}
+    
+    def empty_map(self):
+        for index in self.map_checked.keys():
+            if self.map_checked[index]:
+                return False
+        return True
+    
+    def create_buttons(self):
+        self.buttonOk = QPushButton("Ok")
+        self.buttonOk.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.buttonLayout.addWidget(self.buttonOk)
+        
+        self.buttonCancel = QPushButton("Cancel")
+        self.buttonCancel.setStyleSheet(DEFAULT_BUTTON_STYLE)
+        self.buttonLayout.addWidget(self.buttonCancel)
+    
+    def create_checkbox_frame(self):
+        layout = QVBoxLayout()
+        l = QLabel()
+        l.setPixmap(QPixmap(COPY_BORDER))
+       
+        self.frame = QScrollArea(self)
+        self.frame.setObjectName("restoreScroll")
+        self.frame.setWidgetResizable(True)
+        widget = QWidget(self.frame)
+        widget.setStyleSheet("QWidget{background: transparent;}")
+        self.grid = QGridLayout()
+        self.grid.setSpacing(0)
+        self.create_dialog()
+        widget.setLayout(self.grid)
+        self.frame.setWidget(widget)
+        layout.addWidget(self.frame)
+        self.layout.addLayout(layout)
+        
+    def create_dialog(self):
+        #Add Checkboxes
+#        self.add_select_all()
+        self.add_documents()
+        self.add_emails()
+        self.add_media()
+        self.add_contacts()
+        self.add_bookmarks()
+        self.add_settings()
+        self.add_applications()            
+        
+#    def add_select_all(self):
+#        self.select_all = QCheckBox("Select All")
+#        self.connect(self.select_all, SIGNAL("stateChanged(int)"), 
+#                     self.select_all_func)
+#        self.validPositions.append((1,0))
+#        self.grid.addWidget(self.select_all, 1, 0, Qt.AlignTop)          
+#    
+    def add_documents(self):
+        self.documents = QCheckBox("Documents")
+        self.documents.name = "documents"
+        callback = partial(self.select_func, self.documents)
+        self.connect(self.documents, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "documents" in self.categories:
+            self.validPositions.append((2, 0))
+            self.grid.addWidget(self.documents, 2, 0, Qt.AlignTop)
+    
+    def add_emails(self):
+        self.emails = QCheckBox("Emails")
+        self.emails.name = "emails"
+        callback = partial(self.select_func, self.emails)
+        self.connect(self.emails, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "emails" in self.categories:
+            self.validPositions.append((3, 0))
+            self.grid.addWidget(self.emails, 3, 0, Qt.AlignTop)
+    
+    def add_media(self):
+        self.media = QCheckBox("Media")
+        self.media.name = "media"
+        callback = partial(self.select_func, self.media)
+        self.connect(self.media, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "media" in self.categories:
+            self.validPositions.append((4, 0))
+            self.grid.addWidget(self.media, 4, 0, Qt.AlignTop)
+    
+    def add_contacts(self):
+        self.contacts = QCheckBox("Contacts")
+        self.contacts.name = "contacts"
+        callback = partial(self.select_func, self.contacts)
+        self.connect(self.contacts, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "contacts" in self.categories:
+            self.validPositions.append((5, 0))
+            self.grid.addWidget(self.contacts, 5, 0, Qt.AlignTop)
+    
+    def add_bookmarks(self):
+        self.bookmarks = QCheckBox("Bookmarks")
+        self.bookmarks.name = "bookmarks"
+        callback = partial(self.select_func, self.bookmarks)
+        self.connect(self.bookmarks, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "bookmarks" in self.categories:
+            self.validPositions.append((6, 0))
+            self.grid.addWidget(self.bookmarks, 6, 0, Qt.AlignTop)
+        
+    def add_settings(self):
+        self.settings = QCheckBox("Settings")
+        self.settings.name = "settings"
+        callback = partial(self.select_func, self.settings)
+        self.connect(self.settings, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "settings" in self.categories:
+            self.validPositions.append((7, 0))
+            self.grid.addWidget(self.settings, 7, 0, Qt.AlignTop)
+
+    def add_applications(self):
+        self.applications = QCheckBox("Applications")
+        self.applications.name = "applications"
+        callback = partial(self.select_func, self.applications)
+        self.connect(self.applications, SIGNAL("stateChanged(int)"), 
+                     callback)
+        if "applications" in self.categories:
+            self.validPositions.append((8, 0))
+            self.grid.addWidget(self.applications, 8, 0, Qt.AlignTop)
+
+#    def select_all_func(self):
+#        checked = self.select_all.isChecked()
+#        list = self.map_checked.keys()
+#        for element in list:
+#            self.map_checked[element] = checked
+#        for tuple in self.validPositions:
+#            self.grid.itemAtPosition(tuple[0], tuple[1]).widget().setChecked(checked)
+#        
+    def select_func(self, checkbox):
+        checked = checkbox.isChecked()
+        self.map_checked[checkbox.name] = checked
+        if not checked:
+            list = []
+            for tuple in self.validPositions:
+                item = self.grid.itemAtPosition(tuple[0], tuple[1]).widget()
+#                if item == self.select_all:
+#                    pass
+                if item.isChecked():
+                    list.append(item)
+#            self.select_all.setChecked(False)
+            for element in list:
+                element.setChecked(True)         
+            
+    def getCategories(self):
+        return self.map_checked
+        
diff --git a/src/backup/pcswindowmanager.py b/src/backup/pcswindowmanager.py
new file mode 100644 (file)
index 0000000..a0aa565
--- /dev/null
@@ -0,0 +1,36 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from pcsbackupwizard import PcsBackupWizard
+from pcsrestorebackupui import PcsRestoreBackupUi
+from pcsbackupmanagerui import PcsBackupManagerUi
+
+class PcsWindowManager:
+    class _impl:
+        def __init__(self, deviceInfo, parent = None):
+            self.__newBackup = PcsBackupWizard(deviceInfo, self, parent)
+            self.__restoreBackup = PcsRestoreBackupUi(deviceInfo, self, parent)
+            self.__backupManager = PcsBackupManagerUi(deviceInfo, self, parent)
+            
+        def getNewBackup(self):
+            return self.__newBackup
+        
+        def getRestoreBackup(self):
+            return self.__restoreBackup
+            
+        def getBackupManager(self):
+            return self.__backupManager
+        
+    __instance = None
+
+    def __init__(self, deviceInfo = None, parent = None):
+        if PcsWindowManager.__instance is None:
+            PcsWindowManager.__instance = PcsWindowManager._impl(deviceInfo, parent)
+        self.__dict__['Singleton_instance'] = PcsWindowManager.__instance
+
+    def __getattr__(self, attr):
+        return getattr(self.__instance, attr)
+
+    def __setattr__(self, attr, value):
+        return setattr(self.__instance, attr, value)
+        
\ No newline at end of file
diff --git a/src/battery.py b/src/battery.py
new file mode 100644 (file)
index 0000000..0404ab0
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+# Ainda continua sendo o codigo do cara, apenas retirei as partes que nao nos interessa.
+# Ainda tem que ver se pode usar o codigo, ou seja, olhar a licensa. 
+# Deve ser istalado no dispositivo
+# Otacilio Lacerda
+
+import dbus
+import dbus.service
+import dbus.glib
+import gobject
+
+percent_left = -1
+charging = False
+
+loop = gobject.MainLoop()
+
+class Request(dbus.service.Object): 
+    def __init__(self, bus_name):
+        dbus.service.Object.__init__(self, bus_name, '/com/nokia/bme/request')
+
+    @dbus.service.signal('com.nokia.bme.request')
+    def timeleft_info_req(self):
+        pass
+
+    @dbus.service.signal('com.nokia.bme.request')
+    def status_info_req(self):
+        pass
+
+def timeleft_handler(idle_time, active_time):
+    global percent_left
+    percent_left = min(100, 100.0 * idle_time / 15000)
+    loop.quit()
+
+def charging_on_handler():
+    global charging
+    charging = True
+    loop.quit()
+
+def charging_off_handler():
+    global charging
+    charging = False
+    loop.quit()
+
+def getBatteryState(request):
+    global percent_left
+    global charging
+
+    request.status_info_req()
+    loop.run()
+
+    if charging:
+        return -1
+    request.timeleft_info_req()
+    loop.run()
+    return percent_left
+
+if __name__ == "__main__":
+
+    bus = dbus.SystemBus(private = True)
+    bus.add_signal_receiver(timeleft_handler, 'battery_timeleft')
+    bus.add_signal_receiver(charging_on_handler, 'charger_charging_on')
+    bus.add_signal_receiver(charging_on_handler, 'battery_full')
+    bus.add_signal_receiver(charging_off_handler, 'charger_charging_off')
+    bus_name = dbus.service.BusName('com.nokia.bme.request', bus)
+    request = Request(bus_name)
+
+    percent = getBatteryState(request)
+    if percent < 0:
+        print '-1'
+    else:
+        print '%.1f' % (percent)
+
diff --git a/src/pcsdeviceinfo.py b/src/pcsdeviceinfo.py
new file mode 100644 (file)
index 0000000..5e913eb
--- /dev/null
@@ -0,0 +1,15 @@
+# low_device_info module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+
+class PcsDeviceInfo:
+
+    def __init__(self):
+        self.ip = ""
+        self.storage = 0 # list memory data (FIXME: document the array information
+        self.battery = 0
+        self.model = ""
+        self.name = ""
+        self.hostname = ""
+        self.system = ""
+        self.charging = False
+        self.ossoBackup = ""        
diff --git a/src/pcsdevicemanager.py b/src/pcsdevicemanager.py
new file mode 100644 (file)
index 0000000..a63160f
--- /dev/null
@@ -0,0 +1,131 @@
+# low_device_manager module 
+# Authors: Nicholas Alexander && Otacilio Lacerda
+# Module responsible for management of devices informations. 
+
+import pickle
+import os
+
+from PyQt4.QtCore import *
+
+import pcsutils as utils
+from pcsdeviceinfo import PcsDeviceInfo
+from pcsdeviceutils import *
+from ui.tsuigeneralmethods import showMessageBox
+
+USER_HOST = 'root'
+HOME = os.path.expanduser("~")
+DEVICES_FILE = os.path.join(HOME, ".pcsuite/devices/.ip_list")
+
+
+class PcsDeviceManager(QObject):
+    """Class responsible for devices management such as adding and removing
+    devices, get batery, memory and name informations and saving Device objects.
+
+    The DeviceManager holds a list of Devices objects and can save and load this
+    list on a file and retrieve information about each Device.
+
+    """
+    _currentIp = None
+    def __init__(self):
+        QObject.__init__(self)
+        self._deviceList = []
+        
+        # FIXME: initialize this in another place
+        utils.initDirs()
+        self.loadDevices()
+
+        self._currentIp = None
+
+    def _batteryException(self):
+        errorMessage = "Could not get device battery status, check if " +\
+            "python is installed on your device. To get information about " + \
+            "python installation visit: " +\
+            "http://pymaemo.garage.maemo.org/installation.html"
+        showMessageBox(errorMessage,
+                              "Error while collecting device information")
+
+    def _addDevice(self, deviceIp):
+        """Add a new device to list connecting to it in the process.
+    
+        Arguments:
+        host_ip -- The IP of the device to connect.
+        
+        """
+        self.loadDevices()
+                    
+        deviceInfo = PcsDeviceInfo()
+        deviceInfo.ip = deviceIp
+        (deviceInfo.name, deviceInfo.system,
+         deviceInfo.ossoBackup) = queryProductInformation(deviceIp) 
+        if deviceInfo.name == "NO INFORMATION":
+            return "connectException"
+        try:
+            deviceInfo.battery = float(queryDeviceBattery(deviceIp))
+        except:
+            return "batteryException"
+    
+        if deviceInfo.battery < 0:
+            deviceInfo.charging = True
+            
+        deviceInfo.storage = queryDeviceStorage(deviceIp)
+        
+        if self.getDevice(deviceIp) != None:
+            return deviceInfo
+        
+        self._deviceList.append(deviceInfo)
+        self.saveDevices()
+        return deviceInfo
+
+    def removeDevice(self, deviceIp):
+        """Remove a Device from list.
+
+        Arguments:
+        device_ip -- The IP  of the device to remove
+
+        """
+        deviceInfo = self.getDevice(deviceIp)
+        if deviceInfo != -1:
+            self._deviceList.remove(deviceInfo)
+            self.saveDevices()
+            return 1
+        else:
+            raise Exception("No device with that ip was found")
+
+    def getDevices(self):
+        """Returns a list with the IP address of all devices in the object's 
+        devices list.
+        
+        """
+        ips = []
+        for deviceInfo in self._deviceList:
+            ips.append(deviceInfo.ip)
+        return ips
+
+    def saveDevices(self):
+        """Save the list of Device objects in DEVICES_FILE file."""
+        obj = self._deviceList
+        file = open(DEVICES_FILE, "w")
+        pickle.dump(obj, file)
+        file.close()
+
+    def loadDevices(self):
+        """Loads the list of Device objects from DEVICES_FILE path if possible."""
+
+        if os.path.exists(DEVICES_FILE):
+            file = open(DEVICES_FILE)
+            self._deviceList = pickle.load(file)
+            file.close()
+
+    def getDevice(self, ip):
+        # Returns the Device object with the provided ip
+        for deviceInfo in self._deviceList:
+            if deviceInfo.ip == ip:
+                return deviceInfo
+        return None
+
+    def setCurrentDevice (self, ip):
+        self._currentIp = ip
+        
+    def getCurrentDevice(self):
+        return self.getDevice(self._currentIp)
+    
diff --git a/src/pcsdeviceutils.py b/src/pcsdeviceutils.py
new file mode 100644 (file)
index 0000000..efe8da0
--- /dev/null
@@ -0,0 +1,155 @@
+# low_backup module
+# Authors: Nicholas Alexander && Otacilio Lacerda
+
+import commands
+import os
+
+BATTERY = os.environ['BATTERY_PATH'] + 'battery.py'
+EXECUTE = "./"
+USER_HOST = "root"
+
+def queryProductInformation(deviceIp):
+    """ Update device name by getting device product name and os version
+    informations.
+
+    Use osso-product-info command to get the device and device OS short
+    names and set each to it correspondent attribute.
+
+    """
+
+    info = commands.getoutput("ssh -l %s %s osso-product-info" %
+                                        (USER_HOST, deviceIp))
+
+    deviceName = _extractOssoInfo(info, "shortName")
+    deviceOs = _extractOssoInfo(info, "shortOS")
+    ossoVersion = _extractOssoInfo(info, "ossoVersion")
+    if deviceName != -1 and deviceOs != -1:
+        deviceName = deviceName.strip("'")
+        deviceOs = deviceOs.strip("'")
+    else:
+        deviceName = "NO INFORMATION"
+        deviceOs = "NO INFORMATION"
+
+    return (deviceName, deviceOs, ossoVersion)
+
+def queryDeviceStorage(deviceIp):
+    """Returns a list of tuples, each tuple representing a memory status.
+
+    Tuples are in this format: (total, used)
+
+    Returns:
+        mem_infos -- List with all tuples holding memory info
+
+    """
+    info = commands.getoutput("ssh -l root %s df" %
+                              deviceIp).splitlines()
+    mem_infos = [-1, -1, -1]
+    for line in info:
+        if line.find("/dev/mtdblock4") != -1:
+            if line[-1] == "/":
+                total_used = _get_memory(line, "/dev/mtdblock4")
+                mem_infos.pop(0)
+                mem_infos.insert(0, total_used)
+        
+        elif line.find("/media/mmc1") != -1:
+            total_used = _get_memory(line, "/dev/mmcblk0p1")
+            mem_infos.pop(1)
+            mem_infos.insert(1, total_used)
+        
+        elif line.find("/media/mmc2") != -1:
+            total_used = _get_memory(line, "/dev/mmcblk1p1")
+            mem_infos.pop(2)
+            mem_infos.insert(2, total_used)
+    return mem_infos
+
+def queryDeviceBattery(deviceIp):
+    """Return device current battery status in a string.
+
+    This method runs a python script in the device that returns the battery
+    status, this status is represented by one string with the percentage of
+    battery current charge or the number -1 case battery is charging.
+
+    Returns:
+    text -- Text with the battery status
+
+    """
+
+    # Calls script that returns device battery status    
+    os.system("scp %s %s@%s:/tmp" % (BATTERY, USER_HOST, deviceIp))
+    battery_status = commands.getoutput("ssh -l %s %s /usr/bin/python \
+                                        /tmp/battery.py" % (USER_HOST, 
+                                                            deviceIp))
+    return battery_status
+
+def _get_memory(line, path):
+    """Retrieve and return total and used memory information from the given 
+    line using the memory path to retrieve the right information.
+
+    This function is to be used with a line of the return of a df command.
+
+    Arguments:
+    line -- The line where the memory information is
+    path -- The path in the begining of the line
+
+    Returns:
+    total -- Total memory
+    used -- Amount of used memory
+
+    """
+    number_of_infos = 0
+    i = len(path) + 1
+    while number_of_infos < 2:
+        char = line[i]
+        if char != " ":
+            start = i
+            end = line.find(" ", start + 1)
+            if number_of_infos == 0:
+                total = line[start: end]
+            elif number_of_infos == 1:
+                used = line[start: end]
+            i = end
+            number_of_infos += 1
+        i += 1
+    return total, used
+
+def _extractOssoInfo(osso_string, info_type="name"):
+    """Read the osso-product-info command return string and extract the
+    needed info depeding on info_type argument.
+
+    Arguments:
+    osso_string -- The string returned by osso-product-info command
+    info_type -- the kind of information to b extracted, can be:
+        name - returns device full name (default)
+        OS - returns device OS full name
+        shortName - returns device short name
+        shortOS - returns device short OS name
+
+    Returns:
+    info -- String with the needed information
+    -1 -- Case the information couldn't be found in the given string
+
+    """
+    detailed_type = ""
+    if info_type == "shortName":
+        detailed_type = "OSSO_PRODUCT_NAME"
+    elif info_type == "shortOS":
+        detailed_type = "OSSO_PRODUCT_RELEASE_NAME"
+    elif info_type == "name":
+        detailed_type = "OSSO_PRODUCT_FULL_NAME"
+    elif info_type == "OS":
+        detailed_type = "OSSO_PRODUCT_RELEASE_FULL_NAME"
+    elif info_type == "ossoVersion":
+        detailed_type = "OSSO_VERSION"
+    else:
+        detailed_type = "OSSO_PRODUCT_FULL_NAME"
+
+    types_list = osso_string.splitlines()
+    info = -1
+    for type_line in types_list:
+        if type_line.startswith(detailed_type):
+            # The second argument is the information itself since informations
+            # are displayed like: OSSO_PRODUCT_RELEASE_NAME='OS 2008'
+            info = type_line.split("=")[1]
+
+    return info
diff --git a/src/pcsuite/.svn/all-wcprops b/src/pcsuite/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..b956fd7
--- /dev/null
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/pc-suite/!svn/ver/612/trunk/tabletsuite/src/pcsuite
+END
+pcsuite.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/svn/pc-suite/!svn/ver/612/trunk/tabletsuite/src/pcsuite/pcsuite.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/pcsuite/__init__.py
+END
diff --git a/src/pcsuite/.svn/dir-prop-base b/src/pcsuite/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/pcsuite/.svn/entries b/src/pcsuite/.svn/entries
new file mode 100644 (file)
index 0000000..cf0dc6d
--- /dev/null
@@ -0,0 +1,96 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src/pcsuite
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-09-10T20:35:15.948790Z
+612
+pauloouriques
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+pcsuite.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+1762e558bf43ba18c805db6698bf3945
+2009-09-10T20:35:15.948790Z
+612
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2373
+\f
+__init__.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-04-02T19:30:47.227755Z
+61
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
diff --git a/src/pcsuite/.svn/format b/src/pcsuite/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/pcsuite/.svn/text-base/__init__.py.svn-base b/src/pcsuite/.svn/text-base/__init__.py.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/pcsuite/.svn/text-base/pcsuite.py.svn-base b/src/pcsuite/.svn/text-base/pcsuite.py.svn-base
new file mode 100644 (file)
index 0000000..f4026c8
--- /dev/null
@@ -0,0 +1,71 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+import sys
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsmenu import *
+from ui.pcsapplicationlist import *
+from ui.pcsdeviceviewer import *
+from ui.pcsuiutils import *
+from pcsdevicemanager import PcsDeviceManager
+from ui.pcscustombuttons import PcsCustomButton as customButton
+from ui.pcsbutton import PcsButton
+from style.styleTabletSuite import *
+
+class PCSuite(QMainWindow):
+    
+    ''' Class that creates the main window of Pc Suite. '''
+    
+    def __init__(self):
+        QMainWindow.__init__(self) 
+        
+        self.setWindowIcon(QIcon(TABLET_SUITE_LOGO))
+        self.setWindowTitle(APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+        
+        self.deviceManager = PcsDeviceManager()
+        self.menuBar = PcsMenu(self.deviceManager, self)
+#        self.menuBar.setVisible(False)
+        self.setMenuBar(self.menuBar)
+        
+        self.topPanel = PcsApplicationList(self.deviceManager)
+        self.bottomPanel = PcsDeviceViewer(self.deviceManager, self)
+        
+        layout = QVBoxLayout()
+        spacer = QSpacerItem(0, 70)
+        layout.addItem(spacer)
+        layout.addWidget(self.topPanel)
+        layout.addWidget(self.bottomPanel)
+        layout.setMargin(0)
+        layout.setSpacing(0)
+        centralize(self)
+        
+        centralPanel = QFrame()
+        centralPanel.setLayout(layout)
+        self.setCentralWidget(centralPanel)
+        
+        self.connectLabel = PcsButton("connect", self)
+        self.connectLabel.setObjectName("tsButton")
+        self.connectLabel.setGeometry(QRect(14, 365, 94, 35))
+        self.connect(self.connectLabel, SIGNAL("clicked()"), self.bottomPanel.showConnectDialog)
+        
+        self.backButton = customButton(BACK_BUTTON, BACK_BUTTON_CLICKED, self)
+        self.backButton.setGeometry(QRect(411, 39, 15, 15))
+        self.connect(self.backButton, SIGNAL("clicked()"), self.back)
+        
+        self.forwardButton = customButton(FORWARD_BUTTON, FORWARD_BUTTON_CLICKED, self)
+        self.forwardButton.setGeometry(QRect(430, 39, 15, 15))
+        self.connect(self.forwardButton, SIGNAL("clicked()"), self.forward)
+        
+        self.setStyleSheet(STYLESHEET)
+
+
+    def back(self):
+        print "back"
+        
+    def forward(self):
+        print "forward"
+    
diff --git a/src/pcsuite/__init__.py b/src/pcsuite/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/pcsuite/pcsuite.py b/src/pcsuite/pcsuite.py
new file mode 100644 (file)
index 0000000..f4026c8
--- /dev/null
@@ -0,0 +1,71 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+import sys
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsmenu import *
+from ui.pcsapplicationlist import *
+from ui.pcsdeviceviewer import *
+from ui.pcsuiutils import *
+from pcsdevicemanager import PcsDeviceManager
+from ui.pcscustombuttons import PcsCustomButton as customButton
+from ui.pcsbutton import PcsButton
+from style.styleTabletSuite import *
+
+class PCSuite(QMainWindow):
+    
+    ''' Class that creates the main window of Pc Suite. '''
+    
+    def __init__(self):
+        QMainWindow.__init__(self) 
+        
+        self.setWindowIcon(QIcon(TABLET_SUITE_LOGO))
+        self.setWindowTitle(APPLICATION_NAME)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+        
+        self.deviceManager = PcsDeviceManager()
+        self.menuBar = PcsMenu(self.deviceManager, self)
+#        self.menuBar.setVisible(False)
+        self.setMenuBar(self.menuBar)
+        
+        self.topPanel = PcsApplicationList(self.deviceManager)
+        self.bottomPanel = PcsDeviceViewer(self.deviceManager, self)
+        
+        layout = QVBoxLayout()
+        spacer = QSpacerItem(0, 70)
+        layout.addItem(spacer)
+        layout.addWidget(self.topPanel)
+        layout.addWidget(self.bottomPanel)
+        layout.setMargin(0)
+        layout.setSpacing(0)
+        centralize(self)
+        
+        centralPanel = QFrame()
+        centralPanel.setLayout(layout)
+        self.setCentralWidget(centralPanel)
+        
+        self.connectLabel = PcsButton("connect", self)
+        self.connectLabel.setObjectName("tsButton")
+        self.connectLabel.setGeometry(QRect(14, 365, 94, 35))
+        self.connect(self.connectLabel, SIGNAL("clicked()"), self.bottomPanel.showConnectDialog)
+        
+        self.backButton = customButton(BACK_BUTTON, BACK_BUTTON_CLICKED, self)
+        self.backButton.setGeometry(QRect(411, 39, 15, 15))
+        self.connect(self.backButton, SIGNAL("clicked()"), self.back)
+        
+        self.forwardButton = customButton(FORWARD_BUTTON, FORWARD_BUTTON_CLICKED, self)
+        self.forwardButton.setGeometry(QRect(430, 39, 15, 15))
+        self.connect(self.forwardButton, SIGNAL("clicked()"), self.forward)
+        
+        self.setStyleSheet(STYLESHEET)
+
+
+    def back(self):
+        print "back"
+        
+    def forward(self):
+        print "forward"
+    
diff --git a/src/pcsutils.py b/src/pcsutils.py
new file mode 100755 (executable)
index 0000000..7d8a930
--- /dev/null
@@ -0,0 +1,165 @@
+import os.path
+
+import commands
+import os
+import pwd
+import settings
+import socket
+import sys
+
+import paramiko
+
+from backup.pcsbackuputils import createFolder
+
+sshPath = os.path.expanduser('~/.ssh/') 
+known_hosts = os.path.join(sshPath, 'known_hosts')
+log_file = os.path.expanduser('~/.pcsuite/.ssh_log')
+user = 'root'
+keyName = 'rsa_key'
+
+def create_route(host, port=22):
+    # Verify Auth with privateKey
+    try:
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(15)
+        sock.connect((host, port))
+        sock.close()
+        return True
+    except:
+        print 'No route to host'
+        return False
+
+def verify_exist_keys(host, port=22):
+    try:    
+        transport = _create_transport(host, port)
+    except:
+        return False
+    try:
+        getKey = paramiko.RSAKey.from_private_key_file(sshPath + keyName)
+        transport.start_client()
+        transport.auth_publickey(user, getKey)
+        if transport.is_authenticated():
+            transport.close()
+            return True
+    except:
+        # 'Error in auth with publickey, try with password...'
+        return False
+    return False
+
+def keyExchange(host, passwd, port=22):
+    if not os.path.exists(sshPath):
+        createFolder(sshPath)
+
+    # Clean cached keys in ssh-agent
+    os.system('ssh-add -d')    
+
+    try:
+        transport = _create_transport(host, port)
+    except:
+        transport.close()
+        return False
+
+    if not _add_host_fingerprint(host):
+        transport.close()
+        return False
+
+    if not _authenticate(user, passwd, transport):
+        transport.close()
+        return False
+    
+    if not _add_key_to_host(host, transport):
+        transport.close()
+        return False
+
+    transport.stop_thread()
+    transport.close()
+    return True
+
+def initDirs():
+    settings.makeDirs()
+
+def _create_transport(host, port):
+    # Create a transport and initiate client mode
+    try:
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(15)
+        sock.connect((host, port))
+    except Exception, msg:
+        print 'Connect failed: ' + str(msg)
+        raise Exception('Error while create sockets.')
+    transport = paramiko.Transport(sock)
+    return transport
+
+def _add_host_fingerprint(host):
+    if not os.path.exists(known_hosts):
+        os.system('touch %s' %known_hosts)
+    if os.system('ssh-keyscan -t rsa %s >> %s' %(host, known_hosts)) != 0:
+        return False
+    return True
+
+def _generate_keys():
+    # Generate public and private RSAKey
+    keyFile = os.path.join(sshPath, keyName)
+    if not os.path.exists(keyFile):
+        privateKey = paramiko.RSAKey.generate(2048)
+        privateKey.write_private_key_file(keyFile)
+        login = pwd.getpwuid(os.geteuid())[0]
+        publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
+                                    privateKey.get_base64(),
+                                    login , socket.gethostname())
+        try:
+            keyFile = open(keyFile + '.pub','w')
+            keyFile.write(publicKey)
+            keyFile.close()
+        except:
+            print 'Error while save the public key'
+            raise Exception()
+    else:
+        try:
+            privateKey = paramiko.RSAKey.from_private_key_file(keyFile)
+            login = pwd.getpwuid(os.geteuid())[0]
+            publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
+                                        privateKey.get_base64(),
+                                    login , socket.gethostname())
+        except:
+            print 'Error while read the private key'
+            raise Exception()
+    return publicKey
+
+def _authenticate(user, passwd, transport):
+    # Try Auth with password
+    try:
+        transport.start_client()
+        transport.auth_password(user, passwd)
+    except:
+        print 'Verify user or password.'
+        return False
+    if not transport.is_authenticated():
+        print 'Authentication fail'
+        return False
+
+    try:
+        exception = transport.get_exception()
+        if exception:
+            raise exception
+    except Exception, msg:
+        print 'Error in connection: ' + str(msg)
+        return False
+    return True
+
+def _add_key_to_host(host, transport):
+    # Add publickey in host
+    if not transport.is_active():
+        print 'Channel is not active'
+        return False
+    
+    paramiko.util.log_to_file(log_file, 10)
+    channel = transport.open_session()
+    try:
+        channel.exec_command('mkdir -p ~/.ssh; echo %s >> .ssh/authorized_keys' % (_generate_keys()))
+    except Exception, msg:
+        print 'Error while generate or add the keys.'
+        channel.close()
+        return False
+    channel.close()
+    return True
diff --git a/src/plugins/.svn/all-wcprops b/src/plugins/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..87e0384
--- /dev/null
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/plugins
+END
diff --git a/src/plugins/.svn/entries b/src/plugins/.svn/entries
new file mode 100644 (file)
index 0000000..08f5fb3
--- /dev/null
@@ -0,0 +1,28 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src/plugins
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-06-30T08:48:39.342304Z
+359
+pauloouriques
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
diff --git a/src/plugins/.svn/format b/src/plugins/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/settings.py b/src/settings.py
new file mode 100644 (file)
index 0000000..d5b0325
--- /dev/null
@@ -0,0 +1,36 @@
+import os
+import os.path
+
+class Settings:
+    def __init__(self):
+        self.home = os.path.expanduser("~")
+        self.default_folder = os.path.join(self.home, ".pcsuite")
+        self.devices_folder = os.path.join(self.default_folder,
+                                        "devices")
+        self.backup_config_path = os.path.join(self.default_folder, "config")
+        self.backup_folder = os.path.join(self.default_folder, "Backup")
+
+    def initalize(self):
+
+        """Check the existence of required project folders, creating
+        them if needed. Also gives execution permission to all scripts.
+
+        """
+
+        # This is checking if the default folder exists too, because
+        # if it doesn't exist the mount_point won't exist either
+        if not os.path.exists(self.devices_folder):
+            os.makedirs(self.devices_folder)
+        if not os.path.exists(self.backup_config_path):
+            os.makedirs(self.backup_config_path)
+        if not os.path.exists(self.backup_folder):
+            os.makedirs(self.backup_folder)
+
+def makeDirs():
+    s = Settings()
+    s.initalize()
+
+if __name__ == "__main__":
+    makeDirs()
+    
+
diff --git a/src/style/.svn/all-wcprops b/src/style/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..7c9e76f
--- /dev/null
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/svn/pc-suite/!svn/ver/652/trunk/tabletsuite/src/style
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/style/__init__.py
+END
+styleTabletSuite.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/652/trunk/tabletsuite/src/style/styleTabletSuite.py
+END
diff --git a/src/style/.svn/entries b/src/style/.svn/entries
new file mode 100644 (file)
index 0000000..6757ffc
--- /dev/null
@@ -0,0 +1,96 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src/style
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-10-05T11:14:02.602311Z
+652
+pauloouriques
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+__init__.py
+file
+
+
+
+
+2009-09-29T18:30:21.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-08-11T18:25:49.287367Z
+542
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+styleTabletSuite.py
+file
+
+
+
+
+2009-10-08T18:25:37.000000Z
+7c1ee6b259b399ddeab35930daa946eb
+2009-10-05T11:14:02.602311Z
+652
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19114
+\f
diff --git a/src/style/.svn/format b/src/style/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/style/.svn/text-base/__init__.py.svn-base b/src/style/.svn/text-base/__init__.py.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/style/.svn/text-base/styleTabletSuite.py.svn-base b/src/style/.svn/text-base/styleTabletSuite.py.svn-base
new file mode 100644 (file)
index 0000000..493cdd5
--- /dev/null
@@ -0,0 +1,606 @@
+from ui.pcsuiutils import *
+
+STYLESHEET = ''' 
+            QPushButton {
+                min-height:33px; 
+                min-width:64px; 
+                max-height:33px;
+                max-width:64px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy: NoFocus;
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+            
+            QPushButton#tsButton {
+                color : #636060;
+                background-image: url(''' + BUTTON_BG +''');
+                min-height:33px; 
+                min-width:91px;
+                max-height:32px;
+                max-width:93px;
+                border: none; 
+                qproperty-focusPolicy : NoFocus;
+                qproperty-icon: none; 
+            }
+            
+            QPushButton#tsButton::pressed {
+                background-image: url(''' + BUTTON_BG_CLICKED + ''');
+            }
+            
+            QPushButton#smallButton {
+                color : gray;
+                border-image: url(''' + BUTTON_BG +''');
+                min-height:20px; 
+                min-width:34px;
+                max-height:20px;
+                max-width:34px;
+                border: none; 
+                qproperty-focusPolicy : NoFocus;
+                qproperty-icon: none; 
+                background:transparent;
+            }
+            
+            QPushButton#smallButton::pressed {
+                border-image: url(''' + BUTTON_BG_CLICKED + ''');
+                background:transparent;
+            }
+            
+            QMainWindow {
+                background-image: url(''' + BACKGROUND_IMAGE + ''');
+            }
+            
+            PcsBackup {
+                background-image: url('''+ BACKUP_BG +''')
+            }
+            
+            PcsRestoreBackupUi {
+                background-image: url('''+ RESTORE_BG +''')
+            }
+            
+            PcsBackupManagerUi{
+                background-image: url('''+ MANAGER_BG +''')
+            }
+            
+            QListWidget {
+                selection-background-color : transparent;
+            }
+            
+            QMenuBar::item {
+                background: transparent;
+            }
+            
+            QMenuBar {
+                background: transparent;
+            }
+            
+            QRadioButton{
+                qproperty-focusPolicy: NoFocus;
+                border-image: url('''+ CHECKBOX_BORDER +''');
+                min-height: 38px; 
+                max-height: 38px;
+            }
+            
+            QRadioButton::indicator:unchecked {
+                image: url(''' + CHECKBOX_UNCHECKED + ''');
+            }
+            
+            QRadioButton::indicator:checked {
+                image: url('''+ CHECKBOX_CHECKED +''');
+            }
+            
+            QCheckBox{
+                border-image: url('''+ CHECKBOX_BORDER +''');
+                qproperty-focusPolicy: NoFocus;
+                spacing: 10px;
+                min-height: 38px; 
+                max-height: 38px;
+                min-width: 230px; 
+                max-width: 230px;
+            }
+            
+            QCheckBox::indicator:unchecked {
+                image: url(''' + CHECKBOX_UNCHECKED + ''');
+            }
+            
+            QCheckBox::indicator:checked {
+                image: url('''+ CHECKBOX_CHECKED +''');
+            }
+            
+            QScrollArea {
+                background: none;
+                margin-top : 0px;
+                min-width: 270px;
+                max-width: 270px; 
+                min-height: 243px; 
+                max-height: 243px;
+                border-image :url('''+ COPY_BORDER +''');
+            }
+            
+            QScrollArea#restoreScroll {
+                margin-top : 0px;
+                min-width: 270px;
+                max-width: 270px; 
+                min-height: 150px; 
+                max-height: 150px;
+                border-image :url('''+ COPY_BORDER +''');
+            }
+        
+            QListWidget {
+                border-style: inset;
+            }
+        
+            QInputDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+            }
+      
+            QScrollBar::sub-line, QScrollBar::add-line{
+                background:none;
+            } 
+            
+            QScrollBar::add-page, QScrollBar::sub-page{
+                background:none;
+            }
+           
+            QScrollBar:vertical { 
+                border-image: url(''' + SCROLL_BASE_V + '''); 
+                background:none;
+                margin: 0px;
+                min-width:18px;
+                max-width:18px;
+                border: 1px solid grey;
+            }
+            
+            QScrollBar:handle:vertical { 
+                border-image: url(''' + SCROLL_HANDLE_V +''');
+            }
+            
+            QScrollBar:horizontal{ 
+                border-image: url(''' + SCROLL_BASE_H + '''); 
+                background:none;
+                margin: 0px;
+                min-height:18px;
+                max-height:18px;
+                border: 1px solid grey;
+            }
+            
+            QScrollBar:handle:horizontal { 
+                border-image: url(''' + SCROLL_HANDLE_H +''');
+            }
+                        
+            QPushButton#buttonBrowse {
+                min-height:25px; 
+                min-width:25px; 
+                max-height:25px;
+                max-width:25px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BROWSE_BUTTON +''');
+            }
+            
+            QLineEdit {
+                border-image: url(''' + BACKUP_NAME_BORDER +''');
+                color: white;
+            }
+            
+            QLineEdit#backupNameField {
+                border-image: url(''' + BACKUP_NAME_BORDER +''');
+                color: white;
+                min-height:20px; 
+                min-width:171px; 
+                max-height:20px;
+                max-width:171px;
+            }
+            
+            QLineEdit#pathField {
+                border-image: url(''' + PATH_BORDER +''');
+                color: white;
+                min-height:22px; 
+                min-width:241px; 
+                max-height:22px;
+                max-width:241px;
+            }
+            
+            QLineEdit#ipField {
+                border-image: url(''' + PATH_BORDER +''');
+                color: white;
+                min-height:22px; 
+                min-width:215px; 
+                max-height:22px;
+                max-width:215px;
+            }
+            
+            QProgressBar#progressBarWizard {
+                min-height: 18px; 
+                min-width:  353px; 
+                max-height: 18px;
+                max-width:  353px;
+                border-image: url(''' + PROGRESS_BAR_BORDER +''');
+            }
+            
+            QProgressBar#progressBarWizard::chunk{
+                background-image:url(''' + PROGRESS_BAR_CHUNK +''');
+                max-height: 18px;
+                margin: 0px;
+            }
+            
+            QProgressBar#progressBarDialog {
+                min-height: 18px; 
+                min-width:  260px; 
+                max-height: 18px;
+                max-width:  260px;
+                border-image: url(''' + PROGRESS_BAR_BORDER +''');
+            }
+            
+            QProgressBar#progressBarDialog::chunk{
+                background-image:url(''' + PROGRESS_BAR_CHUNK_DIALOG +''');
+                max-height: 18px;
+                margin: 0px;
+            }
+            
+            QProgressDialog#progressDialog{
+                background-image:url(''' + DEFAULT_BG +''');
+            }
+            
+            QWidget#DeviceListPanel {
+                background-color: transparent;
+                min-height: 265px; 
+                min-width:  370px; 
+                max-height: 265px;
+                max-width:  370px;
+            }
+            
+            QTabWidget#tabBar::pane {
+                border-top: 10px solid transparent;
+                border-left: 40px solid transparent;
+                background-color: transparent;
+            }
+            
+            QTableView#ListView {
+                border-image: url(''' + TABLE_BORDER + ''');
+                background-color: transparent;
+                qproperty-focusPolicy: NoFocus;
+                color: white; 
+                alternate-background-color: #afafaf;
+                padding: 0px;
+                selection-background-color: #ced1cc;
+                selection-color: #1d544f;
+                show-decoration-selected: 0;
+                border: 2px;
+                min-height: 200px; 
+                max-height: 200px;
+                min-width:  350px; 
+                max-width:  350px;
+                
+            }
+            
+            QTableView#ipList {
+                border-image: url(''' + IP_LIST_BORDER + ''');
+                background-color: transparent;
+                qproperty-focusPolicy: NoFocus;
+                color: white; 
+                alternate-background-color: #afafaf;
+                padding: 0px;
+                selection-background-color: #ced1cc;
+                selection-color: #1d544f;
+                show-decoration-selected: 0;
+                border: 2px;
+                min-height: 120px; 
+                max-height: 120px;
+                min-width:  248px; 
+                max-width:  248px;
+                
+            }
+            
+            QScrollArea#listScrollArea {
+                
+            }
+            
+            QHeaderView#listHeader {
+                background-color: gray;
+                
+            }
+            
+            QHeaderView#listHeader::section {
+                border-top: 10px solid transparent;
+                border-color: transparent;
+                background-color: transparent;
+                color: Black; 
+                font: 10px;
+            }
+            
+            QTabBar#restoreTabs {
+                qproperty-focusPolicy: NoFocus;
+            }
+            
+            QTabBar#restoreTabs::tab {
+                 background-color: transparent;
+                 border: none;
+                 min-width: 215px;
+                 max-width: 215px;
+                 padding: 0px;
+                 
+            }
+             
+            QTabBar#restoreTabs::tab:selected {
+                color: white;
+            }
+
+            QTabBar#managerTabs {
+                qproperty-focusPolicy: NoFocus;
+            }
+            
+            QTabBar#managerTabs::tab {
+                 background-color: transparent;
+                 border: none;
+                 min-width: 215px;
+                 max-width: 215px;
+                 padding: 0px;
+                 
+            }
+             
+            QTabBar#managerTabs::tab:selected {
+                color: white;
+            }
+
+            QTabBar#managerTabs::tab:!selected {
+                color: black;
+            }
+            
+            QDialog#connectDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 289px;
+                max-height: 289px;
+                min-width:  275px; 
+            }
+            
+            QDialog#viewDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 190px;
+                max-height: 190px;
+                min-width:  300px; 
+                max-width:  300px;
+            }            
+            
+            QDialog#copyDialogToDevice{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 140px;
+                max-height: 140px;
+                min-width:  230px; 
+                max-width:  230px;
+            }
+            
+            QDialog#copyDialogFromDevice{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 110px;
+                max-height: 110px;
+                min-width:  260px; 
+                max-width:  260px;
+            }
+            
+            PcsRestoreDialog {
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 250px;
+                max-height: 250px;
+                min-width:  300px; 
+                max-width:  300px;
+            }
+            
+            QListWidget#viewList{
+                border-image: url(''' + VIEW_BORDER + ''');
+                qproperty-focusPolicy: NoFocus;
+                padding: 5px;
+            }
+            
+            PcsProgressDialog {
+                background-image: url('''+ DEFAULT_BG +''');
+                min-height: 150px;
+                max-height: 150px;
+                min-width:  295px; 
+                max-width:  295px;                
+            }
+                   
+        '''
+        
+
+      
+        
+BACKUP_BUTTON_STYLE = '''
+
+            QPushButton {
+                color : gray;
+                min-height:35px; 
+                min-width:79px; 
+                max-height:35px;
+                max-width:79px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BT_NEXT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' +BT_NEXT_CLICKED + ''');
+            }
+            
+        '''
+        
+DEFAULT_BUTTON_STYLE = '''
+
+            QPushButton {
+                min-height:33px; 
+                min-width:64px; 
+                max-height:33px;
+                max-width:64px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+            
+        '''
+SMALL_DEFAULT_BUTTON_STYLE = '''
+
+            QPushButton {
+                min-height:20px; 
+                min-width:34px; 
+                max-height:20px;
+                max-width: 34px;
+                border: none;
+                qproperty-icon: none;
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + SMALL_DEFAULT_BUTTON + ''')
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + SMALL_DEFAULT_BUTTON_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+
+            '''
+
+SMALL_ICON_NEW_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:125px; 
+                max-height:25px;
+                max-width: 125px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_NEW_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_NEW_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:125px; 
+                max-height:25px;
+                max-width: 125px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_NEW_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_MANAGER_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:138px; 
+                max-height:25px;
+                max-width: 138px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_MANAGER_BACKUP + ''')
+            }
+
+            '''
+
+SMALL_ICON_MANAGER_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:138px; 
+                max-height:25px;
+                max-width: 138px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_MANAGER_BACKUP + ''')
+            }
+
+            '''
+
+SMALL_ICON_RESTORE_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:130px; 
+                max-height:25px;
+                max-width: 130px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_RESTORE_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_RESTORE_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:130px; 
+                max-height:25px;
+                max-width: 130px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_RESTORE_BACKUP + ''')
+            }
+            '''
+MESSAGE_BOX_DEFAULT = '''
+            
+            QMessageBox {
+                background-image: url('''+ DEFAULT_BG +''');
+                color: black;
+            }
+        ''' + DEFAULT_BUTTON_STYLE
+
+MESSAGE_BOX_APP = '''
+            QMessageBox {
+                background-image: url('''+ DEFAULT_BG +''');
+                color: black;
+            }
+            QAbstractButton {
+                color : #636060;
+                background-image: url(''' + BUTTON_BG +''');
+                min-height:33px; 
+                min-width:91px;
+                max-height:32px;
+                max-width:93px;
+                border: none; 
+                qproperty-icon: none;
+                qproperty-focusPolicy: NoFocus; 
+            }
+            QAbstractButton::pressed {
+                background-image: url(''' + BUTTON_BG_CLICKED + ''');
+            }
+        '''
+    
\ No newline at end of file
diff --git a/src/style/__init__.py b/src/style/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/style/styleTabletSuite.py b/src/style/styleTabletSuite.py
new file mode 100644 (file)
index 0000000..493cdd5
--- /dev/null
@@ -0,0 +1,606 @@
+from ui.pcsuiutils import *
+
+STYLESHEET = ''' 
+            QPushButton {
+                min-height:33px; 
+                min-width:64px; 
+                max-height:33px;
+                max-width:64px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy: NoFocus;
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+            
+            QPushButton#tsButton {
+                color : #636060;
+                background-image: url(''' + BUTTON_BG +''');
+                min-height:33px; 
+                min-width:91px;
+                max-height:32px;
+                max-width:93px;
+                border: none; 
+                qproperty-focusPolicy : NoFocus;
+                qproperty-icon: none; 
+            }
+            
+            QPushButton#tsButton::pressed {
+                background-image: url(''' + BUTTON_BG_CLICKED + ''');
+            }
+            
+            QPushButton#smallButton {
+                color : gray;
+                border-image: url(''' + BUTTON_BG +''');
+                min-height:20px; 
+                min-width:34px;
+                max-height:20px;
+                max-width:34px;
+                border: none; 
+                qproperty-focusPolicy : NoFocus;
+                qproperty-icon: none; 
+                background:transparent;
+            }
+            
+            QPushButton#smallButton::pressed {
+                border-image: url(''' + BUTTON_BG_CLICKED + ''');
+                background:transparent;
+            }
+            
+            QMainWindow {
+                background-image: url(''' + BACKGROUND_IMAGE + ''');
+            }
+            
+            PcsBackup {
+                background-image: url('''+ BACKUP_BG +''')
+            }
+            
+            PcsRestoreBackupUi {
+                background-image: url('''+ RESTORE_BG +''')
+            }
+            
+            PcsBackupManagerUi{
+                background-image: url('''+ MANAGER_BG +''')
+            }
+            
+            QListWidget {
+                selection-background-color : transparent;
+            }
+            
+            QMenuBar::item {
+                background: transparent;
+            }
+            
+            QMenuBar {
+                background: transparent;
+            }
+            
+            QRadioButton{
+                qproperty-focusPolicy: NoFocus;
+                border-image: url('''+ CHECKBOX_BORDER +''');
+                min-height: 38px; 
+                max-height: 38px;
+            }
+            
+            QRadioButton::indicator:unchecked {
+                image: url(''' + CHECKBOX_UNCHECKED + ''');
+            }
+            
+            QRadioButton::indicator:checked {
+                image: url('''+ CHECKBOX_CHECKED +''');
+            }
+            
+            QCheckBox{
+                border-image: url('''+ CHECKBOX_BORDER +''');
+                qproperty-focusPolicy: NoFocus;
+                spacing: 10px;
+                min-height: 38px; 
+                max-height: 38px;
+                min-width: 230px; 
+                max-width: 230px;
+            }
+            
+            QCheckBox::indicator:unchecked {
+                image: url(''' + CHECKBOX_UNCHECKED + ''');
+            }
+            
+            QCheckBox::indicator:checked {
+                image: url('''+ CHECKBOX_CHECKED +''');
+            }
+            
+            QScrollArea {
+                background: none;
+                margin-top : 0px;
+                min-width: 270px;
+                max-width: 270px; 
+                min-height: 243px; 
+                max-height: 243px;
+                border-image :url('''+ COPY_BORDER +''');
+            }
+            
+            QScrollArea#restoreScroll {
+                margin-top : 0px;
+                min-width: 270px;
+                max-width: 270px; 
+                min-height: 150px; 
+                max-height: 150px;
+                border-image :url('''+ COPY_BORDER +''');
+            }
+        
+            QListWidget {
+                border-style: inset;
+            }
+        
+            QInputDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+            }
+      
+            QScrollBar::sub-line, QScrollBar::add-line{
+                background:none;
+            } 
+            
+            QScrollBar::add-page, QScrollBar::sub-page{
+                background:none;
+            }
+           
+            QScrollBar:vertical { 
+                border-image: url(''' + SCROLL_BASE_V + '''); 
+                background:none;
+                margin: 0px;
+                min-width:18px;
+                max-width:18px;
+                border: 1px solid grey;
+            }
+            
+            QScrollBar:handle:vertical { 
+                border-image: url(''' + SCROLL_HANDLE_V +''');
+            }
+            
+            QScrollBar:horizontal{ 
+                border-image: url(''' + SCROLL_BASE_H + '''); 
+                background:none;
+                margin: 0px;
+                min-height:18px;
+                max-height:18px;
+                border: 1px solid grey;
+            }
+            
+            QScrollBar:handle:horizontal { 
+                border-image: url(''' + SCROLL_HANDLE_H +''');
+            }
+                        
+            QPushButton#buttonBrowse {
+                min-height:25px; 
+                min-width:25px; 
+                max-height:25px;
+                max-width:25px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BROWSE_BUTTON +''');
+            }
+            
+            QLineEdit {
+                border-image: url(''' + BACKUP_NAME_BORDER +''');
+                color: white;
+            }
+            
+            QLineEdit#backupNameField {
+                border-image: url(''' + BACKUP_NAME_BORDER +''');
+                color: white;
+                min-height:20px; 
+                min-width:171px; 
+                max-height:20px;
+                max-width:171px;
+            }
+            
+            QLineEdit#pathField {
+                border-image: url(''' + PATH_BORDER +''');
+                color: white;
+                min-height:22px; 
+                min-width:241px; 
+                max-height:22px;
+                max-width:241px;
+            }
+            
+            QLineEdit#ipField {
+                border-image: url(''' + PATH_BORDER +''');
+                color: white;
+                min-height:22px; 
+                min-width:215px; 
+                max-height:22px;
+                max-width:215px;
+            }
+            
+            QProgressBar#progressBarWizard {
+                min-height: 18px; 
+                min-width:  353px; 
+                max-height: 18px;
+                max-width:  353px;
+                border-image: url(''' + PROGRESS_BAR_BORDER +''');
+            }
+            
+            QProgressBar#progressBarWizard::chunk{
+                background-image:url(''' + PROGRESS_BAR_CHUNK +''');
+                max-height: 18px;
+                margin: 0px;
+            }
+            
+            QProgressBar#progressBarDialog {
+                min-height: 18px; 
+                min-width:  260px; 
+                max-height: 18px;
+                max-width:  260px;
+                border-image: url(''' + PROGRESS_BAR_BORDER +''');
+            }
+            
+            QProgressBar#progressBarDialog::chunk{
+                background-image:url(''' + PROGRESS_BAR_CHUNK_DIALOG +''');
+                max-height: 18px;
+                margin: 0px;
+            }
+            
+            QProgressDialog#progressDialog{
+                background-image:url(''' + DEFAULT_BG +''');
+            }
+            
+            QWidget#DeviceListPanel {
+                background-color: transparent;
+                min-height: 265px; 
+                min-width:  370px; 
+                max-height: 265px;
+                max-width:  370px;
+            }
+            
+            QTabWidget#tabBar::pane {
+                border-top: 10px solid transparent;
+                border-left: 40px solid transparent;
+                background-color: transparent;
+            }
+            
+            QTableView#ListView {
+                border-image: url(''' + TABLE_BORDER + ''');
+                background-color: transparent;
+                qproperty-focusPolicy: NoFocus;
+                color: white; 
+                alternate-background-color: #afafaf;
+                padding: 0px;
+                selection-background-color: #ced1cc;
+                selection-color: #1d544f;
+                show-decoration-selected: 0;
+                border: 2px;
+                min-height: 200px; 
+                max-height: 200px;
+                min-width:  350px; 
+                max-width:  350px;
+                
+            }
+            
+            QTableView#ipList {
+                border-image: url(''' + IP_LIST_BORDER + ''');
+                background-color: transparent;
+                qproperty-focusPolicy: NoFocus;
+                color: white; 
+                alternate-background-color: #afafaf;
+                padding: 0px;
+                selection-background-color: #ced1cc;
+                selection-color: #1d544f;
+                show-decoration-selected: 0;
+                border: 2px;
+                min-height: 120px; 
+                max-height: 120px;
+                min-width:  248px; 
+                max-width:  248px;
+                
+            }
+            
+            QScrollArea#listScrollArea {
+                
+            }
+            
+            QHeaderView#listHeader {
+                background-color: gray;
+                
+            }
+            
+            QHeaderView#listHeader::section {
+                border-top: 10px solid transparent;
+                border-color: transparent;
+                background-color: transparent;
+                color: Black; 
+                font: 10px;
+            }
+            
+            QTabBar#restoreTabs {
+                qproperty-focusPolicy: NoFocus;
+            }
+            
+            QTabBar#restoreTabs::tab {
+                 background-color: transparent;
+                 border: none;
+                 min-width: 215px;
+                 max-width: 215px;
+                 padding: 0px;
+                 
+            }
+             
+            QTabBar#restoreTabs::tab:selected {
+                color: white;
+            }
+
+            QTabBar#managerTabs {
+                qproperty-focusPolicy: NoFocus;
+            }
+            
+            QTabBar#managerTabs::tab {
+                 background-color: transparent;
+                 border: none;
+                 min-width: 215px;
+                 max-width: 215px;
+                 padding: 0px;
+                 
+            }
+             
+            QTabBar#managerTabs::tab:selected {
+                color: white;
+            }
+
+            QTabBar#managerTabs::tab:!selected {
+                color: black;
+            }
+            
+            QDialog#connectDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 289px;
+                max-height: 289px;
+                min-width:  275px; 
+            }
+            
+            QDialog#viewDialog{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 190px;
+                max-height: 190px;
+                min-width:  300px; 
+                max-width:  300px;
+            }            
+            
+            QDialog#copyDialogToDevice{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 140px;
+                max-height: 140px;
+                min-width:  230px; 
+                max-width:  230px;
+            }
+            
+            QDialog#copyDialogFromDevice{
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 110px;
+                max-height: 110px;
+                min-width:  260px; 
+                max-width:  260px;
+            }
+            
+            PcsRestoreDialog {
+                background-image: url(''' + DEFAULT_BG + ''');
+                border: none;
+                min-height: 250px;
+                max-height: 250px;
+                min-width:  300px; 
+                max-width:  300px;
+            }
+            
+            QListWidget#viewList{
+                border-image: url(''' + VIEW_BORDER + ''');
+                qproperty-focusPolicy: NoFocus;
+                padding: 5px;
+            }
+            
+            PcsProgressDialog {
+                background-image: url('''+ DEFAULT_BG +''');
+                min-height: 150px;
+                max-height: 150px;
+                min-width:  295px; 
+                max-width:  295px;                
+            }
+                   
+        '''
+        
+
+      
+        
+BACKUP_BUTTON_STYLE = '''
+
+            QPushButton {
+                color : gray;
+                min-height:35px; 
+                min-width:79px; 
+                max-height:35px;
+                max-width:79px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BT_NEXT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' +BT_NEXT_CLICKED + ''');
+            }
+            
+        '''
+        
+DEFAULT_BUTTON_STYLE = '''
+
+            QPushButton {
+                min-height:33px; 
+                min-width:64px; 
+                max-height:33px;
+                max-width:64px;
+                border: none; 
+                qproperty-icon: none; 
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT +''');
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + BACKUP_BUTTON_DEFAULT_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+            
+        '''
+SMALL_DEFAULT_BUTTON_STYLE = '''
+
+            QPushButton {
+                min-height:20px; 
+                min-width:34px; 
+                max-height:20px;
+                max-width: 34px;
+                border: none;
+                qproperty-icon: none;
+                qproperty-focusPolicy : NoFocus;
+                background-image: url(''' + SMALL_DEFAULT_BUTTON + ''')
+            }
+            
+            QPushButton::pressed {
+                background-image: url(''' + SMALL_DEFAULT_BUTTON_CLICKED + ''');
+            }
+            
+            QPushButton::enabled {
+                color:black;
+            }
+
+            '''
+
+SMALL_ICON_NEW_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:125px; 
+                max-height:25px;
+                max-width: 125px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_NEW_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_NEW_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:125px; 
+                max-height:25px;
+                max-width: 125px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_NEW_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_MANAGER_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:138px; 
+                max-height:25px;
+                max-width: 138px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_MANAGER_BACKUP + ''')
+            }
+
+            '''
+
+SMALL_ICON_MANAGER_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:138px; 
+                max-height:25px;
+                max-width: 138px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_MANAGER_BACKUP + ''')
+            }
+
+            '''
+
+SMALL_ICON_RESTORE_BACKUP_STYLE = '''
+            QPushButton {
+                min-height:25px; 
+                min-width:130px; 
+                max-height:25px;
+                max-width: 130px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_RESTORE_BACKUP + ''')
+            }
+
+            '''
+            
+SMALL_ICON_RESTORE_BACKUP_STYLE_SELECTED = '''
+            QPushButton {
+                color: white;
+                min-height:25px; 
+                min-width:130px; 
+                max-height:25px;
+                max-width: 130px;
+                border: none;
+                qproperty-iconSize: 25px 25px;
+                qproperty-focusPolicy : NoFocus;
+                background: transparent;
+                qproperty-icon: url(''' + SMALL_ICON_RESTORE_BACKUP + ''')
+            }
+            '''
+MESSAGE_BOX_DEFAULT = '''
+            
+            QMessageBox {
+                background-image: url('''+ DEFAULT_BG +''');
+                color: black;
+            }
+        ''' + DEFAULT_BUTTON_STYLE
+
+MESSAGE_BOX_APP = '''
+            QMessageBox {
+                background-image: url('''+ DEFAULT_BG +''');
+                color: black;
+            }
+            QAbstractButton {
+                color : #636060;
+                background-image: url(''' + BUTTON_BG +''');
+                min-height:33px; 
+                min-width:91px;
+                max-height:32px;
+                max-width:93px;
+                border: none; 
+                qproperty-icon: none;
+                qproperty-focusPolicy: NoFocus; 
+            }
+            QAbstractButton::pressed {
+                background-image: url(''' + BUTTON_BG_CLICKED + ''');
+            }
+        '''
+    
\ No newline at end of file
diff --git a/src/tabletsuite.py b/src/tabletsuite.py
new file mode 100644 (file)
index 0000000..531c1e8
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+    
+import sys, os
+import optparse
+from PyQt4.QtGui import *
+
+parser = optparse.OptionParser(usage="%prog [options] [project-file]")
+parser.add_option("-l", "--local-dirs", action="store_true", dest="use_local_dirs",
+                help="Use files from the local directory tree")
+
+(options, args) = parser.parse_args()
+if options.use_local_dirs:
+    PATHS = {"IMAGE_PATH" : os.pardir + "/img/",
+             "BATTERY_PATH" : "./"}
+else:
+    PATHS = {"IMAGE_PATH" : "/usr/share/tabletsuite/",
+             "BATTERY_PATH" : "/usr/lib/python2.6/site-packages/src/"}
+
+for var, path in PATHS.iteritems():
+    os.environ.setdefault(var, path)
+
+
+from pcsuite.pcsuite import PCSuite
+
+app = QApplication(sys.argv)
+ps = PCSuite()
+ps.show()    
+        
+app.exec_()
diff --git a/src/ui/.svn/all-wcprops b/src/ui/.svn/all-wcprops
new file mode 100644 (file)
index 0000000..266eecc
--- /dev/null
@@ -0,0 +1,71 @@
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/pc-suite/!svn/ver/651/trunk/tabletsuite/src/ui
+END
+pcsdevicewidget.py
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/624/trunk/tabletsuite/src/ui/pcsdevicewidget.py
+END
+pcsmenu.py
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/pcsmenu.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/__init__.py
+END
+pcscustombuttons.py
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/pcscustombuttons.py
+END
+pcsbutton.py
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/pcsbutton.py
+END
+pcsdeviceinfoviewer.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/pcsdeviceinfoviewer.py
+END
+pcsuiutils.py
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/svn/pc-suite/!svn/ver/648/trunk/tabletsuite/src/ui/pcsuiutils.py
+END
+pcsapplicationlist.py
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/svn/pc-suite/!svn/ver/612/trunk/tabletsuite/src/ui/pcsapplicationlist.py
+END
+pcsapp.py
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/svn/pc-suite/!svn/ver/590/trunk/tabletsuite/src/ui/pcsapp.py
+END
+tsuigeneralmethods.py
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/svn/pc-suite/!svn/ver/616/trunk/tabletsuite/src/ui/tsuigeneralmethods.py
+END
+pcsdeviceviewer.py
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/pc-suite/!svn/ver/651/trunk/tabletsuite/src/ui/pcsdeviceviewer.py
+END
diff --git a/src/ui/.svn/dir-prop-base b/src/ui/.svn/dir-prop-base
new file mode 100644 (file)
index 0000000..3160658
--- /dev/null
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/src/ui/.svn/entries b/src/ui/.svn/entries
new file mode 100644 (file)
index 0000000..b193a34
--- /dev/null
@@ -0,0 +1,402 @@
+9
+
+dir
+653
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite/trunk/tabletsuite/src/ui
+http://gforge.embedded.ufcg.edu.br/svn/pc-suite
+
+
+
+2009-10-01T16:05:02.177628Z
+651
+nicholas
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+ccd57667-b161-0410-a082-fa92f2fb3e95
+\f
+pcsdevicewidget.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+84f28d53fce52d6be1ce09a14a0a1e82
+2009-09-14T19:20:21.821743Z
+624
+amaury
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3004
+\f
+pcsmenu.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+09b541ed1dd300a729ae68ea9f944498
+2009-08-04T18:37:56.490706Z
+510
+amaury
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4005
+\f
+__init__.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2009-04-02T19:30:47.227755Z
+61
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+pcscustombuttons.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+01c999f11e8e38ac29c05fbe9d8a46d9
+2009-08-05T16:55:19.618241Z
+511
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1052
+\f
+pcsbutton.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+8ceb0be1042061439ab2e971a5439fb5
+2009-08-06T18:40:51.041049Z
+523
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+285
+\f
+pcsdeviceinfoviewer.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+ed5d20e8ba52cfb30cedb4b5697f6aa9
+2009-08-18T14:29:37.615498Z
+566
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7187
+\f
+pcsuiutils.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d92be1dd2821ca8bc135e2666c8be881
+2009-09-28T11:36:33.963218Z
+648
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4522
+\f
+pcsapplicationlist.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+d0164df0e34d095d7e6f7d9203a06cf9
+2009-09-10T20:35:15.948790Z
+612
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1583
+\f
+pcsapp.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+80eef7e5d2a325b436d9e9d71d16aee0
+2009-06-30T10:24:42.195284Z
+364
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+390
+\f
+tsuigeneralmethods.py
+file
+
+
+
+
+2009-09-29T18:30:22.000000Z
+4119124fdd8d0ae371ed717af9785a2d
+2009-09-14T12:31:28.560392Z
+616
+pauloouriques
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1062
+\f
+pcsdeviceviewer.py
+file
+
+
+
+
+2009-10-08T18:25:37.000000Z
+20b23b9e27952b9a6598f9df06993c1d
+2009-10-01T16:05:02.177628Z
+651
+nicholas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11580
+\f
diff --git a/src/ui/.svn/format b/src/ui/.svn/format
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/src/ui/.svn/text-base/__init__.py.svn-base b/src/ui/.svn/text-base/__init__.py.svn-base
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/ui/.svn/text-base/pcsapp.py.svn-base b/src/ui/.svn/text-base/pcsapp.py.svn-base
new file mode 100644 (file)
index 0000000..f901392
--- /dev/null
@@ -0,0 +1,16 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+
+class PcsApp(QDialog):
+    
+    ''' Class that represents an application from Pc Suite'''
+    
+    def __init__(self, parent=None):
+        super(PcsApp, self).__init__(parent)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+    
\ No newline at end of file
diff --git a/src/ui/.svn/text-base/pcsapplicationlist.py.svn-base b/src/ui/.svn/text-base/pcsapplicationlist.py.svn-base
new file mode 100644 (file)
index 0000000..bfc3b54
--- /dev/null
@@ -0,0 +1,48 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from backup.pcsbackup import *
+from pcsuiutils import *
+from tsuigeneralmethods import *
+
+class PcsApplicationList(QFrame):
+    
+    ''' Class that creates buttons on the main frame. Each button 
+        represents a Pc Suite Application.'''
+    
+    def __init__(self, deviceManager, parent=None):
+        super(PcsApplicationList, self).__init__(parent)
+        self.layout = QHBoxLayout()
+        self.setFixedSize(480,200)
+        self.createList()
+        self.setLayout(self.layout)  
+        self.deviceManager = deviceManager
+
+    def createList(self):       
+        self.listWidget = QListWidget()
+        self.listWidget.setViewMode(QListView.IconMode)
+        self.listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
+        
+        # Creates Backup application applet
+        backupButton = QListWidgetItem()
+        backupButton.setIcon(QIcon(BACKUP_IMAGE))
+        backupButton.setText("Backup")
+        backupButton.setToolTip("Backup Application")
+        self.listWidget.addItem(backupButton)
+                
+        self.connect(self.listWidget, 
+                     SIGNAL("itemDoubleClicked(QListWidgetItem *)"), 
+                     self.openBackupApplication)
+
+        self.layout.addWidget(self.listWidget)
+         
+    def openBackupApplication(self):
+        deviceInfo = self.deviceManager.getCurrentDevice()
+        backup = PcsBackup(deviceInfo, self)
+        centralize(backup)
+        backup.show()
+        
+        
diff --git a/src/ui/.svn/text-base/pcsbutton.py.svn-base b/src/ui/.svn/text-base/pcsbutton.py.svn-base
new file mode 100644 (file)
index 0000000..8175c81
--- /dev/null
@@ -0,0 +1,13 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PcsButton(QPushButton):
+    def __init__(self, name = "", parent = None):
+        QPushButton.__init__(self, parent)
+        self.setText(name)
+       
+
+
diff --git a/src/ui/.svn/text-base/pcscustombuttons.py.svn-base b/src/ui/.svn/text-base/pcscustombuttons.py.svn-base
new file mode 100644 (file)
index 0000000..cdbe15f
--- /dev/null
@@ -0,0 +1,35 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PcsCustomButton(QLabel):
+    def __init__(self, image, pressedImage, text = "", parent = None):
+        super(QLabel, self).__init__(parent)
+        
+        self.panel = QLabel()
+        self.layout = QHBoxLayout()
+        self.text = QLabel(text)
+        self.defaultPixmap = QPixmap(image)
+        self.pressedPixmap = QPixmap(pressedImage)
+        self.panel.setPixmap(self.defaultPixmap)
+        self.panel.setGeometry(self.defaultPixmap.rect())
+        self.layout.addWidget(self.panel)
+        if(text <> ""):
+            self.layout.addWidget(self.text)
+        self.setLayout(self.layout)
+        
+        
+    def mouseReleaseEvent(self,event):
+        self.panel.setPixmap(self.defaultPixmap)
+        self.emit(SIGNAL("clicked()"))
+        
+    def mousePressEvent(self, event):
+        self.panel.setPixmap(self.pressedPixmap)
+        
+    def setTextVisible(self, flag):
+        if flag:
+            pass 
+
+
diff --git a/src/ui/.svn/text-base/pcsdeviceinfoviewer.py.svn-base b/src/ui/.svn/text-base/pcsdeviceinfoviewer.py.svn-base
new file mode 100644 (file)
index 0000000..4a5959b
--- /dev/null
@@ -0,0 +1,189 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from time import sleep
+import threading
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from pcsuiutils import *
+from ui.pcscustombuttons import PcsCustomButton as customButton
+
+class PcsDeviceInfoViewer(QHBoxLayout):
+    
+    ''' Class that displays how the device is connected with the PC'''
+    
+    def __init__(self, pcSuite):
+        super(PcsDeviceInfoViewer,self).__init__()
+        
+        self.label = QLabel("")
+        self.label.setText("<font style='color: gray'; size=2>Maemo Release</font>")
+        self.label.setFixedSize(90,20)
+        
+        self.pcSuite = pcSuite
+        self.l2 = QLabel()
+        pixmap = QPixmap(SSH_IMAGE)
+        self.l2.setPixmap(pixmap)  
+        
+        spacer = QSpacerItem(60, 60)
+        maemoLayout = QVBoxLayout()
+        maemoLayout.setMargin(0)
+        maemoLayout.addItem(spacer)
+        maemoLayout.addWidget(self.label)
+        maemoLayout.addWidget(self.l2)
+        maemoLayout.addItem(spacer)
+        
+        spacer2 = QSpacerItem(0, 32)
+        spacer3 = QSpacerItem(0, 37.6)
+        self.statusLayout = QGridLayout()
+        self.statusLayout.setColumnStretch(1, 1)
+        self.statusLayout.addItem(spacer2, 0, 0)
+        self._createStatusWidget(self.statusLayout)
+        self.statusLayout.addItem(spacer3, 4, 0)
+        
+        self.setMargin(0)
+        self.addLayout(maemoLayout)
+        spacer4 = QSpacerItem(10, 10)
+        self.addItem(spacer4)
+        self.addLayout(self.statusLayout)
+        
+        self.modelLabel = QLabel("Model", self.pcSuite)
+        self.modelLabel.setText("<font style='color: white'; size=2>Model</font>")
+        self.modelLabel.setGeometry(QRect(330, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+       
+        self.arrowLabel = QLabel(self.pcSuite)
+        self.arrowLabel.setPixmap(QPixmap(WHITE_ARROW))
+        self.arrowLabel.setGeometry(QRect(365, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+        
+        self.deviceNameLabel = QLabel("None", self.pcSuite)
+        self.deviceNameLabel.setText("<font style='color: white'; size=2>None</font>")
+        self.deviceNameLabel.setGeometry(QRect(380, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+        
+        
+        self.deviceNameLabel2 = QLabel(self.pcSuite)
+        self.deviceNameLabel2.setText("<font style='color: #333333'; size=2>None</font>")
+        self.deviceNameLabel2.setGeometry(QRect(10, 39, 50, 15))
+       
+        self.arrowLabel = QLabel(self.pcSuite)
+        self.arrowLabel.setPixmap(QPixmap(BLACK_ARROW))
+        self.arrowLabel.setGeometry(QRect(40, 39, 15, 15))
+        
+        self.actionLabel = QLabel(self.pcSuite)
+        self.actionLabel.setText("<font style='color: white'; size=2>Select option</font>")
+        self.actionLabel.setGeometry(QRect(55, 36, 100, 20))
+                 
+        self.chargingThread = None;
+           
+    def setDeviceInfo(self, deviceInfo):
+        self.deviceInfo = deviceInfo
+        self.label.setText("<font style='color: grey'; size=2>" + deviceInfo.system +"</font>" )
+        
+        
+        self.label.repaint()
+        self.deviceNameLabel.setText("<font style='color: white'; size=2>" 
+                                     + deviceInfo.name + "</font>")
+        self.deviceNameLabel2.setText("<font style='color: #333333'; size=2>" 
+                                     + deviceInfo.name + "</font>")
+        if(self.chargingThread != None):
+            if self.deviceInfo.charging:
+                self._batteryBar.setToolTip("Charging...")
+            else:
+                self.emit(SIGNAL("stopThread"))
+                self._batteryBar.setToolTip("Battery: %d%%" % (deviceInfo.battery))
+                self._batteryBar.setValue(deviceInfo.battery)
+        else:
+            if self.deviceInfo.charging:
+                self._batteryBar.setToolTip("Charging...")
+                self.chargingThread = ChargingThread(self)
+                self.connect(self.chargingThread, SIGNAL("charging"), self._charging)
+                self.chargingThread.start()
+            else:
+                self._batteryBar.setValue(deviceInfo.battery)
+                self._batteryBar.setToolTip("Battery: %d%%" % (deviceInfo.battery))
+       
+
+        memory = deviceInfo.storage
+        tip = ""
+        total_m1 = 0
+        total_m2 = 0
+        current_m1 = 0
+        current_m2 = 0
+        if memory[1] != -1:
+            value_m1 = float(memory[1][1]) * 100 / float(memory[1][0])
+            current_m1 = float(memory[1][1])/1024
+            total_m1 = float(memory[1][0])/1024
+            tip += "MMC1: %.1fMB / %.1fMB - %d%%\n" % (current_m1, total_m1, value_m1)
+        
+        if memory[2] != -1:
+            value_m2 = float(memory[2][1]) * 100 / float(memory[2][0])
+            current_m2 = float(memory[2][1])/1024
+            total_m2 = float(memory[2][0])/1024
+            tip += "MMC2: %.1fMB / %.1fMB - %d%%\n" % (current_m2, total_m2, value_m2)
+
+        if total_m1 == 0 and total_m2 == 0:
+            tip = "No external memory found."
+        else:
+            current = current_m1 + current_m2
+            total = total_m1 + total_m2
+            value = (current_m1 + current_m2) * 100 / total
+            tip += "Total: %.1fMB / %.1fMB - %d%%" % (current, total, value)
+            self._memoryBar.setValue(value)
+        self._memoryBar.setToolTip(tip)
+
+        current = float(memory[0][1])/1024 
+        total = float(memory[0][0])/1024
+        value = current * 100 / total
+        self._deviceBar.setValue(value)
+        self._deviceBar.setToolTip("Device Memory: %.1fMB / %.1fMB - %d%%" % (current, total, value))
+        
+    def _createStatusWidget(self, layout):
+        self._batteryBar = self._newProgressBar(layout, 1, BATTERY_IMAGE)
+        self._deviceBar = self._newProgressBar(layout, 2, DEVICE_MEMORY_IMAGE)
+        self._memoryBar = self._newProgressBar(layout, 3, MEMORY_IMAGE)
+                    
+    def _newProgressBar(self, layout, line, image):
+        bar = QProgressBar()
+        bar.setMaximum(100)
+        bar.setMinimum(0)
+        bar.setFixedSize(150,12.9)
+        bar.setTextVisible(False)
+        layout.addWidget(bar, line, 0 )
+
+        label = QLabel()
+        label.setFixedSize(30,15)
+        pixmap = QPixmap(image)
+        label.setPixmap(pixmap)
+        layout.addWidget(label, line, 1)
+        
+        return bar
+    
+    def _charging(self):
+        currentValue = self._batteryBar.value()
+        if(currentValue == 100):
+            self._batteryBar.setValue(0)
+        self._batteryBar.setValue(currentValue + 1)
+        self._batteryBar.repaint()
+        
+        
+class ChargingThread(QThread):
+    def __init__(self, infoViewer):
+        QThread.__init__(self)
+        self.flag = True
+        self.connect(infoViewer, SIGNAL("stopThread"), self.stopThread)
+        self.connect(infoViewer, SIGNAL("destroyed()"), self.stopThread)
+        
+    def stopThread(self):
+        self.flag = False
+        
+    def run(self):
+        while(self.flag):
+            try:
+                sleep(0.02)
+                self.emit(SIGNAL("charging"))
+            except:
+                self.stopThread()
+            
+        
+    
\ No newline at end of file
diff --git a/src/ui/.svn/text-base/pcsdeviceviewer.py.svn-base b/src/ui/.svn/text-base/pcsdeviceviewer.py.svn-base
new file mode 100644 (file)
index 0000000..17495a0
--- /dev/null
@@ -0,0 +1,292 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from functools import partial
+from time import sleep
+
+from pcsdeviceinfoviewer import PcsDeviceInfoViewer
+from pcsdevicewidget import PcsDeviceWidget
+from pcsuiutils import *
+from tsuigeneralmethods import *
+from pcsutils import *
+
+from style.styleTabletSuite import *
+from backup.pcswindowmanager import *
+
+class PcsDeviceViewer(QFrame):
+
+    '''Class that displays the devices which are connected to the PC'''
+
+    _ip = "None"
+    CONNECTION_ERROR_MESSAGE = "Could not connect to device with the given IP " + \
+                    "address.\nCheck if device is turned on and is properly " + \
+                    "connected to network"
+    
+    def __init__(self, deviceManager, pcSuite):
+        super(PcsDeviceViewer, self).__init__()
+        self.deviceManager = deviceManager
+        self.deviceManager.loadDevices()
+#        self.pcSuite = pcSuite
+        self.setFixedSize(WINDOW_WIDTH, 150)
+        self.deviceWidget = PcsDeviceWidget(0)
+
+        # Create device connection type
+        self.deviceInfoViewer = PcsDeviceInfoViewer(pcSuite)
+
+        self.mainLayout = QHBoxLayout()
+        self.mainLayout.setMargin(0)
+
+        spacer = QSpacerItem(15, 15)
+        self.mainLayout.addItem(spacer)
+        self.mainLayout.addWidget(self.deviceWidget)
+        self.mainLayout.addItem(QSpacerItem(20,20))
+        self.mainLayout.addLayout(self.deviceInfoViewer)
+        self.mainLayout.addItem(spacer)
+        self.setLayout(self.mainLayout)
+        
+        self.connectDialog = None
+        
+    def checkIp(self, ip):
+        list = ip.split(".")
+        if len(list) != 4:
+            return False
+        for sublist in list:
+            if len(sublist) < 1 or len(sublist) > 3:
+                return False
+            for element in sublist:
+                if not str(element).isdigit():
+                    return False
+        return True  
+    
+    def showConnectDialog(self):
+        if(self.connectDialog == None):
+            self.connectDialog = QDialog(self, Qt.FramelessWindowHint)
+            self.connectDialog.setObjectName("connectDialog")
+            self.connectDialog.setWindowIcon(QIcon(TABLET_SUITE_LOGO))
+            self.connectDialog.setWindowTitle("Device Selection")
+            connectDialogLayout = QVBoxLayout()
+            
+            hLayout = QHBoxLayout()
+            addButton = QPushButton("Add")
+            addButton.setObjectName("smallButton")
+            self.connect(addButton, SIGNAL("clicked()"), self.addIp)
+            
+            self.ipField = QLineEdit()
+            self.ipField.setText("IP Number")
+            self.ipField.setObjectName("ipField")
+            hLayout.addWidget(self.ipField)
+            hLayout.addWidget(addButton)
+            
+            buttonLayout = QHBoxLayout()
+            self.connectButton = QPushButton("Connect")
+            self.connectButton.setObjectName("tsButton")
+            self.connect(self.connectButton, SIGNAL("clicked()"), self._connect)
+            
+            self.deleteButton = QPushButton("Delete")
+            self.deleteButton.setObjectName("tsButton")
+            self.connect(self.deleteButton, SIGNAL("clicked()"), self._deleteSelectedIp)
+            
+            cancelButton = QPushButton("Cancel")
+            cancelButton.setObjectName("tsButton")
+            setVisible = partial(self.connectDialog.setVisible, False)
+            self.connect(cancelButton, SIGNAL("clicked()"), setVisible)
+            
+            buttonLayout.addWidget(self.connectButton)
+            buttonLayout.addWidget(self.deleteButton)
+            buttonLayout.addWidget(cancelButton)
+            
+            vLayout = QVBoxLayout()
+            vLayout.setMargin(15)
+            vLayout.addWidget(QLabel("Select the device IP"))
+            vLayout.addLayout(hLayout)
+            vLayout.addWidget(self._createIpList())
+            connectDialogLayout.addLayout(vLayout)
+            connectDialogLayout.addLayout(buttonLayout)
+            self.connectDialog.setLayout(connectDialogLayout)
+            self._updateIpList()
+            self.connectDialog.exec_()
+            
+        else:
+            self._updateIpList()
+            self.connectDialog.setVisible(True)
+    
+    def _connect(self):
+        self._ip = self.getSelectedIp()
+        if not create_route(self._ip):
+            showMessageBox(self.CONNECTION_ERROR_MESSAGE,
+                              "Error while connecting to device")
+            return False
+        if not verify_exist_keys(self._ip):
+            dialog = QMessageBox()
+            dialog.setText( "Wrong Key, It seems that the device key " + \
+                            "changed. Do you want to exchange keys again?")
+            dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+            dialog.setWindowFlags(Qt.FramelessWindowHint)
+            dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
+            ret = dialog.exec_()
+            if ret == QMessageBox.Yes:
+                if not self.showPasswdDialog():
+                    return False
+            else:
+                return False
+        self._runAddDevice()
+
+    def _createIpList(self):
+        self.ipList = QTableView(self)
+        self.ipList.setObjectName("ipList")
+        self.ipList.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+        self.ipList.setAlternatingRowColors(True)
+        self.ipList.setShowGrid(False)
+        self.ipList.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.model = QStandardItemModel()
+        self.ipList.setModel(self.model)
+        self._updateButtonsState()
+        self.connect(self.ipList.selectionModel(), 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
+                     self._updateButtonsState)
+        
+        hHeader = QHeaderView(Qt.Horizontal)
+        hHeader.setVisible(False)
+        hHeader.setResizeMode(QHeaderView.ResizeToContents)
+        hHeader.setMinimumSectionSize(225)
+        self.ipList.setHorizontalHeader(hHeader)  
+        
+        vHeader = QHeaderView(Qt.Vertical)
+        vHeader.setVisible(False)
+        self.ipList.setVerticalHeader(vHeader)
+        
+        return self.ipList 
+    
+    def _deleteSelectedIp(self):
+        dialog = QMessageBox()
+        dialog.setText("Remove selected ip?")
+        dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+        dialog.setWindowFlags(Qt.FramelessWindowHint)
+        dialog.setStyleSheet(MESSAGE_BOX_APP)
+        ret = dialog.exec_()
+        if ret == QMessageBox.Yes:
+            selectionModel = self.ipList.selectionModel()
+            indexList = selectionModel.selectedRows()
+            for index in indexList:
+                if index.isValid():
+                    try:
+                        ipAdress = self.model.itemData(index)[0].toString()
+                        self.deviceManager.removeDevice(ipAdress)
+                    except:
+                        pass
+                    finally:
+                        self.model.removeRow(index.row())
+        
+    def getSelectedIp(self):
+        selectionModel = self.ipList.selectionModel()
+        indexList = selectionModel.selectedRows()
+        
+        for index in indexList:
+            if index.isValid():
+                data = self.model.itemData(index)
+                return data[0].toString()
+    
+    def showInvalidIpDialog(self):
+        showMessageBox("Invalid ip adress", "Invalid ip")
+    
+    def addIp(self):
+        ip = self.ipField.text()
+             
+        if self.checkIp(ip):
+            for i in range(self.model.rowCount()):
+                if(self.model.item(i).text() == ip):
+                    self.ipField.setText("IP Number")
+                    return
+            item = QStandardItem(ip)
+            self.model.appendRow([item])
+            self.ipField.setText("IP Number")
+        else:
+            self.showInvalidIpDialog()
+
+    def showPasswdDialog(self):        
+        (passwd, ok) = QInputDialog.getText(self, "Device Selection",
+                                             "Root Password:",
+                                              QLineEdit.Password,
+                                              QString(), 
+                                              Qt.FramelessWindowHint)
+        if ok and not passwd.isEmpty():
+            self._passwd = passwd
+            if not keyExchange(self._ip, self._passwd):
+                errorMessage = "Could not connect to device with the given IP " + \
+                    "Could not exchange keys"
+                showMessageBox(errorMessage, "Error while connecting to device")
+                return False
+            return True
+    
+    def _updateButtonsState(self):
+        selectionModel = self.ipList.selectionModel()
+        indexList = selectionModel.selectedRows()
+        if len(indexList) > 1 or len(indexList) <= 0:
+            self.connectButton.setDisabled(True)
+            self.deleteButton.setDisabled(True)
+        else:
+            self.connectButton.setEnabled(True)
+            self.deleteButton.setEnabled(True)
+    
+    def _createWindowManager(self, deviceInf):
+         if deviceInf != None:
+                PcsWindowManager(deviceInf, self)
+    
+    def _runAddDevice(self):
+        self.connectingThread = connectingThread(self.deviceManager, self._ip)
+        self.connect(self.connectingThread, SIGNAL("connectException"), self._connectException)
+        self.connect(self.connectingThread, SIGNAL("createWindowManager"), self._createWindowManager)
+        self.connectingThread.start()
+        
+        self.connectionProgress()
+        self.connect(self.connectingThread, SIGNAL("connectionDone"), self.updateDeviceInformation)
+                
+    def updateDeviceInformation(self, deviceInfo):
+        self._progressDialog.cancel()
+        self.deviceInfo = deviceInfo
+        self.deviceManager.setCurrentDevice(self._ip)
+        if self.deviceInfo:
+            self.deviceManager.loadDevices()
+            self.deviceWidget.setDeviceInfo(self.deviceInfo)
+            self.deviceInfoViewer.setDeviceInfo(self.deviceInfo)
+        else:
+            showMessageBox("An error occurred while connect.", "Connection error")
+    
+    def _updateIpList(self):
+        self.model.clear()
+        devices = self.deviceManager.getDevices()
+        for device in devices:
+            self.model.appendRow(QStandardItem(str(device)))
+    
+    def connectionProgress(self):
+        self.connectDialog.setVisible(False)
+        self._progressDialog = QProgressDialog("Connecting...", 
+                                               QString(), 0, -1, self,
+                                               Qt.FramelessWindowHint)
+        self._progressDialog.setObjectName("progressDialog")
+        self._progressDialog.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self._progressDialog.setValue(0)
+        self._progressDialog.show()
+        
+    def _connectException(self):
+        showMessageBox("", "Error while connect to device")
+
+
+class connectingThread(QThread):
+    def __init__(self, deviceManager, deviceIp):
+        QThread.__init__(self)
+        self.deviceManager = deviceManager
+        self.deviceIp = deviceIp
+    
+    def run(self):
+        try:
+            deviceInf = self.deviceManager._addDevice(self.deviceIp)
+            self.emit(SIGNAL("createWindowManager"), deviceInf)
+            self.emit(SIGNAL("connectionDone"), deviceInf)
+        except:
+            self.emit(SIGNAL("connectException"))
+            self.emit(SIGNAL("connectionDone"), None)
\ No newline at end of file
diff --git a/src/ui/.svn/text-base/pcsdevicewidget.py.svn-base b/src/ui/.svn/text-base/pcsdevicewidget.py.svn-base
new file mode 100644 (file)
index 0000000..927316b
--- /dev/null
@@ -0,0 +1,81 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+import sys
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from pcsuiutils import *
+from pcsdeviceinfo import *
+
+class PcsDeviceWidget(QFrame):
+    
+    def __init__(self, size):
+        super(PcsDeviceWidget, self).__init__()
+        self.layout = QGridLayout()
+        self.layout.setMargin(0)
+        self.gridLayout = QGridLayout()
+        self.hasDeviceName = False
+        self.size = size
+        
+        self.deviceLabel = QLabel()
+        if size == 1:
+            img = DEVICE_DISCONNECTED_BACKUP
+        else:
+            img = DEVICE_DISCONNECTED
+        self.deviceLabel.setPixmap(QPixmap(img))
+        self.gridLayout.addWidget(self.deviceLabel, 0, 0, Qt.AlignCenter)
+        
+        self.layout.addLayout(self.gridLayout, 0, 0, Qt.AlignCenter)
+        self.setLayout(self.layout)
+
+    def addBorder(self):
+        devices = [(0, None, (None, None)),
+                   (1, DEVICE_BACKUP_BORDER, (208, 205)), 
+                   (2, DEVICE_CHECKBOX_BORDER, (152, 154)), 
+                   (3, DEVICE_FILE_BORDER, (112, 125))]
+        
+        name = devices[self.size][1]
+        self.borderLabel = QLabel()
+        self.borderLabel.setFixedSize(devices[self.size][2][0], devices[self.size][2][1])
+        self.borderLabel.setPixmap(QPixmap(name))
+        self.layout.addWidget(self.borderLabel, 0, 0, Qt.AlignCenter)
+        
+    def addDeviceName(self):
+        devices = [(0, None, (None, None)),
+                   (1, DEVICE_NAME_BORDER_BACKUP, (174, 23)), 
+                   (2, DEVICE_NAME_BORDER_CHECKBOX, (100, 23)), 
+                   (3, DEVICE_NAME_BORDER_FILE, (91, 23))]
+        
+        name = devices[self.size][1]
+        self.hasDeviceName = True
+        self.nameLayout = QGridLayout()
+        self.nameLabel = QLabel("Connect a device ")
+        nameBorderLabel = QLabel()
+        nameBorderLabel.setFixedSize(devices[self.size][2][0], devices[self.size][2][1])
+        nameBorderLabel.setPixmap(QPixmap(name))
+        self.nameLayout.addWidget(self.nameLabel, 0, 0, Qt.AlignCenter)
+        self.nameLayout.addWidget(nameBorderLabel, 0, 0, Qt.AlignCenter)
+        
+        self.gridLayout.addLayout(self.nameLayout, 1, 0, Qt.AlignCenter)
+    
+    def setImage(self, path):
+        self.deviceLabel.setPixmap(QPixmap(path))
+     
+    def setDeviceInfo(self, deviceInfo):
+        devices = [(0, N800_FILE, N810_FILE),
+                   (1, N800_BACKUP, N810_BACKUP),
+                   (2, N800, N810),
+                   (3, N800_FILE, N810_FILE)]
+        if(deviceInfo != None):
+            if deviceInfo.name == "N800":
+                name = devices[self.size][1]
+            elif deviceInfo.name == "N810":
+                name = devices[self.size][2]
+            self.deviceLabel.setPixmap(QPixmap(name))
+            self.deviceLabel.repaint()
+            if self.hasDeviceName:
+                self.nameLabel.setText(deviceInfo.name)
+                
+
diff --git a/src/ui/.svn/text-base/pcsmenu.py.svn-base b/src/ui/.svn/text-base/pcsmenu.py.svn-base
new file mode 100644 (file)
index 0000000..fcc7809
--- /dev/null
@@ -0,0 +1,98 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from backup.pcsbackup import *
+from pcsuiutils import *
+
+class PcsMenu(QMenuBar):
+
+    ''' Class that creates a menu bar for Pc Suite '''
+
+    def __init__(self, device_manager, parent = None):
+        super(PcsMenu,self).__init__(parent)
+        self.deviceManager = device_manager
+        self.create_menu_file()
+        #self.create_menu_web()
+        #self.create_menu_settings()
+        #self.create_menu_help()
+    
+    def create_menu_file(self):
+        
+            self.menu_file = QMenu("File")
+            
+            menu_list = [("Backup", self.show_backup_dialog,
+                          BACKUP_IMAGE)]
+#                         ("Synchronize", self.pass_func, ""),
+#                         ("Connect to Web", self.pass_func, ""),
+#                         ("Contacts", self.pass_func, ""),
+#                         ("Messages", self.pass_func, ""),
+#                         ("Calendar", self.pass_func, ""),
+#                         ("File manager", self.pass_func, ""),
+#                         ("Tranfer music", self.pass_func, ""),
+#                         ("Store images", self.pass_func, ""),
+#                         ("Video Transfers", self.pass_func, ""),
+#                         ("Install Applications", self.pass_func, ""),
+#                         ("Update Phone's Software", self.pass_func,""),
+#                         ("Download maps", self.pass_func, ""),
+#                         ("Quit", self.pass_func, image._nokia_icon)]
+            
+            for tuple in menu_list:
+                name = tuple[0]
+                callback = tuple[1]
+                icon = tuple[2]
+                        
+                action = QAction(name, self.menu_file)
+                self.menu_file.addAction(action)
+                self.connect(action, SIGNAL("triggered()"), callback)
+                action.setIcon(QIcon(icon))
+            
+            self.addMenu(self.menu_file)
+            
+    def create_menu_web(self):
+        self.menu_web = QMenu("Web")
+        
+        self.menu_web_pc_suite = QMenu("PC Suite at web")
+        self.menu_web.addMenu(self.menu_web_pc_suite)        
+        self.pc_suite_demonstration = QAction("PC Suite demonstration",
+                                              self.menu_web)
+        self.menu_web.addAction(self.pc_suite_demonstration)
+        
+        self.menu_web.addSeparator()
+        
+        self.registration_action = QAction("Registration", self.menu_web)
+        self.menu_web.addAction(self.registration_action)
+        self.browse_updates_action = QAction("Browse updates and complements",
+                                             self.menu_web)
+        self.menu_web.addAction(self.browse_updates_action)
+        
+        self.addMenu(self.menu_web)
+    
+    def create_menu_settings(self):
+        self.menu_settings = QMenu("Options")
+        
+        self.settings_action = QAction("Settings...", self.menu_settings)
+        self.menu_settings.addAction(self.settings_action)
+        self.manage_connections_action = QAction("Manage Connections",
+                                                 self.menu_settings)
+        self.menu_settings.addAction(self.manage_connections_action)
+        self.add_phones_action = QAction("Add more phones",
+                                         self.menu_settings)
+        self.menu_settings.addAction(self.add_phones_action)
+        self.rename_phone_action = QAction("Rename Phone", self.menu_settings)
+        self.menu_settings.addAction(self.rename_phone_action)
+        
+        self.addMenu(self.menu_settings)
+    
+    def create_menu_help(self):
+        self.menu_help = QMenu("?")
+        self.addMenu(self.menu_help)
+        
+    def show_backup_dialog(self):
+        deviceInfo = self.deviceManager.getCurrentDevice()
+        backup = PcsBackup(deviceInfo, self)
+        centralize(backup)
+        backup.show()
+        
diff --git a/src/ui/.svn/text-base/pcsuiutils.py.svn-base b/src/ui/.svn/text-base/pcsuiutils.py.svn-base
new file mode 100644 (file)
index 0000000..db97929
--- /dev/null
@@ -0,0 +1,97 @@
+"""Module contaning most used general functions"""
+
+import os
+
+from PyQt4 import QtGui
+
+APPLICATION_NAME = "TabletSuite"
+
+IMG_PATH = os.environ['IMAGE_PATH']
+
+BACKUP_IMAGE = IMG_PATH + "backup.png"
+TABLET_SUITE_LOGO = IMG_PATH + "tabletSuite_logo.png"
+SSH_IMAGE = IMG_PATH + "ssh.png"
+BATTERY_IMAGE = IMG_PATH + "battery_bar.png"
+CHARGING_IMAGE = IMG_PATH + "battery_bar_charging.png"
+MEMORY_IMAGE = IMG_PATH + "memory_bar.png"
+DEVICE_MEMORY_IMAGE = IMG_PATH + "device_memory.png"
+BACKGROUND_IMAGE = IMG_PATH + "bg_geral0.png"
+N800, N810 = IMG_PATH + "N800.png", IMG_PATH + "N810.png"
+DEVICE_DISCONNECTED = IMG_PATH + "disconnected.png"
+DEVICE_DISCONNECTED_BACKUP = IMG_PATH + "disconnected_backup.png"
+DEVICE_BACKUP_BORDER = IMG_PATH + "device_backup_border.png"
+DEVICE_CHECKBOX_BORDER = IMG_PATH + "device_checkbox_border.png"
+DEVICE_FILE_BORDER = IMG_PATH + "device_file_border.png"
+DEVICE_NAME_BORDER_BACKUP = IMG_PATH + "device_name_border_backup.png"
+DEVICE_NAME_BORDER_CHECKBOX = IMG_PATH + "device_name_border_checkbox.png"
+DEVICE_NAME_BORDER_FILE = IMG_PATH + "device_name_border_file.png"
+N800_BACKUP = IMG_PATH + "N800_backup.png"
+N800_FILE = IMG_PATH + "N800_file.png"
+N810_BACKUP = IMG_PATH + "N810_backup.png"
+N810_FILE = IMG_PATH + "N810_file.png"
+BLACK_ARROW = IMG_PATH + "black_arrow.png"
+WHITE_ARROW = IMG_PATH + "white_arrow.png"
+BUTTON_BG = IMG_PATH + "button_bg.png"
+BUTTON_BG_CLICKED = IMG_PATH + "button_bg_clicked.png"
+BUTTON_WITH_ICON_BG = IMG_PATH + "button_with_icon_bg.png"
+BUTTON_WITH_ICON_BG_CLICKED = IMG_PATH + "button_with_icon_bg_clicked.png"
+FORWARD_BUTTON = IMG_PATH + "forward_arrow_off.png"
+FORWARD_BUTTON_CLICKED = IMG_PATH + "forward_arrow_on.png"
+BACK_BUTTON = IMG_PATH + "back_arrow_off.png"
+BACK_BUTTON_CLICKED = IMG_PATH + "back_arrow_on.png"
+SMALL_ICON_NEW_BACKUP = IMG_PATH + "small_icon-ref-newbackup.png"
+SMALL_ICON_MANAGER_BACKUP = IMG_PATH + "small_icon-ref-managebackups.png"
+SMALL_ICON_RESTORE_BACKUP = IMG_PATH + "small_icon-ref-restorebackups.png"
+SMALL_ICON_SETTINGS = IMG_PATH + "small_icon-ref-settings.png"
+ICON_NEW_BACKUP = IMG_PATH + "icon-ref-newbackup.png"
+ICON_MANAGER_BACKUP = IMG_PATH + "icon-ref-managebackups.png"
+ICON_RESTORE_BACKUP = IMG_PATH + "icon-ref-restorebackups.png"
+ICON_SETTINGS = IMG_PATH + "icon-ref-settings.png"
+ICON_ALERT = IMG_PATH + "icon-alert-ref.png"
+BACKUP_BG = IMG_PATH + "bg_backup0.png"
+RESTORE_BG = IMG_PATH + "bg_restore.png"
+MANAGER_BG = IMG_PATH + "bg_manager.png"
+COPY_BORDER = IMG_PATH + "copy_border.png"
+CHECKBOX_UNCHECKED = IMG_PATH + "checkbox_unchecked.png"
+CHECKBOX_CHECKED = IMG_PATH + "checkbox_checked.png"
+CHECKBOX_BORDER = IMG_PATH + "checkbox_border.png"
+BT_NEXT = IMG_PATH + "bt_next.png"
+BT_NEXT_CLICKED = IMG_PATH + "bt_next_clicked.png"
+PC_BORDER_FILE = IMG_PATH + "pc_file_border.png"
+PC_IMAGE = IMG_PATH + "pc_image.png"
+PC_NAME_BORDER_FILE = IMG_PATH + "pc_name_border_file.png"
+LARGE_ARROW_IMAGE = IMG_PATH + "large_arrow_image.png"
+LARGE_ARROW_BORDER = IMG_PATH + "large_arrow_border.png"
+BROWSE_BUTTON = IMG_PATH + "browse_button.png"
+BACKUP_NAME_BORDER = IMG_PATH + "backup_name_border.png"
+BACKUP_NAME_BG = IMG_PATH + "backup_name_bg.png"
+PATH_BG = IMG_PATH + "path_bg.png"
+PATH_BORDER = IMG_PATH + "path_border.png"
+SCROLL_BASE_H = IMG_PATH + "scroll_base_h.png"
+SCROLL_BASE_V = IMG_PATH + "scroll_base_v.png"
+SCROLL_HANDLE_H = IMG_PATH + "scroll_handle_h.png"
+SCROLL_HANDLE_V = IMG_PATH + "scroll_handle_v.png"
+BACKUP_BUTTON_DEFAULT_CLICKED = IMG_PATH + "backup_default_button_clicked.png"
+BACKUP_BUTTON_DEFAULT = IMG_PATH + "backup_default_button.png"
+PROGRESS_BAR_BG = IMG_PATH + "progress_bar_bg.png"
+PROGRESS_BAR_DIALOG_BG = IMG_PATH + "progress_bar_dialog_bg.png"
+PROGRESS_BAR_BORDER = IMG_PATH + "progress_bar_border.png"
+PROGRESS_BAR_CHUNK = IMG_PATH + "progress_bar_chunk.png"
+PROGRESS_BAR_CHUNK_DIALOG = IMG_PATH + "progress_bar_chunk_dialog.png"
+TABLE_BORDER = IMG_PATH + "table_border.png"
+TAB_BG_1 = IMG_PATH + "tab_bg_1.png"
+TAB_BG_2 = IMG_PATH + "tab_bg_3.png"
+SMALL_DEFAULT_BUTTON_CLICKED = IMG_PATH + "small_default_button_clicked.png"
+SMALL_DEFAULT_BUTTON = IMG_PATH + "small_default_button.png"
+IP_LIST_BORDER = IMG_PATH + "ip_list_border.png"
+DEFAULT_BG = IMG_PATH + "default_bg.png"
+VIEW_BORDER = IMG_PATH + "view_border.png"
+OPEN_FILE_ERROR = "Could not open backup files. Maybe file is protected by" + \
+" password"
+OPEN_FILE_ERROR_TITLE = "Error while opening file"
+
+TOP_SPACER = QtGui.QSpacerItem(0,30)
+TOP_BAR_X, TOP_BAR_Y = 10, 39
+WINDOW_WIDTH = 453
+WINDOW_HEIGHT = 400
+
diff --git a/src/ui/.svn/text-base/tsuigeneralmethods.py.svn-base b/src/ui/.svn/text-base/tsuigeneralmethods.py.svn-base
new file mode 100644 (file)
index 0000000..1535527
--- /dev/null
@@ -0,0 +1,32 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+
+def centralize(widget):
+    screen = QtGui.QDesktopWidget().screenGeometry()
+    size = widget.geometry()
+    widget.move((screen.width() - size.width())/2, (screen.height() - size.height())/2)
+    
+def showMessageBox(message, window_title = ""):
+    """ Creates a QMessageBox object and set its window title and text to the
+    given strings.
+    
+    Attributes:
+        String message - Message to be displayed inside the message box.
+        String window_title - String representing the title of the message box.
+    
+    """
+    message_box = QtGui.QMessageBox()
+    message_box.setStyleSheet(MESSAGE_BOX_DEFAULT)
+    message_box.setWindowFlags(QtCore.Qt.FramelessWindowHint)
+    message_box.setWindowTitle(window_title)
+    message_box.setWindowIcon(QtGui.QIcon(BACKUP_IMAGE))
+    message_box.setText(message)
+    message_box.exec_()
+    
+        
diff --git a/src/ui/__init__.py b/src/ui/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/ui/pcsapp.py b/src/ui/pcsapp.py
new file mode 100644 (file)
index 0000000..f901392
--- /dev/null
@@ -0,0 +1,16 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+
+class PcsApp(QDialog):
+    
+    ''' Class that represents an application from Pc Suite'''
+    
+    def __init__(self, parent=None):
+        super(PcsApp, self).__init__(parent)
+        self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
+    
\ No newline at end of file
diff --git a/src/ui/pcsapplicationlist.py b/src/ui/pcsapplicationlist.py
new file mode 100644 (file)
index 0000000..bfc3b54
--- /dev/null
@@ -0,0 +1,48 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from backup.pcsbackup import *
+from pcsuiutils import *
+from tsuigeneralmethods import *
+
+class PcsApplicationList(QFrame):
+    
+    ''' Class that creates buttons on the main frame. Each button 
+        represents a Pc Suite Application.'''
+    
+    def __init__(self, deviceManager, parent=None):
+        super(PcsApplicationList, self).__init__(parent)
+        self.layout = QHBoxLayout()
+        self.setFixedSize(480,200)
+        self.createList()
+        self.setLayout(self.layout)  
+        self.deviceManager = deviceManager
+
+    def createList(self):       
+        self.listWidget = QListWidget()
+        self.listWidget.setViewMode(QListView.IconMode)
+        self.listWidget.setDragDropMode(QAbstractItemView.NoDragDrop)
+        
+        # Creates Backup application applet
+        backupButton = QListWidgetItem()
+        backupButton.setIcon(QIcon(BACKUP_IMAGE))
+        backupButton.setText("Backup")
+        backupButton.setToolTip("Backup Application")
+        self.listWidget.addItem(backupButton)
+                
+        self.connect(self.listWidget, 
+                     SIGNAL("itemDoubleClicked(QListWidgetItem *)"), 
+                     self.openBackupApplication)
+
+        self.layout.addWidget(self.listWidget)
+         
+    def openBackupApplication(self):
+        deviceInfo = self.deviceManager.getCurrentDevice()
+        backup = PcsBackup(deviceInfo, self)
+        centralize(backup)
+        backup.show()
+        
+        
diff --git a/src/ui/pcsbutton.py b/src/ui/pcsbutton.py
new file mode 100644 (file)
index 0000000..8175c81
--- /dev/null
@@ -0,0 +1,13 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PcsButton(QPushButton):
+    def __init__(self, name = "", parent = None):
+        QPushButton.__init__(self, parent)
+        self.setText(name)
+       
+
+
diff --git a/src/ui/pcscustombuttons.py b/src/ui/pcscustombuttons.py
new file mode 100644 (file)
index 0000000..cdbe15f
--- /dev/null
@@ -0,0 +1,35 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+class PcsCustomButton(QLabel):
+    def __init__(self, image, pressedImage, text = "", parent = None):
+        super(QLabel, self).__init__(parent)
+        
+        self.panel = QLabel()
+        self.layout = QHBoxLayout()
+        self.text = QLabel(text)
+        self.defaultPixmap = QPixmap(image)
+        self.pressedPixmap = QPixmap(pressedImage)
+        self.panel.setPixmap(self.defaultPixmap)
+        self.panel.setGeometry(self.defaultPixmap.rect())
+        self.layout.addWidget(self.panel)
+        if(text <> ""):
+            self.layout.addWidget(self.text)
+        self.setLayout(self.layout)
+        
+        
+    def mouseReleaseEvent(self,event):
+        self.panel.setPixmap(self.defaultPixmap)
+        self.emit(SIGNAL("clicked()"))
+        
+    def mousePressEvent(self, event):
+        self.panel.setPixmap(self.pressedPixmap)
+        
+    def setTextVisible(self, flag):
+        if flag:
+            pass 
+
+
diff --git a/src/ui/pcsdeviceinfoviewer.py b/src/ui/pcsdeviceinfoviewer.py
new file mode 100644 (file)
index 0000000..4a5959b
--- /dev/null
@@ -0,0 +1,189 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from time import sleep
+import threading
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from ui.pcsuiutils import *
+from pcsuiutils import *
+from ui.pcscustombuttons import PcsCustomButton as customButton
+
+class PcsDeviceInfoViewer(QHBoxLayout):
+    
+    ''' Class that displays how the device is connected with the PC'''
+    
+    def __init__(self, pcSuite):
+        super(PcsDeviceInfoViewer,self).__init__()
+        
+        self.label = QLabel("")
+        self.label.setText("<font style='color: gray'; size=2>Maemo Release</font>")
+        self.label.setFixedSize(90,20)
+        
+        self.pcSuite = pcSuite
+        self.l2 = QLabel()
+        pixmap = QPixmap(SSH_IMAGE)
+        self.l2.setPixmap(pixmap)  
+        
+        spacer = QSpacerItem(60, 60)
+        maemoLayout = QVBoxLayout()
+        maemoLayout.setMargin(0)
+        maemoLayout.addItem(spacer)
+        maemoLayout.addWidget(self.label)
+        maemoLayout.addWidget(self.l2)
+        maemoLayout.addItem(spacer)
+        
+        spacer2 = QSpacerItem(0, 32)
+        spacer3 = QSpacerItem(0, 37.6)
+        self.statusLayout = QGridLayout()
+        self.statusLayout.setColumnStretch(1, 1)
+        self.statusLayout.addItem(spacer2, 0, 0)
+        self._createStatusWidget(self.statusLayout)
+        self.statusLayout.addItem(spacer3, 4, 0)
+        
+        self.setMargin(0)
+        self.addLayout(maemoLayout)
+        spacer4 = QSpacerItem(10, 10)
+        self.addItem(spacer4)
+        self.addLayout(self.statusLayout)
+        
+        self.modelLabel = QLabel("Model", self.pcSuite)
+        self.modelLabel.setText("<font style='color: white'; size=2>Model</font>")
+        self.modelLabel.setGeometry(QRect(330, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+       
+        self.arrowLabel = QLabel(self.pcSuite)
+        self.arrowLabel.setPixmap(QPixmap(WHITE_ARROW))
+        self.arrowLabel.setGeometry(QRect(365, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+        
+        self.deviceNameLabel = QLabel("None", self.pcSuite)
+        self.deviceNameLabel.setText("<font style='color: white'; size=2>None</font>")
+        self.deviceNameLabel.setGeometry(QRect(380, 70, WINDOW_WIDTH, WINDOW_HEIGHT))
+        
+        
+        self.deviceNameLabel2 = QLabel(self.pcSuite)
+        self.deviceNameLabel2.setText("<font style='color: #333333'; size=2>None</font>")
+        self.deviceNameLabel2.setGeometry(QRect(10, 39, 50, 15))
+       
+        self.arrowLabel = QLabel(self.pcSuite)
+        self.arrowLabel.setPixmap(QPixmap(BLACK_ARROW))
+        self.arrowLabel.setGeometry(QRect(40, 39, 15, 15))
+        
+        self.actionLabel = QLabel(self.pcSuite)
+        self.actionLabel.setText("<font style='color: white'; size=2>Select option</font>")
+        self.actionLabel.setGeometry(QRect(55, 36, 100, 20))
+                 
+        self.chargingThread = None;
+           
+    def setDeviceInfo(self, deviceInfo):
+        self.deviceInfo = deviceInfo
+        self.label.setText("<font style='color: grey'; size=2>" + deviceInfo.system +"</font>" )
+        
+        
+        self.label.repaint()
+        self.deviceNameLabel.setText("<font style='color: white'; size=2>" 
+                                     + deviceInfo.name + "</font>")
+        self.deviceNameLabel2.setText("<font style='color: #333333'; size=2>" 
+                                     + deviceInfo.name + "</font>")
+        if(self.chargingThread != None):
+            if self.deviceInfo.charging:
+                self._batteryBar.setToolTip("Charging...")
+            else:
+                self.emit(SIGNAL("stopThread"))
+                self._batteryBar.setToolTip("Battery: %d%%" % (deviceInfo.battery))
+                self._batteryBar.setValue(deviceInfo.battery)
+        else:
+            if self.deviceInfo.charging:
+                self._batteryBar.setToolTip("Charging...")
+                self.chargingThread = ChargingThread(self)
+                self.connect(self.chargingThread, SIGNAL("charging"), self._charging)
+                self.chargingThread.start()
+            else:
+                self._batteryBar.setValue(deviceInfo.battery)
+                self._batteryBar.setToolTip("Battery: %d%%" % (deviceInfo.battery))
+       
+
+        memory = deviceInfo.storage
+        tip = ""
+        total_m1 = 0
+        total_m2 = 0
+        current_m1 = 0
+        current_m2 = 0
+        if memory[1] != -1:
+            value_m1 = float(memory[1][1]) * 100 / float(memory[1][0])
+            current_m1 = float(memory[1][1])/1024
+            total_m1 = float(memory[1][0])/1024
+            tip += "MMC1: %.1fMB / %.1fMB - %d%%\n" % (current_m1, total_m1, value_m1)
+        
+        if memory[2] != -1:
+            value_m2 = float(memory[2][1]) * 100 / float(memory[2][0])
+            current_m2 = float(memory[2][1])/1024
+            total_m2 = float(memory[2][0])/1024
+            tip += "MMC2: %.1fMB / %.1fMB - %d%%\n" % (current_m2, total_m2, value_m2)
+
+        if total_m1 == 0 and total_m2 == 0:
+            tip = "No external memory found."
+        else:
+            current = current_m1 + current_m2
+            total = total_m1 + total_m2
+            value = (current_m1 + current_m2) * 100 / total
+            tip += "Total: %.1fMB / %.1fMB - %d%%" % (current, total, value)
+            self._memoryBar.setValue(value)
+        self._memoryBar.setToolTip(tip)
+
+        current = float(memory[0][1])/1024 
+        total = float(memory[0][0])/1024
+        value = current * 100 / total
+        self._deviceBar.setValue(value)
+        self._deviceBar.setToolTip("Device Memory: %.1fMB / %.1fMB - %d%%" % (current, total, value))
+        
+    def _createStatusWidget(self, layout):
+        self._batteryBar = self._newProgressBar(layout, 1, BATTERY_IMAGE)
+        self._deviceBar = self._newProgressBar(layout, 2, DEVICE_MEMORY_IMAGE)
+        self._memoryBar = self._newProgressBar(layout, 3, MEMORY_IMAGE)
+                    
+    def _newProgressBar(self, layout, line, image):
+        bar = QProgressBar()
+        bar.setMaximum(100)
+        bar.setMinimum(0)
+        bar.setFixedSize(150,12.9)
+        bar.setTextVisible(False)
+        layout.addWidget(bar, line, 0 )
+
+        label = QLabel()
+        label.setFixedSize(30,15)
+        pixmap = QPixmap(image)
+        label.setPixmap(pixmap)
+        layout.addWidget(label, line, 1)
+        
+        return bar
+    
+    def _charging(self):
+        currentValue = self._batteryBar.value()
+        if(currentValue == 100):
+            self._batteryBar.setValue(0)
+        self._batteryBar.setValue(currentValue + 1)
+        self._batteryBar.repaint()
+        
+        
+class ChargingThread(QThread):
+    def __init__(self, infoViewer):
+        QThread.__init__(self)
+        self.flag = True
+        self.connect(infoViewer, SIGNAL("stopThread"), self.stopThread)
+        self.connect(infoViewer, SIGNAL("destroyed()"), self.stopThread)
+        
+    def stopThread(self):
+        self.flag = False
+        
+    def run(self):
+        while(self.flag):
+            try:
+                sleep(0.02)
+                self.emit(SIGNAL("charging"))
+            except:
+                self.stopThread()
+            
+        
+    
\ No newline at end of file
diff --git a/src/ui/pcsdeviceviewer.py b/src/ui/pcsdeviceviewer.py
new file mode 100644 (file)
index 0000000..17495a0
--- /dev/null
@@ -0,0 +1,292 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from functools import partial
+from time import sleep
+
+from pcsdeviceinfoviewer import PcsDeviceInfoViewer
+from pcsdevicewidget import PcsDeviceWidget
+from pcsuiutils import *
+from tsuigeneralmethods import *
+from pcsutils import *
+
+from style.styleTabletSuite import *
+from backup.pcswindowmanager import *
+
+class PcsDeviceViewer(QFrame):
+
+    '''Class that displays the devices which are connected to the PC'''
+
+    _ip = "None"
+    CONNECTION_ERROR_MESSAGE = "Could not connect to device with the given IP " + \
+                    "address.\nCheck if device is turned on and is properly " + \
+                    "connected to network"
+    
+    def __init__(self, deviceManager, pcSuite):
+        super(PcsDeviceViewer, self).__init__()
+        self.deviceManager = deviceManager
+        self.deviceManager.loadDevices()
+#        self.pcSuite = pcSuite
+        self.setFixedSize(WINDOW_WIDTH, 150)
+        self.deviceWidget = PcsDeviceWidget(0)
+
+        # Create device connection type
+        self.deviceInfoViewer = PcsDeviceInfoViewer(pcSuite)
+
+        self.mainLayout = QHBoxLayout()
+        self.mainLayout.setMargin(0)
+
+        spacer = QSpacerItem(15, 15)
+        self.mainLayout.addItem(spacer)
+        self.mainLayout.addWidget(self.deviceWidget)
+        self.mainLayout.addItem(QSpacerItem(20,20))
+        self.mainLayout.addLayout(self.deviceInfoViewer)
+        self.mainLayout.addItem(spacer)
+        self.setLayout(self.mainLayout)
+        
+        self.connectDialog = None
+        
+    def checkIp(self, ip):
+        list = ip.split(".")
+        if len(list) != 4:
+            return False
+        for sublist in list:
+            if len(sublist) < 1 or len(sublist) > 3:
+                return False
+            for element in sublist:
+                if not str(element).isdigit():
+                    return False
+        return True  
+    
+    def showConnectDialog(self):
+        if(self.connectDialog == None):
+            self.connectDialog = QDialog(self, Qt.FramelessWindowHint)
+            self.connectDialog.setObjectName("connectDialog")
+            self.connectDialog.setWindowIcon(QIcon(TABLET_SUITE_LOGO))
+            self.connectDialog.setWindowTitle("Device Selection")
+            connectDialogLayout = QVBoxLayout()
+            
+            hLayout = QHBoxLayout()
+            addButton = QPushButton("Add")
+            addButton.setObjectName("smallButton")
+            self.connect(addButton, SIGNAL("clicked()"), self.addIp)
+            
+            self.ipField = QLineEdit()
+            self.ipField.setText("IP Number")
+            self.ipField.setObjectName("ipField")
+            hLayout.addWidget(self.ipField)
+            hLayout.addWidget(addButton)
+            
+            buttonLayout = QHBoxLayout()
+            self.connectButton = QPushButton("Connect")
+            self.connectButton.setObjectName("tsButton")
+            self.connect(self.connectButton, SIGNAL("clicked()"), self._connect)
+            
+            self.deleteButton = QPushButton("Delete")
+            self.deleteButton.setObjectName("tsButton")
+            self.connect(self.deleteButton, SIGNAL("clicked()"), self._deleteSelectedIp)
+            
+            cancelButton = QPushButton("Cancel")
+            cancelButton.setObjectName("tsButton")
+            setVisible = partial(self.connectDialog.setVisible, False)
+            self.connect(cancelButton, SIGNAL("clicked()"), setVisible)
+            
+            buttonLayout.addWidget(self.connectButton)
+            buttonLayout.addWidget(self.deleteButton)
+            buttonLayout.addWidget(cancelButton)
+            
+            vLayout = QVBoxLayout()
+            vLayout.setMargin(15)
+            vLayout.addWidget(QLabel("Select the device IP"))
+            vLayout.addLayout(hLayout)
+            vLayout.addWidget(self._createIpList())
+            connectDialogLayout.addLayout(vLayout)
+            connectDialogLayout.addLayout(buttonLayout)
+            self.connectDialog.setLayout(connectDialogLayout)
+            self._updateIpList()
+            self.connectDialog.exec_()
+            
+        else:
+            self._updateIpList()
+            self.connectDialog.setVisible(True)
+    
+    def _connect(self):
+        self._ip = self.getSelectedIp()
+        if not create_route(self._ip):
+            showMessageBox(self.CONNECTION_ERROR_MESSAGE,
+                              "Error while connecting to device")
+            return False
+        if not verify_exist_keys(self._ip):
+            dialog = QMessageBox()
+            dialog.setText( "Wrong Key, It seems that the device key " + \
+                            "changed. Do you want to exchange keys again?")
+            dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+            dialog.setWindowFlags(Qt.FramelessWindowHint)
+            dialog.setStyleSheet(MESSAGE_BOX_DEFAULT)
+            ret = dialog.exec_()
+            if ret == QMessageBox.Yes:
+                if not self.showPasswdDialog():
+                    return False
+            else:
+                return False
+        self._runAddDevice()
+
+    def _createIpList(self):
+        self.ipList = QTableView(self)
+        self.ipList.setObjectName("ipList")
+        self.ipList.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+        self.ipList.setAlternatingRowColors(True)
+        self.ipList.setShowGrid(False)
+        self.ipList.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.model = QStandardItemModel()
+        self.ipList.setModel(self.model)
+        self._updateButtonsState()
+        self.connect(self.ipList.selectionModel(), 
+                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
+                     self._updateButtonsState)
+        
+        hHeader = QHeaderView(Qt.Horizontal)
+        hHeader.setVisible(False)
+        hHeader.setResizeMode(QHeaderView.ResizeToContents)
+        hHeader.setMinimumSectionSize(225)
+        self.ipList.setHorizontalHeader(hHeader)  
+        
+        vHeader = QHeaderView(Qt.Vertical)
+        vHeader.setVisible(False)
+        self.ipList.setVerticalHeader(vHeader)
+        
+        return self.ipList 
+    
+    def _deleteSelectedIp(self):
+        dialog = QMessageBox()
+        dialog.setText("Remove selected ip?")
+        dialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+        dialog.setWindowFlags(Qt.FramelessWindowHint)
+        dialog.setStyleSheet(MESSAGE_BOX_APP)
+        ret = dialog.exec_()
+        if ret == QMessageBox.Yes:
+            selectionModel = self.ipList.selectionModel()
+            indexList = selectionModel.selectedRows()
+            for index in indexList:
+                if index.isValid():
+                    try:
+                        ipAdress = self.model.itemData(index)[0].toString()
+                        self.deviceManager.removeDevice(ipAdress)
+                    except:
+                        pass
+                    finally:
+                        self.model.removeRow(index.row())
+        
+    def getSelectedIp(self):
+        selectionModel = self.ipList.selectionModel()
+        indexList = selectionModel.selectedRows()
+        
+        for index in indexList:
+            if index.isValid():
+                data = self.model.itemData(index)
+                return data[0].toString()
+    
+    def showInvalidIpDialog(self):
+        showMessageBox("Invalid ip adress", "Invalid ip")
+    
+    def addIp(self):
+        ip = self.ipField.text()
+             
+        if self.checkIp(ip):
+            for i in range(self.model.rowCount()):
+                if(self.model.item(i).text() == ip):
+                    self.ipField.setText("IP Number")
+                    return
+            item = QStandardItem(ip)
+            self.model.appendRow([item])
+            self.ipField.setText("IP Number")
+        else:
+            self.showInvalidIpDialog()
+
+    def showPasswdDialog(self):        
+        (passwd, ok) = QInputDialog.getText(self, "Device Selection",
+                                             "Root Password:",
+                                              QLineEdit.Password,
+                                              QString(), 
+                                              Qt.FramelessWindowHint)
+        if ok and not passwd.isEmpty():
+            self._passwd = passwd
+            if not keyExchange(self._ip, self._passwd):
+                errorMessage = "Could not connect to device with the given IP " + \
+                    "Could not exchange keys"
+                showMessageBox(errorMessage, "Error while connecting to device")
+                return False
+            return True
+    
+    def _updateButtonsState(self):
+        selectionModel = self.ipList.selectionModel()
+        indexList = selectionModel.selectedRows()
+        if len(indexList) > 1 or len(indexList) <= 0:
+            self.connectButton.setDisabled(True)
+            self.deleteButton.setDisabled(True)
+        else:
+            self.connectButton.setEnabled(True)
+            self.deleteButton.setEnabled(True)
+    
+    def _createWindowManager(self, deviceInf):
+         if deviceInf != None:
+                PcsWindowManager(deviceInf, self)
+    
+    def _runAddDevice(self):
+        self.connectingThread = connectingThread(self.deviceManager, self._ip)
+        self.connect(self.connectingThread, SIGNAL("connectException"), self._connectException)
+        self.connect(self.connectingThread, SIGNAL("createWindowManager"), self._createWindowManager)
+        self.connectingThread.start()
+        
+        self.connectionProgress()
+        self.connect(self.connectingThread, SIGNAL("connectionDone"), self.updateDeviceInformation)
+                
+    def updateDeviceInformation(self, deviceInfo):
+        self._progressDialog.cancel()
+        self.deviceInfo = deviceInfo
+        self.deviceManager.setCurrentDevice(self._ip)
+        if self.deviceInfo:
+            self.deviceManager.loadDevices()
+            self.deviceWidget.setDeviceInfo(self.deviceInfo)
+            self.deviceInfoViewer.setDeviceInfo(self.deviceInfo)
+        else:
+            showMessageBox("An error occurred while connect.", "Connection error")
+    
+    def _updateIpList(self):
+        self.model.clear()
+        devices = self.deviceManager.getDevices()
+        for device in devices:
+            self.model.appendRow(QStandardItem(str(device)))
+    
+    def connectionProgress(self):
+        self.connectDialog.setVisible(False)
+        self._progressDialog = QProgressDialog("Connecting...", 
+                                               QString(), 0, -1, self,
+                                               Qt.FramelessWindowHint)
+        self._progressDialog.setObjectName("progressDialog")
+        self._progressDialog.setWindowIcon(QIcon(BACKUP_IMAGE))
+        self._progressDialog.setValue(0)
+        self._progressDialog.show()
+        
+    def _connectException(self):
+        showMessageBox("", "Error while connect to device")
+
+
+class connectingThread(QThread):
+    def __init__(self, deviceManager, deviceIp):
+        QThread.__init__(self)
+        self.deviceManager = deviceManager
+        self.deviceIp = deviceIp
+    
+    def run(self):
+        try:
+            deviceInf = self.deviceManager._addDevice(self.deviceIp)
+            self.emit(SIGNAL("createWindowManager"), deviceInf)
+            self.emit(SIGNAL("connectionDone"), deviceInf)
+        except:
+            self.emit(SIGNAL("connectException"))
+            self.emit(SIGNAL("connectionDone"), None)
\ No newline at end of file
diff --git a/src/ui/pcsdevicewidget.py b/src/ui/pcsdevicewidget.py
new file mode 100644 (file)
index 0000000..927316b
--- /dev/null
@@ -0,0 +1,81 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+import sys
+from functools import partial
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from pcsuiutils import *
+from pcsdeviceinfo import *
+
+class PcsDeviceWidget(QFrame):
+    
+    def __init__(self, size):
+        super(PcsDeviceWidget, self).__init__()
+        self.layout = QGridLayout()
+        self.layout.setMargin(0)
+        self.gridLayout = QGridLayout()
+        self.hasDeviceName = False
+        self.size = size
+        
+        self.deviceLabel = QLabel()
+        if size == 1:
+            img = DEVICE_DISCONNECTED_BACKUP
+        else:
+            img = DEVICE_DISCONNECTED
+        self.deviceLabel.setPixmap(QPixmap(img))
+        self.gridLayout.addWidget(self.deviceLabel, 0, 0, Qt.AlignCenter)
+        
+        self.layout.addLayout(self.gridLayout, 0, 0, Qt.AlignCenter)
+        self.setLayout(self.layout)
+
+    def addBorder(self):
+        devices = [(0, None, (None, None)),
+                   (1, DEVICE_BACKUP_BORDER, (208, 205)), 
+                   (2, DEVICE_CHECKBOX_BORDER, (152, 154)), 
+                   (3, DEVICE_FILE_BORDER, (112, 125))]
+        
+        name = devices[self.size][1]
+        self.borderLabel = QLabel()
+        self.borderLabel.setFixedSize(devices[self.size][2][0], devices[self.size][2][1])
+        self.borderLabel.setPixmap(QPixmap(name))
+        self.layout.addWidget(self.borderLabel, 0, 0, Qt.AlignCenter)
+        
+    def addDeviceName(self):
+        devices = [(0, None, (None, None)),
+                   (1, DEVICE_NAME_BORDER_BACKUP, (174, 23)), 
+                   (2, DEVICE_NAME_BORDER_CHECKBOX, (100, 23)), 
+                   (3, DEVICE_NAME_BORDER_FILE, (91, 23))]
+        
+        name = devices[self.size][1]
+        self.hasDeviceName = True
+        self.nameLayout = QGridLayout()
+        self.nameLabel = QLabel("Connect a device ")
+        nameBorderLabel = QLabel()
+        nameBorderLabel.setFixedSize(devices[self.size][2][0], devices[self.size][2][1])
+        nameBorderLabel.setPixmap(QPixmap(name))
+        self.nameLayout.addWidget(self.nameLabel, 0, 0, Qt.AlignCenter)
+        self.nameLayout.addWidget(nameBorderLabel, 0, 0, Qt.AlignCenter)
+        
+        self.gridLayout.addLayout(self.nameLayout, 1, 0, Qt.AlignCenter)
+    
+    def setImage(self, path):
+        self.deviceLabel.setPixmap(QPixmap(path))
+     
+    def setDeviceInfo(self, deviceInfo):
+        devices = [(0, N800_FILE, N810_FILE),
+                   (1, N800_BACKUP, N810_BACKUP),
+                   (2, N800, N810),
+                   (3, N800_FILE, N810_FILE)]
+        if(deviceInfo != None):
+            if deviceInfo.name == "N800":
+                name = devices[self.size][1]
+            elif deviceInfo.name == "N810":
+                name = devices[self.size][2]
+            self.deviceLabel.setPixmap(QPixmap(name))
+            self.deviceLabel.repaint()
+            if self.hasDeviceName:
+                self.nameLabel.setText(deviceInfo.name)
+                
+
diff --git a/src/ui/pcsmenu.py b/src/ui/pcsmenu.py
new file mode 100644 (file)
index 0000000..fcc7809
--- /dev/null
@@ -0,0 +1,98 @@
+# Authors: Amaury Medeiros and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from backup.pcsbackup import *
+from pcsuiutils import *
+
+class PcsMenu(QMenuBar):
+
+    ''' Class that creates a menu bar for Pc Suite '''
+
+    def __init__(self, device_manager, parent = None):
+        super(PcsMenu,self).__init__(parent)
+        self.deviceManager = device_manager
+        self.create_menu_file()
+        #self.create_menu_web()
+        #self.create_menu_settings()
+        #self.create_menu_help()
+    
+    def create_menu_file(self):
+        
+            self.menu_file = QMenu("File")
+            
+            menu_list = [("Backup", self.show_backup_dialog,
+                          BACKUP_IMAGE)]
+#                         ("Synchronize", self.pass_func, ""),
+#                         ("Connect to Web", self.pass_func, ""),
+#                         ("Contacts", self.pass_func, ""),
+#                         ("Messages", self.pass_func, ""),
+#                         ("Calendar", self.pass_func, ""),
+#                         ("File manager", self.pass_func, ""),
+#                         ("Tranfer music", self.pass_func, ""),
+#                         ("Store images", self.pass_func, ""),
+#                         ("Video Transfers", self.pass_func, ""),
+#                         ("Install Applications", self.pass_func, ""),
+#                         ("Update Phone's Software", self.pass_func,""),
+#                         ("Download maps", self.pass_func, ""),
+#                         ("Quit", self.pass_func, image._nokia_icon)]
+            
+            for tuple in menu_list:
+                name = tuple[0]
+                callback = tuple[1]
+                icon = tuple[2]
+                        
+                action = QAction(name, self.menu_file)
+                self.menu_file.addAction(action)
+                self.connect(action, SIGNAL("triggered()"), callback)
+                action.setIcon(QIcon(icon))
+            
+            self.addMenu(self.menu_file)
+            
+    def create_menu_web(self):
+        self.menu_web = QMenu("Web")
+        
+        self.menu_web_pc_suite = QMenu("PC Suite at web")
+        self.menu_web.addMenu(self.menu_web_pc_suite)        
+        self.pc_suite_demonstration = QAction("PC Suite demonstration",
+                                              self.menu_web)
+        self.menu_web.addAction(self.pc_suite_demonstration)
+        
+        self.menu_web.addSeparator()
+        
+        self.registration_action = QAction("Registration", self.menu_web)
+        self.menu_web.addAction(self.registration_action)
+        self.browse_updates_action = QAction("Browse updates and complements",
+                                             self.menu_web)
+        self.menu_web.addAction(self.browse_updates_action)
+        
+        self.addMenu(self.menu_web)
+    
+    def create_menu_settings(self):
+        self.menu_settings = QMenu("Options")
+        
+        self.settings_action = QAction("Settings...", self.menu_settings)
+        self.menu_settings.addAction(self.settings_action)
+        self.manage_connections_action = QAction("Manage Connections",
+                                                 self.menu_settings)
+        self.menu_settings.addAction(self.manage_connections_action)
+        self.add_phones_action = QAction("Add more phones",
+                                         self.menu_settings)
+        self.menu_settings.addAction(self.add_phones_action)
+        self.rename_phone_action = QAction("Rename Phone", self.menu_settings)
+        self.menu_settings.addAction(self.rename_phone_action)
+        
+        self.addMenu(self.menu_settings)
+    
+    def create_menu_help(self):
+        self.menu_help = QMenu("?")
+        self.addMenu(self.menu_help)
+        
+    def show_backup_dialog(self):
+        deviceInfo = self.deviceManager.getCurrentDevice()
+        backup = PcsBackup(deviceInfo, self)
+        centralize(backup)
+        backup.show()
+        
diff --git a/src/ui/pcsuiutils.py b/src/ui/pcsuiutils.py
new file mode 100644 (file)
index 0000000..db97929
--- /dev/null
@@ -0,0 +1,97 @@
+"""Module contaning most used general functions"""
+
+import os
+
+from PyQt4 import QtGui
+
+APPLICATION_NAME = "TabletSuite"
+
+IMG_PATH = os.environ['IMAGE_PATH']
+
+BACKUP_IMAGE = IMG_PATH + "backup.png"
+TABLET_SUITE_LOGO = IMG_PATH + "tabletSuite_logo.png"
+SSH_IMAGE = IMG_PATH + "ssh.png"
+BATTERY_IMAGE = IMG_PATH + "battery_bar.png"
+CHARGING_IMAGE = IMG_PATH + "battery_bar_charging.png"
+MEMORY_IMAGE = IMG_PATH + "memory_bar.png"
+DEVICE_MEMORY_IMAGE = IMG_PATH + "device_memory.png"
+BACKGROUND_IMAGE = IMG_PATH + "bg_geral0.png"
+N800, N810 = IMG_PATH + "N800.png", IMG_PATH + "N810.png"
+DEVICE_DISCONNECTED = IMG_PATH + "disconnected.png"
+DEVICE_DISCONNECTED_BACKUP = IMG_PATH + "disconnected_backup.png"
+DEVICE_BACKUP_BORDER = IMG_PATH + "device_backup_border.png"
+DEVICE_CHECKBOX_BORDER = IMG_PATH + "device_checkbox_border.png"
+DEVICE_FILE_BORDER = IMG_PATH + "device_file_border.png"
+DEVICE_NAME_BORDER_BACKUP = IMG_PATH + "device_name_border_backup.png"
+DEVICE_NAME_BORDER_CHECKBOX = IMG_PATH + "device_name_border_checkbox.png"
+DEVICE_NAME_BORDER_FILE = IMG_PATH + "device_name_border_file.png"
+N800_BACKUP = IMG_PATH + "N800_backup.png"
+N800_FILE = IMG_PATH + "N800_file.png"
+N810_BACKUP = IMG_PATH + "N810_backup.png"
+N810_FILE = IMG_PATH + "N810_file.png"
+BLACK_ARROW = IMG_PATH + "black_arrow.png"
+WHITE_ARROW = IMG_PATH + "white_arrow.png"
+BUTTON_BG = IMG_PATH + "button_bg.png"
+BUTTON_BG_CLICKED = IMG_PATH + "button_bg_clicked.png"
+BUTTON_WITH_ICON_BG = IMG_PATH + "button_with_icon_bg.png"
+BUTTON_WITH_ICON_BG_CLICKED = IMG_PATH + "button_with_icon_bg_clicked.png"
+FORWARD_BUTTON = IMG_PATH + "forward_arrow_off.png"
+FORWARD_BUTTON_CLICKED = IMG_PATH + "forward_arrow_on.png"
+BACK_BUTTON = IMG_PATH + "back_arrow_off.png"
+BACK_BUTTON_CLICKED = IMG_PATH + "back_arrow_on.png"
+SMALL_ICON_NEW_BACKUP = IMG_PATH + "small_icon-ref-newbackup.png"
+SMALL_ICON_MANAGER_BACKUP = IMG_PATH + "small_icon-ref-managebackups.png"
+SMALL_ICON_RESTORE_BACKUP = IMG_PATH + "small_icon-ref-restorebackups.png"
+SMALL_ICON_SETTINGS = IMG_PATH + "small_icon-ref-settings.png"
+ICON_NEW_BACKUP = IMG_PATH + "icon-ref-newbackup.png"
+ICON_MANAGER_BACKUP = IMG_PATH + "icon-ref-managebackups.png"
+ICON_RESTORE_BACKUP = IMG_PATH + "icon-ref-restorebackups.png"
+ICON_SETTINGS = IMG_PATH + "icon-ref-settings.png"
+ICON_ALERT = IMG_PATH + "icon-alert-ref.png"
+BACKUP_BG = IMG_PATH + "bg_backup0.png"
+RESTORE_BG = IMG_PATH + "bg_restore.png"
+MANAGER_BG = IMG_PATH + "bg_manager.png"
+COPY_BORDER = IMG_PATH + "copy_border.png"
+CHECKBOX_UNCHECKED = IMG_PATH + "checkbox_unchecked.png"
+CHECKBOX_CHECKED = IMG_PATH + "checkbox_checked.png"
+CHECKBOX_BORDER = IMG_PATH + "checkbox_border.png"
+BT_NEXT = IMG_PATH + "bt_next.png"
+BT_NEXT_CLICKED = IMG_PATH + "bt_next_clicked.png"
+PC_BORDER_FILE = IMG_PATH + "pc_file_border.png"
+PC_IMAGE = IMG_PATH + "pc_image.png"
+PC_NAME_BORDER_FILE = IMG_PATH + "pc_name_border_file.png"
+LARGE_ARROW_IMAGE = IMG_PATH + "large_arrow_image.png"
+LARGE_ARROW_BORDER = IMG_PATH + "large_arrow_border.png"
+BROWSE_BUTTON = IMG_PATH + "browse_button.png"
+BACKUP_NAME_BORDER = IMG_PATH + "backup_name_border.png"
+BACKUP_NAME_BG = IMG_PATH + "backup_name_bg.png"
+PATH_BG = IMG_PATH + "path_bg.png"
+PATH_BORDER = IMG_PATH + "path_border.png"
+SCROLL_BASE_H = IMG_PATH + "scroll_base_h.png"
+SCROLL_BASE_V = IMG_PATH + "scroll_base_v.png"
+SCROLL_HANDLE_H = IMG_PATH + "scroll_handle_h.png"
+SCROLL_HANDLE_V = IMG_PATH + "scroll_handle_v.png"
+BACKUP_BUTTON_DEFAULT_CLICKED = IMG_PATH + "backup_default_button_clicked.png"
+BACKUP_BUTTON_DEFAULT = IMG_PATH + "backup_default_button.png"
+PROGRESS_BAR_BG = IMG_PATH + "progress_bar_bg.png"
+PROGRESS_BAR_DIALOG_BG = IMG_PATH + "progress_bar_dialog_bg.png"
+PROGRESS_BAR_BORDER = IMG_PATH + "progress_bar_border.png"
+PROGRESS_BAR_CHUNK = IMG_PATH + "progress_bar_chunk.png"
+PROGRESS_BAR_CHUNK_DIALOG = IMG_PATH + "progress_bar_chunk_dialog.png"
+TABLE_BORDER = IMG_PATH + "table_border.png"
+TAB_BG_1 = IMG_PATH + "tab_bg_1.png"
+TAB_BG_2 = IMG_PATH + "tab_bg_3.png"
+SMALL_DEFAULT_BUTTON_CLICKED = IMG_PATH + "small_default_button_clicked.png"
+SMALL_DEFAULT_BUTTON = IMG_PATH + "small_default_button.png"
+IP_LIST_BORDER = IMG_PATH + "ip_list_border.png"
+DEFAULT_BG = IMG_PATH + "default_bg.png"
+VIEW_BORDER = IMG_PATH + "view_border.png"
+OPEN_FILE_ERROR = "Could not open backup files. Maybe file is protected by" + \
+" password"
+OPEN_FILE_ERROR_TITLE = "Error while opening file"
+
+TOP_SPACER = QtGui.QSpacerItem(0,30)
+TOP_BAR_X, TOP_BAR_Y = 10, 39
+WINDOW_WIDTH = 453
+WINDOW_HEIGHT = 400
+
diff --git a/src/ui/tsuigeneralmethods.py b/src/ui/tsuigeneralmethods.py
new file mode 100644 (file)
index 0000000..1535527
--- /dev/null
@@ -0,0 +1,32 @@
+# Authors: Amaury Medeiros, Nicholas Alexander and Paulo Ouriques
+# Software License: GPL
+
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from ui.pcsuiutils import *
+from style.styleTabletSuite import *
+
+def centralize(widget):
+    screen = QtGui.QDesktopWidget().screenGeometry()
+    size = widget.geometry()
+    widget.move((screen.width() - size.width())/2, (screen.height() - size.height())/2)
+    
+def showMessageBox(message, window_title = ""):
+    """ Creates a QMessageBox object and set its window title and text to the
+    given strings.
+    
+    Attributes:
+        String message - Message to be displayed inside the message box.
+        String window_title - String representing the title of the message box.
+    
+    """
+    message_box = QtGui.QMessageBox()
+    message_box.setStyleSheet(MESSAGE_BOX_DEFAULT)
+    message_box.setWindowFlags(QtCore.Qt.FramelessWindowHint)
+    message_box.setWindowTitle(window_title)
+    message_box.setWindowIcon(QtGui.QIcon(BACKUP_IMAGE))
+    message_box.setText(message)
+    message_box.exec_()
+    
+        
diff --git a/tabletsuite b/tabletsuite
new file mode 100644 (file)
index 0000000..609bd76
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+exec /usr/bin/python /usr/lib/python2.6/site-packages/src/tabletsuite.py
diff --git a/welcome b/welcome
deleted file mode 100644 (file)
index e69de29..0000000