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