libyui-qt  2.52.2
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 
64 
65 
66 YEvent * YQUI::runPkgSelection( YWidget * packageSelector )
67 {
68  YUI_CHECK_PTR( packageSelector );
69  YEvent * event = 0;
70 
71  try
72  {
73  event = packageSelector->findDialog()->waitForEvent();
74  }
75  catch ( YUIException & uiEx )
76  {
77  YUI_CAUGHT( uiEx );
78  }
79  catch ( std::exception & e)
80  {
81  yuiError() << "Caught std::exception: " << e.what() << "\n"
82  << "This is a libzypp problem. Do not file a bug against the UI!"
83  << endl;
84  }
85  catch (...)
86  {
87  yuiError() << "Caught unspecified exception.\n"
88  << "This is a libzypp problem. Do not file a bug against the UI!"
89  << endl;
90  }
91 
92  return event;
93 }
94 
95 
96 void YQUI::makeScreenShot( string stl_filename )
97 {
98  //
99  // Grab the pixels off the screen
100  //
101 
102  QWidget * dialog = (QWidget *) YDialog::currentDialog()->widgetRep();
103  YUI_CHECK_PTR( dialog );
104  QWidget * topLevelWidget = dialog->window();
105  YUI_CHECK_PTR( topLevelWidget );
106  QWindow * window = topLevelWidget->windowHandle();
107  YUI_CHECK_PTR( window );
108  QPixmap screenShot = window->screen()->grabWindow( window->winId() );
109  XSync( QX11Info::display(), false );
110  QString fileName ( stl_filename.c_str() );
111  bool interactive = false;
112 
113  if ( fileName.isEmpty() )
114  {
115  interactive = true;
116 
117  // Open a file selection box. Figure out a reasonable default
118  // directory / file name.
119 
120  //
121  // Initialize screen shot directory
122  //
123 
124  QString home = QDir::homePath();
125  char * ssdir = getenv( "Y2SCREENSHOTS" );
126  QString dir = ssdir ? fromUTF8( ssdir ) : "yast2-screen-shots";
127 
128  if ( home == "/" )
129  {
130  // Special case: $HOME is not set. This is normal in the inst-sys.
131  // In this case, rather than simply dumping all screen shots into
132  // /tmp which is world-writable, let's try to create a subdirectory
133  // below /tmp with restrictive permissions.
134  // If that fails, trust nobody - in particular, do not suggest /tmp
135  // as the default in the file selection box.
136 
137  dir = "/tmp/" + dir;
138 
139  if ( mkdir( toUTF8( dir ).c_str(), 0700 ) == -1 )
140  dir = "";
141  }
142  else
143  {
144  // For all others let's create a directory ~/yast2-screen-shots and
145  // simply ignore if this is already present. This gives the user a
146  // chance to create symlinks to a better location if he wishes so.
147 
148  dir = home + "/" + dir;
149  (void) mkdir( toUTF8( dir ).c_str(), 0750 );
150  }
151 
152 
153  //
154  // Figure out a file name
155  //
156 
157  const char * baseName = "yast2";
158 
159  int no = screenShotNo[ baseName ];
160  fileName = QString( "%1/%2-%3.png" )
161  .arg( dir ) // %1
162  .arg( baseName ) // %2
163  .arg( no, // %3
164  3, // fieldWidth (positive aligns right)
165  10, // base
166  QChar( '0' ) ); // fillChar
167 
168  yuiDebug() << "Screenshot: " << fileName << endl;
169 
170  fileName = YQApplication::askForSaveFileName( fileName,
171  QString( "*.png" ) ,
172  _( "Save screen shot to..." ) );
173 
174  if ( fileName.isEmpty() )
175  {
176  yuiDebug() << "Save screen shot canceled by user" << endl;
177  return;
178  }
179 
180  screenShotNo.insert( baseName, ++no );
181  } // if fileName.isEmpty()
182 
183 
184  //
185  // Actually save the screen shot
186  //
187 
188  yuiDebug() << "Saving screen shot to " << fileName << endl;
189  bool success = screenShot.save( fileName, "PNG" );
190 
191  if ( ! success )
192  {
193  yuiError() << "Couldn't save screen shot " << fileName << endl;
194 
195  if ( interactive )
196  {
197  QWidget* parent = 0;
198  YDialog * currentDialog = YDialog::currentDialog( false );
199 
200  if (currentDialog)
201  parent = (QWidget *) currentDialog->widgetRep();
202 
203  QMessageBox::warning( parent, // parent
204  "Error", // caption
205  QString( "Couldn't save screen shot\nto %1" ).arg( fileName ),
206  QMessageBox::Ok | QMessageBox::Default, // button0
207  Qt::NoButton, // button1
208  Qt::NoButton ); // button2
209  }
210  }
211 }
212 
213 
215 {
216  QString fileName = YQApplication::askForSaveFileName( QString( "/tmp/y2logs.tgz" ), // startWith
217  QString( "*.tgz *.tar.gz" ), // filter
218  QString( "Save y2logs to..." ) ); // headline
219 
220  QWidget* parent = 0;
221  YDialog * currentDialog = YDialog::currentDialog( false );
222 
223  if (currentDialog)
224  parent = (QWidget *) currentDialog->widgetRep();
225 
226  if ( ! fileName.isEmpty() )
227  {
228  QString saveLogsCommand = "/usr/sbin/save_y2logs";
229 
230  if ( access( saveLogsCommand.toLatin1(), X_OK ) == 0 )
231  {
232  saveLogsCommand += " '" + fileName + "'";
233  yuiMilestone() << "Saving y2logs: " << saveLogsCommand << endl;
234  int result = system( qPrintable( saveLogsCommand ) );
235 
236  if ( result != 0 )
237  {
238  yuiError() << "Error saving y2logs: \"" << saveLogsCommand
239  << "\" exited with " << result
240  << endl;
241 
242  QMessageBox::warning( parent, // parent
243  "Error", // caption
244  QString( "Couldn't save y2logs to %1 - "
245  "exit code %2" ).arg( fileName ).arg( result ),
246  QMessageBox::Ok | QMessageBox::Default, // button0
247  QMessageBox::NoButton, // button1
248  QMessageBox::NoButton ); // button2
249  }
250  else
251  {
252  yuiMilestone() << "y2logs saved to " << fileName << endl;
253  }
254  }
255  else
256  {
257  yuiError() << "Error saving y2logs: Command \""
258  << saveLogsCommand << "\" not found"
259  << endl;
260 
261  QMessageBox::warning( parent, // parent
262  "Error", // caption
263  QString( "Couldn't save y2logs to %1:\n"
264  "Command %2 not found" ).arg( fileName ).arg( saveLogsCommand ),
265  QMessageBox::Ok | QMessageBox::Default, // button0
266  QMessageBox::NoButton, // button1
267  QMessageBox::NoButton ); // button2
268  }
269  }
270 }
271 
272 
274 {
275  bool okButtonPressed = false;
276  QStringList items;
277  items << "Debug logging off"
278  << "Debug logging on";
279 
280 
281  QWidget* parent = 0;
282  YDialog * currentDialog = YDialog::currentDialog( false );
283 
284  if (currentDialog)
285  parent = (QWidget *) currentDialog->widgetRep();
286 
287  QString result = QInputDialog::getItem( parent,
288  _("YaST Logging"),
289  _("Configure YaST Logging:"),
290  items, 0,
291  YUILog::debugLoggingEnabled() ? 1 : 0,
292  &okButtonPressed );
293  if ( okButtonPressed )
294  {
295  YUILog::enableDebugLogging( result.endsWith( "on" ) );
296  yuiMilestone() << "Changing logging: " << result << endl;
297  }
298 }
299 
300 
302 {
303  QWidget* parent = 0;
304  YDialog * currentDialog = YDialog::currentDialog( false );
305 
306  if (currentDialog)
307  parent = (QWidget *) currentDialog->widgetRep();
308 
309 
310  if ( YMacro::recording() )
311  {
312  YMacro::endRecording();
313  normalCursor();
314 
315  QMessageBox::information( parent, // parent
316  "YaST2 Macro Recorder", // caption
317  "Macro recording done.", // text
318  QMessageBox::Ok | QMessageBox::Default, // button0
319  QMessageBox::NoButton, // button1
320  QMessageBox::NoButton ); // button2
321  }
322  else
323  {
324  normalCursor();
325 
326  QString filename =
327  QFileDialog::getSaveFileName( parent,
328  "Select Macro File to Record to",
329  DEFAULT_MACRO_FILE_NAME, // startWith
330  "*.ycp", // filter
331  0, // selectedFilter
332  QFileDialog::DontUseNativeDialog
333  );
334 
335  if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
336  {
337  YMacro::record( toUTF8( filename ) );
338  }
339  }
340 }
341 
342 
344 {
345  normalCursor();
346 
347  QWidget* parent = 0;
348  YDialog * currentDialog = YDialog::currentDialog( false );
349 
350  if (currentDialog)
351  parent = (QWidget *) currentDialog->widgetRep();
352 
353 
354  QString filename =
355  QFileDialog::getOpenFileName( parent,
356  "Select Macro File to Play",
357  DEFAULT_MACRO_FILE_NAME, // startWith
358  "*.ycp", 0, QFileDialog::DontUseNativeDialog );
359  busyCursor();
360 
361  if ( ! filename.isEmpty() ) // file selection dialog has been cancelled
362  {
363  YMacro::play( toUTF8( filename ) );
364 
365  // Do special magic to get out of any UserInput() loop right now
366  // without doing any harm - otherwise this would hang until the next
367  // mouse click on a PushButton etc.
368 
369  sendEvent( new YEvent() );
370  }
371 }
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) ...