summaryrefslogtreecommitdiff
path: root/noncore/settings/networksettings2/editconnection.cpp
Unidiff
Diffstat (limited to 'noncore/settings/networksettings2/editconnection.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings2/editconnection.cpp582
1 files changed, 582 insertions, 0 deletions
diff --git a/noncore/settings/networksettings2/editconnection.cpp b/noncore/settings/networksettings2/editconnection.cpp
new file mode 100644
index 0000000..d4b2bb3
--- a/dev/null
+++ b/noncore/settings/networksettings2/editconnection.cpp
@@ -0,0 +1,582 @@
1#include <qlistview.h>
2#include <qwidgetstack.h>
3#include <qframe.h>
4#include <qcombobox.h>
5#include <qtabwidget.h>
6#include <qmessagebox.h>
7#include <qpushbutton.h>
8#include <qlineedit.h>
9#include <qheader.h>
10#include <qpainter.h>
11#include <qcheckbox.h>
12#include <qlabel.h>
13
14#include "editconnection.h"
15#include "resources.h"
16#include "netnode.h"
17
18//
19//
20// THESE TO GIVE BETTER FEEDBACK ABOUT DISABLED ITEMS
21//
22//
23
24class MyQCheckListItem : public QCheckListItem
25{
26public:
27 MyQCheckListItem( QListView *parent, const QString & S, Type T ) :
28 QCheckListItem( parent, S, T ) { }
29 MyQCheckListItem( QCheckListItem *parent, const QString & S, Type T ) :
30 QCheckListItem( parent, S, T ) { }
31 MyQCheckListItem( QListViewItem *parent, const QString & S, Type T ) :
32 QCheckListItem( parent, S, T ) { }
33
34 virtual void paintCell( QPainter *p, const QColorGroup &cg,
35 int column, int width, int alignment );
36
37};
38
39void MyQCheckListItem::paintCell( QPainter *p, const QColorGroup &cg,
40 int column, int width, int alignment )
41{
42 QColorGroup _cg( cg );
43 QColor c = _cg.text();
44 if ( ! isSelectable() )
45 _cg.setColor( QColorGroup::Text, Qt::lightGray );
46 QCheckListItem::paintCell( p, _cg, column, width, alignment );
47 _cg.setColor( QColorGroup::Text, c );
48}
49
50class MyQListViewItem : public QListViewItem
51{
52public:
53 MyQListViewItem( QListView *parent, const QString & S ) :
54 QListViewItem( parent, S ) { }
55 MyQListViewItem( QListViewItem *parent, const QString & S ) :
56 QListViewItem( parent, S ) { }
57
58 virtual void paintCell( QPainter *p, const QColorGroup &cg,
59 int column, int width, int alignment );
60
61};
62
63void MyQListViewItem::paintCell( QPainter *p, const QColorGroup &cg,
64 int column, int width, int alignment )
65{
66 QColorGroup _cg( cg );
67 QColor c = _cg.text();
68 if ( ! isSelectable() )
69 _cg.setColor( QColorGroup::Text, Qt::lightGray );
70 QListViewItem::paintCell( p, _cg, column, width, alignment );
71 _cg.setColor( QColorGroup::Text, c );
72}
73
74//
75//
76// REAL GUI
77//
78//
79
80bool EditConnection::AutoCollapse = 1;
81
82EditConnection::EditConnection( QWidget* parent ) :
83 EditConnectionGUI( parent, 0, TRUE ), TmpCollection() {
84
85 Tab_TB->setTabEnabled( Setup_FRM, FALSE );
86 Setup_FRM->setEnabled( FALSE );
87
88 TmpIsValid = 0;
89 SelectedNodes = 0;
90
91 AutoCollapse_CB->setChecked( AutoCollapse );
92
93 Mapping = new QPtrDict<ANetNode>;
94 Mapping->setAutoDelete( FALSE );
95 Nodes_LV->header()->hide();
96 // popluate tree with all NetNodes
97 buildFullTree();
98}
99
100NodeCollection * EditConnection::getTmpCollection( void ) {
101
102 if( TmpIsValid )
103 // content is stil OK
104 return &(TmpCollection);
105
106 // reset collection -> delete all NEW NetNodes
107 { ANetNodeInstance * NNI;
108 for( QListIterator<ANetNodeInstance> it(TmpCollection);
109 it.current();
110 ++it ) {
111 if( it.current()->isNew() ) {
112 delete it.current();
113 }
114 }
115 TmpCollection.clear();
116 }
117
118 // update content
119 QListViewItem * it = Nodes_LV->firstChild();
120 ANetNode * NN;
121 // start iter
122 ANetNodeInstance * NNI =
123 (SelectedNodes) ? SelectedNodes->first() : 0 ;
124
125 TmpCollection.setModified( 0 );
126
127 while ( it ) {
128 NN = (*Mapping)[it];
129 if( NN == 0 ) {
130 // child is controller -> has sub radio
131 // check if one radio is selected
132 it = it->firstChild();
133 while( it ) {
134 if( ((QCheckListItem *)it)->isOn() ) {
135 // this radio is selected -> go deeper
136 if( SelectedNodes == 0 ||
137 NNI == 0 ||
138 NNI->netNode()->nodeName() != it->text(0) ) {
139 // new item not in previous collection
140 ANetNodeInstance * NNI = (*Mapping)[it]->createInstance();
141 NNI->initialize();
142 // this node type not in collection
143 TmpCollection.append( NNI );
144 // master collection changed because new item in it
145 TmpCollection.setModified( 1 );
146 // no more valid items in old list
147 NNI = 0;
148 } else {
149 // already in list -> copy pointer
150 TmpCollection.append( NNI );
151 NNI = SelectedNodes->next();
152 }
153 it = it->firstChild();
154 // do not bother to check other items
155 break;
156 }
157 it = it->nextSibling();
158 }
159 } else {
160 // check children
161 it = it->firstChild();
162 }
163 }
164
165 TmpIsValid = 1;
166 return &(TmpCollection);
167}
168
169// pass a connection NodeCollection to be edited
170void EditConnection::setConnection( NodeCollection * NC ) {
171 ANetNodeInstance * NNI;
172 ANetNode * NN;
173
174 SelectedNodes = NC;
175 Name_LE->setText( NC->name() );
176 NNI = NC->first();
177
178 // show configure tabl
179 Tab_TB->setCurrentPage( 1 );
180
181 // valid colledction
182 Tab_TB->setTabEnabled( Setup_FRM, FALSE );
183 Setup_FRM->setEnabled( FALSE );
184
185 // select items in collection
186 QListViewItem * it = Nodes_LV->firstChild();
187 bool Found;
188
189 TmpIsValid = 0;
190
191 while ( it ) {
192 // listitem corresponds to netnode
193 NN = (*Mapping)[it];
194 if( NN == 0 ) {
195 // child is controller -> has sub radio
196 QString Ctr = it->text(0);
197 // check if one radio is selected
198 it = it->firstChild();
199 Found = 0;
200 while( it ) {
201 if( NNI && NNI->netNode()->nodeName() == it->text(0) ) {
202 // this radio is part of the collection
203 ((QCheckListItem *)it)->setOn( 1 );
204 updateGUI( it, NNI->netNode() );
205 // check its children
206 Found = 1;
207 it = it->firstChild();
208 NNI = SelectedNodes->next();
209 // do not bother to check other items
210 break;
211 }
212 it = it->nextSibling();
213 }
214 if( ! Found ) {
215 // this means that this level is NOT present in collection
216 // probably INCOMPATIBEL collection OR Missing plugin
217 QMessageBox::warning(
218 0,
219 tr( "Error presentig Connection" ),
220 tr( "<p>Old connection or missing plugin \"<i>%1</i>\"</p>" ).
221 arg(Ctr) );
222 return;
223 }
224 } else {
225 // automatic item -> check children
226 it = it->firstChild();
227 }
228 }
229}
230
231// get result of editing (either new OR updated collection
232NodeCollection * EditConnection::connection( void ) {
233
234 if( SelectedNodes == 0 ) {
235 // new collection
236 SelectedNodes = new NodeCollection;
237 }
238
239 // clean out old entries
240 SelectedNodes->clear();
241
242 // transfer
243 { ANetNodeInstance * NNI;
244
245 for( QListIterator<ANetNodeInstance> it(TmpCollection);
246 it.current();
247 ++it ) {
248 SelectedNodes->append( it.current() );
249 }
250 }
251
252 if( TmpCollection.isModified() )
253 SelectedNodes->setModified( 1 );
254
255 if( SelectedNodes->name() != Name_LE->text() ) {
256 SelectedNodes->setName( Name_LE->text() );
257 SelectedNodes->setModified( 1 );
258 }
259
260 return SelectedNodes;
261}
262
263// Build device tree -> start
264void EditConnection::buildFullTree( void ) {
265 ANetNode * NN;
266
267 // toplevel item
268 MyQCheckListItem * TheTop = new MyQCheckListItem(
269 Nodes_LV,
270 NSResources->netNode2Name("fullsetup"),
271 QCheckListItem::Controller );
272 TheTop->setOpen( TRUE );
273 Description_LBL->setText(
274 NSResources->netNode2Description( "fullsetup" ) );
275 Nodes_LV->setSelected( TheTop, TRUE );
276
277 // find all Nodes that care toplevel nodes -> ie provide
278 // TCP/IP Connection
279 for( QDictIterator<NetNode_t> Iter(NSResources->netNodes());
280 Iter.current();
281 ++Iter ) {
282
283 NN = Iter.current()->NetNode;
284
285 if( ! NN->isToplevel() ) {
286 continue;
287 }
288
289 MyQCheckListItem * it = new MyQCheckListItem( TheTop,
290 NN->nodeName(),
291 QCheckListItem::RadioButton );
292 it->setPixmap( 0, NSResources->getPixmap( "commprofile" ) );
293 // remember that this node maps to this listitem
294 Mapping->insert( it, NN );
295 buildSubTree( it, NN );
296 }
297}
298
299// Build device tree -> help function
300void EditConnection::buildSubTree( QListViewItem * it, ANetNode *NN ) {
301 ANetNode::NetNodeList & NNL = NN->alternatives();
302
303 if( NNL.size() > 1 ) {
304 // this node has alternatives -> needs radio buttons
305 it = new MyQCheckListItem(
306 it,
307 NSResources->netNode2Name(NNL[0]->provides()),
308 QCheckListItem::Controller );
309 it->setSelectable( FALSE );
310 }
311
312 for ( unsigned int i=0; i < NNL.size(); i++ ) {
313 QListViewItem * CI;
314 if( NNL.size() > 1 ) {
315 // generate radio buttons
316 CI = new MyQCheckListItem(
317 (QCheckListItem *)it,
318 NNL[i]->nodeName(), QCheckListItem::RadioButton );
319 // remember that this node maps to this listitem
320 CI->setPixmap( 0, NSResources->getPixmap( NNL[i]->pixmapName() ) );
321 Mapping->insert( CI, NNL[i] );
322 CI->setSelectable( FALSE );
323 } else {
324 // Single item
325 CI = new MyQListViewItem( it, NNL[i]->nodeName() );
326 // remember that this node maps to this listitem
327 Mapping->insert( CI, NNL[i] );
328 CI->setSelectable( FALSE );
329 CI->setPixmap( 0, NSResources->getPixmap( NNL[i]->pixmapName() ) );
330 }
331 buildSubTree( CI, NNL[i] );
332 }
333}
334
335// Clicked ok OK button
336void EditConnection::accept( void ) {
337 if( ! haveCompleteConfig( 0 ) || Name_LE->text().isEmpty() ) {
338 QMessageBox::warning(
339 0,
340 tr( "Closing Connection Setup" ),
341 tr( "Definition not complete or no name" ) );
342 return;
343 }
344
345 // check if all devices have acceptable input
346 getTmpCollection();
347 { ANetNodeInstance * NNI;
348 QString S;
349
350 for( QListIterator<ANetNodeInstance> it(TmpCollection);
351 it.current();
352 ++it ) {
353 NNI = it.current();
354 // widget must show its own problems
355 S = NNI->acceptable();
356 if( ! S.isEmpty() ) {
357 QMessageBox::warning(
358 0,
359 tr( "Cannot save" ),
360 S );
361 return;
362 }
363 NNI->commit();
364
365 if( NNI->isModified() ) {
366 TmpCollection.setModified( 1 );
367 // commit the data
368 }
369 }
370 }
371
372 QDialog::accept();
373}
374
375// triggered by CB
376void EditConnection::SLOT_AutoCollapse( bool b ) {
377 AutoCollapse = b;
378}
379
380// clicked on node in tree -> update GUI
381void EditConnection::SLOT_SelectNode( QListViewItem * it ) {
382 ANetNode * NN;
383 if( it == 0 || it->depth() == 0 ) {
384 Description_LBL->setText(
385 NSResources->netNode2Description( "fullsetup" ) );
386 // topevel or no selection
387 return;
388 }
389
390 // store conversion from lvitem to node
391 NN = (*Mapping)[ it ];
392
393 if( ! NN ) {
394 // intermediate node
395 NN = (*Mapping)[ it->firstChild() ];
396 if( NN ) {
397 // figure out type of this node -> produce mesage
398 Description_LBL->setText( NSResources->netNode2Description(NN->provides()) );
399 } else {
400 Description_LBL->setText( "" );
401 }
402 return;
403 }
404
405 Description_LBL->setText( NN->nodeDescription() );
406
407 if( ! it->isSelectable() ) {
408 return;
409 }
410
411 if( ! ((QCheckListItem *)it)->isOn() ) {
412 // clicked on line but NOT on Check or Radio item
413 return;
414 }
415
416 // item has really changed -> update
417 TmpIsValid = 0;
418 updateGUI( it, NN );
419}
420
421// cliecked on TAB to go to setup
422void EditConnection::SLOT_AlterTab( const QString & S ) {
423 if( S == tr( "Setup" ) && Setup_FRM->isEnabled() ) {
424 // switched to setup -> update CB and populate ws with
425 // forms for devices
426
427 if( ! TmpIsValid ) {
428 getTmpCollection();
429
430 // clear CB and Ws
431 { QWidget * W;
432 int i = 0;
433
434 Devices_CB->clear();
435 while( ( W = Setup_WS->widget( i ) ) ) {
436 Setup_WS->removeWidget( W );
437 i ++;
438 }
439 }
440
441 // update CB
442 // and populate WidgetStack
443 { ANetNodeInstance * NNI;
444 QListIterator<ANetNodeInstance> it(TmpCollection);
445 int i = 0;
446 QWidget * W;
447
448 for ( ; it.current(); ++it ) {
449 NNI = it.current();
450 Devices_CB->insertItem(
451 NSResources->getPixmap( NNI->netNode()->pixmapName() ),
452 NNI->netNode()->nodeName()
453 );
454
455 // add edit widget
456 W = NNI->edit( Setup_WS );
457 if( ! W) {
458 W = new QLabel( Setup_WS,
459 tr("No configuration required"));
460 }
461 Setup_WS->addWidget( W , i );
462 i ++;
463 }
464 }
465 Setup_WS->raiseWidget( 0 );
466 } // still valid
467 }
468}
469
470// update visual feedback of selection state
471void EditConnection::updateGUI( QListViewItem * it, ANetNode * NN ) {
472
473 bool HCC = haveCompleteConfig( it );
474 Tab_TB->setTabEnabled( Setup_FRM, HCC );
475 Setup_FRM->setEnabled( HCC );
476
477 // disable children of all siblings at same level
478 QListViewItem * Sbl = it->parent()->firstChild();
479 while( Sbl ) {
480 if ( Sbl != it ) {
481 disableTree( Sbl->firstChild(), FALSE );
482 Sbl->setSelectable( TRUE );
483 if( AutoCollapse )
484 Sbl->setOpen( FALSE );
485 }
486 Sbl = Sbl->nextSibling();
487 }
488
489 // enable selected path (as deep as it goes
490 it->setOpen( TRUE );
491 enablePath( it->firstChild(),
492 (it->depth()==1) ?
493 1 : // toplevel always alternatives
494 (NN->alternatives().size() > 1) );
495}
496
497void EditConnection::disableTree( QListViewItem * it, bool Mode ) {
498 while( it ) {
499 // disable sbl's chidren
500 it->setSelectable( Mode );
501 if( AutoCollapse )
502 it->setOpen( Mode );
503 disableTree( it->firstChild(), Mode );
504 it = it->nextSibling();
505 }
506}
507
508// pah : ParentHasAlternatives
509void EditConnection::enablePath( QListViewItem * it, bool pha ) {
510 while( it ) {
511 ANetNode * NN;
512 NN = (*Mapping)[it];
513 if( NN ) {
514 if( pha ) {
515 bool doOn = ((QCheckListItem *)it)->isOn();
516 // we are a checklistitem for sure
517 it->setSelectable( TRUE );
518 if( AutoCollapse && ! doOn )
519 it->setOpen( doOn );
520 if( doOn ) {
521 // selected alternative
522 enablePath( it->firstChild(),
523 NN->alternatives().size() > 1);
524 } else {
525 // non-selected alternative
526 disableTree( it->firstChild(), FALSE);
527 }
528 } else {
529 // we are single subitem
530 it->setSelectable( TRUE );
531 it->setOpen( TRUE );
532 enablePath( it->firstChild(),
533 NN->alternatives().size() > 1);
534 }
535 } else {
536 // controller node
537 it->setSelectable( TRUE );
538 it->setOpen( TRUE );
539 enablePath( it->firstChild(), pha );
540 }
541 it = it->nextSibling();
542 }
543}
544
545// do we have a complete configuration (all needs are provided for ?)
546bool EditConnection::haveCompleteConfig( QListViewItem * it ) {
547 if( it == 0 || ((QCheckListItem *)it)->isOn() ) {
548 // check children
549 it = (it) ? it->firstChild() : Nodes_LV->firstChild() ;
550 while ( it ) {
551 if( ((QCheckListItem *)it)->type() ==
552 QCheckListItem::Controller ) {
553 // child is controller -> has sub radio
554 // check if one radio is selected
555 it = it->firstChild();
556 while( it ) {
557 if( ((QCheckListItem *)it)->isOn() ) {
558 // this radio is selected -> go deeper
559 it = it->firstChild();
560 if( ! it ) {
561 // was deepest level
562 return 1;
563 }
564 // do not bother to check other items
565 break;
566 }
567 it = it->nextSibling();
568 }
569 if( ! it ) {
570 // no radio selected
571 return 0;
572 }
573 } else {
574 // check children
575 it = it->firstChild();
576 }
577 }
578 // deepest level -> all is still OK
579 return 1;
580 } // was not ON
581 return 0;
582}