def add_loading_widgets(self, children): # Generate list if only one item was given if not type(children) is list: item_list = [] item_list.append(children) children = item_list # Add loading widgets to tree items for child in children: if child.tree_item == None: return # Create loading widget load_widget = QtGui.QLabel() load_widget.resize(50,50) #load_widget.setMaximumSize(50,50) load_widget.setStyleSheet("QLabel { background-color: transparent; }") # Create animation load_anim = QMovie(self.datahandler.datapath("ui/images/loading_tree.gif"), "GIF", load_widget) load_anim.setCacheMode(QMovie.CacheAll) load_anim.setSpeed(150) load_anim.setScaledSize(QtCore.QSize(50,50)) # Add to data model and tree child.set_load_widget(load_widget, load_anim) self.tree.setItemWidget(child.tree_item, 1, load_widget)
def __init__(self): super(self.__class__, self).__init__() movie = QMovie(HERE_PATH + "/spinner.gif") movie.setScaledSize(QSize(23, 23)) movie.setSpeed(200) self.setMovie(movie) movie.start()
class LoadingItem(QLabel): def __init__(self): super(LoadingItem, self).__init__() self.movie = QMovie(resources.IMAGES["loading"]) self.setMovie(self.movie) self.movie.setScaledSize(QSize(16, 16)) self.movie.start() def add_item_to_tree(self, folder, tree, item_type=None, parent=None): if item_type is None: item = QTreeWidgetItem() item.setText(0, self.tr(' LOADING: "%1"').arg(folder)) else: item = item_type(parent, self.tr(' LOADING: "%1"').arg(folder), folder) tree.addTopLevelItem(item) tree.setItemWidget(item, 0, self) return item
class LoadingItem(QLabel): def __init__(self): super(LoadingItem, self).__init__() self.movie = QMovie(resources.IMAGES['loading']) self.setMovie(self.movie) self.movie.setScaledSize(QSize(16, 16)) self.movie.start() def add_item_to_tree(self, folder, tree, item_type=None, parent=None): if item_type is None: item = QTreeWidgetItem() item.setText(0, self.tr(' LOADING: "%s"' % folder)) else: item = item_type(parent, self.tr(' LOADING: "%s"' % folder), folder) tree.addTopLevelItem(item) tree.setItemWidget(item, 0, self) return item
def setStatus(self,status,message='',tooltip=None): '''Sets indicator icon and statusbar message''' self.parent.statusbar.showMessage(message) self.parent.statusbar.setToolTip(tooltip if tooltip else '') #progress loc = os.path.abspath(os.path.join(IMG_LOC,self.imgset[status])) #loc = os.path.abspath(os.path.join(os.path.dirname(__file__),self.parent.IMG_LOC,self.imgset[status])) self.progressbar.setVisible(status in (self.STATUS.BUSY, self.STATUS.CLEAN)) #icon anim = QMovie(loc, QByteArray(), self) anim.setScaledSize(QSize(self.IMG_WIDTH,self.IMG_HEIGHT)) anim.setCacheMode(QMovie.CacheAll) anim.setSpeed(self.IMG_SPEED) self.view.clear() self.view.setMovie(anim) anim.start() self.view.repaint() QApplication.processEvents(QEventLoop.AllEvents)
class MuteButtonLabel(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) #self.setFixedSize(CustomSize) self.movie_screen = QLabel() self.movie_screen.setFixedSize(CustomSize) self.movie_screen.setAlignment(Qt.AlignLeft) main_layout = QVBoxLayout() main_layout.addWidget(self.movie_screen) self.setLayout(main_layout) self.muted = False #self.unmute() # this is for testpurpose only def unmute(self): """start animation""" self.movie = QMovie(":/unmute.gif", QByteArray(), self) self.movie.setScaledSize(CustomSize*0.7) self.movie.setCacheMode(QMovie.CacheAll) self.movie.setSpeed(100) self.movie_screen.setMovie(self.movie) self.muted = False #print("Emitted 'sig_unmute'") self.emit(SIGNAL("sig_unmute")) self.movie.start() def show_unmute(self): self.movie = QMovie(":/unmute.gif", QByteArray(), self) self.movie.setScaledSize(CustomSize*0.7) self.movie.setCacheMode(QMovie.CacheAll) self.movie.setSpeed(100) self.movie_screen.setMovie(self.movie) self.muted = False self.movie.start() def mute(self): """stop the animation""" self.movie = QMovie(":/mute.gif", QByteArray(), self) self.movie.setScaledSize(CustomSize*0.7) self.movie.setCacheMode(QMovie.CacheAll) self.movie.setSpeed(100) self.movie_screen.setMovie(self.movie) self.muted = True #print("Emitted 'sig_mute'") self.emit(SIGNAL("sig_mute")) self.movie.start() def toggleMute(self): if self.muted: self.unmute() else: self.mute() def mousePressEvent(self, QMouseEvent): self.toggleMute() QMouseEvent.accept()
class UiController: def __init__(self, controller, debug_mode, logger): self.controller = controller self.datahandler = controller.datahandler self.debug_mode = debug_mode self.logger = logger ### Main Window self.main_widget = QMainWindow() self.main_widget.setAttribute(Qt.WA_Maemo5StackedWindow) self.main_ui = Ui_DropN900Widget() self.main_ui.setupUi(self.main_widget) # Stacked layout for context switching self.stacked_layout = QtGui.QStackedLayout() self.main_ui.centralwidget.setLayout(self.stacked_layout) # Menu items self.action_transfers = QtGui.QAction("Transfers", self.main_widget) self.action_settings = QtGui.QAction("Settings", self.main_widget) self.action_sync = QtGui.QAction("Synchronize", self.main_widget) self.action_sync_photos = QtGui.QAction("Sync Media", self.main_widget) self.action_console = QtGui.QAction("Show Log", self.main_widget) self.action_about = QtGui.QAction("About", self.main_widget) self.action_exit = QtGui.QAction("Exit", self.main_widget) self.main_ui.menubar.addAction(self.action_transfers) self.main_ui.menubar.addAction(self.action_settings) self.main_ui.menubar.addAction(self.action_sync) self.main_ui.menubar.addAction(self.action_sync_photos) self.main_ui.menubar.addAction(self.action_console) self.main_ui.menubar.addAction(self.action_about) self.main_ui.menubar.addAction(self.action_exit) # Connects self.action_transfers.triggered.connect(self.show_transfer_widget) self.action_sync.triggered.connect(self.synchronize_now) self.action_sync_photos.triggered.connect(self.synchronize_now_photos) self.action_settings.triggered.connect(self.show_settings_widget) self.action_console.triggered.connect(self.show_console) self.action_about.triggered.connect(self.show_about) self.action_exit.triggered.connect(self.shut_down) ### Trusted Login Widget self.trusted_login_widget = QWidget() self.trusted_login_ui = Ui_TrustedLoginWidget() self.trusted_login_ui.setupUi(self.trusted_login_widget) self.trusted_login_ui.label_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/images/dropn900_logo.png")).scaled(65,65)) # Connects self.trusted_login_ui.button_auth.clicked.connect(self.try_trusted_login) ### Manager Widget self.manager_widget = QWidget() self.manager_ui = Ui_ManagerWidget() self.manager_ui.setupUi(self.manager_widget) # Tree Controller tree = self.manager_ui.tree_widget self.tree_controller = TreeController(tree, self.manager_ui, self.controller, self.logger) # Hide public link elements on start self.manager_ui.button_copy_public_link.hide() self.manager_ui.button_open_public_link.hide() # Connects self.manager_ui.button_copy_public_link.clicked.connect(self.copy_item_link) self.manager_ui.button_open_public_link.clicked.connect(self.open_item_link) self.manager_ui.button_download.clicked.connect(self.item_download) self.manager_ui.button_upload.clicked.connect(self.item_upload) self.manager_ui.button_rename.clicked.connect(self.item_rename) self.manager_ui.button_remove.clicked.connect(self.item_remove) self.manager_ui.button_new_folder.clicked.connect(self.item_new_folder) self.manager_ui.sync_button.clicked.connect(self.synchronize_now) self.last_dl_location = None self.last_ul_location = None ### Console widget self.console_widget = QWidget(self.main_widget, Qt.Window) self.console_widget.setAttribute(Qt.WA_Maemo5StackedWindow) self.console_ui = Ui_ConsoleWidget() self.console_ui.setupUi(self.console_widget) self.console_ui.button_save.clicked.connect(self.save_log_to_file) self.console_ui.button_back.clicked.connect(self.hide_console) ### Settings widget self.settings_widget = None ### Fill stacked layout self.stacked_layout.addWidget(self.trusted_login_widget) self.stacked_layout.addWidget(self.manager_widget) self.stacked_layout.setCurrentWidget(self.trusted_login_widget) ### Loading Widget self.loading_widget = QWidget(self.manager_widget) self.loading_ui = Ui_LoadingWidget() self.loading_ui.setupUi(self.loading_widget) self.manager_ui.action_layout.insertWidget(3, self.loading_widget) self.loading_widget.hide() self.tree_controller.set_loading_ui(self.loading_ui) # Init loading animation self.loading_animation = QMovie(self.datahandler.datapath("ui/images/loading.gif"), "GIF", self.loading_ui.load_animation_label) self.loading_animation.setCacheMode(QMovie.CacheAll) self.loading_animation.setSpeed(150) self.loading_animation.setScaledSize(QtCore.QSize(48,48)) self.loading_ui.load_animation_label.setMovie(self.loading_animation) # Init hide timer and icons for information messages self.information_message_timer = QTimer() self.information_message_timer.setSingleShot(True) self.information_message_timer.timeout.connect(self.hide_information_message) self.information_icon_ok = QPixmap(self.datahandler.datapath("ui/icons/check.png")).scaled(24,24) self.information_icon_error = QPixmap(self.datahandler.datapath("ui/icons/cancel.png")).scaled(24,24) self.information_icon_queue = QPixmap(self.datahandler.datapath("ui/icons/queue.png")).scaled(24,24) ### About dialog self.about_dialog = AboutDialog(self) self.set_synching(False) def set_synching(self, syncing): self.manager_ui.sync_button.setVisible(not syncing) self.manager_ui.sync_label.setVisible(syncing) def set_settings_widget(self, settings_widget): self.settings_widget = settings_widget def set_transfer_widget(self, transfer_widget): self.transfer_widget = transfer_widget def synchronize_now(self): self.settings_widget.sync_now_clicked() def synchronize_now_photos(self): self.controller.sync_manager.sync_media() def show(self): # Nokia N900 screen resolution, full screen self.main_widget.resize(800, 480) self.main_widget.show() self.main_widget.showMaximized() def show_settings_widget(self): if self.settings_widget != None: if not self.settings_widget.isVisible(): self.settings_widget.show() self.settings_widget.check_settings() def show_transfer_widget(self): if self.settings_widget.isVisible(): self.settings_widget.hide() self.transfer_widget.show() def show_about(self): if not self.about_dialog.isVisible(): self.about_dialog.show() def show_note(self, message): QMaemo5InformationBox.information(None, QString(message), 0) def show_banner(self, message, timeout = 5000): QMaemo5InformationBox.information(None, QString(message), timeout) def show_loading_ui(self, message = "", loading = True): self.loading_ui.info_label.setText(message) self.loading_ui.info_label_icon.hide() self.thumb_was_visible = self.manager_ui.thumb_container.isVisible() self.manager_ui.thumb_container.hide() self.loading_widget.show() self.loading_ui.load_animation_label.setVisible(loading) if loading: self.loading_animation.start() else: self.loading_animation.stop() def show_information_ui(self, message, succesfull, timeout = 4000): self.loading_ui.load_animation_label.hide() self.thumb_was_visible = self.manager_ui.thumb_container.isVisible() if self.thumb_was_visible: self.manager_ui.thumb_container.hide() self.loading_ui.info_label.setText(message) if succesfull == None: icon = self.information_icon_queue elif succesfull: icon = self.information_icon_ok else: icon = self.information_icon_error self.loading_ui.info_label_icon.setPixmap(icon) self.loading_ui.info_label_icon.show() self.loading_widget.show() self.information_message_timer.start(timeout) def hide_loading_ui(self): if not self.information_message_timer.isActive(): self.loading_widget.hide() if self.loading_animation.state() == QMovie.Running: self.loading_animation.stop() def hide_information_message(self): self.loading_ui.info_label_icon.hide() self.hide_loading_ui() self.manager_ui.thumb_container.setVisible(self.thumb_was_visible) def try_trusted_login(self): self.trusted_login_ui.label_error.setText("") email = self.trusted_login_ui.line_edit_email.text() password = self.trusted_login_ui.line_edit_password.text() error = None if email.isEmpty(): error = "Email can't be empty!" elif email.count("@") != 1: error = "Invalid email, check your @ signs!" elif email.contains(" "): error = "Invalid email, can't have spaces!" elif password.isEmpty(): error = "Password can't be empty!" if error == None: self.show_banner("Authenticating...", 3000) self.set_trusted_login_info("Authenticating, please wait...") self.truested_email = self.datahandler.to_unicode(str(email.toUtf8())) self.trusted_password = self.datahandler.to_unicode(str(password.toUtf8())) QTimer.singleShot(100, self.do_trusted_login_networking) else: self.set_trusted_login_error(error) def set_trusted_login_error(self, error): self.trusted_login_ui.label_error.setStyleSheet("color: #9d1414;") self.trusted_login_ui.label_error.setText(error) self.truested_email = None self.trusted_password = None def set_trusted_login_info(self, info): self.trusted_login_ui.label_error.setStyleSheet("color: #149d2b;") self.trusted_login_ui.label_error.setText(info) def do_trusted_login_networking(self): self.controller.end_trusted_auth(self.truested_email.encode("utf-8"), self.trusted_password.encode("utf-8")) self.truested_email = None self.trusted_password = None def reset_trusted_login(self): self.trusted_login_ui.line_edit_email.clear() self.trusted_login_ui.line_edit_password.clear() self.trusted_login_ui.label_error.clear() def switch_context(self, view = None): widget = None if view == "trustedlogin": widget = self.trusted_login_widget if view == "manager": widget = self.manager_widget if view == "console": self.console_widget.show() if view == None and self.last_view != None: widget = self.last_view if widget != None: self.last_view = self.stacked_layout.currentWidget() self.stacked_layout.setCurrentWidget(widget) def get_selected_data(self): return self.tree_controller.selected_data # Signal handlers def shut_down(self): self.main_widget.close() def show_console(self): if self.console_widget.isVisible() == False: self.switch_context("console") else: self.hide_console() def hide_console(self): self.console_widget.hide() def save_log_to_file(self): filename = self.datahandler.get_data_dir_path() + "dropn900.log" log_string = str(self.console_ui.text_area.toPlainText()) try: log_file = open(filename, "w") log_file.write(log_string) log_file.close() self.show_banner("Log saved to " + filename) except IOError: self.logger.error("Could not open " + filename + " to save log") def browser_control_clicked(self): if self.controller.connected: self.switch_context() else: self.controller.end_auth() def copy_item_link(self): url = self.tree_controller.current_public_link if url == None: return self.datahandler.copy_url_to_clipboard(url) def open_item_link(self): url = self.tree_controller.current_public_link if url == None: return QDesktopServices.openUrl(QtCore.QUrl(url)) def item_download(self): data = self.get_selected_data() if data == None: return if self.datahandler.dont_show_dl_dialog == False: # This dialog shows sometimes strange stuff on maemo5 # It's a PyQt4 bug and its the best we got, you can cope with this if self.last_dl_location == None: self.last_dl_location = self.datahandler.get_data_dir_path() local_folder_path = QFileDialog.getExistingDirectory(self.manager_widget, QString("Select Download Folder"), QString(self.last_dl_location), QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly) if local_folder_path.isEmpty(): return py_unicode_path = self.datahandler.to_unicode(str(local_folder_path.toUtf8())) self.last_dl_location = py_unicode_path store_path = py_unicode_path + "/" + data.name else: dir_check = QDir(self.datahandler.get_data_dir_path()) if not dir_check.exists(): self.show_note("Cannot download, destination " + self.datahandler.get_data_dir_path() + " does not exist. Please set a new folder in settings.") return store_path = self.datahandler.get_data_dir_path() + data.name self.controller.connection.get_file(data.path, data.root, store_path, data.get_size(), data.mime_type) def item_upload(self): data = self.get_selected_data() if data == None or not data.is_folder(): return # This dialog shows sometimes strange stuff on maemo5 # It's a PyQt4 bug and its the best we got, you can cope with this if self.last_ul_location == None: self.last_ul_location = self.datahandler.get_data_dir_path() local_file_path = QFileDialog.getOpenFileName(self.manager_widget, QString("Select File for Upload"), QString(self.last_ul_location)) if local_file_path.isEmpty(): return py_unicode_path = self.datahandler.to_unicode(str(local_file_path.toUtf8())) self.last_ul_location = py_unicode_path[0:py_unicode_path.rfind("/")] self.controller.connection.upload_file(data.path, data.root, py_unicode_path) def item_rename(self): data = self.get_selected_data() if data == None: return # Get new name from user old_name = data.get_name() keyword = "file" if not data.is_folder() else "folder" new_name, ok = QInputDialog.getText(None, "Renaming " + keyword, "Give new name for " + keyword + " " + old_name, QtGui.QLineEdit.Normal, old_name) if not ok: return # Validate with QString if not self.is_name_valid(new_name, keyword): return # Make QString to python 'unicode' new_name = self.datahandler.to_unicode(str(new_name.toUtf8())) if old_name == new_name: return # Extension will be lost, ask user if he wants to leave it q_old_name = QtCore.QString(old_name) if q_old_name.contains("."): if not new_name.contains("."): format = old_name[q_old_name.lastIndexOf("."):] confirmation = QMessageBox.question(None, "Extension missing", "Do you want to append the original '" + format + "' extensions to the filename '" + new_name + "'?", QMessageBox.Yes, QMessageBox.No) if confirmation == QMessageBox.Yes: new_name.append(format) # Get final new path and rename if data.parent == "/": new_name = data.parent + new_name else: new_name = data.parent + "/" + new_name self.controller.connection.rename(data.root, data.path, new_name, data) def item_remove(self): data = self.get_selected_data() if data == None: return if data.is_folder(): confirmation = QMessageBox.question(None, "Remove folder verification", "Are you sure you want to remove the entire folder " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel) else: confirmation = QMessageBox.question(None, "Remove file verification", "Are you sure you want to remove " + data.get_name() +"?", QMessageBox.Yes, QMessageBox.Cancel) if confirmation == QMessageBox.Yes: self.controller.connection.remove_file(data.root, data.path, data.parent, data.is_folder()) def item_new_folder(self): data = self.get_selected_data() if data == None: return if not data.is_folder(): return full_create_path = data.path + "/" new_folder_name, ok = QInputDialog.getText(None, "Give new folder name", "") if not ok: return # Validate QString if not self.is_name_valid(new_folder_name, "folder"): return # Make QString to python unicode new_folder_name = self.datahandler.to_unicode(str(new_folder_name.toUtf8())) full_create_path = data.path + "/" + new_folder_name self.controller.connection.create_folder(data.root, full_create_path, new_folder_name, data.path) def is_name_valid(self, name, item_type): if name.isEmpty() or name.isNull(): return False if name.contains("/"): self.show_information_ui("Cant use / in new " + item_type + " name", False) return False if name.contains("\\"): self.show_information_ui("Cant use \ in new " + item_type + " name", False) return False if name.startsWith(" "): self.show_information_ui("New " + item_type + " name cant start with a space", False) return False if name.endsWith(" "): self.show_information_ui("New " + item_type + " name cant end with a space", False) return False return True