LeechCraft  %{LEECHCRAFT_VERSION}
Modular cross-platform feature rich live environment.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
categoryselector.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2013 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #include "categoryselector.h"
31 #include <algorithm>
32 #include <QStringList>
33 #include <QCheckBox>
34 #include <QVariant>
35 #include <QVBoxLayout>
36 #include <QMoveEvent>
37 #include <QApplication>
38 #include <QDesktopWidget>
39 #include <QAction>
40 #include <QtDebug>
41 
42 using namespace LeechCraft::Util;
43 const int RoleTag = 52;
44 
46 : QTreeWidget (parent)
47 , Separator_ ("; ")
48 {
49  setWindowTitle (tr ("Tags selector"));
50  setWindowFlags (Qt::Tool | Qt::WindowStaysOnTopHint);
51  setRootIsDecorated (false);
52  setUniformRowHeights (true);
53 
54  QRect avail = QApplication::desktop ()->availableGeometry (this);
55  setMinimumHeight (avail.height () / 3 * 2);
56 
57  connect (this,
58  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
59  this,
60  SLOT (buttonToggled ()));
61 
62  QAction *all = new QAction (tr ("Select all"), this);
63  connect (all,
64  SIGNAL (triggered ()),
65  this,
66  SLOT (selectAll ()));
67 
68  QAction *none = new QAction (tr ("Select none"), this);
69  connect (none,
70  SIGNAL (triggered ()),
71  this,
72  SLOT (selectNone ()));
73 
74  addAction (all);
75  addAction (none);
76 
77  setContextMenuPolicy (Qt::ActionsContextMenu);
78 }
79 
80 void CategorySelector::SetCaption (const QString& caption)
81 {
82  setHeaderLabel (caption);
83  Caption_ = caption;
84 }
85 
86 void CategorySelector::setPossibleSelections (QStringList mytags)
87 {
88  disconnect (this,
89  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
90  this,
91  SLOT (buttonToggled ()));
92 
93  clear ();
94 
95  mytags.sort ();
96  QList<QTreeWidgetItem*> items;
97  for (auto i = mytags.begin (), end = mytags.end (); i != end; ++i)
98  {
99  if (i->isEmpty ())
100  continue;
101 
102  auto item = new QTreeWidgetItem (QStringList (*i));
103  item->setCheckState (0, Qt::Unchecked);
104  item->setData (0, RoleTag, *i);
105  items << item;
106  }
107  addTopLevelItems (items);
108 
109  setHeaderLabel (Caption_);
110 
111  connect (this,
112  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
113  this,
114  SLOT (buttonToggled ()));
115 
116  emit tagsSelectionChanged (QStringList ());
117 }
118 
120 {
121  QStringList tags;
122 
123  for (int i = 0, size = topLevelItemCount ();
124  i < size; ++i)
125  {
126  QTreeWidgetItem *item = topLevelItem (i);
127  if (item->checkState (0) == Qt::Checked)
128  tags += item->data (0, RoleTag).toString ();
129  }
130 
131  return tags;
132 }
133 
134 void CategorySelector::SetSelections (const QStringList& tags)
135 {
136  blockSignals (true);
137  for (int i = 0; i < topLevelItemCount (); ++i)
138  {
139  Qt::CheckState state =
140  tags.contains (topLevelItem (i)->data (0, RoleTag).toString ()) ?
141  Qt::Checked :
142  Qt::Unchecked;
143  topLevelItem (i)->setCheckState (0, state);
144  }
145  blockSignals (false);
146 }
147 
149 {
150  return Separator_;
151 }
152 
153 void CategorySelector::SetSeparator (const QString& sep)
154 {
155  Separator_ = sep;
156 }
157 
158 void CategorySelector::moveEvent (QMoveEvent *e)
159 {
160  QWidget::moveEvent (e);
161  QPoint pos = e->pos ();
162  QRect avail = QApplication::desktop ()->availableGeometry (this);
163  int dx = 0, dy = 0;
164  if (pos.x () + width () > avail.width ())
165  dx = width () + pos.x () - avail.width ();
166  if (pos.y () + height () > avail.height () &&
167  height () < avail.height ())
168  dy = height () + pos.y () - avail.height ();
169 
170  if (dx || dy)
171  move (pos - QPoint (dx, dy));
172 }
173 
175 {
176  disconnect (this,
177  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
178  this,
179  SLOT (buttonToggled ()));
180 
181  QStringList tags;
182 
183  for (int i = 0, size = topLevelItemCount (); i < size; ++i)
184  {
185  QTreeWidgetItem *item = topLevelItem (i);
186  item->setCheckState (0, Qt::Checked);
187  tags += item->data (0, RoleTag).toString ();
188  }
189 
190  connect (this,
191  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
192  this,
193  SLOT (buttonToggled ()));
194 
195  emit tagsSelectionChanged (tags);
196 }
197 
199 {
200  disconnect (this,
201  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
202  this,
203  SLOT (buttonToggled ()));
204 
205  for (int i = 0; i < topLevelItemCount (); ++i)
206  topLevelItem (i)->setCheckState (0, Qt::Unchecked);
207 
208  connect (this,
209  SIGNAL (itemChanged (QTreeWidgetItem*, int)),
210  this,
211  SLOT (buttonToggled ()));
212 
213  emit tagsSelectionChanged (QStringList ());
214 }
215 
216 void CategorySelector::lineTextChanged (const QString& text)
217 {
218  QStringList tags = text.split (Separator_, QString::SkipEmptyParts);
219  SetSelections (tags);
220 }
221 
222 void CategorySelector::buttonToggled ()
223 {
225 }
226 
void selectNone()
Deselects all variants.
void SetCaption(const QString &caption)
Sets the caption of this selector.
void SetSelections(const QStringList &subset)
Selects some of the items.
void selectAll()
Selects all variants.
UTIL_API void SetSeparator(const QString &)
Sets the separator for the tags.
void lineTextChanged(const QString &newText)
Notifies CategorySelector about logical selection changes.
void setPossibleSelections(QStringList selections)
Sets possible selections.
QStringList GetSelections()
Gets selected items.
UTIL_API QString GetSeparator() const
Returns the separator for the tags.
virtual void moveEvent(QMoveEvent *)
Checks whether after the move event the selector won&#39;t be beoynd the screen. if it would...
void tagsSelectionChanged(const QStringList &newSelections)
Indicates that selections have changed.
CategorySelector(QWidget *parent=0)
Constructor.
const int RoleTag