def __init__(self, *arg, **kw):
     super(FlickrUploadConfig, self).__init__(*arg, **kw)
     self.setLayout(QtWidgets.QGridLayout())
     self.layout().setContentsMargins(0, 0, 0, 0)
     # privacy settings
     self.privacy = {}
     privacy_group = QtWidgets.QGroupBox(self.tr('Who can see the photos?'))
     privacy_group.setLayout(QtWidgets.QVBoxLayout())
     self.privacy['private'] = QtWidgets.QRadioButton(self.tr('Only you'))
     privacy_group.layout().addWidget(self.privacy['private'])
     ff_group = QtWidgets.QGroupBox()
     ff_group.setFlat(True)
     ff_group.setLayout(QtWidgets.QVBoxLayout())
     ff_group.layout().setContentsMargins(10, 0, 0, 0)
     self.privacy['friends'] = QtWidgets.QCheckBox(self.tr('Your friends'))
     ff_group.layout().addWidget(self.privacy['friends'])
     self.privacy['family'] = QtWidgets.QCheckBox(self.tr('Your family'))
     ff_group.layout().addWidget(self.privacy['family'])
     privacy_group.layout().addWidget(ff_group)
     self.privacy['public'] = QtWidgets.QRadioButton(self.tr('Anyone'))
     self.privacy['public'].toggled.connect(self.enable_ff)
     self.privacy['public'].setChecked(True)
     privacy_group.layout().addWidget(self.privacy['public'])
     self.hidden = QtWidgets.QCheckBox(self.tr('Hidden from search'))
     privacy_group.layout().addWidget(self.hidden)
     privacy_group.layout().addStretch(1)
     self.layout().addWidget(privacy_group, 0, 0, 2, 1)
     # content type
     self.content_type = {}
     content_group = QtWidgets.QGroupBox(self.tr('Content type'))
     content_group.setLayout(QtWidgets.QVBoxLayout())
     self.content_type['photo'] = QtWidgets.QRadioButton(self.tr('Photo'))
     self.content_type['photo'].setChecked(True)
     content_group.layout().addWidget(self.content_type['photo'])
     self.content_type['screenshot'] = QtWidgets.QRadioButton(self.tr('Screenshot'))
     content_group.layout().addWidget(self.content_type['screenshot'])
     self.content_type['other'] = QtWidgets.QRadioButton(self.tr('Art/Illustration'))
     content_group.layout().addWidget(self.content_type['other'])
     content_group.layout().addStretch(1)
     self.layout().addWidget(content_group, 0, 1)
     # create new set
     new_set_button = QtWidgets.QPushButton(self.tr('New album'))
     new_set_button.clicked.connect(self.new_set)
     self.layout().addWidget(new_set_button, 1, 1)
     # list of sets widget
     sets_group = QtWidgets.QGroupBox(self.tr('Add to albums'))
     sets_group.setLayout(QtWidgets.QVBoxLayout())
     scrollarea = QtWidgets.QScrollArea()
     scrollarea.setFrameStyle(QtWidgets.QFrame.NoFrame)
     scrollarea.setStyleSheet("QScrollArea { background-color: transparent }")
     self.sets_widget = QtWidgets.QWidget()
     self.sets_widget.setLayout(QtWidgets.QVBoxLayout())
     self.sets_widget.layout().setSpacing(0)
     self.sets_widget.layout().setSizeConstraint(
         QtWidgets.QLayout.SetMinAndMaxSize)
     scrollarea.setWidget(self.sets_widget)
     self.sets_widget.setAutoFillBackground(False)
     sets_group.layout().addWidget(scrollarea)
     self.layout().addWidget(sets_group, 0, 2, 2, 1)
     self.layout().setColumnStretch(2, 1)
Exemple #2
0
 def __init__(self, *arg, **kw):
     super(GoogleUploadConfig, self).__init__(*arg, **kw)
     self.setLayout(QtWidgets.QGridLayout())
     self.layout().setContentsMargins(0, 0, 0, 0)
     # create new set
     new_set_button = QtWidgets.QPushButton(
         translate('GooglePhotosTab', 'New album'))
     new_set_button.clicked.connect(self.new_set)
     self.layout().addWidget(new_set_button, 2, 1)
     # list of sets widget
     sets_group = QtWidgets.QGroupBox(
         translate('GooglePhotosTab', 'Add to albums'))
     sets_group.setLayout(QtWidgets.QVBoxLayout())
     scrollarea = QtWidgets.QScrollArea()
     scrollarea.setFrameStyle(QtWidgets.QFrame.NoFrame)
     scrollarea.setStyleSheet(
         "QScrollArea { background-color: transparent }")
     self.sets_widget = QtWidgets.QWidget()
     self.sets_widget.setLayout(QtWidgets.QVBoxLayout())
     self.sets_widget.layout().setSpacing(0)
     self.sets_widget.layout().setSizeConstraint(
         QtWidgets.QLayout.SetMinAndMaxSize)
     scrollarea.setWidget(self.sets_widget)
     self.sets_widget.setAutoFillBackground(False)
     sets_group.layout().addWidget(scrollarea)
     self.layout().addWidget(sets_group, 0, 2, 3, 1)
     self.layout().setColumnStretch(2, 1)
Exemple #3
0
 def _replace_dialog(self, image):
     # has image already been uploaded?
     for keyword in image.metadata.keywords or []:
         name_pred, sep, photo_id = keyword.partition('=')
         if name_pred == ID_TAG:
             break
     else:
         # new upload
         return {
             'set_metadata'  : True,
             'set_visibility': True,
             'set_type'      : True,
             'set_albums'    : True,
             'replace_image' : False,
             'new_photo'     : True,
             }, None
     # get user preferences
     dialog = QtWidgets.QDialog(parent=self)
     dialog.setWindowTitle(self.tr('Replace photo'))
     dialog.setLayout(QtWidgets.QVBoxLayout())
     message = QtWidgets.QLabel(self.tr(
         'File {0} has already been uploaded to Flickr.' +
         ' How would you like to update it?').format(
             os.path.basename(image.path)))
     message.setWordWrap(True)
     dialog.layout().addWidget(message)
     widget = {}
     widget['set_metadata'] = QtWidgets.QCheckBox(
         self.tr('Replace metadata'))
     widget['set_visibility'] = QtWidgets.QCheckBox(
         self.tr('Change who can see it'))
     widget['set_type'] = QtWidgets.QCheckBox(
         self.tr('Change content type'))
     widget['set_albums'] = QtWidgets.QCheckBox(
         self.tr('Change album membership'))
     widget['replace_image'] = QtWidgets.QCheckBox(
         self.tr('Replace image'))
     widget['new_photo'] = QtWidgets.QCheckBox(
         self.tr('Upload as new photo'))
     no_upload = QtWidgets.QCheckBox(self.tr('No image upload'))
     no_upload.setChecked(True)
     button_group = QtWidgets.QButtonGroup()
     button_group.addButton(widget['replace_image'])
     button_group.addButton(widget['new_photo'])
     button_group.addButton(no_upload)
     for key in ('set_metadata', 'set_visibility', 'set_type',
                 'set_albums', 'replace_image', 'new_photo'):
         dialog.layout().addWidget(widget[key])
         widget[key].setChecked(self.replace_prefs[key])
     dialog.layout().addWidget(no_upload)
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(dialog.accept)
     button_box.rejected.connect(dialog.reject)
     dialog.layout().addWidget(button_box)
     if dialog.exec_() != QtWidgets.QDialog.Accepted:
         return None, photo_id
     for key in self.replace_prefs:
         self.replace_prefs[key] = widget[key].isChecked()
     return dict(self.replace_prefs), photo_id
