infocontextmanageritem.cpp 7.14 KB
Newer Older
1
2
/*
Gwenview: an image viewer
3
Copyright 2007 Aurélien Gâteau <aurelien.gateau@free.fr>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/
20
#include "infocontextmanageritem.moc"
21
22

// Qt
23
#include <QFormLayout>
24
#include <QLabel>
25
#include <QPointer>
26
#include <QPushButton>
27
#include <QVBoxLayout>
28
29
30

// KDE
#include <kfileitem.h>
31
#include <klocale.h>
32
#include <kwordwrap.h>
33
34

// Local
Aurélien Gâteau's avatar
Aurélien Gâteau committed
35
#include "contextmanager.h"
36
#include "imagemetainfodialog.h"
37
#include "sidebar.h"
38
#include <lib/archiveutils.h>
39
#include <lib/gwenviewconfig.h>
40
#include <lib/preferredimagemetainfomodel.h>
41
42
#include <lib/document/document.h>
#include <lib/document/documentfactory.h>
43
44
45

namespace Gwenview {

Aurélien Gâteau's avatar
Aurélien Gâteau committed
46
47
48
49
#undef ENABLE_LOG
#undef LOG
//#define ENABLE_LOG
#ifdef ENABLE_LOG
Thiago Macieira's avatar
Thiago Macieira committed
50
#define LOG(x) kDebug() << x
Aurélien Gâteau's avatar
Aurélien Gâteau committed
51
52
53
54
#else
#define LOG(x) ;
#endif

55

56
/**
57
 * This widget is capable of showing multiple lines of key/value pairs.
58
59
60
61
 */
class KeyValueWidget : public QWidget {
public:
	KeyValueWidget(QWidget* parent)
62
63
64
65
	: QWidget(parent)
	, mLayout(new QFormLayout(this)) {
		mLayout->setLabelAlignment(Qt::AlignRight);
		setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
66
67
	}

68
69
	void addRow(const QString& key, const QString& value) {
		QString keyString = i18nc(
70
				"@item:intext %1 is a key, we append a colon to it. A value is displayed after",
71
				"%1:", key);
72

Aurélien Gâteau's avatar
Aurélien Gâteau committed
73
		QLabel* keyLabel = new QLabel;
74
		keyLabel->setWordWrap(true);
Aurélien Gâteau's avatar
Aurélien Gâteau committed
75
		keyLabel->setText(keyString);
76
		keyLabel->setAlignment(Qt::AlignRight);
Aurélien Gâteau's avatar
Aurélien Gâteau committed
77

78
79
		QLabel* valueLabel = new QLabel;
		valueLabel->setWordWrap(true);
80
		valueLabel->setText(value);
Aurélien Gâteau's avatar
Aurélien Gâteau committed
81
82

		mLayout->addRow(keyLabel, valueLabel);
83
	}
84

85
86
87
	void clear() {
		Q_FOREACH(QWidget* child, findChildren<QWidget*>()) {
			child->deleteLater();
88
89
90
91
		}
	}

private:
92
	QFormLayout* mLayout;
93
94
95
};


96
struct InfoContextManagerItemPrivate {
97
	InfoContextManagerItem* q;
98
99
	SideBarGroup* mGroup;

100
	// One selection fields
101
	QWidget* mOneFileWidget;
102
	KeyValueWidget* mKeyValueWidget;
103
	KFileItem mFileItem;
104
	Document::Ptr mDocument;
105

106
107
108
	// Multiple selection fields
	QLabel* mMultipleFilesLabel;

109
	QPointer<ImageMetaInfoDialog> mImageMetaInfoDialog;
110
111
112
113
114
115
116
117

	void updateMetaInfoDialog() {
		if (!mImageMetaInfoDialog) {
			return;
		}
		ImageMetaInfoModel* model = mDocument ? mDocument->metaInfo() : 0;
		mImageMetaInfoDialog->setMetaInfo(model, GwenviewConfig::preferredMetaInfoKeyList());
	}
118

119

120
121
	void setupGroup() {
		mOneFileWidget = new QWidget();
122

123
		mKeyValueWidget = new KeyValueWidget(mOneFileWidget);
124

125
126
127
		QLabel* moreLabel = new QLabel(mOneFileWidget);
		moreLabel->setText(QString("<a href='#'>%1</a>").arg(i18nc("@action show more image meta info", "More...")));
		moreLabel->setAlignment(Qt::AlignRight);
Aurélien Gâteau's avatar
Aurélien Gâteau committed
128

129
130
131
132
133
		QVBoxLayout* layout = new QVBoxLayout(mOneFileWidget);
		layout->setMargin(2);
		layout->setSpacing(2);
		layout->addWidget(mKeyValueWidget);
		layout->addWidget(moreLabel);
134

135
		mMultipleFilesLabel = new QLabel();
136

137
138
139
140
		mGroup = new SideBarGroup(i18nc("@title:group", "Meta Information"));
		q->setWidget(mGroup);
		mGroup->addWidget(mOneFileWidget);
		mGroup->addWidget(mMultipleFilesLabel);
141

142
		new AboutToShowHelper(mGroup, q, SLOT(updateSideBarContent()));
143

144
145
146
147
		QObject::connect(moreLabel, SIGNAL(linkActivated(const QString&)),
			q, SLOT(showMetaInfoDialog()) );
	}
};
148
149


