1 /***************************************************************************
2 *                                                                         *
3 *   This program is free software; you can redistribute it and/or modify  *
4 *   it under the terms of the GNU General Public License as published by  *
5 *   the Free Software Foundation; either version 3 of the License, or     *
6 *   (at your option) any later version.                                   *
7 *                                                                         *
8 ***************************************************************************/
9 
10 #include "ADLS.h"
11 #include "ADLSModel.h"
12 #include "WulforUtil.h"
13 #include "WulforSettings.h"
14 #include "dcpp/stdinc.h"
15 #include "dcpp/ADLSearch.h"
16 
17 #include <QTreeView>
18 #include <QHeaderView>
19 #include <QItemSelectionModel>
20 #include <QList>
21 #include <QtDebug>
22 
23 using namespace dcpp;
24 
ADLS(QWidget * parent)25 ADLS::ADLS(QWidget *parent):
26         QWidget(parent),
27         model(NULL)
28 {
29     setupUi(this);
30 
31     init();
32 
33     ArenaWidget::setState( ArenaWidget::Flags(ArenaWidget::state() | ArenaWidget::Singleton | ArenaWidget::Hidden) );
34 }
35 
~ADLS()36 ADLS::~ADLS(){
37     save();
38 
39     ADLSearchManager::getInstance()->Save();
40 
41     delete model;
42 }
43 
closeEvent(QCloseEvent * e)44 void ADLS::closeEvent(QCloseEvent *e){
45     isUnload()? e->accept() : e->ignore();
46 }
47 
getWidget()48 QWidget *ADLS::getWidget(){
49     return this;
50 }
51 
getArenaTitle()52 QString ADLS::getArenaTitle(){
53     return tr("ADLSearch");
54 }
55 
getArenaShortTitle()56 QString ADLS::getArenaShortTitle(){
57     return getArenaTitle();
58 }
59 
getMenu()60 QMenu *ADLS::getMenu(){
61     return NULL;
62 }
63 
load()64 void ADLS::load(){
65     treeView->header()->restoreState(WVGET(WS_ADLS_STATE, QByteArray()).toByteArray());
66 }
67 
save()68 void ADLS::save(){
69     WVSET(WS_ADLS_STATE, treeView->header()->saveState());
70 }
71 
init()72 void ADLS::init(){
73     model = new ADLSModel();
74     setUnload(false);
75 
76     treeView->setModel(model);
77 
78     ADLSearchManager::SearchCollection& collection = ADLSearchManager::getInstance()->collection;
79 
80     for (auto i = collection.begin(); i != collection.end(); ++i) {
81         ADLSearch &search = *i;
82         addItem(search);
83     }
84 
85     treeView->setRootIsDecorated(false);
86     treeView->setContextMenuPolicy(Qt::CustomContextMenu);
87     treeView->header()->setContextMenuPolicy(Qt::CustomContextMenu);
88     treeView->viewport()->setAcceptDrops(false); // temporary
89     treeView->setDragEnabled(false); // temporary
90     treeView->setAcceptDrops(false); // temporary
91     //treeView->setDragDropMode(QAbstractItemView::InternalMove);
92 
93     WulforUtil *WU = WulforUtil::getInstance();
94 
95     add_newButton->setIcon(WU->getPixmap(WulforUtil::eiBOOKMARK_ADD));
96     changeButton->setIcon(WU->getPixmap(WulforUtil::eiEDIT));
97     removeButton->setIcon(WU->getPixmap(WulforUtil::eiEDITDELETE));
98     upButton->setIcon(WU->getPixmap(WulforUtil::eiUP));
99     downButton->setIcon(WU->getPixmap(WulforUtil::eiDOWN));
100     line_2->hide();
101     upButton->hide();
102     downButton->hide();
103     load();
104 
105     int row_num = model->rowCount();
106     if (!row_num){
107         changeButton->setEnabled(false);
108         removeButton->setEnabled(false);
109         upButton->setEnabled(false);
110         downButton->setEnabled(false);
111     }
112     else if(row_num == 1){
113         upButton->setEnabled(false);
114         downButton->setEnabled(false);
115     }
116 
117     connect(treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotContexMenu(const QPoint&)));
118     connect(treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotClicked(QModelIndex)));
119     connect(treeView->header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotHeaderMenu()));
120     connect(treeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotDblClicked()));
121 
122     connect(WulforSettings::getInstance(), SIGNAL(strValueChanged(QString,QString)), this, SLOT(slotSettingsChanged(QString,QString)));
123 
124     connect(add_newButton, SIGNAL(clicked()), this, SLOT(slotAdd_newButtonClicked()));
125     connect(changeButton,  SIGNAL(clicked()), this, SLOT(slotChangeButtonClicked()));
126     connect(removeButton,  SIGNAL(clicked()), this, SLOT(slotRemoveButtonClicked()));
127     connect(upButton,      SIGNAL(clicked()), this, SLOT(slotUpButtonClicked()));
128     connect(downButton,    SIGNAL(clicked()), this, SLOT(slotDownButtonClicked()));
129 }
130 
slotContexMenu(const QPoint &)131 void ADLS::slotContexMenu(const QPoint &){
132     QItemSelectionModel *s_model = treeView->selectionModel();
133     QModelIndexList list = s_model->selectedRows(0);
134     WulforUtil *WU = WulforUtil::getInstance();
135     bool empty = list.empty();
136     QMenu *menu = new QMenu(this);
137 
138     if (empty){
139         QAction *add_new = new QAction(WU->getPixmap(WulforUtil::eiBOOKMARK_ADD), tr("Add new"), menu);
140         menu->addAction(add_new);
141 
142         QAction *res = menu->exec(QCursor::pos());
143 
144         if (res){
145             slotAdd_newButtonClicked();
146             }
147     } else {
148         ADLSItem *item = static_cast<ADLSItem*>(list.at(0).internalPointer());
149 
150         if (!item){
151             delete menu;
152 
153             return;
154         }
155 
156         QAction *add_new = new QAction(WU->getPixmap(WulforUtil::eiBOOKMARK_ADD), tr("Add new"), menu);
157         QAction *change  = new QAction(WU->getPixmap(WulforUtil::eiEDIT), tr("Change"), menu);
158         QAction *remove  = new QAction(WU->getPixmap(WulforUtil::eiEDITDELETE), tr("Delete"), menu);
159         QAction *sep1    = new QAction(menu);
160         sep1->setSeparator(true);
161 
162         menu->addActions(QList<QAction*>() << change
163                                            << remove
164                                            << sep1
165                                            << add_new);
166 
167         QAction *res = menu->exec(QCursor::pos());
168 
169         if (res == change)
170             slotChangeButtonClicked();
171         else if (res == remove)
172             slotRemoveButtonClicked();
173         else if (res == add_new)
174             slotAdd_newButtonClicked();
175     }
176 
177     delete menu;
178 }
179 
slotDblClicked()180 void ADLS::slotDblClicked(){
181     slotChangeButtonClicked();
182 }
183 
slotHeaderMenu()184 void ADLS::slotHeaderMenu(){
185     WulforUtil::headerMenu(treeView);
186 }
187 
slotClicked(const QModelIndex & index)188 void ADLS::slotClicked(const QModelIndex &index){
189     if (!index.isValid() || index.column() != COLUMN_CHECK || !index.internalPointer())
190         return;
191 
192     ADLSItem *item = reinterpret_cast<ADLSItem*>(index.internalPointer());
193     ADLSearchManager::SearchCollection &collection = ADLSearchManager::getInstance()->collection;
194     StrMap mapcheck;
195     mapcheck["SSTRING"] = item->data(COLUMN_SSTRING).toString();
196     mapcheck["DIRECTORY"] = item->data(COLUMN_DIRECTORY).toString();
197     VectorSize i = findEntry(mapcheck);
198     ADLSearch entry = collection[i];
199 
200         bool check = !item->data(COLUMN_CHECK).toBool();
201 
202         entry.isActive = check;
203         item->updateColumn(COLUMN_CHECK, check);
204         if (i < collection.size())
205             collection[i] = entry;
206         model->repaint();
207 
208         ADLSearchManager::getInstance()->Save();
209 }
210 
initEditor(ADLSEditor & editor)211 void ADLS::initEditor(ADLSEditor &editor){
212 
213 }
slotAdd_newButtonClicked()214 void ADLS::slotAdd_newButtonClicked(){
215     ADLSEditor editor;
216     ADLSearchManager::SearchCollection &collection = ADLSearchManager::getInstance()->collection;
217     ADLSearch search;
218 
219     initEditor(editor);
220 
221     if (editor.exec() == QDialog::Accepted){
222         StrMap map;
223 
224         getParams(editor, map);
225         updateEntry(search, map);
226         collection.push_back(search);
227         ADLSearchManager::getInstance()->Save();
228         addItem(search);
229     }
230 }
231 
slotChangeButtonClicked()232 void ADLS::slotChangeButtonClicked(){
233     ADLSItem *item = getItem();
234 
235     if (!item)
236         return;
237 
238     StrMap mapcheck;
239     mapcheck["SSTRING"] = item->data(COLUMN_SSTRING).toString();
240     mapcheck["DIRECTORY"] = item->data(COLUMN_DIRECTORY).toString();
241     VectorSize i = findEntry(mapcheck);
242     ADLSEditor editor;
243     ADLSearchManager::SearchCollection &collection = ADLSearchManager::getInstance()->collection;
244     ADLSearch search = collection[i];
245 
246         StrMap map;
247 
248         getParams(search, map);
249         initEditor(editor, map);
250 
251         if (editor.exec() == QDialog::Accepted){
252             getParams(editor, map);
253             updateItem(item, map);
254             updateEntry(search, map);
255             if (i < collection.size())
256                 collection[i] = search;
257 
258         }
259 
260 }
261 
slotRemoveButtonClicked()262 void ADLS::slotRemoveButtonClicked(){
263     ADLSItem *item = getItem();
264 
265     if (!item)
266         return;
267     StrMap mapcheck;
268     mapcheck["SSTRING"] = item->data(COLUMN_SSTRING).toString();
269     mapcheck["DIRECTORY"] = item->data(COLUMN_DIRECTORY).toString();
270     VectorSize i = findEntry(mapcheck);
271     ADLSearchManager::SearchCollection &collection = ADLSearchManager::getInstance()->collection;
272         if (i < collection.size()) {
273             collection.erase(collection.begin() + i);
274             model->removeItem(item);
275         }
276 }
277 
slotUpButtonClicked()278 void ADLS::slotUpButtonClicked(){
279     QItemSelectionModel *s_model = treeView->selectionModel();
280     QModelIndexList list = s_model->selectedRows(0);
281 
282     for (const auto &i : list)
283         s_model->select(model->moveUp(i), QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
284 }
285 
slotDownButtonClicked()286 void ADLS::slotDownButtonClicked(){
287     QItemSelectionModel *s_model = treeView->selectionModel();
288     QModelIndexList list = s_model->selectedRows(0);
289 
290     for (const auto &i : list)
291          s_model->select(model->moveDown(i), QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
292 }
293 
getItem()294 ADLSItem *ADLS::getItem(){
295     QItemSelectionModel *s_model = treeView->selectionModel();
296     QModelIndexList list = s_model->selectedRows(0);
297 
298     ADLSItem *item = NULL;
299     if (!list.isEmpty())
300         item = static_cast<ADLSItem*>(list.first().internalPointer());
301 
302     return item;
303 }
304 
updateItem(ADLSItem * item,StrMap & map)305 void ADLS::updateItem(ADLSItem *item, StrMap &map) {
306     if (!item)
307         return;
308 
309     item->updateColumn(COLUMN_CHECK, map["CHECK"]);
310     item->updateColumn(COLUMN_SSTRING, map["SSTRING"]);
311     item->updateColumn(COLUMN_DIRECTORY, map["DIRECTORY"]);
312     item->updateColumn(COLUMN_MINSIZE, map["MINSIZE"]);
313     item->updateColumn(COLUMN_MAXSIZE, map["MAXSIZE"]);
314     item->updateColumn(COLUMN_TYPESIZE, SizeTypeToString((ADLSearch::SizeType)map["TYPESIZE"].toInt()));
315     item->updateColumn(COLUMN_TYPE, SourceTypeToString((ADLSearch::SourceType)map["SOURCETYPE"].toInt()));
316 }
317 
updateEntry(ADLSearch & entry,StrMap & map)318 void ADLS::updateEntry(ADLSearch &entry, StrMap &map){
319     entry.isActive = (int)map["CHECK"].toBool();
320     entry.searchString = map["SSTRING"].toString().toStdString();
321     entry.destDir = map["DIRECTORY"].toString().toStdString();
322     entry.isAutoQueue = (int)map["AUTOQUEUE"].toBool();
323     entry.sourceType = (ADLSearch::SourceType)map["SOURCETYPE"].toInt();
324     entry.minFileSize = map["MINSIZE"].toLongLong();
325     entry.maxFileSize = map["MAXSIZE"].toLongLong();
326     entry.typeFileSize = (ADLSearch::SizeType)map["TYPESIZE"].toInt();
327 
328 }
getParams(const ADLSEditor & editor,StrMap & map)329 void ADLS::getParams(const ADLSEditor &editor, StrMap &map){
330     map["SSTRING"]      = editor.lineEdit_SSTRING->text();
331     map["DIRECTORY"]    = editor.lineEdit_DIRECTORY->text();
332     map["AUTOQUEUE"]    = editor.checkBox_DOWNLOAD->isChecked();
333     map["CHECK"]        = editor.checkBox_CHECK->isChecked();
334     map["SOURCETYPE"]   = editor.comboBox_TYPE->currentIndex();
335     map["TYPESIZE"]     = editor.comboBox_TYPESIZE->currentIndex();
336     map["MINSIZE"]      = editor.spinBox_MINSIZE->value();
337     map["MAXSIZE"]      = editor.spinBox_MAXSIZE->value();
338 
339 }
initEditor(ADLSEditor & editor,StrMap & map)340 void ADLS::initEditor(ADLSEditor &editor, StrMap &map){
341     initEditor(editor);
342 
343     editor.checkBox_CHECK->setChecked(map["CHECK"].toBool());
344     editor.checkBox_DOWNLOAD->setChecked(map["AUTOQUEUE"].toBool());
345     editor.lineEdit_SSTRING->setText(map["SSTRING"].toString());
346     editor.lineEdit_DIRECTORY->setText(map["DIRECTORY"].toString());
347     editor.spinBox_MINSIZE->setValue(map["MINSIZE"].toLongLong());
348     editor.spinBox_MAXSIZE->setValue(map["MAXSIZE"].toLongLong());
349     editor.comboBox_TYPESIZE->setCurrentIndex(map["TYPESIZE"].toInt());
350     editor.comboBox_TYPE->setCurrentIndex(map["SOURCETYPE"].toInt());
351 }
getParams(ADLSearch & entry,StrMap & map)352 void ADLS::getParams(/*const*/ ADLSearch &entry, StrMap &map){
353 
354     map["SSTRING"]     = _q(entry.searchString);
355     map["DIRECTORY"]   = _q(entry.destDir);
356     map["CHECK"]       = entry.isActive;
357     map["AUTOQUEUE"]   = entry.isAutoQueue;
358     map["MINSIZE"]     = (qlonglong)entry.minFileSize;
359     map["MAXSIZE"]     = (qlonglong)entry.maxFileSize;
360     map["SOURCETYPE"]  = entry.sourceType;
361     map["TYPESIZE"]    = entry.typeFileSize;
362 
363 }
addItem(ADLSearch & search)364 void ADLS::addItem(ADLSearch &search){
365         QList<QVariant> data;
366 
367         data << search.isActive
368              << _q(search.searchString)
369              << SourceTypeToString(search.sourceType)
370              << _q(search.destDir)
371              << (qlonglong)search.minFileSize
372              << (qlonglong)search.maxFileSize
373              << SizeTypeToString(search.typeFileSize);
374 
375 
376         model->addResult(data);
377 }
SourceTypeToString(ADLSearch::SourceType t)378 QString ADLS::SourceTypeToString(ADLSearch::SourceType t){
379     switch(t) {
380         default:
381         case ADLSearch::OnlyFile:      return tr("Filename");
382         case ADLSearch::OnlyDirectory: return tr("Directory");
383         case ADLSearch::FullPath:      return tr("Full Path");
384     }
385 }
SizeTypeToString(ADLSearch::SizeType t)386 QString ADLS::SizeTypeToString(ADLSearch::SizeType t){
387     switch(t) {
388         default:
389         case ADLSearch::SizeBytes:     return tr("B");
390         case ADLSearch::SizeKibiBytes: return tr("KiB");
391         case ADLSearch::SizeMebiBytes: return tr("MiB");
392         case ADLSearch::SizeGibiBytes: return tr("GiB");
393     }
394 }
395 
slotSettingsChanged(const QString & key,const QString & value)396 void ADLS::slotSettingsChanged(const QString &key, const QString &value){
397     if (key == WS_TRANSLATION_FILE)
398         retranslateUi(this);
399 }
400 
findEntry(StrMap & map)401 /*ADLS::VectorSize*/int ADLS::findEntry(StrMap &map){
402     ADLSearchManager::SearchCollection& collection = ADLSearchManager::getInstance()->collection;int j=0;
403     for (auto i = collection.begin(); i != collection.end(); ++i,++j) {
404         ADLSearch &search = *i;
405         if (_q(search.searchString) == map["SSTRING"] &&
406             _q(search.destDir) == map["DIRECTORY"])
407             return j;
408     }
409 
410     return -1;
411 }
412