bool SetTrackStatusCommand::ApplyInner(const CommandContext & context, Track * t )
{
   //auto wt = dynamic_cast<WaveTrack *>(t);
   //auto pt = dynamic_cast<PlayableTrack *>(t);

   // You can get some intriguing effects by setting R and L channels to 
   // different values.
   if( bHasTrackName )
      t->SetName(mTrackName);

   // In stereo tracks, both channels need selecting/deselecting.
   if( bHasSelected )
      t->SetSelected(bSelected);

   // These ones don't make sense on the second channel of a stereo track.
   if( !bIsSecondChannel ){
      if( bHasFocused )
      {
         TrackPanel *panel = context.GetProject()->GetTrackPanel();
         if( bFocused)
            panel->SetFocusedTrack( t );
         else if( t== panel->GetFocusedTrack() )
            panel->SetFocusedTrack( nullptr );
      }
   }
   return true;
}
void ToolsToolBar::OnTool(wxCommandEvent & evt)
{
   mCurrentTool = evt.GetId() - firstTool;
   for (int i = 0; i < numTools; i++)
      if (i == mCurrentTool)
         mTool[i]->PushDown();
      else
         mTool[i]->PopUp();

#ifdef EXPERIMENTAL_SCRUBBING_BASIC
   if (0 != mCurrentTool) {
      AudacityProject *p = GetActiveProject();
      if (p) {
         TrackPanel *tp = p->GetTrackPanel();
         if (tp) {
            tp->StopScrubbing();
         }
      }
   }
#endif

   RedrawAllProjects();

   gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
                 IsDown(multiTool));
   gPrefs->Flush();
}
/// Sets the currently active tool
/// @param tool - The index of the tool to be used.
/// @param show - should we update the button display?
void ToolsToolBar::SetCurrentTool(int tool, bool show)
{
   //In multi-mode the current tool is shown by the
   //cursor icon.  The buttons are not updated.

#ifdef EXPERIMENTAL_SCRUBBING_BASIC
   if (tool != selectTool) {
      AudacityProject *p = GetActiveProject();
      if (p) {
         TrackPanel *tp = p->GetTrackPanel();
         if (tp) {
            tp->StopScrubbing();
         }
      }
   }
#endif

   bool leavingMulticlipMode =
      IsDown(multiTool) && show && tool != multiTool;

   if (leavingMulticlipMode)
      mTool[multiTool]->PopUp();

   if (tool != mCurrentTool || leavingMulticlipMode) {
      if (show)
         mTool[mCurrentTool]->PopUp();
      mCurrentTool=tool;
      if (show)
         mTool[mCurrentTool]->PushDown();
   }
   //JKC: ANSWER-ME: Why is this RedrawAllProjects() line required?
   //msmeyer: I think it isn't, we leave it out for 1.3.1 (beta), and
   // we'll see if anyone complains.
   // RedrawAllProjects();

   //msmeyer: But we instruct the projects to handle the cursor shape again
   if (show)
   {
      RefreshCursorForAllProjects();

      gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
                    IsDown(multiTool));
      gPrefs->Flush();
   }
}
int GetProjectInfoCommand::SendFocusedTrackIndex(CommandExecutionContext context)
{
   int returnVal=0;
   int focusTrackIndex=0;
   TrackPanel *panel = context.GetProject()->GetTrackPanel();
   Track* focusedTrack = panel->GetFocusedTrack();

   TrackListIterator iter(context.GetProject()->GetTracks());
   Track *t = iter.First();
   while (t)
   {
      if(t == focusedTrack)   // when we've found the focused track, we know the trackIndex
      {
        returnVal = focusTrackIndex;
        break;
      }
      focusTrackIndex++;
      t = iter.Next();
   }
   wxString trackIndexStr;
   trackIndexStr << returnVal;  // convert to a string to send over named pipe
   Status(trackIndexStr);
   return returnVal;
}
bool ScreenshotCommand::Apply(CommandExecutionContext context)
{
   // Read the parameters that were passed in
   wxString filePath    = GetString(wxT("FilePath"));
   wxString captureMode = GetString(wxT("CaptureMode"));
   wxString background  = GetString(wxT("Background"));

   // Build a suitable filename
   wxString fileName = MakeFileName(filePath, captureMode);

   if (background.IsSameAs(wxT("Blue")))
   {
      mBackground = true;
      mBackColor = wxColour(51, 102, 153);
   }
   else if (background.IsSameAs(wxT("White")))
   {
      mBackground = true;
      mBackColor = wxColour(255, 255, 255);
   }
   else
   {
      mBackground = false;
   }

   // Reset the toolbars to a known state
   context.proj->mToolManager->Reset();

   wxTopLevelWindow *w = GetFrontWindow(context.proj);
   if (!w)
   {
      return false;
   }

   if (captureMode.IsSameAs(wxT("window")))
   {
      int x = 0, y = 0;
      int width, height;

      w->ClientToScreen(&x, &y);
      w->GetClientSize(&width, &height);

      if (w != context.proj && w->GetTitle() != wxT("")) {
         fileName = MakeFileName(filePath,
               captureMode + (wxT("-") + w->GetTitle() + wxT("-")));
      }

      Capture(fileName, w, x, y, width, height);
   }
   else if (captureMode.IsSameAs(wxT("fullwindow"))
         || captureMode.IsSameAs(wxT("windowplus")))
   {

      wxRect r = w->GetRect();
      r.SetPosition(w->GetScreenPosition());
      r = w->GetScreenRect();

      if (w != context.proj && w->GetTitle() != wxT("")) {
         fileName = MakeFileName(filePath,
               captureMode + (wxT("-") + w->GetTitle() + wxT("-")));
      }

#if defined(__WXGTK__)
      // In wxGTK, we need to include decoration sizes
      r.width += (wxSystemSettings::GetMetric(wxSYS_BORDER_X, w) * 2);
      r.height += wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, w) +
         wxSystemSettings::GetMetric(wxSYS_BORDER_Y, w);
#endif
      if (!mBackground && captureMode.IsSameAs(wxT("windowplus")))
      {
         // background colour not selected but we want a background
         wxRect b = GetBackgroundRect();
         r.x = (r.x - b.x) >= 0 ? (r.x - b.x): 0;
         r.y = (r.y - b.y) >= 0 ? (r.y - b.y): 0;
         r.width += b.width;
         r.height += b.height;
      }

      Capture(fileName, w, r.x, r.y, r.width, r.height, true);
   }
   else if (captureMode.IsSameAs(wxT("fullscreen")))
   {
      int width, height;
      wxDisplaySize(&width, &height);

      Capture(fileName, w, 0, 0, width, height);
   }
   else if (captureMode.IsSameAs(wxT("toolbars")))
   {
      CaptureDock(context.proj->mToolManager->GetTopDock(), fileName);
   }
   else if (captureMode.IsSameAs(wxT("selectionbar")))
   {
      CaptureDock(context.proj->mToolManager->GetBotDock(), fileName);
   }
   else if (captureMode.IsSameAs(wxT("tools")))
   {
      CaptureToolbar(context.proj->mToolManager, ToolsBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("control")))
   {
      CaptureToolbar(context.proj->mToolManager, ControlBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("mixer")))
   {
      CaptureToolbar(context.proj->mToolManager, MixerBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("meter")))
   {
      CaptureToolbar(context.proj->mToolManager, MeterBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("edit")))
   {
      CaptureToolbar(context.proj->mToolManager, EditBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("device")))
   {
      CaptureToolbar(context.proj->mToolManager, DeviceBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("transcription")))
   {
      CaptureToolbar(context.proj->mToolManager, TranscriptionBarID, fileName);
   }
   else if (captureMode.IsSameAs(wxT("trackpanel")))
   {
      TrackPanel *panel = context.proj->mTrackPanel;
      AdornedRulerPanel *ruler = panel->mRuler;

      int h = ruler->GetRulerHeight();
      int x = 0, y = -h;
      int width, height;

      panel->ClientToScreen(&x, &y);
      panel->GetParent()->ScreenToClient(&x, &y);
      panel->GetClientSize(&width, &height);

      Capture(fileName, panel, x, y, width, height + h);
   }
   else if (captureMode.IsSameAs(wxT("ruler")))
   {
      TrackPanel *panel = context.proj->mTrackPanel;
      AdornedRulerPanel *ruler = panel->mRuler;

      int x = 0, y = 0;
      int width, height;

      ruler->ClientToScreen(&x, &y);
      ruler->GetParent()->ScreenToClient(&x, &y);
      ruler->GetClientSize(&width, &height);
      height = ruler->GetRulerHeight();

      Capture(fileName, ruler, x, y, width, height);
   }
   else if (captureMode.IsSameAs(wxT("tracks")))
   {
      TrackPanel *panel = context.proj->mTrackPanel;

      int x = 0, y = 0;
      int width, height;

      panel->ClientToScreen(&x, &y);
      panel->GetParent()->ScreenToClient(&x, &y);
      panel->GetClientSize(&width, &height);

      Capture(fileName, panel, x, y, width, height);
   }
   else if (captureMode.IsSameAs(wxT("firsttrack")))
   {
      TrackPanel *panel = context.proj->mTrackPanel;
      TrackListIterator iter(context.proj->GetTracks());
      Track * t = iter.First();
      if (!t) {
         return false;
      }
      wxRect r = panel->FindTrackRect(t, true);

      int x = 0, y = r.y - 3;
      int width, height;

      panel->ClientToScreen(&x, &y);
      panel->GetParent()->ScreenToClient(&x, &y);
      panel->GetClientSize(&width, &height);

      Capture(fileName, panel, x, y, width, r.height + 6);

   }
   else if (captureMode.IsSameAs(wxT("secondtrack")))
   {
      TrackPanel *panel = context.proj->mTrackPanel;
      TrackListIterator iter(context.proj->GetTracks());
      Track * t = iter.First();
      if (!t) {
         return false;
      }
      if (t->GetLinked()) {
         t = iter.Next();
      }
      t = iter.Next();
      if (!t) {
         return false;
      }
      wxRect r = panel->FindTrackRect(t, true);

      int x = 0, y = r.y - 3;
      int width, height;

      panel->ClientToScreen(&x, &y);
      panel->GetParent()->ScreenToClient(&x, &y);
      panel->GetClientSize(&width, &height);

      Capture(fileName, panel, x, y, width, r.height + 6);
   }
   else
   {
      // Invalid capture mode!
      return false;
   }

   return true;
}
bool GetTrackInfoCommand::Apply(CommandExecutionContext context)
{
   wxString mode = GetString(wxT("Type"));

   long trackIndex = GetLong(wxT("TrackIndex"));

   // Get the track indicated by the TrackIndex parameter
   // (Note: this ought to be somewhere else)
   long i = 0;
   TrackListIterator iter(context.proj->GetTracks());
   Track *t = iter.First();
   while (t && i != trackIndex)
   {
      t = iter.Next();
      ++i;
   }
   if (i != trackIndex || !t)
   {
      Error(wxT("TrackIndex was invalid."));
      return false;
   }

   // Now get the particular desired item about the track of interest
   if (mode.IsSameAs(wxT("Name")))
   {
      Status(t->GetName());
   }
   else if (mode.IsSameAs(wxT("StartTime")))
   {
      Status(wxString::Format(wxT("%f"), t->GetStartTime()));
   }
   else if (mode.IsSameAs(wxT("EndTime")))
   {
      Status(wxString::Format(wxT("%f"), t->GetEndTime()));
   }
   else if (mode.IsSameAs(wxT("Pan")))
   {
     if(t->GetKind() == Track::Wave)
       Status(wxString::Format(wxT("%f"), static_cast<WaveTrack*>(t)->GetPan()));
   }
   else if (mode.IsSameAs(wxT("Gain")))
   {
      if(t->GetKind() == Track::Wave)
         Status(wxString::Format(wxT("%f"), static_cast<WaveTrack*>(t)->GetGain()));
   }
   else if (mode.IsSameAs(wxT("Focused")))
   {
      TrackPanel *panel = context.proj->GetTrackPanel();
      SendBooleanStatus(panel->GetFocusedTrack() == t);
   }
   else if (mode.IsSameAs(wxT("Selected")))
   {
      SendBooleanStatus(t->GetSelected());
   }
   else if (mode.IsSameAs(wxT("Linked")))
   {
      SendBooleanStatus(t->GetLinked());
   }
   else if (mode.IsSameAs(wxT("Solo")))
   {
      if (t->GetKind() == Track::Wave)
         SendBooleanStatus(t->GetSolo());
      else
         SendBooleanStatus(false);
   }
   else if (mode.IsSameAs(wxT("Mute")))
   {
      if (t->GetKind() == Track::Wave)
         SendBooleanStatus(t->GetMute());
      else
         SendBooleanStatus(false);
   }
   else
   {
      Error(wxT("Invalid info type!"));
      return false;
   }
   return true;
}