150
151
152
153
154
155
156
157
InfoContextManagerItem::InfoContextManagerItem(ContextManager* manager)
: AbstractContextManagerItem(manager)
, d(new InfoContextManagerItemPrivate) {
	d->q = this;
	d->setupGroup();
	connect(contextManager(), SIGNAL(selectionChanged()),
		SLOT(updateSideBarContent()) );
}
158

159
160
InfoContextManagerItem::~InfoContextManagerItem() {
	delete d;
161
162
}

Aurélien Gâteau's avatar
Aurélien Gâteau committed
163

164
void InfoContextManagerItem::updateSideBarContent() {
Aurélien Gâteau's avatar
Aurélien Gâteau committed
165
	LOG("updateSideBarContent");
166
	if (!d->mGroup->isVisible()) {
Aurélien Gâteau's avatar
Aurélien Gâteau committed
167
168
169
170
171
		LOG("updateSideBarContent: not visible, not updating");
		return;
	}
	LOG("updateSideBarContent: really updating");

172
	KFileItemList itemList = contextManager()->selection();
173
	if (itemList.count() == 0) {
174
175
		// "Garbage collect" document
		d->mDocument = 0;
176
		d->updateMetaInfoDialog();
177
178
179
		return;
	}

180
181
182
183
184
	KFileItem item = itemList.first();
	if (itemList.count() == 1 && !ArchiveUtils::fileItemIsDirOrArchive(item)) {
		fillOneFileGroup(item);
	} else {
		fillMultipleItemsGroup(itemList);
185
	}
186
	d->updateMetaInfoDialog();
187
188
}

189
void InfoContextManagerItem::fillOneFileGroup(const KFileItem& item) {
190
	d->mFileItem = item;
191
192
	d->mOneFileWidget->show();
	d->mMultipleFilesLabel->hide();
193

194
	d->mDocument = DocumentFactory::instance()->load(item.url());
Aurélien Gâteau's avatar
Aurélien Gâteau committed
195
	connect(d->mDocument.data(), SIGNAL(metaInfoUpdated()),
Aurélien Gâteau's avatar
Aurélien Gâteau committed
196
		SLOT(updateOneFileInfo()) );
197

198
199
	d->updateMetaInfoDialog();
	updateOneFileInfo();
200
201
}

202
void InfoContextManagerItem::fillMultipleItemsGroup(const KFileItemList& itemList) {
203
204
205
	// "Garbage collect" document
	d->mDocument = 0;

206
	int folderCount = 0, fileCount = 0;
207
	Q_FOREACH(const KFileItem& item, itemList) {
Aurélien Gâteau's avatar
Aurélien Gâteau committed
208
		if (item.isDir()) {
209
210
211
212
213
214
215
			folderCount++;
		} else {
			fileCount++;
		}
	}

	if (folderCount == 0) {
Andrius Štikonas's avatar
Andrius Štikonas committed
216
		d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 file selected", "%1 files selected", fileCount));
217
	} else if (fileCount == 0) {
Andrius Štikonas's avatar
Andrius Štikonas committed
218
		d->mMultipleFilesLabel->setText(i18ncp("@label", "%1 folder selected", "%1 folders selected", folderCount));
219
	} else {
Andrius Štikonas's avatar
Andrius Štikonas committed
220
221
		d->mMultipleFilesLabel->setText(i18nc("@label. The two parameters are strings like '2 folders' and '1 file'.",
			"%1 and %2 selected", i18np("%1 folder", "%1 folders", folderCount), i18np("%1 file", "%1 files", fileCount)));
222
	}
223
224
	d->mOneFileWidget->hide();
	d->mMultipleFilesLabel->show();
225
226
227
}


228
void InfoContextManagerItem::updateOneFileInfo() {
229
230
231
232
	if (!d->mDocument) {
		return;
	}

233
	QStringList list;
234
	d->mKeyValueWidget->clear();
235
	ImageMetaInfoModel* metaInfoModel = d->mDocument->metaInfo();
236
	Q_FOREACH(const QString& key, GwenviewConfig::preferredMetaInfoKeyList()) {
237
		QString label;
238
		QString value;
239
		metaInfoModel->getInfoForKey(key, &label, &value);
240

241
		if (!label.isEmpty() && !value.isEmpty()) {
242
			d->mKeyValueWidget->addRow(label, value);
243
244
		}
	}
245

246
	d->mKeyValueWidget->show();
247
248
249
}


250
251
252
253
void InfoContextManagerItem::showMetaInfoDialog() {
	if (!d->mImageMetaInfoDialog) {
		d->mImageMetaInfoDialog = new ImageMetaInfoDialog(d->mOneFileWidget);
		d->mImageMetaInfoDialog->setAttribute(Qt::WA_DeleteOnClose, true);
254
255
		connect(d->mImageMetaInfoDialog, SIGNAL(preferredMetaInfoKeyListChanged(const QStringList&)),
			SLOT(slotPreferredMetaInfoKeyListChanged(const QStringList&)) );
256
	}
257
	d->mImageMetaInfoDialog->setMetaInfo(d->mDocument->metaInfo(), GwenviewConfig::preferredMetaInfoKeyList());
258
259
260
261
	d->mImageMetaInfoDialog->show();
}


262
263
264
265
266
267
268
void InfoContextManagerItem::slotPreferredMetaInfoKeyListChanged(const QStringList& list) {
	GwenviewConfig::setPreferredMetaInfoKeyList(list);
	GwenviewConfig::self()->writeConfig();
	updateOneFileInfo();
}


269
} // namespace