Exemple #4
0
 def __init__(self, *arg, **kw):
     super(NewItemDialog, self).__init__(*arg, **kw)
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     scroll_area.setWidgetResizable(True)
     self.layout().addWidget(scroll_area)
     self.panel = QtWidgets.QWidget()
     self.panel.setLayout(QtWidgets.QFormLayout())
     self.panel.layout().setFieldGrowthPolicy(
         QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     # ok & cancel buttons
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(self.accept)
     button_box.rejected.connect(self.reject)
     self.layout().addWidget(button_box)
     # common data items
     self.model_widgets = {}
     for key, label in (
             ('make', translate('TechnicalTab', "Maker's name")),
             ('model', translate('TechnicalTab', 'Model name')),
             ('serial_no', translate('TechnicalTab', 'Serial number')),
             ):
         self.model_widgets[key] = QtWidgets.QLineEdit()
         self.model_widgets[key].setMinimumWidth(
             width_for_text(self.model_widgets[key], 'x' * 35))
         self.panel.layout().addRow(label, self.model_widgets[key])
     # add any other data items
     self.extend_data()
     # add panel to scroll area now its size is known
     scroll_area.setWidget(self.panel)
Exemple #5
0
 def __init__(self, image_list, *arg, **kw):
     super(TabWidget, self).__init__(*arg, **kw)
     self.config_store = QtWidgets.QApplication.instance().config_store
     self.image_list = image_list
     self.setLayout(QtWidgets.QHBoxLayout())
     self.layout().setContentsMargins(0, 0, 0, 0)
     # construct widgets
     self.enableable = []
     ## data fields
     form, self.widgets = self.data_form()
     self.enableable.append(form.widget())
     for key in self.widgets:
         self.widgets[key].editingFinished.connect(
             getattr(self, 'new_' + key))
     self.layout().addWidget(form)
     ## buttons
     buttons = QtWidgets.QVBoxLayout()
     buttons.addStretch(1)
     edit_template = QtWidgets.QPushButton(
         translate('OwnerTab', 'Edit\ntemplate'))
     edit_template.clicked.connect(self.edit_template)
     buttons.addWidget(edit_template)
     apply_template = QtWidgets.QPushButton(
         translate('OwnerTab', 'Apply\ntemplate'))
     apply_template.clicked.connect(self.apply_template)
     self.enableable.append(apply_template)
     buttons.addWidget(apply_template)
     self.layout().addLayout(buttons)
     # disable data entry until an image is selected
     self.set_enabled(False)
Exemple #6
0
 def show_terms(self):
     # return widget to display map terms and conditions
     layout = QtWidgets.QVBoxLayout()
     widget = QtWidgets.QPushButton(self.tr('Terms of Use'))
     widget.clicked.connect(self.load_tou)
     widget.setStyleSheet('QPushButton { font-size: 10px }')
     layout.addWidget(widget)
     return layout
Exemple #7
0
 def __init__(self, *arg, **kw):
     super(FacebookLoginPopup, self).__init__(*arg, **kw)
     self.setSizePolicy(QtWidgets.QSizePolicy.Maximum,
                        QtWidgets.QSizePolicy.Maximum)
     self.setLayout(QtWidgets.QVBoxLayout())
     self.browser = WebView()
     self.browser.urlChanged.connect(self.auth_url_changed)
     self.layout().addWidget(self.browser)
     buttons = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Cancel)
     buttons.rejected.connect(self.reject)
     self.layout().addWidget(buttons)
Exemple #8
0
 def initialize_finished(self):
     self.map_loaded = True
     self.layout().removeWidget(self.load_map)
     self.load_map.setParent(None)
     show_terms = QtWidgets.QVBoxLayout()
     for widget in self.show_terms():
         widget.setStyleSheet('QPushButton, QLabel { font-size: 10px }')
         show_terms.addWidget(widget)
     self.layout().addLayout(show_terms, 7, 0)
     self.edit_box.setEnabled(True)
     self.map.setAcceptDrops(True)
     self.image_list_changed()
     self.image_list.set_drag_to_map(self.drag_icon)
Exemple #9
0
 def __init__(self, upload_config_widget, image_list, *arg, **kw):
     super(PhotiniUploader, self).__init__(*arg, **kw)
     self.app = QtWidgets.QApplication.instance()
     self.app.aboutToQuit.connect(self.shutdown)
     logger.debug('using %s', keyring.get_keyring().__module__)
     self.image_list = image_list
     self.setLayout(QtWidgets.QGridLayout())
     self.session = self.session_factory()
     self.session.connection_changed.connect(self.connection_changed)
     self.upload_worker = None
     # user details
     self.user = {}
     user_group = QtWidgets.QGroupBox(translate('UploaderTabsAll', 'User'))
     user_group.setLayout(QtWidgets.QVBoxLayout())
     self.user_photo = QtWidgets.QLabel()
     self.user_photo.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
     user_group.layout().addWidget(self.user_photo)
     self.user_name = QtWidgets.QLabel()
     self.user_name.setWordWrap(True)
     self.user_name.setFixedWidth(80)
     user_group.layout().addWidget(self.user_name)
     user_group.layout().addStretch(1)
     self.layout().addWidget(user_group, 0, 0, 1, 2)
     # connect / disconnect button
     self.user_connect = StartStopButton(
         translate('UploaderTabsAll', 'Log in'),
         translate('UploaderTabsAll', 'Log out'))
     self.user_connect.click_start.connect(self.log_in)
     self.user_connect.click_stop.connect(self.session.log_out)
     self.layout().addWidget(self.user_connect, 1, 0, 1, 2)
     # 'service' specific widget
     self.layout().addWidget(upload_config_widget, 0, 2, 2, 2)
     # upload button
     self.upload_button = StartStopButton(
         translate('UploaderTabsAll', 'Start upload'),
         translate('UploaderTabsAll', 'Stop upload'))
     self.upload_button.setEnabled(False)
     self.upload_button.click_start.connect(self.start_upload)
     self.upload_button.click_stop.connect(self.stop_upload)
     self.layout().addWidget(self.upload_button, 2, 3)
     # progress bar
     self.layout().addWidget(
         QtWidgets.QLabel(translate('UploaderTabsAll', 'Progress')), 2, 0)
     self.total_progress = QtWidgets.QProgressBar()
     self.layout().addWidget(self.total_progress, 2, 1, 1, 2)
     # adjust spacing
     self.layout().setColumnStretch(2, 1)
     self.layout().setRowStretch(0, 1)
     # initialise as not connected
     self.connection_changed(False)
Exemple #10
0
 def __init__(self, upload_config_widget, image_list, *arg, **kw):
     super(PhotiniUploader, self).__init__(*arg, **kw)
     QtWidgets.QApplication.instance().aboutToQuit.connect(self.shutdown)
     self.logger = logging.getLogger(self.__class__.__name__)
     self.image_list = image_list
     self.setLayout(QtWidgets.QGridLayout())
     self.session = self.session_factory()
     self.upload_worker = None
     self.connected = False
     # user details
     self.user = {}
     user_group = QtWidgets.QGroupBox(self.tr('User'))
     user_group.setLayout(QtWidgets.QVBoxLayout())
     self.user_photo = QtWidgets.QLabel()
     self.user_photo.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
     user_group.layout().addWidget(self.user_photo)
     self.user_name = QtWidgets.QLabel()
     self.user_name.setWordWrap(True)
     self.user_name.setFixedWidth(80)
     user_group.layout().addWidget(self.user_name)
     user_group.layout().addStretch(1)
     self.layout().addWidget(user_group, 0, 0, 1, 2)
     # connect / disconnect button
     self.user_connect = QtWidgets.QPushButton()
     self.user_connect.setCheckable(True)
     self.user_connect.clicked.connect(self.connect_user)
     self.layout().addWidget(self.user_connect, 1, 0, 1, 2)
     # 'service' specific widget
     self.layout().addWidget(upload_config_widget, 0, 2, 2, 2)
     # upload button
     self.upload_button = StartStopButton(self.tr('Start upload'),
                                          self.tr('Stop upload'))
     self.upload_button.setEnabled(False)
     self.upload_button.click_start.connect(self.start_upload)
     self.upload_button.click_stop.connect(self.stop_upload)
     self.layout().addWidget(self.upload_button, 2, 3)
     # progress bar
     self.layout().addWidget(QtWidgets.QLabel(self.tr('Progress')), 2, 0)
     self.total_progress = QtWidgets.QProgressBar()
     self.layout().addWidget(self.total_progress, 2, 1, 1, 2)
     # adjust spacing
     self.layout().setColumnStretch(2, 1)
     self.layout().setRowStretch(0, 1)
