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)
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
def add_album(self, album, index=-1): widget = QtWidgets.QCheckBox(album['title'].replace('&', '&&')) widget.setProperty('id', album['id']) widget.setEnabled(album['isWriteable']) if index >= 0: self.sets_widget.layout().insertWidget(index, widget) else: self.sets_widget.layout().addWidget(widget) return widget
def add_set(self, title, description, photoset_id, index=-1): widget = QtWidgets.QCheckBox(title.replace('&', '&&')) if description: widget.setToolTip(html.unescape(description)) widget.setProperty('photoset_id', photoset_id) if index >= 0: self.sets_widget.layout().insertWidget(index, widget) else: self.sets_widget.layout().addWidget(widget) return widget
def add_set(self, title, description, index=-1): widget = QtWidgets.QCheckBox(title.replace('&', '&&')) if description: h = HTMLParser() widget.setToolTip(h.unescape(description)) if index >= 0: self.sets_widget.layout().insertWidget(index, widget) else: self.sets_widget.layout().addWidget(widget) return widget
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)
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)
def __init__(self, image_list, *arg, **kw): super(Technical, self).__init__(*arg, **kw) self.image_list = image_list self.setLayout(QtWidgets.QGridLayout()) 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(self.tr('Date and time')) date_group.setLayout(QtWidgets.QFormLayout()) # taken self.date_widget['taken'] = DateAndTimeWidget() self.date_widget['taken'].new_value.connect(self.new_date_taken) date_group.layout().addRow(self.tr('Taken'), self.date_widget['taken']) # link taken & digitised self.link_widget['taken', 'digitised'] = QtWidgets.QCheckBox( self.tr("Link 'taken' and 'digitised'")) self.link_widget['taken', 'digitised'].clicked.connect(self.new_link_digitised) date_group.layout().addRow('', self.link_widget['taken', 'digitised']) # digitised self.date_widget['digitised'] = DateAndTimeWidget() self.date_widget['digitised'].new_value.connect( self.new_date_digitised) date_group.layout().addRow(self.tr('Digitised'), self.date_widget['digitised']) # link digitised & modified self.link_widget['digitised', 'modified'] = QtWidgets.QCheckBox( self.tr("Link 'digitised' and 'modified'")) self.link_widget['digitised', 'modified'].clicked.connect(self.new_link_modified) date_group.layout().addRow('', self.link_widget['digitised', 'modified']) # modified self.date_widget['modified'] = DateAndTimeWidget() self.date_widget['modified'].new_value.connect(self.new_date_modified) date_group.layout().addRow(self.tr('Modified'), self.date_widget['modified']) # offset self.offset_widget = OffsetWidget() self.offset_widget.apply_offset.connect(self.apply_offset) date_group.layout().addRow(self.tr('Adjust times'), self.offset_widget) self.layout().addWidget(date_group, 0, 0) # other other_group = QtWidgets.QGroupBox(self.tr('Other')) other_group.setLayout(QtWidgets.QFormLayout()) # orientation self.widgets['orientation'] = DropdownEdit() self.widgets['orientation'].add_item(self.tr('normal'), 1) self.widgets['orientation'].add_item(self.tr('rotate -90'), 6) self.widgets['orientation'].add_item(self.tr('rotate +90'), 8) self.widgets['orientation'].add_item(self.tr('rotate 180'), 3) self.widgets['orientation'].add_item(self.tr('reflect left-right'), 2) self.widgets['orientation'].add_item(self.tr('reflect top-bottom'), 4) self.widgets['orientation'].add_item(self.tr('reflect tr-bl'), 5) self.widgets['orientation'].add_item(self.tr('reflect tl-br'), 7) self.widgets['orientation'].new_value.connect(self.new_orientation) other_group.layout().addRow(self.tr('Orientation'), self.widgets['orientation']) # lens model self.widgets['lens_model'] = DropdownEdit() self.widgets['lens_model'].setContextMenuPolicy(Qt.CustomContextMenu) self.widgets['lens_model'].add_item(self.tr('<define new lens>'), '<add lens>') for model in self.lens_data.lenses: self.widgets['lens_model'].add_item(model, model) 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(self.tr('Lens model'), self.widgets['lens_model']) # lens specification self.widgets['lens_spec'] = LensSpecWidget() other_group.layout().addRow(self.tr('Lens details'), self.widgets['lens_spec']) # focal length self.widgets['focal_length'] = FloatEdit() self.widgets['focal_length'].validator().setBottom(0.1) self.widgets['focal_length'].editingFinished.connect( self.new_focal_length) other_group.layout().addRow(self.tr('Focal length (mm)'), self.widgets['focal_length']) # 35mm equivalent focal length self.widgets['focal_length_35'] = IntEdit() self.widgets['focal_length_35'].validator().setBottom(1) self.widgets['focal_length_35'].editingFinished.connect( self.new_focal_length_35) other_group.layout().addRow(self.tr('35mm equiv (mm)'), self.widgets['focal_length_35']) # aperture self.widgets['aperture'] = FloatEdit() self.widgets['aperture'].validator().setBottom(0.1) self.widgets['aperture'].editingFinished.connect(self.new_aperture) other_group.layout().addRow(self.tr('Aperture f/'), self.widgets['aperture']) self.layout().addWidget(other_group, 0, 1) self.layout().setColumnStretch(0, 1) self.layout().setColumnStretch(1, 1) # disable until an image is selected self.setEnabled(False)
def do_import(self, parent): args = [ parent, self.tr('Import GPX file'), parent.app.config_store.get('paths', 'gpx', ''), self.tr("GPX files (*.gpx *.GPX *.Gpx);;All files (*)") ] if eval(parent.app.config_store.get('pyqt', 'native_dialog', 'True')): pass else: args += [None, QtWidgets.QFileDialog.DontUseNativeDialog] path = QtWidgets.QFileDialog.getOpenFileName(*args) path = path[0] if not path: return parent.app.config_store.set('paths', 'gpx', os.path.dirname(os.path.abspath(path))) # get user options config_store = QtWidgets.QApplication.instance().config_store dialog = QtWidgets.QDialog(parent=parent) dialog.setWindowTitle(self.tr('GPX options')) dialog.setLayout(QtWidgets.QFormLayout()) max_interval = QtWidgets.QSpinBox() max_interval.setRange(60, 300) max_interval.setValue( int(config_store.get('gpx_importer', 'interval', '120'))) max_interval.setSuffix(self.tr(' secs')) dialog.layout().addRow(self.tr('Max time between points'), max_interval) max_dilution = QtWidgets.QDoubleSpinBox() max_dilution.setRange(1.0, 100.0) max_dilution.setValue( float(config_store.get('gpx_importer', 'dilution', '2.5'))) max_dilution.setSingleStep(0.1) dialog.layout().addRow(self.tr('Max dilution of precision'), max_dilution) if hasattr(parent.tabs.currentWidget(), 'plot_track'): plot_track = QtWidgets.QCheckBox() plot_track.setChecked( bool(config_store.get('gpx_importer', 'plot', 'True'))) dialog.layout().addRow(self.tr('Plot track on map'), plot_track) else: plot_track = False button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok) button_box.accepted.connect(dialog.accept) dialog.layout().addWidget(button_box) dialog.exec_() max_interval = max_interval.value() max_dilution = max_dilution.value() config_store.set('gpx_importer', 'interval', max_interval) config_store.set('gpx_importer', 'dilution', max_dilution) if plot_track: plot_track = plot_track.isChecked() config_store.set('gpx_importer', 'plot', plot_track) # make a list of all points in the file points = [] discards = 0 for p in self.read_file(path): if p.horizontal_dilution and p.horizontal_dilution > max_dilution: discards += 1 continue time_stamp = p.time if time_stamp.tzinfo is not None: # convert timestamp to UTC utc_offset = time_stamp.utcoffset() time_stamp = (time_stamp - utc_offset).replace(tzinfo=None) # add point to list points.append((time_stamp, p.latitude, p.longitude)) if discards: logger.warning('Discarded %d low accuracy points', discards) if not points: logger.warning('No points found in file "%s"', path) return logger.warning('Using %d points', len(points)) # sort points by timestamp points.sort(key=lambda x: x[0]) # display on map if plot_track: # divide points into contiguous tracks tracks = [] t = [] for p in points: if t and (p[0] - t[-1][0]).total_seconds() > max_interval: tracks.append(t) t = [] t.append(p) if t: tracks.append(t) parent.tabs.currentWidget().plot_track(tracks) # set image coordinates max_interval = max_interval / 2.0 for image in parent.image_list.get_selected_images(): if not image.metadata.date_taken: continue time_stamp = image.metadata.date_taken.to_utc() if len(points) < 2: lo, hi = 0, 0 elif time_stamp < points[0][0]: lo, hi = 0, 1 elif time_stamp > points[-1][0]: lo, hi = -2, -1 else: # binary search for points with nearest timestamps lo, hi = 0, len(points) - 1 while hi - lo > 1: mid = (lo + hi) // 2 if time_stamp >= points[mid][0]: lo = mid elif time_stamp <= points[mid][0]: hi = mid # use linear interpolation (or extrapolation) to set lat & long dt_lo = (time_stamp - points[lo][0]).total_seconds() dt_hi = (time_stamp - points[hi][0]).total_seconds() if abs(dt_lo) > max_interval and abs(dt_hi) > max_interval: logger.info('No point for time %s', image.metadata.date_taken) continue if dt_lo == dt_hi: beta = 0.5 else: beta = dt_lo / (dt_lo - dt_hi) lat = points[lo][1] + (beta * (points[hi][1] - points[lo][1])) lng = points[lo][2] + (beta * (points[hi][2] - points[lo][2])) image.metadata.latlong = lat, lng parent.image_list.emit_selection()
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)
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)