1 /* -*- c++ -*- */
2 /*
3  * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
4  *           https://gqrx.dk/
5  *
6  * Copyright 2014 Stefano Leucci, Christian Lindner DL2VCL.
7  *
8  * Gqrx is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3, or (at your option)
11  * any later version.
12  *
13  * Gqrx is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Gqrx; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street,
21  * Boston, MA 02110-1301, USA.
22  */
23 #include "bookmarkstaglist.h"
24 #include "bookmarks.h"
25 #include <QColorDialog>
26 #include <stdio.h>
27 #include <QMenu>
28 #include <QHeaderView>
29 
BookmarksTagList(QWidget * parent,bool bShowUntagged)30 BookmarksTagList::BookmarksTagList(QWidget *parent, bool bShowUntagged )
31     : QTableWidget(parent)
32     , m_bUpdating(false)
33     , m_bShowUntagged(bShowUntagged)
34 {
35     connect(this, SIGNAL(cellClicked(int,int)),
36             this, SLOT(on_cellClicked(int,int)));
37 
38     // right click menu
39     setContextMenuPolicy(Qt::CustomContextMenu);
40     connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
41             this, SLOT(ShowContextMenu(const QPoint&)));
42 
43     horizontalHeader()->setVisible(false);
44     verticalHeader()->setVisible(false);
45     setColumnCount(2);
46     setColumnWidth(0, 20);
47     horizontalHeader()->setStretchLastSection(true);
48     setSelectionMode(QAbstractItemView::SingleSelection);
49     setSelectionBehavior(QAbstractItemView::SelectRows);
50     setSortingEnabled(true);
51 }
52 
on_cellClicked(int row,int column)53 void BookmarksTagList::on_cellClicked(int row, int column)
54 {
55     if(column==0)
56     {
57         changeColor(row, column);
58     }
59     if(column==1)
60     {
61         toggleCheckedState(row, column);
62     }
63 }
64 
changeColor(int row,int)65 void BookmarksTagList::changeColor(int row, int /*column*/)
66 {
67     TagInfo &info = Bookmarks::Get().findOrAddTag(item(row, 1)->text());
68     QColor color = QColorDialog::getColor(info.color, this);
69 
70     if(!color.isValid())
71         return;
72 
73     info.color=color;
74     updateTags();
75     Bookmarks::Get().save();
76 }
77 
toggleCheckedState(int row,int column)78 void BookmarksTagList::toggleCheckedState(int row, int column)
79 {
80     QTableWidgetItem* p = item(row,column);
81     if(p->checkState()==Qt::Unchecked)
82     {
83         p->setCheckState(Qt::Checked);
84     }
85     else
86     {
87         p->setCheckState(Qt::Unchecked);
88     }
89 }
90 
updateTags()91 void BookmarksTagList::updateTags()
92 {
93     m_bUpdating = true;
94 
95     // Remember which items were unchecked.
96     QStringList unchecked;
97     for(int i=0; i<rowCount(); i++)
98     {
99         if(item(i,1)->checkState()==Qt::Unchecked)
100             unchecked.append(item(i,1)->text());
101     }
102 
103     // Get current List of Tags.
104     QList<TagInfo> newTags = Bookmarks::Get().getTagList();
105     if(!m_bShowUntagged)
106     {
107         for(int i=0; i<newTags.size(); ++i)
108         {
109             TagInfo& taginfo = newTags[i];
110             if(taginfo.name.compare(TagInfo::strUntagged)==0)
111             {
112                 newTags.removeAt(i);
113                 break;
114             }
115         }
116     }
117 
118     // Rebuild List in GUI.
119     clear();
120     setSortingEnabled(false);
121     setRowCount(0);
122     for(int i=0; i<newTags.count(); i++)
123     {
124         AddTag(newTags[i].name,
125                   ( unchecked.contains(newTags[i].name) ? Qt::Unchecked : Qt::Checked ),
126                   newTags[i].color);
127     }
128     setSortingEnabled(true);
129 
130     m_bUpdating = false;
131 }
132 
setSelectedTagsAsString(const QString & strTags)133 void BookmarksTagList::setSelectedTagsAsString(const QString& strTags)
134 {
135     QStringList list = strTags.split(",");
136     int iRows = rowCount();
137     for(int i=0; i<iRows; ++i)
138     {
139         QTableWidgetItem* pItem = item(i,1);
140         QString name = pItem->text();
141         bool bChecked = list.contains(name);
142         pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
143     }
144     setSortingEnabled(true);
145 }
146 
setSelectedTags(QList<TagInfo * > tags)147 void BookmarksTagList::setSelectedTags(QList<TagInfo*> tags)
148 {
149     int iRows = rowCount();
150     for(int i=0; i<iRows; ++i)
151     {
152         QTableWidgetItem* pItem = item(i,1);
153         QString name = pItem->text();
154         bool bChecked = false;
155         for(QList<TagInfo*>::const_iterator it=tags.begin(), itend=tags.end(); it!=itend; ++it)
156         {
157             TagInfo* pTag = *it;
158             if(pTag->name == name) bChecked = true;
159         }
160         pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
161     }
162     setSortingEnabled(true);
163 }
164 
getSelectedTagsAsString()165 QString BookmarksTagList::getSelectedTagsAsString()
166 {
167     QString strResult;
168 
169     int iRows = rowCount();
170     bool bFirst = true;
171     for(int i=0; i<iRows; ++i)
172     {
173         QTableWidgetItem* pItem = item(i,1);
174         if(pItem->checkState() == Qt::Checked)
175         {
176             if(!bFirst) strResult += ", ";
177             strResult += pItem->text();
178             bFirst = false;
179         }
180     }
181     return strResult;
182 }
183 
ShowContextMenu(const QPoint & pos)184 void BookmarksTagList::ShowContextMenu(const QPoint& pos)
185 {
186     QMenu* menu=new QMenu(this);
187 
188     // Rename currently does not work.
189     // The problem is that after the tag name is changed in GUI
190     // you can not find the right TagInfo because you dont know
191     // the old tag name.
192     #if 0
193     // MenuItem "Rename"
194     {
195         QAction* actionRename = new QAction("Rename", this);
196         menu->addAction(actionRename);
197         connect(actionRename, SIGNAL(triggered()), this, SLOT(RenameSelectedTag()));
198     }
199     #endif
200 
201     // MenuItem "Create new Tag"
202     {
203         QAction* actionNewTag = new QAction("Create new Tag", this);
204         menu->addAction(actionNewTag);
205         connect(actionNewTag, SIGNAL(triggered()), this, SLOT(AddNewTag()));
206     }
207 
208     // Menu "Delete Tag"
209     {
210         QAction* actionDeleteTag = new QAction("Delete Tag", this);
211         menu->addAction(actionDeleteTag);
212         connect(actionDeleteTag, SIGNAL(triggered()), this, SLOT(DeleteSelectedTag()));
213     }
214 
215     // Menu "Select All"
216     {
217         QAction* action = new QAction("Select All", this);
218         menu->addAction(action);
219         connect(action, SIGNAL(triggered()), this, SLOT(SelectAll()));
220     }
221 
222     // Menu "Deselect All"
223     {
224         QAction* action = new QAction("Deselect All", this);
225         menu->addAction(action);
226         connect(action, SIGNAL(triggered()), this, SLOT(DeselectAll()));
227     }
228 
229     menu->popup(viewport()->mapToGlobal(pos));
230 }
231 
232 #if 0
233 bool BookmarksTagList::RenameSelectedTag()
234 {
235     QModelIndexList selected = selectionModel()->selectedRows();
236 
237     if(selected.empty())
238     {
239         return true;
240     }
241 
242     int iRow = selected.first().row();
243     QTableWidgetItem* pItem = item(iRow,1);bUpdating
244     editItem(pItem);
245     //Bookmarks::Get().save();
246 
247     return true;
248 }
249 #endif
250 
AddNewTag()251 void BookmarksTagList::AddNewTag()
252 {
253     AddTag("*new*");
254     scrollToBottom();
255     editItem(item(rowCount()-1, 1));
256 }
257 
AddTag(QString name,Qt::CheckState checkstate,QColor color)258 void BookmarksTagList::AddTag(QString name, Qt::CheckState checkstate, QColor color)
259 {
260     int i = rowCount();
261     setRowCount(i+1);
262 
263     // Column 1
264     QTableWidgetItem *item = new QTableWidgetItem(name);
265     item->setCheckState(checkstate);
266     item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
267     setItem(i, 1, item);
268 
269     // Column 0
270     item = new QTableWidgetItem();
271     item->setFlags(Qt::ItemIsEnabled);
272     item->setBackground(QBrush(color));
273     setItem(i, 0, item);
274 }
275 
DeleteSelectedTag()276 void BookmarksTagList::DeleteSelectedTag()
277 {
278     QModelIndexList selected = selectionModel()->selectedRows();
279     if(selected.empty())
280     {
281         return;
282     }
283     int iRow = selected.first().row();
284     QTableWidgetItem* pItem = item(iRow,1);
285     QString strTagName = pItem->text();
286     DeleteTag(strTagName);
287     return;
288 }
289 
DeleteTag(const QString & name)290 void BookmarksTagList::DeleteTag(const QString& name)
291 {
292     Bookmarks::Get().removeTag(name);
293     updateTags();
294 }
295 
SelectAll()296 void BookmarksTagList::SelectAll()
297 {
298     int iRows = rowCount();
299     for(int i=0; i<iRows; ++i)
300     {
301         QTableWidgetItem* pItem = item(i,1);
302         QString name = pItem->text();
303         pItem->setCheckState(Qt::Checked);
304     }
305 }
306 
DeselectAll()307 void BookmarksTagList::DeselectAll()
308 {
309     int iRows = rowCount();
310     for(int i=0; i<iRows; ++i)
311     {
312         QTableWidgetItem* pItem = item(i,1);
313         QString name = pItem->text();
314         pItem->setCheckState(Qt::Unchecked);
315     }
316 }
317