Exemple #11
0
 def edit_template(self):
     dialog = QtWidgets.QDialog(parent=self)
     width = width_for_text(dialog, 'x' * 120)
     dialog.setFixedSize(min(width,
                             self.window().width()),
                         min(width * 3 // 4,
                             self.window().height()))
     dialog.setWindowTitle(self.tr('Photini: ownership template'))
     dialog.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     form, widgets = self.data_form()
     widgets['copyright'].setToolTip(
         widgets['copyright'].toolTip() + ' ' +
         translate('OwnerTab',
                   'Use %Y to insert the year the photograph was taken.'))
     for key in widgets:
         value = self.config_store.get('ownership', key)
         if key == 'copyright' and not value:
             name = self.config_store.get('user', 'copyright_name') or ''
             text = (self.config_store.get('user', 'copyright_text')
                     or translate(
                         'DescriptiveTab', 'Copyright ©{year} {name}.'
                         ' All rights reserved.'))
             value = text.format(year='%Y', name=name)
         elif key == 'creator' and not value:
             value = self.config_store.get('user', 'creator_name')
         widgets[key].set_value(value)
     dialog.layout().addWidget(form)
     # apply & cancel buttons
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(dialog.accept)
     button_box.rejected.connect(dialog.reject)
     dialog.layout().addWidget(button_box)
     if dialog.exec_() != QtWidgets.QDialog.Accepted:
         return
     for key in widgets:
         value = widgets[key].get_value()
         if value:
             self.config_store.set('ownership', key, value)
         else:
             self.config_store.delete('ownership', key)
Exemple #12
0
 def __init__(self, verbose, *arg, **kw):
     super(LoggerWindow, self).__init__(*arg, **kw)
     QtWidgets.QApplication.instance().aboutToQuit.connect(self.shutdown)
     self.setWindowTitle(self.tr("Photini error logging"))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     self.text = QtWidgets.QTextEdit()
     self.text.setReadOnly(True)
     self.text.setMinimumWidth(width_for_text(self.text, 'x' * 70))
     self.layout().addWidget(self.text)
     # buttons
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Save | QtWidgets.QDialogButtonBox.Close)
     button_box.button(QtWidgets.QDialogButtonBox.Save).clicked.connect(
         self.save)
     button_box.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(
         self.hide)
     self.layout().addWidget(button_box)
     # Python logger
     self.logger = logging.getLogger('')
     for handler in list(self.logger.handlers):
         self.logger.removeHandler(handler)
     threshold = logging.ERROR - (verbose * 10)
     self.logger.setLevel(max(threshold, 1))
     self.stream_proxy = StreamProxy(self)
     self.stream_proxy.write_text.connect(self.write)
     self.stream_proxy.flush_text.connect(self.flush)
     handler = logging.StreamHandler(self.stream_proxy)
     handler.setFormatter(
         logging.Formatter(
             '%(asctime)s: %(levelname)s: %(name)s: %(message)s',
             datefmt='%H:%M:%S'))
     handler.addFilter(LoggerFilter(threshold))
     self.logger.addHandler(handler)
     # intercept stdout and stderr, if they exist
     if sys.stderr:
         sys.stderr = OutputInterceptor('stderr', sys.stderr)
     if sys.stdout:
         sys.stdout = OutputInterceptor('stdout', sys.stdout)
Exemple #13
0
 def __init__(self, parent):
     QtWidgets.QDialog.__init__(self, parent)
     self.config_store = QtWidgets.QApplication.instance().config_store
     self.setWindowTitle(self.tr('Photini: settings'))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     self.layout().addWidget(scroll_area)
     panel = QtWidgets.QWidget()
     panel.setLayout(QtWidgets.QFormLayout())
     # apply & cancel buttons
     self.button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Apply
         | QtWidgets.QDialogButtonBox.Cancel)
     self.button_box.clicked.connect(self.button_clicked)
     self.layout().addWidget(self.button_box)
     # copyright holder name
     self.copyright_name = QtWidgets.QLineEdit()
     self.copyright_name.setText(
         self.config_store.get('user', 'copyright_name', ''))
     self.copyright_name.setMinimumWidth(200)
     panel.layout().addRow(self.tr('Copyright holder'), self.copyright_name)
     # creator name
     self.creator_name = QtWidgets.QLineEdit()
     self.creator_name.setText(
         self.config_store.get('user', 'creator_name', ''))
     panel.layout().addRow(self.tr('Creator'), self.creator_name)
     # reset flickr
     self.reset_flickr = QtWidgets.QCheckBox()
     panel.layout().addRow(self.tr('Disconnect from Flickr'),
                           self.reset_flickr)
     if not keyring or keyring.get_password('photini', 'flickr') is None:
         self.reset_flickr.setDisabled(True)
         panel.layout().labelForField(self.reset_flickr).setDisabled(True)
     # reset picasa
     self.reset_picasa = QtWidgets.QCheckBox()
     panel.layout().addRow(self.tr('Disconnect from Google Photos'),
                           self.reset_picasa)
     if not keyring or keyring.get_password('photini', 'picasa') is None:
         self.reset_picasa.setDisabled(True)
         panel.layout().labelForField(self.reset_picasa).setDisabled(True)
     # reset facebook
     self.reset_facebook = QtWidgets.QCheckBox()
     panel.layout().addRow(self.tr('Disconnect from Facebook'),
                           self.reset_facebook)
     if not keyring or keyring.get_password('photini', 'facebook') is None:
         self.reset_facebook.setDisabled(True)
         panel.layout().labelForField(self.reset_facebook).setDisabled(True)
     # IPTC data
     force_iptc = eval(self.config_store.get('files', 'force_iptc',
                                             'False'))
     self.write_iptc = QtWidgets.QCheckBox(self.tr('Write unconditionally'))
     self.write_iptc.setChecked(force_iptc)
     panel.layout().addRow(self.tr('IPTC metadata'), self.write_iptc)
     # sidecar files
     if_mode = eval(self.config_store.get('files', 'image', 'True'))
     sc_mode = self.config_store.get('files', 'sidecar', 'auto')
     if not if_mode:
         sc_mode = 'always'
     self.sc_always = QtWidgets.QRadioButton(self.tr('Always create'))
     self.sc_always.setChecked(sc_mode == 'always')
     panel.layout().addRow(self.tr('Sidecar files'), self.sc_always)
     self.sc_auto = QtWidgets.QRadioButton(self.tr('Create if necessary'))
     self.sc_auto.setChecked(sc_mode == 'auto')
     self.sc_auto.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_auto)
     self.sc_delete = QtWidgets.QRadioButton(
         self.tr('Delete when possible'))
     self.sc_delete.setChecked(sc_mode == 'delete')
     self.sc_delete.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_delete)
     # image file locking
     self.write_if = QtWidgets.QCheckBox(self.tr('(when possible)'))
     self.write_if.setChecked(if_mode)
     self.write_if.clicked.connect(self.new_write_if)
     panel.layout().addRow(self.tr('Write to image'), self.write_if)
     # add panel to scroll area after its size is known
     scroll_area.setWidget(panel)
