1 /* copyopwin.hh
2  * This file belongs to Worker, a file manager for UN*X/X11.
3  * Copyright (C) 2001-2014 Ralf Hoffmann.
4  * You can contact me at: ralf@boomerangsworld.de
5  *   or http://www.boomerangsworld.de/worker
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #ifndef COPYOPWIN_HH
23 #define COPYOPWIN_HH
24 
25 #include "wdefines.h"
26 #include "aguix/request.h"
27 #include "aguix/message.h"
28 #include <mutex>
29 #include <condition_variable>
30 #include <list>
31 #include <memory>
32 #include "bgcopy_requestmessage.hh"
33 #include <thread>
34 
35 class AGUIX;
36 class AWindow;
37 class Text;
38 class SolidButton;
39 class BevelBox;
40 class Button;
41 class AFontWidth;
42 class ChooseButton;
43 
44 class CopyOpWin
45 {
46 public:
47   CopyOpWin( AGUIX*, bool _move = false );
48   ~CopyOpWin();
49   CopyOpWin( const CopyOpWin &other );
50   CopyOpWin &operator=( const CopyOpWin &other );
51 
52     /*********************************
53      * allowed for master thread only
54      *********************************/
55 
56     int open();
57     void close();
58 
59     /* should be called in copy-loop
60      * does the update of the window AND process X-events
61      * returnvalues: 0 - normal exit
62      *               1 - cancel/close window pressed */
63     int redraw( bool skip_message_handling = false );
64     int handleMessage( AGMessage *msg );
65 
66     void master_process_request();
67 
68     void hide_detach_button();
69 
70     bool getKeepWindow() const;
71     void setFinished();
72 
73     /***************************
74      * allowed for slave thread
75      ***************************/
76 
77     void starttimer(); // called once to set timer
78     void stoptimer();  // when user-action is needed
79     void conttimer();  // when user-interaction finished
80     // called once:
81     void set_files_to_copy( long nfiles );
82     void set_dirs_to_copy( long ndirs );
83     void set_bytes_to_copy( loff_t nbytes );
84     // calld after newfile()
85     void set_bytes_to_copy_curfile( loff_t nbytes );
86 
87     void dir_finished();
88     void file_finished();
89     // called when a block from the current file is copied
90     void add_curbytes_copied( loff_t nbytes );
91     // called when start a new file
92     void newfile( const std::string &name,
93                   const std::string &ndest);
94     // for setting a message in the two lines used for display copy source/dest
95     void setmessage( const std::string &msg, int line );
96     // for dec file/dir-counter (mainly in case of skiped files/dirs
97     void dec_file_counter( unsigned long f );
98     void dec_dir_counter( unsigned long d );
99     void dec_byte_counter( loff_t b );
100 
101     void file_skipped( loff_t byteSum, bool subCopied );
102 
103     int request( const std::string &title,
104                  const std::string &text,
105                  const std::string &buttons,
106                  Requester::request_flags_t flags = Requester::REQUEST_NONE );
107     int string_request( const std::string &title,
108                         const std::string &lines,
109                         const std::string &default_str,
110                         const std::string &buttons,
111                         std::string &return_str,
112                         Requester::request_flags_t flags = Requester::REQUEST_NONE );
113     void update_file_status();
114 protected:
115     std::string source;
116     std::string dest;
117   loff_t copied_bytes_curfile,bytes_curfile;
118   loff_t copied_bytes,bytes;
119   long copied_files,files;
120   long copied_dirs,dirs;
121   struct timeval starttime;
122   struct timeval filestarttime;
123   struct timeval stoptime;
124   struct timeval lasttime;
125   struct timeval lasttime_global;
126   struct timeval last_update_time;
127   int skipped_updates;
128   int sbw;
129   loff_t lastbytes;
130   double lastrate;
131   loff_t lastbytes_global;
132   double lastrate_global;
133 
134   double mintime;
135 
136   AGUIX *aguix;
137   AWindow *window;
138   Text *sourcetext,*desttext,*filetext,*globtext,*files2gotext,*dirs2gotext,*timetext,*fileavgtext;
139   SolidButton *fsb,*gsb;
140   BevelBox *bb1, *bb2, *bb3, *bb4;
141   Button *cb;
142   Button *m_detach_b;
143   bool update_sourcetext,update_desttext,update_filetext,update_globtext,update_files2gotext;
144   bool update_dirs2gotext;
145   int melw;
146   int filenamespace[2];
147   bool ismessage[2];
148 
149 /* currently displayed infos:
150    1.source (only filename)
151    2.destination (whole path)
152    3.progressbar for current file
153    4.<copied Bytes>/<bytes> @ <rate>
154    5.files 2 copy
155    6.dirs 2 copy
156    7.progressbar for the whole operation
157    8.<copied Bytes>/<bytes> @ <rate>
158 */
159   int glob_percent;
160   bool move;
161   AFontWidth *lencalc;
162 
163   bool timer_stopped;
164 
165   static const int UPDATES_PER_SECOND = 15;
166 
167     std::recursive_mutex m_status_update_lock;
168 
169     std::unique_ptr< BGCopyRequestMessage > m_request;
170     std::unique_ptr< BGCopyRequestMessage > m_response;
171     std::mutex m_request_lock;
172     std::mutex m_response_lock;
173     std::condition_variable m_response_cond;
174 
175     std::thread::id m_master_thread_id;
176 
177     int request_int( const char *title,
178                      const char *text,
179                      const char *buttons,
180                      Requester::request_flags_t flags = Requester::REQUEST_NONE );
181     int string_request_int( const char *title,
182                             const char *lines,
183                             const char *default_str,
184                             const char *buttons,
185                             char **return_str,
186                             Requester::request_flags_t flags = Requester::REQUEST_NONE );
187 
188     void process_request( BGCopyRequestMessage &msg );
189 
190     void push_request( const BGCopyRequestMessage &msg );
191     BGCopyRequestMessage wait_for_response();
192 
193     bool m_finished;
194     bool m_detached;
195     bool m_keep_window;
196 
197     ChooseButton *m_keep_window_cb;
198 };
199 
200 #endif
201