]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgConflictList.cc
more porting
[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
202     for ( int level = 0; level < item->depth(); level++ )
203         fprintf( file, "    " );
204
205
206     // Write item
207
208     const Q3CheckListItem * checkListItem = dynamic_cast<const Q3CheckListItem *> (item);
209
210     if ( checkListItem )
211     {
212         switch ( checkListItem->type() )
213         {
214             case Q3CheckListItem::CheckBox:
215                 fprintf( file, "[%c] ", checkListItem->isOn() ? 'x' : ' ' );
216                 break;
217             case Q3CheckListItem::RadioButton:
218                 fprintf( file, "(%c) ", checkListItem->isOn() ? 'x' : ' ' );
219                 break;
220             default:
221                 break;
222         }
223     }
224
225     fprintf( file, "%s\n", (const char *) item->text(0) );
226
227
228     if ( item->isOpen() )
229     {
230         // Recursively write children
231
232         const QTreeWidgetItem * child = item->firstChild();
233
234         while ( child )
235         {
236             saveItemToFile( file, child );
237             child = child->nextSibling();
238         }
239     }
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 ( ! header.isEmpty() )
259     {
260         parent = new QY2ListViewItem( parent, header );
261         Q_CHECK_PTR( parent );
262         parent->setOpen( true );
263     }
264
265     QStringList lines = QStringList::split( '\n', longText,
266                                             true );             // allowEmptyEntries
267     QList<QString>::const_iterator it = lines.begin();
268
269     bool doSplit        = splitThreshold > 1 && lines.size() > splitThreshold + 3;
270     bool didSplit       = false;
271     int  count          = 0;
272
273
274     while ( it != lines.end() )
275     {
276         if ( doSplit && ! didSplit && ++count > splitThreshold )
277         {
278             // Split list
279
280             int more = lines.size() - count + 1;
281             QString text = ( _( "%1 more..." ) ).arg( more );
282             QY2ListViewItem * sublist = new QY2ListViewItem( parent, text );
283             didSplit = true;
284
285             if ( sublist )
286             {
287                 sublist->setBackgroundColor( LIGHT_ORANGE );
288                 parent = sublist;
289             }
290         }
291
292         new QY2ListViewItem( parent, *it );
293         ++it;
294     }
295 }
296
297
298
299
300
301
302
303 YQPkgConflict::YQPkgConflict( YQPkgConflictList *               parentList,
304                               zypp::ResolverProblem_Ptr         problem )
305     : QY2ListViewItem( parentList )
306     , _problem( problem )
307     , _resolutionsHeader( 0 )
308 {
309     setBackgroundColor( LIGHT_BLUE );
310     setOpen( true );
311
312     formatHeading();
313     YQPkgConflictList::dumpList( this, fromUTF8( _problem->details() ) );
314
315     addSolutions();
316 }
317
318
319 void
320 YQPkgConflict::formatHeading()
321 {
322     QString text;
323     QPixmap icon = YQIconPool::normalPkgConflict();
324     setTextColor( BRIGHT_RED );
325
326     setText( 0, Qt::DisplayRole, fromUTF8( problem()->description() ) );
327     setData( 0, Qt::DecorationRole, icon );
328 }
329
330
331 void
332 YQPkgConflict::addSolutions()
333 {
334     _resolutionsHeader = new QY2CheckListItem( this,
335                                                // Heading for the choices
336                                                // how to resolve this conflict
337                                                _( "Conflict Resolution:" ) );
338     Q_CHECK_PTR( _resolutionsHeader );
339     _resolutionsHeader->setOpen( true );
340     _resolutionsHeader->setBackgroundColor( LIGHT_GREY );
341
342     zypp::ProblemSolutionList solutions = problem()->solutions();
343     zypp::ProblemSolutionList::iterator it = solutions.begin();
344
345     while ( it != solutions.end() )
346     {
347         new YQPkgConflictResolution( _resolutionsHeader, *it );
348         ++it;
349     }
350 }
351
352
353 void
354 YQPkgConflict::paintCell( QPainter *            painter,
355                           const QColorGroup &   colorGroup,
356                           int                   column,
357                           int                   width,
358                           int                   alignment )
359 {
360     painter->setFont( YQUI::yqApp()->headingFont() );
361     QY2ListViewItem::paintCell( painter, colorGroup, column, width, alignment );
362 }
363
364
365 zypp::ProblemSolution_Ptr
366 YQPkgConflict::userSelectedResolution()
367 {
368     int count = 0;
369     QTreeWidgetItem * item;
370
371     while ( item = _resolutionsHeader->topLevelItem(count) )
372     {
373         YQPkgConflictResolution * res = dynamic_cast<YQPkgConflictResolution *> (item);
374
375         if ( res && res->isOn() )
376         {
377             zypp::ProblemSolution_Ptr solution = res->solution();
378
379             y2milestone( "User selected resolution \"%s\" for problem \"%s\"",
380                          solution->description().c_str(),
381                          solution->problem()->description().c_str() );
382             return solution;
383         }
384
385         count++;
386     }
387
388     return zypp::ProblemSolution_Ptr();         // Null pointer
389 }
390
391
392
393
394
395
396 YQPkgConflictResolution::YQPkgConflictResolution( QY2CheckListItem *            parent,
397                                                   zypp::ProblemSolution_Ptr     solution )
398     : QY2CheckListItem( parent,
399                         fromUTF8( solution->description() ),
400                         /*Q3CheckListItem::RadioButton) */
401     , _solution( solution ))
402 {
403     YQPkgConflictList::dumpList( this, fromUTF8( solution->details() ) );
404 }
405
406
407
408 #include "YQPkgConflictList.moc"