Audacity  3.0.3
ScreenshotCommand.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity - A Digital Audio Editor
4  Copyright 1999-2018 Audacity Team
5  License: GPL v2 - see LICENSE.txt
6 
7  Dominic Mazzoni
8  Dan Horgan
9  James Crook
10 
11 ******************************************************************//*******************************************************************/
19 
20 
21 #include "ScreenshotCommand.h"
22 
23 #include <mutex>
24 
25 #include "LoadCommands.h"
26 #include "../Project.h"
27 #include <wx/toplevel.h>
28 #include <wx/dcscreen.h>
29 #include <wx/dcmemory.h>
30 #include <wx/settings.h>
31 #include <wx/bitmap.h>
32 #include <wx/valgen.h>
33 
34 #include "../AdornedRulerPanel.h"
35 #include "../BatchCommands.h"
36 #include "../TrackPanel.h"
37 #include "../effects/Effect.h"
38 #include "../toolbars/ToolManager.h"
39 #include "../Prefs.h"
40 #include "../ProjectWindow.h"
41 #include "../Shuttle.h"
42 #include "../ShuttleGui.h"
43 #include "../Track.h"
44 #include "CommandContext.h"
45 #include "CommandManager.h"
46 
48 { XO("Screenshot") };
49 
51 
52 
53 static const EnumValueSymbol
55 {
56  { XO("Window") },
57  { wxT("FullWindow"), XO("Full Window") },
58  { wxT("WindowPlus"), XO("Window Plus") },
59  { XO("Fullscreen") },
60  { XO("Toolbars") },
61  { XO("Effects") },
62  { XO("Scriptables") },
63  { XO("Preferences") },
64  { XO("Selectionbar") },
65  { wxT("SpectralSelection"), XO("Spectral Selection") },
66  { XO("Timer") },
67  { XO("Tools") },
68  { XO("Transport") },
69  { XO("Mixer") },
70  { XO("Meter") },
71  { wxT("PlayMeter"), XO("Play Meter") },
72  { wxT("RecordMeter"), XO("Record Meter") },
73  { XO("Edit") },
74  { XO("Device") },
75  { XO("Scrub") },
76  { XO("Play-at-Speed") },
77  { XO("Trackpanel") },
78  { XO("Ruler") },
79  { XO("Tracks") },
80  { wxT("FirstTrack"), XO("First Track") },
81  { wxT("FirstTwoTracks"), XO("First Two Tracks") },
82  { wxT("FirstThreeTracks"), XO("First Three Tracks") },
83  { wxT("FirstFourTracks"), XO("First Four Tracks") },
84  { wxT("SecondTrack"), XO("Second Track") },
85  { wxT("TracksPlus"), XO("Tracks Plus") },
86  { wxT("FirstTrackPlus"), XO("First Track Plus") },
87  { wxT("AllTracks"), XO("All Tracks") },
88  { wxT("AllTracksPlus"), XO("All Tracks Plus") },
89 };
90 
91 
92 static const EnumValueSymbol
94 {
95  // These are acceptable dual purpose internal/visible names
96  { XO("Blue") },
97  /* i18n-hint: This really means the color, not as in "white noise" */
98  { XC("White", "color") },
99  { XO("None") },
100 };
101 
102 
104 {
105  mbBringToTop=true;
106  mIgnore=NULL;
107 
108  static std::once_flag flag;
109  std::call_once( flag, []{
112  });
113 }
114 
116  S.Define( mPath, wxT("Path"), wxT(""));
117  S.DefineEnum( mWhat, wxT("CaptureWhat"), kwindow,kCaptureWhatStrings, nCaptureWhats );
118  S.DefineEnum( mBack, wxT("Background"), kNone, kBackgroundStrings, nBackgrounds );
119  S.Define( mbBringToTop, wxT("ToTop"), true );
120  return true;
121 };
122 
124 {
125  S.AddSpace(0, 5);
126 
127  S.StartMultiColumn(2, wxALIGN_CENTER);
128  {
129  S.TieTextBox( XXO("Path:"), mPath);
130  S.TieChoice( XXO("Capture What:"),
132  S.TieChoice( XXO("Background:"),
134  S.TieCheckBox( XXO("Bring To Top"), mbBringToTop);
135  }
136  S.EndMultiColumn();
137 }
138 
139 // static member variable.
140 void (*ScreenshotCommand::mIdleHandler)(wxIdleEvent& event) = NULL;
142 // This static variable is used to get from an idle event to the screenshot
143 // command that caused the idle event interception to be set up.
145 
146 // IdleHandler is expected to be called from EVT_IDLE when a dialog has been
147 // fully created. Usually the dialog will have been created by invoking
148 // an effects gui.
149 void IdleHandler(wxIdleEvent& event){
150  event.Skip();
151  wxWindow * pWin = dynamic_cast<wxWindow*>(event.GetEventObject());
152  wxASSERT( pWin );
153  pWin->Unbind(wxEVT_IDLE, IdleHandler);
155  // We have the relevant window, so go and capture it.
158 }
159 
161 {
163  pIdleHandlerProject = &project;
164 }
165 
167 {
168  wxWindow *front = NULL;
169  wxWindow *proj = wxGetTopLevelParent( ProjectWindow::Find( project ) );
170 
171  for (auto & win : wxTopLevelWindows)
172  {
173  win = wxGetTopLevelParent(win);
174  if (win != mIgnore && win != proj && win->IsShown()) {
175  front = win;
176  break;
177  }
178  }
179 
180  if (!front || !front->IsTopLevel()) {
181  return (wxTopLevelWindow *)proj;
182  }
183 
184  return (wxTopLevelWindow *)front;
185 }
186 
188 {
189  wxRect r;
190 
191  r.x = 16;
192  r.y = 16;
193  r.width = r.x * 2;
194  r.height = r.y * 2;
195 
196  return r;
197 }
198 
199 static void Yield()
200 {
201  int cnt;
202  for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) {
203  wxMilliSleep(10);
204  }
205  wxMilliSleep(200);
206  for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) {
207  wxMilliSleep(10);
208  }
209 }
210 
212  const CommandContext & context,
213  const wxString &filename,
214  wxWindow *window, wxRect r,
215  bool bg)
216 {
217  int width = r.width;
218  int height = r.height;
219  if( r.width == 0 )
220  return false;
221  if (window ) {
222  wxWindow * win = window;
223  wxTopLevelWindow * top_win= nullptr;
224  if( !window->IsTopLevel())
225  win = wxGetTopLevelParent(window);
226  top_win = dynamic_cast<wxTopLevelWindow*>( win );
227  if( (!bHasBringToTop || mbBringToTop) && (!top_win || !top_win->IsActive()) ){
228  win->Raise();
229  Yield();
230  }
231  }
232 
233 
234  int screenW, screenH;
235  wxDisplaySize(&screenW, &screenH);
236  // Bug 1378 workaround.
237  // wx 3.0.2 has a bug in Blit from ScreenDC where in default mode
238  // much is drawn transparent - including for example black text!
239  // Forcing 24 bit here is a workaround.
240  wxBitmap full(screenW, screenH, 24);
241 
242  wxScreenDC screenDC;
243  wxMemoryDC fullDC;
244 
245 #if defined(__WXMAC__) && !wxCHECK_VERSION(3, 0, 0)
246  full = DoGetAsBitmap(NULL);
247 #else
248  // We grab the whole screen image since there seems to be a problem with
249  // using non-zero source coordinates on OSX. (as of wx2.8.9)
250  fullDC.SelectObject(full);
251  fullDC.Blit(0, 0, screenW, screenH, &screenDC, 0, 0);
252  fullDC.SelectObject(wxNullBitmap);
253 #endif
254 
255  //wxRect r(x, y, width, height);
256 
257 
258  // Convert to screen coordinates if needed
259  if (window && window->GetParent() && !window->IsTopLevel()) {
260  r.SetPosition(window->GetParent()->ClientToScreen(r.GetPosition()));
261  }
262 
263  // Ensure within bounds (x/y are negative on Windows when maximized)
264  r.Intersect(wxRect(0, 0, screenW, screenH));
265 
266  // Extract the actual image
267  wxBitmap part = full.GetSubBitmap(r);
268 
269  // Add a background
270  if (bg && mBackground) {
271  wxRect b = GetBackgroundRect();
272 
273  wxBitmap back(width + b.width, height + b.height);
274  fullDC.SelectObject(back);
275 
276  fullDC.SetBackground(wxBrush(mBackColor, wxBRUSHSTYLE_SOLID));
277  fullDC.Clear();
278 
279  fullDC.DrawBitmap(part, b.x, b.y);
280  fullDC.SelectObject(wxNullBitmap);
281 
282  part = back;
283  }
284 
285  // Save the final image
286  wxImage image = part.ConvertToImage();
287  ::wxBell();
288 
289  if (image.SaveFile(filename)) {
290  // flush
291  context.Status( wxString::Format( _("Saved %s"), filename ), true );
292  }
293  else {
294  context.Error(
295  wxString::Format( _("Error trying to save file: %s"), filename ) );
296  return false;
297  }
298  return true;
299 }
300 
302  const CommandContext & context,
303  ToolManager *man, int type, const wxString &name)
304 {
305  bool visible = man->IsVisible(type);
306  if (!visible) {
307  man->ShowHide(type);
308  Yield();
309  }
310 
311  wxWindow *w = man->GetToolBar(type);
312  int x = 0, y = 0;
313  int width, height;
314 
315  w->ClientToScreen(&x, &y);
316  w->GetParent()->ScreenToClient(&x, &y);
317  w->GetClientSize(&width, &height);
318 
319  bool result = Capture(context, name, w, wxRect(x, y, width, height));
320 
321  if (!visible) {
322  man->ShowHide(type);
323  if (mIgnore)
324  mIgnore->Raise();
325  }
326  return result;
327 }
328 
330  const CommandContext & context,
331  wxWindow *win, const wxString &FileName)
332 {
333  int x = 0, y = 0;
334  int width, height;
335 
336  win->ClientToScreen(&x, &y);
337  win->GetParent()->ScreenToClient(&x, &y);
338  win->GetClientSize(&width, &height);
339 
340  return Capture(context, FileName, win, wxRect(x, y, width, height));
341 }
342 
343 // Handed a dialog, which it is given the option to capture.
344 bool ScreenshotCommand::MayCapture( wxDialog * pDlg )
345 {
346  if( mIdleHandler == NULL )
347  return false;
348  pDlg->Bind( wxEVT_IDLE, mIdleHandler );
349  mIdleHandler = NULL;
350  pDlg->ShowModal();
351  return true;
352 }
353 
355  const CommandContext & context,
356  wxWindow * pWin )
357 {
358  wxDialog * pDlg = dynamic_cast<wxDialog*>(pWin);
359  if( !pDlg ){
360  wxLogDebug("Event from bogus dlg" );
361  return;
362  }
363 
364  wxPoint Pos = pDlg->GetScreenPosition();
365  wxSize Siz = pDlg->GetSize();
366  wxString Title = pDlg->GetTitle();
367 
368  // Remove '/' from "Sliding Time Scale/Pitch Shift..."
369  // and any other effects that have illegal filename characters.
370  Title.Replace( "/", "" );
371  Title.Replace( ":", "" );
372  wxString Name = mDirToWriteTo + Title + ".png";
373 
374  wxLogDebug("Taking screenshot of window %s (%i,%i,%i,%i)", Name,
375  Pos.x, Pos.y, Siz.x, Siz.y );
376  // This delay is needed, as dialogs take a moment or two to fade in.
377  wxMilliSleep( 400 );
378  // JKC: The border of 7 pixels was determined from a trial capture and then measuring
379  // in the GIMP. I'm unsure where the border comes from.
380  Capture( context, Name, pDlg, wxRect((int)Pos.x+7, (int)Pos.y, (int)Siz.x-14, (int)Siz.y-7) );
381 
382  // We've captured the dialog, so now dismiss the dialog.
383  wxCommandEvent Evt( wxEVT_BUTTON, wxID_CANCEL );
384  pDlg->GetEventHandler()->AddPendingEvent( Evt );
385 }
386 
388  const CommandContext & context,
389  AudacityProject * pProject, const wxString &FileName ){
390  (void)&FileName;//compiler food.
391  (void)&context;
392  CommandManager &commandManager = CommandManager::Get( *pProject );
393 
394  // Yucky static variables. Is there a better way? The problem is that we need the
395  // idle callback to know more about what to do.
396 #ifdef __WXMSW__
397  mDirToWriteTo = FileName.BeforeLast('\\') + "\\";
398 #else
399  mDirToWriteTo = FileName.BeforeLast('/') + "/";
400 #endif
401  mpShooter = this;
402  const int nPrefsPages = 19;
403 
404  for( int i=0;i<nPrefsPages;i++){
405  // The handler is cleared each time it is used.
406  SetIdleHandler( context.project );
407  gPrefs->Write(wxT("/Prefs/PrefsCategory"), (long)i);
408  gPrefs->Flush();
409  CommandID Command{ wxT("Preferences") };
410  const CommandContext projectContext( *pProject );
411  if( !MacroCommands::HandleTextualCommand( commandManager,
412  Command, projectContext, AlwaysEnabledFlag, true ) )
413  {
414  // using GET in a log message for devs' eyes only
415  wxLogDebug("Command %s not found", Command.GET() );
416  }
417  // This sleep is not needed, but gives user a chance to see the
418  // dialogs as they whizz by.
419  wxMilliSleep( 200 );
420  }
421 }
422 
424  const CommandContext & context,
425  AudacityProject * pProject, const wxString &FileName )
426 {
427  (void)pProject;
428  (void)&FileName;//compiler food.
429  (void)&context;
430 #define TRICKY_CAPTURE
431 #define CAPTURE_NYQUIST_TOO
432  // Commented out the effects that don't have dialogs.
433  // Also any problematic ones,
434  CaptureCommands( context, {
435 #ifdef TRICKY_CAPTURE
436  //"Contrast...", // renamed
437  "ContrastAnalyser",
438  //"Plot Spectrum...", // renamed
439  "PlotSpectrum",
440 
441  "Auto Duck...", // needs a track below.
442  //"Spectral edit multi tool",
443  "Spectral edit parametric EQ...", // Needs a spectral selection.
444  "Spectral edit shelves...",
445 
446  //"Noise Reduction...", // Exits twice...
447  //"SC4...", //Has 'Close' rather than 'Cancel'.
448 #endif
449  "Amplify...",
450  "Bass and Treble...",
451  "Change Pitch...",
452  "Change Speed...",
453  "Change Tempo...",
454  "Click Removal...",
455  "Compressor...",
456  "Distortion...",
457  "Echo...",
458  //"Equalization...",
459  "Filter Curve EQ...",
460  "Graphic EQ...",
461  //"Fade In",
462  //"Fade Out",
463  //"Invert",
464  "Normalize...",
465  "Paulstretch...",
466  "Phaser...",
467  //"Repair",
468  "Repeat...",
469  "Reverb...",
470  //"Reverse",
471  "Sliding Stretch...",
472  "Truncate Silence...",
473  "Wahwah...",
474  // Sole LADSPA effect...
475 #ifdef CAPTURE_NYQUIST_TOO
476  "Adjustable Fade...",
477  "Clip Fix...",
478  //"Crossfade Clips",
479  "Crossfade Tracks...",
480  "Delay...",
481  "High Pass Filter...",
482  "Limiter...",
483  "Low Pass Filter...",
484  "Notch Filter...",
485  "Nyquist Effects Prompt...",
486  //"Studio Fade Out",
487  "Tremolo...",
488  "Vocal Reduction and Isolation...",
489  "Vocal Remover...",
490  "Vocoder...",
491 #endif
492  // Generators.....
493  "Chirp...",
494  "DTMF Tones...",
495  "Noise...",
496  "Silence...",
497  "Tone...",
498 #ifdef CAPTURE_NYQUIST_TOO
499  "Pluck...",
500  "Rhythm Track...",
501  "Risset Drum...",
502  "Sample Data Import...",
503 #endif
504  // Analyzers...
505  "Find Clipping...",
506 #ifdef CAPTURE_NYQUIST_TOO
507  "Beat Finder...",
508  "Label Sounds...",
509  "Regular Interval Labels...",
510  "Sample Data Export...",
511 #endif
512  } );
513 }
514 
516  const CommandContext & context,
517  AudacityProject * pProject, const wxString &FileName )
518 {
519  (void)pProject;
520  (void)&FileName;//compiler food.
521  (void)&context;
522 
523  CaptureCommands( context, {
524  "SelectTime",
525  "SelectFrequencies",
526  "SelectTracks",
527  "SetTrackStatus",
528  "SetTrackAudio",
529  "SetTrackVisuals",
530  "GetPreference",
531  "SetPreference",
532  "SetClip",
533  "SetEnvelope",
534  "SetLabel",
535  "SetProject",
536 
537  "Select",
538  "SetTrack",
539  "GetInfo",
540  "Message",
541  "Help", // Help on individual commands
542  "Import2",
543  "Export2",
544  "OpenProject2",
545  "SaveProject2",
546  "Drag",
547  "CompareAudio",
548  "Screenshot",
549  } );
550 
551 }
552 
553 
555  const CommandContext & context, const wxArrayStringEx & Commands ){
556  AudacityProject * pProject = &context.project;
557  CommandManager &manager = CommandManager::Get( *pProject );
558  wxString Str;
559  // Yucky static variables. Is there a better way? The problem is that we need the
560  // idle callback to know more about what to do.
561 #ifdef __WXMSW__
562  mDirToWriteTo = mFileName.BeforeLast('\\') + "\\";
563 #else
564  mDirToWriteTo = mFileName.BeforeLast('/') + "/";
565 #endif
566  mpShooter = this;
567 
568  for( size_t i=0;i<Commands.size();i++){
569  // The handler is cleared each time it is used.
570  SetIdleHandler( context.project );
571  Str = Commands[i];
572  const CommandContext projectContext( *pProject );
573  if( !manager.HandleTextualCommand( Str, projectContext, AlwaysEnabledFlag, true ) )
574  {
575  wxLogDebug("Command %s not found", Str);
576  }
577  // This particular sleep is not needed, but gives user a chance to see the
578  // dialogs as they whizz by.
579  wxMilliSleep( 200 );
580  }
581 }
582 
583 wxString ScreenshotCommand::MakeFileName(const wxString &path, const wxString &basename)
584 {
585  // If the path is a full file name, then use it.
586  if( path.EndsWith( ".png" ) )
587  return path;
588 
589  // Otherwise make up a file name that has not been used already.
590  wxFileName prefixPath;
591  prefixPath.AssignDir(path);
592  wxString prefix = prefixPath.GetPath
593  (wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR);
594 
595  wxString filename;
596  int i = 0;
597  do {
598  filename.Printf(wxT("%s%s%03d.png"),
599  prefix, basename, i);
600  i++;
601  } while (::wxFileExists(filename));
602 
603  return filename;
604 }
605 
607 {
608  // Read the parameters that were passed in
609  mFilePath = mPath;
611 
612  // Build a suitable filename
614  kCaptureWhatStrings[ mCaptureMode ].Translation() );
615 
616  if (mBack == kBlue)
617  {
618  mBackground = true;
619  mBackColor = wxColour(51, 102, 153);
620  }
621  else if (mBack == kWhite)
622  {
623  mBackground = true;
624  mBackColor = wxColour(255, 255, 255);
625  }
626  else
627  {
628  mBackground = false;
629  }
630 
631 }
632 
633 wxRect ScreenshotCommand::GetWindowRect(wxTopLevelWindow *w){
634  int x = 0, y = 0;
635  int width, height;
636 
637  w->ClientToScreen(&x, &y);
638  w->GetClientSize(&width, &height);
639  return wxRect( x,y,width,height);
640 }
641 
642 wxRect ScreenshotCommand::GetFullWindowRect(wxTopLevelWindow *w){
643 
644  wxRect r = w->GetRect();
645  r.SetPosition(w->GetScreenPosition());
646  r = w->GetScreenRect();
647 
648 #if defined(__WXGTK__)
649  // In wxGTK, we need to include decoration sizes
650  r.width += (wxSystemSettings::GetMetric(wxSYS_BORDER_X, w) * 2);
651  r.height += wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, w) +
652  wxSystemSettings::GetMetric(wxSYS_BORDER_Y, w);
653 #endif
655  {
656  // background colour not selected but we want a background
657  wxRect b = GetBackgroundRect();
658  r.x = (r.x - b.x) >= 0 ? (r.x - b.x): 0;
659  r.y = (r.y - b.y) >= 0 ? (r.y - b.y): 0;
660  r.width += b.width;
661  r.height += b.height;
662  }
663 
664  return r;
665 }
666 
668  int width, height;
669  wxDisplaySize(&width, &height);
670 
671  return wxRect( 0,0,width,height);
672 }
673 
675  //AdornedRulerPanel *ruler = panel->mRuler;
676 
677  int h = panel->GetRuler()->GetRulerHeight();
678  int x = 0, y = -h;
679  int width, height;
680 
681  panel->ClientToScreen(&x, &y);
682  panel->GetParent()->ScreenToClient(&x, &y);
683  panel->GetClientSize(&width, &height);
684  return wxRect(x, y, width, height + h);
685 }
686 
688  int x = 0, y = 0;
689  int width, height;
690 
691  ruler->ClientToScreen(&x, &y);
692  ruler->GetParent()->ScreenToClient(&x, &y);
693  ruler->GetClientSize(&width, &height);
694  height = ruler->GetRulerHeight();
695  return wxRect( x, y, width, height);
696 }
697 
699  int x = 0, y = 0;
700  int width, height;
701 
702  panel->ClientToScreen(&x, &y);
703  panel->GetParent()->ScreenToClient(&x, &y);
704  panel->GetClientSize(&width, &height);
705 
706  return wxRect( x, y, width, height);
707 }
708 
710  auto FindRectangle = []( TrackPanel &panel, Track &t )
711  {
712  // This rectangle omits the focus ring about the track, and
713  // also within that, a narrow black border with a "shadow" below and
714  // to the right
715  wxRect rect = panel.FindTrackRect( &t );
716 
717  // Enlarge horizontally.
718  // PRL: perhaps it's one pixel too much each side, including some gray
719  // beyond the yellow?
720  rect.x = 0;
721  panel.GetClientSize(&rect.width, nullptr);
722 
723  // Enlarge vertically, enough to enclose the yellow focus border pixels
724  // Omit the outermost ring of gray pixels
725 
726  // (Note that TrackPanel paints its focus over the "top margin" of the
727  // rectangle allotted to the track, according to TrackView::GetY() and
728  // TrackView::GetHeight(), but also over the margin of the next track.)
729 
730  rect.height += kBottomMargin;
731  int dy = kTopMargin - 1;
732  rect.Inflate( 0, dy );
733 
734  // Reposition it relative to parent of panel
735  rect.SetPosition(
736  panel.GetParent()->ScreenToClient(
737  panel.ClientToScreen(
738  rect.GetPosition())));
739 
740  return rect;
741  };
742 
743  int count = 0;
744  for (auto t : TrackList::Get( *pProj ).Leaders()) {
745  count += 1;
746  if( count > n )
747  {
748  wxRect r = FindRectangle( *panel, *t );
749  return r;
750  }
751  }
752  return wxRect( 0,0,0,0);
753 }
754 
755 wxString ScreenshotCommand::WindowFileName(AudacityProject * proj, wxTopLevelWindow *w){
756  if (w != ProjectWindow::Find( proj ) && !w->GetTitle().empty()) {
758  kCaptureWhatStrings[ mCaptureMode ].Translation() +
759  (wxT("-") + w->GetTitle() + wxT("-")));
760  }
761  return mFileName;
762 }
763 
765 {
767  //Don't reset the toolbars to a known state.
768  //We will be capturing variations of them.
769  //ToolManager::Get( context.project ).Reset();
770 
771  wxTopLevelWindow *w = GetFrontWindow(&context.project);
772  if (!w)
773  return false;
774 
775  TrackPanel *panel = &TrackPanel::Get( context.project );
776  AdornedRulerPanel *ruler = panel->GetRuler();
777 
778  int nTracks = TrackList::Get( context.project ).size();
779 
780  int x1,y1,x2,y2;
781  w->ClientToScreen(&x1, &y1);
782  panel->ClientToScreen(&x2, &y2);
783 
784  wxPoint p( x2-x1, y2-y1);
785 
786  auto &toolManager = ToolManager::Get( context.project );
787 
788  switch (mCaptureMode) {
789  case kwindow:
790  return Capture(context, WindowFileName( &context.project, w ) , w, GetWindowRect(w));
791  case kfullwindow:
792  case kwindowplus:
793  return Capture(context, WindowFileName( &context.project, w ) , w, GetFullWindowRect(w));
794  case kfullscreen:
795  return Capture(context, mFileName, w,GetScreenRect());
796  case ktoolbars:
797  return CaptureDock(context, toolManager.GetTopDock(), mFileName);
798  case kscriptables:
799  CaptureScriptables(context, &context.project, mFileName);
800  break;
801  case keffects:
802  CaptureEffects(context, &context.project, mFileName);
803  break;
804  case kpreferences:
805  CapturePreferences(context, &context.project, mFileName);
806  break;
807  case kselectionbar:
808  return CaptureToolbar(context, &toolManager, SelectionBarID, mFileName);
809  case kspectralselection:
810  return CaptureToolbar(context, &toolManager, SpectralSelectionBarID, mFileName);
811  case ktimer:
812  return CaptureToolbar(context, &toolManager, TimeBarID, mFileName);
813  case ktools:
814  return CaptureToolbar(context, &toolManager, ToolsBarID, mFileName);
815  case ktransport:
816  return CaptureToolbar(context, &toolManager, TransportBarID, mFileName);
817  case kmixer:
818  return CaptureToolbar(context, &toolManager, MixerBarID, mFileName);
819  case kmeter:
820  return CaptureToolbar(context, &toolManager, MeterBarID, mFileName);
821  case krecordmeter:
822  return CaptureToolbar(context, &toolManager, RecordMeterBarID, mFileName);
823  case kplaymeter:
824  return CaptureToolbar(context, &toolManager, PlayMeterBarID, mFileName);
825  case kedit:
826  return CaptureToolbar(context, &toolManager, EditBarID, mFileName);
827  case kdevice:
828  return CaptureToolbar(context, &toolManager, DeviceBarID, mFileName);
829  case ktranscription:
830  return CaptureToolbar(context, &toolManager, TranscriptionBarID, mFileName);
831  case kscrub:
832  return CaptureToolbar(context, &toolManager, ScrubbingBarID, mFileName);
833  case ktrackpanel:
834  return Capture(context, mFileName, panel, GetPanelRect(panel));
835  case kruler:
836  return Capture(context, mFileName, ruler, GetRulerRect(ruler) );
837  case ktracks:
838  return Capture(context, mFileName, panel, GetTracksRect(panel));
839  case kfirsttrack:
840  return Capture(context, mFileName, panel, GetTrackRect( &context.project, panel, 0 ) );
841  case ksecondtrack:
842  return Capture(context, mFileName, panel, GetTrackRect( &context.project, panel, 1 ) );
843  case ktracksplus:
844  { wxRect r = GetTracksRect(panel);
845  r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
846  r.SetHeight( r.GetHeight() + ruler->GetRulerHeight() );
847  return Capture(context, mFileName, panel, r);
848  }
849  case kfirsttrackplus:
850  { wxRect r = GetTrackRect(&context.project, panel, 0 );
851  r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
852  r.SetHeight( r.GetHeight() + ruler->GetRulerHeight() );
853  return Capture(context, mFileName, panel, r );
854  }
855  case kfirsttwotracks:
856  { wxRect r = GetTrackRect( &context.project, panel, 0 );
857  r = r.Union( GetTrackRect( &context.project, panel, 1 ));
858  return Capture(context, mFileName, panel, r );
859  }
860  case kfirstthreetracks:
861  { wxRect r = GetTrackRect( &context.project, panel, 0 );
862  r = r.Union( GetTrackRect( &context.project, panel, 2 ));
863  return Capture(context, mFileName, panel, r );
864  }
865  case kfirstfourtracks:
866  { wxRect r = GetTrackRect( &context.project, panel, 0 );
867  r = r.Union( GetTrackRect( &context.project, panel, 3 ));
868  return Capture(context, mFileName, panel, r );
869  }
870  case kalltracks:
871  { wxRect r = GetTrackRect( &context.project, panel, 0 );
872  r = r.Union( GetTrackRect( &context.project, panel, nTracks-1 ));
873  return Capture(context, mFileName, panel, r );
874  }
875  case kalltracksplus:
876  { wxRect r = GetTrackRect( &context.project, panel, 0 );
877  r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
878  r.SetHeight( r.GetHeight() + ruler->GetRulerHeight() );
879  r = r.Union( GetTrackRect( &context.project, panel, nTracks-1 ));
880  return Capture(context, mFileName, panel, r );
881  }
882  default:
883  return false;
884  }
885 
886  return true;
887 }
TimeBarID
@ TimeBarID
Definition: ToolBar.h:82
ScreenshotCommand::ScreenshotCommand
ScreenshotCommand()
Definition: ScreenshotCommand.cpp:103
ScreenshotCommand::ktranscription
@ ktranscription
Definition: ScreenshotCommand.h:64
kCaptureWhatStrings
static const EnumValueSymbol kCaptureWhatStrings[ScreenshotCommand::nCaptureWhats]
Definition: ScreenshotCommand.cpp:54
LoadCommands.h
AdornedRulerPanel
This is an Audacity Specific ruler panel which additionally has border, selection markers,...
Definition: AdornedRulerPanel.h:28
ScreenshotCommand::kpreferences
@ kpreferences
Definition: ScreenshotCommand.h:51
ScreenshotCommand::GetBackgroundRect
wxRect GetBackgroundRect()
Definition: ScreenshotCommand.cpp:187
ScreenshotCommand::mWhat
int mWhat
Definition: ScreenshotCommand.h:90
IdleHandler
void IdleHandler(wxIdleEvent &event)
Definition: ScreenshotCommand.cpp:149
flag
static std::once_flag flag
Definition: WaveformView.cpp:1113
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
ScreenshotCommand::CaptureDock
bool CaptureDock(const CommandContext &Context, wxWindow *win, const wxString &fileName)
Definition: ScreenshotCommand.cpp:329
ScreenshotCommand::GetPanelRect
wxRect GetPanelRect(TrackPanel *panel)
Definition: ScreenshotCommand.cpp:674
ScreenshotCommand::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: ScreenshotCommand.cpp:115
ScreenshotCommand::GetFullWindowRect
wxRect GetFullWindowRect(wxTopLevelWindow *w)
Definition: ScreenshotCommand.cpp:642
ScreenshotCommand::kfullwindow
@ kfullwindow
Definition: ScreenshotCommand.h:45
ScreenshotCommand::kfirsttrack
@ kfirsttrack
Definition: ScreenshotCommand.h:68
ShuttleGuiBase::TieCheckBox
wxCheckBox * TieCheckBox(const TranslatableString &Prompt, bool &Var)
Definition: ShuttleGui.cpp:1603
ScreenshotCommand::kselectionbar
@ kselectionbar
Definition: ScreenshotCommand.h:52
ScreenshotCommand::ktimer
@ ktimer
Definition: ScreenshotCommand.h:54
ScreenshotCommand::kedit
@ kedit
Definition: ScreenshotCommand.h:61
ToolManager::Get
static ToolManager & Get(AudacityProject &project)
Definition: ToolManager.cpp:355
DeviceBarID
@ DeviceBarID
Definition: ToolBar.h:77
PlayMeterBarID
@ PlayMeterBarID
Definition: ToolBar.h:72
ScreenshotCommand::ktracks
@ ktracks
Definition: ScreenshotCommand.h:67
AudacityCommand::SetVetoDialogHook
static VetoDialogHook SetVetoDialogHook(VetoDialogHook hook)
Definition: AudacityCommand.cpp:58
Yield
static void Yield()
Definition: ScreenshotCommand.cpp:199
CommandManager.h
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2421
ScreenshotCommand::mDirToWriteTo
wxString mDirToWriteTo
Definition: ScreenshotCommand.h:112
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:222
XO
#define XO(s)
Definition: Internat.h:32
XC
#define XC(s, c)
Definition: Internat.h:38
ScreenshotCommand::MakeFileName
wxString MakeFileName(const wxString &path, const wxString &basename)
Definition: ScreenshotCommand.cpp:583
ScreenshotCommand::mPath
wxString mPath
Definition: ScreenshotCommand.h:95
ScreenshotCommand::CaptureScriptables
void CaptureScriptables(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
Definition: ScreenshotCommand.cpp:515
TrackPanel::FindTrackRect
wxRect FindTrackRect(const Track *target)
Definition: TrackPanel.cpp:1488
Effect::SetVetoDialogHook
static VetoDialogHook SetVetoDialogHook(VetoDialogHook hook)
Definition: Effect.cpp:74
CommandManager::HandleTextualCommand
TextualCommandResult HandleTextualCommand(const CommandID &Str, const CommandContext &context, CommandFlag flags, bool alwaysEnabled)
Definition: CommandManager.cpp:1277
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:61
ScreenshotCommand::kscriptables
@ kscriptables
Definition: ScreenshotCommand.h:50
ScreenshotCommand::kmeter
@ kmeter
Definition: ScreenshotCommand.h:58
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1212
ScreenshotCommand::ktoolbars
@ ktoolbars
Definition: ScreenshotCommand.h:48
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
ScreenshotCommand::mIgnore
wxWindow * mIgnore
Definition: ScreenshotCommand.h:108
ScreenshotCommand::ksecondtrack
@ ksecondtrack
Definition: ScreenshotCommand.h:72
TransportBarID
@ TransportBarID
Definition: ToolBar.h:68
anonymous_namespace{TimeTrackVRulerControls.cpp}::ruler
Ruler & ruler()
Definition: TimeTrackVRulerControls.cpp:34
TrackPanel
The TrackPanel class coordinates updates and operations on the main part of the screen which contains...
Definition: TrackPanel.h:64
ScreenshotCommand::mBackground
bool mBackground
Definition: ScreenshotCommand.h:110
ScreenshotCommand::ktracksplus
@ ktracksplus
Definition: ScreenshotCommand.h:73
wxArrayStringEx
Definition: MemoryX.h:663
ScreenshotCommand::mFileName
wxString mFileName
Definition: ScreenshotCommand.h:115
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterface.h:60
ToolManager::IsVisible
bool IsVisible(int type)
Definition: ToolManager.cpp:1081
ScreenshotCommand::kfirsttwotracks
@ kfirsttwotracks
Definition: ScreenshotCommand.h:69
ShuttleGuiBase::TieTextBox
wxTextCtrl * TieTextBox(const TranslatableString &Caption, wxString &Value, const int nChars=0)
Definition: ShuttleGui.cpp:1626
ScreenshotCommand::mFilePath
wxString mFilePath
Definition: ScreenshotCommand.h:114
BuiltinCommandsModule::Registration
Definition: LoadCommands.h:41
ToolManager::ShowHide
void ShowHide(int type)
Definition: ToolManager.cpp:1103
ScreenshotCommand::WindowFileName
wxString WindowFileName(AudacityProject *proj, wxTopLevelWindow *w)
Definition: ScreenshotCommand.cpp:755
ToolsBarID
@ ToolsBarID
Definition: ToolBar.h:69
ScreenshotCommand::mIdleHandler
static void(* mIdleHandler)(wxIdleEvent &event)
Definition: ScreenshotCommand.h:144
CommandContext::Status
virtual void Status(const wxString &message, bool bFlush=false) const
Definition: CommandContext.cpp:63
pIdleHandlerProject
static AudacityProject * pIdleHandlerProject
Definition: ScreenshotCommand.cpp:141
CommandContext.h
ScreenshotCommand::mBack
int mBack
Definition: ScreenshotCommand.h:94
ScreenshotCommand::GetDerivedParams
void GetDerivedParams()
Definition: ScreenshotCommand.cpp:606
ScreenshotCommand::SetIdleHandler
static void SetIdleHandler(AudacityProject &project)
Definition: ScreenshotCommand.cpp:160
XXO
#define XXO(s)
Definition: Internat.h:45
ToolManager::GetToolBar
ToolBar * GetToolBar(int type) const
Definition: ToolManager.cpp:1028
ScreenshotCommand::kBlue
@ kBlue
Definition: ScreenshotCommand.h:36
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:22
ScreenshotCommand::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: ScreenshotCommand.cpp:123
ScreenshotCommand::kalltracks
@ kalltracks
Definition: ScreenshotCommand.h:75
ScreenshotCommand::bHasBringToTop
bool bHasBringToTop
Definition: ScreenshotCommand.h:98
ScreenshotCommand::kplaymeter
@ kplaymeter
Definition: ScreenshotCommand.h:59
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1203
MixerBarID
@ MixerBarID
Definition: ToolBar.h:73
kBackgroundStrings
static const EnumValueSymbol kBackgroundStrings[ScreenshotCommand::nBackgrounds]
Definition: ScreenshotCommand.cpp:93
ScreenshotCommand::kruler
@ kruler
Definition: ScreenshotCommand.h:66
ScrubbingBarID
@ ScrubbingBarID
Definition: ToolBar.h:76
ScreenshotCommand.h
ShuttleParams::DefineEnum
virtual void DefineEnum(int &var, const wxChar *key, const int vdefault, const EnumValueSymbol strings[], size_t nStrings)
Definition: Shuttle.cpp:339
Msgids
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Definition: Internat.cpp:267
name
const TranslatableString name
Definition: Distortion.cpp:98
ScreenshotCommand::nCaptureWhats
@ nCaptureWhats
Definition: ScreenshotCommand.h:77
ScreenshotCommand::kfirstthreetracks
@ kfirstthreetracks
Definition: ScreenshotCommand.h:70
CommandContext::Error
virtual void Error(const wxString &message) const
Definition: CommandContext.cpp:73
kBottomMargin
@ kBottomMargin
Definition: ViewInfo.h:106
ScreenshotCommand::GetWindowRect
wxRect GetWindowRect(wxTopLevelWindow *w)
Definition: ScreenshotCommand.cpp:633
kTopMargin
@ kTopMargin
Definition: ViewInfo.h:105
ScreenshotCommand::GetTrackRect
wxRect GetTrackRect(AudacityProject *pProj, TrackPanel *panel, int n)
Definition: ScreenshotCommand.cpp:709
ScreenshotCommand::Apply
bool Apply(const CommandContext &context) override
Definition: ScreenshotCommand.cpp:764
ScreenshotCommand::mCaptureMode
int mCaptureMode
Definition: ScreenshotCommand.h:116
ScreenshotCommand::kfirstfourtracks
@ kfirstfourtracks
Definition: ScreenshotCommand.h:71
ScreenshotCommand::MayCapture
static bool MayCapture(wxDialog *pDlg)
Definition: ScreenshotCommand.cpp:344
ScreenshotCommand::GetTracksRect
wxRect GetTracksRect(TrackPanel *panel)
Definition: ScreenshotCommand.cpp:698
ScreenshotCommand::mBackColor
wxColour mBackColor
Definition: ScreenshotCommand.h:111
ScreenshotCommand::ktrackpanel
@ ktrackpanel
Definition: ScreenshotCommand.h:65
ScreenshotCommand::ktransport
@ ktransport
Definition: ScreenshotCommand.h:56
TrackList::size
size_t size() const
Definition: Track.cpp:988
SelectionBarID
@ SelectionBarID
Definition: ToolBar.h:78
TranscriptionBarID
@ TranscriptionBarID
Definition: ToolBar.h:75
ScreenshotCommand::kfirsttrackplus
@ kfirsttrackplus
Definition: ScreenshotCommand.h:74
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:151
ScreenshotCommand::CaptureToolbar
bool CaptureToolbar(const CommandContext &Context, ToolManager *man, int type, const wxString &name)
Definition: ScreenshotCommand.cpp:301
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:495
TrackList::Leaders
auto Leaders() -> TrackIterRange< TrackType >
Definition: Track.h:1388
ScreenshotCommand::kwindowplus
@ kwindowplus
Definition: ScreenshotCommand.h:46
MacroCommands::HandleTextualCommand
static bool HandleTextualCommand(CommandManager &commandManager, const CommandID &Str, const CommandContext &context, CommandFlag flags, bool alwaysEnabled)
Definition: BatchCommands.cpp:593
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:238
TaggedIdentifier< CommandIdTag, false >
ScreenshotCommand::nBackgrounds
@ nBackgrounds
Definition: ScreenshotCommand.h:39
_
#define _(s)
Definition: Internat.h:76
MenuTable::Command
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:655
ScreenshotCommand::kfullscreen
@ kfullscreen
Definition: ScreenshotCommand.h:47
ScreenshotCommand::GetScreenRect
wxRect GetScreenRect()
Definition: ScreenshotCommand.cpp:667
ScreenshotCommand::krecordmeter
@ krecordmeter
Definition: ScreenshotCommand.h:60
ScreenshotCommand::GetRulerRect
wxRect GetRulerRect(AdornedRulerPanel *ruler)
Definition: ScreenshotCommand.cpp:687
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
ScreenshotCommand::CaptureCommands
void CaptureCommands(const CommandContext &Context, const wxArrayStringEx &Commands)
Definition: ScreenshotCommand.cpp:554
ScreenshotCommand::kalltracksplus
@ kalltracksplus
Definition: ScreenshotCommand.h:76
ScreenshotCommand::ktools
@ ktools
Definition: ScreenshotCommand.h:55
ScreenshotCommand::kmixer
@ kmixer
Definition: ScreenshotCommand.h:57
EditBarID
@ EditBarID
Definition: ToolBar.h:74
ScreenshotCommand::CaptureEffects
void CaptureEffects(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
Definition: ScreenshotCommand.cpp:423
ProjectWindow::Find
static ProjectWindow * Find(AudacityProject *pProject)
Definition: ProjectWindow.cpp:541
CommandManager
CommandManager implements a system for organizing all user-callable commands.
Definition: CommandManager.h:59
ScreenshotCommand::kdevice
@ kdevice
Definition: ScreenshotCommand.h:62
ScreenshotCommand::kwindow
@ kwindow
Definition: ScreenshotCommand.h:44
ScreenshotCommand::mbBringToTop
bool mbBringToTop
Definition: ScreenshotCommand.h:96
anonymous_namespace{ScreenshotCommand.cpp}::reg
BuiltinCommandsModule::Registration< ScreenshotCommand > reg
Definition: ScreenshotCommand.cpp:50
MeterBarID
@ MeterBarID
Definition: ToolBar.h:70
ScreenshotCommand::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: ScreenshotCommand.h:80
ScreenshotCommand::Capture
bool Capture(const CommandContext &Context, const wxString &basename, wxWindow *window, wxRect rect, bool bg=false)
Definition: ScreenshotCommand.cpp:211
ShuttleParams::Define
virtual void Define(bool &var, const wxChar *key, const bool vdefault, const bool vmin=false, const bool vmax=false, const bool vscl=false)
Definition: Shuttle.cpp:332
TrackPanel::GetRuler
AdornedRulerPanel * GetRuler()
Definition: TrackPanel.h:154
ScreenshotCommand::CapturePreferences
void CapturePreferences(const CommandContext &Context, AudacityProject *pProject, const wxString &fileName)
Definition: ScreenshotCommand.cpp:387
AdornedRulerPanel::GetRulerHeight
int GetRulerHeight()
Definition: AdornedRulerPanel.h:52
CommandManager::Get
static CommandManager & Get(AudacityProject &project)
Definition: CommandManager.cpp:202
ScreenshotCommand::GetFrontWindow
wxTopLevelWindow * GetFrontWindow(AudacityProject *project)
Definition: ScreenshotCommand.cpp:166
RecordMeterBarID
@ RecordMeterBarID
Definition: ToolBar.h:71
ScreenshotCommand::keffects
@ keffects
Definition: ScreenshotCommand.h:49
ScreenshotCommand::mpShooter
static ScreenshotCommand * mpShooter
Definition: ScreenshotCommand.h:143
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:52
ScreenshotCommand::CaptureWindowOnIdle
void CaptureWindowOnIdle(const CommandContext &context, wxWindow *pWin)
Definition: ScreenshotCommand.cpp:354
ShuttleGuiBase::TieChoice
wxChoice * TieChoice(const TranslatableString &Prompt, TranslatableString &Selected, const TranslatableStrings &choices)
Definition: ShuttleGui.cpp:1701
ScreenshotCommand::kWhite
@ kWhite
Definition: ScreenshotCommand.h:37
ScreenshotCommand::kscrub
@ kscrub
Definition: ScreenshotCommand.h:63
ScreenshotCommand
Implements a command for capturing various areas of the screen or project window. It's one big if-els...
Definition: ScreenshotCommand.h:32
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:638
ToolManager
class ToolManager
Definition: ToolManager.h:54
ScreenshotCommand::kNone
@ kNone
Definition: ScreenshotCommand.h:38
ScreenshotCommand::kspectralselection
@ kspectralselection
Definition: ScreenshotCommand.h:53