Exemple #14
0
 def diff_metadata(self):
     dialog = QtWidgets.QDialog(parent=self)
     dialog.setWindowTitle(translate('ImageList', 'Metadata differences'))
     dialog.setLayout(QtWidgets.QVBoxLayout())
     table = TableWidget()
     table.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                         QtWidgets.QSizePolicy.Expanding)
     table.setColumnCount(3)
     table.setHorizontalHeaderLabels([
         translate('ImageList', 'new value'),
         translate('ImageList', 'undo'),
         translate('ImageList', 'old value')
     ])
     labels = []
     row = 0
     undo = {}
     new_md = self.metadata
     old_md = Metadata(self.path)
     for key in ('title', 'description', 'keywords', 'rating', 'copyright',
                 'creator', 'date_taken', 'date_digitised', 'date_modified',
                 'orientation', 'lens_model', 'lens_make', 'lens_serial',
                 'lens_spec', 'focal_length', 'focal_length_35', 'aperture',
                 'latlong', 'altitude', 'location_taken', 'location_shown',
                 'thumbnail'):
         values = getattr(new_md, key), getattr(old_md, key)
         if values[0] == values[1]:
             continue
         table.setRowCount(row + 1)
         for n, value in enumerate(values):
             if not value:
                 value = ''
             elif isinstance(value, MultiString):
                 value = '\n'.join(value)
             else:
                 value = six.text_type(value)
             item = QtWidgets.QTableWidgetItem(value)
             table.setItem(row, n * 2, item)
         undo[key] = QtWidgets.QTableWidgetItem()
         undo[key].setFlags(undo[key].flags() | Qt.ItemIsUserCheckable)
         undo[key].setCheckState(False)
         table.setItem(row, 1, undo[key])
         labels.append(key)
         row += 1
     table.setVerticalHeaderLabels(labels)
     table.resizeColumnsToContents()
     table.resizeRowsToContents()
     dialog.layout().addWidget(table)
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(dialog.accept)
     button_box.rejected.connect(dialog.reject)
     dialog.layout().addWidget(button_box)
     if dialog.exec_() != QtWidgets.QDialog.Accepted:
         return
     changed = False
     dirty = False
     for key, widget in undo.items():
         if widget.checkState() == Qt.Checked:
             setattr(new_md, key, getattr(old_md, key))
             changed = True
         else:
             dirty = True
     if not dirty:
         self.reload_metadata()
     elif changed:
         self.image_list.emit_selection()
Exemple #15
0
 def __init__(self, images, *arg, **kw):
     super(NewLensDialog, self).__init__(*arg, **kw)
     self.setWindowTitle(self.tr('Photini: define lens'))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     scroll_area.setWidgetResizable(True)
     self.layout().addWidget(scroll_area)
     panel = QtWidgets.QWidget()
     panel.setLayout(QtWidgets.QFormLayout())
     # ok & cancel buttons
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(self.accept)
     button_box.rejected.connect(self.reject)
     self.layout().addWidget(button_box)
     # model
     self.lens_model = QtWidgets.QLineEdit()
     self.lens_model.setMinimumWidth(250)
     panel.layout().addRow(self.tr('Model name'), self.lens_model)
     # maker
     self.lens_make = QtWidgets.QLineEdit()
     panel.layout().addRow(self.tr("Maker's name"), self.lens_make)
     # serial number
     self.lens_serial = QtWidgets.QLineEdit()
     panel.layout().addRow(self.tr('Serial number'), self.lens_serial)
     ## spec has four items
     self.lens_spec = {}
     # min focal length
     self.lens_spec['min_fl'] = QtWidgets.QLineEdit()
     self.lens_spec['min_fl'].setValidator(
         QtGui.QDoubleValidator(bottom=0.0))
     panel.layout().addRow(self.tr('Minimum focal length (mm)'),
                           self.lens_spec['min_fl'])
     # min focal length aperture
     self.lens_spec['min_fl_fn'] = QtWidgets.QLineEdit()
     self.lens_spec['min_fl_fn'].setValidator(DoubleValidator(bottom=0.0))
     panel.layout().addRow(self.tr('Aperture at min. focal length f/'),
                           self.lens_spec['min_fl_fn'])
     # max focal length
     self.lens_spec['max_fl'] = QtWidgets.QLineEdit()
     self.lens_spec['max_fl'].setValidator(
         QtGui.QDoubleValidator(bottom=0.0))
     panel.layout().addRow(self.tr('Maximum focal length (mm)'),
                           self.lens_spec['max_fl'])
     # max focal length aperture
     self.lens_spec['max_fl_fn'] = QtWidgets.QLineEdit()
     self.lens_spec['max_fl_fn'].setValidator(DoubleValidator(bottom=0.0))
     panel.layout().addRow(self.tr('Aperture at max. focal length f/'),
                           self.lens_spec['max_fl_fn'])
     # add panel to scroll area after its size is known
     scroll_area.setWidget(panel)
     # fill in any values we can from existing metadata
     for image in images:
         if image.metadata.lens_model:
             self.lens_model.setText(image.metadata.lens_model.value)
         if image.metadata.lens_make:
             self.lens_make.setText(image.metadata.lens_make.value)
         if image.metadata.lens_serial:
             self.lens_serial.setText(image.metadata.lens_serial.value)
         spec = image.metadata.lens_spec
         for key in self.lens_spec:
             if spec and spec.value[key]:
                 self.lens_spec[key].setText('{:g}'.format(
                     float(spec.value[key])))
Exemple #16
0
 def __init__(self, image_list, parent=None):
     super(TabWidget, self).__init__(parent)
     app = QtWidgets.QApplication.instance()
     app.aboutToQuit.connect(self.shutdown)
     if gp and app.test_mode:
         self.gp_log = gp.check_result(gp.use_python_logging())
     self.config_store = app.config_store
     self.image_list = image_list
     self.setLayout(QtWidgets.QGridLayout())
     form = QtWidgets.QFormLayout()
     form.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     self.nm = NameMangler()
     self.file_data = {}
     self.file_list = []
     self.source = None
     self.file_reader = None
     self.file_writer = None
     # source selector
     box = QtWidgets.QHBoxLayout()
     box.setContentsMargins(0, 0, 0, 0)
     self.source_selector = QtWidgets.QComboBox()
     self.source_selector.currentIndexChanged.connect(self.new_source)
     box.addWidget(self.source_selector)
     refresh_button = QtWidgets.QPushButton(self.tr('refresh'))
     refresh_button.clicked.connect(self.refresh)
     box.addWidget(refresh_button)
     box.setStretch(0, 1)
     form.addRow(self.tr('Source'), box)
     # path format
     self.path_format = QtWidgets.QLineEdit()
     self.path_format.setValidator(PathFormatValidator())
     self.path_format.textChanged.connect(self.nm.new_format)
     self.path_format.editingFinished.connect(self.path_format_finished)
     form.addRow(self.tr('Target format'), self.path_format)
     # path example
     self.path_example = QtWidgets.QLabel()
     self.nm.new_example.connect(self.path_example.setText)
     form.addRow('=>', self.path_example)
     self.layout().addLayout(form, 0, 0)
     # file list
     self.file_list_widget = QtWidgets.QListWidget()
     self.file_list_widget.setSelectionMode(
         QtWidgets.QAbstractItemView.ExtendedSelection)
     self.file_list_widget.itemSelectionChanged.connect(self.selection_changed)
     self.layout().addWidget(self.file_list_widget, 1, 0)
     # selection buttons
     buttons = QtWidgets.QVBoxLayout()
     buttons.addStretch(1)
     self.selected_count = QtWidgets.QLabel()
     self.selection_changed()
     buttons.addWidget(self.selected_count)
     select_all = QtWidgets.QPushButton(self.tr('Select\nall'))
     select_all.clicked.connect(self.select_all)
     buttons.addWidget(select_all)
     select_new = QtWidgets.QPushButton(self.tr('Select\nnew'))
     select_new.clicked.connect(self.select_new)
     buttons.addWidget(select_new)
     self.copy_button = StartStopButton(self.tr('Copy\nphotos'),
                                        self.tr('Stop\nimport'))
     self.copy_button.click_start.connect(self.copy_selected)
     self.copy_button.click_stop.connect(self.stop_copy)
     buttons.addWidget(self.copy_button)
     self.layout().addLayout(buttons, 0, 1, 2, 1)
     # final initialisation
     self.image_list.sort_order_changed.connect(self.sort_file_list)
     path = os.path.expanduser('~/Pictures')
     if not os.path.isdir(path) and sys.platform == 'win32':
         try:
             import win32com.shell as ws
             path = ws.shell.SHGetFolderPath(
                 0, ws.shellcon.CSIDL_MYPICTURES, None, 0)
         except ImportError:
             pass
     self.path_format.setText(
         os.path.join(path, '%Y', '%Y_%m_%d', '{name}'))
     self.refresh()
     self.list_files()
