1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YUIQt_builtins.cc
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
21 #define USE_QT_CURSORS 1
22 #define FORCE_UNICODE_FONT 0
28 #include <QFileDialog>
29 #include <QMessageBox>
31 #include <QInputDialog>
33 #include <ycp/YCPTerm.h>
34 #define y2log_component "qt-ui"
35 #include <ycp/y2log.h>
39 #include "YMacroRecorder.h"
40 #include "YUISymbols.h"
42 #include "YQSignalBlocker.h"
50 #define DEFAULT_MACRO_FILE_NAME "macro.ycp"
55 YQUI::glyph( const YCPSymbol & glyphSymbol )
57 string sym = glyphSymbol->symbol();
60 // Hint: Use 'xfd' to view characters available in the Unicode font.
62 if ( sym == YUIGlyph_ArrowLeft ) unicodeChar = QChar( 0x2190 );
63 else if ( sym == YUIGlyph_ArrowRight ) unicodeChar = QChar( 0x2192 );
64 else if ( sym == YUIGlyph_ArrowUp ) unicodeChar = QChar( 0x2191 );
65 else if ( sym == YUIGlyph_ArrowDown ) unicodeChar = QChar( 0x2193 );
66 else if ( sym == YUIGlyph_CheckMark ) unicodeChar = QChar( 0x2714 );
67 else if ( sym == YUIGlyph_BulletArrowRight ) unicodeChar = QChar( 0x279c );
68 else if ( sym == YUIGlyph_BulletCircle ) unicodeChar = QChar( 0x274d );
69 else if ( sym == YUIGlyph_BulletSquare ) unicodeChar = QChar( 0x274f );
70 else return YCPString( "" );
72 QString qstr( unicodeChar );
74 return YCPString( toUTF8( qstr ) );
78 YCPValue YQUI::runPkgSelection( YWidget * packageSelector )
80 y2milestone( "Running package selection..." );
81 _wm_close_blocked = true;
82 _auto_activate_dialogs = false;
84 YCPValue input = YCPVoid();
88 input = evaluateUserInput();
90 catch (const std::exception & e)
92 y2error( "Caught std::exception: %s", e.what() );
93 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
97 y2error( "Caught unspecified exception." );
98 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
101 _auto_activate_dialogs = true;
102 _wm_close_blocked = false;
103 y2milestone( "Package selection done - returning %s", input->toString().c_str() );
109 void YQUI::makeScreenShot( std::string stl_filename )
113 // Grab the pixels off the screen
116 QWidget * dialog = (QWidget *) YDialog::currentDialog()->widgetRep();
117 QPixmap screenShot = QPixmap::grabWindow( dialog->winId() );
118 //FIXME XSync( dialog->x11Display(), false );
119 QString fileName ( stl_filename.c_str() );
120 bool interactive = false;
122 if ( fileName.isEmpty() )
126 // Open a file selection box. Figure out a reasonable default
127 // directory / file name.
129 if ( screenShotNameTemplate.isEmpty() )
132 // Initialize screen shot directory
135 QString home = QDir::homePath();
136 char * ssdir = getenv("Y2SCREENSHOTS");
137 QString dir = ssdir ? ssdir : "yast2-screen-shots";
141 // Special case: $HOME is not set. This is normal in the inst-sys.
142 // In this case, rather than simply dumping all screen shots into
143 // /tmp which is world-writable, let's try to create a subdirectory
144 // below /tmp with restrictive permissions.
145 // If that fails, trust nobody - in particular, do not suggest /tmp
146 // as the default in the file selection box.
150 if ( mkdir( qPrintable(dir), 0700 ) == -1 )
155 // For all others let's create a directory ~/yast2-screen-shots and
156 // simply ignore if this is already present. This gives the user a
157 // chance to create symlinks to a better location if he wishes so.
159 dir = home + "/" + dir;
160 (void) mkdir( qPrintable(dir), 0750 );
163 screenShotNameTemplate = dir + "/%s-%03d.png";
168 // Figure out a file name
171 const char * baseName = moduleName();
172 if ( ! baseName ) baseName = "scr";
173 int no = screenShotNo[ baseName ];
174 fileName.sprintf( qPrintable(screenShotNameTemplate), baseName, no );
175 y2debug( "screenshot: %s", qPrintable(fileName) );
178 YQSignalBlocker sigBlocker( &_user_input_timer );
180 fileName = askForSaveFileName( fileName, QString( "*.png" ) , _( "Save screen shot to..." ) );
183 if ( fileName.isEmpty() )
185 y2debug( "Save screen shot canceled by user" );
189 screenShotNo.insert( baseName, ++no );
190 } // if fileName.isEmpty()
194 // Actually save the screen shot
197 y2debug( "Saving screen shot to %s", qPrintable(fileName) );
198 bool success = screenShot.save( fileName, "PNG" );
202 y2error( "Couldn't save screen shot %s", qPrintable(fileName) );
206 QMessageBox::warning( 0, // parent
208 QString( "Couldn't save screen shot\nto %1" ).arg( fileName ),
209 QMessageBox::Ok | QMessageBox::Default, // button0
210 Qt::NoButton, // button1
211 Qt::NoButton ); // button2
215 if ( recordingMacro() )
217 macroRecorder->beginBlock();
218 YDialog::currentDialog()->saveUserInput( macroRecorder );
219 macroRecorder->recordMakeScreenShot( true, qPrintable(fileName) );
220 macroRecorder->recordUserInput( YCPVoid() );
221 macroRecorder->endBlock();
226 void YQUI::askSaveLogs()
228 QString fileName = askForSaveFileName( "/tmp/y2logs.tgz", // startWith
229 "*.tgz *.tar.gz", // filter
230 "Save y2logs to..." ); // headline
232 if ( ! fileName.isEmpty() )
234 QString saveLogsCommand = "/sbin/save_y2logs";
236 if ( access( saveLogsCommand.toAscii(), X_OK ) == 0 )
238 saveLogsCommand += " '" + fileName + "'";
239 y2milestone( "Saving y2logs: %s", qPrintable(saveLogsCommand) );
240 int result = system( qPrintable(saveLogsCommand) );
244 y2error( "Error saving y2logs: \"%s\" exited with %d",
245 qPrintable(saveLogsCommand), result );
246 QMessageBox::warning( 0, // parent
248 QString( "Couldn't save y2logs to %1 - "
249 "exit code %2" ).arg( fileName ).arg( result ),
250 QMessageBox::Ok | QMessageBox::Default, // button0
251 QMessageBox::NoButton, // button1
252 QMessageBox::NoButton ); // button2
256 y2milestone( "y2logs saved to %s", qPrintable(fileName) );
261 y2error( "Error saving y2logs: Command %s not found",
262 qPrintable(saveLogsCommand) );
264 QMessageBox::warning( 0, // parent
266 QString( "Couldn't save y2logs to %1:\n"
267 "Command %2 not found" ).arg( fileName ).arg( saveLogsCommand ),
268 QMessageBox::Ok | QMessageBox::Default, // button0
269 QMessageBox::NoButton, // button1
270 QMessageBox::NoButton ); // button2
276 void YQUI::askConfigureLogging()
278 bool okButtonPressed = false;
280 items << "Debug logging off"
281 << "Debug logging on";
283 QString result = QInputDialog::getItem( _main_win,
285 tr("Configure YaST2 Logging:"),
286 items, 0, get_log_debug() ? 1 : 0, &okButtonPressed);
287 if ( okButtonPressed )
289 set_log_debug( result.endsWith( "on" ) );
290 y2milestone( "Changing logging: %s - %s", qPrintable(result),
291 get_log_debug() ? "y2debug on" : "y2debug off" );
296 void YQUI::toggleRecordMacro()
298 if ( recordingMacro() )
303 QMessageBox::information( 0, // parent
304 "YaST2 Macro Recorder", // caption
305 "Macro recording done.", // text
306 QMessageBox::Ok | QMessageBox::Default, // button0
307 QMessageBox::NoButton, // button1
308 QMessageBox::NoButton ); // button2
315 QFileDialog::getSaveFileName( 0,
316 "Select Macro File to Record to",
317 DEFAULT_MACRO_FILE_NAME, // startWith
321 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
323 recordMacro( qPrintable(filename) );
329 void YQUI::askPlayMacro()
334 QFileDialog::getOpenFileName( 0,
335 "Select Macro File to Play",
336 DEFAULT_MACRO_FILE_NAME, // startWith
340 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
342 playMacro( qPrintable(filename) );
344 // Do special magic to get out of any UserInput() loop right now
345 // without doing any harm - otherwise this would hang until the next
346 // mouse click on a PushButton etc.
348 sendEvent( new YEvent() );
359 YCPValue YQUI::askForExistingDirectory( const YCPString & startDir,
360 const YCPString & headline )
365 QFileDialog::getExistingDirectory( _main_win,
366 fromUTF8( headline->value() ),
367 fromUTF8( startDir->value() ) );
370 if ( dir_name.isEmpty() ) // this includes dir_name.isNull()
371 return YCPVoid(); // nothing selected -> return 'nil'
373 return YCPString( toUTF8( dir_name ) );
377 YCPValue YQUI::askForExistingFile( const YCPString & startWith,
378 const YCPString & filter,
379 const YCPString & headline )
384 QFileDialog::getOpenFileName( _main_win, // parent
385 fromUTF8( headline->value() ),
386 fromUTF8( startWith->value() ),
387 fromUTF8( filter->value() ) );
390 if ( file_name.isEmpty() ) // this includes file_name.isNull()
391 return YCPVoid(); // nothing selected -> return 'nil'
393 return YCPString( toUTF8( file_name ) );
397 YCPValue YQUI::askForSaveFileName( const YCPString & startWith,
398 const YCPString & filter,
399 const YCPString & headline )
403 QString file_name = askForSaveFileName( fromUTF8( startWith->value() ),
404 fromUTF8( filter->value() ),
405 fromUTF8( headline->value() ) );
408 if ( file_name.isEmpty() ) // this includes file_name.isNull()
409 return YCPVoid(); // nothing selected -> return 'nil'
411 return YCPString( toUTF8( file_name ) );
416 QString YQUI::askForSaveFileName( const QString & startWith,
417 const QString & filter,
418 const QString & headline )
421 bool try_again = false;
425 // Leave the mouse cursor alone - this function might be called from
426 // some other widget, not only from UI::AskForSaveFileName().
428 file_name = QFileDialog::getSaveFileName( _main_win,
433 if ( file_name.isEmpty() ) // this includes file_name.isNull()
434 return QString::null;
437 if ( access( qPrintable(file_name), F_OK ) == 0 ) // file exists?
441 if ( access( qPrintable(file_name), W_OK ) == 0 )
443 // Confirm if the user wishes to overwrite an existing file
444 msg = ( _( "%1 exists! Really overwrite?" ) ).arg( file_name );
448 // Confirm if the user wishes to overwrite a write-protected file %1
449 msg = ( _( "%1 exists and is write-protected!\nReally overwrite?" ) ).arg( file_name );
452 int button_no = QMessageBox::information( _main_win,
453 // Window title for confirmation dialog
458 try_again = ( button_no != 0 );
461 } while ( try_again );