Beispiel #1
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)
Beispiel #2
0
 def __init__(self, image_list, *args, **kwds):
     super(LatLongDisplay, self).__init__(*args, **kwds)
     self.image_list = image_list
     self.label = QtWidgets.QLabel(translate('MapTabsAll', 'Lat, long'))
     self.label.setAlignment(Qt.AlignRight)
     self.setFixedWidth(width_for_text(self, '8' * 23))
     self.setEnabled(False)
     self.editingFinished.connect(self.editing_finished)
Beispiel #3
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.setMinimumWidth(width_for_text(self.user_name, 'x' * 12))
     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)
Beispiel #4
0
 def __init__(self, *args, **kw):
     super(LocationInfo, self).__init__(*args, **kw)
     layout = QtWidgets.QGridLayout()
     self.setLayout(layout)
     layout.setContentsMargins(0, 0, 0, 0)
     self.members = {}
     for key in ('SubLocation', 'City', 'ProvinceState', 'CountryName',
                 'CountryCode', 'WorldRegion'):
         self.members[key] = SingleLineEdit(
             length_check=ImageMetadata.max_bytes(key))
         self.members[key].editingFinished.connect(self.editing_finished)
     self.members['CountryCode'].setMaximumWidth(
         width_for_text(self.members['CountryCode'], 'W' * 4))
     self.members['SubLocation'].setToolTip(
         translate('AddressTab', 'Enter the name of the sublocation.'))
     self.members['City'].setToolTip(
         translate('AddressTab', 'Enter the name of the city.'))
     self.members['ProvinceState'].setToolTip(
         translate('AddressTab',
                   'Enter the name of the province or state.'))
     self.members['CountryName'].setToolTip(
         translate('AddressTab', 'Enter the name of the country.'))
     self.members['CountryCode'].setToolTip(
         translate(
             'AddressTab',
             'Enter the 2 or 3 letter ISO 3166 country code of the country.'
         ))
     self.members['WorldRegion'].setToolTip(
         translate('AddressTab', 'Enter the name of the world region.'))
     for j, text in enumerate((
             translate('AddressTab', 'Street'),
             translate('AddressTab', 'City'),
             translate('AddressTab', 'Province'),
             translate('AddressTab', 'Country'),
             translate('AddressTab', 'Region'),
     )):
         label = QtWidgets.QLabel(text)
         label.setAlignment(Qt.AlignRight)
         layout.addWidget(label, j, 0)
     layout.addWidget(self.members['SubLocation'], 0, 1, 1, 2)
     layout.addWidget(self.members['City'], 1, 1, 1, 2)
     layout.addWidget(self.members['ProvinceState'], 2, 1, 1, 2)
     layout.addWidget(self.members['CountryName'], 3, 1)
     layout.addWidget(self.members['CountryCode'], 3, 2)
     layout.addWidget(self.members['WorldRegion'], 4, 1, 1, 2)
     layout.setRowStretch(5, 1)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #7
0
 def __init__(self, *arg, **kw):
     super(RatingWidget, self).__init__(*arg, **kw)
     self.multiple_values = multiple_values()
     self.setLayout(QtWidgets.QHBoxLayout())
     self.layout().setContentsMargins(0, 0, 0, 0)
     # slider
     self.slider = Slider(Qt.Horizontal)
     self.slider.setFixedWidth(width_for_text(self.slider, 'x' * 25))
     self.slider.setRange(-2, 5)
     self.slider.setPageStep(1)
     self.slider.valueChanged.connect(self.set_display)
     self.layout().addWidget(self.slider)
     # display
     self.display = QtWidgets.QLineEdit()
     self.display.setStyleSheet("* {background-color:rgba(0,0,0,0);}")
     self.display.setFrame(False)
     self.display.setReadOnly(True)
     self.display.setContextMenuPolicy(Qt.NoContextMenu)
     self.display.setFocusPolicy(Qt.NoFocus)
     self.layout().addWidget(self.display)
     # adopt child methods/signals
     self.is_multiple = self.slider.is_multiple
     self.editing_finished = self.slider.editing_finished
