Diffstat (limited to 'noncore/unsupported/oipkg/packagemanager.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/oipkg/packagemanager.cpp | 897 |
1 files changed, 0 insertions, 897 deletions
diff --git a/noncore/unsupported/oipkg/packagemanager.cpp b/noncore/unsupported/oipkg/packagemanager.cpp deleted file mode 100644 index 642eae9..0000000 --- a/noncore/unsupported/oipkg/packagemanager.cpp +++ b/dev/null | |||
@@ -1,897 +0,0 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #include "packagemanager.h" | ||
21 | #include "pkdesc.h" | ||
22 | #include "pkfind.h" | ||
23 | #include "pksettings.h" | ||
24 | |||
25 | #include <qpe/process.h> | ||
26 | #include <qpe/resource.h> | ||
27 | #include <qpe/stringutil.h> | ||
28 | #include <qpe/qpeapplication.h> | ||
29 | #include <qpe/qcopenvelope_qws.h> | ||
30 | #include <qpe/applnk.h> | ||
31 | |||
32 | #include <qprogressbar.h> | ||
33 | #include <qcombobox.h> | ||
34 | #include <qdict.h> | ||
35 | #include <qfile.h> | ||
36 | #include <qlineedit.h> | ||
37 | #include <qpushbutton.h> | ||
38 | #include <qlistview.h> | ||
39 | #include <qlistbox.h> | ||
40 | #include <qmessagebox.h> | ||
41 | #include <qpainter.h> | ||
42 | #include <qpixmap.h> | ||
43 | #include <qregexp.h> | ||
44 | #include <qtextstream.h> | ||
45 | #include <qtextview.h> | ||
46 | #include <qtoolbutton.h> | ||
47 | |||
48 | #include <stdlib.h> | ||
49 | |||
50 | static QPixmap *pm_uninstalled=0; | ||
51 | static QPixmap *pm_installed=0; | ||
52 | static QPixmap *pm_uninstall=0; | ||
53 | static QPixmap *pm_install=0; | ||
54 | |||
55 | |||
56 | class PackageItem : public QCheckListItem { | ||
57 | bool installed; | ||
58 | public: | ||
59 | PackageItem(QListView* lv, const QString& name, const QString& desc, const QString& size, bool inst ) : | ||
60 | QCheckListItem(lv,name,CheckBox), installed(inst) | ||
61 | { | ||
62 | setText(1,desc); | ||
63 | setText(2,size); | ||
64 | } | ||
65 | |||
66 | void paintCell( QPainter *p, const QColorGroup & cg, | ||
67 | int column, int width, int alignment ) | ||
68 | { | ||
69 | if ( !p ) | ||
70 | return; | ||
71 | |||
72 | p->fillRect( 0, 0, width, height(), | ||
73 | isSelected()? cg.highlight() : cg.base() ); | ||
74 | |||
75 | if ( column != 0 ) { | ||
76 | // The rest is text | ||
77 | QListViewItem::paintCell( p, cg, column, width, alignment ); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | QListView *lv = listView(); | ||
82 | if ( !lv ) | ||
83 | return; | ||
84 | int marg = lv->itemMargin(); | ||
85 | int r = marg; | ||
86 | |||
87 | QPixmap pm = statePixmap(); | ||
88 | p->drawPixmap(marg,(height()-pm.height())/2,pm); | ||
89 | r += pm.width()+1; | ||
90 | |||
91 | p->translate( r, 0 ); | ||
92 | QListViewItem::paintCell( p, cg, column, width - r, alignment ); | ||
93 | } | ||
94 | |||
95 | void paintFocus( QPainter *p, const QColorGroup & cg, | ||
96 | const QRect & r ) | ||
97 | { | ||
98 | // Skip QCheckListItem | ||
99 | // (makes you wonder what we're getting from QCheckListItem) | ||
100 | QListViewItem::paintFocus(p,cg,r); | ||
101 | } | ||
102 | |||
103 | QPixmap statePixmap() const | ||
104 | { | ||
105 | if ( !isOn() ) { | ||
106 | if ( !installed ) | ||
107 | return *pm_uninstalled; | ||
108 | else | ||
109 | return *pm_installed; | ||
110 | } else { | ||
111 | if ( !installed ) | ||
112 | return *pm_install; | ||
113 | else | ||
114 | return *pm_uninstall; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | QString name() const { return text(0); } | ||
119 | QString description() const { return text(1); } | ||
120 | bool isInstalled() const { return installed; } | ||
121 | |||
122 | QString key( int column, bool ascending ) const | ||
123 | { | ||
124 | if ( column == 2 ) { | ||
125 | QString t = text(2); | ||
126 | double bytes=t.toDouble(); | ||
127 | if ( t.contains('M') ) bytes*=1024*1024; | ||
128 | else if ( t.contains('K') || t.contains('k') ) bytes*=1024; | ||
129 | if ( !ascending ) bytes=999999999-bytes; | ||
130 | return QString().sprintf("%09d",(int)bytes); | ||
131 | } else { | ||
132 | return QListViewItem::key(column,ascending); | ||
133 | } | ||
134 | } | ||
135 | }; | ||
136 | |||
137 | /* | ||
138 | * Constructs a PackageManager which is a child of 'parent', with the | ||
139 | * name 'name' and widget flags set to 'f' | ||
140 | */ | ||
141 | PackageManager::PackageManager( QWidget* parent, const char* name, WFlags fl ) | ||
142 | : PackageManagerBase( parent, name, fl ) | ||
143 | { | ||
144 | settings = new PackageManagerSettings(this,0,TRUE); | ||
145 | connect( settings->newserver, SIGNAL(clicked()), this, SLOT(newServer()) ); | ||
146 | connect( settings->removeserver, SIGNAL(clicked()), this, SLOT(removeServer()) ); | ||
147 | connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) ); | ||
148 | connect( doit, SIGNAL(clicked()), this, SLOT(doIt()) ); | ||
149 | settings->servername->setEnabled(FALSE); | ||
150 | settings->serverurl->setEnabled(FALSE); | ||
151 | serverurl.setAutoDelete(TRUE); | ||
152 | |||
153 | if (!pm_uninstalled) { | ||
154 | pm_uninstalled = new QPixmap(Resource::loadPixmap("uninstalled")); | ||
155 | pm_installed = new QPixmap(Resource::loadPixmap("installed")); | ||
156 | pm_install = new QPixmap(Resource::loadPixmap("install")); | ||
157 | pm_uninstall = new QPixmap(Resource::loadPixmap("uninstall")); | ||
158 | } | ||
159 | |||
160 | QFontMetrics fm = fontMetrics(); | ||
161 | int w0 = fm.width(PackageManagerBase::tr("Package"))+30; | ||
162 | int w2 = fm.width("00000")+4; | ||
163 | list->setColumnWidth(0,w0); | ||
164 | list->setColumnWidth(1,228-w2-w0); // ### screen-biased | ||
165 | list->setColumnWidth(2,w2); | ||
166 | list->setColumnWidthMode(0,QListView::Manual); | ||
167 | list->setColumnWidthMode(1,QListView::Manual); | ||
168 | list->setColumnWidthMode(2,QListView::Manual); | ||
169 | list->setSelectionMode( QListView::Multi ); | ||
170 | details = 0; | ||
171 | ipkg_old = 0; | ||
172 | readSettings(); | ||
173 | updatePackageList(); | ||
174 | progress->hide(); | ||
175 | } | ||
176 | |||
177 | |||
178 | /* | ||
179 | * Destroys the object and frees any allocated resources | ||
180 | */ | ||
181 | PackageManager::~PackageManager() | ||
182 | { | ||
183 | // no need to delete child widgets, Qt does it all for us | ||
184 | } | ||
185 | |||
186 | void PackageManager::newServer() | ||
187 | { | ||
188 | int i = settings->servers->count(); | ||
189 | if ( settings->servername->isEnabled() || settings->serverurl->text().isEmpty() ) { | ||
190 | serverurl.insert(i,new QString("http://")); | ||
191 | settings->servers->insertItem(tr("New")); | ||
192 | } else { | ||
193 | // allows one-level undo | ||
194 | serverurl.insert(i,new QString(settings->serverurl->text())); | ||
195 | settings->servers->insertItem(settings->servername->text()); | ||
196 | } | ||
197 | settings->servers->setSelected(i,TRUE); | ||
198 | editServer(i); | ||
199 | } | ||
200 | |||
201 | void PackageManager::editServer(int i) | ||
202 | { | ||
203 | if ( settings->servername->isEnabled() ) { | ||
204 | disconnect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) ); | ||
205 | disconnect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) ); | ||
206 | } else { | ||
207 | settings->servername->setEnabled(TRUE); | ||
208 | settings->serverurl->setEnabled(TRUE); | ||
209 | } | ||
210 | |||
211 | settings->servername->setText( settings->servers->text(i) ); | ||
212 | settings->serverurl->setText( *serverurl[i] ); | ||
213 | |||
214 | editedserver = i; | ||
215 | |||
216 | connect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) ); | ||
217 | connect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) ); | ||
218 | } | ||
219 | |||
220 | void PackageManager::removeServer() | ||
221 | { | ||
222 | disconnect( settings->servername, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)) ); | ||
223 | disconnect( settings->serverurl, SIGNAL(textChanged(const QString&)), this, SLOT(urlChanged(const QString&)) ); | ||
224 | settings->servername->setText(settings->servers->text(editedserver)); | ||
225 | settings->serverurl->setText(*serverurl[editedserver]); | ||
226 | disconnect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) ); | ||
227 | settings->servers->removeItem(editedserver); | ||
228 | connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) ); | ||
229 | settings->servername->setEnabled(FALSE); | ||
230 | settings->serverurl->setEnabled(FALSE); | ||
231 | } | ||
232 | |||
233 | void PackageManager::nameChanged(const QString& t) | ||
234 | { | ||
235 | disconnect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) ); | ||
236 | settings->servers->changeItem( t, editedserver ); | ||
237 | connect( settings->servers, SIGNAL(highlighted(int)), this, SLOT(editServer(int)) ); | ||
238 | } | ||
239 | |||
240 | void PackageManager::urlChanged(const QString& t) | ||
241 | { | ||
242 | serverurl.replace(editedserver, new QString(t)); | ||
243 | } | ||
244 | |||
245 | static void selectComboItem(QComboBox *cb, const QString s) | ||
246 | { | ||
247 | for (int i=0; i<cb->count(); i++) { | ||
248 | if ( cb->text(i) == s ) { | ||
249 | cb->setCurrentItem(i); | ||
250 | return; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | |||
255 | void PackageManager::updatePackageList() | ||
256 | { | ||
257 | disconnect(section,SIGNAL(activated(int)),this,SLOT(updatePackageList())); | ||
258 | disconnect(subsection,SIGNAL(activated(int)),this,SLOT(updatePackageList())); | ||
259 | |||
260 | list->clear(); | ||
261 | QString cursection = section->currentText(); | ||
262 | QString cursubsection = subsection->currentText(); | ||
263 | QString all=tr("All"); | ||
264 | if ( cursection == all ) cursection=QString::null; | ||
265 | if ( cursubsection == all ) cursubsection=QString::null; | ||
266 | section->clear(); | ||
267 | subsection->clear(); | ||
268 | |||
269 | QDict<void> sections; | ||
270 | QDict<void> subsections; | ||
271 | QDict<void> installed; | ||
272 | |||
273 | QRegExp separatorRegExp( ":[\t ]+" ); | ||
274 | |||
275 | QString status = ipkgStatusOutput(); | ||
276 | if ( !status.isEmpty() ) { | ||
277 | QStringList lines = QStringList::split('\n',status,TRUE); | ||
278 | QString name; | ||
279 | QString status; | ||
280 | for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) { | ||
281 | QString line = *it; | ||
282 | if ( line.length()<=1 ) { | ||
283 | // EOR | ||
284 | if ( !name.isEmpty() ) { | ||
285 | if ( status.contains(" installed") ) | ||
286 | installed.replace(name,(void*)1); | ||
287 | name=""; | ||
288 | } | ||
289 | status=""; | ||
290 | } else if ( line[0] == ' ' || line[0] == '\t' ) { | ||
291 | // continuation | ||
292 | } else { | ||
293 | int sep = line.find(separatorRegExp); | ||
294 | if ( sep >= 0 ) { | ||
295 | QString tag = line.left(sep); | ||
296 | if ( tag == "Package" ) { | ||
297 | name = line.mid(sep+2).simplifyWhiteSpace(); | ||
298 | } else if ( tag == "Status" ) { | ||
299 | status = line.mid(sep+1); | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | |||
306 | QString info = ipkgInfoOutput(); | ||
307 | if ( !info.isEmpty() ) { | ||
308 | QStringList lines = QStringList::split('\n',info,TRUE); | ||
309 | QString description_short; | ||
310 | QString name; | ||
311 | QString size; | ||
312 | QString sec; | ||
313 | for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) { | ||
314 | QString line = *it; | ||
315 | if ( line.length()<=1 ) { | ||
316 | // EOR | ||
317 | if ( !name.isEmpty() ) { | ||
318 | int sl = sec.find('/'); | ||
319 | QString s = sl < 0 ? sec : sec.left(sl); | ||
320 | QString ss = sl < 0 ? QString::null : sec.mid(sl+1); | ||
321 | sections.replace(s,(void*)1); | ||
322 | if ( cursection.isNull() | ||
323 | || cursection == s | ||
324 | && (cursubsection.isNull() || cursubsection == ss) ) | ||
325 | { | ||
326 | if ( !cursection.isNull() && !ss.isNull() ) | ||
327 | subsections.replace(ss,(void*)1); | ||
328 | description_short[0] = description_short[0].upper(); | ||
329 | if ( description_short.left(4) == "The " ) | ||
330 | description_short = description_short.mid(4); | ||
331 | if ( description_short.left(2) == "A " ) | ||
332 | description_short = description_short.mid(2); | ||
333 | description_short[0] = description_short[0].upper(); | ||
334 | new PackageItem(list,name,description_short,size, | ||
335 | installed.find(name)); | ||
336 | } | ||
337 | installed.remove( name ); | ||
338 | } | ||
339 | name=""; | ||
340 | size=""; | ||
341 | sec="main"; | ||
342 | } else if ( line[0] == ' ' || line[0] == '\t' ) { | ||
343 | // continuation | ||
344 | } else { | ||
345 | int sep = line.find(separatorRegExp); | ||
346 | if ( sep >= 0 ) { | ||
347 | QString tag = line.left(sep); | ||
348 | if ( tag == "Package" ) { | ||
349 | name = line.mid(sep+2).simplifyWhiteSpace(); | ||
350 | } else if ( tag == "Description" ) { | ||
351 | description_short = line.mid(sep+2).simplifyWhiteSpace(); | ||
352 | } else if ( tag == "Installed-Size" ) { | ||
353 | size = line.mid(sep+2).simplifyWhiteSpace(); | ||
354 | } else if ( tag == "Section" ) { | ||
355 | sec = line.mid(sep+2).simplifyWhiteSpace(); | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | if ( installed.count() && cursection.isNull() ) { | ||
361 | // we have some packages without description | ||
362 | QDictIterator<void> it( installed ); | ||
363 | for( ; it.current(); ++it ) | ||
364 | new PackageItem( list, it.currentKey(), "", "?" , TRUE ); | ||
365 | } | ||
366 | |||
367 | QStringList s; | ||
368 | QDictIterator<void> it( sections ); | ||
369 | for( ; it.current(); ++it ) | ||
370 | s.append(it.currentKey()); | ||
371 | s.sort(); | ||
372 | section->insertItem(all); | ||
373 | section->insertStringList(s); | ||
374 | selectComboItem(section,cursection.isNull()?all:cursection); | ||
375 | if ( cursection.isNull() ) { | ||
376 | subsection->setEnabled(FALSE); | ||
377 | } else { | ||
378 | subsection->setEnabled(TRUE); | ||
379 | QStringList s; | ||
380 | QDictIterator<void> it( subsections ); | ||
381 | for( ; it.current(); ++it ) | ||
382 | s.append(it.currentKey()); | ||
383 | s.sort(); | ||
384 | subsection->insertItem(all); | ||
385 | subsection->insertStringList(s); | ||
386 | selectComboItem(subsection,cursubsection.isNull()?all:cursubsection); | ||
387 | } | ||
388 | } else { | ||
389 | new QListViewItem(list,"ERROR"); | ||
390 | } | ||
391 | |||
392 | connect(section,SIGNAL(activated(int)),SLOT(updatePackageList())); | ||
393 | connect(subsection,SIGNAL(activated(int)),this,SLOT(updatePackageList())); | ||
394 | } | ||
395 | |||
396 | PackageItem* PackageManager::current() const | ||
397 | { | ||
398 | return (PackageItem*)list->currentItem(); | ||
399 | } | ||
400 | |||
401 | /* | ||
402 | * public slot | ||
403 | */ | ||
404 | void PackageManager::doCurrentDetails(bool multi) | ||
405 | { | ||
406 | PackageItem* pit = current(); | ||
407 | if ( pit ) { | ||
408 | if ( !details ) { | ||
409 | details = new PackageDetails; | ||
410 | connect( details->install, SIGNAL(clicked()), | ||
411 | this, SLOT(installCurrent())); | ||
412 | connect( details->remove, SIGNAL(clicked()), | ||
413 | this, SLOT(removeCurrent())); | ||
414 | details->description->setTextFormat(RichText); | ||
415 | } | ||
416 | if ( multi ) { | ||
417 | disconnect( details->ignore, SIGNAL(clicked()), | ||
418 | details, SLOT(close())); | ||
419 | connect( details->ignore, SIGNAL(clicked()), | ||
420 | this, SLOT(doNextDetails())); | ||
421 | } else { | ||
422 | disconnect( details->ignore, SIGNAL(clicked()), | ||
423 | this, SLOT(doNextDetails())); | ||
424 | connect( details->ignore, SIGNAL(clicked()), | ||
425 | details, SLOT(close())); | ||
426 | } | ||
427 | pit->setSelected(FALSE); | ||
428 | details->setCaption("Package: " + pit->name()); | ||
429 | details->description->setText(fullDetails(pit->name())); | ||
430 | details->install->setEnabled(!pit->isInstalled()); | ||
431 | details->remove->setEnabled(pit->isInstalled()); | ||
432 | details->showMaximized(); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | void PackageManager::doDetails() | ||
437 | { | ||
438 | doCurrentDetails(FALSE); | ||
439 | } | ||
440 | |||
441 | void PackageManager::doNextDetails() | ||
442 | { | ||
443 | QListViewItem* i = list->firstChild(); | ||
444 | for ( ; i; i = i->nextSibling() ) { | ||
445 | if ( i->isSelected() ) | ||
446 | break; | ||
447 | } | ||
448 | list->setCurrentItem(i); | ||
449 | if ( i ) { | ||
450 | doCurrentDetails(TRUE); | ||
451 | } else if ( details ) | ||
452 | details->close(); | ||
453 | } | ||
454 | |||
455 | QString PackageManager::fullDetails(const QString& pk) | ||
456 | { | ||
457 | QString status; | ||
458 | Process ipkg_status(QStringList() << "ipkg" << "info" << pk); | ||
459 | if ( ipkg_status.exec("",status) ) { | ||
460 | QStringList lines = QStringList::split('\n',status,TRUE); | ||
461 | QString description; | ||
462 | for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) { | ||
463 | QString line = *it; | ||
464 | if ( line == " ." ) { | ||
465 | description.append("<p>"); | ||
466 | } else if ( line[0] == ' ' || line[0] == '\t' ) { | ||
467 | // continuation | ||
468 | description.append(" "); | ||
469 | description.append(Qtopia::escapeString(line)); | ||
470 | } else { | ||
471 | int sep = line.find(QRegExp(":[\t ]+")); | ||
472 | if ( sep >= 0 ) { | ||
473 | QString tag = line.left(sep); | ||
474 | description.append("<br>"); | ||
475 | description.append("<b>"); | ||
476 | description.append(Qtopia::escapeString(tag)); | ||
477 | description.append(":</b> "); | ||
478 | description.append(Qtopia::escapeString(line.mid(sep+2))); | ||
479 | } else { | ||
480 | description.append(" "); | ||
481 | description.append(Qtopia::escapeString(line)); | ||
482 | } | ||
483 | } | ||
484 | } | ||
485 | return description; | ||
486 | } | ||
487 | |||
488 | return QString::null; | ||
489 | } | ||
490 | |||
491 | void PackageManager::installCurrent() | ||
492 | { | ||
493 | current()->setOn(TRUE); | ||
494 | details->close(); | ||
495 | } | ||
496 | |||
497 | void PackageManager::removeCurrent() | ||
498 | { | ||
499 | current()->setOn(TRUE); | ||
500 | details->close(); | ||
501 | } | ||
502 | |||
503 | bool PackageManager::readIpkgConfig(const QString& conffile) | ||
504 | { | ||
505 | QFile conf(conffile); | ||
506 | if ( conf.open(IO_ReadOnly) ) { | ||
507 | QTextStream s(&conf); | ||
508 | settings->servers->clear(); | ||
509 | serverurl.clear(); | ||
510 | ipkg_old=0; | ||
511 | int currentserver=0; | ||
512 | while ( !s.atEnd() ) { | ||
513 | QString l = s.readLine(); | ||
514 | QStringList token = QStringList::split(' ', l); | ||
515 | if ( token[0] == "src" || token[0] == "#src" ) { | ||
516 | currentserver=settings->servers->count(); | ||
517 | serverurl.insert(settings->servers->count(),new QString(token[2])); | ||
518 | int a = token[0] == "src" ? 1 : 0; | ||
519 | int i = settings->servers->count(); | ||
520 | settings->servers->insertItem(token[1]); | ||
521 | settings->servers->setSelected(i,a); | ||
522 | } else if ( token[0] == "dest" ) { | ||
523 | // needs UI | ||
524 | } else if ( token[0] == "option" ) { | ||
525 | // ### somehow need to use the settings from netsetup | ||
526 | // if ( token[1] == "http_proxy" ) | ||
527 | // settings->http->setText(token[2]); | ||
528 | // else if ( token[1] == "ftp_proxy" ) | ||
529 | // settings->ftp->setText(token[2]); | ||
530 | // else if ( token[1] == "proxy_username" ) | ||
531 | // settings->username->setText(token[2]); | ||
532 | // else if ( token[1] == "proxy_password" ) | ||
533 | // settings->password->setText(token[2]); | ||
534 | } else { | ||
535 | // Old style? | ||
536 | int eq = l.find('='); | ||
537 | if ( eq >= 0 ) { | ||
538 | QString v = l.mid(eq+1).stripWhiteSpace(); | ||
539 | if ( v[0] == '"' || v[0] == '\'' ) { | ||
540 | int cl=v.find(v[0],1); | ||
541 | if ( cl >= 0 ) | ||
542 | v = v.mid(1,cl-1); | ||
543 | } | ||
544 | if ( l.left(12) == "IPKG_SOURCE=" ) { | ||
545 | ipkg_old=1; | ||
546 | currentserver=settings->servers->count(); | ||
547 | serverurl.insert(settings->servers->count(),new QString(v)); | ||
548 | settings->servers->insertItem(v); | ||
549 | } else if ( l.left(13) == "#IPKG_SOURCE=" ) { | ||
550 | serverurl.insert(settings->servers->count(),new QString(v)); | ||
551 | settings->servers->insertItem(v); | ||
552 | } else if ( l.left(10) == "IPKG_ROOT=" ) { | ||
553 | // ### no UI | ||
554 | // } else if ( l.left(20) == "IPKG_PROXY_USERNAME=" ) { | ||
555 | // settings->username->setText(v); | ||
556 | // } else if ( l.left(20) == "IPKG_PROXY_PASSWORD=" ) { | ||
557 | // settings->password->setText(v); | ||
558 | // } else if ( l.left(16) == "IPKG_PROXY_HTTP=" ) { | ||
559 | // settings->http->setText(v); | ||
560 | // } else if ( l.left(16) == "IPKG_PROXY_FTP=" ) { | ||
561 | // settings->ftp->setText(v); | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | } | ||
566 | if ( ipkg_old ) { | ||
567 | settings->servers->setSelectionMode(QListBox::Single); | ||
568 | settings->servers->setSelected(currentserver,TRUE); | ||
569 | } | ||
570 | return TRUE; | ||
571 | } else { | ||
572 | return FALSE; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /* | ||
577 | * public slot | ||
578 | */ | ||
579 | void PackageManager::doSettings() | ||
580 | { | ||
581 | settings->showMaximized(); | ||
582 | if ( settings->exec() ) { | ||
583 | writeSettings(); | ||
584 | startRun(); | ||
585 | runIpkg("update"); | ||
586 | endRun(); | ||
587 | updatePackageList(); | ||
588 | } else { | ||
589 | readSettings(); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | void PackageManager::readSettings() | ||
594 | { | ||
595 | // read from config file(s) | ||
596 | readIpkgConfig("/etc/ipkg.conf"); | ||
597 | } | ||
598 | |||
599 | void PackageManager::writeSettings() | ||
600 | { | ||
601 | QFile conf("/etc/ipkg.conf"); | ||
602 | if ( conf.open(IO_WriteOnly) ) { | ||
603 | QTextStream s(&conf); | ||
604 | s << "# Written by Qtopia Package Manager\n"; | ||
605 | if ( !ipkg_old ) { | ||
606 | for (int i=0; i<(int)settings->servers->count(); i++) { | ||
607 | QString url = serverurl[i] ? *serverurl[i] : QString("???"); | ||
608 | // if ( !settings->servers->isSelected(i) ) | ||
609 | // s << "#"; | ||
610 | s << "src " << settings->servers->text(i) << " " << url << "\n"; | ||
611 | } | ||
612 | s << "dest root /\n"; // ### need UI | ||
613 | // if ( !settings->username->text().isEmpty() ) | ||
614 | // s << "option proxy_username " << settings->username->text() << "\n"; | ||
615 | // if ( !settings->password->text().isEmpty() ) | ||
616 | // s << "option proxy_password " << settings->password->text() << "\n"; | ||
617 | // if ( !settings->http->text().isEmpty() ) | ||
618 | // s << "option http_proxy " << settings->http->text() << "\n"; | ||
619 | // if ( !settings->ftp->text().isEmpty() ) | ||
620 | // s << "option ftp_proxy " << settings->ftp->text() << "\n"; | ||
621 | } else { | ||
622 | // Old style | ||
623 | bool src_selected=FALSE; | ||
624 | for (int i=0; i<(int)settings->servers->count(); i++) { | ||
625 | if ( settings->servers->isSelected(i) ) { | ||
626 | src_selected=TRUE; | ||
627 | } else { | ||
628 | s << "#"; | ||
629 | } | ||
630 | s << "IPKG_SOURCE=\"" << settings->servers->text(i) << "\"\n"; | ||
631 | } | ||
632 | if ( !src_selected ) | ||
633 | s << "IPKG_SOURCE=\"" << settings->servers->currentText() << "\"\n"; | ||
634 | s << "IPKG_ROOT=/\n" | ||
635 | // << "IPKG_PROXY_USERNAME=\"" << settings->username->text() << "\"\n" | ||
636 | // << "IPKG_PROXY_PASSWORD=\"" << settings->password->text() << "\"\n" | ||
637 | // << "IPKG_PROXY_HTTP=\"" << settings->http->text() << "\"\n" | ||
638 | // << "IPKG_PROXY_FTP=\"" << settings->ftp->text() << "\"\n" | ||
639 | ; | ||
640 | } | ||
641 | conf.close(); | ||
642 | } | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * public slot | ||
647 | */ | ||
648 | void PackageManager::doFind() | ||
649 | { | ||
650 | Search s(this, 0, TRUE); | ||
651 | if ( s.exec() ) { | ||
652 | QString p = s.pattern->text(); | ||
653 | if ( p.isEmpty() ) { | ||
654 | list->selectAll(FALSE); | ||
655 | } else { | ||
656 | selectPackages(findPackages(p)); | ||
657 | doNextDetails(); | ||
658 | } | ||
659 | } | ||
660 | } | ||
661 | |||
662 | void PackageManager::selectPackages( const QStringList& l ) | ||
663 | { | ||
664 | QDict<void> d; | ||
665 | for (QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) | ||
666 | d.replace(*it,(void*)1); | ||
667 | QListViewItem* i; | ||
668 | for ( i = list->firstChild(); i; i = i->nextSibling() ) { | ||
669 | PackageItem* pit = (PackageItem*)i; | ||
670 | i->setSelected( d[pit->name()] ); | ||
671 | } | ||
672 | } | ||
673 | |||
674 | QStringList PackageManager::findPackages( const QRegExp& r ) | ||
675 | { | ||
676 | QStringList matches; | ||
677 | |||
678 | QString info = ipkgInfoOutput(); | ||
679 | if ( !info.isEmpty() ) { | ||
680 | QStringList lines = QStringList::split('\n',info,TRUE); | ||
681 | QRegExp re = r; | ||
682 | QString description=""; | ||
683 | QString name; | ||
684 | for (QStringList::Iterator it = lines.begin(); it!=lines.end(); ++it) { | ||
685 | QString line = *it; | ||
686 | if ( line.length()<=1 ) { | ||
687 | // EOR | ||
688 | if ( re.match(description) >= 0 ) | ||
689 | matches.append(name); | ||
690 | description=""; | ||
691 | name=""; | ||
692 | } else if ( line[0] == ' ' || line[0] == '\t' ) { | ||
693 | // continuation | ||
694 | description.append(" "); | ||
695 | description.append(Qtopia::escapeString(line)); | ||
696 | } else { | ||
697 | int sep = line.find(QRegExp(":[\t ]+")); | ||
698 | if ( sep >= 0 ) { | ||
699 | QString tag = line.left(sep); | ||
700 | if ( tag == "Package" ) | ||
701 | name = line.mid(sep+2).simplifyWhiteSpace(); | ||
702 | if ( !description.isEmpty() ) | ||
703 | description.append("<br>"); | ||
704 | description.append("<b>"); | ||
705 | description.append(Qtopia::escapeString(tag)); | ||
706 | description.append(":</b> "); | ||
707 | description.append(Qtopia::escapeString(line.mid(sep+2))); | ||
708 | } | ||
709 | } | ||
710 | } | ||
711 | } | ||
712 | |||
713 | return matches; | ||
714 | } | ||
715 | |||
716 | /* | ||
717 | * public slot | ||
718 | */ | ||
719 | void PackageManager::doUpgrade() | ||
720 | { | ||
721 | startMultiRun(2); | ||
722 | runIpkg("update"); | ||
723 | runIpkg("upgrade"); | ||
724 | updatePackageList(); | ||
725 | endRun(); | ||
726 | } | ||
727 | |||
728 | |||
729 | void PackageManager::doIt() | ||
730 | { | ||
731 | bool ok = commitWithIpkg(); | ||
732 | updatePackageList(); // things may have changed | ||
733 | if (!ok) qApp->beep(); | ||
734 | } | ||
735 | |||
736 | bool PackageManager::commitWithIpkg() | ||
737 | { | ||
738 | // A full implementation would do the following, but we'll just do | ||
739 | // it simply and non-interactively for now. | ||
740 | // | ||
741 | // setenv IPKG_CONF_DIR for a null $IPKG_CONF_DIR/ipkg.conf | ||
742 | // setenv IPKG_SOURCE, IPKG_ROOT, etc. | ||
743 | // run ipkg, processing interactivity as dialogs | ||
744 | // - "... (Y/I/N/O/D) [default=N] ?" -> ... | ||
745 | // - "[Press ENTER to continue]" (if D chosen above) | ||
746 | // - "The following packages are marked `Essential'... Install them now [Y/n] ?" | ||
747 | // - "The following packages...ready to be installed:... Install them now [Y/n] ?" | ||
748 | // return FALSE cancelled | ||
749 | |||
750 | QStringList to_remove, to_install; | ||
751 | |||
752 | for ( QListViewItem* i = list->firstChild(); i; i = i->nextSibling() ) { | ||
753 | PackageItem* pit = (PackageItem*)i; | ||
754 | if ( pit->isOn() ) { | ||
755 | if ( pit->isInstalled() ) | ||
756 | to_remove.append(pit->name()); | ||
757 | else | ||
758 | to_install.append(pit->name()); | ||
759 | } | ||
760 | } | ||
761 | |||
762 | bool ok=TRUE; | ||
763 | |||
764 | int jobs = to_remove.count()+to_install.count(); | ||
765 | if ( jobs ) { | ||
766 | startMultiRun(jobs); | ||
767 | |||
768 | if ( to_remove.count() ) { | ||
769 | for (QStringList::ConstIterator it=to_remove.begin(); it!=to_remove.end(); ++it) { | ||
770 | if ( runIpkg("remove " + *it) != 0 ) { | ||
771 | ok = FALSE; | ||
772 | } | ||
773 | } | ||
774 | } | ||
775 | if ( to_install.count() ) { | ||
776 | for (QStringList::ConstIterator it=to_install.begin(); it!=to_install.end(); ++it) { | ||
777 | if ( runIpkg("install " + *it) != 0 ) { | ||
778 | ok = FALSE; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | |||
783 | // ##### If we looked in the list of files, we could send out accurate | ||
784 | // ##### messages. But we don't bother yet, and just do an "all". | ||
785 | QCopEnvelope e("QPE/System", "linkChanged(QString)"); | ||
786 | QString lf = QString::null; | ||
787 | e << lf; | ||
788 | |||
789 | #if QT_VERSION > 230 // a bug breaks this otherwise | ||
790 | if ( !ok ) | ||
791 | QMessageBox::warning(this, "Error", "<p><tt>ipkg</tt> says something went wrong. Sorry."); | ||
792 | #endif | ||
793 | |||
794 | endRun(); | ||
795 | } | ||
796 | |||
797 | return ok; | ||
798 | } | ||
799 | |||
800 | QString PackageManager::ipkgStatusOutput() | ||
801 | { | ||
802 | if ( cachedIpkgStatusOutput.isEmpty() ) { | ||
803 | Process ipkg_status( QStringList() << "ipkg" << "status" ); | ||
804 | ipkg_status.exec( 0, cachedIpkgStatusOutput ); | ||
805 | } | ||
806 | return QString::fromLocal8Bit( cachedIpkgStatusOutput ); | ||
807 | } | ||
808 | |||
809 | QString PackageManager::ipkgInfoOutput() | ||
810 | { | ||
811 | if ( cachedIpkgInfoOutput.isEmpty() ) { | ||
812 | Process ipkg_info( QStringList() << "ipkg" << "info" ); | ||
813 | ipkg_info.exec( 0, cachedIpkgInfoOutput ); | ||
814 | } | ||
815 | return QString::fromLocal8Bit( cachedIpkgInfoOutput ); | ||
816 | } | ||
817 | |||
818 | void PackageManager::setCachedIpkgOutputDirty() | ||
819 | { | ||
820 | cachedIpkgInfoOutput = cachedIpkgStatusOutput = QString::null; | ||
821 | } | ||
822 | |||
823 | void PackageManager::startMultiRun(int jobs) | ||
824 | { | ||
825 | startRun(); | ||
826 | progress->setTotalSteps(jobs); | ||
827 | progress->setProgress(0); | ||
828 | } | ||
829 | |||
830 | void PackageManager::startRun() | ||
831 | { | ||
832 | progress->show(); | ||
833 | doit->hide(); | ||
834 | } | ||
835 | |||
836 | void PackageManager::endRun() | ||
837 | { | ||
838 | doit->show(); | ||
839 | progress->hide(); | ||
840 | } | ||
841 | |||
842 | int PackageManager::runIpkg(const QString& args) | ||
843 | { | ||
844 | if ( progress->progress() == -1 ) | ||
845 | startMultiRun(1); | ||
846 | else | ||
847 | startRun(); | ||
848 | QString cmd = "ipkg "; | ||
849 | if ( ipkg_old ) | ||
850 | cmd += "</dev/null "; | ||
851 | else | ||
852 | cmd += "-force-defaults "; | ||
853 | int r = system((cmd+args).latin1()); | ||
854 | progress->setProgress(progress->progress()+1); | ||
855 | setCachedIpkgOutputDirty(); | ||
856 | endRun(); | ||
857 | return r; | ||
858 | } | ||
859 | |||
860 | // simple hack to get support for ipkg mimetype | ||
861 | void PackageManager::maybeInstall( const QString &ipk ) | ||
862 | { | ||
863 | int pos = ipk.findRev( "/" ); | ||
864 | QString package = ipk.mid( pos + 1 ); | ||
865 | pos = package.find ( "_" ); | ||
866 | if ( pos != -1 ) | ||
867 | package = package.left( pos ); | ||
868 | switch ( QMessageBox::information( 0, tr( "Install Package" ), | ||
869 | tr("Are you sure you want to\ninstall package\n\n%1") | ||
870 | .arg(package), QMessageBox::Yes, | ||
871 | QMessageBox::No|QMessageBox::Default|QMessageBox::Escape, 0 ) ) { | ||
872 | case QMessageBox::Yes: { | ||
873 | startRun(); | ||
874 | runIpkg("install " + ipk ); | ||
875 | QCopEnvelope e("QPE/System", "linkChanged(QString)"); | ||
876 | QString lf = QString::null; | ||
877 | e << lf; | ||
878 | endRun(); | ||
879 | } | ||
880 | break; | ||
881 | case QMessageBox::No: | ||
882 | default: | ||
883 | // do nothing | ||
884 | break; | ||
885 | } | ||
886 | } | ||
887 | |||
888 | void PackageManager::setDocument(const QString& fileref) | ||
889 | { | ||
890 | if ( fileref.isNull() ) | ||
891 | return; | ||
892 | DocLnk doc( fileref ); | ||
893 | if ( doc.file().isEmpty() ) | ||
894 | return; | ||
895 | maybeInstall( doc.file() ); | ||
896 | updatePackageList(); | ||
897 | } | ||