1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YUIQt_builtins.cc
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
22 #define USE_QT_CURSORS 1
23 #define FORCE_UNICODE_FONT 0
29 #include <q3filedialog.h>
30 #include <qmessagebox.h>
32 #include <qinputdialog.h>
35 #include <ycp/YCPTerm.h>
36 #define y2log_component "qt-ui"
37 #include <ycp/y2log.h>
41 #include "YMacroRecorder.h"
42 #include "YUISymbols.h"
44 #include "YQSignalBlocker.h"
52 #define DEFAULT_MACRO_FILE_NAME "macro.ycp"
57 YQUI::glyph( const YCPSymbol & glyphSymbol )
59 string sym = glyphSymbol->symbol();
62 // Hint: Use 'xfd' to view characters available in the Unicode font.
64 if ( sym == YUIGlyph_ArrowLeft ) unicodeChar = QChar( 0x2190 );
65 else if ( sym == YUIGlyph_ArrowRight ) unicodeChar = QChar( 0x2192 );
66 else if ( sym == YUIGlyph_ArrowUp ) unicodeChar = QChar( 0x2191 );
67 else if ( sym == YUIGlyph_ArrowDown ) unicodeChar = QChar( 0x2193 );
68 else if ( sym == YUIGlyph_CheckMark ) unicodeChar = QChar( 0x2714 );
69 else if ( sym == YUIGlyph_BulletArrowRight ) unicodeChar = QChar( 0x279c );
70 else if ( sym == YUIGlyph_BulletCircle ) unicodeChar = QChar( 0x274d );
71 else if ( sym == YUIGlyph_BulletSquare ) unicodeChar = QChar( 0x274f );
72 else return YCPString( "" );
74 QString qstr( unicodeChar );
76 return YCPString( toUTF8( qstr ) );
80 YCPValue YQUI::runPkgSelection( YWidget * packageSelector )
82 y2milestone( "Running package selection..." );
83 _wm_close_blocked = true;
84 _auto_activate_dialogs = false;
86 YCPValue input = YCPVoid();
90 input = evaluateUserInput();
92 catch (const std::exception & e)
94 y2error( "Caught std::exception: %s", e.what() );
95 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
99 y2error( "Caught unspecified exception." );
100 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
103 _auto_activate_dialogs = true;
104 _wm_close_blocked = false;
105 y2milestone( "Package selection done - returning %s", input->toString().c_str() );
111 void YQUI::makeScreenShot( std::string stl_filename )
115 // Grab the pixels off the screen
118 QWidget * dialog = (QWidget *) YDialog::currentDialog()->widgetRep();
119 QPixmap screenShot = QPixmap::grabWindow( dialog->winId() );
120 XSync( dialog->x11Display(), false );
121 QString fileName ( stl_filename.c_str() );
122 bool interactive = false;
124 if ( fileName.isEmpty() )
128 // Open a file selection box. Figure out a reasonable default
129 // directory / file name.
131 if ( screenShotNameTemplate.isEmpty() )
134 // Initialize screen shot directory
137 QString home = QDir::homeDirPath();
138 char * ssdir = getenv("Y2SCREENSHOTS");
139 QString dir = ssdir ? ssdir : "yast2-screen-shots";
143 // Special case: $HOME is not set. This is normal in the inst-sys.
144 // In this case, rather than simply dumping all screen shots into
145 // /tmp which is world-writable, let's try to create a subdirectory
146 // below /tmp with restrictive permissions.
147 // If that fails, trust nobody - in particular, do not suggest /tmp
148 // as the default in the file selection box.
152 if ( mkdir( dir, 0700 ) == -1 )
157 // For all others let's create a directory ~/yast2-screen-shots and
158 // simply ignore if this is already present. This gives the user a
159 // chance to create symlinks to a better location if he wishes so.
161 dir = home + "/" + dir;
162 (void) mkdir( dir, 0750 );
165 screenShotNameTemplate = dir + "/%s-%03d.png";
170 // Figure out a file name
173 const char * baseName = moduleName();
174 if ( ! baseName ) baseName = "scr";
175 int no = screenShotNo[ baseName ];
176 fileName.sprintf( screenShotNameTemplate, baseName, no );
177 y2debug( "screenshot: %s", (const char *) fileName );
180 YQSignalBlocker sigBlocker( &_user_input_timer );
182 fileName = askForSaveFileName( fileName, QString( "*.png" ) , _( "Save screen shot to..." ) );
185 if ( fileName.isEmpty() )
187 y2debug( "Save screen shot canceled by user" );
191 screenShotNo.insert( baseName, ++no );
192 } // if fileName.isEmpty()
196 // Actually save the screen shot
199 y2debug( "Saving screen shot to %s", (const char *) fileName );
200 bool success = screenShot.save( fileName, "PNG" );
204 y2error( "Couldn't save screen shot %s", (const char *) fileName );
208 QMessageBox::warning( 0, // parent
210 QString( "Couldn't save screen shot\nto %1" ).arg( fileName ),
211 QMessageBox::Ok | QMessageBox::Default, // button0
212 Qt::NoButton, // button1
213 Qt::NoButton ); // button2
217 if ( recordingMacro() )
219 macroRecorder->beginBlock();
220 YDialog::currentDialog()->saveUserInput( macroRecorder );
221 macroRecorder->recordMakeScreenShot( true, (const char *) fileName );
222 macroRecorder->recordUserInput( YCPVoid() );
223 macroRecorder->endBlock();
228 void YQUI::askSaveLogs()
230 QString fileName = askForSaveFileName( "/tmp/y2logs.tgz", // startWith
231 "*.tgz *.tar.gz", // filter
232 "Save y2logs to..." ); // headline
234 if ( ! fileName.isEmpty() )
236 QString saveLogsCommand = "/sbin/save_y2logs";
238 if ( access( saveLogsCommand.ascii(), X_OK ) == 0 )
240 saveLogsCommand += " '" + fileName + "'";
241 y2milestone( "Saving y2logs: %s", saveLogsCommand.ascii() );
242 int result = system( saveLogsCommand.ascii() );
246 y2error( "Error saving y2logs: \"%s\" exited with %d",
247 (const char *) saveLogsCommand, result );
248 QMessageBox::warning( 0, // parent
250 QString( "Couldn't save y2logs to %1 - "
251 "exit code %2" ).arg( fileName ).arg( result ),
252 QMessageBox::Ok | QMessageBox::Default, // button0
253 QMessageBox::NoButton, // button1
254 QMessageBox::NoButton ); // button2
258 y2milestone( "y2logs saved to %s", (const char *) fileName );
263 y2error( "Error saving y2logs: Command %s not found",
264 saveLogsCommand.ascii() );
266 QMessageBox::warning( 0, // parent
268 QString( "Couldn't save y2logs to %1:\n"
269 "Command %2 not found" ).arg( fileName ).arg( saveLogsCommand ),
270 QMessageBox::Ok | QMessageBox::Default, // button0
271 QMessageBox::NoButton, // button1
272 QMessageBox::NoButton ); // button2
278 void YQUI::askConfigureLogging()
280 bool okButtonPressed = false;
282 items << "Debug logging off"
283 << "Debug logging on";
285 QString result = QInputDialog::getItem( "YaST2 Logging", // caption
286 "Configure YaST2 Logging:", // label
288 get_log_debug() ? 1 : 0,
291 _main_win ); // parent
293 if ( okButtonPressed )
295 set_log_debug( result.endsWith( "on" ) );
296 y2milestone( "Changing logging: %s - %s", (const char *) result,
297 get_log_debug() ? "y2debug on" : "y2debug off" );
302 void YQUI::toggleRecordMacro()
304 if ( recordingMacro() )
309 QMessageBox::information( 0, // parent
310 "YaST2 Macro Recorder", // caption
311 "Macro recording done.", // text
312 QMessageBox::Ok | QMessageBox::Default, // button0
313 QMessageBox::NoButton, // button1
314 QMessageBox::NoButton ); // button2
321 Q3FileDialog::getSaveFileName( DEFAULT_MACRO_FILE_NAME, // startWith
325 "Select Macro File to Record to" ); // caption
327 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
329 recordMacro( (const char *) filename );
335 void YQUI::askPlayMacro()
340 Q3FileDialog::getOpenFileName( DEFAULT_MACRO_FILE_NAME, // startWith
344 "Select Macro File to Play" ); // caption
347 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
349 playMacro( (const char *) filename );
351 // Do special magic to get out of any UserInput() loop right now
352 // without doing any harm - otherwise this would hang until the next
353 // mouse click on a PushButton etc.
355 sendEvent( new YEvent() );
366 YCPValue YQUI::askForExistingDirectory( const YCPString & startDir,
367 const YCPString & headline )
372 Q3FileDialog::getExistingDirectory( fromUTF8( startDir->value() ),
374 "dir_selector", // name
375 fromUTF8( headline->value() ) ); // caption
378 if ( dir_name.isEmpty() ) // this includes dir_name.isNull()
379 return YCPVoid(); // nothing selected -> return 'nil'
381 return YCPString( toUTF8( dir_name ) );
385 YCPValue YQUI::askForExistingFile( const YCPString & startWith,
386 const YCPString & filter,
387 const YCPString & headline )
392 Q3FileDialog::getOpenFileName( fromUTF8( startWith->value() ),
393 fromUTF8( filter->value() ),
395 "file_selector", // name
396 fromUTF8( headline->value() ) ); // caption
399 if ( file_name.isEmpty() ) // this includes file_name.isNull()
400 return YCPVoid(); // nothing selected -> return 'nil'
402 return YCPString( toUTF8( file_name ) );
406 YCPValue YQUI::askForSaveFileName( const YCPString & startWith,
407 const YCPString & filter,
408 const YCPString & headline )
412 QString file_name = askForSaveFileName( fromUTF8( startWith->value() ),
413 fromUTF8( filter->value() ),
414 fromUTF8( headline->value() ) );
417 if ( file_name.isEmpty() ) // this includes file_name.isNull()
418 return YCPVoid(); // nothing selected -> return 'nil'
420 return YCPString( toUTF8( file_name ) );
425 QString YQUI::askForSaveFileName( const QString & startWith,
426 const QString & filter,
427 const QString & headline )
430 bool try_again = false;
434 // Leave the mouse cursor alone - this function might be called from
435 // some other widget, not only from UI::AskForSaveFileName().
437 file_name = Q3FileDialog::getSaveFileName( startWith,
440 "file_selector", // name
441 headline ); // caption
443 if ( file_name.isEmpty() ) // this includes file_name.isNull()
444 return QString::null;
447 if ( access( (const char *) file_name, F_OK ) == 0 ) // file exists?
451 if ( access( (const char *) file_name, W_OK ) == 0 )
453 // Confirm if the user wishes to overwrite an existing file
454 msg = ( _( "%1 exists! Really overwrite?" ) ).arg( file_name );
458 // Confirm if the user wishes to overwrite a write-protected file %1
459 msg = ( _( "%1 exists and is write-protected!\nReally overwrite?" ) ).arg( file_name );
462 int button_no = QMessageBox::information( _main_win,
463 // Window title for confirmation dialog
468 try_again = ( button_no != 0 );
471 } while ( try_again );