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