1 /*
2 * This file is part of Licq, an instant messaging client for UNIX.
3 * Copyright (C) 2007-2012 Licq developers <licq-dev@googlegroups.com>
4 *
5 * Licq is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Licq is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Licq; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "events.h"
21
22 #include "config.h"
23
24 #include <boost/foreach.hpp>
25
26 #include <QCheckBox>
27 #include <QComboBox>
28 #include <QGridLayout>
29 #include <QGroupBox>
30 #include <QLabel>
31 #include <QPushButton>
32 #include <QTreeWidget>
33 #include <QVBoxLayout>
34
35 #include <licq/contactlist/owner.h>
36 #include <licq/daemon.h>
37 #include <licq/filter.h>
38 #include <licq/plugin/pluginmanager.h>
39 #include <licq/oneventmanager.h>
40 #include <licq/userevents.h>
41
42 #include "config/chat.h"
43 #include "config/contactlist.h"
44 #include "config/general.h"
45 #include "config/shortcuts.h"
46 #include "dialogs/filterruledlg.h"
47 #include "dialogs/hintsdlg.h"
48 #include "widgets/shortcutedit.h"
49
50 #include "oneventbox.h"
51 #include "settingsdlg.h"
52
53
54 using Licq::OnEventData;
55 using Licq::gOnEventManager;
56 using namespace LicqQtGui;
57 /* TRANSLATOR LicqQtGui::Settings::Events */
58
Events(SettingsDlg * parent)59 Settings::Events::Events(SettingsDlg* parent)
60 : QObject(parent)
61 {
62 parent->addPage(SettingsDlg::OnEventPage, createPageOnEvent(parent),
63 tr("Events"));
64 parent->addPage(SettingsDlg::SoundsPage, createPageSounds(parent),
65 tr("Sounds"), SettingsDlg::OnEventPage);
66 parent->addPage(SettingsDlg::FilterPage, createPageFilter(parent),
67 tr("Filter"), SettingsDlg::OnEventPage);
68
69 load();
70 }
71
createPageOnEvent(QWidget * parent)72 QWidget* Settings::Events::createPageOnEvent(QWidget* parent)
73 {
74 QWidget* w = new QWidget(parent);
75 myPageOnEventLayout = new QVBoxLayout(w);
76 myPageOnEventLayout->setContentsMargins(0, 0, 0, 0);
77
78 myNewMsgActionsBox = new QGroupBox(tr("Actions on Incoming Messages"));
79 myMsgActionsLayout = new QGridLayout(myNewMsgActionsBox);
80
81 myBoldOnMsgCheck = new QCheckBox(tr("Bold message label"));
82 myBoldOnMsgCheck->setToolTip(tr("Show the message info label in bold font if there are incoming messages"));
83 myMsgActionsLayout->addWidget(myBoldOnMsgCheck, 0, 0);
84
85 myAutoFocusCheck = new QCheckBox(tr("Auto-focus message"));
86 myAutoFocusCheck->setToolTip(tr("Automatically focus opened message windows."));
87 myMsgActionsLayout->addWidget(myAutoFocusCheck, 1, 0);
88
89 myAutoRaiseCheck = new QCheckBox(tr("Auto-raise main window"));
90 myAutoRaiseCheck->setToolTip(tr("Raise the main window on incoming messages"));
91 myMsgActionsLayout->addWidget(myAutoRaiseCheck, 2, 0);
92
93 QHBoxLayout* autoPopupLayout = new QHBoxLayout();
94 QLabel* autoPopupLabel = new QLabel(tr("Auto-popup message:"));
95 autoPopupLayout->addWidget(autoPopupLabel);
96 myAutoPopupCombo = new QComboBox();
97 myAutoPopupCombo->addItem(tr("Never"));
98 myAutoPopupCombo->addItem(tr("Only when online"));
99 myAutoPopupCombo->addItem(tr("When online or away"));
100 myAutoPopupCombo->addItem(tr("When online, away or N/A"));
101 myAutoPopupCombo->addItem(tr("Always except DND"));
102 myAutoPopupCombo->addItem(tr("Always"));
103 myAutoPopupCombo->setToolTip(tr("Select for which statuses incoming messages should "
104 "open automatically.\nOnline also includes Free for chat."));
105 autoPopupLabel->setBuddy(myAutoPopupCombo);
106 autoPopupLayout->addWidget(myAutoPopupCombo);
107 myMsgActionsLayout->addLayout(autoPopupLayout, 3, 0);
108
109 myAutoUrgentCheck = new QCheckBox(tr("Auto-popup urgent only"));
110 myAutoUrgentCheck->setToolTip(tr("Only auto-popup urgent messages."));
111 myMsgActionsLayout->addWidget(myAutoUrgentCheck, 4, 0);
112
113 myFlashTaskbarCheck = new QCheckBox(tr("Flash taskbar"));
114 myFlashTaskbarCheck->setToolTip(tr("Flash the taskbar on incoming messages"));
115 myMsgActionsLayout->addWidget(myFlashTaskbarCheck, 0, 1);
116
117 myFlashAllCheck = new QCheckBox(tr("Blink all events"));
118 myFlashAllCheck->setToolTip(tr("All incoming events will blink"));
119 myMsgActionsLayout->addWidget(myFlashAllCheck, 1, 1);
120
121 myFlashUrgentCheck = new QCheckBox(tr("Blink urgent events"));
122 myFlashUrgentCheck->setToolTip(tr("Only urgent events will blink"));
123 myMsgActionsLayout->addWidget(myFlashUrgentCheck, 2, 1);
124
125 #ifdef Q_WS_X11
126 QHBoxLayout* hotKeyLayout = new QHBoxLayout();
127 myHotKeyLabel = new QLabel(tr("Hot key:"));
128 hotKeyLayout->addWidget(myHotKeyLabel);
129 hotKeyLayout->addStretch();
130 myHotKeyLabel->setToolTip(tr("Hotkey to pop up the next pending message.\n"
131 "Enter the hotkey literally, like \"shift+f10\", or \"none\" for disabling."));
132 myHotKeyEdit = new ShortcutEdit();
133 myHotKeyEdit->setToolTip(myHotKeyLabel->toolTip());
134 myHotKeyLabel->setBuddy(myHotKeyEdit);
135 hotKeyLayout->addWidget(myHotKeyEdit);
136 myMsgActionsLayout->addLayout(hotKeyLayout, 3, 1);
137 #endif
138
139 // Make the columns evenly wide
140 myMsgActionsLayout->setColumnStretch(0, 1);
141 myMsgActionsLayout->setColumnStretch(1, 1);
142
143 myParanoiaBox = new QGroupBox(tr("Paranoia"));
144 myParanoiaLayout = new QVBoxLayout(myParanoiaBox);
145
146 myIgnoreNewUsersCheck = new QCheckBox(tr("Ignore new users"));
147 myIgnoreNewUsersCheck->setToolTip(tr("Determines if new users are automatically added to your list or must first request authorization."));
148 myParanoiaLayout->addWidget(myIgnoreNewUsersCheck);
149
150 myIgnoreMassMsgCheck = new QCheckBox(tr("Ignore mass messages"));
151 myIgnoreMassMsgCheck->setToolTip(tr("Determines if mass messages are ignored or not."));
152 myParanoiaLayout->addWidget(myIgnoreMassMsgCheck);
153
154 myIgnoreWebPanelCheck = new QCheckBox(tr("Ignore web panel"));
155 myIgnoreWebPanelCheck->setToolTip(tr("Determines if web panel messages are ignored or not."));
156 myParanoiaLayout->addWidget(myIgnoreWebPanelCheck);
157
158 myIgnoreEmailPagerCheck = new QCheckBox(tr("Ignore email pager"));
159 myIgnoreEmailPagerCheck->setToolTip(tr("Determines if email pager messages are ignored or not."));
160 myParanoiaLayout->addWidget(myIgnoreEmailPagerCheck);
161
162
163 myPageOnEventLayout->addWidget(myNewMsgActionsBox);
164 myPageOnEventLayout->addWidget(myParanoiaBox);
165 myPageOnEventLayout->addStretch(1);
166
167 return w;
168 }
169
createPageSounds(QWidget * parent)170 QWidget* Settings::Events::createPageSounds(QWidget* parent)
171 {
172 QWidget* w = new QWidget(parent);
173 myPageSoundsLayout = new QVBoxLayout(w);
174 myPageSoundsLayout->setContentsMargins(0, 0, 0, 0);
175
176 myOnEventBox = new OnEventBox(true);
177 myPageSoundsLayout->addWidget(myOnEventBox);
178
179 QGridLayout* soundsLayout = dynamic_cast<QGridLayout*>(myOnEventBox->layout());
180 int soundsRows = soundsLayout->rowCount();
181
182 myNoSoundInActiveChatCheck = new QCheckBox(tr("Disable sound for active window"));
183 myNoSoundInActiveChatCheck->setToolTip(tr("Don't perform OnEvent command if chat window for user is currently active."));
184 soundsLayout->addWidget(myNoSoundInActiveChatCheck, soundsRows, 1, 1, 3);
185
186 myPageSoundsLayout->addStretch(1);
187
188 return w;
189 }
190
createPageFilter(QWidget * parent)191 QWidget* Settings::Events::createPageFilter(QWidget* parent)
192 {
193 QWidget* w = new QWidget(parent);
194 QVBoxLayout* pageFilterLayout = new QVBoxLayout(w);
195 pageFilterLayout->setContentsMargins(0, 0, 0, 0);
196
197 QGroupBox* filterRulesBox = new QGroupBox(tr("Rules for Incoming Events"));
198 pageFilterLayout->addWidget(filterRulesBox);
199 QVBoxLayout* filterRulesLayout = new QVBoxLayout(filterRulesBox);
200
201 myRulesList = new QTreeWidget();
202 QStringList headers;
203 headers << tr("Enabled") << tr("Action") << tr("Protocol") << tr("Event Type") << tr("Expression");
204 myRulesList->setHeaderLabels(headers);
205 myRulesList->setIndentation(0);
206 myRulesList->setAllColumnsShowFocus(true);
207 filterRulesLayout->addWidget(myRulesList);
208
209 QHBoxLayout* buttons = new QHBoxLayout();
210
211 QPushButton* ruleHintsButton = new QPushButton(tr("Hints"));
212 buttons->addWidget(ruleHintsButton);
213
214 QPushButton* rulesResetButton = new QPushButton(tr("Reset"));
215 buttons->addWidget(rulesResetButton);
216
217 myRuleAddButton = new QPushButton(tr("Add"));
218 buttons->addWidget(myRuleAddButton);
219
220 myRuleRemoveButton = new QPushButton(tr("Remove"));
221 buttons->addWidget(myRuleRemoveButton);
222
223 myRuleEditButton = new QPushButton(tr("Modify"));
224 buttons->addWidget(myRuleEditButton);
225
226 myRuleUpButton = new QPushButton(tr("Move Up"));
227 buttons->addWidget(myRuleUpButton);
228
229 myRuleDownButton = new QPushButton(tr("Move Down"));
230 buttons->addWidget(myRuleDownButton);
231
232 filterRulesLayout->addLayout(buttons);
233
234 myRuleEditor = NULL;
235
236 connect(myRulesList, SIGNAL(itemSelectionChanged()), SLOT(updateRuleButtons()));
237 connect(myRulesList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
238 SLOT(editRule(QTreeWidgetItem*,int)));
239 connect(ruleHintsButton, SIGNAL(clicked()), SLOT(showRuleHints()));
240 connect(rulesResetButton, SIGNAL(clicked()), SLOT(resetRules()));
241 connect(myRuleAddButton, SIGNAL(clicked()), SLOT(insertRule()));
242 connect(myRuleRemoveButton, SIGNAL(clicked()), SLOT(removeRule()));
243 connect(myRuleEditButton, SIGNAL(clicked()), SLOT(editRule()));
244 connect(myRuleUpButton, SIGNAL(clicked()), SLOT(moveRuleUp()));
245 connect(myRuleDownButton, SIGNAL(clicked()), SLOT(moveRuleDown()));
246
247 return w;
248 }
249
load()250 void Settings::Events::load()
251 {
252 Config::Chat* chatConfig = Config::Chat::instance();
253 Config::ContactList* contactListConfig = Config::ContactList::instance();
254 Config::General* generalConfig = Config::General::instance();
255 Config::Shortcuts* shortcutConfig = Config::Shortcuts::instance();
256
257 myAutoRaiseCheck->setChecked(generalConfig->autoRaiseMainwin());
258 myBoldOnMsgCheck->setChecked(generalConfig->boldOnMsg());
259
260 #ifdef Q_WS_X11
261 myHotKeyEdit->setKeySequence(shortcutConfig->getShortcut(Config::Shortcuts::GlobalPopupMessage));
262 #endif
263
264 Config::ContactList::FlashMode flash = contactListConfig->flash();
265 myFlashUrgentCheck->setChecked(flash == Config::ContactList::FlashUrgent || flash == Config::ContactList::FlashAll);
266 myFlashAllCheck->setChecked(flash == Config::ContactList::FlashAll);
267
268 myAutoPopupCombo->setCurrentIndex(chatConfig->autoPopup());
269 myAutoUrgentCheck->setChecked(chatConfig->autoPopupUrgentOnly());
270 myAutoFocusCheck->setChecked(chatConfig->autoFocus());
271 myFlashTaskbarCheck->setChecked(chatConfig->flashTaskbar());
272 myNoSoundInActiveChatCheck->setChecked(chatConfig->noSoundInActiveChat());
273
274 myIgnoreNewUsersCheck->setChecked(Licq::gDaemon.ignoreType(Licq::Daemon::IgnoreNewUsers));
275 myIgnoreMassMsgCheck->setChecked(Licq::gDaemon.ignoreType(Licq::Daemon::IgnoreMassMsg));
276 myIgnoreWebPanelCheck->setChecked(Licq::gDaemon.ignoreType(Licq::Daemon::IgnoreWebPanel));
277 myIgnoreEmailPagerCheck->setChecked(Licq::gDaemon.ignoreType(Licq::Daemon::IgnoreEmailPager));
278
279 const OnEventData* eventData = gOnEventManager.lockGlobal();
280 myOnEventBox->load(eventData, NULL);
281 gOnEventManager.unlock(eventData);
282
283 Licq::gFilterManager.getRules(myFilterRules);
284 updateRulesList();
285 }
286
apply()287 void Settings::Events::apply()
288 {
289 Config::Chat* chatConfig = Config::Chat::instance();
290 Config::ContactList* contactListConfig = Config::ContactList::instance();
291 Config::General* generalConfig = Config::General::instance();
292 Config::Shortcuts* shortcutConfig = Config::Shortcuts::instance();
293 chatConfig->blockUpdates(true);
294 contactListConfig->blockUpdates(true);
295 generalConfig->blockUpdates(true);
296
297 generalConfig->setAutoRaiseMainwin(myAutoRaiseCheck->isChecked());
298 generalConfig->setBoldOnMsg(myBoldOnMsgCheck->isChecked());
299
300 #ifdef Q_WS_X11
301 shortcutConfig->setShortcut(Config::Shortcuts::GlobalPopupMessage, myHotKeyEdit->keySequence());
302 #endif
303
304 if (myFlashAllCheck->isChecked())
305 contactListConfig->setFlash(Config::ContactList::FlashAll);
306 else if(myFlashUrgentCheck->isChecked())
307 contactListConfig->setFlash(Config::ContactList::FlashUrgent);
308 else
309 contactListConfig->setFlash(Config::ContactList::FlashNone);
310
311 chatConfig->setAutoPopup(myAutoPopupCombo->currentIndex());
312 chatConfig->setAutoPopupUrgentOnly(myAutoUrgentCheck->isChecked());
313 chatConfig->setAutoFocus(myAutoFocusCheck->isChecked());
314 chatConfig->setFlashTaskbar(myFlashTaskbarCheck->isChecked());
315 chatConfig->setNoSoundInActiveChat(myNoSoundInActiveChatCheck->isChecked());
316
317 Licq::gDaemon.setIgnoreType(Licq::Daemon::IgnoreNewUsers, myIgnoreNewUsersCheck->isChecked());
318 Licq::gDaemon.setIgnoreType(Licq::Daemon::IgnoreMassMsg, myIgnoreMassMsgCheck->isChecked());
319 Licq::gDaemon.setIgnoreType(Licq::Daemon::IgnoreWebPanel, myIgnoreWebPanelCheck->isChecked());
320 Licq::gDaemon.setIgnoreType(Licq::Daemon::IgnoreEmailPager, myIgnoreEmailPagerCheck->isChecked());
321
322 OnEventData* eventData = gOnEventManager.lockGlobal();
323 myOnEventBox->apply(eventData);
324 gOnEventManager.unlock(eventData, true);
325
326 Licq::gFilterManager.setRules(myFilterRules);
327
328 chatConfig->blockUpdates(false);
329 contactListConfig->blockUpdates(false);
330 generalConfig->blockUpdates(false);
331 }
332
updateRulesList()333 void Settings::Events::updateRulesList()
334 {
335 myRulesList->clear();
336 BOOST_FOREACH(const Licq::FilterRule& rule, myFilterRules)
337 {
338 QTreeWidgetItem* item = new QTreeWidgetItem(myRulesList);
339
340 item->setText(0, (rule.isEnabled ? tr("Yes") : tr("No")));
341
342 QString actionStr;
343 switch (rule.action)
344 {
345 case Licq::FilterRule::ActionAccept: actionStr = tr("Accept"); break;
346 case Licq::FilterRule::ActionSilent: actionStr = tr("Silent"); break;
347 case Licq::FilterRule::ActionIgnore: actionStr = tr("Ignore"); break;
348 }
349 item->setText(1, actionStr);
350
351 if (rule.protocolId == 0)
352 {
353 item->setText(2, tr("Any"));
354 }
355 else
356 {
357 Licq::ProtocolPlugin::Ptr proto = Licq::gPluginManager.getProtocolPlugin(rule.protocolId);
358 if (proto.get() != 0)
359 item->setText(2, QString::fromLocal8Bit(proto->name().c_str()));
360 }
361
362 QString eventName;
363 for (int i = 0; i < 32; ++i)
364 {
365 if ((rule.eventMask & (1<<i)) == 0)
366 continue;
367 if (eventName.isEmpty())
368 {
369 eventName = QString::fromLocal8Bit(Licq::UserEvent::eventName(i).c_str());
370 }
371 else
372 {
373 eventName = tr("(Multiple)");
374 break;
375 }
376 }
377 item->setText(3, eventName);
378
379 item->setText(4, QString::fromUtf8(rule.expression.c_str()));
380 }
381
382 myRulesList->resizeColumnToContents(0);
383 myRulesList->resizeColumnToContents(1);
384 myRulesList->resizeColumnToContents(2);
385 myRulesList->resizeColumnToContents(3);
386 myRulesList->resizeColumnToContents(4);
387 updateRuleButtons();
388 }
389
updateRuleButtons()390 void Settings::Events::updateRuleButtons()
391 {
392 QTreeWidgetItem* item = myRulesList->currentItem();
393 int pos = (item == NULL ? -1 : myRulesList->indexOfTopLevelItem(item));
394 bool editing = (myRuleEditor != NULL);
395 myRuleAddButton->setEnabled(!editing);
396 myRuleRemoveButton->setEnabled(item != NULL && !editing);
397 myRuleEditButton->setEnabled(item != NULL && !editing);
398 myRuleUpButton->setEnabled(item != NULL && !editing && pos > 0);
399 myRuleDownButton->setEnabled(item != NULL && !editing &&
400 pos < myRulesList->topLevelItemCount() - 1);
401 }
402
showRuleHints()403 void Settings::Events::showRuleHints()
404 {
405 QString h = tr(
406 "<h2>Hints for Event Filter Rules</h2>"
407 "<p>Incoming events are run through the list of rules to decide how to"
408 " handle them. The first rule to match decides the action and if no rule"
409 " matches the default action is to accept the event. (To override the"
410 " default, add a rule last with another action that matches all event"
411 " types and has an empty expression.)</p>"
412 "<p>Any event from a user already in the contact list is always accepted"
413 " (unless they're in the ignore list). The event filter is only applied"
414 " to events from unknown users.</p>"
415 "<p>The following actions are available:</p><ul>"
416 "<li>Accept - the event as handled as normal and on events performed.</li>"
417 "<li>Silent - the event is written to history but otherwise ignored.</li>"
418 "<li>Ignore - the event is completely ignored.</li>"
419 "</ul>"
420 "<p>If the expression is empty, it will match any event. Otherwise it is"
421 " applied as a regular expression to any message in the event. "
422 "The expression must match the entire message text. (To match only part"
423 " of a message, enter it as \".*part.*\".)</p>"
424 "<p>The filter has a default set of rules that will block some common"
425 " spam messages. The defaults can be restored by removing the file"
426 " \"~/.licq/filter.conf\" while Licq is NOT running.</p>"
427 );
428 new HintsDlg(h, dynamic_cast<QWidget*>(parent()));
429 }
430
resetRules()431 void Settings::Events::resetRules()
432 {
433 Licq::gFilterManager.getDefaultRules(myFilterRules);
434 updateRulesList();
435 }
436
editRule(QTreeWidgetItem * item,int)437 void Settings::Events::editRule(QTreeWidgetItem* item, int /* index */)
438 {
439 if (myRuleEditor != NULL || item == NULL)
440 return;
441
442 myRuleEditIndex = myRulesList->indexOfTopLevelItem(item);
443 if (myRuleEditIndex < 0)
444 return;
445
446 myRuleEditor = new FilterRuleDlg(&myFilterRules[myRuleEditIndex]);
447 connect(myRuleEditor, SIGNAL(finished(int)), SLOT(editRuleDone(int)));
448
449 updateRuleButtons();
450 }
451
editRule()452 void Settings::Events::editRule()
453 {
454 editRule(myRulesList->currentItem(), 0);
455 }
456
insertRule()457 void Settings::Events::insertRule()
458 {
459 myRuleEditIndex = -1;
460 myRuleEditor = new FilterRuleDlg();
461 connect(myRuleEditor, SIGNAL(finished(int)), SLOT(editRuleDone(int)));
462
463 updateRuleButtons();
464 }
465
editRuleDone(int dialogCode)466 void Settings::Events::editRuleDone(int dialogCode)
467 {
468 if (dialogCode == QDialog::Rejected)
469 {
470 // User pressed cancel
471 myRuleEditor = NULL;
472 updateRuleButtons();
473 return;
474 }
475
476 if (myRuleEditIndex == -1)
477 {
478 // Rule is added, make room for it in list
479 myRuleEditIndex = myFilterRules.size();
480 myFilterRules.resize(myRuleEditIndex + 1);
481 }
482
483 myRuleEditor->getFilterRule(myFilterRules[myRuleEditIndex]);
484 myRuleEditor = NULL;
485
486 updateRulesList();
487 }
488
removeRule()489 void Settings::Events::removeRule()
490 {
491 QTreeWidgetItem* item = myRulesList->currentItem();
492 if (item == NULL)
493 return;
494
495 int pos = myRulesList->indexOfTopLevelItem(item);
496 if (pos < 0)
497 return;
498
499 for (int i = pos; i < (int)myFilterRules.size() - 1; ++i)
500 myFilterRules[i] = myFilterRules[i+1];
501 myFilterRules.erase(--myFilterRules.end());
502
503 // Drop the list item instead of reloading entire list
504 delete item;
505 }
506
moveRuleUp()507 void Settings::Events::moveRuleUp()
508 {
509 QTreeWidgetItem* item = myRulesList->currentItem();
510 if (item == NULL)
511 return;
512
513 int pos = myRulesList->indexOfTopLevelItem(item);
514 if (pos <= 0)
515 return;
516
517 Licq::FilterRule tempRule = myFilterRules[pos];
518 myFilterRules[pos] = myFilterRules[pos - 1];
519 myFilterRules[pos - 1] = tempRule;
520
521 // Swap the list items instead of reloading entire list
522 myRulesList->takeTopLevelItem(pos);
523 myRulesList->insertTopLevelItem(pos-1, item);
524 myRulesList->setCurrentItem(item);
525 }
526
moveRuleDown()527 void Settings::Events::moveRuleDown()
528 {
529 QTreeWidgetItem* item = myRulesList->currentItem();
530 if (item == NULL)
531 return;
532
533 int pos = myRulesList->indexOfTopLevelItem(item);
534 if (pos < 0 || pos >= myRulesList->topLevelItemCount() - 1)
535 return;
536
537 Licq::FilterRule tempRule = myFilterRules[pos];
538 myFilterRules[pos] = myFilterRules[pos + 1];
539 myFilterRules[pos + 1] = tempRule;
540
541 // Swap the list items instead of reloading entire list
542 myRulesList->takeTopLevelItem(pos);
543 myRulesList->insertTopLevelItem(pos+1, item);
544 myRulesList->setCurrentItem(item);
545 }
546