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