Ticket #1520: action_after_rev2.diff

File action_after_rev2.diff, 14.2 KB (added by Eirik, 12 years ago)

The diff 2.0

  • src/interface/resources/menus.xrc

     
    171171        <checkable>1</checkable>
    172172      </object>
    173173    </object>
     174    <object class="wxMenu" name="ID_ACTIONAFTER">
     175      <label>Action after queue &amp;completion</label>
     176      <object class="wxMenuItem" name="ID_ACTIONAFTER_CLOSE">
     177        <label>&amp;Close FileZilla</label>
     178        <checkable>1</checkable>
     179      </object>
     180      <object class="wxMenuItem" name="ID_ACTIONAFTER_DISCONNECT">
     181        <label>&amp;Disconnect from server</label>
     182        <checkable>1</checkable>
     183      </object>
     184      <object class="wxMenuItem" name="ID_ACTIONAFTER_RUNCOMMAND">
     185        <label>&amp;Run command...</label>
     186        <checkable>1</checkable>
     187      </object>
     188      <object class="wxMenuItem" name="ID_ACTIONAFTER_SHOWMESSAGE">
     189        <label>&amp;Show message</label>
     190        <checkable>1</checkable>
     191      </object>
     192      <object class="wxMenuItem" name="ID_ACTIONAFTER_PLAYSOUND">
     193        <label>&amp;Play sound</label>
     194        <checkable>1</checkable>
     195      </object>
     196      <object class="wxMenuItem" name="ID_ACTIONAFTER_REBOOT" platform="win">
     197        <label>&amp;Reboot system</label>
     198        <checkable>1</checkable>
     199      </object>
     200      <object class="wxMenuItem" name="ID_ACTIONAFTER_SHUTDOWN" platform="win">
     201        <label>&amp;Shutdown system</label>
     202        <checkable>1</checkable>
     203      </object>
     204      <object class="separator"/>
     205      <object class="wxMenuItem" name="ID_ACTIONAFTER_DISABLE" platform="win">
     206        <label>&amp;Do nothing</label>
     207        <checkable>1</checkable>
     208      </object>
     209    </object>
    174210  </object>
    175211  <object class="wxMenu" name="ID_MENU_LOG">
    176212    <object class="wxMenuItem" name="ID_MENU_SERVER_CMD">
     
    253289      <help>Change the file permissions.</help>
    254290    </object>
    255291  </object>
    256 </resource>
    257  No newline at end of file
     292</resource>
  • src/interface/QueueView.h

     
    33
    44#include <set>
    55#include "dndobjects.h"
     6#include <wx/progdlg.h>
    67
    78struct t_newEntry
    89{
     
    1213    wxLongLong size;
    1314};
    1415
     16enum ActionAfterState
     17{
     18    ActionAfterState_Disabled,
     19    ActionAfterState_Close,
     20    ActionAfterState_Disconnect,
     21    ActionAfterState_RunCommand,
     22    ActionAfterState_ShowMessage,
     23    ActionAfterState_PlaySound,
     24// On Windows, wx can reboot or shutdown the system as well.
     25#ifdef __WXMSW__
     26    ActionAfterState_Reboot,
     27    ActionAfterState_Shutdown
     28#endif
     29};
     30
    1531class CStatusLineCtrl;
    1632struct t_EngineData
    1733{
     
    108124        retry,
    109125        remove
    110126    };
     127   
     128    enum ActionAfterState GetActionAfterState() const;
    111129
    112130    void ResetEngine(t_EngineData& data, const enum ResetReason reason);
    113131    void DeleteEngines();
     
    126144    void DisplayQueueSize();
    127145    void SaveQueue();
    128146    bool ShouldUseBinaryMode(wxString filename);
     147   
     148    bool IsActionAfter(enum ActionAfterState);
     149    void ActionAfter(bool warned = false);
     150    void ActionAfterWarnUser(wxString message);
    129151
    130152    void ProcessNotification(t_EngineData* pEngineData, CNotification* pNotification);
    131153
     
    158180    int m_activeCountUp;
    159181    int m_activeMode; // 0 inactive, 1 only immediate transfers, 2 all
    160182    bool m_quit;
     183    enum ActionAfterState m_actionAfterState;
     184    wxString m_actionAfterRunCommand;
     185    wxTimer* m_actionAfterTimer;
     186    wxProgressDialog* m_actionAfterWarnDialog;
     187    int m_actionAfterTimerCount;
    161188
    162189    wxLongLong m_totalQueueSize;
    163190    int m_filesWithUnknownSize;
     
    192219    void OnSetPriority(wxCommandEvent& event);
    193220
    194221    void OnExclusiveEngineRequestGranted(wxCommandEvent& event);
     222
     223    void OnActionAfterDisable(wxCommandEvent& event);
     224    void OnActionAfterClose(wxCommandEvent& event);
     225    void OnActionAfterDisconnect(wxCommandEvent& event);
     226    void OnActionAfterRunCommand(wxCommandEvent& event);
     227    void OnActionAfterTimerTick(wxTimerEvent & event);
     228    void OnActionAfterShowMessage(wxCommandEvent& event);
     229    void OnActionAfterPlaySound(wxCommandEvent& event);
     230#ifdef __WXMSW__
     231    void OnActionAfterReboot(wxCommandEvent& event);
     232    void OnActionAfterShutdown(wxCommandEvent& event);
     233#endif
    195234};
    196235
    197236#endif
  • src/interface/QueueView.cpp

     
    1919#include "queueview_failed.h"
    2020#include "queueview_successful.h"
    2121#include "commandqueue.h"
     22#include <wx/utils.h>
     23#include <wx/progdlg.h>
     24#include <wx/sound.h>
    2225
    2326#ifdef _DEBUG
    2427#define new DEBUG_NEW
     
    142145DECLARE_EVENT_TYPE(fzEVT_ASKFORPASSWORD, -1)
    143146DEFINE_EVENT_TYPE(fzEVT_ASKFORPASSWORD)
    144147
     148DECLARE_EVENT_TYPE(fzEVT_ACTIONAFTER_WARN, -1)
     149DEFINE_EVENT_TYPE(fzEVT_ACTIONAFTER_WARN)
     150
    145151BEGIN_EVENT_TABLE(CQueueView, CQueueViewBase)
    146152EVT_FZ_NOTIFICATION(wxID_ANY, CQueueView::OnEngineEvent)
    147153EVT_COMMAND(wxID_ANY, fzEVT_FOLDERTHREAD_COMPLETE, CQueueView::OnFolderThreadComplete)
     
    155161EVT_MENU(XRCID("ID_REMOVEALL"), CQueueView::OnStopAndClear)
    156162EVT_MENU(XRCID("ID_REMOVE"), CQueueView::OnRemoveSelected)
    157163EVT_MENU(XRCID("ID_DEFAULT_FILEEXISTSACTION"), CQueueView::OnSetDefaultFileExistsAction)
     164EVT_MENU(XRCID("ID_ACTIONAFTER_DISABLE"), CQueueView::OnActionAfterDisable)
     165EVT_MENU(XRCID("ID_ACTIONAFTER_CLOSE"), CQueueView::OnActionAfterClose)
     166EVT_MENU(XRCID("ID_ACTIONAFTER_DISCONNECT"), CQueueView::OnActionAfterDisconnect)
     167EVT_MENU(XRCID("ID_ACTIONAFTER_RUNCOMMAND"), CQueueView::OnActionAfterRunCommand)
     168EVT_MENU(XRCID("ID_ACTIONAFTER_SHOWMESSAGE"), CQueueView::OnActionAfterShowMessage)
     169EVT_MENU(XRCID("ID_ACTIONAFTER_PLAYSOUND"), CQueueView::OnActionAfterPlaySound)
     170EVT_MENU(XRCID("ID_ACTIONAFTER_REBOOT"), CQueueView::OnActionAfterReboot)
     171EVT_MENU(XRCID("ID_ACTIONAFTER_SHUTDOWN"), CQueueView::OnActionAfterShutdown)
    158172
    159173EVT_COMMAND(wxID_ANY, fzEVT_ASKFORPASSWORD, CQueueView::OnAskPassword)
    160174
    161175EVT_LIST_ITEM_FOCUSED(wxID_ANY, CQueueView::OnFocusItemChanged)
    162176
     177EVT_TIMER(fzEVT_ACTIONAFTER_WARN,CQueueView::OnActionAfterTimerTick)
    163178EVT_TIMER(wxID_ANY, CQueueView::OnTimer)
    164179
    165180EVT_MENU(XRCID("ID_PRIORITY_HIGHEST"), CQueueView::OnSetPriority)
     
    411426
    412427    m_totalQueueSize = 0;
    413428    m_filesWithUnknownSize = 0;
     429   
     430    m_actionAfterState = ActionAfterState_Disabled;
    414431
    415432    CreateColumns(_("Status"));
    416433
     
    14131430            else if (pSuccessful->GetItemCount())
    14141431                m_pQueue->SetSelection(2);
    14151432        }
     1433    ActionAfter();
    14161434    }
    14171435
    14181436    if (m_quit)
     
    18691887        return;
    18701888
    18711889    pMenu->Check(XRCID("ID_PROCESSQUEUE"), IsActive() ? true : false);
     1890    pMenu->Check(XRCID("ID_ACTIONAFTER_DISABLE"), IsActionAfter(ActionAfterState_Disabled) ? true : false);
     1891    pMenu->Check(XRCID("ID_ACTIONAFTER_CLOSE"), IsActionAfter(ActionAfterState_Close) ? true : false);
     1892    pMenu->Check(XRCID("ID_ACTIONAFTER_DISCONNECT"), IsActionAfter(ActionAfterState_Disconnect) ? true : false);
     1893    pMenu->Check(XRCID("ID_ACTIONAFTER_RUNCOMMAND"), IsActionAfter(ActionAfterState_RunCommand) ? true : false);
     1894    pMenu->Check(XRCID("ID_ACTIONAFTER_SHOWMESSAGE"), IsActionAfter(ActionAfterState_ShowMessage) ? true : false);
     1895    pMenu->Check(XRCID("ID_ACTIONAFTER_PLAYSOUND"), IsActionAfter(ActionAfterState_PlaySound) ? true : false);
     1896#ifdef __WXMSW__
     1897    pMenu->Check(XRCID("ID_ACTIONAFTER_REBOOT"), IsActionAfter(ActionAfterState_Reboot) ? true : false);
     1898    pMenu->Check(XRCID("ID_ACTIONAFTER_SHUTDOWN"), IsActionAfter(ActionAfterState_Shutdown) ? true : false);
     1899#endif
    18721900    pMenu->Enable(XRCID("ID_REMOVE"), GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
    18731901
    18741902    const bool hasSelection = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1;
     
    18901918    RemoveAll();
    18911919}
    18921920
     1921void CQueueView::OnActionAfterDisable(wxCommandEvent& event)
     1922{
     1923    m_actionAfterState = ActionAfterState_Disabled;
     1924}
     1925
     1926void CQueueView::OnActionAfterClose(wxCommandEvent& event)
     1927{
     1928    if(event.IsChecked())
     1929    { // goes from non-checked to checked
     1930        m_actionAfterState = ActionAfterState_Close;
     1931    }
     1932    else
     1933    { // goes from checked to non-checked
     1934        m_actionAfterState = ActionAfterState_Disabled;
     1935    }
     1936}
     1937
     1938void CQueueView::OnActionAfterDisconnect(wxCommandEvent& event)
     1939{
     1940    if(event.IsChecked())
     1941    { // goes from non-checked to checked
     1942        m_actionAfterState = ActionAfterState_Disconnect;
     1943    }
     1944    else
     1945    { // goes from checked to non-checked
     1946        m_actionAfterState = ActionAfterState_Disabled;
     1947    }
     1948}
     1949
     1950void CQueueView::OnActionAfterRunCommand(wxCommandEvent& event)
     1951{
     1952    if(event.IsChecked())
     1953    { // goes from non-checked to checked
     1954        m_actionAfterState = ActionAfterState_RunCommand;
     1955        wxTextEntryDialog dlg(m_pMainFrame, _("Please enter a path and executable to run.\nE.g. c:\\somePath\\file.exe under MS Windows or /somePath/file under Unix.\nYou can also optionally specify program arguments."), _("Enter command"));
     1956       
     1957        if (dlg.ShowModal() != wxID_OK)
     1958        {
     1959            m_actionAfterState = ActionAfterState_Disabled;
     1960            return;
     1961        }
     1962        const wxString &command = dlg.GetValue();
     1963       
     1964        if (command == _T(""))
     1965        {
     1966            wxMessageBox(_("No command given, aborting."), _("Empty command"), wxICON_ERROR, m_pMainFrame);
     1967            m_actionAfterState = ActionAfterState_Disabled;
     1968            return;
     1969        }
     1970        m_actionAfterRunCommand = command;
     1971    }
     1972    else
     1973    { // goes from checked to non-checked
     1974        m_actionAfterState = ActionAfterState_Disabled;
     1975        m_actionAfterRunCommand = _T("");
     1976    }
     1977}
     1978
     1979void CQueueView::OnActionAfterShowMessage(wxCommandEvent& event)
     1980{
     1981    if(event.IsChecked())
     1982    { // goes from non-checked to checked
     1983        m_actionAfterState = ActionAfterState_ShowMessage;
     1984    }
     1985    else
     1986    { // goes from checked to non-checked
     1987        m_actionAfterState = ActionAfterState_Disabled;
     1988    }
     1989}
     1990
     1991void CQueueView::OnActionAfterPlaySound(wxCommandEvent& event)
     1992{
     1993    if(event.IsChecked())
     1994    { // goes from non-checked to checked
     1995        m_actionAfterState = ActionAfterState_PlaySound;
     1996    }
     1997    else
     1998    { // goes from checked to non-checked
     1999        m_actionAfterState = ActionAfterState_Disabled;
     2000    }
     2001}
     2002
     2003#ifdef __WXMSW__
     2004void CQueueView::OnActionAfterReboot(wxCommandEvent& event)
     2005{
     2006    if(event.IsChecked()) // goes from non-checked to checked
     2007    {
     2008        m_actionAfterState = ActionAfterState_Reboot;
     2009    }
     2010    else // goes from checked to non-checked
     2011    {
     2012        m_actionAfterState = ActionAfterState_Disabled;
     2013    }
     2014}
     2015
     2016void CQueueView::OnActionAfterShutdown(wxCommandEvent& event)
     2017{
     2018    if(event.IsChecked()) // goes from non-checked to checked
     2019    {
     2020        m_actionAfterState = ActionAfterState_Shutdown;
     2021    }
     2022    else // goes from checked to non-checked
     2023    {
     2024        m_actionAfterState = ActionAfterState_Disabled;
     2025    }
     2026}
     2027#endif
     2028
    18932029void CQueueView::RemoveAll()
    18942030{
    18952031    // This function removes all inactive items and queues active items
     
    19132049        }
    19142050    }
    19152051    SetItemCount(m_itemCount);
     2052    m_actionAfterState = ActionAfterState_Disabled;
    19162053
    19172054    m_serverList = newServerList;
    19182055    UpdateStatusLinePositions();
     
    24872624
    24882625    SendNextCommand(*pEngineData);
    24892626}
     2627
     2628enum ActionAfterState CQueueView::GetActionAfterState() const
     2629{
     2630    return m_actionAfterState;
     2631}
     2632
     2633bool CQueueView::IsActionAfter(enum ActionAfterState state)
     2634{
     2635    return m_actionAfterState == state;
     2636}
     2637
     2638void CQueueView::ActionAfter(bool warned /*=false*/)
     2639{
     2640    switch(m_actionAfterState)
     2641    {
     2642        case ActionAfterState_Close:
     2643        {
     2644            //m_pMainFrame->Close();
     2645            wxSound(_T("resources/finished.wav")).Play(wxSOUND_ASYNC);
     2646            break;
     2647        }
     2648        case ActionAfterState_Disconnect:
     2649        {
     2650            if (m_pMainFrame->GetState()->IsRemoteConnected() && m_pMainFrame->GetState()->IsRemoteIdle())
     2651                m_pMainFrame->GetState()->m_pCommandQueue->ProcessCommand(new CDisconnectCommand());
     2652            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2653            break;
     2654        }
     2655        case ActionAfterState_RunCommand:
     2656        {
     2657            wxExecute(m_actionAfterRunCommand);
     2658            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2659            break;
     2660        }
     2661        case ActionAfterState_ShowMessage:
     2662        {
     2663            wxMessageDialog* dialog = new wxMessageDialog(m_pMainFrame, _T("No more files in the queue!"), _T("Queue completion"), wxOK | wxICON_INFORMATION);
     2664            dialog->ShowModal();
     2665            m_pMainFrame->RequestUserAttention(wxUSER_ATTENTION_ERROR);
     2666           
     2667            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2668            break;
     2669        }
     2670        case ActionAfterState_PlaySound:
     2671        {
     2672            wxSound(wxGetApp().GetResourceDir() + _T("finished.wav")).Play(wxSOUND_ASYNC);
     2673            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2674            break;
     2675        }
     2676#ifdef __WXMSW__
     2677        case ActionAfterState_Reboot:
     2678        {
     2679            if(!warned)
     2680                ActionAfterWarnUser(_T("The system will soon reboot unless you press cancel."));
     2681            else
     2682                wxShutdown(wxSHUTDOWN_REBOOT);
     2683            break;
     2684        }
     2685
     2686        case ActionAfterState_Shutdown:
     2687        {
     2688            if(!warned)
     2689                ActionAfterWarnUser(_T("The system will soon shutdown unless you press cancel."));
     2690            else
     2691                wxShutdown(wxSHUTDOWN_POWEROFF);
     2692            break;
     2693        }
     2694#endif
     2695        case ActionAfterState_Disabled:
     2696        {
     2697            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2698            break;
     2699        }
     2700    }
     2701}
     2702
     2703void CQueueView::ActionAfterWarnUser(wxString message)
     2704{
     2705    m_actionAfterWarnDialog = new wxProgressDialog(_T("Queue completion dialog"), message, 150, m_pMainFrame, wxPD_CAN_ABORT | wxPD_AUTO_HIDE | wxPD_CAN_SKIP);
     2706    wxSize dialogSize = m_actionAfterWarnDialog->GetSize();
     2707    m_actionAfterWarnDialog->SetSize(dialogSize.GetWidth() / 2, dialogSize.GetHeight());
     2708    m_actionAfterWarnDialog->CentreOnParent();
     2709    m_actionAfterWarnDialog->SetFocus();
     2710    m_pMainFrame->RequestUserAttention(wxUSER_ATTENTION_ERROR);
     2711   
     2712    m_actionAfterTimer = new wxTimer(this,fzEVT_ACTIONAFTER_WARN);
     2713    m_actionAfterTimerCount = 0;
     2714    m_actionAfterTimer->Start(100, wxTIMER_CONTINUOUS);
     2715}
     2716
     2717void CQueueView::OnActionAfterTimerTick(wxTimerEvent& event)
     2718{
     2719    bool skipped = false;
     2720    if(m_actionAfterTimerCount > 150)
     2721    {
     2722        m_actionAfterWarnDialog->Destroy();
     2723        delete m_actionAfterTimer;
     2724        this->ActionAfter(true);
     2725    }
     2726    else if(!m_actionAfterWarnDialog->Update(m_actionAfterTimerCount++, _T(""), &skipped))
     2727    {
     2728        // User has pressed cancel!
     2729        m_actionAfterState = ActionAfterState_Disabled; // resetting to disabled
     2730        m_actionAfterWarnDialog->Destroy();
     2731        delete m_actionAfterTimer;
     2732    }
     2733    else if(skipped)
     2734    {
     2735        m_actionAfterWarnDialog->Destroy();
     2736        delete m_actionAfterTimer;
     2737        this->ActionAfter(true);
     2738    }
     2739       
     2740}