diff --git a/comicarchive.py b/comicarchive.py index 2ef037c..9913f70 100644 --- a/comicarchive.py +++ b/comicarchive.py @@ -440,9 +440,17 @@ class ComicArchive: def resetCache( self ): self.has_cix = None self.has_cbi = None + self.has_comet = None self.comet_filename = None self.page_count = None self.page_list = None + self.cix_md = None + self.cbi_md = None + self.comet_md = None + + def rename( self, path ): + self.path = path + self.archiver.path = path def setExternalRarProgram( self, rar_exe_path ): if self.isRar(): @@ -527,7 +535,6 @@ class ComicArchive: retcode = self.writeCBI( metadata ) elif style == MetaDataStyle.COMET: retcode = self.writeCoMet( metadata ) - self.resetCache() return retcode @@ -550,7 +557,6 @@ class ComicArchive: retcode = self.removeCBI() elif style == MetaDataStyle.COMET: retcode = self.removeCoMet() - self.resetCache() return retcode def getPage( self, index ): @@ -599,15 +605,16 @@ class ComicArchive: return self.page_count def readCBI( self ): - raw_cbi = self.readRawCBI() - if raw_cbi is None: - md = GenericMetadata() - else: - md = ComicBookInfo().metadataFromString( raw_cbi ) - - md.setDefaultPageList( self.getNumberOfPages() ) + if self.cbi_md is None: + raw_cbi = self.readRawCBI() + if raw_cbi is None: + self.cbi_md = GenericMetadata() + else: + self.cbi_md = ComicBookInfo().metadataFromString( raw_cbi ) + + self.cbi_md.setDefaultPageList( self.getNumberOfPages() ) - return md + return self.cbi_md def readRawCBI( self ): if ( not self.hasCBI() ): @@ -628,30 +635,49 @@ class ComicArchive: return self.has_cbi def writeCBI( self, metadata ): - self.applyArchiveInfoToMetadata( metadata ) - cbi_string = ComicBookInfo().stringFromMetadata( metadata ) - return self.archiver.setArchiveComment( cbi_string ) + if metadata is not None: + self.applyArchiveInfoToMetadata( metadata ) + cbi_string = ComicBookInfo().stringFromMetadata( metadata ) + write_success = self.archiver.setArchiveComment( cbi_string ) + if write_success: + self.has_cbi = True + self.cbi_md = metadata + else: + self.resetCache() + return write_success + else: + return False def removeCBI( self ): - return self.archiver.setArchiveComment( "" ) + if self.hasCBI(): + write_success = self.archiver.setArchiveComment( "" ) + if write_success: + self.has_cbi = False + self.cbi_md = None + else: + self.resetCache() + return write_success + return True def readCIX( self ): - raw_cix = self.readRawCIX() - if raw_cix is None: - md = GenericMetadata() - else: - md = ComicInfoXml().metadataFromString( raw_cix ) + if self.cix_md is None: + raw_cix = self.readRawCIX() + if raw_cix is None: + self.cix_md = GenericMetadata() + else: + self.cix_md = ComicInfoXml().metadataFromString( raw_cix ) - #validate the existing page list (make sure count is correct) - if len ( md.pages ) != 0 : - if len ( md.pages ) != self.getNumberOfPages(): - # pages array doesn't match the actual number of images we're seeing - # in the archive, so discard the data - md.pages = [] + #validate the existing page list (make sure count is correct) + if len ( self.cix_md.pages ) != 0 : + if len ( self.cix_md.pages ) != self.getNumberOfPages(): + # pages array doesn't match the actual number of images we're seeing + # in the archive, so discard the data + self.cix_md.pages = [] + + if len( self.cix_md.pages ) == 0: + self.cix_md.setDefaultPageList( self.getNumberOfPages() ) - if len( md.pages ) == 0: - md.setDefaultPageList( self.getNumberOfPages() ) - return md + return self.cix_md def readRawCIX( self ): if not self.hasCIX(): @@ -664,13 +690,27 @@ class ComicArchive: if metadata is not None: self.applyArchiveInfoToMetadata( metadata, calc_page_sizes=True ) cix_string = ComicInfoXml().stringFromMetadata( metadata ) - return self.archiver.writeArchiveFile( self.ci_xml_filename, cix_string ) + write_success = self.archiver.writeArchiveFile( self.ci_xml_filename, cix_string ) + if write_success: + self.has_cix = True + self.cix_md = metadata + else: + self.resetCache() + return write_success else: return False def removeCIX( self ): - - return self.archiver.removeArchiveFile( self.ci_xml_filename ) + if self.hasCIX(): + write_success = self.archiver.removeArchiveFile( self.ci_xml_filename ) + if write_success: + self.has_cix = False + self.cix_md = None + else: + self.resetCache() + return write_success + return True + def hasCIX(self): if self.has_cix is None: @@ -685,28 +725,28 @@ class ComicArchive: def readCoMet( self ): - raw_comet = self.readRawCoMet() - if raw_comet is None: - md = GenericMetadata() - else: - md = CoMet().metadataFromString( raw_comet ) - - md.setDefaultPageList( self.getNumberOfPages() ) - #use the coverImage value from the comet_data to mark the cover in this struct - # walk through list of images in file, and find the matching one for md.coverImage - # need to remove the existing one in the default - if md.coverImage is not None: - cover_idx = 0 - for idx,f in enumerate(self.getPageNameList()): - if md.coverImage == f: - cover_idx = idx - break - if cover_idx != 0: - del (md.pages[0]['Type'] ) - md.pages[ cover_idx ]['Type'] = PageType.FrontCover - - - return md + if self.comet_md is None: + raw_comet = self.readRawCoMet() + if raw_comet is None: + self.comet_md = GenericMetadata() + else: + self.comet_md = CoMet().metadataFromString( raw_comet ) + + self.comet_md.setDefaultPageList( self.getNumberOfPages() ) + #use the coverImage value from the comet_data to mark the cover in this struct + # walk through list of images in file, and find the matching one for md.coverImage + # need to remove the existing one in the default + if self.comet_md.coverImage is not None: + cover_idx = 0 + for idx,f in enumerate(self.getPageNameList()): + if self.comet_md.coverImage == f: + cover_idx = idx + break + if cover_idx != 0: + del (self.comet_md.pages[0]['Type'] ) + self.comet_md.pages[ cover_idx ]['Type'] = PageType.FrontCover + + return self.comet_md def readRawCoMet( self ): if not self.hasCoMet(): @@ -728,24 +768,34 @@ class ComicArchive: metadata.coverImage = self.getPageName( cover_idx ) comet_string = CoMet().stringFromMetadata( metadata ) - return self.archiver.writeArchiveFile( self.comet_filename, comet_string ) + write_success = self.archiver.writeArchiveFile( self.comet_filename, comet_string ) + if write_success: + self.has_comet = True + self.comet_md = metadata + else: + self.resetCache() + return write_success else: return False def removeCoMet( self ): if self.hasCoMet(): - retcode = self.archiver.removeArchiveFile( self.comet_filename ) - self.comet_filename = None - return retcode + write_success = self.archiver.removeArchiveFile( self.comet_filename ) + if write_success: + self.has_comet = False + self.comet_md = None + else: + self.resetCache() + return write_success return True def hasCoMet(self): - if not self.seemsToBeAComicArchive(): - return False - - #Use the existence of self.comet_filename as a cue that the tag block exists - if self.comet_filename is None: - #TODO look at all xml files in root, and search for CoMet data, get first + if self.has_comet is None: + self.has_comet = False + if not self.seemsToBeAComicArchive(): + return self.has_comet + + #look at all xml files in root, and search for CoMet data, get first for n in self.archiver.getArchiveFilenameList(): if ( os.path.dirname(n) == "" and os.path.splitext(n)[1].lower() == '.xml'): @@ -754,12 +804,12 @@ class ComicArchive: if CoMet().validateString( data ): # since we found it, save it! self.comet_filename = n - return True - # if we made it through the loop, no CoMet here... - return False - - else: - return True + self.has_comet = True + break + + return self.has_comet + + def applyArchiveInfoToMetadata( self, md, calc_page_sizes=False): md.pageCount = self.getNumberOfPages() diff --git a/fileselectionlist.py b/fileselectionlist.py index 86ae001..7a165c3 100644 --- a/fileselectionlist.py +++ b/fileselectionlist.py @@ -49,10 +49,7 @@ class FileTableWidgetItem(QTableWidgetItem): class FileInfo( ): - def __init__(self, path, ca, cix_md, cbi_md ): - self.path = path - self.cix_md = cix_md - self.cbi_md = cbi_md + def __init__(self, ca ): self.ca = ca class FileSelectionList(QWidget): @@ -70,9 +67,12 @@ class FileSelectionList(QWidget): #gridlayout = QGridLayout( self ) #gridlayout.addWidget( self.twList ) - self.twList.itemSelectionChanged.connect( self.itemSelectionChangedCB ) + #self.twList.itemSelectionChanged.connect( self.itemSelectionChangedCB ) + self.twList.currentItemChanged.connect( self.currentItemChangedCB ) + self.currentItem = None self.setContextMenuPolicy(Qt.ActionsContextMenu) + self.modifiedFlag = False selectAllAction = QAction("Select All", self) invertSelectionAction = QAction("Invert Selection", self) @@ -84,8 +84,14 @@ class FileSelectionList(QWidget): self.addAction(selectAllAction) self.addAction(removeAction) + def setModifiedFlag( self, modified ): + self.modifiedFlag = modified + def selectAll( self ): self.twList.setRangeSelected( QTableWidgetSelectionRange ( 0, 0, self.twList.rowCount()-1, 1 ), True ) + + def deselectAll( self ): + self.twList.setRangeSelected( QTableWidgetSelectionRange ( 0, 0, self.twList.rowCount()-1, 1 ), False ) def removeSelection( self ): row_list = [] @@ -96,6 +102,11 @@ class FileSelectionList(QWidget): if len(row_list) == 0: return + if self.twList.currentRow() in row_list: + if not self.modifiedFlagVerification( "Remove Archive", + "If you close this archive, data in the form will be lost. Are you sure?"): + return + row_list.sort() row_list.reverse() @@ -153,7 +164,7 @@ class FileSelectionList(QWidget): r = 0 while r < self.twList.rowCount(): fi = self.twList.item(r, 0).data( Qt.UserRole ).toPyObject() - if fi.path == path: + if fi.ca.path == path: return True r = r + 1 @@ -175,71 +186,119 @@ class FileSelectionList(QWidget): row = self.twList.rowCount() self.twList.insertRow( row ) - cix_md = None - cbi_md = None + fi = FileInfo( ca ) - has_cix = ca.hasCIX() - if has_cix: - cix_md = ca.readCIX() + filename_item = QTableWidgetItem() + folder_item = QTableWidgetItem() + cix_item = QTableWidgetItem() + cbi_item = QTableWidgetItem() - has_cbi = ca.hasCBI() - if has_cbi: - cbi_md = ca.readCBI() - - fi = FileInfo( path, ca, cix_md, cbi_md ) - - item_text = os.path.split(path)[1] - item = QTableWidgetItem(item_text) - item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) - item.setData( Qt.UserRole , fi ) - item.setData( Qt.ToolTipRole ,item_text) - self.twList.setItem(row, 0, item) - - item_text = os.path.split(path)[0] - item = QTableWidgetItem(item_text) - item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) - item.setData( Qt.ToolTipRole ,item_text) - self.twList.setItem(row, 1, item) + filename_item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) + filename_item.setData( Qt.UserRole , fi ) + self.twList.setItem(row, 0, filename_item) + + folder_item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) + self.twList.setItem(row, 1, folder_item) - # Attempt to use a special checkbox widget in the cell. - # Couldn't figure out how to disable it with "enabled" colors - #w = QWidget() - #cb = QCheckBox(w) - #cb.setCheckState(Qt.Checked) - #layout = QHBoxLayout() - #layout.addWidget( cb ) - #layout.setAlignment(Qt.AlignHCenter) - #layout.setMargin(2) - #w.setLayout(layout) - #self.twList.setCellWidget( row, 2, w ) + cix_item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) + cix_item.setTextAlignment(Qt.AlignHCenter) + self.twList.setItem(row, 2, cix_item) - item = FileTableWidgetItem() - item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) - item.setTextAlignment(Qt.AlignHCenter) - if has_cix: - item.setCheckState(Qt.Checked) - item.setData(Qt.UserRole, True) - else: - item.setData(Qt.UserRole, False) - self.twList.setItem(row, 2, item) - - item = FileTableWidgetItem() - item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) - item.setTextAlignment(Qt.AlignHCenter) - if has_cbi: - item.setCheckState(Qt.Checked) - item.setData(Qt.UserRole, True) - else: - item.setData(Qt.UserRole, False) - self.twList.setItem(row, 3, item) + cbi_item.setFlags(Qt.ItemIsSelectable| Qt.ItemIsEnabled) + cbi_item.setTextAlignment(Qt.AlignHCenter) + self.twList.setItem(row, 3, cbi_item) + + self.updateRow( row ) + return row + + def updateRow( self, row ): + fi = self.twList.item( row, 0 ).data( Qt.UserRole ).toPyObject() + + filename_item = self.twList.item( row, 0 ) + folder_item = self.twList.item( row, 1 ) + cix_item = self.twList.item( row, 2 ) + cbi_item = self.twList.item( row, 3 ) + + item_text = os.path.split(fi.ca.path)[0] + folder_item.setText( item_text ) + folder_item.setData( Qt.ToolTipRole, item_text ) + + item_text = os.path.split(fi.ca.path)[1] + filename_item.setText( item_text ) + filename_item.setData( Qt.ToolTipRole, item_text ) + + if fi.ca.hasCIX(): + cix_item.setCheckState(Qt.Checked) + cix_item.setData(Qt.UserRole, True) + else: + cix_item.setData(Qt.UserRole, False) + cix_item.setCheckState(Qt.Unchecked) + + if fi.ca.hasCBI(): + cbi_item.setCheckState(Qt.Checked) + cbi_item.setData(Qt.UserRole, True) + else: + cbi_item.setData(Qt.UserRole, False) + cbi_item.setCheckState(Qt.Unchecked) - def itemSelectionChangedCB( self ): - idx = self.twList.currentRow() - - fi = self.twList.item(idx, 0).data( Qt.UserRole ).toPyObject() - - #if fi.cix_md is not None: - # print u"{0}".format(fi.cix_md) + # Reading these will force them into the ComicArchive's cache + fi.ca.readCIX() + fi.ca.hasCBI() + + def updateCurrentRow( self ): + self.updateRow( self.twList.currentRow() ) + + def currentItemChangedCB( self, curr, prev ): + + new_idx = curr.row() + old_idx = -1 + if prev is not None: + old_idx = prev.row() + #print "old {0} new {1}".format(old_idx, new_idx) + + if old_idx == new_idx: + return + + # don't allow change if modified + if prev is not None and new_idx != old_idx: + if not self.modifiedFlagVerification( "Change Archive", + "If you change archives now, data in the form will be lost. Are you sure?"): + self.twList.currentItemChanged.disconnect( self.currentItemChangedCB ) + self.twList.setCurrentItem( prev ) + self.twList.currentItemChanged.connect( self.currentItemChangedCB ) + # Need to defer this revert selection, for some reason + QTimer.singleShot(1, self.revertSelection) + return + + fi = self.twList.item( new_idx, 0 ).data( Qt.UserRole ).toPyObject() self.selectionChanged.emit( QVariant(fi)) + + def revertSelection( self ): + self.twList.selectRow( self.twList.currentRow() ) + + + def modifiedFlagVerification( self, title, desc): + if self.modifiedFlag: + reply = QMessageBox.question(self, + self.tr(title), + self.tr(desc), + QMessageBox.Yes, QMessageBox.No ) + + if reply != QMessageBox.Yes: + return False + return True + + +# Attempt to use a special checkbox widget in the cell. +# Couldn't figure out how to disable it with "enabled" colors +#w = QWidget() +#cb = QCheckBox(w) +#cb.setCheckState(Qt.Checked) +#layout = QHBoxLayout() +#layout.addWidget( cb ) +#layout.setAlignment(Qt.AlignHCenter) +#layout.setMargin(2) +#w.setLayout(layout) +#self.twList.setCellWidget( row, 2, w ) \ No newline at end of file diff --git a/renamewindow.py b/renamewindow.py index 110ac4e..0fb8eaa 100644 --- a/renamewindow.py +++ b/renamewindow.py @@ -75,5 +75,5 @@ class RenameWindow(QtGui.QDialog): os.rename( self.comic_archive.path, new_abs_path ) self.new_name = new_abs_path - + self.comic_archive.rename( new_abs_path ) \ No newline at end of file diff --git a/settings.py b/settings.py index e939b8c..23c774c 100644 --- a/settings.py +++ b/settings.py @@ -51,7 +51,8 @@ class ComicTaggerSettings: self.allow_cbi_in_rar = True # automatic settings - self.last_selected_data_style = 0 + self.last_selected_save_data_style = 0 + self.last_selected_load_data_style = 0 self.last_opened_folder = "" self.last_main_window_width = 0 self.last_main_window_height = 0 @@ -139,9 +140,11 @@ class ComicTaggerSettings: self.rar_exe_path = self.config.get( 'settings', 'rar_exe_path' ) self.unrar_exe_path = self.config.get( 'settings', 'unrar_exe_path' ) - - if self.config.has_option('auto', 'last_selected_data_style'): - self.last_selected_data_style = self.config.getint( 'auto', 'last_selected_data_style' ) + + if self.config.has_option('auto', 'last_selected_load_data_style'): + self.last_selected_load_data_style = self.config.getint( 'auto', 'last_selected_load_data_style' ) + if self.config.has_option('auto', 'last_selected_save_data_style'): + self.last_selected_save_data_style = self.config.getint( 'auto', 'last_selected_save_data_style' ) if self.config.has_option('auto', 'last_opened_folder'): self.last_opened_folder = self.config.get( 'auto', 'last_opened_folder' ) if self.config.has_option('auto', 'last_main_window_width'): @@ -202,7 +205,8 @@ class ComicTaggerSettings: if not self.config.has_section( 'auto' ): self.config.add_section( 'auto' ) - self.config.set( 'auto', 'last_selected_data_style', self.last_selected_data_style ) + self.config.set( 'auto', 'last_selected_load_data_style', self.last_selected_load_data_style ) + self.config.set( 'auto', 'last_selected_save_data_style', self.last_selected_save_data_style ) self.config.set( 'auto', 'last_opened_folder', self.last_opened_folder ) self.config.set( 'auto', 'last_main_window_width', self.last_main_window_width ) self.config.set( 'auto', 'last_main_window_height', self.last_main_window_height ) diff --git a/taggerwindow.py b/taggerwindow.py index 23aa585..b809ac8 100644 --- a/taggerwindow.py +++ b/taggerwindow.py @@ -111,7 +111,8 @@ class TaggerWindow( QtGui.QMainWindow): self.lblCover.setPixmap(QtGui.QPixmap(os.path.join(ComicTaggerSettings.baseDir(), 'graphics/nocover.png' ))) - self.data_style = settings.last_selected_data_style + self.save_data_style = settings.last_selected_save_data_style + self.load_data_style = settings.last_selected_load_data_style self.setAcceptDrops(True) self.configMenus() @@ -142,7 +143,8 @@ class TaggerWindow( QtGui.QMainWindow): self.cbMaturityRating.lineEdit().setAcceptDrops(False) # hook up the callbacks - self.cbDataStyle.currentIndexChanged.connect(self.setDataStyle) + self.cbLoadDataStyle.currentIndexChanged.connect(self.setLoadDataStyle) + self.cbSaveDataStyle.currentIndexChanged.connect(self.setSaveDataStyle) self.btnEditCredit.clicked.connect(self.editCredit) self.btnAddCredit.clicked.connect(self.addCredit) self.btnRemoveCredit.clicked.connect(self.removeCredit) @@ -246,16 +248,6 @@ class TaggerWindow( QtGui.QMainWindow): self.actionRemoveCRTags.setStatusTip( 'Remove ComicRack tags from comic archive' ) self.actionRemoveCRTags.triggered.connect( self.removeCRTags ) - - self.actionReloadAuto.setShortcut( 'Ctrl+R' ) - self.actionReloadAuto.setStatusTip( 'Reload selected style tags from archive' ) - self.actionReloadAuto.triggered.connect( self.reloadAuto ) - - self.actionReloadCBLTags.setStatusTip( 'Reload ComicBookLover tags' ) - self.actionReloadCBLTags.triggered.connect( self.reloadCBLTags ) - - self.actionReloadCRTags.setStatusTip( 'Reload ComicRack tags' ) - self.actionReloadCRTags.triggered.connect( self.reloadCRTags ) self.actionViewRawCRTags.setStatusTip( 'View raw ComicRack tag block from file' ) self.actionViewRawCRTags.triggered.connect( self.viewRawCRTags ) @@ -403,72 +395,12 @@ class TaggerWindow( QtGui.QMainWindow): event.accept() def dropEvent(self, event): - if self.dirtyFlagVerification( "Open Archive", - "If you open a new archive now, data in the form will be lost. Are you sure?"): - #self.openArchive( unicode(self.droppedFile)) - self.fileSelectionList.addPathList( self.droppedFiles ) - event.accept() - - def openArchive( self, path, explicit_style=None, clear_form=True ): - - if path is None or path == "": - return - - ca = ComicArchive( path ) - if self.settings.rar_exe_path != "": - ca.setExternalRarProgram( self.settings.rar_exe_path ) - - if ca is not None and ca.seemsToBeAComicArchive(): + #if self.dirtyFlagVerification( "Open Archive", + # "If you open a new archive now, data in the form will be lost. Are you sure?"): + self.fileSelectionList.addPathList( self.droppedFiles ) + event.accept() - self.settings.last_opened_folder = os.path.dirname( os.path.abspath(path) ) - - # clear form and current metadata, we're all in! - if clear_form: - self.clearForm() - - self.comic_archive = ca - - if explicit_style is None: - hasCBI = ca.hasCBI() - hasCIX = ca.hasCIX() - hasNeither = not hasCIX and not hasCBI - - # no style indicated, so try to choose - if hasNeither: - self.metadata = self.comic_archive.metadataFromFilename( ) - self.metadata.setDefaultPageList( self.comic_archive.getNumberOfPages() ) - else: - if hasCBI and not hasCIX: - self.data_style = MetaDataStyle.CBI - elif hasCIX and not hasCBI: - self.data_style = MetaDataStyle.CIX - else: #both - reply = QtGui.QMessageBox.question(self, - self.tr("Multiple Tag Types!"), - self.tr("This archive has both ComicBookLover and ComicRack type tags. Which do you want to load?"), - self.tr("ComicBookLover"), self.tr("ComicRack" )) - - if reply == 0: - # ComicBookLover - self.data_style = MetaDataStyle.CBI - else: - self.data_style = MetaDataStyle.CIX - self.adjustStyleCombo() - self.metadata = self.comic_archive.readMetadata( self.data_style ) - else: - if ca.hasMetadata( explicit_style ): - self.data_style = explicit_style - self.adjustStyleCombo() - self.metadata = self.comic_archive.readMetadata( self.data_style ) - else: - return - - self.loadCurrentArchive() - - else: - QtGui.QMessageBox.information(self, self.tr("Whoops!"), self.tr("That file doesn't appear to be a comic archive!")) - - def loadCurrentArchive( self ): + def actualLoadCurrentArchive( self ): if self.metadata.isEmpty: self.metadata = self.comic_archive.metadataFromFilename( ) self.metadata.setDefaultPageList( self.comic_archive.getNumberOfPages() ) @@ -511,9 +443,6 @@ class TaggerWindow( QtGui.QMainWindow): self.actionRepackage.setEnabled(False) self.actionViewRawCBLTags.setEnabled( False ) self.actionViewRawCRTags.setEnabled( False ) - self.actionReloadCRTags.setEnabled( False ) - self.actionReloadCBLTags.setEnabled( False ) - self.actionReloadAuto.setEnabled( False ) self.actionParse_Filename.setEnabled( False ) self.actionAutoSearch.setEnabled( False ) self.actionRename.setEnabled( False ) @@ -532,13 +461,9 @@ class TaggerWindow( QtGui.QMainWindow): if not self.comic_archive.isZip(): self.actionRepackage.setEnabled(True) - if has_cix or has_cbi: - self.actionReloadAuto.setEnabled( True ) if has_cix: - self.actionReloadCRTags.setEnabled( True ) self.actionViewRawCRTags.setEnabled( True ) if has_cbi: - self.actionReloadCBLTags.setEnabled( True ) self.actionViewRawCBLTags.setEnabled( True ) if self.comic_archive.isWritable(): @@ -592,11 +517,13 @@ class TaggerWindow( QtGui.QMainWindow): def setDirtyFlag( self, param1=None, param2=None, param3=None ): if not self.dirtyFlag: self.dirtyFlag = True + self.fileSelectionList.setModifiedFlag( True ) self.updateAppTitle() def clearDirtyFlag( self ): if self.dirtyFlag: self.dirtyFlag = False + self.fileSelectionList.setModifiedFlag( False ) self.updateAppTitle() def connectDirtyFlagSignals( self ): @@ -881,9 +808,9 @@ class TaggerWindow( QtGui.QMainWindow): if (dialog.exec_()): fileList = dialog.selectedFiles() - if self.dirtyFlagVerification( "Open Archive", - "If you open a new archive now, data in the form will be lost. Are you sure?"): - self.fileSelectionList.addPathList( fileList ) + #if self.dirtyFlagVerification( "Open Archive", + # "If you open a new archive now, data in the form will be lost. Are you sure?"): + self.fileSelectionList.addPathList( fileList ) def autoSelectSearch(self): if self.comic_archive is None: @@ -952,7 +879,7 @@ class TaggerWindow( QtGui.QMainWindow): if ( self.metadata is not None and self.comic_archive is not None): - if self.comic_archive.isRar() and self.data_style == MetaDataStyle.CBI: + if self.comic_archive.isRar() and self.save_data_style == MetaDataStyle.CBI: if self.settings.ask_about_cbi_in_rar: checked = OptionalMessageDialog.msg( self, "RAR and ComicBookLover", """ @@ -972,14 +899,14 @@ class TaggerWindow( QtGui.QMainWindow): reply = QtGui.QMessageBox.question(self, self.tr("Save Tags"), - self.tr("Are you sure you wish to save " + MetaDataStyle.name[self.data_style] + " tags to this archive?"), + self.tr("Are you sure you wish to save " + MetaDataStyle.name[self.save_data_style] + " tags to this archive?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No ) if reply == QtGui.QMessageBox.Yes: QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) self.formToMetadata() - success = self.comic_archive.writeMetadata( self.metadata, self.data_style ) + success = self.comic_archive.writeMetadata( self.metadata, self.save_data_style ) QtGui.QApplication.restoreOverrideCursor() if not success: @@ -989,15 +916,29 @@ class TaggerWindow( QtGui.QMainWindow): self.updateInfoBox() self.updateMenus() #QtGui.QMessageBox.information(self, self.tr("Yeah!"), self.tr("File written.")) + self.fileSelectionList.updateCurrentRow() else: QtGui.QMessageBox.information(self, self.tr("Whoops!"), self.tr("No data to commit!")) - def setDataStyle(self, s): - self.data_style, b = self.cbDataStyle.itemData(s).toInt() + def setLoadDataStyle(self, s): + if self.dirtyFlagVerification( "Change Tag Read Style", + "If you change tag style now, data in the form will be lost. Are you sure?"): + self.load_data_style, b = self.cbLoadDataStyle.itemData(s).toInt() + self.settings.last_selected_load_data_style = self.load_data_style + self.updateMenus() + if self.comic_archive is not None: + self.loadArchive( self.comic_archive ) + else: + self.cbLoadDataStyle.currentIndexChanged.disconnect(self.setLoadDataStyle) + self.adjustLoadStyleCombo() + self.cbLoadDataStyle.currentIndexChanged.connect(self.setLoadDataStyle) - self.settings.last_selected_data_style = self.data_style + def setSaveDataStyle(self, s): + self.save_data_style, b = self.cbSaveDataStyle.itemData(s).toInt() + + self.settings.last_selected_save_data_style = self.save_data_style self.updateStyleTweaks() self.updateMenus() @@ -1008,7 +949,7 @@ class TaggerWindow( QtGui.QMainWindow): cix_credits = ComicInfoXml().getParseableCredits() - if self.data_style == MetaDataStyle.CIX: + if self.save_data_style == MetaDataStyle.CIX: #loop over credit table, mark selected rows r = 0 while r < self.twCredits.rowCount(): @@ -1020,7 +961,7 @@ class TaggerWindow( QtGui.QMainWindow): self.twCredits.item(r, 0).setBackgroundColor( inactive_color ) r = r + 1 - if self.data_style == MetaDataStyle.CBI: + if self.save_data_style == MetaDataStyle.CBI: #loop over credit table, make all active color r = 0 while r < self.twCredits.rowCount(): @@ -1083,20 +1024,20 @@ class TaggerWindow( QtGui.QMainWindow): self.teLocations, self.cbMaturityRating, self.cbFormat ] - if self.data_style == MetaDataStyle.CIX: + if self.save_data_style == MetaDataStyle.CIX: for item in cix_only: enableWidget( item, True ) for item in cbi_only: enableWidget(item, False ) - if self.data_style == MetaDataStyle.CBI: + if self.save_data_style == MetaDataStyle.CBI: for item in cbi_only: enableWidget( item, True ) for item in cix_only: enableWidget(item, False ) self.updateCreditColors() - self.pageListEditor.setMetadataStyle( self.data_style ) + self.pageListEditor.setMetadataStyle( self.save_data_style ) def cellDoubleClicked( self, r, c ): self.editCredit() @@ -1211,21 +1152,32 @@ class TaggerWindow( QtGui.QMainWindow): self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) - def adjustStyleCombo( self ): + def adjustLoadStyleCombo( self ): # select the current style - if ( self.data_style == MetaDataStyle.CBI ): - self.cbDataStyle.setCurrentIndex ( 0 ) - elif ( self.data_style == MetaDataStyle.CIX ): - self.cbDataStyle.setCurrentIndex ( 1 ) + if ( self.load_data_style == MetaDataStyle.CBI ): + self.cbLoadDataStyle.setCurrentIndex ( 0 ) + elif ( self.load_data_style == MetaDataStyle.CIX ): + self.cbLoadDataStyle.setCurrentIndex ( 1 ) + + def adjustSaveStyleCombo( self ): + # select the current style + if ( self.save_data_style == MetaDataStyle.CBI ): + self.cbSaveDataStyle.setCurrentIndex ( 0 ) + elif ( self.save_data_style == MetaDataStyle.CIX ): + self.cbSaveDataStyle.setCurrentIndex ( 1 ) self.updateStyleTweaks() def populateComboBoxes( self ): # Add the entries to the tag style combobox - self.cbDataStyle.addItem( "ComicBookLover", MetaDataStyle.CBI ) - self.cbDataStyle.addItem( "ComicRack", MetaDataStyle.CIX ) - self.adjustStyleCombo() + self.cbLoadDataStyle.addItem( "ComicBookLover", MetaDataStyle.CBI ) + self.cbLoadDataStyle.addItem( "ComicRack", MetaDataStyle.CIX ) + self.adjustLoadStyleCombo() + + self.cbSaveDataStyle.addItem( "ComicBookLover", MetaDataStyle.CBI ) + self.cbSaveDataStyle.addItem( "ComicRack", MetaDataStyle.CIX ) + self.adjustSaveStyleCombo() # Add the entries to the country combobox self.cbCountry.addItem( "", "" ) @@ -1317,7 +1269,7 @@ class TaggerWindow( QtGui.QMainWindow): self.cbFormat.addItem("Year One") def removeAuto( self ): - self.removeTags( self.data_style ) + self.removeTags( self.save_data_style ) def removeCBLTags( self ): self.removeTags( MetaDataStyle.CBI ) @@ -1341,24 +1293,8 @@ class TaggerWindow( QtGui.QMainWindow): else: self.updateInfoBox() self.updateMenus() - + self.fileSelectionList.updateCurrentRow() - def reloadAuto( self ): - self.actualReload( self.data_style ) - - def reloadCBLTags( self ): - self.actualReload( MetaDataStyle.CBI ) - - def reloadCRTags( self ): - self.actualReload( MetaDataStyle.CIX ) - - def actualReload( self, style ): - if self.comic_archive is not None and self.comic_archive.hasMetadata( style ): - if self.dirtyFlagVerification( "Load Tags", - "If you load tags now, data in the form will be lost. Are you sure?"): - self.openArchive( self.comic_archive.path, explicit_style=style ) - - def dirtyFlagVerification( self, title, desc): if self.dirtyFlag: reply = QtGui.QMessageBox.question(self, @@ -1436,27 +1372,24 @@ class TaggerWindow( QtGui.QMainWindow): dlg = RenameWindow( self, self.comic_archive, self.metadata, self.settings ) dlg.setModal( True ) if dlg.exec_(): - #reopen the archive, since the filename changed - print dlg.new_name - self.comic_archive = None - self.openArchive( dlg.new_name ) + self.fileSelectionList.updateCurrentRow() + self.loadArchive( self.comic_archive ) + def fileListSelectionChanged( self, qvarFI ): fi = qvarFI.toPyObject() - #if fi.cix_md is not None: - # print u"{0}".format(fi.cix_md) + self.loadArchive( fi.ca ) + + def loadArchive( self, comic_archive ): self.comic_archive = None self.clearForm() - self.comic_archive = fi.ca - if self.data_style == MetaDataStyle.CIX: - self.metadata = fi.cix_md - else: - self.metadata = fi.cbi_md + self.comic_archive = comic_archive + self.metadata = self.comic_archive.readMetadata(self.load_data_style) if self.metadata is None: self.metadata = GenericMetadata() - self.loadCurrentArchive() - + self.actualLoadCurrentArchive() + def fileListCleared( self ): self.resetApp() \ No newline at end of file diff --git a/taggerwindow.ui b/taggerwindow.ui index f8ec243..c1a88b3 100644 --- a/taggerwindow.ui +++ b/taggerwindow.ui @@ -7,7 +7,7 @@ 0 0 968 - 547 + 575 @@ -62,12 +62,22 @@ - Tag Style: + Read Style - + + + + + + Write Style + + + + + @@ -1181,14 +1191,6 @@ - - - Reload - - - - - View Raw Tags @@ -1199,7 +1201,6 @@ - diff --git a/todo.txt b/todo.txt index c87ce03..220bc01 100644 --- a/todo.txt +++ b/todo.txt @@ -3,20 +3,14 @@ Features ----------------------------------------------------- Multi-file: - Does the main UI need to have "View/Read Tag Style" and "Write Tag style" concept? - - Select first dropped Item into list - Turn off drop accept for edit lines/boxes - Drop on app goes to list and selects it - Accept multiple files on file open dialog - Warn on moving selection list away from modified form - ComicArchive: cache each metadata block? Need to make sure cache is cleared on file modify Batch Functions: Auto-Select Start/Options Dialog Progress Dialog - maybe reuse - Interactive dialog at end + Interactive dialog at end + Summary Dialog + Rename Start dialog with preview maybe table with checkboxes? @@ -24,7 +18,7 @@ Multi-file: Copy Block Verify overwrites Delete - + Export to CBZ? ----------------------------------------------------- Bugs