2012-11-14 20:34:33 -08:00
# coding=utf-8
2015-02-21 18:30:32 -08:00
""" The main window of the ComicTagger app """
2012-11-06 12:56:30 -08:00
2015-02-21 18:30:32 -08:00
# Copyright 2012-2014 Anthony Beville
2012-11-06 12:56:30 -08:00
2015-02-21 18:30:32 -08:00
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
2012-11-06 12:56:30 -08:00
2015-02-21 18:30:32 -08:00
# http://www.apache.org/licenses/LICENSE-2.0
2012-11-06 12:56:30 -08:00
2015-02-21 18:30:32 -08:00
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
2012-11-02 13:54:17 -07:00
2014-04-08 00:13:04 -07:00
import sys
2012-11-02 20:56:01 -07:00
import locale
2018-09-19 13:05:39 -07:00
import functools
2012-11-06 12:29:18 -08:00
import platform
2012-11-14 17:25:01 -08:00
import os
2012-11-19 20:04:58 -08:00
import pprint
import json
2012-12-04 23:34:53 -08:00
import webbrowser
2013-01-30 10:40:53 -08:00
import re
2014-04-08 00:13:04 -07:00
import pickle
2015-02-21 18:30:32 -08:00
#import signal
2012-11-02 13:54:17 -07:00
2018-09-19 13:05:39 -07:00
from PyQt5 import QtCore , QtGui , QtWidgets , uic
from PyQt5 import QtNetwork
from PyQt5 . QtCore import QUrl
2015-02-13 15:08:07 -08:00
2022-04-01 06:48:53 -07:00
from urllib . parse import urlparse
2015-02-21 18:30:32 -08:00
#from comicarchive import ComicArchive
#from pageloader import PageLoader
2018-09-19 13:05:39 -07:00
from . volumeselectionwindow import VolumeSelectionWindow
from . comicarchive import MetaDataStyle
from . comicinfoxml import ComicInfoXml
from . genericmetadata import GenericMetadata
from . comicvinetalker import ComicVineTalker , ComicVineTalkerException
from . crediteditorwindow import CreditEditorWindow
from . settingswindow import SettingsWindow
from . settings import ComicTaggerSettings
from . pagebrowser import PageBrowserWindow
from . filenameparser import FileNameParser
from . logwindow import LogWindow
from . optionalmsgdialog import OptionalMessageDialog
from . pagelisteditor import PageListEditor
from . fileselectionlist import FileSelectionList
from . cbltransformer import CBLTransformer
from . renamewindow import RenameWindow
from . exportwindow import ExportWindow , ExportConflictOpts
from . issueidentifier import IssueIdentifier
2021-08-07 21:54:29 -07:00
from . issuestring import IssueString
2018-09-19 13:05:39 -07:00
from . autotagstartwindow import AutoTagStartWindow
from . autotagprogresswindow import AutoTagProgressWindow
from . autotagmatchwindow import AutoTagMatchWindow
from . coverimagewidget import CoverImageWidget
from . versionchecker import VersionChecker
2015-02-21 18:30:32 -08:00
from comictaggerlib . ui . qtutils import reduceWidgetFontSize , centerWindowOnParent
2018-09-19 13:05:39 -07:00
from . import utils
from . import ctversion
2012-11-02 20:56:01 -07:00
2015-02-13 15:08:07 -08:00
2013-01-21 16:19:59 -08:00
class OnlineMatchResults ( ) :
2015-02-15 02:44:00 -08:00
2015-02-12 14:57:46 -08:00
def __init__ ( self ) :
self . goodMatches = [ ]
self . noMatches = [ ]
self . multipleMatches = [ ]
self . lowConfidenceMatches = [ ]
self . writeFailures = [ ]
self . fetchDataFailures = [ ]
2015-02-13 15:08:07 -08:00
2013-01-21 16:19:59 -08:00
class MultipleMatch ( ) :
2015-02-15 02:44:00 -08:00
2015-02-13 15:08:07 -08:00
def __init__ ( self , ca , match_list ) :
2015-02-12 14:57:46 -08:00
self . ca = ca
self . matches = match_list
2012-11-02 13:54:17 -07:00
2015-02-13 15:08:07 -08:00
2018-09-19 13:05:39 -07:00
class TaggerWindow ( QtWidgets . QMainWindow ) :
2015-02-12 14:57:46 -08:00
appName = " ComicTagger "
version = ctversion . version
2015-02-15 02:44:00 -08:00
def __init__ ( self , file_list , settings , parent = None , opts = None ) :
2015-02-12 14:57:46 -08:00
super ( TaggerWindow , self ) . __init__ ( parent )
2022-03-18 12:14:42 -07:00
2015-02-13 15:08:07 -08:00
uic . loadUi ( ComicTaggerSettings . getUIFile ( ' taggerwindow.ui ' ) , self )
2015-02-12 14:57:46 -08:00
self . settings = settings
#----------------------------------
# prevent multiple instances
socket = QtNetwork . QLocalSocket ( self )
socket . connectToServer ( settings . install_id )
alive = socket . waitForConnected ( 3000 )
if alive :
2018-09-19 13:05:39 -07:00
print ( (
2015-02-15 03:55:04 -08:00
" Another application with key [ {} ] is already running " . format (
2018-09-19 13:05:39 -07:00
settings . install_id ) ) )
2015-02-12 14:57:46 -08:00
# send file list to other instance
if len ( file_list ) > 0 :
socket . write ( pickle . dumps ( file_list ) )
if not socket . waitForBytesWritten ( 3000 ) :
2018-09-19 13:05:39 -07:00
print ( ( socket . errorString ( ) . toLatin1 ( ) ) )
2015-02-12 14:57:46 -08:00
socket . disconnectFromServer ( )
sys . exit ( )
else :
# listen on a socket to prevent multiple instances
self . socketServer = QtNetwork . QLocalServer ( self )
2015-02-15 02:44:00 -08:00
self . socketServer . newConnection . connect (
self . onIncomingSocketConnection )
2015-02-12 14:57:46 -08:00
ok = self . socketServer . listen ( settings . install_id )
if not ok :
2015-02-15 03:44:09 -08:00
if self . socketServer . serverError (
) == QtNetwork . QAbstractSocket . AddressInUseError :
2015-02-13 15:08:07 -08:00
#print("Resetting unresponsive socket with key [{}]".format(settings.install_id))
2015-02-12 14:57:46 -08:00
self . socketServer . removeServer ( settings . install_id )
ok = self . socketServer . listen ( settings . install_id )
if not ok :
2018-09-19 13:05:39 -07:00
print ( (
2015-02-15 03:55:04 -08:00
" Cannot start local socket with key [ {} ]. Reason: %s " . format (
settings . install_id ,
2018-09-19 13:05:39 -07:00
self . socketServer . errorString ( ) ) ) )
2015-02-12 14:57:46 -08:00
sys . exit ( )
2015-02-13 15:08:07 -08:00
#print("Registering as single instance with key [{}]".format(settings.install_id))
2015-02-12 14:57:46 -08:00
#----------------------------------
2015-02-15 02:44:00 -08:00
self . archiveCoverWidget = CoverImageWidget (
self . coverImageContainer , CoverImageWidget . ArchiveMode )
2018-09-19 13:05:39 -07:00
gridlayout = QtWidgets . QGridLayout ( self . coverImageContainer )
2015-02-13 15:08:07 -08:00
gridlayout . addWidget ( self . archiveCoverWidget )
2015-02-15 02:44:00 -08:00
gridlayout . setContentsMargins ( 0 , 0 , 0 , 0 )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . pageListEditor = PageListEditor ( self . tabPages )
2018-09-19 13:05:39 -07:00
gridlayout = QtWidgets . QGridLayout ( self . tabPages )
2015-02-13 15:08:07 -08:00
gridlayout . addWidget ( self . pageListEditor )
2015-02-12 14:57:46 -08:00
#---------------------------
2015-02-15 02:44:00 -08:00
self . fileSelectionList = FileSelectionList (
self . widgetListHolder , self . settings )
2018-09-19 13:05:39 -07:00
gridlayout = QtWidgets . QGridLayout ( self . widgetListHolder )
2015-02-13 15:08:07 -08:00
gridlayout . addWidget ( self . fileSelectionList )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . fileSelectionList . selectionChanged . connect (
self . fileListSelectionChanged )
2015-02-13 15:08:07 -08:00
self . fileSelectionList . listCleared . connect ( self . fileListCleared )
2015-02-15 03:55:04 -08:00
self . fileSelectionList . setSorting (
self . settings . last_filelist_sorted_column ,
self . settings . last_filelist_sorted_order )
2015-02-12 14:57:46 -08:00
# we can't specify relative font sizes in the UI designer, so
# walk through all the lablels in the main form, and make them
# a smidge smaller
for child in self . scrollAreaWidgetContents . children ( ) :
2018-09-19 13:05:39 -07:00
if ( isinstance ( child , QtWidgets . QLabel ) ) :
2015-02-12 14:57:46 -08:00
f = child . font ( )
if f . pointSize ( ) > 10 :
2015-02-13 15:08:07 -08:00
f . setPointSize ( f . pointSize ( ) - 2 )
f . setItalic ( True )
child . setFont ( f )
2015-02-12 14:57:46 -08:00
self . scrollAreaWidgetContents . adjustSize ( )
2015-02-15 02:44:00 -08:00
self . setWindowIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' app.png ' ) ) )
2015-02-12 14:57:46 -08:00
if opts is not None and opts . data_style is not None and opts . data_style != MetaDataStyle . COMET :
2015-02-15 02:44:00 -08:00
# respect the command line option tag type
2015-02-12 14:57:46 -08:00
settings . last_selected_save_data_style = opts . data_style
settings . last_selected_load_data_style = opts . 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 ( )
self . statusBar ( )
self . populateComboBoxes ( )
self . page_browser = None
self . resetApp ( )
# set up some basic field validators
validator = QtGui . QIntValidator ( 1900 , 2099 , self )
self . lePubYear . setValidator ( validator )
validator = QtGui . QIntValidator ( 1 , 12 , self )
self . lePubMonth . setValidator ( validator )
2015-02-16 07:19:38 -08:00
# TODO: for now keep it simple, ideally we should check the full date
validator = QtGui . QIntValidator ( 1 , 31 , self )
self . lePubDay . setValidator ( validator )
2015-02-12 14:57:46 -08:00
validator = QtGui . QIntValidator ( 1 , 99999 , self )
self . leIssueCount . setValidator ( validator )
self . leVolumeNum . setValidator ( validator )
self . leVolumeCount . setValidator ( validator )
self . leAltIssueNum . setValidator ( validator )
self . leAltIssueCount . setValidator ( validator )
2015-02-15 02:44:00 -08:00
# TODO set up an RE validator for issueNum that allows
2015-02-12 14:57:46 -08:00
# for all sorts of wacky things
# tweak some control fonts
2015-02-16 07:18:00 -08:00
reduceWidgetFontSize ( self . lblFilename , 1 )
reduceWidgetFontSize ( self . lblArchiveType )
reduceWidgetFontSize ( self . lblTagList )
reduceWidgetFontSize ( self . lblPageCount )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
# make sure some editable comboboxes don't take drop actions
2015-02-12 14:57:46 -08:00
self . cbFormat . lineEdit ( ) . setAcceptDrops ( False )
self . cbMaturityRating . lineEdit ( ) . setAcceptDrops ( False )
# hook up the callbacks
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 )
self . twCredits . cellDoubleClicked . connect ( self . editCredit )
2022-03-31 09:40:43 -07:00
self . btnOpenWebLink . clicked . connect ( self . openWebLink )
2015-02-12 14:57:46 -08:00
self . connectDirtyFlagSignals ( )
self . pageListEditor . modified . connect ( self . setDirtyFlag )
2015-02-15 02:44:00 -08:00
self . pageListEditor . firstFrontCoverChanged . connect (
self . frontCoverChanged )
2015-02-13 15:08:07 -08:00
self . pageListEditor . listOrderChanged . connect ( self . pageListOrderChanged )
self . tabWidget . currentChanged . connect ( self . tabChanged )
2015-02-12 14:57:46 -08:00
self . updateStyleTweaks ( )
self . show ( )
self . setAppPosition ( )
if self . settings . last_form_side_width != - 1 :
2015-02-15 02:44:00 -08:00
self . splitter . setSizes (
[ self . settings . last_form_side_width , self . settings . last_list_side_width ] )
2015-02-12 14:57:46 -08:00
self . raise_ ( )
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
self . resizeEvent ( None )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . splitter . splitterMoved . connect ( self . splitterMovedEvent )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addAppAction ( self . actionAutoIdentify )
self . fileSelectionList . addAppAction ( self . actionAutoTag )
self . fileSelectionList . addAppAction ( self . actionCopyTags )
self . fileSelectionList . addAppAction ( self . actionRename )
self . fileSelectionList . addAppAction ( self . actionRemoveAuto )
self . fileSelectionList . addAppAction ( self . actionRepackage )
2015-02-12 14:57:46 -08:00
if len ( file_list ) != 0 :
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addPathList ( file_list )
2015-02-12 14:57:46 -08:00
if self . settings . show_disclaimer :
2015-02-13 15:08:07 -08:00
checked = OptionalMessageDialog . msg ( self , " Welcome! " ,
2015-02-15 02:44:00 -08:00
"""
2015-02-12 14:57:46 -08:00
Thanks for trying ComicTagger ! < br > < br >
Be aware that this is beta - level software , and consider it experimental .
You should use it very carefully when modifying your data files . As the
license says , it ' s " AS IS! " <br><br>
Also , be aware that writing tags to comic archives will change their file hashes ,
which has implications with respect to other software packages . It ' s best to
use ComicTagger on local copies of your comics . < br > < br >
Have fun !
"""
2015-02-15 02:44:00 -08:00
)
2015-02-12 14:57:46 -08:00
self . settings . show_disclaimer = not checked
if self . settings . check_for_new_version :
2017-12-21 06:19:45 -08:00
#self.checkLatestVersionOnline()
pass
2015-02-12 14:57:46 -08:00
def sigint_handler ( self , * args ) :
# defer the actual close in the app loop thread
QtCore . QTimer . singleShot ( 200 , self . close )
2015-02-13 15:08:07 -08:00
def resetApp ( self ) :
2015-02-12 14:57:46 -08:00
self . archiveCoverWidget . clear ( )
self . comic_archive = None
self . dirtyFlag = False
self . clearForm ( )
self . pageListEditor . resetPage ( )
if self . page_browser is not None :
self . page_browser . reset ( )
self . updateAppTitle ( )
self . updateMenus ( )
self . updateInfoBox ( )
self . droppedFile = None
self . page_loader = None
2015-02-13 15:08:07 -08:00
def updateAppTitle ( self ) :
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
self . setWindowIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' app.png ' ) ) )
2022-03-18 12:14:42 -07:00
2015-02-12 14:57:46 -08:00
if self . comic_archive is None :
2015-02-13 15:08:07 -08:00
self . setWindowTitle ( self . appName )
2015-02-12 14:57:46 -08:00
else :
mod_str = " "
ro_str = " "
if self . dirtyFlag :
mod_str = " [modified] "
if not self . comic_archive . isWritable ( ) :
ro_str = " [read only] "
2015-02-15 02:44:00 -08:00
self . setWindowTitle (
2015-02-15 03:55:04 -08:00
self . appName +
" - " +
self . comic_archive . path +
mod_str +
ro_str )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def configMenus ( self ) :
2015-02-12 14:57:46 -08:00
# File Menu
2015-02-13 15:08:07 -08:00
self . actionExit . setShortcut ( ' Ctrl+Q ' )
self . actionExit . setStatusTip ( ' Exit application ' )
self . actionExit . triggered . connect ( self . close )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionLoad . setShortcut ( ' Ctrl+O ' )
self . actionLoad . setStatusTip ( ' Load comic archive ' )
self . actionLoad . triggered . connect ( self . selectFile )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionLoadFolder . setShortcut ( ' Ctrl+Shift+O ' )
self . actionLoadFolder . setStatusTip ( ' Load folder with comic archives ' )
self . actionLoadFolder . triggered . connect ( self . selectFolder )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionWrite_Tags . setShortcut ( ' Ctrl+S ' )
self . actionWrite_Tags . setStatusTip ( ' Save tags to comic archive ' )
self . actionWrite_Tags . triggered . connect ( self . commitMetadata )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionAutoTag . setShortcut ( ' Ctrl+T ' )
self . actionAutoTag . setStatusTip ( ' Auto-tag multiple archives ' )
self . actionAutoTag . triggered . connect ( self . autoTag )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionCopyTags . setShortcut ( ' Ctrl+C ' )
self . actionCopyTags . setStatusTip ( ' Copy one tag style to another ' )
self . actionCopyTags . triggered . connect ( self . copyTags )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionRemoveAuto . setShortcut ( ' Ctrl+D ' )
2015-02-15 02:44:00 -08:00
self . actionRemoveAuto . setStatusTip (
' Remove currently selected modify tag style from the archive ' )
2015-02-13 15:08:07 -08:00
self . actionRemoveAuto . triggered . connect ( self . removeAuto )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . actionRemoveCBLTags . setStatusTip (
' Remove ComicBookLover tags from comic archive ' )
2015-02-13 15:08:07 -08:00
self . actionRemoveCBLTags . triggered . connect ( self . removeCBLTags )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . actionRemoveCRTags . setStatusTip (
' Remove ComicRack tags from comic archive ' )
2015-02-13 15:08:07 -08:00
self . actionRemoveCRTags . triggered . connect ( self . removeCRTags )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . actionViewRawCRTags . setStatusTip (
' View raw ComicRack tag block from file ' )
2015-02-13 15:08:07 -08:00
self . actionViewRawCRTags . triggered . connect ( self . viewRawCRTags )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . actionViewRawCBLTags . setStatusTip (
' View raw ComicBookLover tag block from file ' )
2015-02-13 15:08:07 -08:00
self . actionViewRawCBLTags . triggered . connect ( self . viewRawCBLTags )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionRepackage . setShortcut ( ' Ctrl+E ' )
self . actionRepackage . setStatusTip ( ' Re-create archive as CBZ ' )
self . actionRepackage . triggered . connect ( self . repackageArchive )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionRename . setShortcut ( ' Ctrl+N ' )
self . actionRename . setStatusTip ( ' Rename archive based on tags ' )
self . actionRename . triggered . connect ( self . renameArchive )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionSettings . setShortcut ( ' Ctrl+Shift+S ' )
self . actionSettings . setStatusTip ( ' Configure ComicTagger ' )
self . actionSettings . triggered . connect ( self . showSettings )
2015-02-12 14:57:46 -08:00
# Tag Menu
2015-02-13 15:08:07 -08:00
self . actionParse_Filename . setShortcut ( ' Ctrl+F ' )
2015-02-15 02:44:00 -08:00
self . actionParse_Filename . setStatusTip (
' Try to extract tags from filename ' )
2015-02-13 15:08:07 -08:00
self . actionParse_Filename . triggered . connect ( self . useFilename )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionSearchOnline . setShortcut ( ' Ctrl+W ' )
self . actionSearchOnline . setStatusTip ( ' Search online for tags ' )
self . actionSearchOnline . triggered . connect ( self . queryOnline )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionAutoIdentify . setShortcut ( ' Ctrl+I ' )
self . actionAutoIdentify . triggered . connect ( self . autoIdentifySearch )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionApplyCBLTransform . setShortcut ( ' Ctrl+L ' )
2015-02-15 02:44:00 -08:00
self . actionApplyCBLTransform . setStatusTip (
' Modify tags specifically for CBL format ' )
2015-02-13 15:08:07 -08:00
self . actionApplyCBLTransform . triggered . connect ( self . applyCBLTransform )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . actionClearEntryForm . setShortcut ( ' Ctrl+Shift+C ' )
2015-02-15 02:44:00 -08:00
self . actionClearEntryForm . setStatusTip (
' Clear all the data on the screen ' )
2015-02-13 15:08:07 -08:00
self . actionClearEntryForm . triggered . connect ( self . clearForm )
2015-02-12 14:57:46 -08:00
# Window Menu
2015-02-13 15:08:07 -08:00
self . actionPageBrowser . setShortcut ( ' Ctrl+P ' )
self . actionPageBrowser . setStatusTip ( ' Show the page browser ' )
self . actionPageBrowser . triggered . connect ( self . showPageBrowser )
2015-02-12 14:57:46 -08:00
# Help Menu
2015-02-13 15:08:07 -08:00
self . actionAbout . setStatusTip ( ' Show the ' + self . appName + ' info ' )
self . actionAbout . triggered . connect ( self . aboutApp )
self . actionWiki . triggered . connect ( self . showWiki )
self . actionReportBug . triggered . connect ( self . reportBug )
self . actionComicTaggerForum . triggered . connect ( self . showForum )
2015-02-12 14:57:46 -08:00
2022-03-31 09:40:43 -07:00
# Notes Menu
self . btnOpenWebLink . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' open.png ' ) ) )
2015-02-12 14:57:46 -08:00
2022-03-31 09:40:43 -07:00
# ToolBar
2015-02-15 02:44:00 -08:00
self . actionLoad . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' open.png ' ) ) )
self . actionLoadFolder . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' longbox.png ' ) ) )
self . actionWrite_Tags . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' save.png ' ) ) )
self . actionParse_Filename . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' parse.png ' ) ) )
self . actionSearchOnline . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' search.png ' ) ) )
self . actionAutoIdentify . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' auto.png ' ) ) )
self . actionAutoTag . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' autotag.png ' ) ) )
self . actionClearEntryForm . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' clear.png ' ) ) )
self . actionPageBrowser . setIcon (
QtGui . QIcon ( ComicTaggerSettings . getGraphic ( ' browse.png ' ) ) )
2015-02-13 15:08:07 -08:00
self . toolBar . addAction ( self . actionLoad )
self . toolBar . addAction ( self . actionLoadFolder )
self . toolBar . addAction ( self . actionWrite_Tags )
self . toolBar . addAction ( self . actionSearchOnline )
self . toolBar . addAction ( self . actionAutoIdentify )
self . toolBar . addAction ( self . actionAutoTag )
self . toolBar . addAction ( self . actionClearEntryForm )
self . toolBar . addAction ( self . actionPageBrowser )
def repackageArchive ( self ) :
2015-02-12 14:57:46 -08:00
ca_list = self . fileSelectionList . getSelectedArchiveList ( )
rar_count = 0
for ca in ca_list :
2015-02-13 15:08:07 -08:00
if ca . isRar ( ) :
2015-02-12 14:57:46 -08:00
rar_count + = 1
if rar_count == 0 :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Export as Zip Archive " ) ,
self . tr ( " No RAR archives selected! " ) )
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
if not self . dirtyFlagVerification (
" Export as Zip Archive " ,
" If you export archives as Zip now, unsaved data in the form may be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
return
if rar_count != 0 :
2015-02-15 03:55:04 -08:00
dlg = ExportWindow (
self ,
self . settings ,
self . tr (
" You have selected {0} archive(s) to export to Zip format. New archives will be created in the same folder as the original. \n \n Please choose options below, and select OK. \n " . format ( rar_count ) ) )
2015-02-13 15:08:07 -08:00
dlg . adjustSize ( )
dlg . setModal ( True )
2015-02-12 14:57:46 -08:00
if not dlg . exec_ ( ) :
return
2018-09-19 13:05:39 -07:00
progdialog = QtWidgets . QProgressDialog (
2015-02-15 02:44:00 -08:00
" " , " Cancel " , 0 , rar_count , self )
2015-02-13 15:08:07 -08:00
progdialog . setWindowTitle ( " Exporting as ZIP " )
2015-02-12 14:57:46 -08:00
progdialog . setWindowModality ( QtCore . Qt . ApplicationModal )
2018-09-19 13:05:39 -07:00
progdialog . setMinimumDuration ( 300 )
centerWindowOnParent ( progdialog )
QtCore . QCoreApplication . processEvents ( )
2015-02-12 14:57:46 -08:00
prog_idx = 0
new_archives_to_add = [ ]
archives_to_remove = [ ]
skipped_list = [ ]
failed_list = [ ]
success_count = 0
for ca in ca_list :
if ca . isRar ( ) :
QtCore . QCoreApplication . processEvents ( )
if progdialog . wasCanceled ( ) :
break
prog_idx + = 1
2018-09-19 13:05:39 -07:00
progdialog . setValue ( prog_idx )
2015-02-13 15:08:07 -08:00
progdialog . setLabelText ( ca . path )
2015-02-21 18:30:32 -08:00
centerWindowOnParent ( progdialog )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
original_path = os . path . abspath ( ca . path )
2015-02-12 14:57:46 -08:00
export_name = os . path . splitext ( original_path ) [ 0 ] + " .cbz "
2015-02-13 15:08:07 -08:00
if os . path . lexists ( export_name ) :
2015-02-12 14:57:46 -08:00
if dlg . fileConflictBehavior == ExportConflictOpts . dontCreate :
export_name = None
2015-02-13 15:08:07 -08:00
skipped_list . append ( ca . path )
2015-02-12 14:57:46 -08:00
elif dlg . fileConflictBehavior == ExportConflictOpts . createUnique :
2015-02-13 15:08:07 -08:00
export_name = utils . unique_file ( export_name )
2015-02-12 14:57:46 -08:00
if export_name is not None :
2015-02-13 15:08:07 -08:00
if ca . exportAsZip ( export_name ) :
2015-02-12 14:57:46 -08:00
success_count + = 1
if dlg . addToList :
2015-02-13 15:08:07 -08:00
new_archives_to_add . append ( export_name )
2015-02-12 14:57:46 -08:00
if dlg . deleteOriginal :
2015-02-13 15:08:07 -08:00
archives_to_remove . append ( ca )
os . unlink ( ca . path )
2015-02-12 14:57:46 -08:00
else :
2015-02-15 02:44:00 -08:00
# last export failed, so remove the zip, if it
# exists
2015-02-13 15:08:07 -08:00
failed_list . append ( ca . path )
if os . path . lexists ( export_name ) :
os . remove ( export_name )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
progdialog . hide ( )
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addPathList ( new_archives_to_add )
self . fileSelectionList . removeArchiveList ( archives_to_remove )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
summary = " Successfully created {0} Zip archive(s). " . format (
2015-02-15 02:44:00 -08:00
success_count )
2015-02-13 15:08:07 -08:00
if len ( skipped_list ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " \n \n The following {0} RAR archive(s) were skipped due to file name conflicts: \n " . format (
2015-02-15 02:44:00 -08:00
len ( skipped_list ) )
2015-02-12 14:57:46 -08:00
for f in skipped_list :
2018-09-19 13:05:39 -07:00
summary + = " \t {0} \n " . format ( f )
2015-02-13 15:08:07 -08:00
if len ( failed_list ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " \n \n The following {0} RAR archive(s) failed to export due to read/write errors: \n " . format (
2015-02-15 02:44:00 -08:00
len ( failed_list ) )
2015-02-12 14:57:46 -08:00
for f in failed_list :
2018-09-19 13:05:39 -07:00
summary + = " \t {0} \n " . format ( f )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
dlg = LogWindow ( self )
dlg . setText ( summary )
dlg . setWindowTitle ( " Archive Export to Zip Summary " )
2015-02-12 14:57:46 -08:00
dlg . exec_ ( )
2015-02-13 15:08:07 -08:00
def aboutApp ( self ) :
2015-02-12 14:57:46 -08:00
2019-10-05 07:31:12 -07:00
website = " https://github.com/comictagger/comictagger "
2015-02-12 14:57:46 -08:00
email = " comictagger@gmail.com "
license_link = " http://www.apache.org/licenses/LICENSE-2.0 "
license_name = " Apache License 2.0 "
2018-09-19 13:05:39 -07:00
msgBox = QtWidgets . QMessageBox ( )
2015-02-13 15:08:07 -08:00
msgBox . setWindowTitle ( self . tr ( " About " + self . appName ) )
msgBox . setTextFormat ( QtCore . Qt . RichText )
2015-02-15 02:44:00 -08:00
msgBox . setIconPixmap (
QtGui . QPixmap ( ComicTaggerSettings . getGraphic ( ' about.png ' ) ) )
2015-02-15 03:55:04 -08:00
msgBox . setText ( " <br><br><br> " +
self . appName +
" v " +
self . version +
" <br> " +
2018-09-19 13:05:39 -07:00
" ©2014-2018 ComicTagger Devs<br><br> " +
2015-02-15 03:55:04 -08:00
" <a href= ' {0} ' > {0} </a><br><br> " . format ( website ) +
" <a href= ' mailto: {0} ' > {0} </a><br><br> " . format ( email ) +
" License: <a href= ' {0} ' > {1} </a> " . format ( license_link , license_name ) )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
msgBox . setStandardButtons ( QtWidgets . QMessageBox . Ok )
2015-02-12 14:57:46 -08:00
msgBox . exec_ ( )
def dragEnterEvent ( self , event ) :
self . droppedFiles = None
if event . mimeData ( ) . hasUrls ( ) :
# walk through the URL list and build a file list
for url in event . mimeData ( ) . urls ( ) :
if url . isValid ( ) and url . scheme ( ) == " file " :
if self . droppedFiles is None :
self . droppedFiles = [ ]
2017-12-21 06:19:45 -08:00
self . droppedFiles . append ( self . getUrlFromLocalFileID ( url ) )
2015-02-12 14:57:46 -08:00
if self . droppedFiles is not None :
event . accept ( )
2017-12-21 06:19:45 -08:00
def getUrlFromLocalFileID ( self , localFileID ) :
2022-03-18 12:14:42 -07:00
return localFileID . toLocalFile ( )
2017-12-21 06:19:45 -08:00
2015-02-12 14:57:46 -08:00
def dropEvent ( self , event ) :
2015-02-15 02:44:00 -08:00
# if self.dirtyFlagVerification("Open Archive",
2015-02-12 14:57:46 -08:00
# "If you open a new archive now, data in the form will be lost. Are you sure?"):
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addPathList ( self . droppedFiles )
2015-02-12 14:57:46 -08:00
event . accept ( )
2015-02-13 15:08:07 -08:00
def actualLoadCurrentArchive ( self ) :
2015-02-12 14:57:46 -08:00
if self . metadata . isEmpty :
2015-02-15 02:44:00 -08:00
self . metadata = self . comic_archive . metadataFromFilename (
self . settings . parse_scan_info )
2015-02-12 14:57:46 -08:00
if len ( self . metadata . pages ) == 0 :
2015-02-15 02:44:00 -08:00
self . metadata . setDefaultPageList (
self . comic_archive . getNumberOfPages ( ) )
2015-02-12 14:57:46 -08:00
self . updateCoverImage ( )
if self . page_browser is not None :
2015-02-13 15:08:07 -08:00
self . page_browser . setComicArchive ( self . comic_archive )
2015-02-12 14:57:46 -08:00
self . page_browser . metadata = self . metadata
self . metadataToForm ( )
2015-02-13 15:08:07 -08:00
self . pageListEditor . setData ( self . comic_archive , self . metadata . pages )
2015-02-12 14:57:46 -08:00
self . clearDirtyFlag ( ) # also updates the app title
self . updateInfoBox ( )
self . updateMenus ( )
self . updateAppTitle ( )
2015-02-13 15:08:07 -08:00
def updateCoverImage ( self ) :
2015-02-12 14:57:46 -08:00
cover_idx = self . metadata . getCoverPageIndexList ( ) [ 0 ]
2015-02-13 15:08:07 -08:00
self . archiveCoverWidget . setArchive ( self . comic_archive , cover_idx )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def updateMenus ( self ) :
2015-02-12 14:57:46 -08:00
# First just disable all the questionable items
2015-02-13 15:08:07 -08:00
self . actionAutoTag . setEnabled ( False )
self . actionCopyTags . setEnabled ( False )
self . actionRemoveAuto . setEnabled ( False )
self . actionRemoveCRTags . setEnabled ( False )
self . actionRemoveCBLTags . setEnabled ( False )
self . actionWrite_Tags . setEnabled ( False )
2015-02-12 14:57:46 -08:00
self . actionRepackage . setEnabled ( False )
2015-02-13 15:08:07 -08:00
self . actionViewRawCBLTags . setEnabled ( False )
self . actionViewRawCRTags . setEnabled ( False )
self . actionParse_Filename . setEnabled ( False )
self . actionAutoIdentify . setEnabled ( False )
self . actionRename . setEnabled ( False )
self . actionApplyCBLTransform . setEnabled ( False )
2015-02-12 14:57:46 -08:00
# now, selectively re-enable
2015-02-15 02:44:00 -08:00
if self . comic_archive is not None :
2015-02-12 14:57:46 -08:00
has_cix = self . comic_archive . hasCIX ( )
has_cbi = self . comic_archive . hasCBI ( )
2015-02-13 15:08:07 -08:00
self . actionParse_Filename . setEnabled ( True )
self . actionAutoIdentify . setEnabled ( True )
self . actionAutoTag . setEnabled ( True )
self . actionRename . setEnabled ( True )
self . actionApplyCBLTransform . setEnabled ( True )
2015-02-12 14:57:46 -08:00
self . actionRepackage . setEnabled ( True )
2015-02-13 15:08:07 -08:00
self . actionRemoveAuto . setEnabled ( True )
self . actionRemoveCRTags . setEnabled ( True )
self . actionRemoveCBLTags . setEnabled ( True )
self . actionCopyTags . setEnabled ( True )
2015-02-12 14:57:46 -08:00
if has_cix :
2015-02-13 15:08:07 -08:00
self . actionViewRawCRTags . setEnabled ( True )
2015-02-12 14:57:46 -08:00
if has_cbi :
2015-02-13 15:08:07 -08:00
self . actionViewRawCBLTags . setEnabled ( True )
2015-02-12 14:57:46 -08:00
if self . comic_archive . isWritable ( ) :
2015-02-13 15:08:07 -08:00
self . actionWrite_Tags . setEnabled ( True )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def updateInfoBox ( self ) :
2015-02-12 14:57:46 -08:00
ca = self . comic_archive
if ca is None :
2015-02-13 15:08:07 -08:00
self . lblFilename . setText ( " " )
self . lblArchiveType . setText ( " " )
self . lblTagList . setText ( " " )
self . lblPageCount . setText ( " " )
2015-02-12 14:57:46 -08:00
return
2015-02-13 15:08:07 -08:00
filename = os . path . basename ( ca . path )
2015-02-12 14:57:46 -08:00
filename = os . path . splitext ( filename ) [ 0 ]
filename = FileNameParser ( ) . fixSpaces ( filename , False )
2015-02-13 15:08:07 -08:00
self . lblFilename . setText ( filename )
2015-02-12 14:57:46 -08:00
2022-03-18 12:14:42 -07:00
if ca . isSevenZip ( ) :
self . lblArchiveType . setText ( " 7Z archive " )
elif ca . isZip ( ) :
2015-02-13 15:08:07 -08:00
self . lblArchiveType . setText ( " ZIP archive " )
2015-02-12 14:57:46 -08:00
elif ca . isRar ( ) :
2015-02-13 15:08:07 -08:00
self . lblArchiveType . setText ( " RAR archive " )
2015-02-12 14:57:46 -08:00
elif ca . isFolder ( ) :
2015-02-13 15:08:07 -08:00
self . lblArchiveType . setText ( " Folder archive " )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
self . lblArchiveType . setText ( " " )
2015-02-12 14:57:46 -08:00
page_count = " ( {0} pages) " . format ( ca . getNumberOfPages ( ) )
2015-02-13 15:08:07 -08:00
self . lblPageCount . setText ( page_count )
2015-02-12 14:57:46 -08:00
tag_info = " "
if ca . hasCIX ( ) :
2018-09-19 13:05:39 -07:00
tag_info = " • ComicRack tags "
2015-02-12 14:57:46 -08:00
if ca . hasCBI ( ) :
if tag_info != " " :
tag_info + = " \n "
2018-09-19 13:05:39 -07:00
tag_info + = " • ComicBookLover tags "
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
self . lblTagList . setText ( tag_info )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def setDirtyFlag ( self , param1 = None , param2 = None , param3 = None ) :
2015-02-12 14:57:46 -08:00
if not self . dirtyFlag :
self . dirtyFlag = True
2015-02-13 15:08:07 -08:00
self . fileSelectionList . setModifiedFlag ( True )
2015-02-12 14:57:46 -08:00
self . updateAppTitle ( )
2015-02-13 15:08:07 -08:00
def clearDirtyFlag ( self ) :
2015-02-12 14:57:46 -08:00
if self . dirtyFlag :
self . dirtyFlag = False
2015-02-13 15:08:07 -08:00
self . fileSelectionList . setModifiedFlag ( False )
2015-02-12 14:57:46 -08:00
self . updateAppTitle ( )
2015-02-13 15:08:07 -08:00
def connectDirtyFlagSignals ( self ) :
2015-02-21 18:30:32 -08:00
# recursively connect the tab form child slots
2015-02-13 15:08:07 -08:00
self . connectChildDirtyFlagSignals ( self . tabWidget )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
def connectChildDirtyFlagSignals ( self , widget ) :
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QLineEdit ) ) :
2015-02-12 14:57:46 -08:00
widget . textEdited . connect ( self . setDirtyFlag )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QTextEdit ) ) :
2015-02-12 14:57:46 -08:00
widget . textChanged . connect ( self . setDirtyFlag )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QComboBox ) ) :
2015-02-12 14:57:46 -08:00
widget . currentIndexChanged . connect ( self . setDirtyFlag )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QCheckBox ) ) :
2015-02-12 14:57:46 -08:00
widget . stateChanged . connect ( self . setDirtyFlag )
# recursive call on chillun
for child in widget . children ( ) :
if child != self . pageListEditor :
2015-02-13 15:08:07 -08:00
self . connectChildDirtyFlagSignals ( child )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def clearForm ( self ) :
2015-02-12 14:57:46 -08:00
# get a minty fresh metadata object
self . metadata = GenericMetadata ( )
if self . comic_archive is not None :
2015-02-15 02:44:00 -08:00
self . metadata . setDefaultPageList (
self . comic_archive . getNumberOfPages ( ) )
2015-02-12 14:57:46 -08:00
2015-02-21 18:30:32 -08:00
# recursively clear the tab form
2015-02-13 15:08:07 -08:00
self . clearChildren ( self . tabWidget )
2015-02-12 14:57:46 -08:00
# clear the dirty flag, since there is nothing in there now to lose
self . clearDirtyFlag ( )
2015-02-13 15:08:07 -08:00
self . pageListEditor . setData ( self . comic_archive , self . metadata . pages )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
def clearChildren ( self , widget ) :
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QLineEdit ) or
isinstance ( widget , QtWidgets . QTextEdit ) ) :
2015-02-12 14:57:46 -08:00
widget . setText ( " " )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QComboBox ) ) :
2015-02-13 15:08:07 -08:00
widget . setCurrentIndex ( 0 )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QCheckBox ) ) :
2015-02-13 15:08:07 -08:00
widget . setChecked ( False )
2018-09-19 13:05:39 -07:00
if ( isinstance ( widget , QtWidgets . QTableWidget ) ) :
2015-02-12 14:57:46 -08:00
while widget . rowCount ( ) > 0 :
widget . removeRow ( 0 )
# recursive call on chillun
for child in widget . children ( ) :
2015-02-13 15:08:07 -08:00
self . clearChildren ( child )
2015-02-12 14:57:46 -08:00
2021-08-07 21:54:29 -07:00
# Copy all of the metadata object into to the form.
# Merging of metadata should be done via the overlay function
2015-02-13 15:08:07 -08:00
def metadataToForm ( self ) :
def assignText ( field , value ) :
2015-02-12 14:57:46 -08:00
if value is not None :
2018-09-19 13:05:39 -07:00
field . setText ( str ( value ) )
2015-02-12 14:57:46 -08:00
md = self . metadata
2015-02-15 03:44:09 -08:00
assignText ( self . leSeries , md . series )
assignText ( self . leIssueNum , md . issue )
assignText ( self . leIssueCount , md . issueCount )
assignText ( self . leVolumeNum , md . volume )
assignText ( self . leVolumeCount , md . volumeCount )
assignText ( self . leTitle , md . title )
assignText ( self . lePublisher , md . publisher )
assignText ( self . lePubMonth , md . month )
assignText ( self . lePubYear , md . year )
2015-02-16 07:19:38 -08:00
assignText ( self . lePubDay , md . day )
2015-02-15 03:44:09 -08:00
assignText ( self . leGenre , md . genre )
assignText ( self . leImprint , md . imprint )
assignText ( self . teComments , md . comments )
assignText ( self . teNotes , md . notes )
2015-02-13 15:08:07 -08:00
assignText ( self . leCriticalRating , md . criticalRating )
2015-02-15 03:44:09 -08:00
assignText ( self . leStoryArc , md . storyArc )
assignText ( self . leScanInfo , md . scanInfo )
assignText ( self . leSeriesGroup , md . seriesGroup )
assignText ( self . leAltSeries , md . alternateSeries )
assignText ( self . leAltIssueNum , md . alternateNumber )
2015-02-13 15:08:07 -08:00
assignText ( self . leAltIssueCount , md . alternateCount )
2015-02-15 03:44:09 -08:00
assignText ( self . leWebLink , md . webLink )
assignText ( self . teCharacters , md . characters )
assignText ( self . teTeams , md . teams )
assignText ( self . teLocations , md . locations )
2015-02-12 14:57:46 -08:00
if md . format is not None and md . format != " " :
2015-02-13 15:08:07 -08:00
i = self . cbFormat . findText ( md . format )
2015-02-12 14:57:46 -08:00
if i == - 1 :
2015-02-13 15:08:07 -08:00
self . cbFormat . setEditText ( md . format )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
self . cbFormat . setCurrentIndex ( i )
2015-02-12 14:57:46 -08:00
if md . maturityRating is not None and md . maturityRating != " " :
2015-02-13 15:08:07 -08:00
i = self . cbMaturityRating . findText ( md . maturityRating )
2015-02-12 14:57:46 -08:00
if i == - 1 :
2015-02-13 15:08:07 -08:00
self . cbMaturityRating . setEditText ( md . maturityRating )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
self . cbMaturityRating . setCurrentIndex ( i )
2021-08-07 21:54:29 -07:00
else :
self . cbMaturityRating . setCurrentIndex ( 0 )
2015-02-12 14:57:46 -08:00
if md . language is not None :
2015-02-13 15:08:07 -08:00
i = self . cbLanguage . findData ( md . language )
self . cbLanguage . setCurrentIndex ( i )
2021-08-07 21:54:29 -07:00
else :
self . cbLanguage . setCurrentIndex ( 0 )
2015-02-12 14:57:46 -08:00
if md . country is not None :
2015-02-13 15:08:07 -08:00
i = self . cbCountry . findText ( md . country )
self . cbCountry . setCurrentIndex ( i )
2021-08-07 21:54:29 -07:00
else :
self . cbCountry . setCurrentIndex ( 0 )
2015-02-12 14:57:46 -08:00
if md . manga is not None :
2015-02-13 15:08:07 -08:00
i = self . cbManga . findData ( md . manga )
self . cbManga . setCurrentIndex ( i )
2021-08-07 21:54:29 -07:00
else :
self . cbManga . setCurrentIndex ( 0 )
2015-02-12 14:57:46 -08:00
2021-08-07 21:54:29 -07:00
if md . blackAndWhite :
2015-02-13 15:08:07 -08:00
self . cbBW . setChecked ( True )
2021-08-07 21:54:29 -07:00
else :
self . cbBW . setChecked ( False )
2015-02-12 14:57:46 -08:00
2021-08-07 21:54:29 -07:00
self . teTags . setText ( utils . listToString ( md . tags ) )
2015-02-12 14:57:46 -08:00
# !!! Should we clear the credits table or just avoid duplicates?
while self . twCredits . rowCount ( ) > 0 :
self . twCredits . removeRow ( 0 )
if md . credits is not None and len ( md . credits ) != 0 :
2015-02-13 15:08:07 -08:00
self . twCredits . setSortingEnabled ( False )
2015-02-12 14:57:46 -08:00
row = 0
for credit in md . credits :
2015-02-15 02:44:00 -08:00
# if the role-person pair already exists, just skip adding it
# to the list
2015-02-13 15:08:07 -08:00
if self . isDupeCredit ( credit [ ' role ' ] . title ( ) , credit [ ' person ' ] ) :
2015-02-12 14:57:46 -08:00
continue
2015-02-15 03:55:04 -08:00
self . addNewCreditEntry (
row ,
credit [ ' role ' ] . title ( ) ,
credit [ ' person ' ] ,
( credit [ ' primary ' ] if ' primary ' in credit else False ) )
2015-02-12 14:57:46 -08:00
row + = 1
2015-02-13 15:08:07 -08:00
self . twCredits . setSortingEnabled ( True )
2015-02-12 14:57:46 -08:00
self . updateCreditColors ( )
2015-02-13 15:08:07 -08:00
def addNewCreditEntry ( self , row , role , name , primary_flag = False ) :
2015-02-12 14:57:46 -08:00
self . twCredits . insertRow ( row )
item_text = role
2018-09-19 13:05:39 -07:00
item = QtWidgets . QTableWidgetItem ( item_text )
2015-02-15 02:44:00 -08:00
item . setFlags ( QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEnabled )
2015-02-13 15:08:07 -08:00
item . setData ( QtCore . Qt . ToolTipRole , item_text )
2015-02-12 14:57:46 -08:00
self . twCredits . setItem ( row , 1 , item )
item_text = name
2018-09-19 13:05:39 -07:00
item = QtWidgets . QTableWidgetItem ( item_text )
2015-02-13 15:08:07 -08:00
item . setData ( QtCore . Qt . ToolTipRole , item_text )
2015-02-15 02:44:00 -08:00
item . setFlags ( QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEnabled )
2015-02-12 14:57:46 -08:00
self . twCredits . setItem ( row , 2 , item )
2018-09-19 13:05:39 -07:00
item = QtWidgets . QTableWidgetItem ( " " )
2015-02-15 02:44:00 -08:00
item . setFlags ( QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEnabled )
2015-02-12 14:57:46 -08:00
self . twCredits . setItem ( row , 0 , item )
2015-02-13 15:08:07 -08:00
self . updateCreditPrimaryFlag ( row , primary_flag )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def isDupeCredit ( self , role , name ) :
2015-02-12 14:57:46 -08:00
r = 0
while r < self . twCredits . rowCount ( ) :
2015-02-13 15:08:07 -08:00
if ( self . twCredits . item ( r , 1 ) . text ( ) == role and
self . twCredits . item ( r , 2 ) . text ( ) == name ) :
2015-02-12 14:57:46 -08:00
return True
r = r + 1
return False
2015-02-13 15:08:07 -08:00
def formToMetadata ( self ) :
2015-02-12 14:57:46 -08:00
# copy the data from the form into the metadata
2021-08-07 21:54:29 -07:00
md = GenericMetadata ( )
md . isEmpty = False
md . alternateNumber = IssueString ( self . leAltIssueNum . text ( ) ) . asString ( )
md . issue = IssueString ( self . leIssueNum . text ( ) ) . asString ( )
md . issueCount = utils . xlate ( self . leIssueCount . text ( ) , True )
md . volume = utils . xlate ( self . leVolumeNum . text ( ) , True )
md . volumeCount = utils . xlate ( self . leVolumeCount . text ( ) , True )
md . month = utils . xlate ( self . lePubMonth . text ( ) , True )
md . year = utils . xlate ( self . lePubYear . text ( ) , True )
md . day = utils . xlate ( self . lePubDay . text ( ) , True )
md . criticalRating = utils . xlate ( self . leCriticalRating . text ( ) , True )
md . alternateCount = utils . xlate ( self . leAltIssueCount . text ( ) , True )
md . series = self . leSeries . text ( )
md . title = self . leTitle . text ( )
md . publisher = self . lePublisher . text ( )
md . genre = self . leGenre . text ( )
md . imprint = self . leImprint . text ( )
md . comments = self . teComments . toPlainText ( )
md . notes = self . teNotes . toPlainText ( )
md . maturityRating = self . cbMaturityRating . currentText ( )
md . storyArc = self . leStoryArc . text ( )
md . scanInfo = self . leScanInfo . text ( )
md . seriesGroup = self . leSeriesGroup . text ( )
md . alternateSeries = self . leAltSeries . text ( )
md . webLink = self . leWebLink . text ( )
md . characters = self . teCharacters . toPlainText ( )
md . teams = self . teTeams . toPlainText ( )
md . locations = self . teLocations . toPlainText ( )
md . format = self . cbFormat . currentText ( )
md . country = self . cbCountry . currentText ( )
md . language = utils . xlate ( self . cbLanguage . itemData ( self . cbLanguage . currentIndex ( ) ) )
md . manga = utils . xlate ( self . cbManga . itemData ( self . cbManga . currentIndex ( ) ) )
2015-02-12 14:57:46 -08:00
# Make a list from the coma delimited tags string
2021-08-07 21:54:29 -07:00
tmp = self . teTags . toPlainText ( )
2015-02-15 03:44:09 -08:00
if tmp is not None :
2015-02-12 14:57:46 -08:00
def striplist ( l ) :
return ( [ x . strip ( ) for x in l ] )
2015-02-13 15:08:07 -08:00
md . tags = striplist ( tmp . split ( " , " ) )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
if ( self . cbBW . isChecked ( ) ) :
2015-02-12 14:57:46 -08:00
md . blackAndWhite = True
else :
md . blackAndWhite = False
# get the credits from the table
md . credits = list ( )
row = 0
while row < self . twCredits . rowCount ( ) :
2018-09-19 13:05:39 -07:00
role = " {0} " . format ( self . twCredits . item ( row , 1 ) . text ( ) )
name = " {0} " . format ( self . twCredits . item ( row , 2 ) . text ( ) )
2015-02-13 15:08:07 -08:00
primary_flag = self . twCredits . item ( row , 0 ) . text ( ) != " "
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
md . addCredit ( name , role , bool ( primary_flag ) )
2015-02-12 14:57:46 -08:00
row + = 1
md . pages = self . pageListEditor . getPageList ( )
2021-08-07 21:54:29 -07:00
self . metadata = md
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def useFilename ( self ) :
2015-02-12 14:57:46 -08:00
if self . comic_archive is not None :
2015-02-15 02:44:00 -08:00
# copy the form onto metadata object
2015-02-12 14:57:46 -08:00
self . formToMetadata ( )
2015-02-15 02:44:00 -08:00
new_metadata = self . comic_archive . metadataFromFilename (
self . settings . parse_scan_info )
2015-02-12 14:57:46 -08:00
if new_metadata is not None :
2015-02-13 15:08:07 -08:00
self . metadata . overlay ( new_metadata )
2015-02-12 14:57:46 -08:00
self . metadataToForm ( )
2015-02-13 15:08:07 -08:00
def selectFolder ( self ) :
self . selectFile ( folder_mode = True )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
def selectFile ( self , folder_mode = False ) :
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
dialog = QtWidgets . QFileDialog ( self )
2015-02-12 14:57:46 -08:00
if folder_mode :
2018-09-19 13:05:39 -07:00
dialog . setFileMode ( QtWidgets . QFileDialog . Directory )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
dialog . setFileMode ( QtWidgets . QFileDialog . ExistingFiles )
2015-02-12 14:57:46 -08:00
if self . settings . last_opened_folder is not None :
2015-02-13 15:08:07 -08:00
dialog . setDirectory ( self . settings . last_opened_folder )
2015-02-12 14:57:46 -08:00
if not folder_mode :
2022-03-18 12:14:42 -07:00
archive_filter = " Comic archive files (*.cb7 *.7z *.cbz *.zip *.cbr *.rar) "
2015-02-15 02:44:00 -08:00
filters = [
archive_filter ,
" Any files (*) "
]
2015-02-12 14:57:46 -08:00
dialog . setNameFilters ( filters )
if ( dialog . exec_ ( ) ) :
fileList = dialog . selectedFiles ( )
2015-02-15 02:44:00 -08:00
# if self.dirtyFlagVerification("Open Archive",
2015-02-12 14:57:46 -08:00
# "If you open a new archive now, data in the form will be lost. Are you sure?"):
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addPathList ( fileList )
2015-02-12 14:57:46 -08:00
def autoIdentifySearch ( self ) :
if self . comic_archive is None :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . warning (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Automatic Identify Search " ) ,
self . tr ( " You need to load a comic first! " ) )
2015-02-12 14:57:46 -08:00
return
2015-02-13 15:08:07 -08:00
self . queryOnline ( autoselect = True )
2015-02-12 14:57:46 -08:00
def queryOnline ( self , autoselect = False ) :
2018-09-19 13:05:39 -07:00
issue_number = str ( self . leIssueNum . text ( ) ) . strip ( )
2015-02-12 14:57:46 -08:00
if autoselect and issue_number == " " :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self ,
" Automatic Identify Search " ,
" Can ' t auto-identify without an issue number (yet!) " )
2015-02-12 14:57:46 -08:00
return
2018-09-19 13:05:39 -07:00
if str ( self . leSeries . text ( ) ) . strip ( ) != " " :
series_name = str ( self . leSeries . text ( ) ) . strip ( )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Online Search " ) ,
self . tr ( " Need to enter a series name to search. " ) )
2015-02-12 14:57:46 -08:00
return
year = str ( self . lePubYear . text ( ) ) . strip ( )
if year == " " :
year = None
issue_count = str ( self . leIssueCount . text ( ) ) . strip ( )
if issue_count == " " :
issue_count = None
2015-02-15 02:44:00 -08:00
cover_index_list = self . metadata . getCoverPageIndexList ( )
selector = VolumeSelectionWindow (
2015-02-15 03:55:04 -08:00
self ,
series_name ,
issue_number ,
year ,
issue_count ,
cover_index_list ,
self . comic_archive ,
self . settings ,
autoselect )
2015-02-12 14:57:46 -08:00
title = " Search: ' " + series_name + " ' - "
2015-02-13 15:08:07 -08:00
selector . setWindowTitle ( title + " Select Series " )
2015-02-12 14:57:46 -08:00
selector . setModal ( True )
selector . exec_ ( )
if selector . result ( ) :
2015-02-15 02:44:00 -08:00
# we should now have a volume ID
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . setOverrideCursor (
2015-02-15 02:44:00 -08:00
QtGui . QCursor ( QtCore . Qt . WaitCursor ) )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
# copy the form onto metadata object
2015-02-12 14:57:46 -08:00
self . formToMetadata ( )
try :
comicVine = ComicVineTalker ( )
2015-02-15 02:44:00 -08:00
new_metadata = comicVine . fetchIssueData (
selector . volume_id , selector . issue_number , self . settings )
2015-02-12 14:57:46 -08:00
except ComicVineTalkerException as e :
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . restoreOverrideCursor ( )
2015-02-12 14:57:46 -08:00
if e . code == ComicVineTalkerException . RateLimit :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . critical (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Comic Vine Error " ) ,
ComicVineTalker . getRateLimitMessage ( ) )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . critical (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Network Issue " ) ,
2015-02-21 18:30:32 -08:00
self . tr ( " Could not connect to Comic Vine to get issue details.! " ) )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . restoreOverrideCursor ( )
2015-02-12 14:57:46 -08:00
if new_metadata is not None :
if self . settings . apply_cbl_transform_on_cv_import :
2015-02-15 02:44:00 -08:00
new_metadata = CBLTransformer (
new_metadata , self . settings ) . apply ( )
2015-02-12 14:57:46 -08:00
if self . settings . clear_form_before_populating_from_cv :
self . clearForm ( )
2015-02-13 15:08:07 -08:00
self . metadata . overlay ( new_metadata )
2015-02-12 14:57:46 -08:00
# Now push the new combined data into the edit controls
self . metadataToForm ( )
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . critical (
2015-02-15 03:55:04 -08:00
self , self . tr ( " Search " ) , self . tr (
" Could not find an issue {0} for that series " . format (
selector . issue_number ) ) )
2015-02-12 14:57:46 -08:00
def commitMetadata ( self ) :
2015-02-13 15:08:07 -08:00
if ( self . metadata is not None and self . comic_archive is not None ) :
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Save Tags " ) ,
self . tr (
" Are you sure you wish to save " +
MetaDataStyle . name [
self . save_data_style ] +
" tags to this archive? " ) ,
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . Yes ,
QtWidgets . QMessageBox . No )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if reply == QtWidgets . QMessageBox . Yes :
QtWidgets . QApplication . setOverrideCursor (
2015-02-15 02:44:00 -08:00
QtGui . QCursor ( QtCore . Qt . WaitCursor ) )
2015-02-12 14:57:46 -08:00
self . formToMetadata ( )
2015-02-15 02:44:00 -08:00
success = self . comic_archive . writeMetadata (
self . metadata , self . save_data_style )
self . comic_archive . loadCache (
[ MetaDataStyle . CBI , MetaDataStyle . CIX ] )
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . restoreOverrideCursor ( )
2015-02-12 14:57:46 -08:00
if not success :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . warning (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Save failed " ) ,
self . tr ( " The tag save operation seemed to fail! " ) )
2015-02-12 14:57:46 -08:00
else :
self . clearDirtyFlag ( )
self . updateInfoBox ( )
self . updateMenus ( )
2018-09-19 13:05:39 -07:00
#QtWidgets.QMessageBox.information(self, self.tr("Yeah!"), self.tr("File written."))
2015-02-12 14:57:46 -08:00
self . fileSelectionList . updateCurrentRow ( )
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 02:44:00 -08:00
self , self . tr ( " Whoops! " ) , self . tr ( " No data to commit! " ) )
2015-02-12 14:57:46 -08:00
def setLoadDataStyle ( self , s ) :
2015-02-15 03:55:04 -08:00
if self . dirtyFlagVerification (
" Change Tag Read Style " ,
" If you change read tag style now, data in the form will be lost. Are you sure? " ) :
2018-09-19 13:05:39 -07:00
self . load_data_style = self . cbLoadDataStyle . itemData ( s )
2015-02-12 14:57:46 -08:00
self . settings . last_selected_load_data_style = self . load_data_style
self . updateMenus ( )
if self . comic_archive is not None :
2015-02-13 15:08:07 -08:00
self . loadArchive ( self . comic_archive )
2015-02-12 14:57:46 -08:00
else :
2015-02-15 02:44:00 -08:00
self . cbLoadDataStyle . currentIndexChanged . disconnect (
self . setLoadDataStyle )
2015-02-12 14:57:46 -08:00
self . adjustLoadStyleCombo ( )
2015-02-15 02:44:00 -08:00
self . cbLoadDataStyle . currentIndexChanged . connect (
self . setLoadDataStyle )
2015-02-12 14:57:46 -08:00
def setSaveDataStyle ( self , s ) :
2018-09-19 13:05:39 -07:00
self . save_data_style = self . cbSaveDataStyle . itemData ( s )
2015-02-12 14:57:46 -08:00
self . settings . last_selected_save_data_style = self . save_data_style
self . updateStyleTweaks ( )
self . updateMenus ( )
2015-02-13 15:08:07 -08:00
def updateCreditColors ( self ) :
2018-09-19 13:05:39 -07:00
#!!!ATB qt5 porting TODO
2022-03-18 12:14:42 -07:00
#return
2015-02-12 14:57:46 -08:00
inactive_color = QtGui . QColor ( 255 , 170 , 150 )
active_palette = self . leSeries . palette ( )
2015-02-13 15:08:07 -08:00
active_color = active_palette . color ( QtGui . QPalette . Base )
2022-03-18 12:14:42 -07:00
2018-09-19 13:05:39 -07:00
inactive_brush = QtGui . QBrush ( inactive_color )
active_brush = QtGui . QBrush ( active_color )
2015-02-12 14:57:46 -08:00
cix_credits = ComicInfoXml ( ) . getParseableCredits ( )
if self . save_data_style == MetaDataStyle . CIX :
2015-02-15 02:44:00 -08:00
# loop over credit table, mark selected rows
2015-02-12 14:57:46 -08:00
r = 0
while r < self . twCredits . rowCount ( ) :
2015-02-15 03:44:09 -08:00
if str ( self . twCredits . item ( r , 1 ) . text ( )
) . lower ( ) not in cix_credits :
2015-02-15 02:44:00 -08:00
self . twCredits . item (
2018-09-19 13:05:39 -07:00
r , 1 ) . setBackground ( inactive_brush )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
self . twCredits . item ( r , 1 ) . setBackground ( active_brush )
2015-02-12 14:57:46 -08:00
# turn off entire primary column
2018-09-19 13:05:39 -07:00
self . twCredits . item ( r , 0 ) . setBackground ( inactive_brush )
2015-02-12 14:57:46 -08:00
r = r + 1
if self . save_data_style == MetaDataStyle . CBI :
2015-02-15 02:44:00 -08:00
# loop over credit table, make all active color
2015-02-12 14:57:46 -08:00
r = 0
while r < self . twCredits . rowCount ( ) :
2018-09-19 13:05:39 -07:00
self . twCredits . item ( r , 0 ) . setBackground ( active_brush )
self . twCredits . item ( r , 1 ) . setBackground ( active_brush )
2015-02-12 14:57:46 -08:00
r = r + 1
2015-02-13 15:08:07 -08:00
def updateStyleTweaks ( self ) :
2015-02-12 14:57:46 -08:00
# depending on the current data style, certain fields are disabled
inactive_color = QtGui . QColor ( 255 , 170 , 150 )
active_palette = self . leSeries . palette ( )
inactive_palette1 = self . leSeries . palette ( )
inactive_palette1 . setColor ( QtGui . QPalette . Base , inactive_color )
inactive_palette2 = self . leSeries . palette ( )
inactive_palette3 = self . leSeries . palette ( )
inactive_palette3 . setColor ( QtGui . QPalette . Base , inactive_color )
inactive_palette3 . setColor ( QtGui . QPalette . Base , inactive_color )
2015-02-15 02:44:00 -08:00
# helper func
2015-02-13 15:08:07 -08:00
def enableWidget ( item , enable ) :
2015-02-12 14:57:46 -08:00
inactive_palette3 . setColor ( item . backgroundRole ( ) , inactive_color )
inactive_palette2 . setColor ( item . backgroundRole ( ) , inactive_color )
inactive_palette3 . setColor ( item . foregroundRole ( ) , inactive_color )
if enable :
item . setPalette ( active_palette )
2015-02-13 15:08:07 -08:00
item . setAutoFillBackground ( False )
2018-09-19 13:05:39 -07:00
if isinstance ( item , QtWidgets . QCheckBox ) :
2015-02-13 15:08:07 -08:00
item . setEnabled ( True )
2018-09-19 13:05:39 -07:00
elif isinstance ( item , QtWidgets . QComboBox ) :
2015-02-13 15:08:07 -08:00
item . setEnabled ( True )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
item . setReadOnly ( False )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
item . setAutoFillBackground ( True )
2018-09-19 13:05:39 -07:00
if isinstance ( item , QtWidgets . QCheckBox ) :
2015-02-12 14:57:46 -08:00
item . setPalette ( inactive_palette2 )
2015-02-13 15:08:07 -08:00
item . setEnabled ( False )
2018-09-19 13:05:39 -07:00
elif isinstance ( item , QtWidgets . QComboBox ) :
2015-02-12 14:57:46 -08:00
item . setPalette ( inactive_palette3 )
2015-02-13 15:08:07 -08:00
item . setEnabled ( False )
2015-02-12 14:57:46 -08:00
else :
2015-02-13 15:08:07 -08:00
item . setReadOnly ( True )
2015-02-12 14:57:46 -08:00
item . setPalette ( inactive_palette1 )
2015-02-15 02:44:00 -08:00
cbi_only = [ self . leVolumeCount , self . cbCountry ,
self . leCriticalRating , self . teTags ]
2015-02-12 14:57:46 -08:00
cix_only = [
2015-02-15 02:44:00 -08:00
self . leImprint , self . teNotes , self . cbBW , self . cbManga ,
self . leStoryArc , self . leScanInfo , self . leSeriesGroup ,
self . leAltSeries , self . leAltIssueNum , self . leAltIssueCount ,
self . leWebLink , self . teCharacters , self . teTeams ,
self . teLocations , self . cbMaturityRating , self . cbFormat
]
2015-02-12 14:57:46 -08:00
if self . save_data_style == MetaDataStyle . CIX :
for item in cix_only :
2015-02-13 15:08:07 -08:00
enableWidget ( item , True )
2015-02-12 14:57:46 -08:00
for item in cbi_only :
2015-02-13 15:08:07 -08:00
enableWidget ( item , False )
2015-02-12 14:57:46 -08:00
if self . save_data_style == MetaDataStyle . CBI :
for item in cbi_only :
2015-02-13 15:08:07 -08:00
enableWidget ( item , True )
2015-02-12 14:57:46 -08:00
for item in cix_only :
2015-02-13 15:08:07 -08:00
enableWidget ( item , False )
2015-02-12 14:57:46 -08:00
self . updateCreditColors ( )
2015-02-13 15:08:07 -08:00
self . pageListEditor . setMetadataStyle ( self . save_data_style )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def cellDoubleClicked ( self , r , c ) :
2015-02-12 14:57:46 -08:00
self . editCredit ( )
2015-02-13 15:08:07 -08:00
def addCredit ( self ) :
self . modifyCredits ( " add " )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def editCredit ( self ) :
if ( self . twCredits . currentRow ( ) > - 1 ) :
self . modifyCredits ( " edit " )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def updateCreditPrimaryFlag ( self , row , primary ) :
2015-02-12 14:57:46 -08:00
# if we're clearing a flagm do it and quit
if not primary :
2015-02-13 15:08:07 -08:00
self . twCredits . item ( row , 0 ) . setText ( " " )
2015-02-12 14:57:46 -08:00
return
2015-02-15 02:44:00 -08:00
# otherwise, we need to check for, and clear, other primaries with same
# role
2015-02-12 14:57:46 -08:00
role = str ( self . twCredits . item ( row , 1 ) . text ( ) )
r = 0
while r < self . twCredits . rowCount ( ) :
2015-02-15 03:55:04 -08:00
if ( self . twCredits . item ( r , 0 ) . text ( ) != " " and str (
self . twCredits . item ( r , 1 ) . text ( ) ) . lower ( ) == role . lower ( ) ) :
2015-02-13 15:08:07 -08:00
self . twCredits . item ( r , 0 ) . setText ( " " )
2015-02-12 14:57:46 -08:00
r = r + 1
# Now set our new primary
2015-02-13 15:08:07 -08:00
self . twCredits . item ( row , 0 ) . setText ( " Yes " )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
def modifyCredits ( self , action ) :
2015-02-12 14:57:46 -08:00
if action == " edit " :
row = self . twCredits . currentRow ( )
2015-02-13 15:08:07 -08:00
role = self . twCredits . item ( row , 1 ) . text ( )
name = self . twCredits . item ( row , 2 ) . text ( )
primary = self . twCredits . item ( row , 0 ) . text ( ) != " "
2015-02-12 14:57:46 -08:00
else :
role = " "
name = " "
primary = False
2015-02-15 02:44:00 -08:00
editor = CreditEditorWindow (
self , CreditEditorWindow . ModeEdit , role , name , primary )
2015-02-12 14:57:46 -08:00
editor . setModal ( True )
editor . exec_ ( )
if editor . result ( ) :
2015-02-15 02:44:00 -08:00
new_role , new_name , new_primary = editor . getCredits ( )
2015-02-12 14:57:46 -08:00
if new_name == name and new_role == role and new_primary == primary :
2015-02-15 02:44:00 -08:00
# nothing has changed, just quit
2015-02-12 14:57:46 -08:00
return
# name and role is the same, but primary flag changed
if new_name == name and new_role == role :
2015-02-13 15:08:07 -08:00
self . updateCreditPrimaryFlag ( row , new_primary )
2015-02-12 14:57:46 -08:00
return
# check for dupes
ok_to_mod = True
2015-02-13 15:08:07 -08:00
if self . isDupeCredit ( new_role , new_name ) :
2015-02-12 14:57:46 -08:00
# delete the dupe credit from list
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Duplicate Credit! " ) ,
2015-02-21 18:30:32 -08:00
self . tr (
" This will create a duplicate credit entry. Would you like to merge the entries, or create a duplicate? " ) ,
2015-02-15 03:55:04 -08:00
self . tr ( " Merge " ) ,
self . tr ( " Duplicate " ) )
2015-02-12 14:57:46 -08:00
if reply == 0 :
# merge
if action == " edit " :
# just remove the row that would be same
2015-02-13 15:08:07 -08:00
self . twCredits . removeRow ( row )
2015-02-15 02:44:00 -08:00
# TODO -- need to find the row of the dupe, and
# possible change the primary flag
2015-02-12 14:57:46 -08:00
ok_to_mod = False
if ok_to_mod :
2015-02-15 02:44:00 -08:00
# modify it
2015-02-12 14:57:46 -08:00
if action == " edit " :
2015-02-13 15:08:07 -08:00
self . twCredits . item ( row , 1 ) . setText ( new_role )
self . twCredits . item ( row , 2 ) . setText ( new_name )
self . updateCreditPrimaryFlag ( row , new_primary )
2015-02-12 14:57:46 -08:00
else :
# add new entry
row = self . twCredits . rowCount ( )
2015-02-15 02:44:00 -08:00
self . addNewCreditEntry (
row , new_role , new_name , new_primary )
2015-02-12 14:57:46 -08:00
self . updateCreditColors ( )
self . setDirtyFlag ( )
2015-02-13 15:08:07 -08:00
def removeCredit ( self ) :
2015-02-12 14:57:46 -08:00
row = self . twCredits . currentRow ( )
2015-02-15 02:44:00 -08:00
if row != - 1 :
2015-02-13 15:08:07 -08:00
self . twCredits . removeRow ( row )
2015-02-12 14:57:46 -08:00
self . setDirtyFlag ( )
2022-03-31 09:40:43 -07:00
def openWebLink ( self ) :
if self . leWebLink is not None :
2022-03-31 10:34:40 -07:00
web_link = self . leWebLink . text ( ) . strip ( ) ;
2022-04-01 06:48:53 -07:00
valid = False ;
try :
result = urlparse ( web_link )
valid = all ( [ result . scheme in [ " http " , " https " ] , result . netloc ] )
except :
pass
if valid :
webbrowser . open_new_tab ( web_link )
else :
QtWidgets . QMessageBox . warning (
self ,
self . tr ( " Web Link " ) ,
self . tr ( " Web Link is invalid. " ) )
2022-03-31 09:40:43 -07:00
2015-02-13 15:08:07 -08:00
def showSettings ( self ) :
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
settingswin = SettingsWindow ( self , self . settings )
2015-02-12 14:57:46 -08:00
settingswin . setModal ( True )
settingswin . exec_ ( )
if settingswin . result ( ) :
pass
2015-02-13 15:08:07 -08:00
def setAppPosition ( self ) :
2015-02-12 14:57:46 -08:00
if self . settings . last_main_window_width != 0 :
2015-02-15 02:44:00 -08:00
self . move (
2015-02-15 03:55:04 -08:00
self . settings . last_main_window_x ,
self . settings . last_main_window_y )
2015-02-15 02:44:00 -08:00
self . resize (
2015-02-15 03:55:04 -08:00
self . settings . last_main_window_width ,
self . settings . last_main_window_height )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
screen = QtWidgets . QDesktopWidget ( ) . screenGeometry ( )
2015-02-15 02:44:00 -08:00
size = self . frameGeometry ( )
2022-02-21 20:05:07 -08:00
self . move ( int ( ( screen . width ( ) - size . width ( ) ) / 2 ) ,
int ( ( screen . height ( ) - size . height ( ) ) / 2 ) )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def adjustLoadStyleCombo ( self ) :
2015-02-12 14:57:46 -08:00
# select the current style
2015-02-13 15:08:07 -08:00
if ( self . load_data_style == MetaDataStyle . CBI ) :
2015-02-15 02:44:00 -08:00
self . cbLoadDataStyle . setCurrentIndex ( 0 )
2015-02-13 15:08:07 -08:00
elif ( self . load_data_style == MetaDataStyle . CIX ) :
2015-02-15 02:44:00 -08:00
self . cbLoadDataStyle . setCurrentIndex ( 1 )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def adjustSaveStyleCombo ( self ) :
2015-02-12 14:57:46 -08:00
# select the current style
2015-02-13 15:08:07 -08:00
if ( self . save_data_style == MetaDataStyle . CBI ) :
2015-02-15 02:44:00 -08:00
self . cbSaveDataStyle . setCurrentIndex ( 0 )
2015-02-13 15:08:07 -08:00
elif ( self . save_data_style == MetaDataStyle . CIX ) :
2015-02-15 02:44:00 -08:00
self . cbSaveDataStyle . setCurrentIndex ( 1 )
2015-02-12 14:57:46 -08:00
self . updateStyleTweaks ( )
2015-02-13 15:08:07 -08:00
def populateComboBoxes ( self ) :
2015-02-12 14:57:46 -08:00
# Add the entries to the tag style combobox
2015-02-13 15:08:07 -08:00
self . cbLoadDataStyle . addItem ( " ComicBookLover " , MetaDataStyle . CBI )
self . cbLoadDataStyle . addItem ( " ComicRack " , MetaDataStyle . CIX )
2015-02-12 14:57:46 -08:00
self . adjustLoadStyleCombo ( )
2015-02-13 15:08:07 -08:00
self . cbSaveDataStyle . addItem ( " ComicBookLover " , MetaDataStyle . CBI )
self . cbSaveDataStyle . addItem ( " ComicRack " , MetaDataStyle . CIX )
2015-02-12 14:57:46 -08:00
self . adjustSaveStyleCombo ( )
# Add the entries to the country combobox
2015-02-13 15:08:07 -08:00
self . cbCountry . addItem ( " " , " " )
2015-02-12 14:57:46 -08:00
for c in utils . countries :
2015-02-13 15:08:07 -08:00
self . cbCountry . addItem ( c [ 1 ] , c [ 0 ] )
2015-02-12 14:57:46 -08:00
# Add the entries to the language combobox
2015-02-13 15:08:07 -08:00
self . cbLanguage . addItem ( " " , " " )
2015-02-12 14:57:46 -08:00
lang_dict = utils . getLanguageDict ( )
2019-08-16 13:16:25 -07:00
for key in sorted ( lang_dict , key = lang_dict . get ) :
2015-02-13 15:08:07 -08:00
self . cbLanguage . addItem ( lang_dict [ key ] , key )
2015-02-12 14:57:46 -08:00
# Add the entries to the manga combobox
2015-02-13 15:08:07 -08:00
self . cbManga . addItem ( " " , " " )
self . cbManga . addItem ( " Yes " , " Yes " )
self . cbManga . addItem ( " Yes (Right to Left) " , " YesAndRightToLeft " )
self . cbManga . addItem ( " No " , " No " )
2015-02-12 14:57:46 -08:00
# Add the entries to the maturity combobox
2015-02-13 15:08:07 -08:00
self . cbMaturityRating . addItem ( " " , " " )
self . cbMaturityRating . addItem ( " Everyone " , " " )
self . cbMaturityRating . addItem ( " G " , " " )
self . cbMaturityRating . addItem ( " Early Childhood " , " " )
self . cbMaturityRating . addItem ( " Everyone 10+ " , " " )
self . cbMaturityRating . addItem ( " PG " , " " )
self . cbMaturityRating . addItem ( " Kids to Adults " , " " )
self . cbMaturityRating . addItem ( " Teen " , " " )
self . cbMaturityRating . addItem ( " MA15+ " , " " )
self . cbMaturityRating . addItem ( " Mature 17+ " , " " )
self . cbMaturityRating . addItem ( " R18+ " , " " )
self . cbMaturityRating . addItem ( " X18+ " , " " )
self . cbMaturityRating . addItem ( " Adults Only 18+ " , " " )
self . cbMaturityRating . addItem ( " Rating Pending " , " " )
2015-02-12 14:57:46 -08:00
# Add entries to the format combobox
self . cbFormat . addItem ( " " )
self . cbFormat . addItem ( " .1 " )
self . cbFormat . addItem ( " -1 " )
self . cbFormat . addItem ( " 1 Shot " )
self . cbFormat . addItem ( " 1/2 " )
self . cbFormat . addItem ( " 1-Shot " )
self . cbFormat . addItem ( " Annotation " )
self . cbFormat . addItem ( " Annotations " )
self . cbFormat . addItem ( " Annual " )
self . cbFormat . addItem ( " Anthology " )
self . cbFormat . addItem ( " B&W " )
self . cbFormat . addItem ( " B/W " )
self . cbFormat . addItem ( " B&&W " )
self . cbFormat . addItem ( " Black & White " )
self . cbFormat . addItem ( " Box Set " )
self . cbFormat . addItem ( " Box-Set " )
self . cbFormat . addItem ( " Crossover " )
self . cbFormat . addItem ( " Director ' s Cut " )
self . cbFormat . addItem ( " Epilogue " )
self . cbFormat . addItem ( " Event " )
self . cbFormat . addItem ( " FCBD " )
self . cbFormat . addItem ( " Flyer " )
self . cbFormat . addItem ( " Giant " )
self . cbFormat . addItem ( " Giant Size " )
self . cbFormat . addItem ( " Giant-Size " )
self . cbFormat . addItem ( " Graphic Novel " )
self . cbFormat . addItem ( " Hardcover " )
self . cbFormat . addItem ( " Hard-Cover " )
self . cbFormat . addItem ( " King " )
self . cbFormat . addItem ( " King Size " )
self . cbFormat . addItem ( " King-Size " )
self . cbFormat . addItem ( " Limited Series " )
self . cbFormat . addItem ( " Magazine " )
self . cbFormat . addItem ( " -1 " )
self . cbFormat . addItem ( " NSFW " )
self . cbFormat . addItem ( " One Shot " )
self . cbFormat . addItem ( " One-Shot " )
self . cbFormat . addItem ( " Point 1 " )
self . cbFormat . addItem ( " Preview " )
self . cbFormat . addItem ( " Prologue " )
self . cbFormat . addItem ( " Reference " )
self . cbFormat . addItem ( " Review " )
self . cbFormat . addItem ( " Reviewed " )
self . cbFormat . addItem ( " Scanlation " )
self . cbFormat . addItem ( " Script " )
self . cbFormat . addItem ( " Series " )
self . cbFormat . addItem ( " Sketch " )
self . cbFormat . addItem ( " Special " )
self . cbFormat . addItem ( " TPB " )
self . cbFormat . addItem ( " Trade Paper Back " )
self . cbFormat . addItem ( " WebComic " )
self . cbFormat . addItem ( " Web Comic " )
self . cbFormat . addItem ( " Year 1 " )
self . cbFormat . addItem ( " Year One " )
2015-02-13 15:08:07 -08:00
def removeAuto ( self ) :
self . removeTags ( self . save_data_style )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def removeCBLTags ( self ) :
self . removeTags ( MetaDataStyle . CBI )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def removeCRTags ( self ) :
self . removeTags ( MetaDataStyle . CIX )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def removeTags ( self , style ) :
2015-02-12 14:57:46 -08:00
# remove the indicated tags from the archive
ca_list = self . fileSelectionList . getSelectedArchiveList ( )
has_md_count = 0
for ca in ca_list :
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( style ) :
2015-02-12 14:57:46 -08:00
has_md_count + = 1
if has_md_count == 0 :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self , self . tr ( " Remove Tags " ) , self . tr (
" No archives with {0} tags selected! " . format (
MetaDataStyle . name [ style ] ) ) )
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
if has_md_count != 0 and not self . dirtyFlagVerification (
" Remove Tags " ,
" If you remove tags now, unsaved data in the form will be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
return
if has_md_count != 0 :
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Remove Tags " ) ,
self . tr (
" Are you sure you wish to remove the {0} tags from {1} archive(s)? " . format (
MetaDataStyle . name [ style ] ,
has_md_count ) ) ,
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . Yes ,
QtWidgets . QMessageBox . No )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if reply == QtWidgets . QMessageBox . Yes :
progdialog = QtWidgets . QProgressDialog (
2015-02-15 02:44:00 -08:00
" " , " Cancel " , 0 , has_md_count , self )
2015-02-13 15:08:07 -08:00
progdialog . setWindowTitle ( " Removing Tags " )
2015-02-12 14:57:46 -08:00
progdialog . setWindowModality ( QtCore . Qt . ApplicationModal )
2018-09-19 13:05:39 -07:00
progdialog . setMinimumDuration ( 300 )
centerWindowOnParent ( progdialog )
QtCore . QCoreApplication . processEvents ( )
#progdialog.show()
2015-02-12 14:57:46 -08:00
prog_idx = 0
failed_list = [ ]
success_count = 0
for ca in ca_list :
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( style ) :
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
if progdialog . wasCanceled ( ) :
break
prog_idx + = 1
2018-09-19 13:05:39 -07:00
progdialog . setValue ( prog_idx )
2015-02-13 15:08:07 -08:00
progdialog . setLabelText ( ca . path )
2015-02-21 18:30:32 -08:00
centerWindowOnParent ( progdialog )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( style ) and ca . isWritable ( ) :
if not ca . removeMetadata ( style ) :
failed_list . append ( ca . path )
2015-02-12 14:57:46 -08:00
else :
success_count + = 1
2015-02-15 02:44:00 -08:00
ca . loadCache ( [ MetaDataStyle . CBI , MetaDataStyle . CIX ] )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
progdialog . hide ( )
QtCore . QCoreApplication . processEvents ( )
2015-02-12 14:57:46 -08:00
self . fileSelectionList . updateSelectedRows ( )
self . updateInfoBox ( )
self . updateMenus ( )
2018-09-19 13:05:39 -07:00
summary = " Successfully removed tags in {0} archive(s). " . format (
2015-02-15 02:44:00 -08:00
success_count )
2015-02-13 15:08:07 -08:00
if len ( failed_list ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " \n \n The remove operation failed in the following {0} archive(s): \n " . format (
2015-02-15 02:44:00 -08:00
len ( failed_list ) )
2015-02-12 14:57:46 -08:00
for f in failed_list :
2018-09-19 13:05:39 -07:00
summary + = " \t {0} \n " . format ( f )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
dlg = LogWindow ( self )
dlg . setText ( summary )
dlg . setWindowTitle ( " Tag Remove Summary " )
2015-02-15 02:44:00 -08:00
# dlg.adjustSize()
2015-02-12 14:57:46 -08:00
dlg . exec_ ( )
2015-02-13 15:08:07 -08:00
def copyTags ( self ) :
2015-02-12 14:57:46 -08:00
# copy the indicated tags in the archive
ca_list = self . fileSelectionList . getSelectedArchiveList ( )
has_src_count = 0
src_style = self . load_data_style
dest_style = self . save_data_style
if src_style == dest_style :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Copy Tags " ) ,
self . tr (
" Can ' t copy tag style onto itself. " +
" Read style and modify style must be different. " ) )
2015-02-12 14:57:46 -08:00
return
for ca in ca_list :
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( src_style ) :
2015-02-12 14:57:46 -08:00
has_src_count + = 1
if has_src_count == 0 :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 03:55:04 -08:00
self , self . tr ( " Copy Tags " ) , self . tr (
" No archives with {0} tags selected! " . format (
MetaDataStyle . name [ src_style ] ) ) )
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
if has_src_count != 0 and not self . dirtyFlagVerification (
" Copy Tags " ,
" If you copy tags now, unsaved data in the form may be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
return
if has_src_count != 0 :
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( " Copy Tags " ) ,
self . tr (
" Are you sure you wish to copy the {0} tags to {1} tags in {2} archive(s)? " . format (
MetaDataStyle . name [ src_style ] ,
MetaDataStyle . name [ dest_style ] ,
has_src_count ) ) ,
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . Yes ,
QtWidgets . QMessageBox . No )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if reply == QtWidgets . QMessageBox . Yes :
progdialog = QtWidgets . QProgressDialog (
2015-02-15 02:44:00 -08:00
" " , " Cancel " , 0 , has_src_count , self )
2015-02-13 15:08:07 -08:00
progdialog . setWindowTitle ( " Copying Tags " )
2015-02-12 14:57:46 -08:00
progdialog . setWindowModality ( QtCore . Qt . ApplicationModal )
2018-09-19 13:05:39 -07:00
progdialog . setMinimumDuration ( 300 )
centerWindowOnParent ( progdialog )
QtCore . QCoreApplication . processEvents ( )
2015-02-12 14:57:46 -08:00
prog_idx = 0
failed_list = [ ]
success_count = 0
for ca in ca_list :
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( src_style ) :
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
if progdialog . wasCanceled ( ) :
break
prog_idx + = 1
2018-09-19 13:05:39 -07:00
progdialog . setValue ( prog_idx )
2015-02-13 15:08:07 -08:00
progdialog . setLabelText ( ca . path )
2015-02-21 18:30:32 -08:00
centerWindowOnParent ( progdialog )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
if ca . hasMetadata ( src_style ) and ca . isWritable ( ) :
md = ca . readMetadata ( src_style )
2015-02-12 14:57:46 -08:00
if dest_style == MetaDataStyle . CBI and self . settings . apply_cbl_transform_on_bulk_operation :
2015-02-13 15:08:07 -08:00
md = CBLTransformer ( md , self . settings ) . apply ( )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
if not ca . writeMetadata ( md , dest_style ) :
failed_list . append ( ca . path )
2015-02-12 14:57:46 -08:00
else :
success_count + = 1
2015-02-15 02:44:00 -08:00
ca . loadCache ( [ MetaDataStyle . CBI , MetaDataStyle . CIX ] )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
progdialog . hide ( )
QtCore . QCoreApplication . processEvents ( )
2015-02-12 14:57:46 -08:00
self . fileSelectionList . updateSelectedRows ( )
self . updateInfoBox ( )
self . updateMenus ( )
2018-09-19 13:05:39 -07:00
summary = " Successfully copied tags in {0} archive(s). " . format (
2015-02-15 02:44:00 -08:00
success_count )
2015-02-13 15:08:07 -08:00
if len ( failed_list ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " \n \n The copy operation failed in the following {0} archive(s): \n " . format (
2015-02-15 02:44:00 -08:00
len ( failed_list ) )
2015-02-12 14:57:46 -08:00
for f in failed_list :
2018-09-19 13:05:39 -07:00
summary + = " \t {0} \n " . format ( f )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
dlg = LogWindow ( self )
dlg . setText ( summary )
dlg . setWindowTitle ( " Tag Copy Summary " )
2015-02-12 14:57:46 -08:00
dlg . exec_ ( )
2015-02-13 15:08:07 -08:00
def actualIssueDataFetch ( self , match ) :
2015-02-12 14:57:46 -08:00
# now get the particular issue data
cv_md = None
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . setOverrideCursor (
2015-02-15 02:44:00 -08:00
QtGui . QCursor ( QtCore . Qt . WaitCursor ) )
2015-02-12 14:57:46 -08:00
try :
2015-02-13 15:08:07 -08:00
comicVine = ComicVineTalker ( )
2015-02-12 14:57:46 -08:00
comicVine . wait_for_rate_limit = self . settings . wait_and_retry_on_rate_limit
2015-02-15 02:44:00 -08:00
cv_md = comicVine . fetchIssueData (
2015-02-15 03:44:09 -08:00
match [ ' volume_id ' ] , match [ ' issue_number ' ] , self . settings )
2015-02-12 14:57:46 -08:00
except ComicVineTalkerException :
2015-02-13 15:08:07 -08:00
print ( " Network error while getting issue details. Save aborted " )
2015-02-12 14:57:46 -08:00
if cv_md is not None :
if self . settings . apply_cbl_transform_on_cv_import :
2015-02-13 15:08:07 -08:00
cv_md = CBLTransformer ( cv_md , self . settings ) . apply ( )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
QtWidgets . QApplication . restoreOverrideCursor ( )
2015-02-12 14:57:46 -08:00
return cv_md
2015-02-13 15:08:07 -08:00
def autoTagLog ( self , text ) :
IssueIdentifier . defaultWriteOutput ( text )
2015-02-12 14:57:46 -08:00
if self . atprogdialog is not None :
2022-02-21 20:05:07 -08:00
self . atprogdialog . textEdit . append ( text . rstrip ( ) )
2015-02-12 14:57:46 -08:00
self . atprogdialog . textEdit . ensureCursorVisible ( )
QtCore . QCoreApplication . processEvents ( )
QtCore . QCoreApplication . processEvents ( )
QtCore . QCoreApplication . processEvents ( )
2015-02-13 15:08:07 -08:00
def identifyAndTagSingleArchive ( self , ca , match_results , dlg ) :
2015-02-12 14:57:46 -08:00
success = False
2015-02-13 15:08:07 -08:00
ii = IssueIdentifier ( ca , self . settings )
2015-02-12 14:57:46 -08:00
# read in metadata, and parse file name if not there
2015-02-13 15:08:07 -08:00
md = ca . readMetadata ( self . save_data_style )
2015-02-12 14:57:46 -08:00
if md . isEmpty :
md = ca . metadataFromFilename ( self . settings . parse_scan_info )
if dlg . ignoreLeadingDigitsInFilename and md . series is not None :
2015-02-15 02:44:00 -08:00
# remove all leading numbers
2015-02-13 15:08:07 -08:00
md . series = re . sub ( " ([ \ d.]*)(.*) " , " \\ 2 " , md . series )
2015-02-12 14:57:46 -08:00
# use the dialog specified search string
if dlg . searchString is not None :
md . series = dlg . searchString
if md is None or md . isEmpty :
2015-02-13 15:08:07 -08:00
print ( " No metadata given to search online with! " )
2015-02-12 14:57:46 -08:00
return False , match_results
if dlg . dontUseYear :
md . year = None
2015-02-13 15:08:07 -08:00
if dlg . assumeIssueOne and ( md . issue is None or md . issue == " " ) :
2015-02-12 14:57:46 -08:00
md . issue = " 1 "
2015-02-13 15:08:07 -08:00
ii . setAdditionalMetadata ( md )
2015-02-12 14:57:46 -08:00
ii . onlyUseAdditionalMetaData = True
ii . waitAndRetryOnRateLimit = dlg . waitAndRetryOnRateLimit
2015-02-13 15:08:07 -08:00
ii . setOutputFunction ( self . autoTagLog )
2015-02-12 14:57:46 -08:00
ii . cover_page_index = md . getCoverPageIndexList ( ) [ 0 ]
2015-02-13 15:08:07 -08:00
ii . setCoverURLCallback ( self . atprogdialog . setTestImage )
ii . setNameLengthDeltaThreshold ( dlg . nameLengthMatchTolerance )
2015-02-12 14:57:46 -08:00
matches = ii . search ( )
result = ii . search_result
found_match = False
choices = False
low_confidence = False
no_match = False
if result == ii . ResultNoMatches :
pass
elif result == ii . ResultFoundMatchButBadCoverScore :
low_confidence = True
found_match = True
2015-02-15 02:44:00 -08:00
elif result == ii . ResultFoundMatchButNotFirstPage :
2015-02-12 14:57:46 -08:00
found_match = True
elif result == ii . ResultMultipleMatchesWithBadImageScores :
low_confidence = True
choices = True
elif result == ii . ResultOneGoodMatch :
found_match = True
elif result == ii . ResultMultipleGoodMatches :
choices = True
if choices :
if low_confidence :
2015-02-15 02:44:00 -08:00
self . autoTagLog (
" Online search: Multiple low-confidence matches. Save aborted \n " )
match_results . lowConfidenceMatches . append (
MultipleMatch ( ca , matches ) )
2015-02-12 14:57:46 -08:00
else :
2015-02-15 02:44:00 -08:00
self . autoTagLog (
" Online search: Multiple matches. Save aborted \n " )
match_results . multipleMatches . append (
MultipleMatch ( ca , matches ) )
2015-02-12 14:57:46 -08:00
elif low_confidence and not dlg . autoSaveOnLow :
2015-02-15 02:44:00 -08:00
self . autoTagLog (
" Online search: Low confidence match. Save aborted \n " )
match_results . lowConfidenceMatches . append (
MultipleMatch ( ca , matches ) )
2015-02-12 14:57:46 -08:00
elif not found_match :
2015-02-13 15:08:07 -08:00
self . autoTagLog ( " Online search: No match found. Save aborted \n " )
2015-02-12 14:57:46 -08:00
match_results . noMatches . append ( ca . path )
else :
# a single match!
if low_confidence :
2015-02-15 02:44:00 -08:00
self . autoTagLog (
" Online search: Low confidence match, but saving anyways, as indicated... \n " )
2015-02-12 14:57:46 -08:00
# now get the particular issue data
2015-02-13 15:08:07 -08:00
cv_md = self . actualIssueDataFetch ( matches [ 0 ] )
2015-02-12 14:57:46 -08:00
if cv_md is None :
match_results . fetchDataFailures . append ( ca . path )
if cv_md is not None :
2015-02-13 15:08:07 -08:00
md . overlay ( cv_md )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
if not ca . writeMetadata ( md , self . save_data_style ) :
2015-02-15 02:44:00 -08:00
match_results . writeFailures . append ( ca . path )
self . autoTagLog ( " Save failed ;-( \n " )
2015-02-12 14:57:46 -08:00
else :
2015-02-15 02:44:00 -08:00
match_results . goodMatches . append ( ca . path )
success = True
self . autoTagLog ( " Save complete! \n " )
ca . loadCache ( [ MetaDataStyle . CBI , MetaDataStyle . CIX ] )
2015-02-12 14:57:46 -08:00
return success , match_results
2015-02-13 15:08:07 -08:00
def autoTag ( self ) :
2015-02-12 14:57:46 -08:00
ca_list = self . fileSelectionList . getSelectedArchiveList ( )
style = self . save_data_style
if len ( ca_list ) == 0 :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 02:44:00 -08:00
self , self . tr ( " Auto-Tag " ) , self . tr ( " No archives selected! " ) )
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
if not self . dirtyFlagVerification (
" Auto-Tag " ,
" If you auto-tag now, unsaved data in the form will be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
atstartdlg = AutoTagStartWindow (
self ,
self . settings ,
self . tr (
" You have selected {0} archive(s) to automatically identify and write {1} tags to. \n \n " . format (
len ( ca_list ) ,
MetaDataStyle . name [ style ] ) +
" Please choose options below, and select OK to Auto-Tag. \n " ) )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
atstartdlg . adjustSize ( )
atstartdlg . setModal ( True )
2015-02-12 14:57:46 -08:00
if not atstartdlg . exec_ ( ) :
return
2015-02-13 15:08:07 -08:00
self . atprogdialog = AutoTagProgressWindow ( self )
2015-02-12 14:57:46 -08:00
self . atprogdialog . setModal ( True )
self . atprogdialog . show ( )
2015-02-13 15:08:07 -08:00
self . atprogdialog . progressBar . setMaximum ( len ( ca_list ) )
self . atprogdialog . setWindowTitle ( " Auto-Tagging " )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
self . autoTagLog (
2018-09-19 13:05:39 -07:00
" ========================================================================== \n " )
2015-02-15 02:44:00 -08:00
self . autoTagLog (
2018-09-19 13:05:39 -07:00
" Auto-Tagging Started for {0} items \n " . format ( len ( ca_list ) ) )
2015-02-12 14:57:46 -08:00
prog_idx = 0
match_results = OnlineMatchResults ( )
archives_to_remove = [ ]
for ca in ca_list :
2015-02-15 02:44:00 -08:00
self . autoTagLog (
2018-09-19 13:05:39 -07:00
" ========================================================================== \n " )
2015-02-15 02:44:00 -08:00
self . autoTagLog (
2018-09-19 13:05:39 -07:00
" Auto-Tagging {0} of {1} \n " . format ( prog_idx + 1 , len ( ca_list ) ) )
self . autoTagLog ( " {0} \n " . format ( ca . path ) )
2015-02-12 14:57:46 -08:00
cover_idx = ca . readMetadata ( style ) . getCoverPageIndexList ( ) [ 0 ]
2015-02-13 15:08:07 -08:00
image_data = ca . getPage ( cover_idx )
self . atprogdialog . setArchiveImage ( image_data )
self . atprogdialog . setTestImage ( None )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
if self . atprogdialog . isdone :
break
2015-02-13 15:08:07 -08:00
self . atprogdialog . progressBar . setValue ( prog_idx )
2015-02-12 14:57:46 -08:00
prog_idx + = 1
2015-02-13 15:08:07 -08:00
self . atprogdialog . label . setText ( ca . path )
2015-02-21 18:30:32 -08:00
centerWindowOnParent ( self . atprogdialog )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
if ca . isWritable ( ) :
2015-02-15 02:44:00 -08:00
success , match_results = self . identifyAndTagSingleArchive (
ca , match_results , atstartdlg )
2015-02-12 14:57:46 -08:00
if success and atstartdlg . removeAfterSuccess :
2015-02-13 15:08:07 -08:00
archives_to_remove . append ( ca )
2015-02-12 14:57:46 -08:00
self . atprogdialog . close ( )
if atstartdlg . removeAfterSuccess :
2015-02-13 15:08:07 -08:00
self . fileSelectionList . removeArchiveList ( archives_to_remove )
2015-02-12 14:57:46 -08:00
self . fileSelectionList . updateSelectedRows ( )
2015-02-13 15:08:07 -08:00
self . loadArchive ( self . fileSelectionList . getCurrentArchive ( ) )
2015-02-12 14:57:46 -08:00
self . atprogdialog = None
2018-09-19 13:05:39 -07:00
summary = " "
summary + = " Successfully tagged archives: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . goodMatches ) )
if len ( match_results . multipleMatches ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " Archives with multiple matches: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . multipleMatches ) )
if len ( match_results . lowConfidenceMatches ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " Archives with one or more low-confidence matches: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . lowConfidenceMatches ) )
if len ( match_results . noMatches ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " Archives with no matches: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . noMatches ) )
if len ( match_results . fetchDataFailures ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " Archives that failed due to data fetch errors: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . fetchDataFailures ) )
if len ( match_results . writeFailures ) > 0 :
2018-09-19 13:05:39 -07:00
summary + = " Archives that failed due to file writing errors: {0} \n " . format (
2015-02-15 02:44:00 -08:00
len ( match_results . writeFailures ) )
2015-02-13 15:08:07 -08:00
self . autoTagLog ( summary )
2015-02-15 02:44:00 -08:00
sum_selectable = len (
match_results . multipleMatches ) + len ( match_results . lowConfidenceMatches )
2015-02-12 14:57:46 -08:00
if sum_selectable > 0 :
2018-09-19 13:05:39 -07:00
summary + = " \n \n Do you want to manually select the ones with multiple matches and/or low-confidence matches now? "
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
2018-09-19 13:05:39 -07:00
self . tr ( " Auto-Tag Summary " ) ,
2015-02-15 03:55:04 -08:00
self . tr ( summary ) ,
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . Yes ,
QtWidgets . QMessageBox . No )
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
match_results . multipleMatches . extend (
match_results . lowConfidenceMatches )
2018-09-19 13:05:39 -07:00
if reply == QtWidgets . QMessageBox . Yes :
2015-02-15 02:44:00 -08:00
matchdlg = AutoTagMatchWindow (
2015-02-15 03:55:04 -08:00
self ,
match_results . multipleMatches ,
style ,
self . actualIssueDataFetch )
2015-02-13 15:08:07 -08:00
matchdlg . setModal ( True )
2015-02-12 14:57:46 -08:00
matchdlg . exec_ ( )
self . fileSelectionList . updateSelectedRows ( )
2015-02-13 15:08:07 -08:00
self . loadArchive ( self . fileSelectionList . getCurrentArchive ( ) )
2015-02-12 14:57:46 -08:00
else :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 02:44:00 -08:00
self , self . tr ( " Auto-Tag Summary " ) , self . tr ( summary ) )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def dirtyFlagVerification ( self , title , desc ) :
2015-02-12 14:57:46 -08:00
if self . dirtyFlag :
2018-09-19 13:05:39 -07:00
reply = QtWidgets . QMessageBox . question (
2015-02-15 03:55:04 -08:00
self ,
self . tr ( title ) ,
self . tr ( desc ) ,
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . Yes ,
QtWidgets . QMessageBox . No )
2015-02-12 14:57:46 -08:00
2018-09-19 13:05:39 -07:00
if reply != QtWidgets . QMessageBox . Yes :
2015-02-12 14:57:46 -08:00
return False
return True
def closeEvent ( self , event ) :
2015-02-15 03:55:04 -08:00
if self . dirtyFlagVerification (
" Exit " +
self . appName ,
" If you quit now, data in the form will be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
appsize = self . size ( )
self . settings . last_main_window_width = appsize . width ( )
self . settings . last_main_window_height = appsize . height ( )
self . settings . last_main_window_x = self . x ( )
self . settings . last_main_window_y = self . y ( )
self . settings . last_form_side_width = self . splitter . sizes ( ) [ 0 ]
self . settings . last_list_side_width = self . splitter . sizes ( ) [ 1 ]
self . settings . last_filelist_sorted_column , self . settings . last_filelist_sorted_order = self . fileSelectionList . getSorting ( )
self . settings . save ( )
event . accept ( )
else :
event . ignore ( )
2015-02-13 15:08:07 -08:00
def showPageBrowser ( self ) :
2015-02-12 14:57:46 -08:00
if self . page_browser is None :
2015-02-13 15:08:07 -08:00
self . page_browser = PageBrowserWindow ( self , self . metadata )
2015-02-12 14:57:46 -08:00
if self . comic_archive is not None :
2015-02-13 15:08:07 -08:00
self . page_browser . setComicArchive ( self . comic_archive )
2015-02-12 14:57:46 -08:00
self . page_browser . finished . connect ( self . pageBrowserClosed )
2015-02-13 15:08:07 -08:00
def pageBrowserClosed ( self ) :
2015-02-12 14:57:46 -08:00
self . page_browser = None
2015-02-13 15:08:07 -08:00
def viewRawCRTags ( self ) :
2015-02-12 14:57:46 -08:00
if self . comic_archive is not None and self . comic_archive . hasCIX ( ) :
2015-02-13 15:08:07 -08:00
dlg = LogWindow ( self )
dlg . setText ( self . comic_archive . readRawCIX ( ) )
dlg . setWindowTitle ( " Raw ComicRack Tag View " )
2015-02-12 14:57:46 -08:00
dlg . exec_ ( )
2015-02-13 15:08:07 -08:00
def viewRawCBLTags ( self ) :
2015-02-12 14:57:46 -08:00
if self . comic_archive is not None and self . comic_archive . hasCBI ( ) :
2015-02-13 15:08:07 -08:00
dlg = LogWindow ( self )
2015-02-15 02:44:00 -08:00
text = pprint . pformat (
json . loads ( self . comic_archive . readRawCBI ( ) ) , indent = 4 )
2015-02-13 15:08:07 -08:00
dlg . setText ( text )
dlg . setWindowTitle ( " Raw ComicBookLover Tag View " )
2015-02-12 14:57:46 -08:00
dlg . exec_ ( )
2015-02-13 15:08:07 -08:00
def showWiki ( self ) :
2019-10-05 07:31:12 -07:00
webbrowser . open ( " https://github.com/comictagger/comictagger/wiki " )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def reportBug ( self ) :
2019-10-05 07:31:12 -07:00
webbrowser . open ( " https://github.com/comictagger/comictagger/issues " )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def showForum ( self ) :
2015-02-12 14:57:46 -08:00
webbrowser . open ( " http://comictagger.forumotion.com/ " )
2015-02-13 15:08:07 -08:00
def frontCoverChanged ( self , int ) :
2015-02-12 14:57:46 -08:00
self . metadata . pages = self . pageListEditor . getPageList ( )
self . updateCoverImage ( )
2015-02-13 15:08:07 -08:00
def pageListOrderChanged ( self ) :
2015-02-12 14:57:46 -08:00
self . metadata . pages = self . pageListEditor . getPageList ( )
def applyCBLTransform ( self ) :
self . formToMetadata ( )
2015-02-13 15:08:07 -08:00
self . metadata = CBLTransformer ( self . metadata , self . settings ) . apply ( )
2015-02-12 14:57:46 -08:00
self . metadataToForm ( )
def renameArchive ( self ) :
ca_list = self . fileSelectionList . getSelectedArchiveList ( )
if len ( ca_list ) == 0 :
2018-09-19 13:05:39 -07:00
QtWidgets . QMessageBox . information (
2015-02-15 02:44:00 -08:00
self , self . tr ( " Rename " ) , self . tr ( " No archives selected! " ) )
2015-02-12 14:57:46 -08:00
return
2015-02-15 03:55:04 -08:00
if self . dirtyFlagVerification (
" File Rename " ,
" If you rename files now, unsaved data in the form will be lost. Are you sure? " ) :
2015-02-12 14:57:46 -08:00
2015-02-15 02:44:00 -08:00
dlg = RenameWindow (
self , ca_list , self . load_data_style , self . settings )
2015-02-13 15:08:07 -08:00
dlg . setModal ( True )
2015-02-12 14:57:46 -08:00
if dlg . exec_ ( ) :
self . fileSelectionList . updateSelectedRows ( )
2015-02-13 15:08:07 -08:00
self . loadArchive ( self . comic_archive )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def fileListSelectionChanged ( self , qvarFI ) :
2018-09-19 13:05:39 -07:00
fi = qvarFI #.toPyObject()
2015-02-13 15:08:07 -08:00
self . loadArchive ( fi . ca )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def loadArchive ( self , comic_archive ) :
2015-02-12 14:57:46 -08:00
self . comic_archive = None
self . clearForm ( )
2022-02-21 20:05:07 -08:00
if not os . path . exists ( comic_archive . path ) :
self . fileSelectionList . dirty_flag = False
self . fileSelectionList . removeArchiveList ( [ comic_archive ] )
QtCore . QTimer . singleShot ( 1 , self . fileSelectionList . revertSelection )
return
self . settings . last_opened_folder = os . path . abspath ( os . path . split ( comic_archive . path ) [ 0 ] )
2015-02-12 14:57:46 -08:00
self . comic_archive = comic_archive
self . metadata = self . comic_archive . readMetadata ( self . load_data_style )
if self . metadata is None :
self . metadata = GenericMetadata ( )
self . actualLoadCurrentArchive ( )
2015-02-13 15:08:07 -08:00
def fileListCleared ( self ) :
2015-02-12 14:57:46 -08:00
self . resetApp ( )
2015-02-13 15:08:07 -08:00
def splitterMovedEvent ( self , w1 , w2 ) :
2015-02-12 14:57:46 -08:00
scrollbar_w = 0
if self . scrollArea . verticalScrollBar ( ) . isVisible ( ) :
scrollbar_w = self . scrollArea . verticalScrollBar ( ) . width ( )
new_w = self . scrollArea . width ( ) - scrollbar_w - 5
2015-02-15 02:44:00 -08:00
self . scrollAreaWidgetContents . resize (
new_w , self . scrollAreaWidgetContents . height ( ) )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def resizeEvent ( self , ev ) :
self . splitterMovedEvent ( 0 , 0 )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def tabChanged ( self , idx ) :
2015-02-12 14:57:46 -08:00
if idx == 0 :
2015-02-13 15:08:07 -08:00
self . splitterMovedEvent ( 0 , 0 )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def checkLatestVersionOnline ( self ) :
2015-02-12 14:57:46 -08:00
self . versionChecker = VersionChecker ( )
2015-02-15 02:44:00 -08:00
self . versionChecker . versionRequestComplete . connect (
self . versionCheckComplete )
self . versionChecker . asyncGetLatestVersion (
self . settings . install_id , self . settings . send_usage_stats )
2015-02-12 14:57:46 -08:00
2015-02-13 15:08:07 -08:00
def versionCheckComplete ( self , new_version ) :
if ( new_version != self . version and
2015-02-15 02:44:00 -08:00
new_version != self . settings . dont_notify_about_this_version ) :
2019-10-06 05:15:18 -07:00
website = " https://github.com/comictagger/comictagger "
2015-02-15 03:55:04 -08:00
checked = OptionalMessageDialog . msg (
self ,
" New version available! " ,
" New version ( {0} ) available!<br>(You are currently running {1} )<br><br> " . format (
new_version ,
self . version ) +
" Visit <a href= ' {0} ' > {0} </a> for more info.<br><br> " . format ( website ) ,
QtCore . Qt . Unchecked ,
" Don ' t tell me about this version again " )
2015-02-12 14:57:46 -08:00
if checked :
self . settings . dont_notify_about_this_version = new_version
def onIncomingSocketConnection ( self ) :
# accept connection from other instance.
# read in the file list if they're giving it,
# and add to our own list
localSocket = self . socketServer . nextPendingConnection ( )
if localSocket . waitForReadyRead ( 3000 ) :
byteArray = localSocket . readAll ( )
if len ( byteArray ) > 0 :
obj = pickle . loads ( byteArray )
localSocket . disconnectFromServer ( )
2015-02-15 03:44:09 -08:00
if isinstance ( obj , list ) :
2015-02-13 15:08:07 -08:00
self . fileSelectionList . addPathList ( obj )
2015-02-12 14:57:46 -08:00
else :
2015-02-15 02:44:00 -08:00
# print(localSocket.errorString().toLatin1())
2015-02-12 14:57:46 -08:00
pass
self . bringToTop ( )
def bringToTop ( self ) :
if platform . system ( ) == " Windows " :
self . showNormal ( )
self . raise_ ( )
self . activateWindow ( )
try :
import win32con
import win32gui
hwnd = self . effectiveWinId ( )
rect = win32gui . GetWindowRect ( hwnd )
x = rect [ 0 ]
y = rect [ 1 ]
w = rect [ 2 ] - x
h = rect [ 3 ] - y
2015-02-15 02:44:00 -08:00
# mark it "always on top", just for a moment, to force it to
# the top
win32gui . SetWindowPos (
2015-02-15 03:44:09 -08:00
hwnd , win32con . HWND_TOPMOST , x , y , w , h , 0 )
2015-02-15 02:44:00 -08:00
win32gui . SetWindowPos (
hwnd , win32con . HWND_NOTOPMOST , x , y , w , h , 0 )
2015-02-12 14:57:46 -08:00
except Exception as e :
2018-09-19 13:05:39 -07:00
print ( " Whoops " , e )
2015-02-12 14:57:46 -08:00
elif platform . system ( ) == " Darwin " :
self . raise_ ( )
self . showNormal ( )
self . activateWindow ( )
else :
flags = self . windowFlags ( )
2015-02-15 02:44:00 -08:00
self . setWindowFlags (
flags | QtCore . Qt . WindowStaysOnTopHint | QtCore . Qt . X11BypassWindowManagerHint )
2015-02-12 14:57:46 -08:00
QtCore . QCoreApplication . processEvents ( )
2015-02-15 02:44:00 -08:00
# self.show()
2015-02-13 15:08:07 -08:00
self . setWindowFlags ( flags )
2015-02-12 14:57:46 -08:00
self . show ( )