def display_series(self):
        """Retrieves and displays info for selected series.

        This function retrieves the unique rowid for the selected
        series and retrieves the series from the database. It then
        updates all main window elements which show series info to
        show up-to-date properties. Once all series information is
        properly displayed, buttons which can change the selected
        series's properties are enabled.

        """
        data_mgr = DatabaseManager(Config().database_name, None)
        if self.list_series.currentItem():
            series_rowid = self.list_series.currentItem().data(Qt.UserRole)
            cur = data_mgr.query("SELECT rowid, * FROM Series WHERE rowid = %d"
                                 % series_rowid)
            series = entry_to_series(cur.fetchone())

            if series:
                self.list_series.currentItem().setText(series.compact_string())
                self.table_setup(series)
                self.edit_series_button.setEnabled(True)
                self.remove_series_button.setEnabled(True)
                self.add_next_volume_button.setEnabled(True)
                self.mark_as_completed_button.setEnabled(True)
    def get_list_items(self):
        """Retrieves all series from database and populates list in main window.

        Populates the list in the main window with the compact_string()
        representations of all the series in the database, sorting by the
        given property (default "name") and placing any series with an
        unknown value for that property at the end of the list

        """
        order = self.get_list_order()
        data_mgr = DatabaseManager(Config().database_name, None)
        cur = data_mgr.query("SELECT rowid, * FROM Series ORDER BY %s "
                             "COLLATE NOCASE ASC, name ASC;" % order)
        entries = cur.fetchall()
        unknown_entries = []
        selected_series = None
        selected_series_found = False

        if self.list_series.currentItem():
            selected_series = self.list_series.currentItem().data(Qt.UserRole)
        if hasattr(self, "add_window") and self.add_window.added > -1:
            selected_series = self.add_window.added
            self.add_window.added = -1

        self.list_series.clear()
        for entry in entries:
            if entry[SI[order.upper()]] in ["Unknown", ""]:
                unknown_entries.append(entry)
                continue
            series = entry_to_series(entry)

            # Check if any filters are selected.
            if not self.check_filters(series):
                continue

            series_item = QListWidgetItem(series.compact_string())
            series_item.setData(Qt.UserRole, series.rowid)
            self.list_series.addItem(series_item)
            if selected_series and selected_series == series.rowid:
                self.list_series.setCurrentItem(series_item)
                selected_series_found = True

        for entry in unknown_entries:
            series = entry_to_series(entry)
            series_item = QListWidgetItem(series.compact_string())
            series_item.setData(Qt.UserRole, series.rowid)
            self.list_series.addItem(series_item)
            if selected_series and selected_series == series.rowid:
                self.list_series.setCurrentItem(series_item)
                selected_series_found = True

        # If previous series item no longer exists, select first entry in list
        if selected_series and not selected_series_found:
            self.list_series.setCurrentRow(0)

        if not self.list_series.currentItem():
            self.clear_table()

        self.filter_series_list()
 def toggle_is_completed(self):
     """Toggles completion status of selected series."""
     data_mgr = DatabaseManager(Config().database_name, None)
     if self.list_series.currentItem():
         series_rowid = self.list_series.currentItem().data(Qt.UserRole)
         cur = data_mgr.query("SELECT rowid, * FROM Series WHERE rowid = %d"
                              % series_rowid)
         series = entry_to_series(cur.fetchone())
         series.is_completed ^= 1
         series.update_database_entry(data_mgr)
         self.get_list_items()
 def add_next_volume(self):
     """Adds next volume to selected series."""
     data_mgr = DatabaseManager(Config().database_name, None)
     if self.list_series.currentItem():
         series_rowid = self.list_series.currentItem().data(Qt.UserRole)
         cur = data_mgr.query("SELECT rowid, * FROM Series WHERE rowid = %d"
                              % series_rowid)
         series = entry_to_series(cur.fetchone())
         if not series.is_completed:
             series.add_volumes(str(series.next_volume))
             series.update_database_entry(data_mgr)
             self.get_list_items()
    def __init__(self, rowid, item=None, parent=None):
        """Initializes edit window

        Retrieves series information from database and populates the
        table with the results for the user to edit.

        """
        super(MangaTrackerEditWindow, self).__init__(parent)
        self.setupUi(self)
        self.edit_series_save_button.clicked.connect(self.save_edit)
        self.edit_series_cancel_button.clicked.connect(self.close)
        self.rowid = rowid
        data_mgr = DatabaseManager(Config().database_name, None)
        cur = data_mgr.query("SELECT rowid, * FROM Series WHERE rowid = %d"
                             % rowid)
        self.series = entry_to_series(cur.fetchone())
        self.table_setup(self.series, item)
    def add_series(self):
        data_mgr = DatabaseManager(Config().database_name, None)
        series_args = {}
        for i in range(self.add_series_table.rowCount()):
            try:
                if self.add_series_table.item(i, 1).background() == Qt.red:
                    return
            except AttributeError:
                pass

            curr_heading = self.add_series_table.item(i, 0).text()
            try:
                curr_text = self.add_series_table.item(i, 1).text()
            except AttributeError:  # is_completed
                curr_text = (self.add_series_table.cellWidget(i, 1)
                             .currentText())

            if curr_heading == "Name":
                series_args['name'] = curr_text
                if series_args['name'] in ["", "Unknown"]:
                    self.add_series_table.item(i, 1).setBackground(Qt.red)
                    return
            elif curr_heading == "Alt. Names":
                series_args['alt_names'] = curr_text
            elif curr_heading == "Author":
                series_args['author'] = curr_text
            elif curr_heading == "Volumes Owned":
                if curr_text in ["None", "0", ""]:
                    series_args['volumes_owned'] = generate_volumes_owned("")
                else:
                    series_args['volumes_owned'] = generate_volumes_owned(
                        curr_text)
            elif curr_heading == "Publisher":
                series_args['publisher'] = curr_text
            elif curr_heading == "Completed":
                status = curr_text
                series_args['is_completed'] = 1 if status == "Yes" else 0

        new_series = Series(**series_args)

        if new_series.add_series_to_database(data_mgr):
            cur = data_mgr.query("SELECT rowid FROM series WHERE name='%s'"
                                 % series_args['name'].replace("'", "''"))
            self.added = cur.fetchone()[0]
            self.close()
    def validate_cells(self, item):
        if item.row() == 0:  # Name
            name = item.text()
            data_mgr = DatabaseManager(Config().database_name, None)
            cur = data_mgr.query("SELECT name FROM Series WHERE name = '{0}'"
                                 .format(name.replace("'", "''")))
            row = cur.fetchall()
            if row or name in ["", "Unknown"]:
                item.setBackground(Qt.red)
            else:
                item.setBackground(Qt.white)

        elif item.row() == 3:  # Volumes Owned
            volumes_owned_raw = item.text()
            pattern = r"^\d+(-\d+)?(,\s*\d+(-\d+)?)*\s*$"

            if (not regexp(pattern, volumes_owned_raw)
                    and volumes_owned_raw not in ["None", "0", ""]):
                item.setBackground(Qt.red)
            else:
                item.setBackground(Qt.white)
    def remove_series(self):
        """Remove selected series from database

        Removes the currently selected series from the database, after
        prompting the user for confirmation.

        """
        data_mgr = DatabaseManager(Config().database_name, None)
        if self.list_series.currentItem():
            series_rowid = self.list_series.currentItem().data(Qt.UserRole)
            cur = data_mgr.query("SELECT rowid, * FROM Series WHERE rowid = %d"
                                 % series_rowid)
            series = entry_to_series(cur.fetchone())
            confirm_dialog = QMessageBox.question(
                self, "Remove %s" % series.name,
                "Are you sure you want to remove this series?\n"
                "This can't be undone.",
                QMessageBox.Discard | QMessageBox.Cancel,
                QMessageBox.Cancel)
            if confirm_dialog == QMessageBox.Discard:
                remove_series_from_database(data_mgr, series)
                self.list_series.takeItem(self.list_series.currentRow())
                self.list_series.setFocus()
    def save_edit(self):
        """Saves changes to series object or discards them depending on user choice.

        Displays a dialog to the user asking if they want to save. If
        'save' is selected, all modified properties of the series are
        saved to the database and the edit window closes. If 'discard'
        is selected, the window closes without saving any changes. If
        'cancel' is selected, the dialog is closed and editing can
        continue.

        """
        reserved_words = ["unknown"]
        confirm_dialog = QMessageBox.question(
            self, "Save Changes",
            "Are you sure you want to save changes?\nThis cannot be undone.",
            QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel,
            QMessageBox.Cancel)

        if confirm_dialog == QMessageBox.Save:
            series_keys = ["name", "alt_names", "author",
                           "volumes_owned", "next_volume",
                           "publisher", "is_completed"]
            data_mgr = DatabaseManager(Config().database_name, None)

            for i in range(len(series_keys)):
                try:
                    new_data = self.edit_series_table.item(i, 1).text()
                except AttributeError:
                    new_data = (self.edit_series_table.cellWidget(i, 1)
                                .currentText())

                if series_keys[i] == "name":
                    if (new_data
                            and self.series.name != new_data
                            and new_data not in reserved_words):
                        cur = data_mgr.query("SELECT name FROM Series WHERE "
                                             "name = '{0}'"
                                             .format(new_data
                                                     .replace("'", "''")))
                        row = cur.fetchall()
                        if not row:
                            self.series.name = new_data

                elif series_keys[i] == "volumes_owned":
                    if new_data in ["None", "0", ""]:
                        new_data = generate_volumes_owned("")
                    else:
                        new_data = generate_volumes_owned(new_data)
                    self.series.volumes_owned = new_data
                    self.series.vol_arr = [int(x) for x in
                                           self.series.volumes_owned
                                           .split(',')]

                elif series_keys[i] == "next_volume":
                    self.series.next_volume = (self.series
                                               .calculate_next_volume())

                elif series_keys[i] == "is_completed":
                    if new_data in ["Yes", "yes", "Y", "y", 1]:
                        self.series.is_completed = 1
                    elif new_data in ["No", "no", "N", "n", 0]:
                        self.series.is_completed = 0

                else:
                    self.series.__dict__[series_keys[i]] = new_data

            self.series.update_database_entry(data_mgr)
            self.close()
        elif confirm_dialog == QMessageBox.Discard:
            self.close()