Ticket #1520: action_after_rev4.diff

File action_after_rev4.diff, 12.7 KB (added by Eirik, 12 years ago)

The diff 4.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;
     431    m_actionAfterWarnDialog = NULL;
    414432
    415433    CreateColumns(_("Status"));
    416434
     
    14131431            else if (pSuccessful->GetItemCount())
    14141432                m_pQueue->SetSelection(2);
    14151433        }
     1434        ActionAfter();
    14161435    }
    14171436
    14181437    if (m_quit)
     
    18691888        return;
    18701889
    18711890    pMenu->Check(XRCID("ID_PROCESSQUEUE"), IsActive() ? true : false);
     1891    pMenu->Check(XRCID("ID_ACTIONAFTER_DISABLE"), IsActionAfter(ActionAfterState_Disabled));
     1892    pMenu->Check(XRCID("ID_ACTIONAFTER_CLOSE"), IsActionAfter(ActionAfterState_Close));
     1893    pMenu->Check(XRCID("ID_ACTIONAFTER_DISCONNECT"), IsActionAfter(ActionAfterState_Disconnect));
     1894    pMenu->Check(XRCID("ID_ACTIONAFTER_RUNCOMMAND"), IsActionAfter(ActionAfterState_RunCommand));
     1895    pMenu->Check(XRCID("ID_ACTIONAFTER_SHOWMESSAGE"), IsActionAfter(ActionAfterState_ShowMessage));
     1896    pMenu->Check(XRCID("ID_ACTIONAFTER_PLAYSOUND"), IsActionAfter(ActionAfterState_PlaySound));
     1897#ifdef __WXMSW__
     1898    pMenu->Check(XRCID("ID_ACTIONAFTER_REBOOT"), IsActionAfter(ActionAfterState_Reboot));
     1899    pMenu->Check(XRCID("ID_ACTIONAFTER_SHUTDOWN"), IsActionAfter(ActionAfterState_Shutdown));
     1900#endif
    18721901    pMenu->Enable(XRCID("ID_REMOVE"), GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
    18731902
    18741903    const bool hasSelection = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1;
     1904   
    18751905    pMenu->Enable(XRCID("ID_PRIORITY"), hasSelection);
    18761906    pMenu->Enable(XRCID("ID_DEFAULT_FILEEXISTSACTION"), hasSelection);
     1907    pMenu->Enable(XRCID("ID_ACTIONAFTER"), m_actionAfterWarnDialog == NULL);
    18771908
    18781909    PopupMenu(pMenu);
    18791910    delete pMenu;
     
    18901921    RemoveAll();
    18911922}
    18921923
     1924void CQueueView::OnActionAfter(wxCommandEvent& event)
     1925{
     1926    if (!event.IsChecked() || event.GetId() == XRCID("ID_ACTIONAFTER_DISABLE"))
     1927    { // Goes from checked to non-checked or disable is pressed
     1928        m_actionAfterState = ActionAfterState_Disabled;
     1929        m_actionAfterRunCommand = _T("");
     1930    }
     1931    else if (event.GetId() == XRCID("ID_ACTIONAFTER_DISABLE"))
     1932        m_actionAfterState = ActionAfterState_Disabled;
     1933   
     1934    else if (event.GetId() == XRCID("ID_ACTIONAFTER_CLOSE"))
     1935        m_actionAfterState = ActionAfterState_Close;
     1936   
     1937    else if (event.GetId() == XRCID("ID_ACTIONAFTER_DISCONNECT"))
     1938        m_actionAfterState = ActionAfterState_Disconnect;
     1939   
     1940    else if (event.GetId() == XRCID("ID_ACTIONAFTER_SHOWMESSAGE"))
     1941        m_actionAfterState = ActionAfterState_ShowMessage;
     1942   
     1943    else if (event.GetId() == XRCID("ID_ACTIONAFTER_PLAYSOUND"))
     1944        m_actionAfterState = ActionAfterState_PlaySound;
     1945       
     1946    else if (event.GetId() == XRCID("ID_ACTIONAFTER_RUNCOMMAND"))
     1947    {   
     1948        m_actionAfterState = ActionAfterState_RunCommand;
     1949        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"));
     1950       
     1951        if (dlg.ShowModal() != wxID_OK)
     1952        {
     1953            m_actionAfterState = ActionAfterState_Disabled;
     1954            return;
     1955        }
     1956        const wxString &command = dlg.GetValue();
     1957       
     1958        if (command == _T(""))
     1959        {
     1960            wxMessageBox(_("No command given, aborting."), _("Empty command"), wxICON_ERROR, m_pMainFrame);
     1961            m_actionAfterState = ActionAfterState_Disabled;
     1962            return;
     1963        }
     1964        m_actionAfterRunCommand = command;
     1965    }
     1966
     1967#ifdef __WXMSW__
     1968   
     1969    else if (event.GetId() == XRCID("ID_ACTIONAFTER_REBOOT"))
     1970        m_actionAfterState = ActionAfterState_Reboot;
     1971       
     1972    else if (event.GetId() == XRCID("ID_ACTIONAFTER_SHUTDOWN"))
     1973        m_actionAfterState = ActionAfterState_Shutdown;
     1974
     1975#endif
     1976
     1977}
     1978
    18931979void CQueueView::RemoveAll()
    18941980{
    18951981    // This function removes all inactive items and queues active items
     
    19131999        }
    19142000    }
    19152001    SetItemCount(m_itemCount);
     2002    m_actionAfterState = ActionAfterState_Disabled;
    19162003
    19172004    m_serverList = newServerList;
    19182005    UpdateStatusLinePositions();
     
    24872574
    24882575    SendNextCommand(*pEngineData);
    24892576}
     2577
     2578enum ActionAfterState CQueueView::GetActionAfterState() const
     2579{
     2580    return m_actionAfterState;
     2581}
     2582
     2583bool CQueueView::IsActionAfter(enum ActionAfterState state)
     2584{
     2585    return m_actionAfterState == state;
     2586}
     2587
     2588void CQueueView::ActionAfter(bool warned /*=false*/)
     2589{
     2590    switch (m_actionAfterState)
     2591    {
     2592        case ActionAfterState_Close:
     2593        {
     2594            m_pMainFrame->Close();
     2595            break;
     2596        }
     2597        case ActionAfterState_Disconnect:
     2598        {
     2599            if (m_pMainFrame->GetState()->IsRemoteConnected() && m_pMainFrame->GetState()->IsRemoteIdle())
     2600                m_pMainFrame->GetState()->m_pCommandQueue->ProcessCommand(new CDisconnectCommand());
     2601            break;
     2602        }
     2603        case ActionAfterState_RunCommand:
     2604        {
     2605            wxExecute(m_actionAfterRunCommand);
     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            break;
     2614        }
     2615        case ActionAfterState_PlaySound:
     2616        {
     2617            wxSound(wxGetApp().GetResourceDir() + _T("finished.wav")).Play(wxSOUND_ASYNC);
     2618            break;
     2619        }
     2620#ifdef __WXMSW__
     2621        case ActionAfterState_Reboot:
     2622        {
     2623            if (!warned)
     2624                ActionAfterWarnUser(_T("The system will soon reboot unless you press cancel."));
     2625            else
     2626                wxShutdown(wxSHUTDOWN_REBOOT);
     2627            break;
     2628        }
     2629
     2630        case ActionAfterState_Shutdown:
     2631        {
     2632            if (!warned)
     2633                ActionAfterWarnUser(_T("The system will soon shutdown unless you press cancel."));
     2634            else
     2635                wxShutdown(wxSHUTDOWN_POWEROFF);
     2636            break;
     2637        }
     2638#endif
     2639
     2640    }
     2641    m_actionAfterState = ActionAfterState_Disabled; // Resetting the state.
     2642}
     2643
     2644void CQueueView::ActionAfterWarnUser(wxString message)
     2645{
     2646    if (m_actionAfterWarnDialog == NULL)
     2647    {
     2648        m_actionAfterWarnDialog = new wxProgressDialog(_T("Queue completion dialog"), message, 150, m_pMainFrame, wxPD_CAN_ABORT | wxPD_AUTO_HIDE | wxPD_CAN_SKIP | wxPD_APP_MODAL);
     2649        wxSize dialogSize = m_actionAfterWarnDialog->GetSize();
     2650        m_actionAfterWarnDialog->SetSize(dialogSize.GetWidth() / 2, dialogSize.GetHeight());
     2651        m_actionAfterWarnDialog->CentreOnParent();
     2652        m_actionAfterWarnDialog->SetFocus();
     2653        m_pMainFrame->RequestUserAttention(wxUSER_ATTENTION_ERROR);
     2654       
     2655        m_actionAfterTimer = new wxTimer(this,fzEVT_ACTIONAFTER_WARN);
     2656        m_actionAfterTimerCount = 0;
     2657        m_actionAfterTimer->Start(100, wxTIMER_CONTINUOUS);
     2658    }
     2659}
     2660
     2661void CQueueView::OnActionAfterTimerTick(wxTimerEvent& event)
     2662{
     2663    bool skipped = false;
     2664    if (m_actionAfterTimerCount > 150)
     2665    {
     2666        m_actionAfterWarnDialog->Destroy();
     2667        m_actionAfterWarnDialog = NULL;
     2668        delete m_actionAfterTimer;
     2669        ActionAfter(true);
     2670    }
     2671    else if (!m_actionAfterWarnDialog->Update(m_actionAfterTimerCount++, _T(""), &skipped))
     2672    {
     2673        // User has pressed cancel!
     2674        m_actionAfterState = ActionAfterState_Disabled; // resetting to disabled
     2675        m_actionAfterWarnDialog->Destroy();
     2676        m_actionAfterWarnDialog = NULL;
     2677        delete m_actionAfterTimer;
     2678    }
     2679    else if (skipped)
     2680    {
     2681        m_actionAfterWarnDialog->Destroy();
     2682        m_actionAfterWarnDialog = NULL;
     2683        delete m_actionAfterTimer;
     2684        ActionAfter(true);
     2685    }
     2686       
     2687}