11#include < QListWidget>
22#include < QMenu>
33#include < QWidgetAction>
4- #include < QButtonGroup>
5- #include < QRadioButton>
4+ #include < QCheckBox>
65#include " kiwixapp.h"
76#include " multizimbutton.h"
87#include " css_constants.h"
@@ -11,8 +10,7 @@ QString getElidedText(const QFont& font, int length, const QString& text);
1110
1211MultiZimButton::MultiZimButton (QWidget *parent) :
1312 QToolButton(parent),
14- mp_buttonList(new QListWidget),
15- mp_radioButtonGroup(new QButtonGroup(this ))
13+ mp_buttonList(new QListWidget)
1614{
1715 setMenu (new QMenu (this ));
1816 setPopupMode (QToolButton::InstantPopup);
@@ -23,17 +21,82 @@ MultiZimButton::MultiZimButton(QWidget *parent) :
2321 popupAction->setDefaultWidget (mp_buttonList);
2422 menu ()->addAction (popupAction);
2523
26- connect (mp_buttonList, &QListWidget::currentRowChanged, this , [=](int row){
27- if (const auto widget = getZimWidget (row))
28- widget->getRadioButton ()->setChecked (true );
24+ connect (mp_buttonList, &QListWidget::itemActivated, this , [=](QListWidgetItem *item) {
25+ if (const auto widget = getZimWidget (item))
26+ widget->toggle ();
27+ });
28+ connect (mp_buttonList, &QListWidget::itemClicked, this , [=](QListWidgetItem *item) {
29+ if (const auto widget = getZimWidget (item))
30+ widget->toggle ();
2931 });
3032}
3133
3234void MultiZimButton::updateDisplay ()
3335{
36+ const auto library = KiwixApp::instance ()->getLibrary ();
37+ const auto view = KiwixApp::instance ()->getTabWidget ()->currentWebView ();
38+ QListWidgetItem* currentItem = nullptr ;
39+ QIcon currentIcon;
40+ const int paddingTopBot = CSS::MultiZimButton::QListWidget::paddingVertical * 2 ;
41+ const int itemHeight = paddingTopBot + CSS::ZimItemWidget::QLabel::lineHeight;
42+
43+ for (int row = 0 ; row < mp_buttonList->count (); row++)
44+ {
45+ const auto item = mp_buttonList->item (row);
46+ const auto bookId = item->data (Qt::UserRole).toString ();
47+ const QString bookTitle = QString::fromStdString (library->getBookById (bookId).getTitle ());
48+ const QIcon zimIcon = library->getBookIcon (bookId);
49+ item->setData (Qt::DisplayRole, bookTitle);
50+ item->setSizeHint (QSize (0 , itemHeight));
51+
52+ if (view && view->zimId () == bookId)
53+ {
54+ currentItem = item;
55+ currentIcon = zimIcon;
56+ continue ;
57+ }
58+
59+ setItemZimWidget (item, bookTitle, zimIcon);
60+ }
61+
62+ mp_buttonList->sortItems ();
63+ if (currentItem)
64+ {
65+ const auto checked = getZimWidget (currentItem)->isChecked ();
66+ const auto title = currentItem->data (Qt::DisplayRole).toString ();
67+ const auto currentRow = mp_buttonList->row (currentItem);
68+ if (currentRow > 0 ) {
69+ currentItem = mp_buttonList->takeItem (currentRow);
70+ mp_buttonList->insertItem (0 , currentItem);
71+ currentItem = mp_buttonList->item (0 );
72+ setItemZimWidget (currentItem, " *" + title, currentIcon);
73+ if (checked)
74+ getZimWidget (currentItem)->setChecked (checked);
75+ }
76+ else {
77+ setItemZimWidget (currentItem, " *" + title, currentIcon);
78+ }
79+ }
80+
81+ /* Display should not be used other than for sorting. */
82+ for (int i = 0 ; i < mp_buttonList->count (); i++)
83+ mp_buttonList->item (i)->setData (Qt::DisplayRole, QVariant ());
84+
85+ setDisabled (mp_buttonList->model ()->rowCount () == 0 );
86+
87+ mp_buttonList->scrollToTop ();
88+ mp_buttonList->setCurrentRow (0 );
89+
90+ /* We set a maximum display height for list. Respect padding. */
91+ const int listHeight = itemHeight * std::min (7 , mp_buttonList->count ());
92+ mp_buttonList->setFixedHeight (listHeight + paddingTopBot);
93+ mp_buttonList->setFixedWidth (menu ()->width ());
94+ }
95+
96+ void MultiZimButton::updateBooks ()
97+ {
98+ auto checkedZimIds = getCheckedZimIds ();
3499 mp_buttonList->clear ();
35- for (const auto & button : mp_radioButtonGroup->buttons ())
36- mp_radioButtonGroup->removeButton (button);
37100
38101 const auto library = KiwixApp::instance ()->getLibrary ();
39102 const auto view = KiwixApp::instance ()->getTabWidget ()->currentWebView ();
@@ -65,6 +128,10 @@ void MultiZimButton::updateDisplay()
65128
66129 mp_buttonList->addItem (item);
67130 setItemZimWidget (item, bookTitle, zimIcon);
131+ if (checkedZimIds.contains (bookId)) {
132+ checkedZimIds.removeOne (bookId);
133+ getZimWidget (item)->setChecked (true );
134+ }
68135 }
69136
70137 mp_buttonList->sortItems ();
@@ -77,6 +144,7 @@ void MultiZimButton::updateDisplay()
77144 }
78145
79146 /* Display should not be used other than for sorting. */
147+
80148 for (int i = 0 ; i < mp_buttonList->count (); i++)
81149 mp_buttonList->item (i)->setData (Qt::DisplayRole, QVariant ());
82150
@@ -86,6 +154,7 @@ void MultiZimButton::updateDisplay()
86154 mp_buttonList->setCurrentRow (0 );
87155
88156 /* We set a maximum display height for list. Respect padding. */
157+
89158 const int listHeight = itemHeight * std::min (7 , mp_buttonList->count ());
90159 mp_buttonList->setFixedHeight (listHeight + paddingTopBot);
91160 mp_buttonList->setFixedWidth (menu ()->width ());
@@ -94,10 +163,30 @@ void MultiZimButton::updateDisplay()
94163QStringList MultiZimButton::getZimIds () const
95164{
96165 QStringList idList;
166+ bool someChecked = false ;
97167 for (int row = 0 ; row < mp_buttonList->count (); row++)
98168 {
99169 const auto widget = getZimWidget (row);
100- if (widget && widget->getRadioButton ()->isChecked ())
170+ if (widget && widget->isChecked ()) {
171+ if (!someChecked) {
172+ someChecked = true ;
173+ idList.clear ();
174+ }
175+ idList.append (mp_buttonList->item (row)->data (Qt::UserRole).toString ());
176+ }
177+ else if (!someChecked)
178+ idList.append (mp_buttonList->item (row)->data (Qt::UserRole).toString ());
179+ }
180+ return idList;
181+ }
182+
183+ QStringList MultiZimButton::getCheckedZimIds () const
184+ {
185+ QStringList idList;
186+ for (int row = 0 ; row < mp_buttonList->count (); row++)
187+ {
188+ const auto widget = getZimWidget (row);
189+ if (widget && widget->isChecked ())
101190 idList.append (mp_buttonList->item (row)->data (Qt::UserRole).toString ());
102191 }
103192 return idList;
@@ -109,19 +198,30 @@ ZimItemWidget *MultiZimButton::getZimWidget(int row) const
109198 return qobject_cast<ZimItemWidget *>(widget);
110199}
111200
201+ ZimItemWidget *MultiZimButton::getZimWidget (QListWidgetItem *item) const
202+ {
203+ const auto widget = mp_buttonList->itemWidget (item);
204+ return qobject_cast<ZimItemWidget *>(widget);
205+ }
206+
112207void MultiZimButton::setItemZimWidget (QListWidgetItem *item,
113208 const QString &title, const QIcon &icon)
114209{
210+ const auto oldWidget = getZimWidget (item);
211+ const auto checked = oldWidget
212+ ? oldWidget->isChecked ()
213+ : false ;
115214 const auto zimWidget = new ZimItemWidget (title, icon);
116- mp_radioButtonGroup->addButton (zimWidget->getRadioButton ());
117215 mp_buttonList->setItemWidget (item, zimWidget);
216+ if (checked)
217+ zimWidget->setChecked (true );
118218}
119219
120220ZimItemWidget::ZimItemWidget (QString text, QIcon icon, QWidget *parent) :
121221 QWidget(parent),
122222 textLabel(new QLabel(this )),
123223 iconLabel(new QLabel(this )),
124- radioBt (new QRadioButton (this ))
224+ checkBx (new QCheckBox (this ))
125225{
126226 setLayout (new QHBoxLayout);
127227
@@ -163,5 +263,24 @@ ZimItemWidget::ZimItemWidget(QString text, QIcon icon, QWidget *parent) :
163263
164264 layout ()->addWidget (iconLabel);
165265 layout ()->addWidget (textLabel);
166- layout ()->addWidget (radioBt);
266+ layout ()->addWidget (checkBx);
267+ }
268+
269+ bool ZimItemWidget::isChecked () const {
270+ const auto cb = getCheckBox ();
271+ if (cb)
272+ return cb->isChecked ();
273+ return false ;
274+ }
275+
276+ void ZimItemWidget::setChecked (bool checked) {
277+ const auto cb = getCheckBox ();
278+ if (cb)
279+ cb->setChecked (checked);
280+ }
281+
282+ void ZimItemWidget::toggle () {
283+ const auto cb = getCheckBox ();
284+ if (cb)
285+ cb->toggle ();
167286}
0 commit comments