Ticket #1520: action_after_rev3.diff

File action_after_rev3.diff, 12.7 KB (added by Eirik, 13 years ago)

The diff 3.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 OnActionAfter(wxCommandEvent& event);
     224    void OnActionAfterTimerTick(wxTimerEvent & event);
    195225};
    196226
    197227#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::OnActionAfter)
     165EVT_MENU(XRCID("ID_ACTIONAFTER_CLOSE"), CQueueView::OnActionAfter)
     166EVT_MENU(XRCID("ID_ACTIONAFTER_DISCONNECT"), CQueueView::OnActionAfter)
     167EVT_MENU(XRCID("ID_ACTIONAFTER_RUNCOMMAND"), CQueueView::OnActionAfter)
     168EVT_MENU(XRCID("ID_ACTIONAFTER_SHOWMESSAGE"), CQueueView::OnActionAfter)
     169EVT_MENU(XRCID("ID_ACTIONAFTER_PLAYSOUND"), CQueueView::OnActionAfter)
     170EVT_MENU(XRCID("ID_ACTIONAFTER_REBOOT"), CQueueView::OnActionAfter)
     171EVT_MENU(XRCID("ID_ACTIONAFTER_SHUTDOWN"), CQueueView::OnActionAfter)
    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));
     1891    pMenu->Check(XRCID("ID_ACTIONAFTER_CLOSE"), IsActionAfter(ActionAfterState_Close));
     1892    pMenu->Check(XRCID("ID_ACTIONAFTER_DISCONNECT"), IsActionAfter(ActionAfterState_Disconnect));
     1893    pMenu->Check(XRCID("ID_ACTIONAFTER_RUNCOMMAND"), IsActionAfter(ActionAfterState_RunCommand));
     1894    pMenu->Check(XRCID("ID_ACTIONAFTER_SHOWMESSAGE"), IsActionAfter(ActionAfterState_ShowMessage));
     1895    pMenu->Check(XRCID("ID_ACTIONAFTER_PLAYSOUND"), IsActionAfter(ActionAfterState_PlaySound));
     1896#ifdef __WXMSW__
     1897    pMenu->Check(XRCID("ID_ACTIONAFTER_REBOOT"), IsActionAfter(ActionAfterState_Reboot));
     1898    pMenu->Check(XRCID("ID_ACTIONAFTER_SHUTDOWN"), IsActionAfter(ActionAfterState_Shutdown));
     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::OnActionAfter(wxCommandEvent& event)
     1922{
     1923    if (!event.IsChecked() || event.GetId() == XRCID("ID_ACTIONAFTER_DISABLE"))
     1924    { // Goes from checked to non-checked or disable is pressed
     1925        m_actionAfterState = ActionAfterState_Disabled;
     1926        m_actionAfterRunCommand = _T("");
     1927    }
     1928    else if (event.GetId() == XRCID("ID_ACTIONAFTER_DISABLE"))
     1929        m_actionAfterState = ActionAfterState_Disabled;
     1930   
     1931    else if (event.GetId() == XRCID("ID_ACTIONAFTER_CLOSE"))
     1932        m_actionAfterState = ActionAfterState_Close;
     1933   
     1934    else if (event.GetId() == XRCID("ID_ACTIONAFTER_DISCONNECT"))
     1935        m_actionAfterState = ActionAfterState_Disconnect;
     1936   
     1937    else if (event.GetId() == XRCID("ID_ACTIONAFTER_SHOWMESSAGE"))
     1938        m_actionAfterState = ActionAfterState_ShowMessage;
     1939   
     1940    else if (event.GetId() == XRCID("ID_ACTIONAFTER_PLAYSOUND"))
     1941        m_actionAfterState = ActionAfterState_PlaySound;
     1942       
     1943    else if (event.GetId() == XRCID("ID_ACTIONAFTER_RUNCOMMAND"))
     1944    {
     1945        m_actionAfterState = ActionAfterState_RunCommand;
     1946        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"));
     1947       
     1948        if (dlg.ShowModal() != wxID_OK)
     1949        {
     1950            m_actionAfterState = ActionAfterState_Disabled;
     1951            return;
     1952        }
     1953        const wxString &command = dlg.GetValue();
     1954       
     1955        if (command == _T(""))
     1956        {
     1957            wxMessageBox(_("No command given, aborting."), _("Empty command"), wxICON_ERROR, m_pMainFrame);
     1958            m_actionAfterState = ActionAfterState_Disabled;
     1959            return;
     1960        }
     1961        m_actionAfterRunCommand = command;
     1962    }
     1963
     1964#ifdef __WXMSW__
     1965   
     1966    else if (event.GetId() == XRCID("ID_ACTIONAFTER_REBOOT"))
     1967        m_actionAfterState = ActionAfterState_Reboot;
     1968       
     1969    else if (event.GetId() == XRCID("ID_ACTIONAFTER_SHUTDOWN"))
     1970        m_actionAfterState = ActionAfterState_Shutdown;
     1971
     1972#endif
     1973
     1974}
     1975
    18931976void CQueueView::RemoveAll()
    18941977{
    18951978    // This function removes all inactive items and queues active items
     
    19131996        }
    19141997    }
    19151998    SetItemCount(m_itemCount);
     1999    m_actionAfterState = ActionAfterState_Disabled;
    19162000
    19172001    m_serverList = newServerList;
    19182002    UpdateStatusLinePositions();
     
    24872571
    24882572    SendNextCommand(*pEngineData);
    24892573}
     2574
     2575enum ActionAfterState CQueueView::GetActionAfterState() const
     2576{
     2577    return m_actionAfterState;
     2578}
     2579
     2580bool CQueueView::IsActionAfter(enum ActionAfterState state)
     2581{
     2582    return m_actionAfterState == state;
     2583}
     2584
     2585void CQueueView::ActionAfter(bool warned /*=false*/)
     2586{
     2587    switch(m_actionAfterState)
     2588    {
     2589        case ActionAfterState_Close:
     2590        {
     2591            //m_pMainFrame->Close();
     2592            wxSound(_T("resources/finished.wav")).Play(wxSOUND_ASYNC);
     2593            break;
     2594        }
     2595        case ActionAfterState_Disconnect:
     2596        {
     2597            if (m_pMainFrame->GetState()->IsRemoteConnected() && m_pMainFrame->GetState()->IsRemoteIdle())
     2598                m_pMainFrame->GetState()->m_pCommandQueue->ProcessCommand(new CDisconnectCommand());
     2599            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2600            break;
     2601        }
     2602        case ActionAfterState_RunCommand:
     2603        {
     2604            wxExecute(m_actionAfterRunCommand);
     2605            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2606            break;
     2607        }
     2608        case ActionAfterState_ShowMessage:
     2609        {
     2610            wxMessageDialog* dialog = new wxMessageDialog(m_pMainFrame, _T("No more files in the queue!"), _T("Queue completion"), wxOK | wxICON_INFORMATION);
     2611            dialog->ShowModal();
     2612            m_pMainFrame->RequestUserAttention(wxUSER_ATTENTION_ERROR);
     2613           
     2614            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2615            break;
     2616        }
     2617        case ActionAfterState_PlaySound:
     2618        {
     2619            wxSound(wxGetApp().GetResourceDir() + _T("finished.wav")).Play(wxSOUND_ASYNC);
     2620            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2621            break;
     2622        }
     2623#ifdef __WXMSW__
     2624        case ActionAfterState_Reboot:
     2625        {
     2626            if (!warned)
     2627                ActionAfterWarnUser(_T("The system will soon reboot unless you press cancel."));
     2628            else
     2629                wxShutdown(wxSHUTDOWN_REBOOT);
     2630            break;
     2631        }
     2632
     2633        case ActionAfterState_Shutdown:
     2634        {
     2635            if (!warned)
     2636                ActionAfterWarnUser(_T("The system will soon shutdown unless you press cancel."));
     2637            else
     2638                wxShutdown(wxSHUTDOWN_POWEROFF);
     2639            break;
     2640        }
     2641#endif
     2642        case ActionAfterState_Disabled:
     2643        {
     2644            m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2645            break;
     2646        }
     2647    }
     2648}
     2649
     2650void CQueueView::ActionAfterWarnUser(wxString message)
     2651{
     2652    m_actionAfterWarnDialog = new wxProgressDialog(_T("Queue completion dialog"), message, 150, m_pMainFrame, wxPD_CAN_ABORT | wxPD_AUTO_HIDE | wxPD_CAN_SKIP);
     2653    wxSize dialogSize = m_actionAfterWarnDialog->GetSize();
     2654    m_actionAfterWarnDialog->SetSize(dialogSize.GetWidth() / 2, dialogSize.GetHeight());
     2655    m_actionAfterWarnDialog->CentreOnParent();
     2656    m_actionAfterWarnDialog->SetFocus();
     2657    m_pMainFrame->RequestUserAttention(wxUSER_ATTENTION_ERROR);
     2658   
     2659    m_actionAfterTimer = new wxTimer(this,fzEVT_ACTIONAFTER_WARN);
     2660    m_actionAfterTimerCount = 0;
     2661    m_actionAfterTimer->Start(100, wxTIMER_CONTINUOUS);
     2662}
     2663
     2664void CQueueView::OnActionAfterTimerTick(wxTimerEvent& event)
     2665{
     2666    bool skipped = false;
     2667    if (m_actionAfterTimerCount > 150)
     2668    {
     2669        m_actionAfterWarnDialog->Destroy();
     2670        delete m_actionAfterTimer;
     2671        this->ActionAfter(true);
     2672    }
     2673    else if (!m_actionAfterWarnDialog->Update(m_actionAfterTimerCount++, _T(""), &skipped))
     2674    {
     2675        // User has pressed cancel!
     2676        m_actionAfterState = ActionAfterState_Disabled; // resetting to disabled
     2677        m_actionAfterWarnDialog->Destroy();
     2678        delete m_actionAfterTimer;
     2679    }
     2680    else if (skipped)
     2681    {
     2682        m_actionAfterWarnDialog->Destroy();
     2683        delete m_actionAfterTimer;
     2684        this->ActionAfter(true);
     2685    }
     2686       
     2687}