Beispiel #8
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)
Beispiel #9
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.widgets = {}
     self.date_widget = {}
     self.link_widget = {}
     # date and time
     date_group = QtWidgets.QGroupBox(
         translate('TechnicalTab', 'Date and time'))
     date_group.setLayout(QtWidgets.QFormLayout())
     # create date and link widgets
     for master in self._master_slave:
         self.date_widget[master] = DateAndTimeWidget(master)
         self.date_widget[master].new_value.connect(self.new_date_value)
         slave = self._master_slave[master]
         if slave:
             self.link_widget[master, slave] = DateLink(master)
             self.link_widget[master, slave].new_link.connect(self.new_link)
     self.link_widget['taken', 'digitised'].setText(
         translate('TechnicalTab', "Link 'taken' and 'digitised'"))
     self.link_widget['digitised', 'modified'].setText(
         translate('TechnicalTab', "Link 'digitised' and 'modified'"))
     # add to layout
     date_group.layout().addRow(translate('TechnicalTab', 'Taken'),
                                self.date_widget['taken'])
     date_group.layout().addRow('', self.link_widget['taken', 'digitised'])
     date_group.layout().addRow(translate('TechnicalTab', 'Digitised'),
                                self.date_widget['digitised'])
     date_group.layout().addRow('', self.link_widget['digitised', 'modified'])
     date_group.layout().addRow(translate('TechnicalTab', 'Modified'),
                                self.date_widget['modified'])
     # offset
     self.offset_widget = OffsetWidget()
     self.offset_widget.apply_offset.connect(self.apply_offset)
     date_group.layout().addRow(
         translate('TechnicalTab', 'Adjust times'), self.offset_widget)
     self.layout().addWidget(date_group)
     # other
     other_group = QtWidgets.QGroupBox(translate('TechnicalTab', 'Other'))
     other_group.setLayout(QtWidgets.QFormLayout())
     other_group.layout().setFieldGrowthPolicy(
         QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     # orientation
     self.widgets['orientation'] = DropdownEdit()
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'normal'), 1, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate -90'), 6, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate +90'), 8, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate 180'), 3, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect left-right'), 2, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect top-bottom'), 4, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect tr-bl'), 5, ordered=False)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect tl-br'), 7, ordered=False)
     self.widgets['orientation'].new_value.connect(self.new_orientation)
     other_group.layout().addRow(translate(
         'TechnicalTab', 'Orientation'), self.widgets['orientation'])
     # camera model
     self.widgets['camera_model'] = CameraList(extendable=True)
     self.widgets['camera_model'].setMinimumWidth(
         width_for_text(self.widgets['camera_model'], 'x' * 30))
     self.widgets['camera_model'].new_value.connect(self.new_camera_model)
     self.widgets['camera_model'].extend_list.connect(self.add_camera_model)
     other_group.layout().addRow(translate(
         'TechnicalTab', 'Camera'), self.widgets['camera_model'])
     # lens model
     self.widgets['lens_model'] = LensList(extendable=True)
     self.widgets['lens_model'].setMinimumWidth(
         width_for_text(self.widgets['lens_model'], 'x' * 30))
     self.widgets['lens_model'].new_value.connect(self.new_lens_model)
     self.widgets['lens_model'].extend_list.connect(self.add_lens_model)
     other_group.layout().addRow(translate(
         'TechnicalTab', 'Lens model'), self.widgets['lens_model'])
     # focal length
     self.widgets['focal_length'] = DoubleSpinBox()
     self.widgets['focal_length'].setMinimum(0.0)
     self.widgets['focal_length'].setSuffix(' mm')
     self.widgets['focal_length'].new_value.connect(self.new_focal_length)
     other_group.layout().addRow(translate(
         'TechnicalTab', 'Focal length'), self.widgets['focal_length'])
     # 35mm equivalent focal length
     self.widgets['focal_length_35'] = IntSpinBox()
     self.widgets['focal_length_35'].setMinimum(0)
     self.widgets['focal_length_35'].setSuffix(' mm')
     self.widgets['focal_length_35'].new_value.connect(self.new_focal_length_35)
     other_group.layout().addRow(translate(
         'TechnicalTab', '35mm equiv'), self.widgets['focal_length_35'])
     # aperture
     self.widgets['aperture'] = DoubleSpinBox()
     self.widgets['aperture'].setMinimum(0.0)
     self.widgets['aperture'].setPrefix('ƒ/')
     self.widgets['aperture'].new_value.connect(self.new_aperture)
     other_group.layout().addRow(translate(
         'TechnicalTab', 'Aperture'), self.widgets['aperture'])
     self.layout().addWidget(other_group, stretch=1)
     # disable until an image is selected
     self.setEnabled(False)
