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