Exemple #17
0
 def __init__(self, image_list, *arg, **kw):
     super(TabWidget, self).__init__(*arg, **kw)
     self.config_store = QtWidgets.QApplication.instance().config_store
     self.image_list = image_list
     self.form = QtWidgets.QFormLayout()
     self.setLayout(QtWidgets.QVBoxLayout())
     self.layout().addLayout(self.form)
     self.layout().addStretch(1)
     # construct widgets
     self.widgets = {}
     # title
     self.widgets['title'] = SingleLineEdit(
         spell_check=True, length_check=ImageMetadata.max_bytes('title'))
     self.widgets['title'].setToolTip(
         translate(
             'DescriptiveTab',
             'Enter a short verbal and human readable name'
             ' for the image, this may be the file name.'))
     self.widgets['title'].editingFinished.connect(self.new_title)
     self.form.addRow(translate('DescriptiveTab', 'Title / Object Name'),
                      self.widgets['title'])
     # description
     self.widgets['description'] = MultiLineEdit(
         spell_check=True,
         length_check=ImageMetadata.max_bytes('description'))
     self.widgets['description'].setToolTip(
         translate(
             'DescriptiveTab', 'Enter a "caption" describing the who, what,'
             ' and why of what is happening in this image,\nthis might include'
             ' names of people, and/or their role in the action that is taking'
             ' place within the image.'))
     self.widgets['description'].editingFinished.connect(
         self.new_description)
     self.form.addRow(translate('DescriptiveTab', 'Description / Caption'),
                      self.widgets['description'])
     # keywords
     self.widgets['keywords'] = KeywordsEditor(
         spell_check=True,
         length_check=ImageMetadata.max_bytes('keywords'),
         multi_string=True)
     self.widgets['keywords'].setToolTip(
         translate(
             'DescriptiveTab',
             'Enter any number of keywords, terms or phrases'
             ' used to express the subject matter in the image.'
             '\nSeparate them with ";" characters.'))
     self.widgets['keywords'].editingFinished.connect(self.new_keywords)
     self.form.addRow(translate('DescriptiveTab', 'Keywords'),
                      self.widgets['keywords'])
     self.image_list.image_list_changed.connect(self.image_list_changed)
     # rating
     self.widgets['rating'] = RatingWidget()
     self.widgets['rating'].editing_finished.connect(self.new_rating)
     self.form.addRow(translate('DescriptiveTab', 'Rating'),
                      self.widgets['rating'])
     # copyright
     self.widgets['copyright'] = LineEditWithAuto(
         length_check=ImageMetadata.max_bytes('copyright'))
     self.widgets['copyright'].setToolTip(
         translate(
             'OwnerTab', 'Enter a notice on the current owner of the'
             ' copyright for this image, such as "©2008 Jane Doe".'))
     self.widgets['copyright'].editingFinished.connect(self.new_copyright)
     self.widgets['copyright'].autoComplete.connect(self.auto_copyright)
     self.form.addRow(translate('DescriptiveTab', 'Copyright'),
                      self.widgets['copyright'])
     # creator
     self.widgets['creator'] = LineEditWithAuto(
         length_check=ImageMetadata.max_bytes('creator'), multi_string=True)
     self.widgets['creator'].setToolTip(
         translate('OwnerTab',
                   'Enter the name of the person that created this image.'))
     self.widgets['creator'].editingFinished.connect(self.new_creator)
     self.widgets['creator'].autoComplete.connect(self.auto_creator)
     self.form.addRow(translate('DescriptiveTab', 'Creator / Artist'),
                      self.widgets['creator'])
     # disable until an image is selected
     self.setEnabled(False)
Exemple #18
0
 def __init__(self, *arg, **kw):
     super(EditSettings, self).__init__(*arg, **kw)
     self.config_store = QtWidgets.QApplication.instance().config_store
     self.setWindowTitle(self.tr('Photini: settings'))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     self.layout().addWidget(scroll_area)
     panel = QtWidgets.QWidget()
     panel.setLayout(QtWidgets.QFormLayout())
     panel.layout().setRowWrapPolicy(
         max(QtWidgets.QFormLayout.WrapLongRows,
             panel.layout().rowWrapPolicy()))
     # apply & cancel buttons
     self.button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Apply
         | QtWidgets.QDialogButtonBox.Cancel)
     self.button_box.clicked.connect(self.button_clicked)
     self.layout().addWidget(self.button_box)
     # copyright holder name
     self.copyright_name = SingleLineEdit(spell_check=True)
     self.copyright_name.set_value(
         self.config_store.get('user', 'copyright_name', ''))
     panel.layout().addRow(self.tr('Copyright holder name'),
                           self.copyright_name)
     # copyright text
     self.copyright_text = SingleLineEdit(spell_check=True)
     self.copyright_text.set_value(
         self.config_store.get('user', 'copyright_text', ''))
     self.copyright_text.setMinimumWidth(
         width_for_text(self.copyright_text, 'x' * 50))
     panel.layout().addRow(self.tr('Copyright text'), self.copyright_text)
     # creator name
     self.creator_name = SingleLineEdit(spell_check=True)
     self.creator_name.set_value(
         self.config_store.get('user', 'creator_name', ''))
     panel.layout().addRow(self.tr('Creator name'), self.creator_name)
     # IPTC data
     force_iptc = self.config_store.get('files', 'force_iptc', False)
     self.write_iptc = QtWidgets.QCheckBox(self.tr('Always write'))
     self.write_iptc.setChecked(force_iptc)
     panel.layout().addRow(self.tr('IPTC-IIM metadata'), self.write_iptc)
     # show IPTC-IIM length limits
     length_warning = self.config_store.get('files', 'length_warning', True)
     self.length_warning = QtWidgets.QCheckBox(
         self.tr('Show IPTC-IIM length limits'))
     self.length_warning.setChecked(length_warning)
     panel.layout().addRow('', self.length_warning)
     # sidecar files
     if_mode = self.config_store.get('files', 'image', True)
     sc_mode = self.config_store.get('files', 'sidecar', 'auto')
     if not if_mode:
         sc_mode = 'always'
     button_group = QtWidgets.QButtonGroup(parent=self)
     self.sc_always = QtWidgets.QRadioButton(self.tr('Always create'))
     button_group.addButton(self.sc_always)
     self.sc_always.setChecked(sc_mode == 'always')
     panel.layout().addRow(self.tr('Sidecar files'), self.sc_always)
     self.sc_auto = QtWidgets.QRadioButton(self.tr('Create if necessary'))
     button_group.addButton(self.sc_auto)
     self.sc_auto.setChecked(sc_mode == 'auto')
     self.sc_auto.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_auto)
     self.sc_delete = QtWidgets.QRadioButton(
         self.tr('Delete when possible'))
     button_group.addButton(self.sc_delete)
     self.sc_delete.setChecked(sc_mode == 'delete')
     self.sc_delete.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_delete)
     # image file locking
     self.write_if = QtWidgets.QCheckBox(self.tr('(when possible)'))
     self.write_if.setChecked(if_mode)
     self.write_if.clicked.connect(self.new_write_if)
     panel.layout().addRow(self.tr('Write to image file'), self.write_if)
     # preserve file timestamps
     keep_time = self.config_store.get('files', 'preserve_timestamps',
                                       'now')
     if isinstance(keep_time, bool):
         # old config format
         keep_time = ('now', 'keep')[keep_time]
     button_group = QtWidgets.QButtonGroup(parent=self)
     self.keep_time = QtWidgets.QRadioButton(self.tr('Keep original'))
     button_group.addButton(self.keep_time)
     self.keep_time.setChecked(keep_time == 'keep')
     panel.layout().addRow(self.tr('File timestamps'), self.keep_time)
     self.time_taken = QtWidgets.QRadioButton(
         self.tr('Set to when photo was taken'))
     button_group.addButton(self.time_taken)
     self.time_taken.setChecked(keep_time == 'taken')
     panel.layout().addRow('', self.time_taken)
     button = QtWidgets.QRadioButton(self.tr('Set to when file is saved'))
     button_group.addButton(button)
     button.setChecked(keep_time == 'now')
     panel.layout().addRow('', button)
     # add panel to scroll area after its size is known
     scroll_area.setWidget(panel)
