class AddDownloads(QVBoxLayout): def __init__(self, downloads, parent=None): QVBoxLayout.__init__(self) self.setContentsMargins(0, 0, 0, 0) self.setSpacing(5) self.downloads = downloads self.parent = parent self.tree_view = QTreeView(parent) # self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_view.customContextMenuRequested.connect(self.context_menu) # #listview look self.tree_view.setWordWrap(True) #search textElideMode self.tree_view.setRootIsDecorated(False) self.tree_view.setIndentation(0) self.tree_view.setAlternatingRowColors(True) # self.items = [] self.rows_buffer = {} #{id_item: row_obj, } #self.items = [[True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"]] bool_cols = [ 1, ] headers = [ "hidden_id_item", "", _("Status"), _("File Name"), _("Host"), _("Size"), _("Status Message") ] # self.__model = SimpleListModel(headers, self.items, bool_cols) self.tree_view.setModel(self.__model) self.addWidget(self.tree_view) # self.tree_view.setColumnHidden(0, True) self.tree_view.setColumnWidth(1, 27) self.tree_view.header().setResizeMode(1, QHeaderView.Fixed) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(10) self.cb = QComboBox() #self.cb.setFixedWidth(100) self.cb.setEditable(True) self.cb.setFixedHeight(35) self.cb.setMinimumWidth(1) cb_view = self.cb.view() cb_view.setAlternatingRowColors(True) # self.paths_list = conf.get_save_dl_paths() if not self.paths_list: self.cb.addItem(cons.DLFOLDER_PATH) else: [self.cb.addItem(path) for path in reversed(self.paths_list)] # hbox.addWidget(self.cb) btn_examine = QPushButton('...') btn_examine.clicked.connect(self.on_examine) btn_examine.setFixedHeight(35) btn_examine.setMaximumWidth(80) hbox.addWidget(btn_examine) hbox.addSpacing(40) #index, size btn_download = QPushButton() btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM)) btn_download.setIconSize(QSize(24, 24)) btn_download.clicked.connect(self.on_download_selected) btn_download.setFixedHeight(35) btn_download.setMaximumWidth(40) hbox.addWidget(btn_download) btn_add = QPushButton() btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM)) btn_add.setIconSize(QSize(24, 24)) btn_add.clicked.connect(self.on_add_links) btn_add.setFixedHeight(35) btn_add.setMaximumWidth(40) hbox.addWidget(btn_add) self.menu = QMenu(parent) import_action = self.menu.addAction(_("Import Container"), self.on_import_container) self.menu.addSeparator() recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck) clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list) # btn_menu = QPushButton() btn_menu.setMenu(self.menu) btn_menu.setFixedHeight(35) btn_menu.setMaximumWidth(22) btn_menu.setFlat(True) hbox.addWidget(btn_menu) self.addLayout(hbox) #update list parent.idle_timeout(1000, self.update) def context_menu(self, position): menu = QMenu() #indexes = self.selectedIndexes() #sensitive = True if indexes else False #individual_items = [('Open destination folder', self.on_open_folder),] #[menu.addAction(title, callback).setEnabled(sensitive) for title, callback in individual_items] #menu.addSeparator() generic_items = [(_('Download Selected'), self.on_download_selected), (None, None), (_('Select all'), self.on_select_all), (_('Select none'), self.on_select_none), (_('Select inverse'), self.on_select_inverse), (None, None), (_('Re-check'), self.on_recheck), (_('Clear list'), self.on_clear_list)] [ menu.addAction(title, callback) if title is not None else menu.addSeparator() for title, callback in generic_items ] menu.exec_(self.tree_view.viewport().mapToGlobal(position)) def on_clear_list(self): self.__model.clear() self.rows_buffer.clear() api.clear_pending() def on_recheck(self): api.recheck_items() def on_select_all(self): for row in self.items: row[1] = True def on_select_none(self): for row in self.items: row[1] = False def on_select_inverse(self): for row in self.items: row[1] = False if row[1] else True def on_import_container(self): file_name, filter = QFileDialog.getOpenFileName( filter='OCH Files (*.och)') if file_name: container = Container(file_name) container.extract_links() links_list = container.get_linklist() if links_list: self.links_checking(links_list, copy_link=False) def on_add_links(self): add_links = AddLinks(self.parent) result_code = add_links.result() links_list = add_links.links_list if result_code == QDialog.Accepted and links_list: self.links_checking(links_list) def on_examine(self): folder = QFileDialog.getExistingDirectory() if folder: self.cb.setEditText(folder) def cb_remove(self, text): index = self.cb.findText(text) if index >= 0: self.cb.removeItem(index) def on_download_selected(self): current_path = self.cb.currentText() self.cb_remove(current_path) self.cb.insertItem(0, current_path) if current_path in self.paths_list: self.paths_list.remove(current_path) self.paths_list.append(current_path) if len(self.paths_list) > 5: self.paths_list.pop(0) self.cb.removeItem(5) self.cb.setCurrentIndex(0) conf.set_save_dl_paths(self.paths_list) id_items_list = [] iters = [] for row in self.items: if row[1]: # and row[4] != cons.UNSUPPORTED: #tmp iters.append(row) id_item = row[0] id_items_list.append(id_item) del self.rows_buffer[id_item] [self.__model.remove(self.items.index(iter)) for iter in iters] item_list = api.get_added_items(id_items_list) api.downloader_init(item_list, current_path) #iniciar threads de descarga. #TODO: use a signal. self.downloads.store_items(item_list) def links_checking(self, links_list, copy_link=True): for link in links_list: download_item = api.create_download_item( cons.UNKNOWN, 0, link, copy_link) #return download_item object item = [ download_item.id, True, cons.LINK_CHECKING, cons.UNKNOWN, None, None, None ] #self.items.append(item) self.__model.append(item) self.rows_buffer[item[0]] = item api.start_checking() def update(self): #this method steals cycles, its not a new thread items_list = api.get_checking_update() for download_item in items_list: try: row = self.rows_buffer[download_item.id] row[1] = True if download_item.link_status != cons.LINK_DEAD else False row[2] = download_item.link_status row[3] = download_item.name row[4] = download_item.host row[5] = misc.size_format(download_item.size) row[6] = download_item.link_status_msg except KeyError as err: logger.debug(err) self.__model.refresh()
class ConfigAccounts(QDialog): def __init__(self, parent): QDialog.__init__(self, parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.setWindowTitle(_('Host Accounts')) self.resize(500, 450) vbox = QVBoxLayout() self.setLayout(vbox) # ####################### # vbox_accounts = QVBoxLayout() group_accounts = QGroupBox(_('Accounts:')) group_accounts.setLayout(vbox_accounts) self.tree_view = QTreeView() # #listview look self.tree_view.setWordWrap(True) #search textElideMode self.tree_view.setRootIsDecorated(False) self.tree_view.setIndentation(0) self.tree_view.setAlternatingRowColors(True) # self.items = [] headers = ["hidden_id_account", _("Host"), _("Status"), _("Username"), _("Password"), _("Enable")] bool_cols = [ENABLE, ] # self.__model = SimpleListModel(headers, self.items, bool_cols) self.tree_view.setModel(self.__model) vbox_accounts.addWidget(self.tree_view) self.tree_view.setColumnHidden(0, True) hbox_accounts = QHBoxLayout() hbox_accounts.addStretch(0) #stretch/align widget to right. vbox_accounts.addLayout(hbox_accounts) self.btn_remove = QPushButton(_('Remove')) self.btn_remove.clicked.connect(self.on_remove) self.btn_remove.setFixedHeight(35) self.btn_remove.setMaximumWidth(80) self.btn_remove.setEnabled(False) hbox_accounts.addWidget(self.btn_remove) self.btn_check = QPushButton(_('Check')) self.btn_check.clicked.connect(self.on_check) self.btn_check.setFixedHeight(35) self.btn_check.setMaximumWidth(80) self.btn_check.setEnabled(False) hbox_accounts.addWidget(self.btn_check) vbox.addWidget(group_accounts) # ####################### # vbox_login = QVBoxLayout() group_login = QGroupBox(_('Login:'******'Server:')) #label_server.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) label_user = QLabel(_('Username:'******'Password:'******'Add')) btn_add.clicked.connect(self.on_add) btn_add.setFixedHeight(35) btn_add.setMaximumWidth(80) if not self.cb.count(): btn_add.setEnabled(False) hbox_add.addStretch(0) hbox_add.addWidget(btn_add) vbox_login.addLayout(hbox_add) vbox.addWidget(group_login) # ####################### # vbox.addSpacing(20) hbox_btns = QHBoxLayout() hbox_btns.addStretch() btn_accept = QPushButton(_('Close')) btn_accept.clicked.connect(self.accept) btn_accept.setDefault(True) btn_accept.setFixedHeight(35) btn_accept.setMaximumWidth(80) hbox_btns.addWidget(btn_accept) vbox.addLayout(hbox_btns) # ####################### # #self.tree_view.selectionModel().selectionChanged.connect(self.on_selected) self.load_accounts() self.timer = parent.idle_timeout(1000, self.update_) #self.show() self.exec_() self.deleteLater() def get_selected_row(self): """""" selected_row = self.tree_view.selectionModel().selectedRows()[0].row() return selected_row #def on_selected(self, selected, unselected): #"""""" #todo: heredar treeView y subclass selectionChanged #row = self.get_selected_row() #self.btn_remove.setEnabled(True) #self.btn_check.setEnabled(True) def load_accounts(self): accounts_list = [account for service, accounts in sorted(accounts_manager.accounts_dict.iteritems()) for account in accounts.itervalues()] for account in accounts_list: password = "".join(["*" for _ in account.password]) self.__model.append([account.id_account, account.host, account.status, account.username, password, account.enable]) #TODO: Automatic accounts checking on load. def on_add(self): username = self.entry_user.text() password = self.entry_pass.text() if username and password: accounts_manager.new_account(self.cb.currentText(), username, password) self.__model.clear() self.load_accounts() def on_remove(self): row = self.get_selected_row() accounts_manager.remove_account(self.items[row][HOST], self.items[row][ACCOUNT_ID]) self.__model.remove(row) def on_check(self): row = self.get_selected_row() accounts_manager.manual_checking(self.items[row][HOST], self.items[row][ACCOUNT_ID]) def update_(self): account_list = accounts_manager.update() for account_item in account_list: for row in self.items: if row[ACCOUNT_ID] == account_item.id_account: row[STATUS] = account_item.status def save(self): for row in self.items: if row[ENABLE]: accounts_manager.enable_account(row[HOST], row[ACCOUNT_ID]) else: accounts_manager.disable_account(row[HOST], row[ACCOUNT_ID]) def accept(self, *args, **kwargs): self.timer.stop() self.save() self.hide() QDialog.accept(self, *args, **kwargs) def reject(self, *args, **kwargs): self.timer.stop() self.save() self.hide() QDialog.reject(self, *args, **kwargs)
class AddDownloads(QVBoxLayout): def __init__(self, parent): QVBoxLayout.__init__(self) self.setContentsMargins(0, 0, 0, 0) self.setSpacing(5) self.weak_parent = weakref.ref(parent) self.tree_view = QTreeView() self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_view.customContextMenuRequested.connect(self.context_menu) #listview look self.tree_view.setWordWrap(True) #search textElideMode self.tree_view.setRootIsDecorated(False) self.tree_view.setIndentation(0) self.tree_view.setAlternatingRowColors(True) self.icons_dict = self.get_icons() self.items = [] self.rows_buffer = {} #{id_item: row_obj, } bool_cols = [1, ] image_cols = [2, ] headers = ["hidden_id_item", "", "", _("File Name"), _("Host"), _("Size"), _("Status Message")] self.__model = SimpleListModel(headers, self.items, bool_cols, image_cols) self.tree_view.setModel(self.__model) self.addWidget(self.tree_view) self.tree_view.setColumnHidden(0, True) self.tree_view.setColumnWidth(1, 27) self.tree_view.setColumnWidth(2, 27) self.tree_view.header().setResizeMode(1, QHeaderView.Fixed) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(10) self.cb = QComboBox() #self.cb.setFixedWidth(100) self.cb.setEditable(True) self.cb.setFixedHeight(35) self.cb.setMinimumWidth(1) cb_view = self.cb.view() cb_view.setAlternatingRowColors(True) self.paths_list = conf.get_save_dl_paths() if not self.paths_list: self.cb.addItem(cons.DLFOLDER_PATH) else: [self.cb.addItem(path) for path in reversed(self.paths_list)] hbox.addWidget(self.cb) btn_examine = QPushButton('...') btn_examine.clicked.connect(self.on_examine) btn_examine.setFixedHeight(35) btn_examine.setMaximumWidth(80) hbox.addWidget(btn_examine) hbox.addSpacing(40) #index, size btn_download = QPushButton() btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM)) btn_download.setIconSize(QSize(24, 24)) btn_download.clicked.connect(self.on_download_selected) btn_download.setFixedHeight(35) btn_download.setMaximumWidth(40) hbox.addWidget(btn_download) btn_add = QPushButton() btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM)) btn_add.setIconSize(QSize(24, 24)) btn_add.clicked.connect(self.on_add_links) btn_add.setFixedHeight(35) btn_add.setMaximumWidth(40) hbox.addWidget(btn_add) self.menu = QMenu() import_action = self.menu.addAction(_("Import Container"), self.on_import_container) self.menu.addSeparator() recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck) clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list) btn_menu = QPushButton() btn_menu.setMenu(self.menu) btn_menu.setFixedHeight(35) btn_menu.setMaximumWidth(22) btn_menu.setFlat(True) hbox.addWidget(btn_menu) self.addLayout(hbox) #custom signals signals.add_downloads_to_check.connect(self.add_downloads_to_check) #update list self.timer = parent.idle_timeout(1000, self.update_) @property def parent(self): return self.weak_parent() def get_selected_rows(self): """""" selected_rows = [index.row() for index in self.tree_view.selectionModel().selectedRows()] selected_rows.sort() return selected_rows def context_menu(self, position): rows = self.get_selected_rows() is_single_row = True if len(rows) == 1 else False options = [(_('Save as...'), self.on_save_as, is_single_row), None, (_('Download Selected'), self.on_download_selected, True), None, (_('Select all'), self.on_select_all, True), (_('Select none'), self.on_select_none, True), (_('Select inverse'), self.on_select_inverse, True), None, (_('Re-check'), self.on_recheck, True), (_('Clear list'), self.on_clear_list, True)] menu = Menu(options) menu.exec_(self.tree_view.viewport().mapToGlobal(position)) def on_save_as(self): rows = self.get_selected_rows() row = self.items[rows[0]] item_id = row[0] download_item = api.get_checking_download_item(item_id) widget = QLineEdit() # set the line entry file name if we have one. if download_item.save_as: widget.setText(download_item.save_as) elif download_item.name != cons.UNKNOWN: widget.setText(download_item.name) dialog = Dialog(self.parent, "Save as", widget) if dialog.result() == QDialog.Accepted: save_as = widget.text() # change the file name in treeview and DownloadItem if save_as: api.save_download_as(download_item, save_as) api.set_download_name(download_item, save_as) row[3] = save_as def on_clear_list(self): self.__model.clear() self.rows_buffer.clear() api.clear_pending() def on_recheck(self): api.recheck_items() def on_select_all(self): for row in self.items: row[1] = True def on_select_none(self): for row in self.items: row[1] = False def on_select_inverse(self): for row in self.items: row[1] = False if row[1] else True def on_import_container(self): file_name, filter = QFileDialog.getOpenFileName(filter='OCH Files (*.och)') if file_name: container = Container(file_name) container.extract_links() links_list = container.get_linklist() if links_list: self.add_downloads_to_check(links_list, copy_link=False) def on_add_links(self): dialog = AddLinks(self.parent) result_code = dialog.result() links_list = dialog.links_list if result_code == QDialog.Accepted and links_list: self.add_downloads_to_check(links_list) def on_examine(self): folder = QFileDialog.getExistingDirectory() if folder: self.cb.setEditText(folder) def cb_remove(self, text): index = self.cb.findText(text) if index >= 0: self.cb.removeItem(index) def on_download_selected(self): # save the selected path current_path = self.cb.currentText() self.cb_remove(current_path) self.cb.insertItem(0, current_path) if current_path in self.paths_list: self.paths_list.remove(current_path) self.paths_list.append(current_path) if len(self.paths_list) > 5: self.paths_list.pop(0) self.cb.removeItem(5) self.cb.setCurrentIndex(0) conf.set_save_dl_paths(self.paths_list) # move selected items to downloads tab id_items_list = [] iters = [] for row in self.items: if row[1]: iters.append(row) id_item = row[0] id_items_list.append(id_item) del self.rows_buffer[id_item] [self.__model.remove(self.items.index(iter)) for iter in iters] item_list = api.pop_checking_items(id_items_list) for download_item in item_list: download_item.path = current_path signals.add_to_downloader.emit(item_list) def add_downloads_to_check(self, links_list, copy_link=True): for link in links_list: download_item = api.create_download_item(cons.UNKNOWN, link, copy_link=copy_link) api.add_to_checker(download_item) item = [download_item.id, True, self.icons_dict[cons.LINK_CHECKING], cons.UNKNOWN, None, None, None] #self.items.append(item) self.__model.append(item) self.rows_buffer[item[0]] = item api.start_checking() def update_(self): checking_downloads = api.get_checking_downloads() api.update_checking_downloads() for download_item in checking_downloads.itervalues(): row = self.rows_buffer[download_item.id] if download_item.link_status == cons.LINK_DEAD: row[1] = False row[2] = self.icons_dict[download_item.link_status] row[3] = download_item.name if not download_item.host == cons.UNSUPPORTED: row[4] = download_item.host if download_item.size: row[5] = utils.size_format(download_item.size) row[6] = download_item.link_status_msg self.__model.refresh() def get_icons(self): alive = media.get_pixmap(media.ALIVE, media.SMALL) dead = media.get_pixmap(media.DEAD, media.SMALL) error = media.get_pixmap(media.ERROR, media.SMALL) checking = media.get_pixmap(media.CHECKING, media.SMALL) #unavailable = media.get_pixmap(media.ERROR, media.SMALL) return {cons.LINK_ALIVE: alive, cons.LINK_DEAD: dead, cons.LINK_UNAVAILABLE: error, cons.LINK_ERROR: error, cons.LINK_CHECKING: checking}
class ConfigAccounts(QDialog): def __init__(self, parent): QDialog.__init__(self, parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.setWindowTitle(_('Host Accounts')) self.resize(500, 450) vbox = QVBoxLayout() self.setLayout(vbox) # ####################### # vbox_accounts = QVBoxLayout() group_accounts = QGroupBox(_('Accounts:')) group_accounts.setLayout(vbox_accounts) self.tree_view = QTreeView() # #listview look self.tree_view.setWordWrap(True) #search textElideMode self.tree_view.setRootIsDecorated(False) self.tree_view.setIndentation(0) self.tree_view.setAlternatingRowColors(True) # self.items = [] headers = [ "hidden_id_account", _("Host"), _("Status"), _("Username"), _("Password"), _("Enable") ] bool_cols = [ ENABLE, ] # self.__model = SimpleListModel(headers, self.items, bool_cols) self.tree_view.setModel(self.__model) vbox_accounts.addWidget(self.tree_view) self.tree_view.setColumnHidden(0, True) hbox_accounts = QHBoxLayout() hbox_accounts.addStretch(0) #stretch/align widget to right. vbox_accounts.addLayout(hbox_accounts) self.btn_remove = QPushButton(_('Remove')) self.btn_remove.clicked.connect(self.on_remove) self.btn_remove.setFixedHeight(35) self.btn_remove.setMaximumWidth(80) self.btn_remove.setEnabled(False) hbox_accounts.addWidget(self.btn_remove) self.btn_check = QPushButton(_('Check')) self.btn_check.clicked.connect(self.on_check) self.btn_check.setFixedHeight(35) self.btn_check.setMaximumWidth(80) self.btn_check.setEnabled(False) hbox_accounts.addWidget(self.btn_check) vbox.addWidget(group_accounts) # ####################### # vbox_login = QVBoxLayout() group_login = QGroupBox(_('Login:'******'Server:')) #label_server.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) label_user = QLabel(_('Username:'******'Password:'******'Add')) btn_add.clicked.connect(self.on_add) btn_add.setFixedHeight(35) btn_add.setMaximumWidth(80) if not self.cb.count(): btn_add.setEnabled(False) hbox_add.addStretch(0) hbox_add.addWidget(btn_add) vbox_login.addLayout(hbox_add) vbox.addWidget(group_login) # ####################### # vbox.addSpacing(20) hbox_btns = QHBoxLayout() hbox_btns.addStretch() btn_accept = QPushButton(_('Close')) btn_accept.clicked.connect(self.accept) btn_accept.setDefault(True) btn_accept.setFixedHeight(35) btn_accept.setMaximumWidth(80) hbox_btns.addWidget(btn_accept) vbox.addLayout(hbox_btns) # ####################### # #self.tree_view.selectionModel().selectionChanged.connect(self.on_selected) self.load_accounts() self.timer = parent.idle_timeout(1000, self.update_) #self.show() self.exec_() self.deleteLater() def get_selected_row(self): """""" selected_row = self.tree_view.selectionModel().selectedRows()[0].row() return selected_row #def on_selected(self, selected, unselected): #"""""" #todo: heredar treeView y subclass selectionChanged #row = self.get_selected_row() #self.btn_remove.setEnabled(True) #self.btn_check.setEnabled(True) def load_accounts(self): accounts_list = [ account for service, accounts in sorted( accounts_manager.accounts_dict.iteritems()) for account in accounts.itervalues() ] for account in accounts_list: password = "".join(["*" for _ in account.password]) self.__model.append([ account.id_account, account.host, account.status, account.username, password, account.enable ]) #TODO: Automatic accounts checking on load. def on_add(self): username = self.entry_user.text() password = self.entry_pass.text() if username and password: accounts_manager.new_account(self.cb.currentText(), username, password) self.__model.clear() self.load_accounts() def on_remove(self): row = self.get_selected_row() accounts_manager.remove_account(self.items[row][HOST], self.items[row][ACCOUNT_ID]) self.__model.remove(row) def on_check(self): row = self.get_selected_row() accounts_manager.manual_checking(self.items[row][HOST], self.items[row][ACCOUNT_ID]) def update_(self): account_list = accounts_manager.update() for account_item in account_list: for row in self.items: if row[ACCOUNT_ID] == account_item.id_account: row[STATUS] = account_item.status def save(self): for row in self.items: if row[ENABLE]: accounts_manager.enable_account(row[HOST], row[ACCOUNT_ID]) else: accounts_manager.disable_account(row[HOST], row[ACCOUNT_ID]) def accept(self, *args, **kwargs): self.timer.stop() self.save() self.hide() QDialog.accept(self, *args, **kwargs) def reject(self, *args, **kwargs): self.timer.stop() self.save() self.hide() QDialog.reject(self, *args, **kwargs)
class AddDownloads(QVBoxLayout): def __init__(self, downloads, parent=None): QVBoxLayout.__init__(self) self.setContentsMargins(0, 0, 0, 0) self.setSpacing(5) self.downloads = downloads self.parent = parent self.tree_view = QTreeView(parent) # self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_view.customContextMenuRequested.connect(self.context_menu) # #listview look self.tree_view.setWordWrap(True) #search textElideMode self.tree_view.setRootIsDecorated(False) self.tree_view.setIndentation(0) self.tree_view.setAlternatingRowColors(True) # self.items = [] self.rows_buffer = {} #{id_item: row_obj, } #self.items = [[True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"], [True, "1", "11", "t5est", "t3est"]] bool_cols = [1, ] headers = ["hidden_id_item", "", _("Status"), _("File Name"), _("Host"), _("Size"), _("Status Message")] # self.__model = SimpleListModel(headers, self.items, bool_cols) self.tree_view.setModel(self.__model) self.addWidget(self.tree_view) # self.tree_view.setColumnHidden(0, True) self.tree_view.setColumnWidth(1, 27) self.tree_view.header().setResizeMode(1, QHeaderView.Fixed) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(10) self.cb = QComboBox() #self.cb.setFixedWidth(100) self.cb.setEditable(True) self.cb.setFixedHeight(35) self.cb.setMinimumWidth(1) cb_view = self.cb.view() cb_view.setAlternatingRowColors(True) # self.paths_list = conf.get_save_dl_paths() if not self.paths_list: self.cb.addItem(cons.DLFOLDER_PATH) else: [self.cb.addItem(path) for path in reversed(self.paths_list)] # hbox.addWidget(self.cb) btn_examine = QPushButton('...') btn_examine.clicked.connect(self.on_examine) btn_examine.setFixedHeight(35) btn_examine.setMaximumWidth(80) hbox.addWidget(btn_examine) hbox.addSpacing(40) #index, size btn_download = QPushButton() btn_download.setIcon(media.get_icon(media.DOWN, media.MEDIUM)) btn_download.setIconSize(QSize(24, 24)) btn_download.clicked.connect(self.on_download_selected) btn_download.setFixedHeight(35) btn_download.setMaximumWidth(40) hbox.addWidget(btn_download) btn_add = QPushButton() btn_add.setIcon(media.get_icon(media.ADD, media.MEDIUM)) btn_add.setIconSize(QSize(24, 24)) btn_add.clicked.connect(self.on_add_links) btn_add.setFixedHeight(35) btn_add.setMaximumWidth(40) hbox.addWidget(btn_add) self.menu = QMenu(parent) import_action = self.menu.addAction(_("Import Container"), self.on_import_container) self.menu.addSeparator() recheck_action = self.menu.addAction(_("Re-check"), self.on_recheck) clear_action = self.menu.addAction(_("Clear list"), self.on_clear_list) # btn_menu = QPushButton() btn_menu.setMenu(self.menu) btn_menu.setFixedHeight(35) btn_menu.setMaximumWidth(22) btn_menu.setFlat(True) hbox.addWidget(btn_menu) self.addLayout(hbox) #update list parent.idle_timeout(1000, self.update) def context_menu(self, position): menu = QMenu() #indexes = self.selectedIndexes() #sensitive = True if indexes else False #individual_items = [('Open destination folder', self.on_open_folder),] #[menu.addAction(title, callback).setEnabled(sensitive) for title, callback in individual_items] #menu.addSeparator() generic_items = [(_('Download Selected'), self.on_download_selected), (None, None), (_('Select all'), self.on_select_all), (_('Select none'), self.on_select_none), (_('Select inverse'), self.on_select_inverse), (None, None), (_('Re-check'), self.on_recheck), (_('Clear list'), self.on_clear_list)] [menu.addAction(title, callback) if title is not None else menu.addSeparator() for title, callback in generic_items] menu.exec_(self.tree_view.viewport().mapToGlobal(position)) def on_clear_list(self): self.__model.clear() self.rows_buffer.clear() api.clear_pending() def on_recheck(self): api.recheck_items() def on_select_all(self): for row in self.items: row[1] = True def on_select_none(self): for row in self.items: row[1] = False def on_select_inverse(self): for row in self.items: row[1] = False if row[1] else True def on_import_container(self): file_name, filter = QFileDialog.getOpenFileName(filter='OCH Files (*.och)') if file_name: container = Container(file_name) container.extract_links() links_list = container.get_linklist() if links_list: self.links_checking(links_list, copy_link=False) def on_add_links(self): add_links = AddLinks(self.parent) result_code = add_links.result() links_list = add_links.links_list if result_code == QDialog.Accepted and links_list: self.links_checking(links_list) def on_examine(self): folder = QFileDialog.getExistingDirectory() if folder: self.cb.setEditText(folder) def cb_remove(self, text): index = self.cb.findText(text) if index >= 0: self.cb.removeItem(index) def on_download_selected(self): current_path = self.cb.currentText() self.cb_remove(current_path) self.cb.insertItem(0, current_path) if current_path in self.paths_list: self.paths_list.remove(current_path) self.paths_list.append(current_path) if len(self.paths_list) > 5: self.paths_list.pop(0) self.cb.removeItem(5) self.cb.setCurrentIndex(0) conf.set_save_dl_paths(self.paths_list) id_items_list = [] iters = [] for row in self.items: if row[1]: # and row[4] != cons.UNSUPPORTED: #tmp iters.append(row) id_item = row[0] id_items_list.append(id_item) del self.rows_buffer[id_item] [self.__model.remove(self.items.index(iter)) for iter in iters] item_list = api.get_added_items(id_items_list) api.downloader_init(item_list, current_path) #iniciar threads de descarga. #TODO: use a signal. self.downloads.store_items(item_list) def links_checking(self, links_list, copy_link=True): for link in links_list: download_item = api.create_download_item(cons.UNKNOWN, 0, link, copy_link) #return download_item object item = [download_item.id, True, cons.LINK_CHECKING, cons.UNKNOWN, None, None, None] #self.items.append(item) self.__model.append(item) self.rows_buffer[item[0]] = item api.start_checking() def update(self): #this method steals cycles, its not a new thread items_list = api.get_checking_update() for download_item in items_list: try: row = self.rows_buffer[download_item.id] row[1] = True if download_item.link_status != cons.LINK_DEAD else False row[2] = download_item.link_status row[3] = download_item.name row[4] = download_item.host row[5] = misc.size_format(download_item.size) row[6] = download_item.link_status_msg except KeyError as err: logger.debug(err) self.__model.refresh()