1//---------------------------------------------------------------------------
2//
3// kPPP: A pppd front end for the KDE project
4//
5//---------------------------------------------------------------------------
6//
7// (c) 1997-1998 Bernd Johannes Wuebben <wuebben@kde.org>
8// (c) 1997-1999 Mario Weilguni <mweilguni@kde.org>
9// (c) 1998-1999 Harri Porten <porten@kde.org>
10//
11// derived from Jay Painters "ezppp"
12//
13//---------------------------------------------------------------------------
14//
15// $Id$
16//
17//---------------------------------------------------------------------------
18//
19// This program is free software; you can redistribute it and-or
20// modify it under the terms of the GNU Library General Public
21// License as published by the Free Software Foundation; either
22// version 2 of the License, or (at your option) any later version.
23//
24// This program is distributed in the hope that it will be useful,
25// but WITHOUT ANY WARRANTY; without even the implied warranty of
26// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27// Library General Public License for more details.
28//
29// You should have received a copy of the GNU Library General Public
30// License along with this program; if not, write to the Free
31// Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32//
33//---------------------------------------------------------------------------
34
35#define QT3_SUPPORT
36#include <q3listview.h>
37#undef QT3_SUPPORT
38#include <qcombobox.h>
39#include <qlabel.h>
40#include <kurllabel.h>
41#include <qlayout.h>
42#include <qdir.h>
43#include <qregexp.h>
44#include <qmatrix.h>
45#include <qcheckbox.h>
46#include <kdialog.h>
47#include <kstandarddirs.h>
48#include <klocale.h>
49#include <kiconloader.h>
50#include <krun.h>
51
52#include "acctselect.h"
53#include "pppdata.h"
54
55
56AccountingSelector::AccountingSelector(QWidget *parent, bool _isnewaccount, const char *name)
57 : QWidget(parent),
58 isnewaccount(_isnewaccount)
59{
60 setObjectName(name);
61
62 QVBoxLayout *l1 = new QVBoxLayout(parent);
63 l1->setSpacing(KDialog::spacingHint());
64 l1->setMargin(0);
65
66 enable_accounting = new QCheckBox(i18n("&Enable accounting"), parent);
67 l1->addWidget(enable_accounting, 1);
68 connect(enable_accounting, SIGNAL(toggled(bool)), this, SLOT(enableItems(bool)));
69
70 // insert the tree widget
71 tl = new Q3ListView(parent, "treewidget");
72
73 connect(tl, SIGNAL(selectionChanged(Q3ListViewItem*)), this,
74 SLOT(slotSelectionChanged(Q3ListViewItem*)));
75 tl->setMinimumSize(220, 200);
76 l1->addWidget(tl, 1);
77
78 KUrlLabel *up = new KUrlLabel(parent);
79 up->setText(i18n("Check for rule updates"));
80 up->setUrl("http://developer.kde.org/~kppp/rules.html");
81 connect(up, SIGNAL(leftClickedUrl(QString)), SLOT(openUrl(QString)));
82
83 l1->addWidget(up, 1);
84
85 // label to display the currently selected ruleset
86 QHBoxLayout *l11 = new QHBoxLayout;
87 l1->addSpacing(10);
88 l1->addLayout(l11);
89 QLabel *lsel = new QLabel(i18n("Selected:"), parent);
90 selected = new QLabel(parent);
91 selected->setFrameStyle(QFrame::Sunken | QFrame::WinPanel);
92 selected->setLineWidth(1);
93 selected->setFixedHeight(selected->sizeHint().height() + 16);
94 l11->addWidget(lsel, 0);
95 l11->addSpacing(10);
96 l11->addWidget(selected, 1);
97
98 // volume accounting
99 l1->addStretch(1);
100 QHBoxLayout *l12 = new QHBoxLayout;
101 l1->addLayout(l12);
102 QLabel *usevol_l = new QLabel(i18n("Volume accounting:"), parent);
103 use_vol = new QComboBox(parent);
104 use_vol->insertItem(0, i18n("No Accounting"));
105 use_vol->insertItem(1, i18n("Bytes In"));
106 use_vol->insertItem(2, i18n("Bytes Out"));
107 use_vol->insertItem(3, i18n("Bytes In & Out"));
108 use_vol->setCurrentIndex(gpppdata.VolAcctEnabled());
109 l12->addWidget(usevol_l);
110 l12->addWidget(use_vol);
111
112 // load the pmfolder pixmap from KDEdir
113 pmfolder = UserIcon("folder");
114
115 // scale the pixmap
116 if(pmfolder.width() > 0) {
117 QMatrix wm;
118 wm.scale(16.0/pmfolder.width(), 16.0/pmfolder.width());
119 pmfolder = pmfolder.transformed(wm);
120 }
121
122 // load the pmfolder pixmap from KDEdir
123 pmfile = UserIcon("phone");
124
125 // scale the pixmap
126 if(pmfile.width() > 0) {
127 QMatrix wm;
128 wm.scale(16.0/pmfile.width(), 16.0/pmfile.width());
129 pmfile = pmfile.transformed(wm);
130 }
131
132 enable_accounting->setChecked(gpppdata.AcctEnabled());
133
134 setupTreeWidget();
135
136 l1->activate();
137}
138
139
140QString AccountingSelector::fileNameToName(QString s) {
141
142 s.replace('_', " ");
143 return KUrl::decode_string(s);
144
145}
146
147
148QString AccountingSelector::nameToFileName(QString s) {
149
150 s.replace(' ', "_");
151 return s;
152
153}
154
155Q3ListViewItem *AccountingSelector::findByName(QString name)
156{
157 Q3ListViewItem *ch = tl->firstChild();
158 while(ch) {
159 if(ch->text(0) == name)
160 return ch;
161 ch = ch->nextSibling();
162 }
163 return 0;
164}
165
166
167void AccountingSelector::insertDir(QDir d, Q3ListViewItem *root) {
168
169 Q3ListViewItem* tli = 0;
170
171 // sanity check
172 if(!d.exists() || !d.isReadable())
173 return;
174
175
176 // set up filter
177 QStringList filters;
178 filters << "*.rst";
179 d.setNameFilters(filters);
180 d.setFilter(QDir::Files);
181 d.setSorting(QDir::Name);
182
183 // read the list of files
184 const QFileInfoList list = d.entryInfoList();
185 QFileInfoList::const_iterator it = list.begin();
186 QFileInfoList::const_iterator itEnd = list.end();
187 QFileInfo fi;
188
189 // traverse the list and insert into the widget
190 while(it != itEnd) {
191 fi = *it;
192
193 QString samename = fi.fileName();
194
195 Q3ListViewItem *i = findByName(samename);
196
197 // skip this file if already in tree
198 if(i)
199 continue;
200
201 // check if this is the file we should mark
202 QString name = fileNameToName(fi.completeBaseName());
203 if(root)
204 tli = new Q3ListViewItem(root, name);
205 else
206 tli = new Q3ListViewItem(tl, name);
207
208 tli->setPixmap(0, pmfile);
209
210 // check if this is the item we are searching for
211 // (only in "Edit"-mode, not in "New"-mode
212 if(!isnewaccount && !edit_s.isEmpty() &&
213 (edit_s == QString(fi.filePath()).right(edit_s.length()))) {
214 edit_item = tli;
215 }
216 ++it;
217 }
218
219 // set up a filter for the directories
220 d.setFilter(QDir::Dirs);
221 filters.clear();
222 filters << "*";
223 d.setNameFilters(filters);
224 const QFileInfoList dlist = d.entryInfoList();
225 QFileInfoList::const_iterator dit= dlist.begin();
226 QFileInfoList::const_iterator ditEnd = dlist.end();
227
228 while(dit != ditEnd) {
229 fi = *dit;
230 // skip "." and ".." directories
231 if(fi.fileName().left(1) != ".") {
232 // convert to human-readable name
233 QString name = fileNameToName(fi.fileName());
234
235 // if the tree already has an item with this name,
236 // skip creation and use this one, otherwise
237 // create a new entry
238 Q3ListViewItem *i = findByName(name);
239 if(!i) {
240 Q3ListViewItem* item;
241
242 if(root)
243 item = new Q3ListViewItem(root, name);
244 else
245 item = new Q3ListViewItem(tl, name);
246
247 item->setPixmap(0, pmfolder);
248
249 insertDir(QDir(fi.filePath()), item);
250 } else
251 insertDir(QDir(fi.filePath()), i);
252 }
253 ++dit;
254 }
255}
256
257
258void AccountingSelector::setupTreeWidget() {
259 // search the item
260 edit_item = 0;
261 if(!isnewaccount) {
262 edit_s = gpppdata.accountingFile();
263 }
264 else
265 edit_s = "";
266
267 tl->addColumn( i18n("Available Rules") );
268 tl->setColumnWidth(0, 205);
269 tl->setRootIsDecorated(true);
270
271 // look in ~/.kde/share/apps/kppp/Rules and $KDEDIR/share/apps/kppp/Rules
272 const QStringList dirs = KGlobal::dirs()->resourceDirs("appdata");
273 for (QStringList::ConstIterator it = dirs.constBegin();
274 it != dirs.constEnd(); it++) {
275 insertDir(QDir((*it) + "Rules"), 0);
276 }
277
278 // when mode is "Edit", then hightlight the
279 // appropriate item
280 if(!isnewaccount && edit_item) {
281 tl->setSelected(edit_item, true);
282 tl->setOpen(edit_item->parent(), true);
283 tl->ensureItemVisible(edit_item);
284 }
285
286 enableItems(enable_accounting->isChecked());
287}
288
289
290void AccountingSelector::enableItems(bool enabled) {
291
292 tl->setEnabled(enabled);
293
294 if(!enabled || (!tl->currentItem()))
295 selected->setText(i18n("(none)"));
296 else {
297 Q3ListViewItem* i = tl->currentItem();
298 QString s;
299 while(i) {
300 s = '/' + i->text(0) + s;
301 i = i->parent();
302 }
303 selected->setText(s.mid(1));
304
305 s += ".rst";
306 edit_s = nameToFileName(s);
307 }
308}
309
310
311void AccountingSelector::slotSelectionChanged(Q3ListViewItem* i) {
312
313 if(!i || i->childCount())
314 return;
315
316 if(!enable_accounting->isChecked())
317 return;
318
319 enableItems(true);
320}
321
322
323bool AccountingSelector::save() {
324
325 if(enable_accounting->isChecked()) {
326 gpppdata.setAccountingFile(edit_s);
327 gpppdata.setAcctEnabled(true);
328 } else {
329 gpppdata.setAccountingFile("");
330 gpppdata.setAcctEnabled(false);
331 }
332
333 gpppdata.setVolAcctEnabled(use_vol->currentIndex());
334
335 return true;
336}
337
338void AccountingSelector::openUrl(const QString &url) {
339 new KRun( KUrl( url ),this);
340}
341
342#include "acctselect.moc"
343
344