Exemple #19
0
 def diff_selected_metadata(self):
     dialog = QtWidgets.QDialog(parent=self)
     dialog.setLayout(QtWidgets.QVBoxLayout())
     dialog.setFixedSize(min(800,
                             self.window().width()),
                         min(400,
                             self.window().height()))
     table = QtWidgets.QTableWidget()
     table.setColumnCount(3)
     table.setHorizontalHeaderLabels([
         translate('ImageList', 'new value'),
         translate('ImageList', 'undo'),
         translate('ImageList', 'old value')
     ])
     table.horizontalHeader().setSectionResizeMode(
         0, QtWidgets.QHeaderView.Stretch)
     table.horizontalHeader().setSectionResizeMode(
         2, QtWidgets.QHeaderView.Stretch)
     dialog.layout().addWidget(table)
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(dialog.accept)
     button_box.rejected.connect(dialog.reject)
     dialog.layout().addWidget(button_box)
     changed = False
     position = None
     for image in self.get_selected_images():
         if not image.metadata.changed():
             continue
         dialog.setWindowTitle(
             translate('ImageList',
                       'Metadata differences: {}').format(image.name))
         labels = []
         row = 0
         undo = {}
         table.clearContents()
         new_md = image.metadata
         old_md = Metadata(image.path)
         for key in ('title', 'description', 'keywords', 'rating',
                     'copyright', 'creator', 'date_taken', 'date_digitised',
                     'date_modified', 'orientation', 'camera_model',
                     'lens_model', 'lens_spec', 'focal_length',
                     'focal_length_35', 'aperture', 'latlong', 'altitude',
                     'location_taken', 'location_shown', 'thumbnail'):
             values = getattr(new_md, key), getattr(old_md, key)
             if values[0] == values[1]:
                 continue
             values = [str(x or '') for x in values]
             table.setRowCount(row + 1)
             for n, value in enumerate(values):
                 item = QtWidgets.QTableWidgetItem(value)
                 table.setItem(row, n * 2, item)
             undo[key] = QtWidgets.QTableWidgetItem()
             undo[key].setFlags(undo[key].flags() | Qt.ItemIsUserCheckable)
             undo[key].setCheckState(Qt.Unchecked)
             table.setItem(row, 1, undo[key])
             labels.append(key)
             row += 1
         if not row:
             continue
         table.setVerticalHeaderLabels(labels)
         table.resizeColumnsToContents()
         table.resizeRowsToContents()
         if position:
             dialog.move(position)
         if dialog.exec_() != QtWidgets.QDialog.Accepted:
             return
         position = dialog.pos()
         undo_all = True
         for key, widget in undo.items():
             if widget.checkState() == Qt.Checked:
                 setattr(new_md, key, getattr(old_md, key))
                 changed = True
             else:
                 undo_all = False
         if undo_all:
             image.reload_metadata()
     if changed:
         self.emit_selection()