Beispiel #10
0
 def diff_selected_metadata(self):
     dialog = QtWidgets.QDialog(parent=self)
     dialog.setLayout(QtWidgets.QVBoxLayout())
     width = width_for_text(dialog, 'x' * 120)
     dialog.setFixedSize(min(width,
                             self.window().width()),
                         min(width // 2,
                             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, utf_safe=self.app.options.utf_safe)
         for key in ('title', 'description', 'keywords', 'rating',
                     'creator', 'creator_title', 'credit_line', 'copyright',
                     'usageterms', 'instructions', 'contact_info',
                     '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 qt_version_info >= (6, 0):
             result = dialog.exec()
         else:
             result = dialog.exec_()
         if result != 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()
Beispiel #11
0
 def __init__(self, parent=None):
     super(ImageList, self).__init__(parent)
     self.app = QtWidgets.QApplication.instance()
     self.drag_icon = None
     self.images = []
     self.last_selected = None
     self.selection_anchor = None
     self.thumb_size = self.app.config_store.get('controls', 'thumb_size',
                                                 4)
     if self.thumb_size > 20:
         # old config, in pixels
         self.thumb_size = self.thumb_size // 20
     layout = QtWidgets.QGridLayout()
     layout.setSpacing(0)
     layout.setRowStretch(0, 1)
     layout.setColumnStretch(3, 1)
     self.setLayout(layout)
     layout.setContentsMargins(0, 0, 0, 0)
     # thumbnail display
     self.scroll_area = ScrollArea()
     self.scroll_area.dropped_images.connect(self.open_file_list)
     self.scroll_area.multi_row_changed.connect(
         self._ensure_selected_visible)
     layout.addWidget(self.scroll_area, 0, 0, 1, 6)
     QtGui2.QShortcut(QtGui.QKeySequence.MoveToPreviousChar,
                      self.scroll_area, self.move_to_prev_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.MoveToNextChar, self.scroll_area,
                      self.move_to_next_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.MoveToStartOfLine,
                      self.scroll_area, self.move_to_first_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.MoveToEndOfLine, self.scroll_area,
                      self.move_to_last_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.SelectPreviousChar,
                      self.scroll_area, self.select_prev_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.SelectNextChar, self.scroll_area,
                      self.select_next_thumb)
     QtGui2.QShortcut(QtGui.QKeySequence.SelectAll, self.scroll_area,
                      self.select_all)
     # sort key selector
     layout.addWidget(QtWidgets.QLabel(self.tr('sort by: ')), 1, 0)
     self.sort_name = QtWidgets.QRadioButton(self.tr('file name'))
     self.sort_name.clicked.connect(self._new_sort_order)
     layout.addWidget(self.sort_name, 1, 1)
     self.sort_date = QtWidgets.QRadioButton(self.tr('date taken'))
     layout.addWidget(self.sort_date, 1, 2)
     self.sort_date.clicked.connect(self._new_sort_order)
     if self.app.config_store.get('controls', 'sort_date', False):
         self.sort_date.setChecked(True)
     else:
         self.sort_name.setChecked(True)
     # size selector
     layout.addWidget(QtWidgets.QLabel(self.tr('thumbnail size: ')), 1, 4)
     self.size_slider = QtWidgets.QSlider(Qt.Horizontal)
     self.size_slider.setTracking(False)
     self.size_slider.setRange(4, 9)
     self.size_slider.setPageStep(1)
     self.size_slider.setValue(self.thumb_size)
     self.size_slider.setTickPosition(QtWidgets.QSlider.TicksBelow)
     self.size_slider.setMinimumWidth(
         width_for_text(self.size_slider, 'x' * 20))
     self.size_slider.valueChanged.connect(self._new_thumb_size)
     layout.addWidget(self.size_slider, 1, 5)
Beispiel #12
0
 def _set_thumb_size(self, thumb_size):
     width = width_for_text(self.label, 'X' * thumb_size * 20) // 6
     self.image.setFixedSize(width, width)
     self._elide_name()
Beispiel #13
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.widgets = {}
     self.date_widget = {}
     self.link_widget = {}
     # store lens data in another object
     self.lens_data = LensData()
     # date and time
     date_group = QtWidgets.QGroupBox(
         translate('TechnicalTab', 'Date and time'))
     date_group.setLayout(QtWidgets.QFormLayout())
     # create date and link widgets
     for master in self._master_slave:
         self.date_widget[master] = DateAndTimeWidget(master)
         self.date_widget[master].new_value.connect(self.new_date_value)
         slave = self._master_slave[master]
         if slave:
             self.link_widget[master, slave] = DateLink(master)
             self.link_widget[master, slave].new_link.connect(self.new_link)
     self.link_widget['taken', 'digitised'].setText(
         translate('TechnicalTab', "Link 'taken' and 'digitised'"))
     self.link_widget['digitised', 'modified'].setText(
         translate('TechnicalTab', "Link 'digitised' and 'modified'"))
     # add to layout
     date_group.layout().addRow(translate('TechnicalTab', 'Taken'),
                                self.date_widget['taken'])
     date_group.layout().addRow('', self.link_widget['taken', 'digitised'])
     date_group.layout().addRow(translate('TechnicalTab', 'Digitised'),
                                self.date_widget['digitised'])
     date_group.layout().addRow('', self.link_widget['digitised',
                                                     'modified'])
     date_group.layout().addRow(translate('TechnicalTab', 'Modified'),
                                self.date_widget['modified'])
     # offset
     self.offset_widget = OffsetWidget()
     self.offset_widget.apply_offset.connect(self.apply_offset)
     date_group.layout().addRow(translate('TechnicalTab', 'Adjust times'),
                                self.offset_widget)
     self.layout().addWidget(date_group)
     # other
     other_group = QtWidgets.QGroupBox(translate('TechnicalTab', 'Other'))
     other_group.setLayout(QtWidgets.QFormLayout())
     other_group.layout().setFieldGrowthPolicy(
         QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
     # orientation
     self.widgets['orientation'] = DropdownEdit()
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'normal'), 1)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate -90'), 6)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate +90'), 8)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'rotate 180'), 3)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect left-right'), 2)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect top-bottom'), 4)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect tr-bl'), 5)
     self.widgets['orientation'].add_item(
         translate('TechnicalTab', 'reflect tl-br'), 7)
     self.widgets['orientation'].new_value.connect(self.new_orientation)
     other_group.layout().addRow(translate('TechnicalTab', 'Orientation'),
                                 self.widgets['orientation'])
     # lens model
     self.widgets['lens_model'] = DropdownEdit()
     self.widgets['lens_model'].setMinimumWidth(
         width_for_text(self.widgets['lens_model'], 'x' * 30))
     self.widgets['lens_model'].setContextMenuPolicy(Qt.CustomContextMenu)
     self.widgets['lens_model'].add_item(
         translate('TechnicalTab', '<define new lens>'), '<add lens>')
     for lens_id in self.lens_data.lenses:
         self.widgets['lens_model'].add_item(
             self.lens_data.get_name(lens_id), lens_id)
     self.widgets['lens_model'].new_value.connect(self.new_lens_model)
     self.widgets['lens_model'].customContextMenuRequested.connect(
         self.remove_lens_model)
     other_group.layout().addRow(translate('TechnicalTab', 'Lens model'),
                                 self.widgets['lens_model'])
     # lens specification
     self.widgets['lens_spec'] = LensSpecWidget()
     other_group.layout().addRow(translate('TechnicalTab', 'Lens details'),
                                 self.widgets['lens_spec'])
     # focal length
     self.widgets['focal_length'] = DoubleSpinBox()
     self.widgets['focal_length'].setMinimum(0.0)
     self.widgets['focal_length'].setSuffix(' mm')
     self.widgets['focal_length'].new_value.connect(self.new_focal_length)
     other_group.layout().addRow(translate('TechnicalTab', 'Focal length'),
                                 self.widgets['focal_length'])
     # 35mm equivalent focal length
     self.widgets['focal_length_35'] = IntSpinBox()
     self.widgets['focal_length_35'].setMinimum(0)
     self.widgets['focal_length_35'].setSuffix(' mm')
     self.widgets['focal_length_35'].new_value.connect(
         self.new_focal_length_35)
     other_group.layout().addRow(translate('TechnicalTab', '35mm equiv'),
                                 self.widgets['focal_length_35'])
     # aperture
     self.widgets['aperture'] = DoubleSpinBox()
     self.widgets['aperture'].setMinimum(0.0)
     self.widgets['aperture'].setPrefix('ƒ/')
     self.widgets['aperture'].new_value.connect(self.new_aperture)
     other_group.layout().addRow(translate('TechnicalTab', 'Aperture'),
                                 self.widgets['aperture'])
     self.layout().addWidget(other_group, stretch=1)
     # disable until an image is selected
     self.setEnabled(False)
Beispiel #14
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])
Beispiel #15
0
 def tabSizeHint(self, index):
     size = super(QTabBar, self).tabSizeHint(index)
     size.setWidth(max(size.width(), width_for_text(self, 'x' * 10)))
     return size
Beispiel #16
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)