libyui-qt  2.52.4
YQUI_builtins.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YUIQt_builtins.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23  Textdomain "qt"
24 
25 /-*/
26 
27 #define USE_QT_CURSORS 1
28 #define FORCE_UNICODE_FONT 0
29 
30 #include <sys/stat.h>
31 #include <unistd.h>
32 
33 #include <QCursor>
34 #include <QFileDialog>
35 #include <QX11Info>
36 #include <QMessageBox>
37 #include <QPixmap>
38 #include <QInputDialog>
39 #include <QWindow>
40 #include <QScreen>
41 #include <qdir.h>
42 
43 #define YUILogComponent "qt-ui"
44 #include <yui/YUILog.h>
45 
46 #include "YQUI.h"
47 #include <yui/YEvent.h>
48 #include <yui/YMacro.h>
49 #include <yui/YUISymbols.h>
50 #include "YQDialog.h"
51 #include "YQSignalBlocker.h"
52 #include "YQApplication.h"
53 
54 #include "utf8.h"
55 #include "YQi18n.h"
56 
57 #include <X11/Xlib.h>
58 
59 
60 #define DEFAULT_MACRO_FILE_NAME "macro.ycp"
61 
62 using std::string;
63 using std::endl;
64 
65 
66 
67 YEvent * YQUI::runPkgSelection( YWidget * packageSelector )
68 {
69  YUI_CHECK_PTR( packageSelector );
70  YEvent * event = 0;
71 
72  try
73  {
74  event = packageSelector->findDialog()->waitForEvent();
75  }
76  catch ( YUIException & uiEx )
77  {
78  YUI_CAUGHT( uiEx );
79  }
80  catch ( std::exception & e)
81  {
82  yuiError() << "Caught std::exception: " << e.what() << "\n"
83  << "This is a libzypp problem. Do not file a bug against the UI!"
84  << endl;
85  }
86  catch (...)
87  {
88  yuiError() << "Caught unspecified exception.\n"
89  << "This is a libzypp problem. Do not file a bug against the UI!"
90  << endl;
91  }
92 
93  return event;
94 }
95 
96 
97 void YQUI::makeScreenShot( string stl_filename )
98 {
99  //
100  // Grab the pixels off the screen
101  //
102 
103  QWidget * dialog = (QWidget *) YDialog::currentDialog()->widgetRep();
104  YUI_CHECK_PTR( dialog );
105  QWidget * topLevelWidget = dialog->window();
106  YUI_CHECK_PTR( topLevelWidget );
107  QWindow * window = topLevelWidget->windowHandle();
108  YUI_CHECK_PTR( window );
109  QPixmap screenShot = window->screen()->grabWindow( window->winId() );
110  XSync( QX11Info::display(), false );
111  QString fileName ( stl_filename.c_str() );
112  bool interactive = false;
113 
114  if ( fileName.isEmpty() )
115  {
116  interactive = true;
117 
118  // Open a file selection box. Figure out a reasonable default
119  // directory / file name.
120 
121  //
122  // Initialize screen shot directory
123  //
124 
125  QString home = QDir::homePath();
126  char * ssdir = getenv( "Y2SCREENSHOTS" );
127  QString dir = ssdir ? fromUTF8( ssdir ) : "yast2-screen-shots";
128 
129  if ( home == "/" )
130  {
131  // Special case: $HOME is not set. This is normal in the inst-sys.
132  // In this case, rather than simply dumping all screen shots into
133  // /tmp which is world-writable, let's try to create a subdirectory
134  // below /tmp with restrictive permissions.
135  // If that fails, trust nobody - in particular, do not suggest /tmp
136  // as the default in the file selection box.
137 
138  dir = "/tmp/" + dir;
139 
140  if ( mkdir( toUTF8( dir ).c_str(), 0700 ) == -1 )
141  dir = "";
142  }
143  else
144  {
145  // For all others let's create a directory ~/yast2-screen-shots and
146  // simply ignore if this is already present. This gives the user a
147  // chance to create symlinks to a better location if he wishes so.
148 
149  dir = home + "/" + dir;
150  (void) mkdir( toUTF8( dir ).c_str(), 0750 );
151  }
152 
153 
154  //
155  // Figure out a file name
156  //
157 
158  const char * baseName = "yast2";
159 
160  int no = screenShotNo[ baseName ];
161  fileName = QString( "%1/%2-%3.png" )
162  .arg( dir ) // %1
163  .arg( baseName ) // %2
164  .arg( no, // %3
165  3, // fieldWidth (positive aligns right)
166  10, // base
167  QChar( '0' ) ); // fillChar
168 
169  yuiDebug() << "Screenshot: " << fileName << endl;
170 
171  fileName = YQApplication::askForSaveFileName( fileName,
172  QString( "*.png" ) ,
173  _( "Save screen shot to..." ) );
174 
175  if ( fileName.isEmpty() )
176  {
177  yuiDebug() << "Save screen shot canceled by user" << endl;
178  return;
179  }
180 
181  screenShotNo.insert( baseName, ++no );
182  } // if fileName.isEmpty()
183 
184 
185  //
186  // Actually save the screen shot
187  //
188 
189  yuiDebug() << "Saving screen shot to " << fileName << endl;
190  bool success = screenShot.save( fileName, "PNG" );
191 
192  if ( ! success )
193  {
194  yuiError() << "Couldn't save screen shot " << fileName << endl;
195 
196  if ( interactive )
197  {
198  QWidget* parent = 0;
199  YDialog * currentDialog = YDialog::currentDialog( false );
200 
201  if (currentDialog)
202  parent = (QWidget *) currentDialog->widgetRep();
203 
204  QMessageBox::warning( parent, // parent
205  "Error", // caption
206  QString( "Couldn't save screen shot\nto %1" ).arg( fileName ),
207  QMessageBox::Ok | QMessageBox::Default, // button0
208  Qt::NoButton, // button1
209  Qt::NoButton ); // button2
210  }
211  }
212 }
213 
214 
216 {
217  QString fileName = YQApplication::askForSaveFileName( QString( "/tmp/y2logs.tgz" ), // startWith
218  QString( "*.tgz *.tar.gz" ), // filter
219  QString( "Save y2logs to..." ) ); // headline
220 
221  QWidget* parent = 0;
222  YDialog * currentDialog = YDialog::currentDialog( false );
223 
224  if (currentDialog)
225  parent = (QWidget *) currentDialog->widgetRep();
226 
227  if ( ! fileName.isEmpty() )
228  {
229  QString saveLogsCommand = "/usr/sbin/save_y2logs";
230 
231  if ( access( saveLogsCommand.toLatin1(), X_OK ) == 0 )
232  {
233  saveLogsCommand += " '" + fileName + "'";
234  yuiMilestone() << "Saving y2logs: " << saveLogsCommand << endl;
235  int result = system( qPrintable( saveLogsCommand ) );
236 
237  if ( result != 0 )
238  {
239  yuiError() << "Error saving y2logs: \"" << saveLogsCommand
240  << "\" exited with " << result
241  << endl;
242 
243  QMessageBox::warning( parent, // parent
244  "Error", // caption
245  QString( "Couldn't save y2logs to %1 - "
246  "exit code %2" ).arg( fileName ).arg( result ),
247  QMessageBox::Ok | QMessageBox::Default, // button0
248  QMessageBox::NoButton, // button1
249  QMessageBox::NoButton ); // button2
250  }
251  else
252  {
253  yuiMilestone() << "y2logs saved to " << fileName << endl;
254  }
255  }
256  else
257  {
258  yuiError() << "Error saving y2logs: Command \""
259  << saveLogsCommand << "\" not found"
260  << endl;
261 
262  QMessageBox::warning( parent, // parent
263  "Error", // caption
264  QString( "Couldn't save y2logs to %1:\n"
265  "Command %2 not found" ).arg( fileName ).arg( saveLogsCommand ),
266  QMessageBox::Ok | QMessageBox::Default, // button0
267  QMessageBox::NoButton, // button1
268  QMessageBox::NoButton ); // button2
269  }
270  }
271 }
272 
273 
275 {
276  bool okButtonPressed = false;
277  QStringList items;
278  items << "Debug logging off"
279  << "Debug logging on";
280 
281 
282  QWidget* parent = 0;
283  YDialog * currentDialog = YDialog::currentDialog( false );
284 
285  if (currentDialog)
286  parent = (QWidget *) currentDialog->widgetRep();
287 
288  QString result = QInputDialog::getItem( parent,
289  _("YaST Logging"),
290  _("Configure YaST Logging:"),
291  items, 0,
292  YUILog::debugLoggingEnabled() ? 1 : 0,
293  &okButtonPressed );
294  if ( okButtonPressed )
295  {
296  YUILog::enableDebugLogging( result.endsWith( "on" ) );
297  yuiMilestone() << "Changing logging: " << result << endl;
298  }
299 }
300 
301 
303 {
304  QWidget* parent = 0;
305  YDialog * currentDialog = YDialog::currentDialog( false );
306 
307  if (currentDialog)
308  parent = (QWidget *) currentDialog->widgetRep();
309 
310 
311  if ( YMacro::recording() )
312  {
313  YMacro::endRecording();
314  normalCursor();
315 
316  QMessageBox::information( parent, // parent
317  "YaST2 Macro Recorder", // caption
318  "Macro recording done.", // text
319  QMessageBox::Ok | QMessageBox::Default, // button0
320  QMessageBox::NoButton, // button1
321  QMessageBox::NoButton ); // button2
322  }
323  else
324  {
325  normalCursor();
326 
327  QString filename =
328  QFileDialog::getSaveFileName( parent,
329  "Select Macro File to Record to",
330  DEFAULT_MACRO_FILE_NAME, // startWith
331  "*.ycp", // filter
332  0, // selectedFilter
333  QFileDialog::DontUseNativeDialog
334  );
335 
336  if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
337  {
338  YMacro::record( toUTF8( filename ) );
339  }
340  }
341 }
342 
343 
345 {
346  normalCursor();
347 
348  QWidget* parent = 0;
349  YDialog * currentDialog = YDialog::currentDialog( false );
350 
351  if (currentDialog)
352  parent = (QWidget *) currentDialog->widgetRep();
353 
354 
355  QString filename =
356  QFileDialog::getOpenFileName( parent,
357  "Select Macro File to Play",
358  DEFAULT_MACRO_FILE_NAME, // startWith
359  "*.ycp", 0, QFileDialog::DontUseNativeDialog );
360  busyCursor();
361 
362  if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
363  {
364  YMacro::play( toUTF8( filename ) );
365 
366  // Do special magic to get out of any UserInput() loop right now
367  // without doing any harm - otherwise this would hang until the next
368  // mouse click on a PushButton etc.
369 
370  sendEvent( new YEvent() );
371  }
372 }
void askConfigureLogging()
Open dialog to configure logging.
void makeScreenShot(std::string filename)
Make a screen shot in .png format and save it to &#39;filename&#39;.
void askSaveLogs()
Open file selection box and let the user save y2logs to that location.
virtual YEvent * runPkgSelection(YWidget *packageSelector)
UI-specific runPkgSeleciton method: Start the package selection.
void toggleRecordMacro()
Toggle macro recording (activated by Ctrl-Shift-Alt-M): Stop macro recording if it is in progress...
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:480
virtual std::string askForSaveFileName(const std::string &startWith, const std::string &filter, const std::string &headline)
Open a file selection box and prompt the user for a file to save data to.
void busyCursor()
Show mouse cursor indicating busy state.
Definition: YQUI.cc:562
void normalCursor()
Show normal mouse cursor not indicating busy status.
Definition: YQUI.cc:568
void askPlayMacro()
Open file selection box and ask for a macro file to play (activated by Ctrl-Shift-Alt-P) ...