Exemple #20
0
 def __init__(self, *arg, **kw):
     super(FacebookUploadConfig, self).__init__(*arg, **kw)
     self.setLayout(QtWidgets.QHBoxLayout())
     self.layout().setContentsMargins(0, 0, 0, 0)
     self.widgets = {}
     ## upload config
     config_group = QtWidgets.QGroupBox(self.tr('Options'))
     config_group.setLayout(QtWidgets.QFormLayout())
     self.layout().addWidget(config_group)
     # suppress feed story
     self.widgets['no_story'] = QtWidgets.QCheckBox()
     config_group.layout().addRow(self.tr('Suppress news feed story'),
                                  self.widgets['no_story'])
     label = config_group.layout().labelForField(self.widgets['no_story'])
     label.setWordWrap(True)
     label.setFixedWidth(90)
     # geotagging
     self.widgets['geo_tag'] = QtWidgets.QCheckBox()
     config_group.layout().addRow(
         self.tr('Set "city" from map coordinates'),
         self.widgets['geo_tag'])
     self.widgets['geo_tag'].setChecked(True)
     label = config_group.layout().labelForField(self.widgets['geo_tag'])
     label.setWordWrap(True)
     label.setFixedWidth(90)
     # optimise
     self.widgets['optimise'] = QtWidgets.QCheckBox()
     config_group.layout().addRow(self.tr('Optimise image size'),
                                  self.widgets['optimise'])
     label = config_group.layout().labelForField(self.widgets['optimise'])
     label.setWordWrap(True)
     label.setFixedWidth(90)
     if PIL:
         self.widgets['optimise'].setChecked(True)
     else:
         self.widgets['optimise'].setEnabled(False)
         label.setEnabled(False)
     ## album details
     album_group = QtWidgets.QGroupBox(self.tr('Album'))
     album_group.setLayout(QtWidgets.QHBoxLayout())
     # left hand side
     album_form_left = QtWidgets.QFormLayout()
     album_form_left.setFieldGrowthPolicy(
         QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     album_group.layout().addLayout(album_form_left)
     # album title / selector
     self.widgets['album_choose'] = QtWidgets.QComboBox()
     self.widgets['album_choose'].activated.connect(self.select_album)
     album_form_left.addRow(self.tr('Title'), self.widgets['album_choose'])
     # album description
     self.widgets['album_description'] = QtWidgets.QPlainTextEdit()
     self.widgets['album_description'].setReadOnly(True)
     policy = self.widgets['album_description'].sizePolicy()
     policy.setVerticalStretch(1)
     self.widgets['album_description'].setSizePolicy(policy)
     album_form_left.addRow(self.tr('Description'),
                            self.widgets['album_description'])
     # album location
     self.widgets['album_location'] = QtWidgets.QLineEdit()
     self.widgets['album_location'].setReadOnly(True)
     album_form_left.addRow(self.tr('Location'),
                            self.widgets['album_location'])
     # right hand side
     album_form_right = QtWidgets.QVBoxLayout()
     album_group.layout().addLayout(album_form_right)
     # album thumbnail
     self.widgets['album_thumb'] = QtWidgets.QLabel()
     self.widgets['album_thumb'].setFixedSize(150, 150)
     self.widgets['album_thumb'].setAlignment(Qt.AlignHCenter | Qt.AlignTop)
     album_form_right.addWidget(self.widgets['album_thumb'])
     album_form_right.addStretch(1)
     # new album
     new_album_button = QtWidgets.QPushButton(self.tr('New album'))
     new_album_button.clicked.connect(self.new_album)
     album_form_right.addWidget(new_album_button)
     self.layout().addWidget(album_group, stretch=1)
Exemple #21
0
 def __init__(self, image_list, parent=None):
     super(TabWidget, self).__init__(parent)
     app = QtWidgets.QApplication.instance()
     app.aboutToQuit.connect(self.shutdown)
     if gp and app.test_mode:
         self.gp_log = gp.check_result(gp.use_python_logging())
     self.config_store = app.config_store
     self.image_list = image_list
     self.setLayout(QtWidgets.QGridLayout())
     form = QtWidgets.QFormLayout()
     form.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     self.nm = NameMangler()
     self.file_data = {}
     self.file_list = []
     self.source = None
     self.file_copier = None
     # source selector
     box = QtWidgets.QHBoxLayout()
     box.setContentsMargins(0, 0, 0, 0)
     self.source_selector = QtWidgets.QComboBox()
     self.source_selector.currentIndexChanged.connect(self.new_source)
     box.addWidget(self.source_selector)
     refresh_button = QtWidgets.QPushButton(self.tr('refresh'))
     refresh_button.clicked.connect(self.refresh)
     box.addWidget(refresh_button)
     box.setStretch(0, 1)
     form.addRow(self.tr('Source'), box)
     # path format
     self.path_format = QtWidgets.QLineEdit()
     self.path_format.setValidator(PathFormatValidator())
     self.path_format.textChanged.connect(self.nm.new_format)
     self.path_format.editingFinished.connect(self.path_format_finished)
     form.addRow(self.tr('Target format'), self.path_format)
     # path example
     self.path_example = QtWidgets.QLabel()
     self.nm.new_example.connect(self.path_example.setText)
     form.addRow('=>', self.path_example)
     self.layout().addLayout(form, 0, 0)
     # file list
     self.file_list_widget = QtWidgets.QListWidget()
     self.file_list_widget.setSelectionMode(
         QtWidgets.QAbstractItemView.ExtendedSelection)
     self.file_list_widget.itemSelectionChanged.connect(
         self.selection_changed)
     self.layout().addWidget(self.file_list_widget, 1, 0)
     # selection buttons
     buttons = QtWidgets.QVBoxLayout()
     buttons.addStretch(1)
     self.selected_count = QtWidgets.QLabel()
     buttons.addWidget(self.selected_count)
     select_all = QtWidgets.QPushButton(self.tr('Select\nall'))
     select_all.clicked.connect(self.select_all)
     buttons.addWidget(select_all)
     select_new = QtWidgets.QPushButton(self.tr('Select\nnew'))
     select_new.clicked.connect(self.select_new)
     buttons.addWidget(select_new)
     # copy buttons
     self.move_button = StartStopButton(self.tr('Move\nphotos'),
                                        self.tr('Stop\nmove'))
     self.move_button.click_start.connect(self.move_selected)
     self.move_button.click_stop.connect(self.stop_copy)
     buttons.addWidget(self.move_button)
     self.copy_button = StartStopButton(self.tr('Copy\nphotos'),
                                        self.tr('Stop\ncopy'))
     self.copy_button.click_start.connect(self.copy_selected)
     self.copy_button.click_stop.connect(self.stop_copy)
     buttons.addWidget(self.copy_button)
     self.layout().addLayout(buttons, 0, 1, 2, 1)
     self.selection_changed()
     # final initialisation
     self.image_list.sort_order_changed.connect(self.sort_file_list)
     if qt_version_info >= (5, 0):
         path = QtCore.QStandardPaths.writableLocation(
             QtCore.QStandardPaths.PicturesLocation)
     else:
         path = QtGui.QDesktopServices.storageLocation(
             QtGui.QDesktopServices.PicturesLocation)
     self.path_format.setText(os.path.join(path, '%Y', '%Y_%m_%d',
                                           '{name}'))
     self.refresh()
     self.list_files()
Exemple #22
0
 def __init__(self, image_list, parent=None):
     super(TabWidget, self).__init__(parent)
     self.app = QtWidgets.QApplication.instance()
     self.app.aboutToQuit.connect(self.stop_copy)
     if gp and self.app.options.test:
         self.gp_log = gp.check_result(gp.use_python_logging())
     self.config_store = self.app.config_store
     self.image_list = image_list
     self.setLayout(QtWidgets.QGridLayout())
     form = QtWidgets.QFormLayout()
     form.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     self.nm = NameMangler()
     self.file_data = {}
     self.file_list = []
     self.source = None
     self.file_copier = None
     self.updating = QtCore.QMutex()
     # source selector
     box = QtWidgets.QHBoxLayout()
     box.setContentsMargins(0, 0, 0, 0)
     self.source_selector = QtWidgets.QComboBox()
     self.source_selector.currentIndexChanged.connect(self.new_source)
     self.source_selector.setContextMenuPolicy(Qt.CustomContextMenu)
     self.source_selector.customContextMenuRequested.connect(
         self.remove_folder)
     box.addWidget(self.source_selector)
     refresh_button = QtWidgets.QPushButton(
         translate('ImporterTab', 'refresh'))
     refresh_button.clicked.connect(self.refresh)
     box.addWidget(refresh_button)
     box.setStretch(0, 1)
     form.addRow(translate('ImporterTab', 'Source'), box)
     # update config
     self.config_store.delete('importer', 'folders')
     for section in self.config_store.config.sections():
         if not section.startswith('importer'):
             continue
         path_format = self.config_store.get(section, 'path_format')
         if not (path_format and '(' in path_format):
             continue
         path_format = path_format.replace('(', '{').replace(')', '}')
         self.config_store.set(section, 'path_format', path_format)
     # path format
     self.path_format = QtWidgets.QLineEdit()
     self.path_format.setValidator(PathFormatValidator())
     self.path_format.textChanged.connect(self.nm.new_format)
     self.path_format.editingFinished.connect(self.path_format_finished)
     form.addRow(translate('ImporterTab', 'Target format'),
                 self.path_format)
     # path example
     self.path_example = QtWidgets.QLabel()
     self.nm.new_example.connect(self.path_example.setText)
     form.addRow('=>', self.path_example)
     self.layout().addLayout(form, 0, 0)
     # file list
     self.file_list_widget = QtWidgets.QListWidget()
     self.file_list_widget.setSelectionMode(
         QtWidgets.QAbstractItemView.ExtendedSelection)
     self.file_list_widget.itemSelectionChanged.connect(
         self.selection_changed)
     self.layout().addWidget(self.file_list_widget, 1, 0)
     # selection buttons
     buttons = QtWidgets.QVBoxLayout()
     buttons.addStretch(1)
     self.selected_count = QtWidgets.QLabel()
     buttons.addWidget(self.selected_count)
     select_all = QtWidgets.QPushButton(
         translate('ImporterTab', 'Select\nall'))
     select_all.clicked.connect(self.select_all)
     buttons.addWidget(select_all)
     select_new = QtWidgets.QPushButton(
         translate('ImporterTab', 'Select\nnew'))
     select_new.clicked.connect(self.select_new)
     buttons.addWidget(select_new)
     # copy buttons
     self.move_button = StartStopButton(
         translate('ImporterTab', 'Move\nphotos'),
         translate('ImporterTab', 'Stop\nmove'))
     self.move_button.click_start.connect(self.move_selected)
     self.move_button.click_stop.connect(self.stop_copy)
     buttons.addWidget(self.move_button)
     self.copy_button = StartStopButton(
         translate('ImporterTab', 'Copy\nphotos'),
         translate('ImporterTab', 'Stop\ncopy'))
     self.copy_button.click_start.connect(self.copy_selected)
     self.copy_button.click_stop.connect(self.stop_copy)
     buttons.addWidget(self.copy_button)
     self.layout().addLayout(buttons, 0, 1, 2, 1)
     self.selection_changed()
     # final initialisation
     self.image_list.sort_order_changed.connect(self.sort_file_list)
     path = QtCore.QStandardPaths.writableLocation(
         QtCore.QStandardPaths.PicturesLocation)
     self.path_format.setText(os.path.join(path, '%Y', '%Y_%m_%d',
                                           '{name}'))
Exemple #23
0
 def __init__(self, *arg, **kw):
     super(EditSettings, self).__init__(*arg, **kw)
     self.config_store = QtWidgets.QApplication.instance().config_store
     self.setWindowTitle(self.tr('Photini: settings'))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     self.layout().addWidget(scroll_area)
     panel = QtWidgets.QWidget()
     panel.setLayout(QtWidgets.QFormLayout())
     panel.layout().setRowWrapPolicy(
         max(QtWidgets.QFormLayout.WrapLongRows,
             panel.layout().rowWrapPolicy()))
     # apply & cancel buttons
     self.button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Apply
         | QtWidgets.QDialogButtonBox.Cancel)
     self.button_box.clicked.connect(self.button_clicked)
     self.layout().addWidget(self.button_box)
     # copyright holder name
     self.copyright_name = SingleLineEdit(spell_check=True)
     self.copyright_name.set_value(
         self.config_store.get('user', 'copyright_name', ''))
     panel.layout().addRow(self.tr('Copyright holder name'),
                           self.copyright_name)
     # copyright text
     self.copyright_text = SingleLineEdit(spell_check=True)
     self.copyright_text.set_value(
         self.config_store.get('user', 'copyright_text', ''))
     self.copyright_text.setMinimumWidth(
         width_for_text(self.copyright_text, 'x' * 50))
     panel.layout().addRow(self.tr('Copyright text'), self.copyright_text)
     # creator name
     self.creator_name = SingleLineEdit(spell_check=True)
     self.creator_name.set_value(
         self.config_store.get('user', 'creator_name', ''))
     panel.layout().addRow(self.tr('Creator name'), self.creator_name)
     # IPTC data
     force_iptc = eval(self.config_store.get('files', 'force_iptc',
                                             'False'))
     self.write_iptc = QtWidgets.QCheckBox(self.tr('Always write'))
     self.write_iptc.setChecked(force_iptc)
     panel.layout().addRow(self.tr('IPTC metadata'), self.write_iptc)
     # sidecar files
     if_mode = eval(self.config_store.get('files', 'image', 'True'))
     sc_mode = self.config_store.get('files', 'sidecar', 'auto')
     if not if_mode:
         sc_mode = 'always'
     self.sc_always = QtWidgets.QRadioButton(self.tr('Always create'))
     self.sc_always.setChecked(sc_mode == 'always')
     panel.layout().addRow(self.tr('Sidecar files'), self.sc_always)
     self.sc_auto = QtWidgets.QRadioButton(self.tr('Create if necessary'))
     self.sc_auto.setChecked(sc_mode == 'auto')
     self.sc_auto.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_auto)
     self.sc_delete = QtWidgets.QRadioButton(
         self.tr('Delete when possible'))
     self.sc_delete.setChecked(sc_mode == 'delete')
     self.sc_delete.setEnabled(if_mode)
     panel.layout().addRow('', self.sc_delete)
     # image file locking
     self.write_if = QtWidgets.QCheckBox(self.tr('(when possible)'))
     self.write_if.setChecked(if_mode)
     self.write_if.clicked.connect(self.new_write_if)
     panel.layout().addRow(self.tr('Write to image file'), self.write_if)
     # preserve file timestamps
     keep_time = eval(
         self.config_store.get('files', 'preserve_timestamps', 'False'))
     self.keep_time = QtWidgets.QCheckBox()
     self.keep_time.setChecked(keep_time)
     panel.layout().addRow(self.tr('Preserve file timestamps'),
                           self.keep_time)
     # add panel to scroll area after its size is known
     scroll_area.setWidget(panel)
