1 /*
2  *  Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 or (at your option)
7  *  version 3 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "EditWidgetIcons.h"
19 #include "ui_EditWidgetIcons.h"
20 
21 #include <QFileDialog>
22 #include <QImageReader>
23 
24 #include "core/Group.h"
25 #include "core/Metadata.h"
26 #include "core/Tools.h"
27 #include "gui/IconModels.h"
28 #include "gui/MessageBox.h"
29 
IconStruct()30 IconStruct::IconStruct()
31     : uuid(Uuid())
32     , number(0)
33 {
34 }
35 
EditWidgetIcons(QWidget * parent)36 EditWidgetIcons::EditWidgetIcons(QWidget* parent)
37     : QWidget(parent)
38     , m_ui(new Ui::EditWidgetIcons())
39     , m_database(nullptr)
40     , m_defaultIconModel(new DefaultIconModel(this))
41     , m_customIconModel(new CustomIconModel(this))
42 {
43     m_ui->setupUi(this);
44 
45     m_ui->defaultIconsView->setModel(m_defaultIconModel);
46     m_ui->customIconsView->setModel(m_customIconModel);
47 
48     connect(m_ui->defaultIconsView, SIGNAL(clicked(QModelIndex)),
49             this, SLOT(updateRadioButtonDefaultIcons()));
50     connect(m_ui->customIconsView, SIGNAL(clicked(QModelIndex)),
51             this, SLOT(updateRadioButtonCustomIcons()));
52     connect(m_ui->defaultIconsRadio, SIGNAL(toggled(bool)),
53             this, SLOT(updateWidgetsDefaultIcons(bool)));
54     connect(m_ui->customIconsRadio, SIGNAL(toggled(bool)),
55             this, SLOT(updateWidgetsCustomIcons(bool)));
56     connect(m_ui->addButton, SIGNAL(clicked()), SLOT(addCustomIcon()));
57     connect(m_ui->deleteButton, SIGNAL(clicked()), SLOT(removeCustomIcon()));
58 }
59 
~EditWidgetIcons()60 EditWidgetIcons::~EditWidgetIcons()
61 {
62 }
63 
state() const64 IconStruct EditWidgetIcons::state() const
65 {
66     IconStruct iconStruct;
67     if (m_ui->defaultIconsRadio->isChecked()) {
68         QModelIndex index = m_ui->defaultIconsView->currentIndex();
69         if (index.isValid()) {
70             iconStruct.number = index.row();
71         }
72         else {
73             Q_ASSERT(false);
74         }
75     }
76     else {
77         QModelIndex index = m_ui->customIconsView->currentIndex();
78         if (index.isValid()) {
79             iconStruct.uuid = m_customIconModel->uuidFromIndex(m_ui->customIconsView->currentIndex());
80         }
81         else {
82             iconStruct.number = -1;
83         }
84     }
85 
86     return iconStruct;
87 }
88 
reset()89 void EditWidgetIcons::reset()
90 {
91     m_database = nullptr;
92     m_currentUuid = Uuid();
93 }
94 
load(Uuid currentUuid,Database * database,IconStruct iconStruct)95 void EditWidgetIcons::load(Uuid currentUuid, Database* database, IconStruct iconStruct)
96 {
97     Q_ASSERT(database);
98     Q_ASSERT(!currentUuid.isNull());
99 
100     m_database = database;
101     m_currentUuid = currentUuid;
102 
103     m_customIconModel->setIcons(database->metadata()->customIconsScaledPixmaps(),
104                                 database->metadata()->customIconsOrder());
105 
106     Uuid iconUuid = iconStruct.uuid;
107     if (iconUuid.isNull()) {
108         int iconNumber = iconStruct.number;
109         m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(iconNumber, 0));
110         m_ui->defaultIconsRadio->setChecked(true);
111     }
112     else {
113         QModelIndex index = m_customIconModel->indexFromUuid(iconUuid);
114         if (index.isValid()) {
115             m_ui->customIconsView->setCurrentIndex(index);
116             m_ui->customIconsRadio->setChecked(true);
117         }
118         else {
119             m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(0, 0));
120             m_ui->defaultIconsRadio->setChecked(true);
121         }
122     }
123 }
124 
addCustomIcon()125 void EditWidgetIcons::addCustomIcon()
126 {
127     if (m_database) {
128         QString filter = QString("%1 (%2);;%3 (*)").arg(tr("Images"),
129                     Tools::imageReaderFilter(), tr("All files"));
130 
131         QString filename = QFileDialog::getOpenFileName(
132                     this, tr("Select Image"), "", filter);
133         if (!filename.isEmpty()) {
134             QImageReader imageReader(filename);
135             // detect from content, otherwise reading fails if file extension is wrong
136             imageReader.setDecideFormatFromContent(true);
137             QImage image = imageReader.read();
138             if (!image.isNull()) {
139                 Uuid uuid = Uuid::random();
140                 m_database->metadata()->addCustomIconScaled(uuid, image);
141                 m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
142                                             m_database->metadata()->customIconsOrder());
143                 QModelIndex index = m_customIconModel->indexFromUuid(uuid);
144                 m_ui->customIconsView->setCurrentIndex(index);
145             }
146             else {
147                 MessageBox::critical(this, tr("Error"),
148                                      tr("Can't read icon:").append("\n").append(imageReader.errorString()));
149             }
150         }
151     }
152 }
153 
removeCustomIcon()154 void EditWidgetIcons::removeCustomIcon()
155 {
156     if (m_database) {
157         QModelIndex index = m_ui->customIconsView->currentIndex();
158         if (index.isValid()) {
159             Uuid iconUuid = m_customIconModel->uuidFromIndex(index);
160             int iconUsedCount = 0;
161 
162             const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true);
163             QList<Entry*> historyEntriesWithSameIcon;
164 
165             for (Entry* entry : allEntries) {
166                 bool isHistoryEntry = !entry->group();
167                 if (iconUuid == entry->iconUuid()) {
168                     if (isHistoryEntry) {
169                         historyEntriesWithSameIcon << entry;
170                     }
171                     else if (m_currentUuid != entry->uuid()) {
172                         iconUsedCount++;
173                     }
174                 }
175             }
176 
177             const QList<Group*> allGroups = m_database->rootGroup()->groupsRecursive(true);
178             for (const Group* group : allGroups) {
179                 if (iconUuid == group->iconUuid() && m_currentUuid != group->uuid()) {
180                     iconUsedCount++;
181                 }
182             }
183 
184             if (iconUsedCount == 0) {
185                 for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
186                     entry->setUpdateTimeinfo(false);
187                     entry->setIcon(0);
188                     entry->setUpdateTimeinfo(true);
189                 }
190 
191                 m_database->metadata()->removeCustomIcon(iconUuid);
192                 m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
193                                             m_database->metadata()->customIconsOrder());
194                 if (m_customIconModel->rowCount() > 0) {
195                     m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0));
196                 }
197                 else {
198                     updateRadioButtonDefaultIcons();
199                 }
200             }
201             else {
202                 MessageBox::information(this, tr("Can't delete icon!"),
203                                         tr("Can't delete icon. Still used by %n item(s).", 0, iconUsedCount));
204             }
205         }
206     }
207 }
208 
updateWidgetsDefaultIcons(bool check)209 void EditWidgetIcons::updateWidgetsDefaultIcons(bool check)
210 {
211     if (check) {
212         QModelIndex index = m_ui->defaultIconsView->currentIndex();
213         if (!index.isValid()) {
214             m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(0, 0));
215         }
216         else {
217             m_ui->defaultIconsView->setCurrentIndex(index);
218         }
219         m_ui->customIconsView->selectionModel()->clearSelection();
220         m_ui->addButton->setEnabled(false);
221         m_ui->deleteButton->setEnabled(false);
222     }
223 }
224 
updateWidgetsCustomIcons(bool check)225 void EditWidgetIcons::updateWidgetsCustomIcons(bool check)
226 {
227     if (check) {
228         QModelIndex index = m_ui->customIconsView->currentIndex();
229         if (!index.isValid()) {
230             m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0));
231         }
232         else {
233             m_ui->customIconsView->setCurrentIndex(index);
234         }
235         m_ui->defaultIconsView->selectionModel()->clearSelection();
236         m_ui->addButton->setEnabled(true);
237         m_ui->deleteButton->setEnabled(true);
238     }
239 }
240 
updateRadioButtonDefaultIcons()241 void EditWidgetIcons::updateRadioButtonDefaultIcons()
242 {
243     m_ui->defaultIconsRadio->setChecked(true);
244 }
245 
updateRadioButtonCustomIcons()246 void EditWidgetIcons::updateRadioButtonCustomIcons()
247 {
248     m_ui->customIconsRadio->setChecked(true);
249 }
250