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 YCPValue input = YCPVoid();
85 input = evaluateUserInput();
87 catch (const std::exception & e)
89 y2error( "Caught std::exception: %s", e.what() );
90 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
94 y2error( "Caught unspecified exception." );
95 y2error( "This is a libzypp problem. Do not file a bug against the UI!" );
98 y2milestone( "Package selection done - returning %s", input->toString().c_str() );
104 void YQUI::makeScreenShot( std::string stl_filename )
108 // Grab the pixels off the screen
111 QWidget * dialog = (QWidget *) YDialog::currentDialog()->widgetRep();
112 QPixmap screenShot = QPixmap::grabWindow( dialog->winId() );
113 //FIXME XSync( dialog->x11Display(), false );
114 QString fileName ( stl_filename.c_str() );
115 bool interactive = false;
117 if ( fileName.isEmpty() )
121 // Open a file selection box. Figure out a reasonable default
122 // directory / file name.
124 if ( screenShotNameTemplate.isEmpty() )
127 // Initialize screen shot directory
130 QString home = QDir::homePath();
131 char * ssdir = getenv("Y2SCREENSHOTS");
132 QString dir = ssdir ? ssdir : "yast2-screen-shots";
136 // Special case: $HOME is not set. This is normal in the inst-sys.
137 // In this case, rather than simply dumping all screen shots into
138 // /tmp which is world-writable, let's try to create a subdirectory
139 // below /tmp with restrictive permissions.
140 // If that fails, trust nobody - in particular, do not suggest /tmp
141 // as the default in the file selection box.
145 if ( mkdir( qPrintable(dir), 0700 ) == -1 )
150 // For all others let's create a directory ~/yast2-screen-shots and
151 // simply ignore if this is already present. This gives the user a
152 // chance to create symlinks to a better location if he wishes so.
154 dir = home + "/" + dir;
155 (void) mkdir( qPrintable(dir), 0750 );
158 screenShotNameTemplate = dir + "/%s-%03d.png";
163 // Figure out a file name
166 const char * baseName = moduleName();
167 if ( ! baseName ) baseName = "scr";
168 int no = screenShotNo[ baseName ];
169 fileName.sprintf( qPrintable(screenShotNameTemplate), baseName, no );
170 y2debug( "screenshot: %s", qPrintable(fileName) );
173 YQSignalBlocker sigBlocker( &_user_input_timer );
175 fileName = askForSaveFileName( fileName, QString( "*.png" ) , _( "Save screen shot to..." ) );
178 if ( fileName.isEmpty() )
180 y2debug( "Save screen shot canceled by user" );
184 screenShotNo.insert( baseName, ++no );
185 } // if fileName.isEmpty()
189 // Actually save the screen shot
192 y2debug( "Saving screen shot to %s", qPrintable(fileName) );
193 bool success = screenShot.save( fileName, "PNG" );
197 y2error( "Couldn't save screen shot %s", qPrintable(fileName) );
201 QMessageBox::warning( 0, // parent
203 QString( "Couldn't save screen shot\nto %1" ).arg( fileName ),
204 QMessageBox::Ok | QMessageBox::Default, // button0
205 Qt::NoButton, // button1
206 Qt::NoButton ); // button2
210 if ( recordingMacro() )
212 macroRecorder->beginBlock();
213 YDialog::currentDialog()->saveUserInput( macroRecorder );
214 macroRecorder->recordMakeScreenShot( true, qPrintable(fileName) );
215 macroRecorder->recordUserInput( YCPVoid() );
216 macroRecorder->endBlock();
221 void YQUI::askSaveLogs()
223 QString fileName = askForSaveFileName( "/tmp/y2logs.tgz", // startWith
224 "*.tgz *.tar.gz", // filter
225 "Save y2logs to..." ); // headline
227 if ( ! fileName.isEmpty() )
229 QString saveLogsCommand = "/sbin/save_y2logs";
231 if ( access( saveLogsCommand.toAscii(), X_OK ) == 0 )
233 saveLogsCommand += " '" + fileName + "'";
234 y2milestone( "Saving y2logs: %s", qPrintable(saveLogsCommand) );
235 int result = system( qPrintable(saveLogsCommand) );
239 y2error( "Error saving y2logs: \"%s\" exited with %d",
240 qPrintable(saveLogsCommand), result );
241 QMessageBox::warning( 0, // parent
243 QString( "Couldn't save y2logs to %1 - "
244 "exit code %2" ).arg( fileName ).arg( result ),
245 QMessageBox::Ok | QMessageBox::Default, // button0
246 QMessageBox::NoButton, // button1
247 QMessageBox::NoButton ); // button2
251 y2milestone( "y2logs saved to %s", qPrintable(fileName) );
256 y2error( "Error saving y2logs: Command %s not found",
257 qPrintable(saveLogsCommand) );
259 QMessageBox::warning( 0, // parent
261 QString( "Couldn't save y2logs to %1:\n"
262 "Command %2 not found" ).arg( fileName ).arg( saveLogsCommand ),
263 QMessageBox::Ok | QMessageBox::Default, // button0
264 QMessageBox::NoButton, // button1
265 QMessageBox::NoButton ); // button2
271 void YQUI::askConfigureLogging()
273 bool okButtonPressed = false;
275 items << "Debug logging off"
276 << "Debug logging on";
278 QString result = QInputDialog::getItem( _main_win,
280 tr("Configure YaST2 Logging:"),
281 items, 0, get_log_debug() ? 1 : 0, &okButtonPressed);
282 if ( okButtonPressed )
284 set_log_debug( result.endsWith( "on" ) );
285 y2milestone( "Changing logging: %s - %s", qPrintable(result),
286 get_log_debug() ? "y2debug on" : "y2debug off" );
291 void YQUI::toggleRecordMacro()
293 if ( recordingMacro() )
298 QMessageBox::information( 0, // parent
299 "YaST2 Macro Recorder", // caption
300 "Macro recording done.", // text
301 QMessageBox::Ok | QMessageBox::Default, // button0
302 QMessageBox::NoButton, // button1
303 QMessageBox::NoButton ); // button2
310 QFileDialog::getSaveFileName( 0,
311 "Select Macro File to Record to",
312 DEFAULT_MACRO_FILE_NAME, // startWith
316 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
318 recordMacro( qPrintable(filename) );
324 void YQUI::askPlayMacro()
329 QFileDialog::getOpenFileName( 0,
330 "Select Macro File to Play",
331 DEFAULT_MACRO_FILE_NAME, // startWith
335 if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
337 playMacro( qPrintable(filename) );
339 // Do special magic to get out of any UserInput() loop right now
340 // without doing any harm - otherwise this would hang until the next
341 // mouse click on a PushButton etc.
343 sendEvent( new YEvent() );
354 YCPValue YQUI::askForExistingDirectory( const YCPString & startDir,
355 const YCPString & headline )
360 QFileDialog::getExistingDirectory( _main_win,
361 fromUTF8( headline->value() ),
362 fromUTF8( startDir->value() ) );
365 if ( dir_name.isEmpty() ) // this includes dir_name.isNull()
366 return YCPVoid(); // nothing selected -> return 'nil'
368 return YCPString( toUTF8( dir_name ) );
372 YCPValue YQUI::askForExistingFile( const YCPString & startWith,
373 const YCPString & filter,
374 const YCPString & headline )
379 QFileDialog::getOpenFileName( _main_win, // parent
380 fromUTF8( headline->value() ),
381 fromUTF8( startWith->value() ),
382 fromUTF8( filter->value() ) );
385 if ( file_name.isEmpty() ) // this includes file_name.isNull()
386 return YCPVoid(); // nothing selected -> return 'nil'
388 return YCPString( toUTF8( file_name ) );
392 YCPValue YQUI::askForSaveFileName( const YCPString & startWith,
393 const YCPString & filter,
394 const YCPString & headline )
398 QString file_name = askForSaveFileName( fromUTF8( startWith->value() ),
399 fromUTF8( filter->value() ),
400 fromUTF8( headline->value() ) );
403 if ( file_name.isEmpty() ) // this includes file_name.isNull()
404 return YCPVoid(); // nothing selected -> return 'nil'
406 return YCPString( toUTF8( file_name ) );
411 QString YQUI::askForSaveFileName( const QString & startWith,
412 const QString & filter,
413 const QString & headline )
416 bool try_again = false;
420 // Leave the mouse cursor alone - this function might be called from
421 // some other widget, not only from UI::AskForSaveFileName().
423 file_name = QFileDialog::getSaveFileName( _main_win,
428 if ( file_name.isEmpty() ) // this includes file_name.isNull()
429 return QString::null;
432 if ( access( qPrintable(file_name), F_OK ) == 0 ) // file exists?
436 if ( access( qPrintable(file_name), W_OK ) == 0 )
438 // Confirm if the user wishes to overwrite an existing file
439 msg = ( _( "%1 exists! Really overwrite?" ) ).arg( file_name );
443 // Confirm if the user wishes to overwrite a write-protected file %1
444 msg = ( _( "%1 exists and is write-protected!\nReally overwrite?" ) ).arg( file_name );
447 int button_no = QMessageBox::information( _main_win,
448 // Window title for confirmation dialog
453 try_again = ( button_no != 0 );
456 } while ( try_again );