Exemple #24
0
 def __init__(self, images, *arg, **kw):
     super(NewLensDialog, self).__init__(*arg, **kw)
     self.setWindowTitle(translate('TechnicalTab', 'Photini: define lens'))
     self.setLayout(QtWidgets.QVBoxLayout())
     # main dialog area
     scroll_area = QtWidgets.QScrollArea()
     scroll_area.setWidgetResizable(True)
     self.layout().addWidget(scroll_area)
     panel = QtWidgets.QWidget()
     panel.setLayout(QtWidgets.QFormLayout())
     panel.layout().setFieldGrowthPolicy(
         QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     # ok & cancel buttons
     button_box = QtWidgets.QDialogButtonBox(
         QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
     button_box.accepted.connect(self.accept)
     button_box.rejected.connect(self.reject)
     self.layout().addWidget(button_box)
     # model
     self.lens_model = QtWidgets.QLineEdit()
     self.lens_model.setMinimumWidth(
         width_for_text(self.lens_model, 'x' * 35))
     panel.layout().addRow(translate('TechnicalTab', 'Model name'),
                           self.lens_model)
     # maker
     self.lens_make = QtWidgets.QLineEdit()
     panel.layout().addRow(translate('TechnicalTab', "Maker's name"),
                           self.lens_make)
     # serial number
     self.lens_serial = QtWidgets.QLineEdit()
     panel.layout().addRow(translate('TechnicalTab', 'Serial number'),
                           self.lens_serial)
     ## spec has four items
     self.lens_spec = {}
     # min focal length
     self.lens_spec['min_fl'] = DoubleSpinBox()
     self.lens_spec['min_fl'].setMinimum(0.0)
     self.lens_spec['min_fl'].setSingleStep(1.0)
     self.lens_spec['min_fl'].setSuffix(' mm')
     panel.layout().addRow(
         translate('TechnicalTab', 'Minimum focal length'),
         self.lens_spec['min_fl'])
     # min focal length aperture
     self.lens_spec['min_fl_fn'] = DoubleSpinBox()
     self.lens_spec['min_fl_fn'].setMinimum(0.0)
     self.lens_spec['min_fl_fn'].setPrefix('ƒ/')
     panel.layout().addRow(
         translate('TechnicalTab', 'Aperture at min. focal length'),
         self.lens_spec['min_fl_fn'])
     # max focal length
     self.lens_spec['max_fl'] = DoubleSpinBox()
     self.lens_spec['max_fl'].setMinimum(0.0)
     self.lens_spec['max_fl'].setSingleStep(1.0)
     self.lens_spec['max_fl'].setSuffix(' mm')
     panel.layout().addRow(
         translate('TechnicalTab', 'Maximum focal length'),
         self.lens_spec['max_fl'])
     # max focal length aperture
     self.lens_spec['max_fl_fn'] = DoubleSpinBox()
     self.lens_spec['max_fl_fn'].setMinimum(0.0)
     self.lens_spec['max_fl_fn'].setPrefix('ƒ/')
     panel.layout().addRow(
         translate('TechnicalTab', 'Aperture at max. focal length'),
         self.lens_spec['max_fl_fn'])
     # add panel to scroll area after its size is known
     scroll_area.setWidget(panel)
     # fill in any values we can from existing metadata
     for image in images:
         if image.metadata.lens_model:
             self.lens_model.setText(image.metadata.lens_model)
         if image.metadata.lens_make:
             self.lens_make.setText(image.metadata.lens_make)
         if image.metadata.lens_serial:
             self.lens_serial.setText(image.metadata.lens_serial)
         spec = image.metadata.lens_spec
         for key in self.lens_spec:
             if spec and spec[key]:
                 self.lens_spec[key].set_value(spec[key])