1 /* worker.h 2 * This file belongs to Worker, a file manager for UN*X/X11. 3 * Copyright (C) 2001-2021 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 WORKER_H 23 #define WORKER_H 24 25 #include "wdefines.h" 26 #include "functionproto.h" 27 #include <string> 28 #include "generic_callback.hh" 29 #include "layoutsettings.hh" 30 #include "timedtext.hh" 31 #include "processhandler.hh" 32 #include <map> 33 #include "aguix/message.h" 34 #include "hw_volume_manager.hh" 35 #include <memory> 36 #include "event_callbacks.hh" 37 #include "temporaryfilecache.hh" 38 #include "deeppathstore.hh" 39 #include <set> 40 #include "kvpstore.hh" 41 #include <future> 42 #include "worker_types.h" 43 #include "existence_test.hh" 44 #include "wconfig_initial_command.hh" 45 #include "file_command_log.hh" 46 47 class ListerMode; 48 class Lister; 49 class BookmarkDBProxy; 50 class PopUpMenu; 51 class HWVolume; 52 class WaitThread; 53 class TimeoutStore; 54 class EventQueue; 55 class Requester; 56 class Button; 57 class AWindow; 58 class AContainer; 59 class WCHotkey; 60 class WCButton; 61 class WCPath; 62 class PartSpace; 63 class CopyfileProgressCallback; 64 class PersDeepPathStore; 65 class HintDB; 66 class PathnameWatcher; 67 class Slider; 68 class MenuTreeUI; 69 class MenuTreeNode; 70 class WConfig; 71 class PersistentKVP; 72 class PrefixDB; 73 74 class worker_version 75 { 76 public: worker_version()77 worker_version() : m_major( 0 ), 78 m_minor( 0 ), 79 m_patch( 0 ) 80 {} 81 worker_version(int major,int minor,int patch)82 worker_version( int major , 83 int minor, 84 int patch ) : m_major( major ), 85 m_minor( minor ), 86 m_patch( patch ) 87 {} 88 89 bool operator<( const worker_version &rhs ) const 90 { 91 if ( m_major < rhs.m_major ) return true; 92 93 if ( m_major > rhs.m_major ) return false; 94 95 if ( m_minor < rhs.m_minor ) return true; 96 97 if ( m_minor > rhs.m_minor ) return false; 98 99 if ( m_patch < rhs.m_patch ) return true; 100 101 return false; 102 } 103 104 bool operator<=( const worker_version &rhs ) const 105 { 106 return ! ( rhs < *this ); 107 } 108 109 bool operator>( const worker_version &rhs ) const 110 { 111 return rhs < *this; 112 } 113 114 int m_major; 115 int m_minor; 116 int m_patch; 117 }; 118 119 class Worker 120 { 121 public: 122 Worker( int argc, char **argv, int optind = -1 ); 123 ~Worker(); 124 Worker( const Worker &other ); 125 Worker &operator=( const Worker &other ); 126 127 void run(); 128 static AGUIX *getAGUIX(); 129 static int getMaxModeNr(); 130 static int getID4Mode(ListerMode*); 131 static const char *getNameOfMode( int nr ); 132 static const char *getLocaleNameOfMode( int nr ); 133 static int getID4Name( const char *str ); 134 ListerMode *getMode4ID(int,Lister *); 135 AWindow *getMainWin(); 136 void setStatebarText(const char*); 137 static int getNrOfCommands(); 138 static std::shared_ptr< FunctionProto > getCommand4ID(int); 139 static int getID4Command(FunctionProto*); 140 Lister *getOtherLister(Lister*); 141 int getSide(Lister*); 142 Lister *getLister(int); 143 Lister *getActiveLister(); 144 int interpret( const command_list_t &,ActionMessage *); 145 AWindow *getListerWin( Lister *l ); 146 147 int quit(int mode); 148 void checkfirststart( char **setlang ); 149 void setTitle(const char *add_infos); 150 151 static Requester *getRequester(); 152 void activateShortkeyFromList(); 153 154 int PS_readSpace( const char*name ); 155 156 loff_t PS_getBlocksize(); 157 loff_t PS_getFreeSpace(); 158 loff_t PS_getSpace(); 159 160 std::string PS_getFreeSpaceH() const; 161 std::string PS_getSpaceH() const; 162 void PS_setLifetime( double t ); 163 void setWaitCursor(); 164 void unsetWaitCursor(); 165 static const std::string getDataDir(); 166 167 int runCommand( const char *exestr, 168 const char *tmpname, 169 const char *tmpoutput, 170 bool inbackground, 171 RefCount< GenericCallbackArg< void, int > > pea ); 172 173 static std::string getWorkerConfigDir(); 174 175 void openWorkerMenu(); 176 void handleHelp(); 177 178 int getStatebarWidth(); 179 180 static BookmarkDBProxy &getBookmarkDBInstance(); 181 182 void registerPopUpCallback( RefCount<GenericCallbackArg<void, AGMessage*> > cb, 183 const PopUpMenu *menu ); 184 void unregisterPopUpCallback( RefCount<GenericCallbackArg<void, AGMessage*> > cb ); 185 186 LayoutSettings getCustomLayout() const; 187 bool getUseCustomLayout() const; 188 void setCustomLayout( const LayoutSettings &nv ); 189 void unsetCustomLayout(); 190 191 void pushStatebarText( const TimedText &text ); 192 void updateStatebarText( const TimedText &text ); 193 void removeStatebarText( const TimedText &text ); 194 195 HWVolumeManager &getVolumeManager(); 196 void clearNewVolumesInfo(); 197 198 void registerTimeout( loff_t timeout_ms ); 199 void unregisterTimeout( loff_t timeout_ms ); 200 void wakeupMainLoop(); 201 202 void showCommandFailed( int status ); 203 204 void setIgnoreKey( KeySym key, bool state ); 205 bool isIgnoredKey( KeySym key ) const; 206 207 void shuffleButton( int dir ); 208 void switchToButtonBank( int nr ); 209 210 EventCallbacks &getEventHandler(); 211 TemporaryFileCache::TemporaryFileCacheEntry getTempCopy( const std::string &filename, 212 CopyfileProgressCallback *progress_callback = NULL ); 213 214 DeepPathStore &getPathStore(); 215 216 bool storePathPers( const std::string &path, time_t ts ); 217 bool storePathPers( const std::string &path, 218 const std::string &command_str, 219 time_t ts ); 220 bool storePathPersArchive( const std::string &path, time_t ts ); 221 void removePathPers( const std::string &path ); 222 void removePathPersArchive( const std::string &path ); 223 void removePathProgramPers( const std::string &program ); 224 DeepPathStore getPathsPers(); 225 DeepPathStore getPathsPersArchive(); 226 std::map< std::string, DeepPathStore > getPathProgramsPers(); 227 loff_t getSizeOfPersPaths() const; 228 loff_t getSizeOfPersPathsArchive() const; 229 loff_t getSizeOfPersPathPrograms() const; 230 void relocateEntriesPers( const std::string &dest, 231 const std::string &source, 232 time_t ts, 233 bool move ); 234 235 bool storePathPersIfInProgress( const std::string &path ); 236 void setPathJumpInProgress( bool nv = true ); 237 void setPathJumpInProgress( const std::string last_filter ); 238 239 void copyToClipboard( const std::string &str ); 240 241 void showNextHint(); 242 243 RefCount< PathnameWatcher > getPathnameWatcher(); 244 245 bool checkEnterDir( const std::string &dir ); 246 247 static mode_t getUMask(); 248 249 void openCommandMenu( bool show_recently_used ); 250 251 worker_version getLastRunningVersion(); 252 void checkForUpdates( const worker_version &last_running_version, 253 WConfig *conf ); 254 255 void setOverrideXIM( bool nv ); 256 257 static PersistentKVP &getPersKVPStore(); 258 259 PrefixDB &getDirHistPrefixDB(); 260 261 bool getKeyChainCandidateActive() const; 262 263 static KVPStore &getKVPStore(); 264 265 void enqueueFuture( std::future< ExistenceTest::existence_state_t > f ); 266 267 std::list< WorkerTypes::reg_command_info_t > getListOfCommandsWithoutArgs() const; 268 WorkerTypes::reg_command_info_t getCommandInfo( const std::string &command, bool args ) const; 269 270 static std::string getTerminalCommand( const std::string &cmdfile, 271 const std::string &outfile, 272 bool &remove_after_exec ); 273 274 void issueConfigOpen( const std::string &panel ); 275 void issueConfigOpen( const std::string &panel, const WConfigInitialCommand &cmd ); 276 277 std::shared_ptr< WPUContext > getCurrentWPU(); 278 279 static void pushCommandLog( const std::string &command, 280 const std::string &path, 281 const std::string &description ); 282 283 std::list< FileCommandLog::Entry > getCommandLog() const; 284 void clearCommandLog(); 285 protected: 286 void createMainWin(); 287 void setupMainWin(); 288 void closeMainWin(); 289 void shufflePath(); 290 void shuffleButton( int dir, bool nocycle ); 291 void about(); 292 bool configure( const std::string &panel = "" ); 293 void showPathBank(); 294 void showButtonBank(); 295 void setPath(int); 296 void setPath( WCPath *); 297 int activateShortkey(AGMessage*); 298 void activateButton(int,int,int); 299 void activateButton( int pos ); 300 void activateHotkey( int pos ); 301 void activateCommandByID( int id, bool interactive = false ); 302 int saveListerState(); 303 int initListerState(); 304 void updateTime(); 305 306 static AGUIX *aguix; 307 static int workerInstances; 308 Lister *lister[2]; 309 AWindow *mainwin; 310 Button *aboutb,*configureb,*clockbar; 311 Button *statebar; 312 Button **pathbs; 313 Button **buttons; 314 Slider *button_bank_slider; 315 AWindow *listerwin[2]; 316 AContainer *maincont; 317 318 int m_main_window_width, m_main_window_height; 319 int m_main_window_last_absolute_x; 320 int m_main_window_last_absolute_y; 321 bool m_main_window_last_maximized_x; 322 bool m_main_window_last_maximized_y; 323 324 unsigned int curRows,curColumns; 325 int pbanknr,bbanknr; 326 327 enum {WORKER_NORMAL,WORKER_QUIT}; 328 int runningmode; 329 static int argc; 330 static char **argv; 331 static int m_optind; 332 static std::string startcwd; 333 time_t lasttimep; 334 335 DNDMsg *dm; 336 337 static Requester *req_static; 338 339 static int shortkeysort( void *p1, void *p2, int sortmode ); 340 struct shortkeylisttype {WCHotkey *h; 341 WCButton *b; 342 WCPath *p;}; 343 PartSpace *freesp; 344 bool isRoot; 345 346 KeySym lastkey; 347 unsigned int lastmod; 348 Time lastkey_time; 349 350 typedef struct _keyhash { 351 WCButton *b; 352 WCHotkey *h; 353 WCPath *p; 354 struct _keyhash *next; 355 } keyhash; 356 keyhash **keyhashtable; 357 int keyhashtable_size; 358 void buildtable(); 359 void deletetable(); 360 unsigned int keyhashfunc( KeySym k, unsigned int m ); 361 void insertkey( KeySym k, unsigned int m, WCButton *b, WCHotkey *h, WCPath *p ); 362 int findkey( KeySym k, unsigned int m, WCButton **b, WCHotkey **h, WCPath **p ); 363 int findkey( KeySym k1, unsigned int m1, KeySym k2, unsigned int m2, WCButton **b, WCHotkey **h, WCPath **p ); 364 bool isKeyChainPrefix( KeySym k, unsigned int m ); 365 int waitcursorcount; 366 367 int getMaxButtonsWidth(); 368 369 std::string m_statebar_text; 370 371 std::string queryLanguage(); 372 373 void createWorkerMenu(); 374 PopUpMenu *m_worker_menu; 375 void startMenuAction( AGMessage *msg ); 376 void saveWorkerState(); 377 378 int m_interpret_recursion_depth; 379 static const int m_interpret_max_recursion = 1000; 380 381 static std::unique_ptr<BookmarkDBProxy> m_bookmarkproxy; 382 383 std::map<const PopUpMenu *, std::list< RefCount<GenericCallbackArg<void, AGMessage*> > > > m_popup_callbacks; 384 385 void handlePopUps( AGMessage *msg ); 386 387 bool m_use_custom_layout; 388 LayoutSettings m_custom_layout; 389 390 typedef enum { 391 RS_RECONFIG, 392 RS_RELAYOUT, 393 RS_NONE 394 } restart_t; 395 restart_t restart; 396 397 std::list< TimedText > m_statebar_texts; 398 bool getValidStatebarText( TimedText &return_text ); 399 bool getNextValidStatebarText( TimedText &return_text ); 400 void updateStatebar(); 401 402 TimedText m_key_message; 403 std::string getNamesOfKeyChainCompletions( KeySym k, unsigned int m, 404 std::list< WCButton * > *buttons, 405 std::list< WCHotkey * > *hotkeys, 406 std::list< WCPath * > *paths ); 407 408 HWVolumeManager m_volume_manager; 409 void checkNewVolumes(); 410 std::list< HWVolume > m_known_volumes; 411 TimedText m_new_volumes_infotext; 412 413 void updateVolumeManagerConfig(); 414 void initVolumeManagerStuff(); 415 416 void queryNewVolumeAction( const std::list< HWVolume > &l ); 417 418 void initWaitThread(); 419 void shutdownWaitThread(); 420 421 RefCount< EventQueue > m_eventqueue; 422 std::shared_ptr< TimeoutStore > m_timeouts; 423 RefCount< WaitThread > m_waitthread; 424 425 loff_t m_current_clock_update_ms; 426 void setClockUpdate( loff_t time_ms ); 427 428 loff_t m_current_dbus_update_ms; 429 void setDbusUpdate( loff_t time_ms ); 430 431 loff_t m_current_statebar_update_ms; 432 void setStatebarUpdate( loff_t time_ms ); 433 434 TemporaryFileCache m_temp_file_cache; 435 ProcessHandler m_process_handler; 436 void waitForEvent(); 437 438 struct worker_event_store { worker_event_storeworker_event_store439 worker_event_store() : check_children( false ) {} 440 bool check_children; 441 } m_event_store; 442 443 int buildShortkeyLV( FieldListView *lv, 444 List *sklist ); 445 446 std::map< KeySym, int > m_ignored_keys; 447 448 void updateSettingsFromWConfig(); 449 450 EventCallbacks m_event_handler; 451 std::map< EventCallbacks::event_callback_type_t, bool > m_events_seen; 452 void fireSeenEvents(); 453 454 void updateHintDB(); 455 456 void prepareMenuTree( MenuTreeUI &menuui ); 457 void initWorkerTextMenu( MenuTreeNode *menu ); 458 bool checkCommandListForCommand( const command_list_t &list, const std::string &name ); 459 460 void updateRunningVersion(); 461 462 bool importUpdate( WConfig *baseconfig, 463 const std::pair< worker_version, std::string > &config_entry ); 464 465 void switchCurrentMode( int mode ); 466 void configureCurrentMode(); 467 468 std::string getOverrideXIMPath() const; 469 470 void setKeyChainCandidateActive( bool nv ); 471 472 void showButtonCommandHelp( int i, int j, int state ); 473 474 void loadWindowGeometry(); 475 476 void cleanFutures(); 477 void checkFutures(); 478 479 void disableHelp(); 480 void showHelp( KeySym lastkey, 481 unsigned int lastmod, 482 const std::list< WCButton * > &button_list, 483 const std::list< WCHotkey * > &hotkey_list, 484 const std::list< WCPath * > &path_list ); 485 486 std::string getButtonHelpText( int relative_pos_in_bank ) const; 487 488 void setCurrentWPU( std::shared_ptr< WPUContext > wpu ); 489 490 DeepPathStore m_path_store; 491 std::unique_ptr< PersDeepPathStore > m_pers_path_store; 492 std::unique_ptr< PersDeepPathStore > m_pers_path_store_archive; 493 494 std::string m_current_hint; 495 time_t m_hint_time; 496 RefCount< HintDB > m_hint_db; 497 RefCount< PathnameWatcher > m_pathname_watcher; 498 std::set< std::string > m_changed_paths; 499 500 enum ssh_allow_t { SSH_ASK, SSH_NEVER, SSH_ALWAYS } m_ssh_allow; 501 502 static mode_t m_process_umask; 503 504 RefCount< MenuTreeUI > m_menu_ui; 505 bool m_menu_active; 506 507 int m_commandmenu_original_button_banknr; 508 int m_commandmenu_original_path_banknr; 509 510 static std::unique_ptr< PersistentKVP > m_pers_kvp_store; 511 static KVPStore m_kvp_store; 512 513 bool m_path_jump_in_progress; 514 std::string m_path_jump_last_filter; 515 516 std::unique_ptr< PrefixDB > m_pdb; 517 518 bool m_key_chain_cand_active; 519 520 TimedText m_button_help_text; 521 522 std::list< std::future< ExistenceTest::existence_state_t > > m_existence_futures; 523 524 std::string m_pending_config_open; 525 WConfigInitialCommand m_pending_config_command; 526 527 TimedText m_help_message; 528 bool m_help_active = false; 529 530 std::weak_ptr< WPUContext > m_current_wpu; 531 532 static std::unique_ptr< FileCommandLog > m_command_log; 533 static std::mutex m_command_log_mutex; 534 }; 535 536 #endif 537 538 /* Local Variables: */ 539 /* mode:c++ */ 540 /* End: */ 541