61
62
* A label which fades out if its content does not fit. If the content is
62
63
* cropped, a tooltip is shown when the mouse hovers the widget.
64
class FadingLabel : public QLabel {
65
class FadingLabel : public QLabel
66
explicit FadingLabel(QWidget* parent = 0)
69
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
70
setTextInteractionFlags(Qt::TextBrowserInteraction);
68
explicit FadingLabel(QWidget* parent = 0)
70
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
71
setTextInteractionFlags(Qt::TextBrowserInteraction);
73
QSize minimumSizeHint() const {
74
QSize minimumSizeHint() const {
78
void paintEvent(QPaintEvent* event) {
79
QLabel::paintEvent(event);
84
QLinearGradient gradient;
85
int gradientWidth = fontMetrics().averageCharWidth() * 4;
86
if (alignment() & Qt::AlignLeft) {
87
gradient.setStart(width() - gradientWidth, 0);
88
gradient.setFinalStop(width(), 0);
89
gradient.setColorAt(0, Qt::transparent);
90
gradient.setColorAt(1, palette().color(backgroundRole()));
92
gradient.setStart(0, 0);
93
gradient.setFinalStop(gradientWidth, 0);
94
gradient.setColorAt(0, palette().color(backgroundRole()));
95
gradient.setColorAt(1, Qt::transparent);
97
QPainter painter(this);
98
painter.fillRect(rect(), gradient);
101
bool event(QEvent* event) {
102
if (event->type() == QEvent::ToolTip) {
103
// Show tooltip if cropped
104
QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
106
QToolTip::showText(helpEvent->globalPos(), text());
108
QToolTip::hideText();
113
return QLabel::event(event);
116
inline bool isCropped() const {
117
return sizeHint().width() > width();
79
void paintEvent(QPaintEvent* event)
81
QLabel::paintEvent(event);
86
QLinearGradient gradient;
87
int gradientWidth = fontMetrics().averageCharWidth() * 4;
88
if (alignment() & Qt::AlignLeft) {
89
gradient.setStart(width() - gradientWidth, 0);
90
gradient.setFinalStop(width(), 0);
91
gradient.setColorAt(0, Qt::transparent);
92
gradient.setColorAt(1, palette().color(backgroundRole()));
94
gradient.setStart(0, 0);
95
gradient.setFinalStop(gradientWidth, 0);
96
gradient.setColorAt(0, palette().color(backgroundRole()));
97
gradient.setColorAt(1, Qt::transparent);
99
QPainter painter(this);
100
painter.fillRect(rect(), gradient);
103
bool event(QEvent* event)
105
if (event->type() == QEvent::ToolTip) {
106
// Show tooltip if cropped
107
QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
109
QToolTip::showText(helpEvent->globalPos(), text());
111
QToolTip::hideText();
116
return QLabel::event(event);
119
inline bool isCropped() const {
120
return sizeHint().width() > width();
122
125
* This widget is capable of showing multiple lines of key/value pairs.
124
class KeyValueWidget : public QWidget {
127
: keyLabel(new FadingLabel)
128
, valueLabel(new FadingLabel)
130
if (QApplication::isLeftToRight()) {
131
keyLabel->setAlignment(Qt::AlignRight);
133
valueLabel->setAlignment(Qt::AlignRight);
142
FadingLabel* keyLabel;
143
FadingLabel* valueLabel;
127
class KeyValueWidget : public QWidget
131
: keyLabel(new FadingLabel)
132
, valueLabel(new FadingLabel) {
133
if (QApplication::isLeftToRight()) {
134
keyLabel->setAlignment(Qt::AlignRight);
136
valueLabel->setAlignment(Qt::AlignRight);
145
FadingLabel* keyLabel;
146
FadingLabel* valueLabel;
146
KeyValueWidget(QWidget* parent)
148
, mLayout(new QGridLayout(this))
150
mLayout->setMargin(0);
151
mLayout->setVerticalSpacing(0);
152
mLayout->setHorizontalSpacing(4);
153
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
156
QSize sizeHint() const {
157
int height = fontMetrics().height() * mRows.count();
158
return QSize(150, height);
161
void addRow(const QString& key, const QString& value) {
163
row->keyLabel->setText(i18nc(
164
"@item:intext %1 is a key, we append a colon to it. A value is displayed after",
166
row->valueLabel->setText(value);
169
int rowCount = mLayout->rowCount();
170
mLayout->addWidget(row->keyLabel, rowCount, 0);
171
mLayout->addWidget(row->valueLabel, rowCount, 1);
172
updateKeyColumnWidth();
149
KeyValueWidget(QWidget* parent)
151
, mLayout(new QGridLayout(this)) {
152
mLayout->setMargin(0);
153
mLayout->setVerticalSpacing(0);
154
mLayout->setHorizontalSpacing(4);
155
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
158
QSize sizeHint() const {
159
int height = fontMetrics().height() * mRows.count();
160
return QSize(150, height);
163
void addRow(const QString& key, const QString& value)
166
row->keyLabel->setText(i18nc(
167
"@item:intext %1 is a key, we append a colon to it. A value is displayed after",
169
row->valueLabel->setText(value);
172
int rowCount = mLayout->rowCount();
173
mLayout->addWidget(row->keyLabel, rowCount, 0);
174
mLayout->addWidget(row->valueLabel, rowCount, 1);
175
updateKeyColumnWidth();
183
void resizeEvent(QResizeEvent* event) {
184
QWidget::resizeEvent(event);
185
updateKeyColumnWidth();
187
void resizeEvent(QResizeEvent* event)
189
QWidget::resizeEvent(event);
190
updateKeyColumnWidth();
191
QGridLayout* mLayout;
196
QGridLayout* mLayout;
193
void updateKeyColumnWidth() {
194
const int maxWidth = width() / 2;
196
Q_FOREACH(Row* row, mRows) {
197
int wantedWidth = row->keyLabel->sizeHint().width();
198
if (wantedWidth > keyWidth) {
199
keyWidth = qMin(wantedWidth, maxWidth);
202
Q_FOREACH(Row* row, mRows) {
203
row->keyLabel->setFixedWidth(keyWidth);
198
void updateKeyColumnWidth()
200
const int maxWidth = width() / 2;
202
Q_FOREACH(Row * row, mRows) {
203
int wantedWidth = row->keyLabel->sizeHint().width();
204
if (wantedWidth > keyWidth) {
205
keyWidth = qMin(wantedWidth, maxWidth);
208
Q_FOREACH(Row * row, mRows) {
209
row->keyLabel->setFixedWidth(keyWidth);
208
214
struct InfoContextManagerItemPrivate {
209
InfoContextManagerItem* q;
210
SideBarGroup* mGroup;
212
// One selection fields
213
QWidget* mOneFileWidget;
214
KeyValueWidget* mKeyValueWidget;
215
Document::Ptr mDocument;
217
// Multiple selection fields
218
QLabel* mMultipleFilesLabel;
220
QPointer<ImageMetaInfoDialog> mImageMetaInfoDialog;
222
void updateMetaInfoDialog() {
223
if (!mImageMetaInfoDialog) {
226
ImageMetaInfoModel* model = mDocument ? mDocument->metaInfo() : 0;
227
mImageMetaInfoDialog->setMetaInfo(model, GwenviewConfig::preferredMetaInfoKeyList());
232
mOneFileWidget = new QWidget();
234
mKeyValueWidget = new KeyValueWidget(mOneFileWidget);
236
QLabel* moreLabel = new QLabel(mOneFileWidget);
237
moreLabel->setText(QString("<a href='#'>%1</a>").arg(i18nc("@action show more image meta info", "More...")));
238
moreLabel->setAlignment(Qt::AlignRight);
240
QVBoxLayout* layout = new QVBoxLayout(mOneFileWidget);
241
layout->setMargin(2);
242
layout->setSpacing(2);
243
layout->addWidget(mKeyValueWidget);
244
layout->addWidget(moreLabel);
246
mMultipleFilesLabel = new QLabel();
248
mGroup = new SideBarGroup(i18nc("@title:group", "Meta Information"));
249
q->setWidget(mGroup);
250
mGroup->addWidget(mOneFileWidget);
251
mGroup->addWidget(mMultipleFilesLabel);
253
EventWatcher::install(mGroup, QEvent::Show, q, SLOT(updateSideBarContent()));
255
QObject::connect(moreLabel, SIGNAL(linkActivated(const QString&)),
256
q, SLOT(showMetaInfoDialog()) );
259
void forgetCurrentDocument() {
261
QObject::disconnect(mDocument.data(), 0, q, 0);
262
// "Garbage collect" document
215
InfoContextManagerItem* q;
216
SideBarGroup* mGroup;
218
// One selection fields
219
QWidget* mOneFileWidget;
220
KeyValueWidget* mKeyValueWidget;
221
Document::Ptr mDocument;
223
// Multiple selection fields
224
QLabel* mMultipleFilesLabel;
226
QPointer<ImageMetaInfoDialog> mImageMetaInfoDialog;
228
void updateMetaInfoDialog()
230
if (!mImageMetaInfoDialog) {
233
ImageMetaInfoModel* model = mDocument ? mDocument->metaInfo() : 0;
234
mImageMetaInfoDialog->setMetaInfo(model, GwenviewConfig::preferredMetaInfoKeyList());
239
mOneFileWidget = new QWidget();
241
mKeyValueWidget = new KeyValueWidget(mOneFileWidget);
243
QLabel* moreLabel = new QLabel(mOneFileWidget);
244
moreLabel->setText(QString("<a href='#'>%1</a>").arg(i18nc("@action show more image meta info", "More...")));
245
moreLabel->setAlignment(Qt::AlignRight);
247
QVBoxLayout* layout = new QVBoxLayout(mOneFileWidget);
248
layout->setMargin(2);
249
layout->setSpacing(2);
250
layout->addWidget(mKeyValueWidget);
251
layout->addWidget(moreLabel);
253
mMultipleFilesLabel = new QLabel();
255
mGroup = new SideBarGroup(i18nc("@title:group", "Meta Information"));
256
q->setWidget(mGroup);
257
mGroup->addWidget(mOneFileWidget);
258
mGroup->addWidget(mMultipleFilesLabel);
260
EventWatcher::install(mGroup, QEvent::Show, q, SLOT(updateSideBarContent()));
262
QObject::connect(moreLabel, SIGNAL(linkActivated(QString)),
263
q, SLOT(showMetaInfoDialog()));
266
void forgetCurrentDocument()
269
QObject::disconnect(mDocument.data(), 0, q, 0);
270
// "Garbage collect" document
269
276
InfoContextManagerItem::InfoContextManagerItem(ContextManager* manager)
270
277
: AbstractContextManagerItem(manager)
271
, d(new InfoContextManagerItemPrivate) {
274
connect(contextManager(), SIGNAL(selectionChanged()),
275
SLOT(updateSideBarContent()) );
276
connect(contextManager(), SIGNAL(selectionDataChanged()),
277
SLOT(updateSideBarContent()) );
280
InfoContextManagerItem::~InfoContextManagerItem() {
285
void InfoContextManagerItem::updateSideBarContent() {
286
LOG("updateSideBarContent");
287
if (!d->mGroup->isVisible()) {
288
LOG("updateSideBarContent: not visible, not updating");
291
LOG("updateSideBarContent: really updating");
293
KFileItemList itemList = contextManager()->selectedFileItemList();
294
if (itemList.count() == 0) {
295
d->forgetCurrentDocument();
296
d->mOneFileWidget->hide();
297
d->mMultipleFilesLabel->hide();
298
d->updateMetaInfoDialog();
302
KFileItem item = itemList.first();
303
if (itemList.count() == 1 && !ArchiveUtils::fileItemIsDirOrArchive(item)) {
304
fillOneFileGroup(item);
306
fillMultipleItemsGroup(itemList);
308
d->updateMetaInfoDialog();
311
void InfoContextManagerItem::fillOneFileGroup(const KFileItem& item) {
312
d->mOneFileWidget->show();
313
d->mMultipleFilesLabel->hide();
315
d->forgetCurrentDocument();
316
d->mDocument = DocumentFactory::instance()->load(item.url());
317
connect(d->mDocument.data(), SIGNAL(metaInfoUpdated()),
318
SLOT(updateOneFileInfo()) );
320
d->updateMetaInfoDialog();
324
void InfoContextManagerItem::fillMultipleItemsGroup(const KFileItemList& itemList) {
325
d->forgetCurrentDocument();
327
int folderCount = 0, fileCount = 0;
328
Q_FOREACH(const KFileItem& item, itemList) {
336
if (folderCount == 0) {
337
d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 file selected", "%1 files selected", fileCount));
338
} else if (fileCount == 0) {
339
d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 folder selected", "%1 folders selected", folderCount));
341
d->mMultipleFilesLabel->setText(i18nc("@label. The two parameters are strings like '2 folders' and '1 file'.",
342
"%1 and %2 selected", i18np("%1 folder", "%1 folders", folderCount), i18np("%1 file", "%1 files", fileCount)));
344
d->mOneFileWidget->hide();
345
d->mMultipleFilesLabel->show();
349
void InfoContextManagerItem::updateOneFileInfo() {
355
d->mKeyValueWidget->clear();
356
ImageMetaInfoModel* metaInfoModel = d->mDocument->metaInfo();
357
Q_FOREACH(const QString& key, GwenviewConfig::preferredMetaInfoKeyList()) {
360
metaInfoModel->getInfoForKey(key, &label, &value);
362
if (!label.isEmpty() && !value.isEmpty()) {
363
d->mKeyValueWidget->addRow(label, value);
367
d->mKeyValueWidget->show();
371
void InfoContextManagerItem::showMetaInfoDialog() {
372
if (!d->mImageMetaInfoDialog) {
373
d->mImageMetaInfoDialog = new ImageMetaInfoDialog(d->mOneFileWidget);
374
d->mImageMetaInfoDialog->setAttribute(Qt::WA_DeleteOnClose, true);
375
connect(d->mImageMetaInfoDialog, SIGNAL(preferredMetaInfoKeyListChanged(const QStringList&)),
376
SLOT(slotPreferredMetaInfoKeyListChanged(const QStringList&)) );
378
d->mImageMetaInfoDialog->setMetaInfo(d->mDocument ? d->mDocument->metaInfo() : 0, GwenviewConfig::preferredMetaInfoKeyList());
379
d->mImageMetaInfoDialog->show();
383
void InfoContextManagerItem::slotPreferredMetaInfoKeyListChanged(const QStringList& list) {
384
GwenviewConfig::setPreferredMetaInfoKeyList(list);
385
GwenviewConfig::self()->writeConfig();
278
, d(new InfoContextManagerItemPrivate)
282
connect(contextManager(), SIGNAL(selectionChanged()),
283
SLOT(updateSideBarContent()));
284
connect(contextManager(), SIGNAL(selectionDataChanged()),
285
SLOT(updateSideBarContent()));
288
InfoContextManagerItem::~InfoContextManagerItem()
293
void InfoContextManagerItem::updateSideBarContent()
295
LOG("updateSideBarContent");
296
if (!d->mGroup->isVisible()) {
297
LOG("updateSideBarContent: not visible, not updating");
300
LOG("updateSideBarContent: really updating");
302
KFileItemList itemList = contextManager()->selectedFileItemList();
303
if (itemList.count() == 0) {
304
d->forgetCurrentDocument();
305
d->mOneFileWidget->hide();
306
d->mMultipleFilesLabel->hide();
307
d->updateMetaInfoDialog();
311
KFileItem item = itemList.first();
312
if (itemList.count() == 1 && !ArchiveUtils::fileItemIsDirOrArchive(item)) {
313
fillOneFileGroup(item);
315
fillMultipleItemsGroup(itemList);
317
d->updateMetaInfoDialog();
320
void InfoContextManagerItem::fillOneFileGroup(const KFileItem& item)
322
d->mOneFileWidget->show();
323
d->mMultipleFilesLabel->hide();
325
d->forgetCurrentDocument();
326
d->mDocument = DocumentFactory::instance()->load(item.url());
327
connect(d->mDocument.data(), SIGNAL(metaInfoUpdated()),
328
SLOT(updateOneFileInfo()));
330
d->updateMetaInfoDialog();
334
void InfoContextManagerItem::fillMultipleItemsGroup(const KFileItemList& itemList)
336
d->forgetCurrentDocument();
338
int folderCount = 0, fileCount = 0;
339
Q_FOREACH(const KFileItem & item, itemList) {
347
if (folderCount == 0) {
348
d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 file selected", "%1 files selected", fileCount));
349
} else if (fileCount == 0) {
350
d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 folder selected", "%1 folders selected", folderCount));
352
d->mMultipleFilesLabel->setText(i18nc("@label. The two parameters are strings like '2 folders' and '1 file'.",
353
"%1 and %2 selected", i18np("%1 folder", "%1 folders", folderCount), i18np("%1 file", "%1 files", fileCount)));
355
d->mOneFileWidget->hide();
356
d->mMultipleFilesLabel->show();
359
void InfoContextManagerItem::updateOneFileInfo()
366
d->mKeyValueWidget->clear();
367
ImageMetaInfoModel* metaInfoModel = d->mDocument->metaInfo();
368
Q_FOREACH(const QString & key, GwenviewConfig::preferredMetaInfoKeyList()) {
371
metaInfoModel->getInfoForKey(key, &label, &value);
373
if (!label.isEmpty() && !value.isEmpty()) {
374
d->mKeyValueWidget->addRow(label, value);
378
d->mKeyValueWidget->show();
381
void InfoContextManagerItem::showMetaInfoDialog()
383
if (!d->mImageMetaInfoDialog) {
384
d->mImageMetaInfoDialog = new ImageMetaInfoDialog(d->mOneFileWidget);
385
d->mImageMetaInfoDialog->setAttribute(Qt::WA_DeleteOnClose, true);
386
connect(d->mImageMetaInfoDialog, SIGNAL(preferredMetaInfoKeyListChanged(QStringList)),
387
SLOT(slotPreferredMetaInfoKeyListChanged(QStringList)));
389
d->mImageMetaInfoDialog->setMetaInfo(d->mDocument ? d->mDocument->metaInfo() : 0, GwenviewConfig::preferredMetaInfoKeyList());
390
d->mImageMetaInfoDialog->show();
393
void InfoContextManagerItem::slotPreferredMetaInfoKeyListChanged(const QStringList& list)
395
GwenviewConfig::setPreferredMetaInfoKeyList(list);
396
GwenviewConfig::self()->writeConfig();