]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgConflictList.cc
Duncan, for you
[duncan/yast2-qt4.git] / src / pkg / YQPkgConflictList.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPkgConflictList.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19 /-*/
20
21
22 #include <qpainter.h>
23 #include <qpixmap.h>
24 #include <qdatetime.h>
25 #include <qmessagebox.h>
26 //Added by qt3to4:
27 #include <q3valuelist.h>
28
29 #include <errno.h>
30
31 #define y2log_component "qt-pkg"
32 #include <ycp/y2log.h>
33
34 #include <zypp/ZYppFactory.h>
35 #include "YQPkgConflictList.h"
36 #include "YQPkgConflictDialog.h"
37 #include "YQIconPool.h"
38
39 #include "YQApplication.h"
40 #include "YQUI.h"
41 #include "YQi18n.h"
42 #include "utf8.h"
43
44 using std::list;
45 using std::string;
46
47
48 #define LIST_SPLIT_THRESHOLD    8
49
50 #define RED                     QColor( 0xC0, 0, 0 )
51 #define BRIGHT_RED              QColor( 0xFF, 0, 0 )
52 #define BLUE                    QColor( 0, 0, 0xC0 )
53 #define LIGHT_BLUE              QColor( 0xE0, 0xE0, 0xF8 )
54 #define LIGHT_GREY              QColor( 0xE0, 0xE0, 0xE0 )
55 #define MAGENTA                 Qt::magenta
56 #define DEEP_ORANGE             QColor( 0xFF, 0x80, 0x20 )
57 #define LIGHT_ORANGE            QColor( 0xFF, 0xC0, 0x50 )
58
59
60 YQPkgConflictList::YQPkgConflictList( QWidget * parent )
61     : QY2ListView( parent )
62 {
63
64     setHeaderLabel( _( "Dependency Conflict" ) );
65     setRootIsDecorated( true );
66     setSortByInsertionSequence( true );
67 }
68
69
70 YQPkgConflictList::~YQPkgConflictList()
71 {
72     // NOP
73 }
74
75
76 void
77 YQPkgConflictList::fill( zypp::ResolverProblemList problemList )
78 {
79     clear();
80     string text;
81
82
83     zypp::ResolverProblemList::iterator it = problemList.begin();
84
85     while ( it != problemList.end() )
86     {
87         YQPkgConflict * conflict = new YQPkgConflict( this, *it );
88         Q_CHECK_PTR( conflict );
89
90         ++it;
91     }
92 }
93
94
95 void
96 YQPkgConflictList::applyResolutions()
97 {
98     zypp::ProblemSolutionList userChoices;
99
100     int count=0;
101     QTreeWidgetItem * child;
102
103     while ( (child = topLevelItem(count)) )
104     {
105         YQPkgConflict * conflict = dynamic_cast<YQPkgConflict *> (child);
106
107         if ( conflict )
108         {
109             zypp::ProblemSolution_Ptr userChoice = conflict->userSelectedResolution();
110
111             if ( userChoice )
112                 userChoices.push_back( userChoice );
113         }
114
115         count++;
116     }
117
118     zypp::getZYpp()->resolver()->applySolutions( userChoices );
119
120     emit updatePackages();
121 }
122
123
124 void
125 YQPkgConflictList::askSaveToFile() const
126 {
127     QString filename = YQUI::ui()->askForSaveFileName( "conflicts.txt", // startsWith
128                                                        "*.txt",         // filter
129                                                        _( "Save Conflicts List" ) );
130     if ( ! filename.isEmpty() )
131         saveToFile( filename, true );
132 }
133
134
135 void
136 YQPkgConflictList::saveToFile( const QString filename, bool interactive ) const
137 {
138     // Open file
139
140     FILE * file = fopen( (const char *) filename, "w" );
141
142     if ( ! file )
143     {
144         y2error( "Can't open file %s", (const char *) filename );
145
146         if ( interactive )
147         {
148             // Post error popup.
149
150             QMessageBox::warning( 0,                                            // parent
151                                   _( "Error" ),                                 // caption
152                                   _( "Cannot open file %1" ).arg( filename ),
153                                   QMessageBox::Ok | QMessageBox::Default,       // button0
154                                   QMessageBox::NoButton,                        // button1
155                                   QMessageBox::NoButton );                      // button2
156         }
157         return;
158     }
159
160
161     // Write header
162
163     QString header = "#### YaST2 conflicts list - generated ";
164     header += QDateTime::currentDateTime().toString( "yyyy-MM-dd hh:mm:ss" );
165     header += " ####\n\n";
166
167     fputs( (const char *) header, file );
168
169
170     // Recursively write all items
171     int count=0;
172     const QTreeWidgetItem * item;
173
174     while ( (item = topLevelItem(count)) )
175     {
176         saveItemToFile( file, item );
177         count++;
178     }
179
180
181     // Write footer
182
183     fprintf( file, "\n#### YaST2 conflicts list END ###\n" );
184
185
186     // Clean up
187
188     if ( file )
189         fclose( file );
190 }
191
192
193 void
194 YQPkgConflictList::saveItemToFile( FILE *                       file,
195                                    const QTreeWidgetItem *      item ) const
196 {
197     if ( ! item || ! file )
198         return;
199
200     // Write indentation
201 #if FIXME
202     for ( int level = 0; level < item->depth(); level++ )
203         fprintf( file, "    " );
204
205     // Write item
206
207     const Q3CheckListItem * checkListItem = dynamic_cast<const Q3CheckListItem *> (item);
208
209     if ( checkListItem )
210     {
211         switch ( checkListItem->type() )
212         {
213             case Q3CheckListItem::CheckBox:
214                 fprintf( file, "[%c] ", checkListItem->isOn() ? 'x' : ' ' );
215                 break;
216             case Q3CheckListItem::RadioButton:
217                 fprintf( file, "(%c) ", checkListItem->isOn() ? 'x' : ' ' );
218                 break;
219             default:
220                 break;
221         }
222     }
223
224     fprintf( file, "%s\n", (const char *) item->text(0) );
225
226
227     if ( item->isOpen() )
228     {
229         // Recursively write children
230
231         const QTreeWidgetItem * child = item->firstChild();
232
233         while ( child )
234         {
235             saveItemToFile( file, child );
236             child = child->nextSibling();
237         }
238     }
239 #endif
240 }
241
242
243 void
244 YQPkgConflictList::dumpList( QTreeWidgetItem *  parent,
245                              const QString &    longText,
246                              const QString &    header,
247                              int                splitThreshold )
248 {
249     if ( ! parent )
250     {
251         y2error( "Null parent" );
252         return;
253     }
254
255     if ( longText.isEmpty() )
256         return;
257
258 #if FIXME
259     if ( ! header.isEmpty() )
260     {
261         parent = new QY2ListViewItem( parent, header );
262         Q_CHECK_PTR( parent );
263         parent->setOpen( true );
264     }
265
266     QStringList lines = QStringList::split( '\n', longText,
267                                             true );             // allowEmptyEntries
268     QList<QString>::const_iterator it = lines.begin();
269
270     bool doSplit        = splitThreshold > 1 && lines.size() > splitThreshold + 3;
271     bool didSplit       = false;
272     int  count          = 0;
273
274
275     while ( it != lines.end() )
276     {
277         if ( doSplit && ! didSplit && ++count > splitThreshold )
278         {
279             // Split list
280
281             int more = lines.size() - count + 1;
282             QString text = ( _( "%1 more..." ) ).arg( more );
283             QY2ListViewItem * sublist = new QY2ListViewItem( parent, text );
284             didSplit = true;
285
286             if ( sublist )
287             {
288                 sublist->setBackgroundColor( LIGHT_ORANGE );
289                 parent = sublist;
290             }
291         }
292
293         new QY2ListViewItem( parent, *it );
294         ++it;
295     }
296 #endif
297 }
298
299
300
301
302
303
304
305 YQPkgConflict::YQPkgConflict( YQPkgConflictList *               parentList,
306                               zypp::ResolverProblem_Ptr         problem )
307     : QY2ListViewItem( parentList )
308     , _problem( problem )
309     , _resolutionsHeader( 0 )
310 {
311     setBackgroundColor( LIGHT_BLUE );
312 #if FIXME
313     setOpen( true );
314 #endif
315
316     formatHeading();
317     YQPkgConflictList::dumpList( this, fromUTF8( _problem->details() ) );
318
319     addSolutions();
320 }
321
322
323 void
324 YQPkgConflict::formatHeading()
325 {
326     QString text;
327     QPixmap icon = YQIconPool::normalPkgConflict();
328     setTextColor( BRIGHT_RED );
329
330 #if FIXME
331     setText( 0, Qt::DisplayRole, fromUTF8( problem()->description() ) );
332 #endif
333     setData( 0, Qt::DecorationRole, icon );
334 }
335
336
337 void
338 YQPkgConflict::addSolutions()
339 {
340     _resolutionsHeader = new QY2CheckListItem( this,
341                                                // Heading for the choices
342                                                // how to resolve this conflict
343                                                _( "Conflict Resolution:" ) );
344     Q_CHECK_PTR( _resolutionsHeader );
345 #if FIXME
346     _resolutionsHeader->setOpen( true );
347 #endif
348     _resolutionsHeader->setBackgroundColor( LIGHT_GREY );
349
350     zypp::ProblemSolutionList solutions = problem()->solutions();
351     zypp::ProblemSolutionList::iterator it = solutions.begin();
352
353     while ( it != solutions.end() )
354     {
355         YQPkgConflictResolution * solution = new YQPkgConflictResolution( _resolutionsHeader, *it );
356         Q_CHECK_PTR( solution );
357         //FIXME solution->setOpen(true);
358
359         ++it;
360     }
361 }
362
363
364 void
365 YQPkgConflict::paintCell( QPainter *            painter,
366                           const QColorGroup &   colorGroup,
367                           int                   column,
368                           int                   width,
369                           int                   alignment )
370 {
371     painter->setFont( YQUI::yqApp()->headingFont() );
372 #if FIXME
373     QY2ListViewItem::paintCell( painter, colorGroup, column, width, alignment );
374 #endif
375 }
376
377
378 zypp::ProblemSolution_Ptr
379 YQPkgConflict::userSelectedResolution()
380 {
381     int count = 0;
382     QTreeWidgetItem * item;
383
384 #if FIXME
385     while ( item = _resolutionsHeader->topLevelItem(count) )
386     {
387         YQPkgConflictResolution * res = dynamic_cast<YQPkgConflictResolution *> (item);
388
389         if ( res && res->isOn() )
390         {
391             zypp::ProblemSolution_Ptr solution = res->solution();
392
393             y2milestone( "User selected resolution \"%s\" for problem \"%s\"",
394                          solution->description().c_str(),
395                          solution->problem()->description().c_str() );
396             return solution;
397         }
398
399         count++;
400     }
401
402 #endif
403     return zypp::ProblemSolution_Ptr();         // Null pointer
404 }
405
406
407
408
409
410
411 YQPkgConflictResolution::YQPkgConflictResolution( QY2CheckListItem *            parent,
412                                                   zypp::ProblemSolution_Ptr     solution )
413     : QY2CheckListItem( parent,
414                         fromUTF8( solution->description() ) )
415                         /*, Q3CheckListItem::RadioButton) */
416 {
417     _solution = solution;
418     YQPkgConflictList::dumpList( this, fromUTF8( solution->details() ) );
419 }
420
421
422
423 #include "YQPkgConflictList.moc"