From 83b9bf0e3bfb1d842b10b80bbe749095b2c661a1 Mon Sep 17 00:00:00 2001 From: tpearson Date: Mon, 22 Feb 2010 18:58:28 +0000 Subject: Added old KDE3 version of Krusader git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/krusader@1094427 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- krusader/ActionMan/Makefile.am | 14 + krusader/ActionMan/actionman.cpp | 60 + krusader/ActionMan/actionman.h | 36 + krusader/ActionMan/actionproperty.cpp | 470 +++++ krusader/ActionMan/actionproperty.h | 146 ++ krusader/ActionMan/actionpropertybase.cpp | 463 +++++ krusader/ActionMan/actionpropertybase.ui | 1125 +++++++++++ krusader/ActionMan/addplaceholderpopup.cpp | 582 ++++++ krusader/ActionMan/addplaceholderpopup.h | 318 +++ krusader/ActionMan/useractionlistview.cpp | 232 +++ krusader/ActionMan/useractionlistview.h | 81 + krusader/ActionMan/useractionpage.cpp | 317 +++ krusader/ActionMan/useractionpage.h | 73 + krusader/BookMan/Makefile.am | 11 + krusader/BookMan/kraddbookmarkdlg.cpp | 117 ++ krusader/BookMan/kraddbookmarkdlg.h | 39 + krusader/BookMan/krbookmark.cpp | 92 + krusader/BookMan/krbookmark.h | 45 + krusader/BookMan/krbookmarkbutton.cpp | 38 + krusader/BookMan/krbookmarkbutton.h | 23 + krusader/BookMan/krbookmarkhandler.cpp | 576 ++++++ krusader/BookMan/krbookmarkhandler.h | 63 + krusader/Dialogs/Makefile.am | 22 + krusader/Dialogs/checksumdlg.cpp | 603 ++++++ krusader/Dialogs/checksumdlg.h | 54 + krusader/Dialogs/krdialogs.cpp | 255 +++ krusader/Dialogs/krdialogs.h | 115 ++ krusader/Dialogs/krkeydialog.cpp | 157 ++ krusader/Dialogs/krkeydialog.h | 37 + krusader/Dialogs/krmaskchoice.cpp | 179 ++ krusader/Dialogs/krmaskchoice.h | 76 + krusader/Dialogs/krpleasewait.cpp | 153 ++ krusader/Dialogs/krpleasewait.h | 82 + krusader/Dialogs/krprogress.cpp | 270 +++ krusader/Dialogs/krprogress.h | 86 + krusader/Dialogs/krspecialwidgets.cpp | 239 +++ krusader/Dialogs/krspecialwidgets.h | 126 ++ krusader/Dialogs/krspwidgets.cpp | 316 +++ krusader/Dialogs/krspwidgets.h | 110 ++ krusader/Dialogs/krsqueezedtextlabel.cpp | 80 + krusader/Dialogs/krsqueezedtextlabel.h | 44 + krusader/Dialogs/kurllistrequester.cpp | 202 ++ krusader/Dialogs/kurllistrequester.h | 76 + krusader/Dialogs/newftpgui.cpp | 185 ++ krusader/Dialogs/newftpgui.h | 54 + krusader/Dialogs/packgui.cpp | 120 ++ krusader/Dialogs/packgui.h | 53 + krusader/Dialogs/packguibase.cpp | 468 +++++ krusader/Dialogs/packguibase.h | 109 ++ krusader/Dialogs/percentalsplitter.cpp | 193 ++ krusader/Dialogs/percentalsplitter.h | 58 + krusader/Dialogs/popularurls.cpp | 307 +++ krusader/Dialogs/popularurls.h | 84 + krusader/DiskUsage/Makefile.am | 17 + krusader/DiskUsage/diskusage.cpp | 1147 +++++++++++ krusader/DiskUsage/diskusage.h | 204 ++ krusader/DiskUsage/diskusagegui.cpp | 227 +++ krusader/DiskUsage/diskusagegui.h | 89 + krusader/DiskUsage/dufilelight.cpp | 236 +++ krusader/DiskUsage/dufilelight.h | 80 + krusader/DiskUsage/dulines.cpp | 522 +++++ krusader/DiskUsage/dulines.h | 78 + krusader/DiskUsage/dulistview.cpp | 293 +++ krusader/DiskUsage/dulistview.h | 144 ++ krusader/DiskUsage/filelightParts/Config.cpp | 50 + krusader/DiskUsage/filelightParts/Config.h | 37 + krusader/DiskUsage/filelightParts/Makefile.am | 9 + krusader/DiskUsage/filelightParts/debug.h | 14 + krusader/DiskUsage/filelightParts/fileTree.cpp | 78 + krusader/DiskUsage/filelightParts/fileTree.h | 299 +++ krusader/DiskUsage/radialMap/Makefile.am | 14 + krusader/DiskUsage/radialMap/builder.cpp | 139 ++ krusader/DiskUsage/radialMap/builder.h | 37 + krusader/DiskUsage/radialMap/labels.cpp | 342 ++++ krusader/DiskUsage/radialMap/map.cpp | 432 +++++ krusader/DiskUsage/radialMap/radialMap.h | 71 + krusader/DiskUsage/radialMap/segmentTip.cpp | 163 ++ krusader/DiskUsage/radialMap/segmentTip.h | 33 + krusader/DiskUsage/radialMap/sincos.h | 17 + krusader/DiskUsage/radialMap/widget.cpp | 199 ++ krusader/DiskUsage/radialMap/widget.h | 110 ++ krusader/DiskUsage/radialMap/widgetEvents.cpp | 241 +++ krusader/Filter/Makefile.am | 11 + krusader/Filter/advancedfilter.cpp | 711 +++++++ krusader/Filter/advancedfilter.h | 115 ++ krusader/Filter/filterbase.h | 51 + krusader/Filter/filterdialog.cpp | 87 + krusader/Filter/filterdialog.h | 60 + krusader/Filter/filtertabs.cpp | 133 ++ krusader/Filter/filtertabs.h | 80 + krusader/Filter/generalfilter.cpp | 536 +++++ krusader/Filter/generalfilter.h | 106 + krusader/GUI/Makefile.am | 18 + krusader/GUI/dirhistorybutton.cpp | 82 + krusader/GUI/dirhistorybutton.h | 56 + krusader/GUI/dirhistoryqueue.cpp | 87 + krusader/GUI/dirhistoryqueue.h | 47 + krusader/GUI/kcmdline.cpp | 253 +++ krusader/GUI/kcmdline.h | 99 + krusader/GUI/kcmdmodebutton.cpp | 74 + krusader/GUI/kcmdmodebutton.h | 52 + krusader/GUI/kfnkeys.cpp | 133 ++ krusader/GUI/kfnkeys.h | 54 + krusader/GUI/krremoteencodingmenu.cpp | 207 ++ krusader/GUI/krremoteencodingmenu.h | 67 + krusader/GUI/krusaderstatus.cpp | 46 + krusader/GUI/krusaderstatus.h | 56 + krusader/GUI/mediabutton.cpp | 692 +++++++ krusader/GUI/mediabutton.h | 106 + krusader/GUI/profilemanager.cpp | 198 ++ krusader/GUI/profilemanager.h | 69 + krusader/GUI/syncbrowsebutton.cpp | 72 + krusader/GUI/syncbrowsebutton.h | 66 + krusader/KViewer/Makefile.am | 11 + krusader/KViewer/diskusageviewer.cpp | 129 ++ krusader/KViewer/diskusageviewer.h | 68 + krusader/KViewer/kimagefilepreview.cpp | 136 ++ krusader/KViewer/kimagefilepreview.h | 70 + krusader/KViewer/krviewer.cpp | 702 +++++++ krusader/KViewer/krviewer.h | 128 ++ krusader/KViewer/panelviewer.cpp | 307 +++ krusader/KViewer/panelviewer.h | 88 + krusader/Konfigurator/Makefile.am | 23 + krusader/Konfigurator/kgadvanced.cpp | 133 ++ krusader/Konfigurator/kgadvanced.h | 44 + krusader/Konfigurator/kgarchives.cpp | 155 ++ krusader/Konfigurator/kgarchives.h | 54 + krusader/Konfigurator/kgcolors.cpp | 633 ++++++ krusader/Konfigurator/kgcolors.h | 139 ++ krusader/Konfigurator/kgdependencies.cpp | 169 ++ krusader/Konfigurator/kgdependencies.h | 58 + krusader/Konfigurator/kggeneral.cpp | 213 ++ krusader/Konfigurator/kggeneral.h | 54 + krusader/Konfigurator/kglookfeel.cpp | 373 ++++ krusader/Konfigurator/kglookfeel.h | 69 + krusader/Konfigurator/kgprotocols.cpp | 418 ++++ krusader/Konfigurator/kgprotocols.h | 86 + krusader/Konfigurator/kgstartup.cpp | 117 ++ krusader/Konfigurator/kgstartup.h | 52 + krusader/Konfigurator/kguseractions.cpp | 106 + krusader/Konfigurator/kguseractions.h | 51 + krusader/Konfigurator/kgwelcome.cpp | 50 + krusader/Konfigurator/kgwelcome.h | 44 + krusader/Konfigurator/konfigurator.cpp | 220 +++ krusader/Konfigurator/konfigurator.h | 81 + krusader/Konfigurator/konfiguratoritems.cpp | 815 ++++++++ krusader/Konfigurator/konfiguratoritems.h | 418 ++++ krusader/Konfigurator/konfiguratorpage.cpp | 334 ++++ krusader/Konfigurator/konfiguratorpage.h | 522 +++++ krusader/Konfigurator/krresulttable.cpp | 377 ++++ krusader/Konfigurator/krresulttable.h | 140 ++ krusader/Konfigurator/krresulttabledialog.cpp | 97 + krusader/Konfigurator/krresulttabledialog.h | 84 + krusader/Konfigurator/searchobject.cpp | 106 + krusader/Konfigurator/searchobject.h | 131 ++ krusader/KrJS/Makefile.am | 13 + krusader/KrJS/krjs.cpp | 89 + krusader/KrJS/krjs.h | 32 + krusader/Locate/Makefile.am | 7 + krusader/Locate/locate.cpp | 613 ++++++ krusader/Locate/locate.h | 100 + krusader/Makefile.am | 192 ++ krusader/MountMan/Makefile.am | 10 + krusader/MountMan/kdiskfreesp.cpp | 168 ++ krusader/MountMan/kdiskfreesp.h | 88 + krusader/MountMan/kmountman.cpp | 327 ++++ krusader/MountMan/kmountman.h | 102 + krusader/MountMan/kmountmangui.cpp | 396 ++++ krusader/MountMan/kmountmangui.h | 198 ++ krusader/Panel/Makefile.am | 29 + krusader/Panel/krbriefview.cpp | 1461 ++++++++++++++ krusader/Panel/krbriefview.h | 172 ++ krusader/Panel/krbriefviewitem.cpp | 225 +++ krusader/Panel/krbriefviewitem.h | 79 + krusader/Panel/krcalcspacedialog.cpp | 187 ++ krusader/Panel/krcalcspacedialog.h | 106 + krusader/Panel/krcolorcache.cpp | 761 ++++++++ krusader/Panel/krcolorcache.h | 101 + krusader/Panel/krdetailedview.cpp | 1587 +++++++++++++++ krusader/Panel/krdetailedview.h | 180 ++ krusader/Panel/krdetailedviewitem.cpp | 313 +++ krusader/Panel/krdetailedviewitem.h | 73 + krusader/Panel/krdrag.cpp | 103 + krusader/Panel/krdrag.h | 62 + krusader/Panel/krpopupmenu.cpp | 354 ++++ krusader/Panel/krpopupmenu.h | 77 + krusader/Panel/krpreviewpopup.cpp | 68 + krusader/Panel/krpreviewpopup.h | 48 + krusader/Panel/krselectionmode.cpp | 61 + krusader/Panel/krselectionmode.h | 97 + krusader/Panel/krview.cpp | 332 ++++ krusader/Panel/krview.h | 245 +++ krusader/Panel/krviewitem.cpp | 105 + krusader/Panel/krviewitem.h | 76 + krusader/Panel/listpanel.cpp | 1115 +++++++++++ krusader/Panel/listpanel.h | 211 ++ krusader/Panel/panelfunc.cpp | 1186 ++++++++++++ krusader/Panel/panelfunc.h | 105 + krusader/Panel/panelpopup.cpp | 400 ++++ krusader/Panel/panelpopup.h | 73 + krusader/Queue/Makefile.am | 10 + krusader/Queue/queue.cpp | 22 + krusader/Queue/queue.h | 32 + krusader/Queue/queue_mgr.cpp | 31 + krusader/Queue/queue_mgr.h | 26 + krusader/Queue/queuewidget.cpp | 10 + krusader/Queue/queuewidget.h | 14 + krusader/RemoteMan/Makefile.am | 9 + krusader/RemoteMan/remoteman.cpp | 385 ++++ krusader/RemoteMan/remoteman.h | 70 + krusader/RemoteMan/remotemanbase.cpp | 331 ++++ krusader/RemoteMan/remotemanbase.h | 82 + krusader/Search/Makefile.am | 9 + krusader/Search/krsearchdialog.cpp | 628 ++++++ krusader/Search/krsearchdialog.h | 183 ++ krusader/Search/krsearchmod.cpp | 253 +++ krusader/Search/krsearchmod.h | 85 + krusader/Splitter/Makefile.am | 11 + krusader/Splitter/combiner.cpp | 328 ++++ krusader/Splitter/combiner.h | 92 + krusader/Splitter/crc32.cpp | 69 + krusader/Splitter/crc32.h | 48 + krusader/Splitter/splitter.cpp | 252 +++ krusader/Splitter/splitter.h | 83 + krusader/Splitter/splittergui.cpp | 213 ++ krusader/Splitter/splittergui.h | 178 ++ krusader/Synchronizer/Makefile.am | 13 + krusader/Synchronizer/feedtolistboxdialog.cpp | 200 ++ krusader/Synchronizer/feedtolistboxdialog.h | 65 + krusader/Synchronizer/synchronizedialog.cpp | 199 ++ krusader/Synchronizer/synchronizedialog.h | 91 + krusader/Synchronizer/synchronizer.cpp | 1493 ++++++++++++++ krusader/Synchronizer/synchronizer.h | 204 ++ krusader/Synchronizer/synchronizerdirlist.cpp | 216 +++ krusader/Synchronizer/synchronizerdirlist.h | 72 + krusader/Synchronizer/synchronizerfileitem.h | 170 ++ krusader/Synchronizer/synchronizergui.cpp | 2478 ++++++++++++++++++++++++ krusader/Synchronizer/synchronizergui.h | 224 +++ krusader/Synchronizer/synchronizertask.cpp | 343 ++++ krusader/Synchronizer/synchronizertask.h | 167 ++ krusader/UserAction/Makefile.am | 17 + krusader/UserAction/expander.cpp | 1224 ++++++++++++ krusader/UserAction/expander.h | 245 +++ krusader/UserAction/kraction.cpp | 586 ++++++ krusader/UserAction/kraction.h | 167 ++ krusader/UserAction/kractionbase.cpp | 77 + krusader/UserAction/kractionbase.h | 97 + krusader/UserAction/tstring.h | 113 ++ krusader/UserAction/useraction.cpp | 210 ++ krusader/UserAction/useraction.h | 145 ++ krusader/UserAction/useractionpopupmenu.cpp | 26 + krusader/UserAction/useractionpopupmenu.h | 25 + krusader/UserMenu/Makefile.am | 7 + krusader/UserMenu/usermenu.cpp | 85 + krusader/UserMenu/usermenu.h | 46 + krusader/VFS/Makefile.am | 19 + krusader/VFS/arc_vfs.cpp | 866 +++++++++ krusader/VFS/arc_vfs.h | 130 ++ krusader/VFS/ftp_vfs.cpp | 297 +++ krusader/VFS/ftp_vfs.h | 79 + krusader/VFS/krarchandler.cpp | 756 ++++++++ krusader/VFS/krarchandler.h | 148 ++ krusader/VFS/krdirwatch.cpp | 124 ++ krusader/VFS/krdirwatch.h | 79 + krusader/VFS/krpermhandler.cpp | 355 ++++ krusader/VFS/krpermhandler.h | 89 + krusader/VFS/krquery.cpp | 653 +++++++ krusader/VFS/krquery.h | 208 ++ krusader/VFS/krvfshandler.cpp | 71 + krusader/VFS/krvfshandler.h | 40 + krusader/VFS/normal_vfs.cpp | 437 +++++ krusader/VFS/normal_vfs.h | 92 + krusader/VFS/preservingcopyjob.cpp | 319 +++ krusader/VFS/preservingcopyjob.h | 84 + krusader/VFS/temp_vfs.cpp | 127 ++ krusader/VFS/temp_vfs.h | 57 + krusader/VFS/vfile.cpp | 311 +++ krusader/VFS/vfile.h | 166 ++ krusader/VFS/vfs.cpp | 393 ++++ krusader/VFS/vfs.h | 186 ++ krusader/VFS/virt_vfs.cpp | 341 ++++ krusader/VFS/virt_vfs.h | 76 + krusader/VFS/virtualcopyjob.cpp | 316 +++ krusader/VFS/virtualcopyjob.h | 125 ++ krusader/alpa-yellow.color | Bin 0 -> 2468 bytes krusader/bash.color | Bin 0 -> 2650 bytes krusader/calc.js | 64 + krusader/calc.ui | 267 +++ krusader/cr16-app-krusader_blue.png | Bin 0 -> 910 bytes krusader/cr16-app-krusader_red.png | Bin 0 -> 935 bytes krusader/cr16-app-krusader_root.png | Bin 0 -> 210 bytes krusader/cr16-app-krusader_user.png | Bin 0 -> 184 bytes krusader/cr22-app-krusader_blue.png | Bin 0 -> 1377 bytes krusader/cr22-app-krusader_red.png | Bin 0 -> 1436 bytes krusader/cr22-app-krusader_root.png | Bin 0 -> 579 bytes krusader/cr22-app-krusader_shield.png | Bin 0 -> 1256 bytes krusader/cr22-app-krusader_user.png | Bin 0 -> 568 bytes krusader/cr32-app-krusader_blue.png | Bin 0 -> 2453 bytes krusader/cr32-app-krusader_red.png | Bin 0 -> 2523 bytes krusader/cr32-app-krusader_root.png | Bin 0 -> 846 bytes krusader/cr32-app-krusader_shield.png | Bin 0 -> 2024 bytes krusader/cr32-app-krusader_user.png | Bin 0 -> 922 bytes krusader/cr48-app-krusader_blue.png | Bin 0 -> 4528 bytes krusader/cr48-app-krusader_red.png | Bin 0 -> 4497 bytes krusader/cr48-app-krusader_root.png | Bin 0 -> 2002 bytes krusader/cr48-app-krusader_shield.png | Bin 0 -> 3302 bytes krusader/cr48-app-krusader_user.png | Bin 0 -> 2105 bytes krusader/cr64-app-krusader_blue.png | Bin 0 -> 6469 bytes krusader/cr64-app-krusader_red.png | Bin 0 -> 6585 bytes krusader/cr64-app-krusader_root.png | Bin 0 -> 2731 bytes krusader/cr64-app-krusader_shield.png | Bin 0 -> 4794 bytes krusader/cr64-app-krusader_user.png | Bin 0 -> 2826 bytes krusader/defaults.h | 306 +++ krusader/dos_navigator.color | Bin 0 -> 2674 bytes krusader/kicons.cpp | 377 ++++ krusader/kicons.h | 29 + krusader/krservices.cpp | 216 +++ krusader/krservices.h | 78 + krusader/krslots.cpp | 944 +++++++++ krusader/krslots.h | 187 ++ krusader/krusader.cpp | 1248 ++++++++++++ krusader/krusader.desktop | 86 + krusader/krusader.h | 274 +++ krusader/krusader_root-mode.desktop | 90 + krusader/krusaderapp.h | 31 + krusader/krusaderui.rc | 193 ++ krusader/krusaderview.cpp | 415 ++++ krusader/krusaderview.h | 110 ++ krusader/lo16-app-krusader.png | Bin 0 -> 814 bytes krusader/lo32-app-krusader.png | Bin 0 -> 3742 bytes krusader/lo32-app-krusader2.png | Bin 0 -> 680 bytes krusader/main.cpp | 248 +++ krusader/midnight_cmd_AHamann.color | Bin 0 -> 2732 bytes krusader/midnight_commander.color | Bin 0 -> 1776 bytes krusader/midnight_commander.keymap | Bin 0 -> 1375 bytes krusader/midnight_commander.keymap.info | 42 + krusader/mount.js | 37 + krusader/mount.ui | 208 ++ krusader/panelmanager.cpp | 352 ++++ krusader/panelmanager.h | 78 + krusader/paneltabbar.cpp | 262 +++ krusader/paneltabbar.h | 99 + krusader/recode.js | 202 ++ krusader/recode.ui | 297 +++ krusader/resources.h | 42 + krusader/select_from_file.js | 13 + krusader/splash.png | Bin 0 -> 67168 bytes krusader/total_cmd_pleasent.color | Bin 0 -> 2652 bytes krusader/total_commander.color | Bin 0 -> 1760 bytes krusader/total_commander.keymap | 112 ++ krusader/total_commander.keymap.info | 10 + krusader/useraction_examples.xml | 406 ++++ krusader/x-ace.desktop | 7 + 353 files changed, 66645 insertions(+) create mode 100644 krusader/ActionMan/Makefile.am create mode 100644 krusader/ActionMan/actionman.cpp create mode 100644 krusader/ActionMan/actionman.h create mode 100644 krusader/ActionMan/actionproperty.cpp create mode 100644 krusader/ActionMan/actionproperty.h create mode 100644 krusader/ActionMan/actionpropertybase.cpp create mode 100644 krusader/ActionMan/actionpropertybase.ui create mode 100644 krusader/ActionMan/addplaceholderpopup.cpp create mode 100644 krusader/ActionMan/addplaceholderpopup.h create mode 100644 krusader/ActionMan/useractionlistview.cpp create mode 100644 krusader/ActionMan/useractionlistview.h create mode 100644 krusader/ActionMan/useractionpage.cpp create mode 100644 krusader/ActionMan/useractionpage.h create mode 100644 krusader/BookMan/Makefile.am create mode 100644 krusader/BookMan/kraddbookmarkdlg.cpp create mode 100644 krusader/BookMan/kraddbookmarkdlg.h create mode 100644 krusader/BookMan/krbookmark.cpp create mode 100644 krusader/BookMan/krbookmark.h create mode 100644 krusader/BookMan/krbookmarkbutton.cpp create mode 100644 krusader/BookMan/krbookmarkbutton.h create mode 100644 krusader/BookMan/krbookmarkhandler.cpp create mode 100644 krusader/BookMan/krbookmarkhandler.h create mode 100644 krusader/Dialogs/Makefile.am create mode 100644 krusader/Dialogs/checksumdlg.cpp create mode 100644 krusader/Dialogs/checksumdlg.h create mode 100644 krusader/Dialogs/krdialogs.cpp create mode 100644 krusader/Dialogs/krdialogs.h create mode 100644 krusader/Dialogs/krkeydialog.cpp create mode 100644 krusader/Dialogs/krkeydialog.h create mode 100644 krusader/Dialogs/krmaskchoice.cpp create mode 100644 krusader/Dialogs/krmaskchoice.h create mode 100644 krusader/Dialogs/krpleasewait.cpp create mode 100644 krusader/Dialogs/krpleasewait.h create mode 100644 krusader/Dialogs/krprogress.cpp create mode 100644 krusader/Dialogs/krprogress.h create mode 100644 krusader/Dialogs/krspecialwidgets.cpp create mode 100644 krusader/Dialogs/krspecialwidgets.h create mode 100644 krusader/Dialogs/krspwidgets.cpp create mode 100644 krusader/Dialogs/krspwidgets.h create mode 100644 krusader/Dialogs/krsqueezedtextlabel.cpp create mode 100644 krusader/Dialogs/krsqueezedtextlabel.h create mode 100644 krusader/Dialogs/kurllistrequester.cpp create mode 100644 krusader/Dialogs/kurllistrequester.h create mode 100644 krusader/Dialogs/newftpgui.cpp create mode 100644 krusader/Dialogs/newftpgui.h create mode 100644 krusader/Dialogs/packgui.cpp create mode 100644 krusader/Dialogs/packgui.h create mode 100644 krusader/Dialogs/packguibase.cpp create mode 100644 krusader/Dialogs/packguibase.h create mode 100644 krusader/Dialogs/percentalsplitter.cpp create mode 100644 krusader/Dialogs/percentalsplitter.h create mode 100644 krusader/Dialogs/popularurls.cpp create mode 100644 krusader/Dialogs/popularurls.h create mode 100644 krusader/DiskUsage/Makefile.am create mode 100644 krusader/DiskUsage/diskusage.cpp create mode 100644 krusader/DiskUsage/diskusage.h create mode 100644 krusader/DiskUsage/diskusagegui.cpp create mode 100644 krusader/DiskUsage/diskusagegui.h create mode 100644 krusader/DiskUsage/dufilelight.cpp create mode 100644 krusader/DiskUsage/dufilelight.h create mode 100644 krusader/DiskUsage/dulines.cpp create mode 100644 krusader/DiskUsage/dulines.h create mode 100644 krusader/DiskUsage/dulistview.cpp create mode 100644 krusader/DiskUsage/dulistview.h create mode 100644 krusader/DiskUsage/filelightParts/Config.cpp create mode 100644 krusader/DiskUsage/filelightParts/Config.h create mode 100644 krusader/DiskUsage/filelightParts/Makefile.am create mode 100644 krusader/DiskUsage/filelightParts/debug.h create mode 100644 krusader/DiskUsage/filelightParts/fileTree.cpp create mode 100644 krusader/DiskUsage/filelightParts/fileTree.h create mode 100644 krusader/DiskUsage/radialMap/Makefile.am create mode 100644 krusader/DiskUsage/radialMap/builder.cpp create mode 100644 krusader/DiskUsage/radialMap/builder.h create mode 100644 krusader/DiskUsage/radialMap/labels.cpp create mode 100644 krusader/DiskUsage/radialMap/map.cpp create mode 100644 krusader/DiskUsage/radialMap/radialMap.h create mode 100644 krusader/DiskUsage/radialMap/segmentTip.cpp create mode 100644 krusader/DiskUsage/radialMap/segmentTip.h create mode 100644 krusader/DiskUsage/radialMap/sincos.h create mode 100644 krusader/DiskUsage/radialMap/widget.cpp create mode 100644 krusader/DiskUsage/radialMap/widget.h create mode 100644 krusader/DiskUsage/radialMap/widgetEvents.cpp create mode 100644 krusader/Filter/Makefile.am create mode 100644 krusader/Filter/advancedfilter.cpp create mode 100644 krusader/Filter/advancedfilter.h create mode 100644 krusader/Filter/filterbase.h create mode 100644 krusader/Filter/filterdialog.cpp create mode 100644 krusader/Filter/filterdialog.h create mode 100644 krusader/Filter/filtertabs.cpp create mode 100644 krusader/Filter/filtertabs.h create mode 100644 krusader/Filter/generalfilter.cpp create mode 100644 krusader/Filter/generalfilter.h create mode 100644 krusader/GUI/Makefile.am create mode 100644 krusader/GUI/dirhistorybutton.cpp create mode 100644 krusader/GUI/dirhistorybutton.h create mode 100644 krusader/GUI/dirhistoryqueue.cpp create mode 100644 krusader/GUI/dirhistoryqueue.h create mode 100644 krusader/GUI/kcmdline.cpp create mode 100644 krusader/GUI/kcmdline.h create mode 100644 krusader/GUI/kcmdmodebutton.cpp create mode 100644 krusader/GUI/kcmdmodebutton.h create mode 100644 krusader/GUI/kfnkeys.cpp create mode 100644 krusader/GUI/kfnkeys.h create mode 100644 krusader/GUI/krremoteencodingmenu.cpp create mode 100644 krusader/GUI/krremoteencodingmenu.h create mode 100644 krusader/GUI/krusaderstatus.cpp create mode 100644 krusader/GUI/krusaderstatus.h create mode 100644 krusader/GUI/mediabutton.cpp create mode 100644 krusader/GUI/mediabutton.h create mode 100644 krusader/GUI/profilemanager.cpp create mode 100644 krusader/GUI/profilemanager.h create mode 100644 krusader/GUI/syncbrowsebutton.cpp create mode 100644 krusader/GUI/syncbrowsebutton.h create mode 100644 krusader/KViewer/Makefile.am create mode 100644 krusader/KViewer/diskusageviewer.cpp create mode 100644 krusader/KViewer/diskusageviewer.h create mode 100644 krusader/KViewer/kimagefilepreview.cpp create mode 100644 krusader/KViewer/kimagefilepreview.h create mode 100644 krusader/KViewer/krviewer.cpp create mode 100644 krusader/KViewer/krviewer.h create mode 100644 krusader/KViewer/panelviewer.cpp create mode 100644 krusader/KViewer/panelviewer.h create mode 100644 krusader/Konfigurator/Makefile.am create mode 100644 krusader/Konfigurator/kgadvanced.cpp create mode 100644 krusader/Konfigurator/kgadvanced.h create mode 100644 krusader/Konfigurator/kgarchives.cpp create mode 100644 krusader/Konfigurator/kgarchives.h create mode 100644 krusader/Konfigurator/kgcolors.cpp create mode 100644 krusader/Konfigurator/kgcolors.h create mode 100644 krusader/Konfigurator/kgdependencies.cpp create mode 100644 krusader/Konfigurator/kgdependencies.h create mode 100644 krusader/Konfigurator/kggeneral.cpp create mode 100644 krusader/Konfigurator/kggeneral.h create mode 100644 krusader/Konfigurator/kglookfeel.cpp create mode 100644 krusader/Konfigurator/kglookfeel.h create mode 100644 krusader/Konfigurator/kgprotocols.cpp create mode 100644 krusader/Konfigurator/kgprotocols.h create mode 100644 krusader/Konfigurator/kgstartup.cpp create mode 100644 krusader/Konfigurator/kgstartup.h create mode 100644 krusader/Konfigurator/kguseractions.cpp create mode 100644 krusader/Konfigurator/kguseractions.h create mode 100644 krusader/Konfigurator/kgwelcome.cpp create mode 100644 krusader/Konfigurator/kgwelcome.h create mode 100644 krusader/Konfigurator/konfigurator.cpp create mode 100644 krusader/Konfigurator/konfigurator.h create mode 100644 krusader/Konfigurator/konfiguratoritems.cpp create mode 100644 krusader/Konfigurator/konfiguratoritems.h create mode 100644 krusader/Konfigurator/konfiguratorpage.cpp create mode 100644 krusader/Konfigurator/konfiguratorpage.h create mode 100644 krusader/Konfigurator/krresulttable.cpp create mode 100644 krusader/Konfigurator/krresulttable.h create mode 100644 krusader/Konfigurator/krresulttabledialog.cpp create mode 100644 krusader/Konfigurator/krresulttabledialog.h create mode 100644 krusader/Konfigurator/searchobject.cpp create mode 100644 krusader/Konfigurator/searchobject.h create mode 100644 krusader/KrJS/Makefile.am create mode 100644 krusader/KrJS/krjs.cpp create mode 100644 krusader/KrJS/krjs.h create mode 100644 krusader/Locate/Makefile.am create mode 100755 krusader/Locate/locate.cpp create mode 100755 krusader/Locate/locate.h create mode 100644 krusader/Makefile.am create mode 100644 krusader/MountMan/Makefile.am create mode 100644 krusader/MountMan/kdiskfreesp.cpp create mode 100644 krusader/MountMan/kdiskfreesp.h create mode 100644 krusader/MountMan/kmountman.cpp create mode 100644 krusader/MountMan/kmountman.h create mode 100644 krusader/MountMan/kmountmangui.cpp create mode 100644 krusader/MountMan/kmountmangui.h create mode 100644 krusader/Panel/Makefile.am create mode 100644 krusader/Panel/krbriefview.cpp create mode 100644 krusader/Panel/krbriefview.h create mode 100644 krusader/Panel/krbriefviewitem.cpp create mode 100644 krusader/Panel/krbriefviewitem.h create mode 100644 krusader/Panel/krcalcspacedialog.cpp create mode 100644 krusader/Panel/krcalcspacedialog.h create mode 100644 krusader/Panel/krcolorcache.cpp create mode 100644 krusader/Panel/krcolorcache.h create mode 100644 krusader/Panel/krdetailedview.cpp create mode 100644 krusader/Panel/krdetailedview.h create mode 100644 krusader/Panel/krdetailedviewitem.cpp create mode 100644 krusader/Panel/krdetailedviewitem.h create mode 100644 krusader/Panel/krdrag.cpp create mode 100644 krusader/Panel/krdrag.h create mode 100644 krusader/Panel/krpopupmenu.cpp create mode 100644 krusader/Panel/krpopupmenu.h create mode 100644 krusader/Panel/krpreviewpopup.cpp create mode 100644 krusader/Panel/krpreviewpopup.h create mode 100644 krusader/Panel/krselectionmode.cpp create mode 100644 krusader/Panel/krselectionmode.h create mode 100644 krusader/Panel/krview.cpp create mode 100644 krusader/Panel/krview.h create mode 100644 krusader/Panel/krviewitem.cpp create mode 100644 krusader/Panel/krviewitem.h create mode 100644 krusader/Panel/listpanel.cpp create mode 100644 krusader/Panel/listpanel.h create mode 100755 krusader/Panel/panelfunc.cpp create mode 100644 krusader/Panel/panelfunc.h create mode 100644 krusader/Panel/panelpopup.cpp create mode 100644 krusader/Panel/panelpopup.h create mode 100644 krusader/Queue/Makefile.am create mode 100644 krusader/Queue/queue.cpp create mode 100644 krusader/Queue/queue.h create mode 100644 krusader/Queue/queue_mgr.cpp create mode 100644 krusader/Queue/queue_mgr.h create mode 100644 krusader/Queue/queuewidget.cpp create mode 100644 krusader/Queue/queuewidget.h create mode 100644 krusader/RemoteMan/Makefile.am create mode 100644 krusader/RemoteMan/remoteman.cpp create mode 100644 krusader/RemoteMan/remoteman.h create mode 100644 krusader/RemoteMan/remotemanbase.cpp create mode 100644 krusader/RemoteMan/remotemanbase.h create mode 100644 krusader/Search/Makefile.am create mode 100644 krusader/Search/krsearchdialog.cpp create mode 100644 krusader/Search/krsearchdialog.h create mode 100644 krusader/Search/krsearchmod.cpp create mode 100644 krusader/Search/krsearchmod.h create mode 100644 krusader/Splitter/Makefile.am create mode 100644 krusader/Splitter/combiner.cpp create mode 100644 krusader/Splitter/combiner.h create mode 100755 krusader/Splitter/crc32.cpp create mode 100755 krusader/Splitter/crc32.h create mode 100644 krusader/Splitter/splitter.cpp create mode 100644 krusader/Splitter/splitter.h create mode 100644 krusader/Splitter/splittergui.cpp create mode 100644 krusader/Splitter/splittergui.h create mode 100755 krusader/Synchronizer/Makefile.am create mode 100644 krusader/Synchronizer/feedtolistboxdialog.cpp create mode 100644 krusader/Synchronizer/feedtolistboxdialog.h create mode 100755 krusader/Synchronizer/synchronizedialog.cpp create mode 100755 krusader/Synchronizer/synchronizedialog.h create mode 100755 krusader/Synchronizer/synchronizer.cpp create mode 100755 krusader/Synchronizer/synchronizer.h create mode 100644 krusader/Synchronizer/synchronizerdirlist.cpp create mode 100644 krusader/Synchronizer/synchronizerdirlist.h create mode 100644 krusader/Synchronizer/synchronizerfileitem.h create mode 100755 krusader/Synchronizer/synchronizergui.cpp create mode 100755 krusader/Synchronizer/synchronizergui.h create mode 100644 krusader/Synchronizer/synchronizertask.cpp create mode 100644 krusader/Synchronizer/synchronizertask.h create mode 100644 krusader/UserAction/Makefile.am create mode 100644 krusader/UserAction/expander.cpp create mode 100644 krusader/UserAction/expander.h create mode 100644 krusader/UserAction/kraction.cpp create mode 100644 krusader/UserAction/kraction.h create mode 100644 krusader/UserAction/kractionbase.cpp create mode 100644 krusader/UserAction/kractionbase.h create mode 100644 krusader/UserAction/tstring.h create mode 100644 krusader/UserAction/useraction.cpp create mode 100644 krusader/UserAction/useraction.h create mode 100644 krusader/UserAction/useractionpopupmenu.cpp create mode 100644 krusader/UserAction/useractionpopupmenu.h create mode 100644 krusader/UserMenu/Makefile.am create mode 100644 krusader/UserMenu/usermenu.cpp create mode 100644 krusader/UserMenu/usermenu.h create mode 100644 krusader/VFS/Makefile.am create mode 100755 krusader/VFS/arc_vfs.cpp create mode 100644 krusader/VFS/arc_vfs.h create mode 100644 krusader/VFS/ftp_vfs.cpp create mode 100644 krusader/VFS/ftp_vfs.h create mode 100644 krusader/VFS/krarchandler.cpp create mode 100644 krusader/VFS/krarchandler.h create mode 100644 krusader/VFS/krdirwatch.cpp create mode 100644 krusader/VFS/krdirwatch.h create mode 100644 krusader/VFS/krpermhandler.cpp create mode 100644 krusader/VFS/krpermhandler.h create mode 100644 krusader/VFS/krquery.cpp create mode 100644 krusader/VFS/krquery.h create mode 100644 krusader/VFS/krvfshandler.cpp create mode 100644 krusader/VFS/krvfshandler.h create mode 100644 krusader/VFS/normal_vfs.cpp create mode 100644 krusader/VFS/normal_vfs.h create mode 100644 krusader/VFS/preservingcopyjob.cpp create mode 100644 krusader/VFS/preservingcopyjob.h create mode 100644 krusader/VFS/temp_vfs.cpp create mode 100644 krusader/VFS/temp_vfs.h create mode 100644 krusader/VFS/vfile.cpp create mode 100644 krusader/VFS/vfile.h create mode 100644 krusader/VFS/vfs.cpp create mode 100644 krusader/VFS/vfs.h create mode 100644 krusader/VFS/virt_vfs.cpp create mode 100644 krusader/VFS/virt_vfs.h create mode 100644 krusader/VFS/virtualcopyjob.cpp create mode 100644 krusader/VFS/virtualcopyjob.h create mode 100644 krusader/alpa-yellow.color create mode 100644 krusader/bash.color create mode 100644 krusader/calc.js create mode 100644 krusader/calc.ui create mode 100644 krusader/cr16-app-krusader_blue.png create mode 100644 krusader/cr16-app-krusader_red.png create mode 100644 krusader/cr16-app-krusader_root.png create mode 100644 krusader/cr16-app-krusader_user.png create mode 100644 krusader/cr22-app-krusader_blue.png create mode 100644 krusader/cr22-app-krusader_red.png create mode 100644 krusader/cr22-app-krusader_root.png create mode 100644 krusader/cr22-app-krusader_shield.png create mode 100644 krusader/cr22-app-krusader_user.png create mode 100644 krusader/cr32-app-krusader_blue.png create mode 100644 krusader/cr32-app-krusader_red.png create mode 100644 krusader/cr32-app-krusader_root.png create mode 100644 krusader/cr32-app-krusader_shield.png create mode 100644 krusader/cr32-app-krusader_user.png create mode 100644 krusader/cr48-app-krusader_blue.png create mode 100644 krusader/cr48-app-krusader_red.png create mode 100644 krusader/cr48-app-krusader_root.png create mode 100644 krusader/cr48-app-krusader_shield.png create mode 100644 krusader/cr48-app-krusader_user.png create mode 100644 krusader/cr64-app-krusader_blue.png create mode 100644 krusader/cr64-app-krusader_red.png create mode 100644 krusader/cr64-app-krusader_root.png create mode 100644 krusader/cr64-app-krusader_shield.png create mode 100644 krusader/cr64-app-krusader_user.png create mode 100644 krusader/defaults.h create mode 100644 krusader/dos_navigator.color create mode 100644 krusader/kicons.cpp create mode 100644 krusader/kicons.h create mode 100644 krusader/krservices.cpp create mode 100644 krusader/krservices.h create mode 100644 krusader/krslots.cpp create mode 100644 krusader/krslots.h create mode 100644 krusader/krusader.cpp create mode 100644 krusader/krusader.desktop create mode 100644 krusader/krusader.h create mode 100644 krusader/krusader_root-mode.desktop create mode 100644 krusader/krusaderapp.h create mode 100644 krusader/krusaderui.rc create mode 100644 krusader/krusaderview.cpp create mode 100644 krusader/krusaderview.h create mode 100644 krusader/lo16-app-krusader.png create mode 100644 krusader/lo32-app-krusader.png create mode 100644 krusader/lo32-app-krusader2.png create mode 100644 krusader/main.cpp create mode 100644 krusader/midnight_cmd_AHamann.color create mode 100644 krusader/midnight_commander.color create mode 100644 krusader/midnight_commander.keymap create mode 100644 krusader/midnight_commander.keymap.info create mode 100644 krusader/mount.js create mode 100644 krusader/mount.ui create mode 100644 krusader/panelmanager.cpp create mode 100644 krusader/panelmanager.h create mode 100644 krusader/paneltabbar.cpp create mode 100644 krusader/paneltabbar.h create mode 100644 krusader/recode.js create mode 100644 krusader/recode.ui create mode 100644 krusader/resources.h create mode 100644 krusader/select_from_file.js create mode 100644 krusader/splash.png create mode 100644 krusader/total_cmd_pleasent.color create mode 100644 krusader/total_commander.color create mode 100644 krusader/total_commander.keymap create mode 100644 krusader/total_commander.keymap.info create mode 100644 krusader/useraction_examples.xml create mode 100644 krusader/x-ace.desktop (limited to 'krusader') diff --git a/krusader/ActionMan/Makefile.am b/krusader/ActionMan/Makefile.am new file mode 100644 index 0000000..e71563a --- /dev/null +++ b/krusader/ActionMan/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libActionMan.a + +INCLUDES = $(all_includes) + +libActionMan_a_METASOURCES = AUTO + +libActionMan_a_SOURCES = \ + actionman.cpp \ + actionpropertybase.ui \ + actionproperty.cpp \ + addplaceholderpopup.cpp \ + useractionlistview.cpp \ + useractionpage.cpp +noinst_HEADERS = useractionpage.h diff --git a/krusader/ActionMan/actionman.cpp b/krusader/ActionMan/actionman.cpp new file mode 100644 index 0000000..10b604b --- /dev/null +++ b/krusader/ActionMan/actionman.cpp @@ -0,0 +1,60 @@ +// +// C++ Implementation: actionman +// +// Description: This manages all useractions +// +// +// Author: Jonas Bähr (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "actionman.h" + +#include +#include + +#include "useractionpage.h" +#include "../krusader.h" +#include "../UserAction/useraction.h" + + +ActionMan::ActionMan( QWidget * parent ) + : KDialogBase( parent, "ActionMan", true /*modal*/, "ActionMan - Manage your useractions", KDialogBase::Apply | KDialogBase::Close ) +{ + setPlainCaption(i18n("ActionMan - Manage Your Useractions")); + + userActionPage = new UserActionPage( this ); + setMainWidget( userActionPage ); + + connect( userActionPage, SIGNAL( changed() ), SLOT( slotEnableApplyButton() ) ); + connect( userActionPage, SIGNAL( applied() ), SLOT( slotDisableApplyButton() ) ); + enableButtonApply( false ); + + exec(); +} + +ActionMan::~ActionMan() { +} + +void ActionMan::slotClose() { + if ( userActionPage->readyToQuit() ) + reject(); +} + +void ActionMan::slotApply() { + userActionPage->applyChanges(); +} + +void ActionMan::slotEnableApplyButton() { + enableButtonApply( true ); +} + +void ActionMan::slotDisableApplyButton() { + enableButtonApply( false ); +} + + + +#include "actionman.moc" diff --git a/krusader/ActionMan/actionman.h b/krusader/ActionMan/actionman.h new file mode 100644 index 0000000..bbfe33f --- /dev/null +++ b/krusader/ActionMan/actionman.h @@ -0,0 +1,36 @@ +// +// C++ Interface: actionman +// +// Description: This manages all useractions +// +// +// Author: Jonas B�r (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef ACTIONMAN_H +#define ACTIONMAN_H + +#include + +class UserActionPage; + +class ActionMan : public KDialogBase { +Q_OBJECT +public: + ActionMan( QWidget* parent=0 ); + ~ActionMan(); + +protected slots: + void slotClose(); + void slotApply(); + void slotEnableApplyButton(); + void slotDisableApplyButton(); + +private: + UserActionPage* userActionPage; +}; + +#endif // ifndef ACTIONMAN_H diff --git a/krusader/ActionMan/actionproperty.cpp b/krusader/ActionMan/actionproperty.cpp new file mode 100644 index 0000000..077b035 --- /dev/null +++ b/krusader/ActionMan/actionproperty.cpp @@ -0,0 +1,470 @@ +// +// C++ Implementation: actionproperty +// +// Description: +// +// +// Author: Jonas B�r (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "actionproperty.h" +#include "addplaceholderpopup.h" + +#include "../UserAction/useraction.h" +#include "../UserAction/kraction.h" +#include "../krusader.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ICON(N) KGlobal::iconLoader()->loadIcon(N, KIcon::Small) + +ActionProperty::ActionProperty( QWidget *parent, const char *name, KrAction *action ) + : ActionPropertyBase( parent, name ), _modified(false) + { + if ( action ) { + _action = action; + updateGUI( _action ); + } + + ButtonAddPlaceholder->setPixmap( ICON("add") ); + ButtonAddStartpath->setPixmap( ICON("fileopen") ); + + // fill with all existing categories + cbCategory->insertStringList( krUserAction->allCategories() ); + + connect( ButtonAddPlaceholder, SIGNAL( clicked() ), this, SLOT( addPlaceholder() ) ); + connect( ButtonAddStartpath, SIGNAL( clicked() ), this, SLOT( addStartpath() ) ); + connect( ButtonNewProtocol, SIGNAL( clicked() ), this, SLOT( newProtocol() ) ); + connect( ButtonEditProtocol, SIGNAL( clicked() ), this, SLOT( editProtocol() ) ); + connect( ButtonRemoveProtocol, SIGNAL( clicked() ), this, SLOT( removeProtocol() ) ); + connect( ButtonAddPath, SIGNAL( clicked() ), this, SLOT( addPath() ) ); + connect( ButtonEditPath, SIGNAL( clicked() ), this, SLOT( editPath() ) ); + connect( ButtonRemovePath, SIGNAL( clicked() ), this, SLOT( removePath() ) ); + connect( ButtonAddMime, SIGNAL( clicked() ), this, SLOT( addMime() ) ); + connect( ButtonEditMime, SIGNAL( clicked() ), this, SLOT( editMime() ) ); + connect( ButtonRemoveMime, SIGNAL( clicked() ), this, SLOT( removeMime() ) ); + connect( ButtonNewFile, SIGNAL( clicked() ), this, SLOT( newFile() ) ); + connect( ButtonEditFile, SIGNAL( clicked() ), this, SLOT( editFile() ) ); + connect( ButtonRemoveFile, SIGNAL( clicked() ), this, SLOT( removeFile() ) ); + connect( KeyButtonShortcut, SIGNAL( capturedShortcut(const KShortcut&) ), this, SLOT( changedShortcut(const KShortcut&) ) ); + // track modifications: + connect( leDistinctName, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( leTitle, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( ButtonIcon, SIGNAL( iconChanged(QString) ), SLOT( setModified() ) ); + connect( cbCategory, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( leTooltip, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( textDescription, SIGNAL( textChanged() ), SLOT( setModified() ) ); + connect( leDistinctName, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( leCommandline, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( leStartpath, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( bgExecType, SIGNAL( clicked(int) ), SLOT( setModified() ) ); + connect( bgAccept, SIGNAL( clicked(int) ), SLOT( setModified() ) ); + connect( KeyButtonShortcut, SIGNAL( capturedShortcut(const KShortcut&) ), SLOT( setModified() ) ); + connect( leDifferentUser, SIGNAL( textChanged(const QString&) ), SLOT( setModified() ) ); + connect( chkDifferentUser, SIGNAL( clicked() ), SLOT( setModified() ) ); + connect( chkConfirmExecution, SIGNAL( clicked() ), SLOT( setModified() ) ); + // The modified-state of the ShowOnly-lists is tracked in the access-functions below +} + +ActionProperty::~ActionProperty() { +} + +void ActionProperty::changedShortcut( const KShortcut& shortcut ) { + KeyButtonShortcut->setShortcut( shortcut, false ); +} + + +void ActionProperty::clear() { + _action = 0; + + // This prevents the changed-signal from being emited during the GUI-update + _modified = true; // The real state is set at the end of this function. + + leDistinctName->clear(); + cbCategory->clearEdit(); + leTitle->clear(); + leTooltip->clear(); + textDescription->clear(); + leCommandline->clear(); + leStartpath->clear(); + KeyButtonShortcut->setShortcut( KShortcut(), false ); + + lbShowonlyProtocol->clear(); + lbShowonlyPath->clear(); + lbShowonlyMime->clear(); + lbShowonlyFile->clear(); + + chkSeparateStdError->setChecked( false ); + radioNormal->setChecked( true ); + + radioLocal->setChecked( true ); + + chkConfirmExecution->setChecked( false ); + + ButtonIcon->resetIcon(); + + leDifferentUser->clear(); + chkDifferentUser->setChecked( false ); + + setModified( false ); +} + +void ActionProperty::updateGUI( KrAction *action ) { + if ( action ) + _action = action; + if ( ! _action ) + return; + + // This prevents the changed-signal from being emited during the GUI-update. + _modified = true; // The real state is set at the end of this function. + + leDistinctName->setText( _action->name() ); + cbCategory->setCurrentText( _action->category() ); + leTitle->setText( _action->text() ); + leTooltip->setText( _action->toolTip() ); + textDescription->setText( _action->whatsThis() ); + leCommandline->setText( _action->command() ); + leCommandline->home(false); + leStartpath->setText( _action->startpath() ); + KeyButtonShortcut->setShortcut( _action->shortcut(), false ); + + lbShowonlyProtocol->clear(); + lbShowonlyProtocol->insertStringList( _action->showonlyProtocol() ); + lbShowonlyPath->clear(); + lbShowonlyPath->insertStringList( _action->showonlyPath() ); + lbShowonlyMime->clear(); + lbShowonlyMime->insertStringList( _action->showonlyMime() ); + lbShowonlyFile->clear(); + lbShowonlyFile->insertStringList( _action->showonlyFile() ); + + chkSeparateStdError->setChecked( false ); + switch ( _action->execType() ) { + case KrAction::CollectOutputSeparateStderr: + chkSeparateStdError->setChecked( true ); + radioCollectOutput->setChecked( true ); + break; + case KrAction::CollectOutput: + radioCollectOutput->setChecked( true ); + break; + case KrAction::Terminal: + radioTerminal->setChecked( true ); + break; + default: // case KrAction::Normal: + radioNormal->setChecked( true ); + break; + } + + if ( _action->acceptURLs() ) + radioUrl->setChecked( true ); + else + radioLocal->setChecked( true ); + + chkConfirmExecution->setChecked( _action->confirmExecution() ); + + if ( ! _action->icon().isEmpty() ) + ButtonIcon->setIcon( _action->icon() ); + else + ButtonIcon->resetIcon(); + + leDifferentUser->setText( _action->user() ); + if ( _action->user().isEmpty() ) + chkDifferentUser->setChecked( false ); + else + chkDifferentUser->setChecked( true ); + + setModified( false ); +} + +void ActionProperty::updateAction( KrAction *action ) { + if ( action ) + _action = action; + if ( ! _action ) + return; + + if ( _action->category() != cbCategory->currentText() ) { + _action->setCategory( cbCategory->currentText() ); + // Update the category-list + cbCategory->clear(); + cbCategory->insertStringList( krUserAction->allCategories() ); + cbCategory->setCurrentText( _action->category() ); + } + + _action->setName( leDistinctName->text().latin1() ); + _action->setText( leTitle->text() ); + _action->setToolTip( leTooltip->text() ); + _action->setWhatsThis( textDescription->text() ); + _action->setCommand( leCommandline->text() ); + _action->setStartpath( leStartpath->text() ); + _action->setShortcut( KeyButtonShortcut->shortcut() ); + + QListBoxItem* lbi = lbShowonlyProtocol->firstItem(); + QStringList list; + while ( lbi ) { + list << lbi->text(); + lbi = lbi->next(); + } + _action->setShowonlyProtocol( list ); + + lbi = lbShowonlyPath->firstItem(); + list = QStringList(); + while ( lbi ) { + list << lbi->text(); + lbi = lbi->next(); + } + _action->setShowonlyPath( list ); + + lbi = lbShowonlyMime->firstItem(); + list = QStringList(); + while ( lbi ) { + list << lbi->text(); + lbi = lbi->next(); + } + _action->setShowonlyMime( list ); + + lbi = lbShowonlyFile->firstItem(); + list = QStringList(); + while ( lbi ) { + list << lbi->text(); + lbi = lbi->next(); + } + _action->setShowonlyFile( list ); + + if ( radioCollectOutput->isChecked() && chkSeparateStdError->isChecked() ) + _action->setExecType( KrAction::CollectOutputSeparateStderr ); + else if ( radioCollectOutput->isChecked() && ! chkSeparateStdError->isChecked() ) + _action->setExecType( KrAction::CollectOutput ); + else if ( radioTerminal->isChecked() ) + _action->setExecType( KrAction::Terminal ); + else + _action->setExecType( KrAction::Normal ); + + if ( radioUrl->isChecked() ) + _action->setAcceptURLs( true ); + else + _action->setAcceptURLs( false ); + + _action->setConfirmExecution( chkConfirmExecution->isChecked() ); + + _action->setIcon( ButtonIcon->icon() ); + + _action->setUser( leDifferentUser->text() ); + + setModified( false ); +} + +void ActionProperty::addPlaceholder() { + AddPlaceholderPopup popup( this ); + QString exp = popup.getPlaceholder( mapToGlobal( + QPoint( + ButtonAddPlaceholder->pos().x() + ButtonAddPlaceholder->width()+6, // 6 is the default margin + ButtonAddPlaceholder->pos().y() + ) + ) ); + leCommandline->insert( exp ); +} + + +void ActionProperty::addStartpath() { + QString folder = KFileDialog::getExistingDirectory(QString::null, this); + if (folder != QString::null) { + leStartpath->setText( folder ); + } +} + + +void ActionProperty::newProtocol() { + bool ok; + QString text = KInputDialog::getText( + i18n( "New protocol" ), + i18n( "Set a protocol:" ), + lbShowonlyProtocol->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyProtocol->insertStringList( QStringList::split( ";", text ) ); + setModified(); + } +} + +void ActionProperty::editProtocol() { + if (lbShowonlyProtocol->currentItem() == -1) + return; + + bool ok; + QString text = KInputDialog::getText( + i18n( "Edit protocol" ), + i18n( "Set another protocol:" ), + lbShowonlyProtocol->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyProtocol->changeItem( text, lbShowonlyProtocol->currentItem() ); + setModified(); + } +} + +void ActionProperty::removeProtocol() { + if (lbShowonlyProtocol->currentItem() != -1) { + lbShowonlyProtocol->removeItem( lbShowonlyProtocol->currentItem() ); + setModified(); + } +} + +void ActionProperty::addPath() { + QString folder = KFileDialog::getExistingDirectory(QString::null, this); + if (folder != QString::null) { + lbShowonlyPath->insertItem( folder ); + setModified(); + } +} + +void ActionProperty::editPath() { + if (lbShowonlyPath->currentItem() == -1) + return; + + bool ok; + QString text = KInputDialog::getText( + i18n( "Edit path" ), + i18n( "Set another path:" ), + lbShowonlyPath->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyPath->changeItem( text, lbShowonlyPath->currentItem() ); + setModified(); + } +} + +void ActionProperty::removePath() { + if (lbShowonlyPath->currentItem() != -1) { + lbShowonlyPath->removeItem( lbShowonlyPath->currentItem() ); + setModified(); + } +} + +void ActionProperty::addMime() { + bool ok; + QString text = KInputDialog::getText( + i18n( "New mime-type" ), + i18n( "Set a mime-type:" ), + lbShowonlyMime->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyMime->insertStringList( QStringList::split( ";", text ) ); + setModified(); + } +} + +void ActionProperty::editMime() { + if (lbShowonlyMime->currentItem() == -1) + return; + + bool ok; + QString text = KInputDialog::getText( + i18n( "Edit mime-type" ), + i18n( "Set another mime-type:" ), + lbShowonlyMime->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyMime->changeItem( text, lbShowonlyMime->currentItem() ); + setModified(); + } +} + +void ActionProperty::removeMime() { + if (lbShowonlyMime->currentItem() != -1) { + lbShowonlyMime->removeItem( lbShowonlyMime->currentItem() ); + setModified(); + } +} + +void ActionProperty::newFile() { + bool ok; + QString text = KInputDialog::getText( + i18n( "New filename" ), + i18n( "Set a filename:" ), + lbShowonlyFile->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyFile->insertStringList( QStringList::split( ";", text ) ); + setModified(); + } +} + +void ActionProperty::editFile() { + if (lbShowonlyFile->currentItem() == -1) + return; + + bool ok; + QString text = KInputDialog::getText( + i18n( "Edit filename" ), + i18n( "Set another filename:" ), + lbShowonlyFile->currentText(), + &ok, this ); + if ( ok && !text.isEmpty() ) { + lbShowonlyFile->changeItem( text, lbShowonlyFile->currentItem() ); + setModified(); + } +} + +void ActionProperty::removeFile() { + if (lbShowonlyFile->currentItem() != -1) { + lbShowonlyFile->removeItem( lbShowonlyFile->currentItem() ); + setModified(); + } +} + + +bool ActionProperty::validProperties() { + if ( leDistinctName->text().simplifyWhiteSpace().isEmpty() ) { + KMessageBox::error( this, i18n("Please set a unique name for the useraction") ); + leDistinctName->setFocus(); + return false; + } + if ( leTitle->text().simplifyWhiteSpace().isEmpty() ) { + KMessageBox::error( this, i18n("Please set a title for the menu entry") ); + leTitle->setFocus(); + return false; + } + if ( leCommandline->text().simplifyWhiteSpace().isEmpty() ) { + KMessageBox::error( this, i18n("Command line is empty") ); + leCommandline->setFocus(); + return false; + } + if ( leDistinctName->isEnabled() ) + if ( krApp->actionCollection()->action( leDistinctName->text().latin1() ) ) { + KMessageBox::error( this, + i18n("There already is an action with this name\n" + "If you don't have such an useraction the name is used by Krusader for an internal action") + ); + leDistinctName->setFocus(); + return false; + } + + return true; +} + +void ActionProperty::setModified( bool m ) +{ + if ( m && !_modified ) { // emit only when the state _changes_to_true_, + emit changed(); + } + _modified = m; +} + + +#include "actionproperty.moc" diff --git a/krusader/ActionMan/actionproperty.h b/krusader/ActionMan/actionproperty.h new file mode 100644 index 0000000..41cc564 --- /dev/null +++ b/krusader/ActionMan/actionproperty.h @@ -0,0 +1,146 @@ +// +// C++ Interface: actionproperty +// +// Description: +// +// +// Author: Jonas Bähr (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef ACTIONPROPERTY_H +#define ACTIONPROPERTY_H + +#include "actionpropertybase.h" + +class KrAction; +class KShortcut; + +/** + * Use this widget where ever you need to manipulate a UserAction + * @author Jonas Bähr (http://www.jonas-baehr.de) + */ +class ActionProperty : public ActionPropertyBase { + Q_OBJECT +public: + ActionProperty( QWidget *parent=0, const char *name=0, KrAction *action=0 ); + ~ActionProperty(); + + /** + * @return the currently displayed action + */ + KrAction* action() { return _action; }; + + /** + * This inits the widget with the actions properties. + * If no action is provided, the last used will be taken! + * It also resets the changed() state. + * @param action the action which should be displayd + */ + void updateGUI( KrAction *action = 0 ); + + /** + * This writes the displayed properties back into the action. + * If no action is provided, the last used will be taken! + * It also resets the changed() state. + * @param action the action which should be manipulated + */ + void updateAction( KrAction *action = 0 ); + + /** + * clears everything + */ + void clear(); + + /** + * @return true if all properties got valid values + */ + bool validProperties(); + + /** + * @return true if any property got changed + */ + bool isModified() { return _modified; }; + +signals: + /** + * emited when any actionproperty changed. This signal is only emited when + * the _modified attribute changes to true. If there are changes made and + * _modified is already true, no signal is emited! + */ + void changed(); + +protected slots: + void setModified( bool m = true ); + /** + * executes the AddPlaceholderPopup + */ + void addPlaceholder(); + /** + * asks for an existing path + */ + void addStartpath(); + /** + * (availability) asks for a new protocol + */ + void newProtocol(); + /** + * (availability) changes a protocol of the list + */ + void editProtocol(); + /** + * (availability) removes a protocol from the list + */ + void removeProtocol(); + /** + * (availability) asks for a new path + */ + void addPath(); + /** + * (availability) edits a path of the list + */ + void editPath(); + /** + * (availability) removes a path from the list + */ + void removePath(); + /** + * (availability) asks for a new mime-type + */ + void addMime(); + /** + * (availability) changes a mime-type of the list + */ + void editMime(); + /** + * (availability) removes a mime-type from the list + */ + void removeMime(); + /** + * (availability) asks for a new file-filter + */ + void newFile(); + /** + * (availability) edits a file-filter of the list + */ + void editFile(); + /** + * (availability) removes a file-filter from the lsit + */ + void removeFile(); + +private: + KrAction *_action; + bool _modified; + +private slots: + /** + * This updates the ShortcutButton + * @internal + */ + void changedShortcut(const KShortcut& shortcut); +}; + +#endif diff --git a/krusader/ActionMan/actionpropertybase.cpp b/krusader/ActionMan/actionpropertybase.cpp new file mode 100644 index 0000000..639f6fd --- /dev/null +++ b/krusader/ActionMan/actionpropertybase.cpp @@ -0,0 +1,463 @@ +#include +#include +/**************************************************************************** +** Form implementation generated from reading ui file './actionpropertybase.ui' +** +** Created: Sat Mar 15 11:41:43 2008 +** by: The User Interface Compiler ($Id: qt/main.cpp 3.3.8 edited Jan 11 14:47 $) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "actionpropertybase.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "klineedit.h" +#include "kcombobox.h" +#include "kicondialog.h" +#include "ktextedit.h" +#include "kkeybutton.h" +#include "klistbox.h" + +/* + * Constructs a ActionPropertyBase as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + */ +ActionPropertyBase::ActionPropertyBase( QWidget* parent, const char* name, WFlags fl ) + : QWidget( parent, name, fl ) +{ + if ( !name ) + setName( "ActionPropertyBase" ); + ActionPropertyBaseLayout = new QGridLayout( this, 1, 1, 0, 0, "ActionPropertyBaseLayout"); + + tabWidget3 = new QTabWidget( this, "tabWidget3" ); + + tab = new QWidget( tabWidget3, "tab" ); + tabLayout = new QGridLayout( tab, 1, 1, 11, 6, "tabLayout"); + + ButtonAddStartpath = new QToolButton( tab, "ButtonAddStartpath" ); + + tabLayout->addWidget( ButtonAddStartpath, 8, 3 ); + + LabelDescription = new QLabel( tab, "LabelDescription" ); + LabelDescription->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, LabelDescription->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelDescription, 4, 0 ); + + bgAccept = new QButtonGroup( tab, "bgAccept" ); + bgAccept->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)1, 0, 0, bgAccept->sizePolicy().hasHeightForWidth() ) ); + bgAccept->setColumnLayout(0, Qt::Vertical ); + bgAccept->layout()->setSpacing( 6 ); + bgAccept->layout()->setMargin( 11 ); + bgAcceptLayout = new QGridLayout( bgAccept->layout() ); + bgAcceptLayout->setAlignment( Qt::AlignTop ); + + radioLocal = new QRadioButton( bgAccept, "radioLocal" ); + radioLocal->setChecked( TRUE ); + + bgAcceptLayout->addWidget( radioLocal, 0, 0 ); + + radioUrl = new QRadioButton( bgAccept, "radioUrl" ); + + bgAcceptLayout->addWidget( radioUrl, 1, 0 ); + + tabLayout->addMultiCellWidget( bgAccept, 9, 9, 2, 3 ); + + leTitle = new KLineEdit( tab, "leTitle" ); + + tabLayout->addMultiCellWidget( leTitle, 2, 2, 1, 3 ); + + LabelTitle = new QLabel( tab, "LabelTitle" ); + LabelTitle->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, LabelTitle->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelTitle, 2, 0 ); + + layout3 = new QHBoxLayout( 0, 0, 6, "layout3"); + + layout2 = new QVBoxLayout( 0, 0, 6, "layout2"); + + leDistinctName = new KLineEdit( tab, "leDistinctName" ); + layout2->addWidget( leDistinctName ); + + cbCategory = new KComboBox( FALSE, tab, "cbCategory" ); + cbCategory->setEditable( TRUE ); + layout2->addWidget( cbCategory ); + layout3->addLayout( layout2 ); + + ButtonIcon = new KIconButton( tab, "ButtonIcon" ); + ButtonIcon->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, ButtonIcon->sizePolicy().hasHeightForWidth() ) ); + ButtonIcon->setMinimumSize( QSize( 50, 50 ) ); + ButtonIcon->setMaximumSize( QSize( 50, 50 ) ); + layout3->addWidget( ButtonIcon ); + + tabLayout->addMultiCellLayout( layout3, 0, 1, 1, 3 ); + + LabelDistinctName = new QLabel( tab, "LabelDistinctName" ); + LabelDistinctName->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, LabelDistinctName->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelDistinctName, 0, 0 ); + + LabelCommandline = new QLabel( tab, "LabelCommandline" ); + LabelCommandline->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, LabelCommandline->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelCommandline, 7, 0 ); + + leTooltip = new KLineEdit( tab, "leTooltip" ); + + tabLayout->addMultiCellWidget( leTooltip, 3, 3, 1, 3 ); + + leStartpath = new KLineEdit( tab, "leStartpath" ); + + tabLayout->addMultiCellWidget( leStartpath, 8, 8, 1, 2 ); + + LabelTooltip = new QLabel( tab, "LabelTooltip" ); + LabelTooltip->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, LabelTooltip->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelTooltip, 3, 0 ); + + leCommandline = new KLineEdit( tab, "leCommandline" ); + + tabLayout->addMultiCellWidget( leCommandline, 7, 7, 1, 2 ); + + LabelCategory = new QLabel( tab, "LabelCategory" ); + LabelCategory->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, LabelCategory->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelCategory, 1, 0 ); + + ButtonAddPlaceholder = new QToolButton( tab, "ButtonAddPlaceholder" ); + ButtonAddPlaceholder->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, ButtonAddPlaceholder->sizePolicy().hasHeightForWidth() ) ); + ButtonAddPlaceholder->setMinimumSize( QSize( 0, 0 ) ); + + tabLayout->addWidget( ButtonAddPlaceholder, 7, 3 ); + + textDescription = new KTextEdit( tab, "textDescription" ); + textDescription->setWordWrap( KTextEdit::WidgetWidth ); + + tabLayout->addMultiCellWidget( textDescription, 4, 6, 1, 3 ); + + LabelStartpath = new QLabel( tab, "LabelStartpath" ); + LabelStartpath->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, LabelStartpath->sizePolicy().hasHeightForWidth() ) ); + + tabLayout->addWidget( LabelStartpath, 8, 0 ); + spacer = new QSpacerItem( 80, 19, QSizePolicy::Minimum, QSizePolicy::Expanding ); + tabLayout->addItem( spacer, 6, 0 ); + + layout4 = new QHBoxLayout( 0, 0, 6, "layout4"); + + LabelShortcut = new QLabel( tab, "LabelShortcut" ); + layout4->addWidget( LabelShortcut ); + spacer6_2 = new QSpacerItem( 161, 21, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout4->addItem( spacer6_2 ); + + KeyButtonShortcut = new KKeyButton( tab, "KeyButtonShortcut" ); + layout4->addWidget( KeyButtonShortcut ); + + tabLayout->addMultiCellLayout( layout4, 10, 10, 2, 3 ); + + bgExecType = new QButtonGroup( tab, "bgExecType" ); + bgExecType->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)1, 0, 0, bgExecType->sizePolicy().hasHeightForWidth() ) ); + bgExecType->setColumnLayout(0, Qt::Vertical ); + bgExecType->layout()->setSpacing( 6 ); + bgExecType->layout()->setMargin( 11 ); + bgExecTypeLayout = new QGridLayout( bgExecType->layout() ); + bgExecTypeLayout->setAlignment( Qt::AlignTop ); + + radioCollectOutput = new QRadioButton( bgExecType, "radioCollectOutput" ); + + bgExecTypeLayout->addWidget( radioCollectOutput, 2, 0 ); + + chkSeparateStdError = new QCheckBox( bgExecType, "chkSeparateStdError" ); + chkSeparateStdError->setEnabled( FALSE ); + + bgExecTypeLayout->addWidget( chkSeparateStdError, 3, 0 ); + + radioNormal = new QRadioButton( bgExecType, "radioNormal" ); + radioNormal->setChecked( TRUE ); + + bgExecTypeLayout->addWidget( radioNormal, 0, 0 ); + + radioTerminal = new QRadioButton( bgExecType, "radioTerminal" ); + + bgExecTypeLayout->addWidget( radioTerminal, 1, 0 ); + + tabLayout->addMultiCellWidget( bgExecType, 9, 10, 0, 1 ); + tabWidget3->insertTab( tab, QString::fromLatin1("") ); + + tab_2 = new QWidget( tabWidget3, "tab_2" ); + tabLayout_2 = new QGridLayout( tab_2, 1, 1, 11, 6, "tabLayout_2"); + + gbShowonly = new QGroupBox( tab_2, "gbShowonly" ); + gbShowonly->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, 0, 0, gbShowonly->sizePolicy().hasHeightForWidth() ) ); + gbShowonly->setColumnLayout(0, Qt::Vertical ); + gbShowonly->layout()->setSpacing( 6 ); + gbShowonly->layout()->setMargin( 11 ); + gbShowonlyLayout = new QGridLayout( gbShowonly->layout() ); + gbShowonlyLayout->setAlignment( Qt::AlignTop ); + + tabShowonly = new QTabWidget( gbShowonly, "tabShowonly" ); + tabShowonly->setTabPosition( QTabWidget::Top ); + tabShowonly->setTabShape( QTabWidget::Triangular ); + + TabPage = new QWidget( tabShowonly, "TabPage" ); + TabPageLayout = new QGridLayout( TabPage, 1, 1, 11, 6, "TabPageLayout"); + + ButtonNewProtocol = new QToolButton( TabPage, "ButtonNewProtocol" ); + ButtonNewProtocol->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonNewProtocol->sizePolicy().hasHeightForWidth() ) ); + ButtonNewProtocol->setMinimumSize( QSize( 0, 0 ) ); + ButtonNewProtocol->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout->addWidget( ButtonNewProtocol, 0, 1 ); + + ButtonEditProtocol = new QToolButton( TabPage, "ButtonEditProtocol" ); + ButtonEditProtocol->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonEditProtocol->sizePolicy().hasHeightForWidth() ) ); + ButtonEditProtocol->setMinimumSize( QSize( 0, 0 ) ); + ButtonEditProtocol->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout->addWidget( ButtonEditProtocol, 1, 1 ); + spacer6_3 = new QSpacerItem( 21, 58, QSizePolicy::Minimum, QSizePolicy::Expanding ); + TabPageLayout->addItem( spacer6_3, 3, 1 ); + + ButtonRemoveProtocol = new QToolButton( TabPage, "ButtonRemoveProtocol" ); + ButtonRemoveProtocol->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonRemoveProtocol->sizePolicy().hasHeightForWidth() ) ); + ButtonRemoveProtocol->setMinimumSize( QSize( 0, 0 ) ); + ButtonRemoveProtocol->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout->addWidget( ButtonRemoveProtocol, 2, 1 ); + + lbShowonlyProtocol = new KListBox( TabPage, "lbShowonlyProtocol" ); + + TabPageLayout->addMultiCellWidget( lbShowonlyProtocol, 0, 3, 0, 0 ); + tabShowonly->insertTab( TabPage, QString::fromLatin1("") ); + + tab_3 = new QWidget( tabShowonly, "tab_3" ); + tabLayout_3 = new QGridLayout( tab_3, 1, 1, 11, 6, "tabLayout_3"); + + lbShowonlyPath = new KListBox( tab_3, "lbShowonlyPath" ); + + tabLayout_3->addMultiCellWidget( lbShowonlyPath, 0, 3, 0, 0 ); + + ButtonAddPath = new QToolButton( tab_3, "ButtonAddPath" ); + ButtonAddPath->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonAddPath->sizePolicy().hasHeightForWidth() ) ); + ButtonAddPath->setMinimumSize( QSize( 0, 0 ) ); + ButtonAddPath->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_3->addWidget( ButtonAddPath, 0, 1 ); + + ButtonEditPath = new QToolButton( tab_3, "ButtonEditPath" ); + ButtonEditPath->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonEditPath->sizePolicy().hasHeightForWidth() ) ); + ButtonEditPath->setMinimumSize( QSize( 0, 0 ) ); + ButtonEditPath->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_3->addWidget( ButtonEditPath, 1, 1 ); + + ButtonRemovePath = new QToolButton( tab_3, "ButtonRemovePath" ); + ButtonRemovePath->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonRemovePath->sizePolicy().hasHeightForWidth() ) ); + ButtonRemovePath->setMinimumSize( QSize( 0, 0 ) ); + ButtonRemovePath->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_3->addWidget( ButtonRemovePath, 2, 1 ); + spacer4 = new QSpacerItem( 21, 61, QSizePolicy::Minimum, QSizePolicy::Expanding ); + tabLayout_3->addItem( spacer4, 3, 1 ); + tabShowonly->insertTab( tab_3, QString::fromLatin1("") ); + + tab_4 = new QWidget( tabShowonly, "tab_4" ); + tabLayout_4 = new QGridLayout( tab_4, 1, 1, 11, 6, "tabLayout_4"); + + lbShowonlyMime = new KListBox( tab_4, "lbShowonlyMime" ); + + tabLayout_4->addMultiCellWidget( lbShowonlyMime, 0, 3, 0, 0 ); + + ButtonAddMime = new QToolButton( tab_4, "ButtonAddMime" ); + ButtonAddMime->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonAddMime->sizePolicy().hasHeightForWidth() ) ); + ButtonAddMime->setMinimumSize( QSize( 0, 0 ) ); + ButtonAddMime->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_4->addWidget( ButtonAddMime, 0, 1 ); + + ButtonEditMime = new QToolButton( tab_4, "ButtonEditMime" ); + ButtonEditMime->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonEditMime->sizePolicy().hasHeightForWidth() ) ); + ButtonEditMime->setMinimumSize( QSize( 0, 0 ) ); + ButtonEditMime->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_4->addWidget( ButtonEditMime, 1, 1 ); + + ButtonRemoveMime = new QToolButton( tab_4, "ButtonRemoveMime" ); + ButtonRemoveMime->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonRemoveMime->sizePolicy().hasHeightForWidth() ) ); + ButtonRemoveMime->setMinimumSize( QSize( 0, 0 ) ); + ButtonRemoveMime->setMaximumSize( QSize( 32767, 32767 ) ); + + tabLayout_4->addWidget( ButtonRemoveMime, 2, 1 ); + spacer5 = new QSpacerItem( 21, 41, QSizePolicy::Minimum, QSizePolicy::Expanding ); + tabLayout_4->addItem( spacer5, 3, 1 ); + tabShowonly->insertTab( tab_4, QString::fromLatin1("") ); + + TabPage_2 = new QWidget( tabShowonly, "TabPage_2" ); + TabPageLayout_2 = new QGridLayout( TabPage_2, 1, 1, 11, 6, "TabPageLayout_2"); + + lbShowonlyFile = new KListBox( TabPage_2, "lbShowonlyFile" ); + + TabPageLayout_2->addMultiCellWidget( lbShowonlyFile, 0, 3, 0, 0 ); + + ButtonNewFile = new QToolButton( TabPage_2, "ButtonNewFile" ); + ButtonNewFile->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonNewFile->sizePolicy().hasHeightForWidth() ) ); + ButtonNewFile->setMinimumSize( QSize( 0, 0 ) ); + ButtonNewFile->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout_2->addWidget( ButtonNewFile, 0, 1 ); + + ButtonEditFile = new QToolButton( TabPage_2, "ButtonEditFile" ); + ButtonEditFile->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonEditFile->sizePolicy().hasHeightForWidth() ) ); + ButtonEditFile->setMinimumSize( QSize( 0, 0 ) ); + ButtonEditFile->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout_2->addWidget( ButtonEditFile, 1, 1 ); + + ButtonRemoveFile = new QToolButton( TabPage_2, "ButtonRemoveFile" ); + ButtonRemoveFile->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, ButtonRemoveFile->sizePolicy().hasHeightForWidth() ) ); + ButtonRemoveFile->setMinimumSize( QSize( 0, 0 ) ); + ButtonRemoveFile->setMaximumSize( QSize( 32767, 32767 ) ); + + TabPageLayout_2->addWidget( ButtonRemoveFile, 2, 1 ); + spacer6 = new QSpacerItem( 21, 41, QSizePolicy::Minimum, QSizePolicy::Expanding ); + TabPageLayout_2->addItem( spacer6, 3, 1 ); + tabShowonly->insertTab( TabPage_2, QString::fromLatin1("") ); + + gbShowonlyLayout->addWidget( tabShowonly, 0, 0 ); + + tabLayout_2->addMultiCellWidget( gbShowonly, 0, 0, 0, 1 ); + + chkConfirmExecution = new QCheckBox( tab_2, "chkConfirmExecution" ); + + tabLayout_2->addMultiCellWidget( chkConfirmExecution, 1, 1, 0, 1 ); + + chkDifferentUser = new QCheckBox( tab_2, "chkDifferentUser" ); + + tabLayout_2->addWidget( chkDifferentUser, 2, 0 ); + + leDifferentUser = new KLineEdit( tab_2, "leDifferentUser" ); + leDifferentUser->setEnabled( FALSE ); + + tabLayout_2->addWidget( leDifferentUser, 2, 1 ); + spacer3 = new QSpacerItem( 161, 102, QSizePolicy::Minimum, QSizePolicy::Expanding ); + tabLayout_2->addMultiCell( spacer3, 3, 3, 0, 1 ); + tabWidget3->insertTab( tab_2, QString::fromLatin1("") ); + + ActionPropertyBaseLayout->addWidget( tabWidget3, 0, 0 ); + languageChange(); + resize( QSize(485, 470).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( radioCollectOutput, SIGNAL( toggled(bool) ), chkSeparateStdError, SLOT( setEnabled(bool) ) ); + connect( chkDifferentUser, SIGNAL( toggled(bool) ), leDifferentUser, SLOT( setEnabled(bool) ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +ActionPropertyBase::~ActionPropertyBase() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void ActionPropertyBase::languageChange() +{ + setCaption( tr2i18n( "Action Property" ) ); + ButtonAddStartpath->setText( tr2i18n( "..." ) ); + LabelDescription->setText( tr2i18n( "Description:" ) ); + QWhatsThis::add( LabelDescription, tr2i18n( "A detailed description of the Useraction. It is only displayed in the Konfigurator and via Shift-F1." ) ); + bgAccept->setTitle( tr2i18n( "Command accepts" ) ); + radioLocal->setText( tr2i18n( "Local files only (no URL's)" ) ); + QWhatsThis::add( radioLocal, tr2i18n( "Substitute the Placeholders with local filenames." ) ); + radioUrl->setText( tr2i18n( "URL's (remote and local)" ) ); + QWhatsThis::add( radioUrl, tr2i18n( "Substitute the Placeholders with valid URL's." ) ); + QWhatsThis::add( leTitle, tr2i18n( "The title displayed in the Usermenu." ) ); + LabelTitle->setText( tr2i18n( "Title:" ) ); + QWhatsThis::add( LabelTitle, tr2i18n( "The title displayed in the Usermenu." ) ); + QWhatsThis::add( leDistinctName, tr2i18n( "Unique name of the Useraction. It is only used in the Konfigurator and doesn't appear in any other menu.

Note: The Title shown in the Usermenu can be set below." ) ); + QWhatsThis::add( cbCategory, tr2i18n( "Useractions can be grouped in categories for better distinction. Choose a existing Category or create a new one by entering a name." ) ); + ButtonIcon->setText( tr2i18n( "Icon" ) ); + QWhatsThis::add( ButtonIcon, tr2i18n( "Each Useraction can have its own icon. It will appear in front of the title in the Usermenu." ) ); + LabelDistinctName->setText( tr2i18n( "Identifier:" ) ); + QWhatsThis::add( LabelDistinctName, tr2i18n( "

Unique name of the Useraction. It is only used in the Konfigurator and doesn't appear in any other menu.

Note: The Title shown in the Usermenu can be set below.

" ) ); + LabelCommandline->setText( tr2i18n( "Command:" ) ); + QWhatsThis::add( LabelCommandline, tr2i18n( "

The Command defines the command that will be executed when the Useraction is used. It can be a simple shell command or a complex sequence of multiple commands with Placeholders.

Examples:

  • eject /mnt/cdrom
  • amarok --append %aList(\"Selected\")%
\n" +"Please consult the handbook to learn more about the syntax.

" ) ); + QWhatsThis::add( leTooltip, tr2i18n( "The Tooltip is shown when the mouse cursor is hold over an entry of the Useraction Toolbar." ) ); + QWhatsThis::add( leStartpath, tr2i18n( "The Workdir defines in which directory the Command will be executed." ) ); + LabelTooltip->setText( tr2i18n( "Tooltip:" ) ); + QWhatsThis::add( LabelTooltip, tr2i18n( "The Tooltip is shown when the mouse cursor is hold over an entry of the Useraction Toolbar." ) ); + leCommandline->setText( QString::null ); + QWhatsThis::add( leCommandline, tr2i18n( "The Command defines the command that will be executed when the Useraction is used. It can be a simple shell command or a complex sequence of multiple commands with Placeholders.

\n" +"Examples:

  • eject /mnt/cdrom
  • amarok --append %aList(\"Selected\")%
\n" +"Please consult the handbook to learn more about the syntax." ) ); + LabelCategory->setText( tr2i18n( "Category:" ) ); + QWhatsThis::add( LabelCategory, tr2i18n( "Useractions can be grouped in categories for better distinction. Choose a existing Category or create a new one by entering a name." ) ); + ButtonAddPlaceholder->setText( tr2i18n( "&Add" ) ); + QWhatsThis::add( ButtonAddPlaceholder, tr2i18n( "Add Placeholders for the selected files in the panel." ) ); + QWhatsThis::add( textDescription, tr2i18n( "A detailed description of the Useraction. It is only displayed in the Konfigurator and via Shift-F1." ) ); + LabelStartpath->setText( tr2i18n( "Workdir:" ) ); + QWhatsThis::add( LabelStartpath, tr2i18n( "The Workdir defines in which directory the Command will be executed." ) ); + LabelShortcut->setText( tr2i18n( "Default shortcut:" ) ); + KeyButtonShortcut->setText( tr2i18n( "None" ) ); + QWhatsThis::add( KeyButtonShortcut, tr2i18n( "Set a default keyboard shortcut." ) ); + bgExecType->setTitle( tr2i18n( "Execution mode" ) ); + radioCollectOutput->setText( tr2i18n( "Collect output" ) ); + QWhatsThis::add( radioCollectOutput, tr2i18n( "Collect the output of the executed program." ) ); + chkSeparateStdError->setText( tr2i18n( "Separate standard error" ) ); + QWhatsThis::add( chkSeparateStdError, tr2i18n( "Separate standard out and standard error in the output collection." ) ); + radioNormal->setText( tr2i18n( "Normal" ) ); + radioTerminal->setText( tr2i18n( "Run in terminal" ) ); + QWhatsThis::add( radioTerminal, tr2i18n( "Run the command in a terminal." ) ); + tabWidget3->changeTab( tab, tr2i18n( "Basic Properties" ) ); + gbShowonly->setTitle( tr2i18n( "The Useraction is only available for" ) ); + ButtonNewProtocol->setText( tr2i18n( "&New..." ) ); + ButtonEditProtocol->setText( tr2i18n( "Chan&ge..." ) ); + ButtonRemoveProtocol->setText( tr2i18n( "De&lete" ) ); + QWhatsThis::add( lbShowonlyProtocol, tr2i18n( "Show the Useraction only for the values defined here." ) ); + tabShowonly->changeTab( TabPage, tr2i18n( "Protocol" ) ); + QWhatsThis::add( lbShowonlyPath, tr2i18n( "Show the Useraction only for the values defined here." ) ); + ButtonAddPath->setText( tr2i18n( "&New..." ) ); + ButtonEditPath->setText( tr2i18n( "Chan&ge..." ) ); + ButtonRemovePath->setText( tr2i18n( "De&lete" ) ); + tabShowonly->changeTab( tab_3, tr2i18n( "Path" ) ); + QWhatsThis::add( lbShowonlyMime, tr2i18n( "Show the Useraction only for the values defined here." ) ); + ButtonAddMime->setText( tr2i18n( "&New..." ) ); + ButtonEditMime->setText( tr2i18n( "Chan&ge..." ) ); + ButtonRemoveMime->setText( tr2i18n( "De&lete" ) ); + tabShowonly->changeTab( tab_4, tr2i18n( "Mime-type" ) ); + QWhatsThis::add( lbShowonlyFile, tr2i18n( "Show the Useraction only for the filenames defined here. The wildcards '?' and '*' can be used." ) ); + ButtonNewFile->setText( tr2i18n( "&New..." ) ); + ButtonEditFile->setText( tr2i18n( "Chan&ge..." ) ); + ButtonRemoveFile->setText( tr2i18n( "De&lete" ) ); + tabShowonly->changeTab( TabPage_2, tr2i18n( "Filename" ) ); + chkConfirmExecution->setText( tr2i18n( "Confirm each program call separately" ) ); + QWhatsThis::add( chkConfirmExecution, tr2i18n( "Allows to tweak the Command before it is executed." ) ); + chkDifferentUser->setText( tr2i18n( "Run as different user:" ) ); + QWhatsThis::add( chkDifferentUser, tr2i18n( "Execute the Command under a different user-id." ) ); + QWhatsThis::add( leDifferentUser, tr2i18n( "Execute the Command under a different user-id." ) ); + tabWidget3->changeTab( tab_2, tr2i18n( "Advanced Properties" ) ); +} + +#include "actionpropertybase.moc" diff --git a/krusader/ActionMan/actionpropertybase.ui b/krusader/ActionMan/actionpropertybase.ui new file mode 100644 index 0000000..9079e85 --- /dev/null +++ b/krusader/ActionMan/actionpropertybase.ui @@ -0,0 +1,1125 @@ + +ActionPropertyBase + + + ActionPropertyBase + + + + 0 + 0 + 485 + 470 + + + + Action Property + + + + unnamed + + + 0 + + + 0 + + + + tabWidget3 + + + + tab + + + Basic Properties + + + + unnamed + + + + ButtonAddStartpath + + + ... + + + + + LabelDescription + + + + 1 + 1 + 0 + 0 + + + + Description: + + + A detailed description of the <b>Useraction</b>. It is only displayed in the <i>Konfigurator</i> and via <code>Shift-F1</code>. + + + + + bgAccept + + + + 5 + 1 + 0 + 0 + + + + Command accepts + + + + unnamed + + + + radioLocal + + + Local files only (no URL's) + + + true + + + Substitute the <b>Placeholders</b> with local filenames. + + + + + radioUrl + + + URL's (remote and local) + + + Substitute the <b>Placeholders</b> with valid URL's. + + + + + + + leTitle + + + The title displayed in the <b>Usermenu</b>. + + + + + LabelTitle + + + + 1 + 0 + 0 + 0 + + + + Title: + + + The title displayed in the <b>Usermenu</b>. + + + + + layout3 + + + + unnamed + + + + layout2 + + + + unnamed + + + + leDistinctName + + + Unique name of the <b>Useraction</b>. It is only used in the <i>Konfigurator</i> and doesn't appear in any other menu.<p><b>Note</b>: The <i>Title</i> shown in the <b>Usermenu</b> can be set below. + + + + + cbCategory + + + true + + + <b>Useractions</b> can be grouped in categories for better distinction. Choose a existing <i>Category</i> or create a new one by entering a name. + + + + + + + ButtonIcon + + + + 0 + 0 + 0 + 0 + + + + + 50 + 50 + + + + + 50 + 50 + + + + Icon + + + Each <b>Useraction</b> can have its own icon. It will appear in front of the title in the <b>Usermenu</b>. + + + + + + + LabelDistinctName + + + + 1 + 0 + 0 + 0 + + + + Identifier: + + + <p>Unique name of the <b>Useraction</b>. It is only used in the <i>Konfigurator</i> and doesn't appear in any other menu.</p><p><b>Note</b>: The <i>Title</i> shown in the <b>Usermenu</b> can be set below.</p> + + + + + LabelCommandline + + + + 0 + 0 + 0 + 0 + + + + Command: + + + <p>The <i>Command</i> defines the command that will be executed when the <b>Useraction</b> is used. It can be a simple shell command or a complex sequence of multiple commands with <b>Placeholders</b>.</p><p>Examples:<ul><code><li>eject /mnt/cdrom</li><li>amarok --append %aList("Selected")%</li></code></ul> +Please consult the handbook to learn more about the syntax.</p> + + + + + leTooltip + + + The <i>Tooltip</i> is shown when the mouse cursor is hold over an entry of the <b>Useraction Toolbar</b>. + + + + + leStartpath + + + The <i>Workdir</i> defines in which directory the <i>Command</i> will be executed. + + + + + LabelTooltip + + + + 1 + 0 + 0 + 0 + + + + Tooltip: + + + The <i>Tooltip</i> is shown when the mouse cursor is hold over an entry of the <b>Useraction Toolbar</b>. + + + + + leCommandline + + + + + + The <i>Command</i> defines the command that will be executed when the <b>Useraction</b> is used. It can be a simple shell command or a complex sequence of multiple commands with <b>Placeholders</b>.<p> +Examples:<ul><code><li>eject /mnt/cdrom</li><li>amarok --append %aList("Selected")%</li></code></ul> +Please consult the handbook to learn more about the syntax. + + + + + LabelCategory + + + + 1 + 0 + 0 + 0 + + + + Category: + + + <b>Useractions</b> can be grouped in categories for better distinction. Choose a existing <i>Category</i> or create a new one by entering a name. + + + + + ButtonAddPlaceholder + + + + 0 + 0 + 0 + 0 + + + + + 0 + 0 + + + + &Add + + + Add <b>Placeholders</b> for the selected files in the panel. + + + + + textDescription + + + WidgetWidth + + + A detailed description of the <b>Useraction</b>. It is only displayed in the <i>Konfigurator</i> and via <code>Shift-F1</code>. + + + + + LabelStartpath + + + + 0 + 0 + 0 + 0 + + + + Workdir: + + + The <i>Workdir</i> defines in which directory the <i>Command</i> will be executed. + + + + + spacer + + + Vertical + + + Expanding + + + + 80 + 19 + + + + + + layout4 + + + + unnamed + + + + LabelShortcut + + + Default shortcut: + + + + + spacer6_2 + + + Horizontal + + + Expanding + + + + 161 + 21 + + + + + + KeyButtonShortcut + + + None + + + Set a default keyboard shortcut. + + + + + + + bgExecType + + + + 5 + 1 + 0 + 0 + + + + Execution mode + + + + unnamed + + + + radioCollectOutput + + + Collect output + + + Collect the output of the executed program. + + + + + chkSeparateStdError + + + false + + + Separate standard error + + + Separate standard out and standard error in the output collection. + + + + + radioNormal + + + Normal + + + true + + + + + radioTerminal + + + Run in terminal + + + Run the command in a terminal. + + + + + + + + + tab + + + Advanced Properties + + + + unnamed + + + + gbShowonly + + + + 7 + 7 + 0 + 0 + + + + The Useraction is only available for + + + + unnamed + + + + tabShowonly + + + Top + + + Triangular + + + + TabPage + + + Protocol + + + + unnamed + + + + ButtonNewProtocol + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + &New... + + + + + ButtonEditProtocol + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + Chan&ge... + + + + + spacer6_3 + + + Vertical + + + Expanding + + + + 21 + 58 + + + + + + ButtonRemoveProtocol + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + De&lete + + + + + lbShowonlyProtocol + + + Show the <b>Useraction</b> only for the values defined here. + + + + + + + tab + + + Path + + + + unnamed + + + + lbShowonlyPath + + + Show the <b>Useraction</b> only for the values defined here. + + + + + ButtonAddPath + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + &New... + + + + + ButtonEditPath + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + Chan&ge... + + + + + ButtonRemovePath + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + De&lete + + + + + spacer4 + + + Vertical + + + Expanding + + + + 21 + 61 + + + + + + + + tab + + + Mime-type + + + + unnamed + + + + lbShowonlyMime + + + Show the <b>Useraction</b> only for the values defined here. + + + + + ButtonAddMime + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + &New... + + + + + ButtonEditMime + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + Chan&ge... + + + + + ButtonRemoveMime + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + De&lete + + + + + spacer5 + + + Vertical + + + Expanding + + + + 21 + 41 + + + + + + + + TabPage + + + Filename + + + + unnamed + + + + lbShowonlyFile + + + Show the <b>Useraction</b> only for the filenames defined here. The wildcards '<code>?</code>' and '<code>*</code>' can be used. + + + + + ButtonNewFile + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + &New... + + + + + ButtonEditFile + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + Chan&ge... + + + + + ButtonRemoveFile + + + + 1 + 0 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + De&lete + + + + + spacer6 + + + Vertical + + + Expanding + + + + 21 + 41 + + + + + + + + + + + chkConfirmExecution + + + Confirm each program call separately + + + Allows to tweak the <i>Command</i> before it is executed. + + + + + chkDifferentUser + + + Run as different user: + + + Execute the <i>Command</i> under a different user-id. + + + + + leDifferentUser + + + false + + + Execute the <i>Command</i> under a different user-id. + + + + + spacer3 + + + Vertical + + + Expanding + + + + 161 + 102 + + + + + + + + + + + radioCollectOutput + toggled(bool) + chkSeparateStdError + setEnabled(bool) + + + chkDifferentUser + toggled(bool) + leDifferentUser + setEnabled(bool) + + + + + klineedit.h + klineedit.h + kcombobox.h + klineedit.h + kicondialog.h + klineedit.h + klineedit.h + klineedit.h + ktextedit.h + kkeybutton.h + klistbox.h + klistbox.h + klistbox.h + klistbox.h + klineedit.h + + diff --git a/krusader/ActionMan/addplaceholderpopup.cpp b/krusader/ActionMan/addplaceholderpopup.cpp new file mode 100644 index 0000000..1dc2ef1 --- /dev/null +++ b/krusader/ActionMan/addplaceholderpopup.cpp @@ -0,0 +1,582 @@ +// +// C++ Implementation: addplaceholderpopup +// +// Description: +// +// +// Author: Shie Erlich and Rafi Yanai <>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "addplaceholderpopup.h" + +#include "../UserAction/expander.h" + +#include +#include +#include + +// for ParameterDialog +#include "../krusader.h" // for konfig-access +#include "../BookMan/krbookmarkbutton.h" +#include "../GUI/profilemanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define ACTIVE_MASK 0x0100 +#define OTHER_MASK 0x0200 +#define LEFT_MASK 0x0400 +#define RIGHT_MASK 0x0800 +#define INDEPENDENT_MASK 0x1000 +#define EXECUTABLE_ID 0xFFFF + + +AddPlaceholderPopup::AddPlaceholderPopup( QWidget *parent ) : KPopupMenu( parent ) { + + _activeSub = new KPopupMenu( this ); + _otherSub = new KPopupMenu( this ); + _leftSub = new KPopupMenu( this ); + _rightSub = new KPopupMenu( this ); + _independentSub = new KPopupMenu( this ); + + insertItem( i18n( "Active panel" ), _activeSub ); + insertItem( i18n( "Other panel" ), _otherSub ); + insertItem( i18n( "Left panel" ), _leftSub ); + insertItem( i18n( "Right panel" ), _rightSub ); + insertItem( i18n( "Panel independent" ), _independentSub ); + _independentSub->insertItem( i18n( "Choose executable..." ), EXECUTABLE_ID ); + _independentSub->insertSeparator(); + + // read the expressions array from the user menu and populate menus + Expander expander; + for ( int i = 0; i < expander.placeholderCount(); ++i ) { + if ( expander.placeholder( i )->expression().isEmpty() ) { + if ( expander.placeholder( i )->needPanel() ) { + _activeSub->insertSeparator(); + _otherSub->insertSeparator(); + _leftSub->insertSeparator(); + _rightSub->insertSeparator(); + } + else + _independentSub->insertSeparator(); + } + else { + if ( expander.placeholder( i )->needPanel() ) { + _activeSub->insertItem( i18n( expander.placeholder( i )->description().utf8() ), ( i | ACTIVE_MASK ) ); + _otherSub->insertItem( i18n( expander.placeholder( i )->description().utf8() ), ( i | OTHER_MASK ) ); + _leftSub->insertItem( i18n( expander.placeholder( i )->description().utf8() ), ( i | LEFT_MASK ) ); + _rightSub->insertItem( i18n( expander.placeholder( i )->description().utf8() ), ( i | RIGHT_MASK ) ); + } + else + _independentSub->insertItem( i18n( expander.placeholder( i )->description().utf8() ), ( i | INDEPENDENT_MASK ) ); + } + } + +} + + +QString AddPlaceholderPopup::getPlaceholder( const QPoint& pos ) { + int res = exec( pos ); + if ( res == -1 ) + return QString::null; + + // add the selected flag to the command line + if ( res == EXECUTABLE_ID ) { // did the user need an executable ? + // select an executable + QString filename = KFileDialog::getOpenFileName(QString::null, QString::null, this); + if (filename != QString::null) + return filename + " "; // with extra space + //return filename; // without extra space + } else { // user selected something from the menus + Expander expander; + const exp_placeholder* currentPlaceholder = expander.placeholder( res & ~( ACTIVE_MASK | OTHER_MASK | LEFT_MASK | RIGHT_MASK | INDEPENDENT_MASK ) ); +// if ( ¤tPlaceholder->expFunc == 0 ) { +// KMessageBox::sorry( this, "BOFH Excuse #93:\nFeature not yet implemented" ); +// return QString::null; +// } + ParameterDialog* parameterDialog = new ParameterDialog( currentPlaceholder, this ); + QString panel, parameter = parameterDialog->getParameter(); + delete parameterDialog; + // indicate the panel with 'a' 'o', 'l', 'r' or '_'. + if ( res & ACTIVE_MASK ) + panel = "a"; + else if ( res & OTHER_MASK ) + panel = "o"; + else if ( res & LEFT_MASK ) + panel = "l"; + else if ( res & RIGHT_MASK ) + panel = "r"; + else if ( res & INDEPENDENT_MASK ) + panel = "_"; + //return "%" + panel + currentPlaceholder->expression() + parameter + "% "; // with extra space + return "%" + panel + currentPlaceholder->expression() + parameter + "%"; // without extra space + } + return QString::null; +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// ParameterDialog //////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +ParameterDialog::ParameterDialog( const exp_placeholder* currentPlaceholder, QWidget *parent ) : KDialogBase( Plain, i18n("User Action Parameter Dialog"), Default | Ok, Ok, parent ) { + _parameter.clear(); + _parameterCount = currentPlaceholder->parameterCount(); + + QVBoxLayout* layout = new QVBoxLayout( plainPage() ); + layout->setAutoAdd( true ); + layout->setSpacing( 11 ); + + new QLabel( i18n("This placeholder allows some parameter:"), plainPage(), "intro" ); + + for (int i = 0; i < _parameterCount; ++i ) { + if ( currentPlaceholder->parameter( i ).preset() == "__placeholder" ) + _parameter.append( new ParameterPlaceholder( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__yes" ) + _parameter.append( new ParameterYes( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__no" ) + _parameter.append( new ParameterNo( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__file" ) + _parameter.append( new ParameterFile( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset().find( "__choose" ) != -1 ) + _parameter.append( new ParameterChoose( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__select" ) + _parameter.append( new ParameterSelect( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__goto" ) + _parameter.append( new ParameterGoto( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__syncprofile" ) + _parameter.append( new ParameterSyncprofile( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__searchprofile" ) + _parameter.append( new ParameterSearch( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset() == "__panelprofile" ) + _parameter.append( new ParameterPanelprofile( currentPlaceholder->parameter( i ), plainPage() ) ); + else if ( currentPlaceholder->parameter( i ).preset().find( "__int" ) != -1 ) + _parameter.append( new ParameterInt( currentPlaceholder->parameter( i ), plainPage() ) ); + else + _parameter.append( new ParameterText( currentPlaceholder->parameter( i ), plainPage() ) ); + } + + QFrame * line = new QFrame( plainPage() ); + line->setFrameShape( QFrame::HLine ); + line->setFrameShadow( QFrame::Sunken ); + + connect( this, SIGNAL(defaultClicked()), this, SLOT(reset()) ); +} + +QString ParameterDialog::getParameter() { + if ( _parameterCount == 0 ) // meaning no parameters + return QString::null; + + if ( exec() == -1 ) + return QString::null; + + int lastParameter = _parameterCount; + while ( --lastParameter > -1 ) { + if ( _parameter[ lastParameter ]->text() != _parameter[ lastParameter ]->preset() || _parameter[ lastParameter ]->nessesary() ) + break; + } + + if ( lastParameter < 0) // all parameters have default-values + return QString::null; + + QString parameter = "("; + for ( int i = 0; i <= lastParameter; ++i ) { + if ( i > 0 ) + parameter += ", "; + parameter += "\"" + _parameter[ i ]->text().replace( "\"", "\\\"" ) + "\""; + } + parameter += ")"; + return parameter; +} + +void ParameterDialog::reset() { + for ( int i = 0; i < _parameterCount; ++i ) + _parameter[ i ]->reset(); +} + +void ParameterDialog::slotOk() { + bool valid = true; + for (int i = 0; i < _parameterCount; ++i ) { + if ( _parameter[ i ]->nessesary() && ! _parameter[ i ]->valid() ) + valid = false; + } + + if ( valid ) + accept(); +} + +///////////// ParameterText +ParameterText::ParameterText( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _lineEdit = new KLineEdit( parameter.preset(), this ); + _preset = parameter.preset(); +} + +QString ParameterText::text() { + return _lineEdit->text(); +} +QString ParameterText::preset() { + return _preset; +} +void ParameterText::reset() { + _lineEdit->setText( _preset ); +} +bool ParameterText::valid() { + if ( _lineEdit->text().isEmpty() ) + return false; + else + return true; +} + +///////////// ParameterPlaceholder +ParameterPlaceholder::ParameterPlaceholder( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + QHBox * hbox = new QHBox( this ); + hbox->setSpacing( 6 ); + _lineEdit = new KLineEdit( hbox ); + _button = new QToolButton( hbox); + _button->setText( i18n("add") ); + connect( _button, SIGNAL(clicked()), this, SLOT(addPlaceholder()) ); +} + +QString ParameterPlaceholder::text() { + return _lineEdit->text(); +} +QString ParameterPlaceholder::preset() { + return QString::null; +} +void ParameterPlaceholder::reset() { + _lineEdit->setText( QString::null ); +} +bool ParameterPlaceholder::valid() { + if ( _lineEdit->text().isEmpty() ) + return false; + else + return true; +} +void ParameterPlaceholder::addPlaceholder() { + AddPlaceholderPopup* popup = new AddPlaceholderPopup( this ); + QString exp = popup->getPlaceholder( mapToGlobal( QPoint( _button->pos().x() + _button->width() + 6, _button->pos().y() + _button->height() / 2 ) ) ); + _lineEdit->insert( exp ); + delete popup; +} + +///////////// ParameterYes +ParameterYes::ParameterYes( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + _checkBox = new QCheckBox( i18n( parameter.description().utf8() ), this ); + _checkBox->setChecked( true ); +} + +QString ParameterYes::text() { + if ( _checkBox->isChecked() ) + return QString::null; + else + return "No"; +} +QString ParameterYes::preset() { + return QString::null; +} +void ParameterYes::reset() { + _checkBox->setChecked( true ); +} +bool ParameterYes::valid() { + return true; +} + +///////////// ParameterNo +ParameterNo::ParameterNo( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + _checkBox = new QCheckBox( i18n( parameter.description().utf8() ), this ); + _checkBox->setChecked( false ); +} + +QString ParameterNo::text() { + if ( _checkBox->isChecked() ) + return "Yes"; + else + return QString::null; +} +QString ParameterNo::preset() { + return QString::null; +} +void ParameterNo::reset() { + _checkBox->setChecked( false ); +} +bool ParameterNo::valid() { + return true; +} + +///////////// ParameterFile +ParameterFile::ParameterFile( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + QHBox * hbox = new QHBox( this ); + hbox->setSpacing( 6 ); + _lineEdit = new KLineEdit( hbox ); + _button = new QToolButton( hbox); + KIconLoader *iconLoader = new KIconLoader(); + _button->setPixmap( iconLoader->loadIcon( "fileopen", KIcon::Toolbar, 16 ) ); + connect( _button, SIGNAL(clicked()), this, SLOT(addFile()) ); +} + +QString ParameterFile::text() { + return _lineEdit->text(); +} +QString ParameterFile::preset() { + return QString::null; +} +void ParameterFile::reset() { + _lineEdit->setText( QString::null ); +} +bool ParameterFile::valid() { + if ( _lineEdit->text().isEmpty() ) + return false; + else + return true; +} +void ParameterFile::addFile() { + QString filename = KFileDialog::getOpenFileName(QString::null, QString::null, this); + _lineEdit->insert( filename ); +} + +///////////// ParameterChoose +ParameterChoose::ParameterChoose( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _combobox = new KComboBox( this ); + _combobox->insertStringList( QStringList::split( ";", parameter.preset().section(":", 1) ) ); +} + +QString ParameterChoose::text() { + return _combobox->currentText(); +} +QString ParameterChoose::preset() { + return _combobox->text( 0 ); +} +void ParameterChoose::reset() { + _combobox->setCurrentItem( 0 ); +} +bool ParameterChoose::valid() { + return true; +} + +///////////// ParameterSelect +ParameterSelect::ParameterSelect( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _combobox = new KComboBox( this ); + _combobox->setEditable( true ); + + krConfig->setGroup( "Private" ); + QStrList lst; + int i = krConfig->readListEntry( "Predefined Selections", lst ); + if ( i > 0 ) + _combobox->insertStrList( lst ); + + _combobox->setCurrentText( "*" ); +} + +QString ParameterSelect::text() { + return _combobox->currentText(); +} +QString ParameterSelect::preset() { + return "*"; +} +void ParameterSelect::reset() { + _combobox->setCurrentText( "*" ); +} +bool ParameterSelect::valid() { + return true; +} + +///////////// ParameterGoto +ParameterGoto::ParameterGoto( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + QHBox * hbox = new QHBox( this ); + hbox->setSpacing( 6 ); + _lineEdit = new KLineEdit( hbox ); + _lineEdit->setCompletionObject( new KURLCompletion( KURLCompletion::DirCompletion ) ); + _dirButton = new QToolButton( hbox ); + KIconLoader *iconLoader = new KIconLoader(); + _dirButton->setPixmap( iconLoader->loadIcon( "fileopen", KIcon::Toolbar, 16 ) ); + connect( _dirButton, SIGNAL(clicked()), this, SLOT(setDir()) ); + _placeholderButton = new QToolButton( hbox); + _placeholderButton->setText( i18n("add") ); + connect( _placeholderButton, SIGNAL(clicked()), this, SLOT(addPlaceholder()) ); +} + +QString ParameterGoto::text() { + return _lineEdit->text(); +} +QString ParameterGoto::preset() { + return QString::null; +} +void ParameterGoto::reset() { + _lineEdit->setText( QString::null ); +} +bool ParameterGoto::valid() { + if ( _lineEdit->text().isEmpty() ) + return false; + else + return true; +} +void ParameterGoto::setDir() { + QString folder = KFileDialog::getExistingDirectory(QString::null, this); + _lineEdit->setText( folder ); +} +void ParameterGoto::addPlaceholder() { + AddPlaceholderPopup* popup = new AddPlaceholderPopup( this ); + QString exp = popup->getPlaceholder( mapToGlobal( QPoint( _placeholderButton->pos().x() + _placeholderButton->width() + 6, _placeholderButton->pos().y() + _placeholderButton->height() / 2 ) ) ); + _lineEdit->insert( exp ); + delete popup; +} + +///////////// ParameterSyncprofile +ParameterSyncprofile::ParameterSyncprofile( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _combobox = new KComboBox( this ); + + _combobox->insertStringList( ProfileManager::availableProfiles("SynchronizerProfile") ); +} + +QString ParameterSyncprofile::text() { + return _combobox->currentText(); +} +QString ParameterSyncprofile::preset() { + return _combobox->text( 0 ); +} +void ParameterSyncprofile::reset() { + _combobox->setCurrentItem( 0 ); +} +bool ParameterSyncprofile::valid() { + return true; +} + +///////////// ParameterSearch +ParameterSearch::ParameterSearch( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _combobox = new KComboBox( this ); + + _combobox->insertStringList( ProfileManager::availableProfiles("SearcherProfile") ); +} + +QString ParameterSearch::text() { + return _combobox->currentText(); +} +QString ParameterSearch::preset() { + return _combobox->text( 0 ); +} +void ParameterSearch::reset() { + _combobox->setCurrentItem( 0 ); +} +bool ParameterSearch::valid() { + return true; +} + +///////////// ParameterPanelprofile +ParameterPanelprofile::ParameterPanelprofile( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _combobox = new KComboBox( this ); + + _combobox->insertStringList( ProfileManager::availableProfiles("Panel") ); +} + +QString ParameterPanelprofile::text() { + return _combobox->currentText(); +} +QString ParameterPanelprofile::preset() { + return _combobox->text( 0 ); +} +void ParameterPanelprofile::reset() { + _combobox->setCurrentItem( 0 ); +} +bool ParameterPanelprofile::valid() { + return true; +} + +///////////// ParameterInt +ParameterInt::ParameterInt( const exp_parameter& parameter, QWidget* parent ) : ParameterBase( parameter, parent ) { + QHBoxLayout* layout = new QHBoxLayout( this ); + layout->setAutoAdd( true ); + layout->setSpacing( 6 ); + + new QLabel( i18n( parameter.description().utf8() ), this ); + _spinbox = new KIntSpinBox( this ); + QStringList para = QStringList::split( ";", parameter.preset().section(":", 1) ); + + _spinbox->setMinValue( para[0].toInt() ); + _spinbox->setMaxValue( para[1].toInt() ); + _spinbox->setLineStep( para[2].toInt() ); + _spinbox->setValue( para[3].toInt() ); + + _default = _spinbox->value(); +} + +QString ParameterInt::text() { + return _spinbox->text(); +} +QString ParameterInt::preset() { + return QString( "%1" ).arg( _default ); +} +void ParameterInt::reset() { + return _spinbox->setValue( _default ); +} +bool ParameterInt::valid() { + return true; +} + + +#include "addplaceholderpopup.moc" diff --git a/krusader/ActionMan/addplaceholderpopup.h b/krusader/ActionMan/addplaceholderpopup.h new file mode 100644 index 0000000..285d6a4 --- /dev/null +++ b/krusader/ActionMan/addplaceholderpopup.h @@ -0,0 +1,318 @@ +// +// C++ Interface: addplaceholderpopup +// +// Description: +// +// +// Author: Shie Erlich and Rafi Yanai <>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef ADDPLACEHOLDERPOPUP_H +#define ADDPLACEHOLDERPOPUP_H + +#include +#include +#include "../UserAction/expander.h" + +class QString; +class KLineEdit; +class QToolButton; +class QCheckBox; +class KComboBox; +class KrBookmarkButton; +class KURL; +class KIntSpinBox; + + +/** + * This reads Expander::placeholder[] and fills a popup for easy access to the UserAction Placeholder + * @author Jonas Bhr (http://www.jonas-baehr.de), Shie Erlich + */ +class AddPlaceholderPopup : public KPopupMenu { + +public: + AddPlaceholderPopup( QWidget *parent ); + + /** + * Use this to exec the popup. + * @param pos Position where the popup should appear + * @return the expression which can be placed in the UserAction commandline + */ + QString getPlaceholder( const QPoint& pos ); + +protected: + /** + * This is calles when a Placeholder got parameter. + * @param currentPlaceholder A pointer to the Placeholder the user has choosen + * @return a parameter-string + */ + QString getParameter( exp_placeholder* currentPlaceholder ); + +private: + KPopupMenu *_activeSub, *_otherSub, *_leftSub, *_rightSub, *_independentSub; +}; + + +//////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////// Parameter Widgets /////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +/** + * abstract baseclass for all Parameter widgets + * @author Jonas Bhr (http://www.jonas-baehr.de) + */ +class ParameterBase : public QWidget { +public: + inline ParameterBase( const exp_parameter& parameter, QWidget* parent ) : QWidget( parent ) { _nessesary = parameter.nessesary(); } + /** + * @return the text for the parameter + */ + virtual QString text() = 0; + /** + * @return the default of the parameter + */ + virtual QString preset() = 0; + /** + * re-init the parameter with the default + */ + virtual void reset() = 0; + /** + * @return true if the Parameter as a valid value + */ + virtual bool valid() = 0; + /** + * @return true if the Placeholder realy needs this parameter + */ + inline bool nessesary() { return _nessesary; } +private: + bool _nessesary; +}; + +/** + * The simple Parameter widgets: a line-edit with the description above + * used by default + */ +class ParameterText : public ParameterBase { +public: + ParameterText( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KLineEdit * _lineEdit; + QString _preset; +}; + +/** + * A line-edit with the "addPlaceholder"-button + * used with default = "__placeholder" + */ +class ParameterPlaceholder : public ParameterBase { +Q_OBJECT +public: + ParameterPlaceholder( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KLineEdit * _lineEdit; + QToolButton* _button; +private slots: + void addPlaceholder(); +}; + +/** + * A Checkbox, default: checked; retuns "No" if unchecked + * used with default = "__yes" + */ +class ParameterYes : public ParameterBase { +public: + ParameterYes( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + QCheckBox* _checkBox; +}; + +/** + * A Checkbox, default: unchecked; retuns "Yes" if checked + * used with default = "__no" + */ +class ParameterNo : public ParameterBase { +public: + ParameterNo( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + QCheckBox* _checkBox; +}; + +/** + * A line-edit with the "file open"-button + * used with default = "__file" + */ +class ParameterFile : public ParameterBase { +Q_OBJECT +public: + ParameterFile( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KLineEdit * _lineEdit; + QToolButton* _button; +private slots: + void addFile(); +}; + +/** + * A ComboBox with the description above + * used with default = "__choose:item1;item2;..." + */ +class ParameterChoose : public ParameterBase { +public: + ParameterChoose( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KComboBox * _combobox; +}; + +/** + * An editable ComboBox with the predifined selections + * used with default = "__select" + */ +class ParameterSelect : public ParameterBase { +public: + ParameterSelect( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KComboBox * _combobox; +}; + +/** + * A line-edit with a "choose dir"- and a bookmark-button + * used with default = "__goto" + */ +class ParameterGoto : public ParameterBase { +Q_OBJECT +public: + ParameterGoto( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KLineEdit * _lineEdit; + QToolButton* _dirButton, *_placeholderButton; +private slots: + void setDir(); + void addPlaceholder(); +}; + +/** + * A ComboBox with all profiles available for the Synchronizer + * used with default = "__syncprofile" + */ +class ParameterSyncprofile : public ParameterBase { +public: + ParameterSyncprofile( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KComboBox * _combobox; +}; + +/** + * A ComboBox with all profiles available for the panels + * used with default = "__panelprofile" + */ +class ParameterPanelprofile : public ParameterBase { +public: + ParameterPanelprofile( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KComboBox * _combobox; +}; + +/** + * A ComboBox with all profiles available for the Searchmodule + * used with default = "__searchprofile" + */ +class ParameterSearch : public ParameterBase { +public: + ParameterSearch( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KComboBox * _combobox; +}; + +/** + * A SpinBox for integer + * used with default = "__int:min;max;step;value" + */ +class ParameterInt : public ParameterBase { +public: + ParameterInt( const exp_parameter& parameter, QWidget* parent ); + QString text(); + QString preset(); + void reset(); + bool valid(); +private: + KIntSpinBox * _spinbox; + int _default; +}; + +//////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// ParameterDialog //////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Opens a dialog for the parameter. Depending on the default (preset) a differend widget is used. + * See Parameter-Classes for details + */ +class ParameterDialog : public KDialogBase { +Q_OBJECT +public: + ParameterDialog( const exp_placeholder* currentPlaceholder, QWidget *parent ); + + /** + * Use this to execute the dialog. + * @return a QString with all paremeters; ommiting the optional ones if they have the default-value. + */ + QString getParameter(); + +private: + typedef QValueList ParameterList; + ParameterList _parameter; + int _parameterCount; +private slots: + void reset(); + void slotOk(); +}; + + +#endif // ADDPLACEHOLDERPOPUP_H diff --git a/krusader/ActionMan/useractionlistview.cpp b/krusader/ActionMan/useractionlistview.cpp new file mode 100644 index 0000000..0534027 --- /dev/null +++ b/krusader/ActionMan/useractionlistview.cpp @@ -0,0 +1,232 @@ +// +// C++ Implementation: useractionlistview +// +// Description: +// +// +// Author: Jonas Bähr, (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "useractionlistview.h" + +#include +#include +#include +#include + +#include "../krusader.h" +#include "../UserAction/kraction.h" +#include "../UserAction/useraction.h" + +#define COL_TITLE 0 +#define COL_NAME 1 + + +////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////// UserActionListView ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////// + +UserActionListView::UserActionListView( QWidget * parent, const char * name ) + : KListView( parent, name ) +{ + addColumn( i18n("Title") ); + //addColumn( i18n("Identifier") ); + setResizeMode( QListView::AllColumns ); + + setRootIsDecorated( true ); + setSelectionMode( QListView::Extended ); // normaly select single items but one may use Ctrl or Shift to select multiple + setSorting( COL_TITLE ); + + update(); +} + +UserActionListView::~UserActionListView() +{ +} + +QSize UserActionListView::sizeHint() const { + return QSize(200, 400); +} + + +void UserActionListView::update() { + clear(); + UserAction::KrActionList list = krUserAction->actionList(); + for ( KrAction* action = list.first(); action; action = list.next() ) + insertAction( action ); + //sort(); // this is done automaticly +} + +void UserActionListView::update( KrAction* action ) { + UserActionListViewItem* item = findActionItem( action ); + if ( item ) { + // deleting & re-inserting is _much_easyer then tracking all possible cases of category changes! + bool current = ( item == currentItem() ); + bool selected = item->isSelected(); + delete item; + item = insertAction( action ); + if ( current ) + setCurrentItem( item ); + if ( selected ) + setSelected( item, true ); + } +} + +UserActionListViewItem* UserActionListView::insertAction( KrAction* action ) { + if ( ! action ) + return 0; + + UserActionListViewItem* item; + + if ( action->category().isEmpty() ) + item = new UserActionListViewItem( this, action ); + else { + QListViewItem* categoryItem = findCategoryItem( action->category() ); + if ( ! categoryItem ) { + categoryItem = new KListViewItem( this, action->category() ); // create the new category item it not already present + categoryItem->setSelectable( false ); + } + item = new UserActionListViewItem( categoryItem, action ); + } + + item->setAction( action ); + return item; +} + +QListViewItem* UserActionListView::findCategoryItem( const QString& category ) { + for ( QListViewItem* item = firstChild(); item; item = item->nextSibling() ) + if ( item->text( COL_TITLE ) == category && item->text( COL_NAME ).isEmpty() ) // because actions must have a name, items without name haveto be categories + return item; + + return 0; +} + +UserActionListViewItem* UserActionListView::findActionItem( const KrAction* action ) { + for ( QListViewItemIterator it( this ); it.current(); ++it ) { + if ( UserActionListViewItem* item = dynamic_cast( it.current() ) ) { + if ( item->action() == action ) + return item; + } + } //for + return 0; +} + +KrAction * UserActionListView::currentAction() const { + if ( UserActionListViewItem* item = dynamic_cast( currentItem() ) ) + return item->action(); + else + return 0; +} + +void UserActionListView::setCurrentAction( const KrAction* action) { + UserActionListViewItem* item = findActionItem( action ); + if ( item ) { + setCurrentItem( item ); +// setSelected( item, true ); +// repaintItem( item ); + } +} + +void UserActionListView::setFirstActionCurrent() { + for ( QListViewItemIterator it( this ); it.current(); ++it ) { + if ( UserActionListViewItem* item = dynamic_cast( it.current() ) ) { + setCurrentItem( item ); + break; + } + } //for +} + +void UserActionListView::setCurrentItem( QListViewItem* item ) { + if ( ! item ) + return; + ensureItemVisible( item ); + QListView::setCurrentItem( item ); +} + +QDomDocument UserActionListView::dumpSelectedActions( QDomDocument* mergeDoc ) const { + QPtrList list = selectedItems(); + QDomDocument doc; + if ( mergeDoc ) + doc = *mergeDoc; + else + doc = UserAction::createEmptyDoc(); + QDomElement root = doc.documentElement(); + + for ( QListViewItem* item = list.first(); item; item = list.next() ) + if ( UserActionListViewItem* actionItem = dynamic_cast( item ) ) + root.appendChild( actionItem->action()->xmlDump( doc ) ); + + return doc; +} + +void UserActionListView::removeSelectedActions() { + QPtrList list = selectedItems(); + + for ( QListViewItem* item = list.first(); item; item = list.next() ) + if ( UserActionListViewItem* actionItem = dynamic_cast( item ) ) { + delete actionItem->action(); // remove the action itself + delete actionItem; // remove the action from the list + } // if + +} + +////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////// UserActionListViewItem //////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////// + +UserActionListViewItem::UserActionListViewItem( QListView* view, KrAction* action ) + : KListViewItem( view ) +{ + setAction( action ); +} + +UserActionListViewItem::UserActionListViewItem( QListViewItem* item, KrAction * action ) + : KListViewItem( item ) +{ + setAction( action ); +} + +UserActionListViewItem::~UserActionListViewItem() { +/* // remove category-item if the last member ofthiscategory disappears + if ( QListViewItem* item = dynamic_cast( parent() ) ) { + if ( item->childCount() <= 1 ) + item->deleteLater(); // not possible since not inherited from QObject + }*/ +} + + +void UserActionListViewItem::setAction( KrAction * action ) { + if ( ! action ) + return; + + _action = action; + update(); +} + +KrAction * UserActionListViewItem::action() const { + return _action; +} + +void UserActionListViewItem::update() { + if ( ! _action ) + return; + + if ( ! _action->icon().isEmpty() ) + setPixmap( COL_TITLE, KGlobal::iconLoader()->loadIcon( _action->icon(), KIcon::Small ) ); + setText( COL_TITLE, _action->text() ); + setText( COL_NAME, _action->name() ); +} + +int UserActionListViewItem::compare( QListViewItem* i, int col, bool ascending ) const { +// FIXME some how this only produces bullshit :-/ +// if ( i->text( COL_NAME ).isEmpty() ) { // categories only have titles +// //kdDebug() << "this->title: " << text(COL_TITLE) << " |=| i->title: " << i->text(COL_TITLE) << endl; +// return ( ascending ? -1 : 1 ); // <0 means this is smaller then i +// } +// else + return QListViewItem::compare( i, col, ascending ); +} + + diff --git a/krusader/ActionMan/useractionlistview.h b/krusader/ActionMan/useractionlistview.h new file mode 100644 index 0000000..e0a57f6 --- /dev/null +++ b/krusader/ActionMan/useractionlistview.h @@ -0,0 +1,81 @@ +// +// C++ Interface: useractionlistview +// +// Description: +// +// +// Author: Jonas Bähr, (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef USERACTIONLISTVIEW_H +#define USERACTIONLISTVIEW_H + +#include + +class KrAction; +class QString; +class UserActionListViewItem; +class QDomDocument; + +/** + * @author Jonas Bähr + */ +class UserActionListView : public KListView { +public: + UserActionListView( QWidget* parent = 0, const char* name = 0 ); + ~UserActionListView(); + virtual QSize sizeHint() const; + + void update(); + void update( KrAction* action ); + UserActionListViewItem* insertAction( KrAction* action ); + + KrAction* currentAction() const; + void setCurrentAction( const KrAction* ); + + QDomDocument dumpSelectedActions( QDomDocument* mergeDoc = 0 ) const; + + void removeSelectedActions(); + + /** + * makes the first action in the list current + */ + void setFirstActionCurrent(); + + /** + * makes @e item current and ensures its visibility + */ + virtual void setCurrentItem( QListViewItem* item ); + +protected: + QListViewItem* findCategoryItem( const QString& category ); + UserActionListViewItem* findActionItem( const KrAction* action ); +}; + + +/** + * @author Jonas Bähr + */ +class UserActionListViewItem : public KListViewItem { +public: + UserActionListViewItem( QListView* view, KrAction* action ); + UserActionListViewItem( QListViewItem* item, KrAction* action ); + ~UserActionListViewItem(); + + void setAction( KrAction* action ); + KrAction* action() const; + void update(); + + /** + * This reimplements qt's compare-function in order to have categories on the top of the list + */ + int compare ( QListViewItem * i, int col, bool ascending ) const; + +private: + KrAction* _action; +}; + + +#endif //USERACTIONLISTVIEW_H diff --git a/krusader/ActionMan/useractionpage.cpp b/krusader/ActionMan/useractionpage.cpp new file mode 100644 index 0000000..c4c91e7 --- /dev/null +++ b/krusader/ActionMan/useractionpage.cpp @@ -0,0 +1,317 @@ +// +// C++ Implementation: useractionpage +// +// Description: +// +// +// Author: Shie Erlich and Rafi Yanai <>, (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "useractionpage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "actionproperty.h" +#include "useractionlistview.h" +#include "../UserMenu/usermenu.h" //FIXME this should not be needed here! +#include "../UserAction/useraction.h" +#include "../UserAction/kraction.h" +#include "../krusader.h" + +#define ICON(N) KGlobal::iconLoader()->loadIcon(N, KIcon::Toolbar) +//This is the filter in the KFileDialog of Import/Export: +static const char* FILE_FILTER = I18N_NOOP("*.xml|xml-files\n*|all files"); + + +UserActionPage::UserActionPage( QWidget* parent ) + : QWidget( parent, "UserActionPage" ) +{ + QVBoxLayout* layout = new QVBoxLayout( this, 0, 6, "UserActionPageLayout" ); // 0px margin, 6px item-spacing + + // ======== pseudo-toolbar start ======== + QHBoxLayout* toolbarLayout = new QHBoxLayout( layout, 0, 0 ); // neither margin nor spacing for the toolbar with autoRaise + + newButton = new QToolButton( this, "newButton" ); + newButton->setPixmap( ICON("filenew") ); + newButton->setAutoRaise(true); + QToolTip::add( newButton, i18n("Create new useraction") ); + + importButton = new QToolButton( this, "importButton" ); + importButton->setPixmap( ICON("fileimport") ); + importButton->setAutoRaise(true); + QToolTip::add( importButton, i18n("Import useractions") ); + + exportButton = new QToolButton( this, "exportButton" ); + exportButton->setPixmap( ICON("fileexport") ); + exportButton->setAutoRaise(true); + QToolTip::add( exportButton, i18n("Export useractions") ); + + copyButton = new QToolButton( this, "copyButton" ); + copyButton->setPixmap( ICON("editcopy") ); + copyButton->setAutoRaise(true); + QToolTip::add( copyButton, i18n("Copy useractions to clipboard") ); + + pasteButton = new QToolButton( this, "pasteButton" ); + pasteButton->setPixmap( ICON("editpaste") ); + pasteButton->setAutoRaise(true); + QToolTip::add( pasteButton, i18n("Paste useractions from clipboard") ); + + removeButton = new QToolButton( this, "removeButton" ); + removeButton->setPixmap( ICON("editdelete") ); + removeButton->setAutoRaise(true); + QToolTip::add( removeButton, i18n("Delete selected useractions") ); + + toolbarLayout->addWidget( newButton ); + toolbarLayout->addWidget( importButton ); + toolbarLayout->addWidget( exportButton ); + toolbarLayout->addWidget( copyButton ); + toolbarLayout->addWidget( pasteButton ); + toolbarLayout->addSpacing( 6 ); // 6 pixel nothing + toolbarLayout->addWidget( removeButton ); + toolbarLayout->addStretch( 1000 ); // some very large stretch-factor + // ======== pseudo-toolbar end ======== +/* This seems obsolete now! + // Display some help + KMessageBox::information( this, // parent + i18n( "When you apply changes to an action, the modifications " + "become available in the current session immediately.\n" + "When closing ActionMan, you will be asked to save the changes permanently." + ), + QString::null, // caption + "show UserAction help" //dontShowAgainName for the config + ); +*/ + QSplitter *split = new QSplitter( this, "useractionpage splitter"); + layout->addWidget( split, 1000 ); // again a very large stretch-factor to fix the height of the toolbar + + actionTree = new UserActionListView( split, "actionTree" ); + actionProperties = new ActionProperty( split, "actionProperties" ); + actionProperties->setEnabled( false ); // if there are any actions in the list, the first is displayed and this widget is enabled + + connect( actionTree, SIGNAL( currentChanged(QListViewItem*) ), SLOT( slotChangeCurrent() ) ); + connect( newButton, SIGNAL( clicked() ), SLOT( slotNewAction() ) ); + connect( removeButton, SIGNAL( clicked() ), SLOT( slotRemoveAction() ) ); + connect( importButton, SIGNAL( clicked() ), SLOT( slotImport() ) ); + connect( exportButton, SIGNAL( clicked() ), SLOT( slotExport() ) ); + connect( copyButton, SIGNAL( clicked() ), SLOT( slotToClip() ) ); + connect( pasteButton, SIGNAL( clicked() ), SLOT( slotFromClip() ) ); + + // forwards the changed signal of the properties + connect ( actionProperties, SIGNAL( changed() ), SIGNAL( changed() ) ); + + actionTree->setFirstActionCurrent(); + actionTree->setFocus(); +} + +UserActionPage::~UserActionPage() +{ +} + +bool UserActionPage::continueInSpiteOfChanges() { + if ( ! actionProperties->isModified() ) + return true; + + int answer = KMessageBox::questionYesNoCancel( this, + i18n("The current action has been modified. Do you want to apply these changes?") + ); + if ( answer == KMessageBox::Cancel ) { + disconnect( actionTree, SIGNAL( currentChanged(QListViewItem*) ), this, SLOT( slotChangeCurrent() ) ); + actionTree->setCurrentAction( actionProperties->action() ); + connect( actionTree, SIGNAL( currentChanged(QListViewItem*) ), SLOT( slotChangeCurrent() ) ); + return false; + } + if ( answer == KMessageBox::Yes ) { + if ( ! actionProperties->validProperties() ) { + disconnect( actionTree, SIGNAL( currentChanged(QListViewItem*) ), this, SLOT( slotChangeCurrent() ) ); + actionTree->setCurrentAction( actionProperties->action() ); + connect( actionTree, SIGNAL( currentChanged(QListViewItem*) ), SLOT( slotChangeCurrent() ) ); + return false; + } + slotUpdateAction(); + } // if Yes + return true; +} + +void UserActionPage::slotChangeCurrent() { + if ( ! continueInSpiteOfChanges() ) + return; + + KrAction* action = actionTree->currentAction(); + if ( action ) { + actionProperties->setEnabled( true ); + // the discinct name is used as ID it is not allowd to change it afterwards because it is may referenced anywhere else + actionProperties->leDistinctName->setEnabled( false ); + actionProperties->updateGUI( action ); + } + else { + // If the current item in the tree is no action (i.e. a cathegory), disable the properties + actionProperties->clear(); + actionProperties->setEnabled( false ); + } + emit applied(); // to disable the apply-button +} + + +void UserActionPage::slotUpdateAction() { + // check that we have a command line, title and a name + if ( ! actionProperties->validProperties() ) + return; + + if ( actionProperties->leDistinctName->isEnabled() ) { + // := new entry + KrAction* action = new KrAction( krApp->actionCollection(), actionProperties->leDistinctName->text().latin1() ); + krUserAction->addKrAction( action ); + actionProperties->updateAction( action ); + UserActionListViewItem* item = actionTree->insertAction( action ); + actionTree->setCurrentItem( item ); + krApp->userMenu->update(); + } + else { // := edit an existing + actionProperties->updateAction(); + actionTree->update( actionProperties->action() ); // update the listviewitem as well... + } + apply(); +} + + +void UserActionPage::slotNewAction() { + if ( continueInSpiteOfChanges() ) { + actionTree->clearSelection(); // else the user may think that he is overwriting the selected action + actionProperties->clear(); + actionProperties->setEnabled( true ); // it may be disabled because the tree has the focus on a category + actionProperties->leDistinctName->setEnabled( true ); + actionProperties->leDistinctName->setFocus(); + } +} + +void UserActionPage::slotRemoveAction() { + if ( ! dynamic_cast( actionTree->currentItem() ) ) + return; + + int messageDelete = KMessageBox::warningContinueCancel ( this, //parent + i18n("Are you sure that you want to remove all selected actions?"), //text + i18n("Remove selected actions?"), //caption + i18n("Remove"), //Label for the continue-button + "Confirm Remove UserAction", //dontAskAgainName (for the config-file) + KMessageBox::Dangerous) ; + + if ( messageDelete != KMessageBox::Continue ) + return; + + actionTree->removeSelectedActions(); + + apply(); +} + +void UserActionPage::slotImport() { + QString filename = KFileDialog::getOpenFileName(QString::null, i18n(FILE_FILTER), this); + if ( filename.isEmpty() ) + return; + + UserAction::KrActionList newActions; + krUserAction->readFromFile( filename, UserAction::renameDoublicated, &newActions ); + for ( KrAction* action = newActions.first(); action; action = newActions.next() ) + actionTree->insertAction( action ); + + if ( newActions.count() > 0 ) { + apply(); + } +} + +void UserActionPage::slotExport() { + if ( ! dynamic_cast( actionTree->currentItem() ) ) + return; + + QString filename = KFileDialog::getSaveFileName(QString::null, i18n(FILE_FILTER), this); + if ( filename.isEmpty() ) + return; + + QDomDocument doc = QDomDocument( ACTION_DOCTYPE ); + QFile file( filename ); + int answer = 0; + if( file.open( IO_ReadOnly ) ) { // getting here, means the file already exists an can be read + if( doc.setContent( &file ) ) // getting here means the file exists and already contains an UserAction-XML-tree + answer = KMessageBox::warningYesNoCancel( this, //parent + i18n("This file already contains some useractions.\nDo you want to overwrite it or should it be merged with the selected actions?"), //text + i18n("Overwrite or merge?"), //caption + i18n("Overwrite"), //label for Yes-Button + i18n("Merge") //label for No-Button + ); + file.close(); + } + if ( answer == 0 && file.exists() ) + answer = KMessageBox::warningContinueCancel( this, //parent + i18n("This file already exists. Do you want to overwrite it?"), //text + i18n("Overwrite existing file?"), //caption + i18n("Overwrite") //label for Continue-Button + ); + + if ( answer == KMessageBox::Cancel ) + return; + + if ( answer == KMessageBox::No ) // that means the merge-button + doc = actionTree->dumpSelectedActions( &doc ); // merge + else // Yes or Continue means overwrite + doc = actionTree->dumpSelectedActions(); + + bool success = UserAction::writeToFile( doc, filename ); + if ( ! success ) + KMessageBox::error( this, + i18n("Can't open %1 for writing!\nNothing exported.").arg(filename), + i18n("Export failed!") + ); +} + +void UserActionPage::slotToClip() { + if ( ! dynamic_cast( actionTree->currentItem() ) ) + return; + + QDomDocument doc = actionTree->dumpSelectedActions(); + KApplication::clipboard()->setText( doc.toString() ); +} + +void UserActionPage::slotFromClip() { + QDomDocument doc( ACTION_DOCTYPE ); + if ( doc.setContent( KApplication::clipboard()->text() ) ) { + QDomElement root = doc.documentElement(); + UserAction::KrActionList newActions; + krUserAction->readFromElement( root, UserAction::renameDoublicated, &newActions ); + for ( KrAction* action = newActions.first(); action; action = newActions.next() ) + actionTree->insertAction( action ); + if ( newActions.count() > 0 ) { + apply(); + } + } // if ( doc.setContent ) +} + +bool UserActionPage::readyToQuit() { + // Check if the current UserAction has changed + if ( ! continueInSpiteOfChanges() ) + return false; + + krUserAction->writeActionFile(); + return true; +} + +void UserActionPage::apply() { + krUserAction->writeActionFile(); + emit applied(); +} + +void UserActionPage::applyChanges() { + slotUpdateAction(); +} + + +#include "useractionpage.moc" diff --git a/krusader/ActionMan/useractionpage.h b/krusader/ActionMan/useractionpage.h new file mode 100644 index 0000000..cda2dfc --- /dev/null +++ b/krusader/ActionMan/useractionpage.h @@ -0,0 +1,73 @@ +// +// C++ Interface: useractionpage +// +// Description: +// +// +// Author: Shie Erlich and Rafi Yanai <>, (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef USERACTIONPAGE_H +#define USERACTIONPAGE_H + +#include + +class UserActionListView; +class ActionProperty; +class QToolButton; + +/** + * @author Jonas Bähr +*/ +class UserActionPage : public QWidget { +Q_OBJECT +public: + UserActionPage( QWidget* parent ); + ~UserActionPage(); + + /** + * Be sure to call this function before you delete this page!! + * @return true if this page can be closed + */ + bool readyToQuit(); + + void applyChanges(); + +signals: + void changed(); ///< emited on changes to an action (used to enable the apply-button) + void applied(); ///< emited when changes are applied to an action (used to disable the apply-button) + +private: + /** + * If there are modifications in the property-widget, the user is asked + * what to do. Apply, discard or continue editing. In the first case, + * saving is done in this function. + * @return true if a new action can be loaded in the property-widget. + */ + bool continueInSpiteOfChanges(); + /** + * applyes all changes by writing the actionfile and emits "applied" + */ + void apply(); + + //bool _modified; ///< true if the action-tree was changed (= changes were applied to an action) + UserActionListView *actionTree; + ActionProperty *actionProperties; + QToolButton *importButton, *exportButton; + QToolButton *copyButton, *pasteButton; + QToolButton *removeButton, *newButton; + +private slots: + void slotChangeCurrent(); //loads a new action into the detail-view + void slotUpdateAction(); //updates the action to the xml-file + void slotNewAction(); + void slotRemoveAction(); + void slotImport(); + void slotExport(); + void slotToClip(); + void slotFromClip(); +}; + +#endif //USERACTIONPAGE_H diff --git a/krusader/BookMan/Makefile.am b/krusader/BookMan/Makefile.am new file mode 100644 index 0000000..3f602d3 --- /dev/null +++ b/krusader/BookMan/Makefile.am @@ -0,0 +1,11 @@ +noinst_LIBRARIES = libBookMan.a + +INCLUDES = $(all_includes) + +libBookMan_a_METASOURCES = AUTO + +libBookMan_a_SOURCES = \ + krbookmark.cpp \ + krbookmarkbutton.cpp \ + krbookmarkhandler.cpp \ + kraddbookmarkdlg.cpp diff --git a/krusader/BookMan/kraddbookmarkdlg.cpp b/krusader/BookMan/kraddbookmarkdlg.cpp new file mode 100644 index 0000000..c5ecfd4 --- /dev/null +++ b/krusader/BookMan/kraddbookmarkdlg.cpp @@ -0,0 +1,117 @@ +#include "kraddbookmarkdlg.h" +#include "../krusader.h" +#include "krbookmarkhandler.h" +#include +#include +#include +#include +#include +#include +#include + +KrAddBookmarkDlg::KrAddBookmarkDlg(QWidget *parent, KURL url): + KDialogBase(KDialogBase::Swallow, i18n("Add Bookmark"), + KDialogBase::User1 | KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, parent) { + // create the 'new folder' button + setButtonText(KDialogBase::User1, i18n("New Folder")); + showButton(KDialogBase::User1, false); // hide it until _createIn is shown + connect(this, SIGNAL(user1Clicked()), this, SLOT(newFolder())); + + // create the main widget + QWidget *page = new QWidget(this); + setMainWidget(page); + + QGridLayout *layout = new QGridLayout(page, 1, 1, 0, spacingHint()); // expanding + // name and url + QLabel *lb1 = new QLabel(i18n("Name:"), page); + _name = new KLineEdit(page); + _name->setText(url.prettyURL()); // default name is the url + _name->selectAll(); // make the text selected + layout->addWidget(lb1, 0, 0); + layout->addWidget(_name, 0, 1); + + QLabel *lb2 = new QLabel(i18n("URL:"), page); + _url = new KLineEdit(page); + layout->addWidget(lb2, 1, 0); + layout->addWidget(_url, 1, 1); + _url->setText(url.prettyURL()); // set the url in the field + + // create in linedit and button + QLabel *lb3 = new QLabel(i18n("Create in:"), page); + _folder = new KLineEdit(page); + layout->addWidget(lb3, 2, 0); + layout->addWidget(_folder, 2, 1); + _folder->setReadOnly(true); + + _createInBtn = new QToolButton(page); + _createInBtn->setPixmap(krLoader->loadIcon("down", KIcon::Small)); + _createInBtn->setToggleButton(true); + connect(_createInBtn, SIGNAL(toggled(bool)), this, SLOT(toggleCreateIn(bool ))); + layout->addWidget(_createInBtn, 2, 2); + + setDetailsWidget(createInWidget()); + + _name->setFocus(); +} + +void KrAddBookmarkDlg::toggleCreateIn(bool show) { + _createInBtn->setPixmap(krLoader->loadIcon(show ? "up" :"down", KIcon::Small)); + showButton(KDialogBase::User1, show); + setDetails(show); +} + +// creates the widget that lets you decide where to put the new bookmark +QWidget *KrAddBookmarkDlg::createInWidget() { + _createIn = new KListView(this); + _createIn->addColumn("Folders"); + _createIn->header()->hide(); + _createIn->setRootIsDecorated(true); + _createIn->setAlternateBackground(QColor()); // disable alternate coloring + + KListViewItem *item = new KListViewItem(_createIn, i18n("Bookmarks")); + item->setOpen(true); + item->setSelected(true); + _xr[item] = krBookMan->_root; + + populateCreateInWidget(krBookMan->_root, item); + _createIn->setCurrentItem(item); + createInSelection(item); + connect(_createIn, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(createInSelection(QListViewItem*))); + + return _createIn; +} + +void KrAddBookmarkDlg::createInSelection(QListViewItem *item) { + if (item) { + _folder->setText(_xr[static_cast(item)]->text()); + } +} + +void KrAddBookmarkDlg::populateCreateInWidget(KrBookmark *root, KListViewItem *parent) { + for (KrBookmark *bm = root->children().first(); bm; bm = root->children().next()) { + if (bm->isFolder()) { + KListViewItem *item = new KListViewItem(parent, bm->text()); + item->setOpen(true); + _xr[item] = bm; + populateCreateInWidget(bm, item); + } + } +} + +void KrAddBookmarkDlg::newFolder() { + // get the name + QString newFolder = KInputDialog::getText(i18n("New Folder"), i18n("Folder name:"), QString::null, 0, this); + if (newFolder == QString::null) + return; + // add to the list in bookman + KrBookmark *bm = new KrBookmark(newFolder); + krBookMan->addBookmark(bm, _xr[static_cast(_createIn->selectedItem())]); + // fix the gui + KListViewItem *item = new KListViewItem(_createIn->selectedItem(), bm->text()); + _xr[item] = bm; + + _createIn->setCurrentItem(item); + item->setSelected(true); +} + +#include "kraddbookmarkdlg.moc" diff --git a/krusader/BookMan/kraddbookmarkdlg.h b/krusader/BookMan/kraddbookmarkdlg.h new file mode 100644 index 0000000..d9db75c --- /dev/null +++ b/krusader/BookMan/kraddbookmarkdlg.h @@ -0,0 +1,39 @@ +#ifndef KRADDBOOKMARKDLG_H +#define KRADDBOOKMARKDLG_H + +#include "krbookmark.h" +#include "../VFS/vfs.h" +#include +#include +#include +#include +#include +#include + +class KrAddBookmarkDlg: public KDialogBase { + Q_OBJECT +public: + KrAddBookmarkDlg(QWidget *parent, KURL url = 0); + KURL url() const { return vfs::fromPathOrURL(_url->text()); } + QString name() const { return _name->text(); } + KrBookmark *folder() const { return _xr[static_cast(_createIn->selectedItem())]; } + +protected: + QWidget *createInWidget(); + void populateCreateInWidget(KrBookmark *root, KListViewItem *parent); + +protected slots: + void toggleCreateIn(bool show); + void createInSelection(QListViewItem *item); + void newFolder(); + +private: + KLineEdit *_name; + KLineEdit *_url; + KLineEdit *_folder; + KListView *_createIn; + QMap _xr; + QToolButton *_createInBtn; +}; + +#endif // KRADDBOOKMARKDLG_H diff --git a/krusader/BookMan/krbookmark.cpp b/krusader/BookMan/krbookmark.cpp new file mode 100644 index 0000000..f0708d3 --- /dev/null +++ b/krusader/BookMan/krbookmark.cpp @@ -0,0 +1,92 @@ +#include "krbookmark.h" +#include "../krusader.h" +#include "../VFS/krarchandler.h" +#include +#include +#include +#include + +#define BM_NAME(X) (QString("Bookmark:")+X) + +#if KDE_IS_VERSION(3,4,0) +static const char* NAME_DEVICES = I18N_NOOP("Media"); +#else +static const char* NAME_DEVICES = I18N_NOOP("Devices"); +#endif +static const char* NAME_VIRTUAL = I18N_NOOP("Virtual Filesystem"); +static const char* NAME_LAN = I18N_NOOP("Local Network"); + +KrBookmark::KrBookmark(QString name, KURL url, KActionCollection *parent, QString icon, QString actionName ): + KAction(name, 0, 0, 0, parent, actionName.isNull() ? BM_NAME(name).latin1() : BM_NAME(actionName).latin1()), + _url(url), _folder(false), _separator(false) { + connect(this, SIGNAL(activated()), this, SLOT(activatedProxy())); + // do we have an icon? + if (!icon.isEmpty()) + setIcon(icon); + else { + // what kind of a url is it? + if (_url.isLocalFile()) { + setIcon("folder"); + } else { // is it an archive? + if (KRarcHandler::isArchive(_url)) + setIcon("tar"); + else setIcon("folder_html"); + } + } + + _children.setAutoDelete(true); +} + +KrBookmark::KrBookmark(QString name, QString icon): + KAction(name, 0, 0, 0, 0), _folder(true), _separator(false) { + setIcon(icon=="" ? "folder" : icon); +} + +KrBookmark* KrBookmark::getExistingBookmark(QString actionName, KActionCollection *collection) { + return static_cast(collection->action(BM_NAME(actionName).latin1())); +} + +KrBookmark* KrBookmark::devices(KActionCollection *collection) { + KrBookmark *bm = getExistingBookmark(i18n(NAME_DEVICES), collection); + if (!bm) { +#if KDE_IS_VERSION(3,4,0) + bm = new KrBookmark(i18n(NAME_DEVICES), "media:/", collection); +#else + bm = new KrBookmark(i18n(NAME_DEVICES), "devices:/", collection); +#endif + bm->setIconSet(krLoader->loadIcon("blockdevice", KIcon::Small)); + } + return bm; +} + +KrBookmark* KrBookmark::virt(KActionCollection *collection) { + KrBookmark *bm = getExistingBookmark(i18n(NAME_VIRTUAL), collection); + if (!bm) { + bm = new KrBookmark(i18n(NAME_VIRTUAL), "virt:/", collection); + bm->setIconSet(krLoader->loadIcon("pipe", KIcon::Small)); + } + return bm; +} + +KrBookmark* KrBookmark::lan(KActionCollection *collection) { + KrBookmark *bm = getExistingBookmark(i18n(NAME_LAN), collection); + if (!bm) { + bm = new KrBookmark(i18n(NAME_LAN), "lan:/", collection); + bm->setIconSet(krLoader->loadIcon("network", KIcon::Small)); + } + return bm; +} + +KrBookmark* KrBookmark::separator() { + KrBookmark *bm = new KrBookmark(""); + bm->_separator = true; + bm->_folder = false; + return bm; +} + + +void KrBookmark::activatedProxy() { + emit activated(url()); +} + +#include "krbookmark.moc" diff --git a/krusader/BookMan/krbookmark.h b/krusader/BookMan/krbookmark.h new file mode 100644 index 0000000..fda39ce --- /dev/null +++ b/krusader/BookMan/krbookmark.h @@ -0,0 +1,45 @@ +#ifndef KRBOOKMARK_H +#define KRBOOKMARK_H + +#include +#include +#include + +class KActionCollection; + +class KrBookmark: public KAction { + Q_OBJECT +public: + KrBookmark(QString name, KURL url, KActionCollection *parent, QString icon = "", QString actionName = QString::null ); + KrBookmark(QString name, QString icon = ""); // creates a folder + // text() and setText() to change the name of the bookmark + // icon() and setIcon() to change icons (by name) + inline const KURL& url() const { return _url; } + inline void setURL(const KURL& url) { _url = url; } + inline bool isFolder() const { return _folder; } + inline bool isSeparator() const { return _separator; } + QPtrList& children() { return _children; } + + static KrBookmark* getExistingBookmark(QString actionName, KActionCollection *collection); + // ----- special bookmarks + static KrBookmark* devices(KActionCollection *collection); + static KrBookmark* virt(KActionCollection *collection); + static KrBookmark* lan(KActionCollection *collection); + static KrBookmark* separator(); + +signals: + void activated(const KURL& url); + +protected slots: + void activatedProxy(); + + +private: + KURL _url; + QString _icon; + bool _folder; + bool _separator; + QPtrList _children; +}; + +#endif // KRBOOKMARK_H diff --git a/krusader/BookMan/krbookmarkbutton.cpp b/krusader/BookMan/krbookmarkbutton.cpp new file mode 100644 index 0000000..08d13a5 --- /dev/null +++ b/krusader/BookMan/krbookmarkbutton.cpp @@ -0,0 +1,38 @@ +#include "krbookmarkbutton.h" +#include "krbookmarkhandler.h" +#include "../krusader.h" +#include +#include +#include +#include +#include +#include + +KrBookmarkButton::KrBookmarkButton(QWidget *parent): QToolButton(parent) { + QPixmap icon = krLoader->loadIcon("bookmark", KIcon::Toolbar, 16); + setFixedSize(icon.width() + 4, icon.height() + 4); + setPixmap(icon); + setTextLabel(i18n("BookMan II"), true); + setPopupDelay(10); // 0.01 seconds press + setAcceptDrops(false); + + acmBookmarks = new KActionMenu(i18n("Bookmarks"), "bookmark", 0, 0); + acmBookmarks->setDelayed(false); + acmBookmarks->popupMenu()->setKeyboardShortcutsEnabled(true); + acmBookmarks->popupMenu()->setKeyboardShortcutsExecute(true); + + setPopup(acmBookmarks->popupMenu()); + connect(this, SIGNAL(pressed()), this, SLOT(populate())); + populate(); +} + +void KrBookmarkButton::populate() { + krBookMan->populate(static_cast(popup())); +} + +void KrBookmarkButton::openPopup() { + populate(); + popup()->exec(mapToGlobal(QPoint(0, height()))); +} + +#include "krbookmarkbutton.moc" diff --git a/krusader/BookMan/krbookmarkbutton.h b/krusader/BookMan/krbookmarkbutton.h new file mode 100644 index 0000000..1267871 --- /dev/null +++ b/krusader/BookMan/krbookmarkbutton.h @@ -0,0 +1,23 @@ +#ifndef KRBOOKMARK_BUTTON_H +#define KRBOOKMARK_BUTTON_H + +#include +#include "krbookmarkhandler.h" + +class KrBookmarkButton: public QToolButton { + Q_OBJECT +public: + KrBookmarkButton(QWidget *parent); + void openPopup(); + +signals: + void openUrl(const KURL &url); + +protected slots: + void populate(); + +private: + KActionMenu *acmBookmarks; +}; + +#endif // KRBOOKMARK_BUTTON_H diff --git a/krusader/BookMan/krbookmarkhandler.cpp b/krusader/BookMan/krbookmarkhandler.cpp new file mode 100644 index 0000000..9f1413b --- /dev/null +++ b/krusader/BookMan/krbookmarkhandler.cpp @@ -0,0 +1,576 @@ +#include "krbookmarkhandler.h" +#include "kraddbookmarkdlg.h" +#include "../krusader.h" +#include "../krslots.h" +#include "../Dialogs/popularurls.h" +#include "../VFS/vfs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPECIAL_BOOKMARKS true + +// ------------------------ for internal use +#define BOOKMARKS_FILE "krusader/krbookmarks.xml" +#define CONNECT_BM(X) { disconnect(X, SIGNAL(activated(const KURL&)), 0, 0); connect(X, SIGNAL(activated(const KURL&)), this, SLOT(slotActivated(const KURL&))); } + +KrBookmarkHandler::KrBookmarkHandler(): QObject(0), _middleClick(false), _mainBookmarkPopup( 0 ), _specialBookmarkIDs(), _bookmarkIDTable() { + // create our own action collection and make the shortcuts apply only to parent + _privateCollection = new KActionCollection(krApp, "private collection"); + _collection = krApp->actionCollection(); + + // create _root: father of all bookmarks. it is a dummy bookmark and never shown + _root = new KrBookmark(i18n("Bookmarks")); + + _bookmarkIDTable.setAutoDelete( true ); + + // load bookmarks + importFromFile(); + + // hack + manager = KBookmarkManager::managerForFile(locateLocal( "data", BOOKMARKS_FILE ), false); + connect(manager, SIGNAL(changed(const QString&, const QString& )), this, SLOT(bookmarksChanged(const QString&, const QString& ))); +} + +KrBookmarkHandler::~KrBookmarkHandler() { + delete manager; + delete _privateCollection; +} + +void KrBookmarkHandler::menuOperation(int id) { + switch (id) { + case BookmarkCurrent: + bookmarkCurrent(ACTIVE_PANEL->virtualPath()); + break; + case ManageBookmarks: + manager->slotEditBookmarks(); + break; + } +} + +void KrBookmarkHandler::bookmarkCurrent(KURL url) { + KrAddBookmarkDlg dlg(krApp, url); + if (dlg.exec() == KDialog::Accepted) { + KrBookmark *bm = new KrBookmark(dlg.name(), dlg.url(), _collection); + addBookmark(bm, dlg.folder()); + } +} + +void KrBookmarkHandler::addBookmark(KrBookmark *bm, KrBookmark *folder) { + if (folder == 0) + folder = _root; + + // add to the list (bottom) + folder->children().append(bm); + + exportToFile(); +} + +void KrBookmarkHandler::deleteBookmark(KrBookmark *bm) { + if( bm->isFolder() ) + clearBookmarks( bm ); // remove the child bookmarks + removeReferences( _root, bm ); + bm->unplugAll(); + delete bm; + + exportToFile(); +} + +void KrBookmarkHandler::removeReferences( KrBookmark *root, KrBookmark *bmToRemove ) { + int index = root->children().find( bmToRemove ); + if( index >= 0 ) + root->children().take( index ); + + KrBookmark *bm = root->children().first(); + while (bm) { + if (bm->isFolder()) + removeReferences(bm, bmToRemove); + bm = root->children().next(); + } +} + +void KrBookmarkHandler::exportToFileBookmark(QDomDocument &doc, QDomElement &where, KrBookmark *bm) { + if( bm->isSeparator() ) { + QDomElement bookmark = doc.createElement("separator"); + where.appendChild(bookmark); + } + else { + QDomElement bookmark = doc.createElement("bookmark"); + // url + bookmark.setAttribute("href", bm->url().prettyURL()); + // icon + bookmark.setAttribute("icon", bm->icon()); + // title + QDomElement title = doc.createElement("title"); + title.appendChild(doc.createTextNode(bm->text())); + bookmark.appendChild(title); + + where.appendChild(bookmark); + } +} + +void KrBookmarkHandler::exportToFileFolder(QDomDocument &doc, QDomElement &parent, KrBookmark *folder) { + for (KrBookmark *bm = folder->children().first(); bm; bm = folder->children().next()) { + if (bm->isFolder()) { + QDomElement newFolder = doc.createElement("folder"); + newFolder.setAttribute("icon", bm->icon()); + parent.appendChild(newFolder); + QDomElement title = doc.createElement("title"); + title.appendChild(doc.createTextNode(bm->text())); + newFolder.appendChild(title); + exportToFileFolder(doc, newFolder, bm); + } else { + exportToFileBookmark(doc, parent, bm); + } + } +} + +// export to file using the xbel standard +// +// +// Developer Web Site +// +// Title of this folder +// KDE Web Site +// +// My own bookmarks +// KOffice Web Site +// +// KDevelop Web Site +// +// +// +void KrBookmarkHandler::exportToFile() { + QDomDocument doc( "xbel" ); + QDomElement root = doc.createElement( "xbel" ); + doc.appendChild( root ); + + exportToFileFolder(doc, root, _root); + if (!doc.firstChild().isProcessingInstruction()) { + // adding: if not already present + QDomProcessingInstruction instr = doc.createProcessingInstruction( "xml", + "version=\"1.0\" encoding=\"UTF-8\" "); + doc.insertBefore( instr, doc.firstChild() ); + } + + + QString filename = locateLocal( "data", BOOKMARKS_FILE ); + QFile file(filename); + if ( file.open( IO_WriteOnly ) ) { + QTextStream stream( &file ); + stream.setEncoding(stream.UnicodeUTF8); + stream << doc.toString(); + file.close(); + } else { + KMessageBox::error(krApp, i18n("Unable to write to %1").arg(filename), i18n("Error")); + } +} + +bool KrBookmarkHandler::importFromFileBookmark(QDomElement &e, KrBookmark *parent, QString path, QString *errorMsg) { + QString url, name, icon; + // verify tag + if (e.tagName() != "bookmark") { + *errorMsg = e.tagName() + i18n(" instead of ")+"bookmark"; + return false; + } + // verify href + if (!e.hasAttribute("href")) { + *errorMsg = i18n("missing tag ")+ "href"; + return false; + } else url = e.attribute("href"); + // verify title + QDomElement te = e.firstChild().toElement(); + if (te.tagName() != "title") { + *errorMsg = i18n("missing tag ")+"title"; + return false; + } else name = te.text(); + // do we have an icon? + if (e.hasAttribute("icon")) { + icon=e.attribute("icon"); + } + // ok: got name and url, let's add a bookmark + KrBookmark *bm = KrBookmark::getExistingBookmark(path+name, _collection); + if (!bm) { + bm = new KrBookmark(name, vfs::fromPathOrURL( url ), _collection, icon, path+name); + parent->children().append(bm); + } + + return true; +} + +bool KrBookmarkHandler::importFromFileFolder(QDomNode &first, KrBookmark *parent, QString path, QString *errorMsg) { + QString name; + QDomNode n = first; + while (!n.isNull()) { + QDomElement e = n.toElement(); + if (e.tagName() == "bookmark") { + if (!importFromFileBookmark(e, parent, path, errorMsg)) + return false; + } else if (e.tagName() == "folder") { + QString iconName = ""; + if (e.hasAttribute("icon")) iconName=e.attribute("icon"); + // the title is the first child of the folder + QDomElement tmp = e.firstChild().toElement(); + if (tmp.tagName() != "title") { + *errorMsg = i18n("missing tag ")+"title"; + return false; + } else name = tmp.text(); + KrBookmark *folder = new KrBookmark(name, iconName); + parent->children().append(folder); + + QDomNode nextOne = tmp.nextSibling(); + if (!importFromFileFolder(nextOne, folder, path + name + "/", errorMsg)) + return false; + } else if (e.tagName() == "separator") { + parent->children().append(KrBookmark::separator()); + } + n = n.nextSibling(); + } + return true; +} + + +void KrBookmarkHandler::importFromFile() { + clearBookmarks(_root); + + QString filename = locateLocal( "data", BOOKMARKS_FILE ); + QFile file( filename ); + if ( !file.open(IO_ReadOnly)) + return; // no bookmarks file + + QString errorMsg; + QDomNode n; + QDomElement e; + QDomDocument doc( "xbel" ); + if ( !doc.setContent( &file, &errorMsg ) ) { + goto ERROR; + } + // iterate through the document: first child should be "xbel" (skip all until we find it) + n = doc.firstChild(); + while (!n.isNull() && n.toElement().tagName()!="xbel") + n = n.nextSibling(); + + if (n.isNull() || n.toElement().tagName()!="xbel") { + errorMsg = i18n("%1 doesn't seem to be a valid Bookmarks file").arg(filename); + goto ERROR; + } else n = n.firstChild(); // skip the xbel part + importFromFileFolder(n, _root, "", &errorMsg); + goto SUCCESS; + +ERROR: + KMessageBox::error(krApp, i18n("Error reading bookmarks file: %1").arg(errorMsg), i18n( "Error" )); + +SUCCESS: + file.close(); +} + +void KrBookmarkHandler::populate(KPopupMenu *menu) { + _mainBookmarkPopup = menu; + menu->clear(); + _bookmarkIDTable.clear(); + _specialBookmarkIDs.clear(); + buildMenu(_root, menu); +} + +void KrBookmarkHandler::buildMenu(KrBookmark *parent, KPopupMenu *menu) { + static int inSecondaryMenu = 0; // used to know if we're on the top menu + + // run the loop twice, in order to put the folders on top. stupid but easy :-) + // note: this code drops the separators put there by the user + for (KrBookmark *bm = parent->children().first(); bm; bm = parent->children().next()) { + if (!bm->isFolder()) continue; + KPopupMenu *newMenu = new KPopupMenu(menu); + int id = menu->insertItem(QIconSet(krLoader->loadIcon(bm->icon(), KIcon::Small)), + bm->text(), newMenu, -1 /* dummy id */, -1 /* end of list */); + + if( !_bookmarkIDTable.find( menu ) ) + _bookmarkIDTable.insert( menu, new QMap ); + (*_bookmarkIDTable[ menu ])[ id ] = bm; + + ++inSecondaryMenu; + buildMenu(bm, newMenu); + --inSecondaryMenu; + } + for (KrBookmark *bm = parent->children().first(); bm; bm = parent->children().next()) { + if (bm->isFolder()) continue; + if (bm->isSeparator() ) { + menu->insertSeparator(); + continue; + } + int itemIndex = bm->plug(menu, -1 /* end of list */); + CONNECT_BM(bm); + + int id = bm->itemId( itemIndex ); + if( !_bookmarkIDTable.find( menu ) ) + _bookmarkIDTable.insert( menu, new QMap ); + (*_bookmarkIDTable[ menu ])[ id ] = bm; + } + + if (!inSecondaryMenu) { + krConfig->setGroup( "Private" ); + bool hasPopularURLs = krConfig->readBoolEntry( "BM Popular URLs", true ); + bool hasDevices = krConfig->readBoolEntry( "BM Devices", true ); + bool hasLan = krConfig->readBoolEntry( "BM Lan", true ); + bool hasVirtualFS = krConfig->readBoolEntry( "BM Virtual FS", true ); + bool hasJumpback = krConfig->readBoolEntry( "BM Jumpback", true ); + + int itemIndex; + + if( hasPopularURLs ) { + menu->insertSeparator(); + + // add the popular links submenu + KPopupMenu *newMenu = new KPopupMenu(menu); + itemIndex = menu->insertItem(QIconSet(krLoader->loadIcon("bookmark_folder", KIcon::Small)), + i18n("Popular URLs"), newMenu, -1 /* dummy id */, -1 /* end of list */); + _specialBookmarkIDs.append( itemIndex ); + // add the top 15 urls + #define MAX 15 + KURL::List list = krApp->popularUrls->getMostPopularUrls(MAX); + KURL::List::Iterator it; + for (it = list.begin(); it != list.end(); ++it) { + QString name; + if ((*it).isLocalFile()) name = (*it).path(); + else name = (*it).prettyURL(); + // note: these bookmark are put into the private collection + // as to not spam the general collection + KrBookmark *bm = KrBookmark::getExistingBookmark(name, _privateCollection); + if (!bm) + bm = new KrBookmark(name, *it, _privateCollection); + bm->plug(newMenu); + CONNECT_BM(bm); + } + + newMenu->insertSeparator(); + krPopularUrls->plug(newMenu); + newMenu->installEventFilter(this); + } + + // do we need to add special bookmarks? + if (SPECIAL_BOOKMARKS) { + if( hasDevices || hasLan || hasVirtualFS || hasJumpback ) + menu->insertSeparator(); + + KrBookmark *bm; + + // note: special bookmarks are not kept inside the _bookmarks list and added ad-hoc + if( hasDevices ) { + bm = KrBookmark::devices(_collection); + itemIndex = bm->plug(menu); + _specialBookmarkIDs.append( bm->itemId( itemIndex ) ); + CONNECT_BM(bm); + } + + if( hasLan ) { + bm = KrBookmark::lan(_collection); + itemIndex = bm->plug(menu); + _specialBookmarkIDs.append( bm->itemId( itemIndex ) ); + CONNECT_BM(bm); + } + + if( hasVirtualFS ) { + bm = KrBookmark::virt(_collection); + itemIndex = bm->plug(menu); + _specialBookmarkIDs.append( bm->itemId( itemIndex ) ); + CONNECT_BM(bm); + } + + if( hasJumpback ) { + // add the jump-back button + itemIndex = krJumpBack->plug(menu); + _specialBookmarkIDs.append( krJumpBack->itemId( itemIndex ) ); + menu->insertSeparator(); + itemIndex = krSetJumpBack->plug(menu); + _specialBookmarkIDs.append( krSetJumpBack->itemId( itemIndex ) ); + } + } + + if( !hasJumpback ) + menu->insertSeparator(); + + itemIndex = menu->insertItem(krLoader->loadIcon("bookmark_add", KIcon::Small), + i18n("Bookmark Current"), BookmarkCurrent); + _specialBookmarkIDs.append( itemIndex ); + itemIndex = menu->insertItem(krLoader->loadIcon("bookmark", KIcon::Small), + i18n("Manage Bookmarks"), ManageBookmarks); + _specialBookmarkIDs.append( itemIndex ); + + // make sure the menu is connected to us + disconnect(menu, SIGNAL(activated(int)), 0, 0); + connect(menu, SIGNAL(activated(int)), this, SLOT(menuOperation(int))); + } + + menu->installEventFilter(this); +} + +void KrBookmarkHandler::clearBookmarks(KrBookmark *root) { + KrBookmark *bm = root->children().first(); + while (bm) { + if (bm->isFolder()) + clearBookmarks(bm); + else { + bm->unplugAll(); + delete bm; + } + + bm = root->children().next(); + } + root->children().clear(); +} + +void KrBookmarkHandler::bookmarksChanged(const QString&, const QString&) { + importFromFile(); +} + +bool KrBookmarkHandler::eventFilter( QObject *obj, QEvent *ev ) { + if (ev->type() == QEvent::MouseButtonRelease) { + switch (static_cast(ev)->button()) { + case RightButton: + _middleClick = false; + if( obj->inherits( "QPopupMenu" ) ) { + int id = static_cast(obj)->idAt( static_cast(ev)->pos() ); + + if( obj == _mainBookmarkPopup && _specialBookmarkIDs.contains( id ) ) { + rightClickOnSpecialBookmark(); + return true; + } + + if( _bookmarkIDTable.find( obj ) ) { + QMap * table = _bookmarkIDTable[ obj ]; + if( table && table->count( id ) ) { + KrBookmark *bm = (*table)[ id ]; + rightClicked( static_cast(obj), id, bm ); + return true; + } + } + } + case LeftButton: + _middleClick = false; + break; + case MidButton: + _middleClick = true; + break; + default: + break; + } + } + return QObject::eventFilter(obj, ev); +} + +#define POPULAR_URLS_ID 100100 +#define DEVICES_ID 100101 +#define LAN_ID 100103 +#define VIRTUAL_FS_ID 100102 +#define JUMP_BACK_ID 100104 + +void KrBookmarkHandler::rightClickOnSpecialBookmark() { + krConfig->setGroup( "Private" ); + bool hasPopularURLs = krConfig->readBoolEntry( "BM Popular URLs", true ); + bool hasDevices = krConfig->readBoolEntry( "BM Devices", true ); + bool hasLan = krConfig->readBoolEntry( "BM Lan", true ); + bool hasVirtualFS = krConfig->readBoolEntry( "BM Virtual FS", true ); + bool hasJumpback = krConfig->readBoolEntry( "BM Jumpback", true ); + + QPopupMenu menu( _mainBookmarkPopup ); + menu.setCaption( i18n( "Enable special bookmarks" ) ); + menu.setCheckable( true ); + + menu.insertItem( i18n( "Popular URLs" ), POPULAR_URLS_ID ); + menu.setItemChecked( POPULAR_URLS_ID, hasPopularURLs ); + menu.insertItem( i18n( "Devices" ), DEVICES_ID ); + menu.setItemChecked( DEVICES_ID, hasDevices ); + menu.insertItem( i18n( "Local Network" ), LAN_ID ); + menu.setItemChecked( LAN_ID, hasLan ); + menu.insertItem( i18n( "Virtual Filesystem" ), VIRTUAL_FS_ID ); + menu.setItemChecked( VIRTUAL_FS_ID, hasVirtualFS ); + menu.insertItem( i18n( "Jump back" ), JUMP_BACK_ID ); + menu.setItemChecked( JUMP_BACK_ID, hasJumpback ); + + connect( _mainBookmarkPopup, SIGNAL( highlighted( int ) ), &menu, SLOT( close() ) ); + connect( _mainBookmarkPopup, SIGNAL( activated( int ) ), &menu, SLOT( close() ) ); + + int result = menu.exec( QCursor::pos() ); + bool doCloseMain = true; + + krConfig->setGroup( "Private" ); + + switch( result ) { + case POPULAR_URLS_ID: + krConfig->writeEntry( "BM Popular URLs", !hasPopularURLs ); + break; + case DEVICES_ID: + krConfig->writeEntry( "BM Devices", !hasDevices ); + break; + case LAN_ID: + krConfig->writeEntry( "BM Lan", !hasLan ); + break; + case VIRTUAL_FS_ID: + krConfig->writeEntry( "BM Virtual FS", !hasVirtualFS ); + break; + case JUMP_BACK_ID: + krConfig->writeEntry( "BM Jumpback", !hasJumpback ); + break; + default: + doCloseMain = false; + break; + } + + menu.close(); + + if( doCloseMain && _mainBookmarkPopup ) + _mainBookmarkPopup->close(); +} + +#define OPEN_ID 100200 +#define OPEN_NEW_TAB_ID 100201 +#define DELETE_ID 100202 + +void KrBookmarkHandler::rightClicked( QPopupMenu *menu, int /*id*/, KrBookmark * bm ) { + QPopupMenu popup( _mainBookmarkPopup ); + + popup.insertItem( krLoader->loadIcon( "fileopen", KIcon::Panel ), i18n( "Open" ), OPEN_ID ); + popup.insertItem( krLoader->loadIcon( "tab_new", KIcon::Panel ), i18n( "Open in a new tab" ), OPEN_NEW_TAB_ID ); + popup.insertSeparator(); + popup.insertItem( krLoader->loadIcon( "editdelete", KIcon::Panel ), i18n( "Delete" ), DELETE_ID ); + + connect( menu, SIGNAL( highlighted( int ) ), &popup, SLOT( close() ) ); + connect( menu, SIGNAL( activated( int ) ), &popup, SLOT( close() ) ); + + int result = popup.exec( QCursor::pos() ); + + popup.close(); + if( _mainBookmarkPopup && result >= OPEN_ID && result <= DELETE_ID ) { + _mainBookmarkPopup->close(); + } + + switch( result ) { + case OPEN_ID: + SLOTS->refresh( bm->url() ); + break; + case OPEN_NEW_TAB_ID: + SLOTS->newTab( bm->url() ); + break; + case DELETE_ID: + deleteBookmark( bm ); + break; + } +} + +// used to monitor middle clicks. if mid is found, then the +// bookmark is opened in a new tab. ugly, but easier than overloading +// KAction and KActionCollection. +void KrBookmarkHandler::slotActivated(const KURL& url) { + if (_middleClick) + SLOTS->newTab(url); + else SLOTS->refresh(url); +} + + +#include "krbookmarkhandler.moc" diff --git a/krusader/BookMan/krbookmarkhandler.h b/krusader/BookMan/krbookmarkhandler.h new file mode 100644 index 0000000..c6bd9d9 --- /dev/null +++ b/krusader/BookMan/krbookmarkhandler.h @@ -0,0 +1,63 @@ +#ifndef KRBOOKMARK_HANDLER_H +#define KRBOOKMARK_HANDLER_H + +#include "krbookmark.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class KActionCollection; +class KBookmarkManager; + +class KrBookmarkHandler: public QObject { + Q_OBJECT + friend class KrAddBookmarkDlg; + enum Actions { BookmarkCurrent=0, ManageBookmarks }; +public: + KrBookmarkHandler(); + ~KrBookmarkHandler(); + void populate(KPopupMenu *menu); + void addBookmark(KrBookmark *bm, KrBookmark *parent = 0); + void bookmarkCurrent(KURL url); + +protected: + void deleteBookmark(KrBookmark *bm); + void importFromFile(); + bool importFromFileBookmark(QDomElement &e, KrBookmark *parent, QString path, QString *errorMsg); + bool importFromFileFolder(QDomNode &first, KrBookmark *parent, QString path, QString *errorMsg); + void exportToFile(); + void exportToFileFolder(QDomDocument &doc, QDomElement &parent, KrBookmark *folder); + void exportToFileBookmark(QDomDocument &doc, QDomElement &where, KrBookmark *bm); + void clearBookmarks(KrBookmark *root); + void buildMenu(KrBookmark *parent, KPopupMenu *menu); + + bool eventFilter( QObject *obj, QEvent *ev ); + + void rightClicked( QPopupMenu *menu, int id, KrBookmark *bm ); + void rightClickOnSpecialBookmark(); + + void removeReferences( KrBookmark *root, KrBookmark *bmToRemove ); + +protected slots: + void menuOperation(int id); + void bookmarksChanged(const QString&, const QString&); + void slotActivated(const KURL& url); + +private: + KActionCollection *_collection, *_privateCollection; + KrBookmark *_root; + // the whole KBookmarkManager is an ugly hack. use it until we have our own + KBookmarkManager *manager; + bool _middleClick; // if true, the user clicked the middle button to open the bookmark + + QGuardedPtr _mainBookmarkPopup; // main bookmark popup menu + QValueList _specialBookmarkIDs; // the ID list of the special bookmarks + QPtrDict > _bookmarkIDTable; // the IDs of the bookmarks +}; + +#endif // KRBOOKMARK_HANDLER_H diff --git a/krusader/Dialogs/Makefile.am b/krusader/Dialogs/Makefile.am new file mode 100644 index 0000000..83cc13d --- /dev/null +++ b/krusader/Dialogs/Makefile.am @@ -0,0 +1,22 @@ +noinst_LIBRARIES = libDialogs.a + +INCLUDES = $(all_includes) + +libDialogs_a_METASOURCES = AUTO + +libDialogs_a_SOURCES = \ + krsqueezedtextlabel.cpp \ + krprogress.cpp \ + packgui.cpp \ + packguibase.cpp \ + newftpgui.cpp \ + krspwidgets.cpp \ + krspecialwidgets.cpp \ + krpleasewait.cpp \ + krmaskchoice.cpp \ + krdialogs.cpp \ + kurllistrequester.cpp \ + popularurls.cpp \ + checksumdlg.cpp \ + percentalsplitter.cpp \ + krkeydialog.cpp diff --git a/krusader/Dialogs/checksumdlg.cpp b/krusader/Dialogs/checksumdlg.cpp new file mode 100644 index 0000000..c79a66e --- /dev/null +++ b/krusader/Dialogs/checksumdlg.cpp @@ -0,0 +1,603 @@ +#include "checksumdlg.h" +#include "../krusader.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../krservices.h" +#include +#include +#include +#include + +class CS_Tool; // forward +typedef void PREPARE_PROC_FUNC(KProcess& proc, CS_Tool *self, const QStringList& files, + const QString checksumFile, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString& type=QString::null); +typedef QStringList GET_FAILED_FUNC(const QStringList& stdOut, const QStringList& stdErr); + +class CS_Tool { +public: + enum Type { + MD5=0, SHA1, SHA256, TIGER, WHIRLPOOL, SFV, CRC, + SHA224, SHA384, SHA512, + NumOfTypes + }; + + Type type; + QString binary; + bool recursive; + bool standardFormat; + PREPARE_PROC_FUNC *create, *verify; + GET_FAILED_FUNC *failed; +}; + +class CS_ToolByType { +public: + QPtrList tools, r_tools; // normal and recursive tools +}; + +// handles md5sum and sha1sum +void sumCreateFunc(KProcess& proc, CS_Tool *self, const QStringList& files, + const QString, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString&) { + proc.setUseShell(true, "/bin/bash"); + proc << KrServices::fullPathName( self->binary ); + Q_ASSERT(!recursive); + proc << files << "1>" << stdoutFileName << "2>" << stderrFileName; +} + +void sumVerifyFunc(KProcess& proc, CS_Tool *self, const QStringList& /* files */, + const QString checksumFile, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString& /* type */) { + proc.setUseShell(true, "/bin/bash"); + proc << KrServices::fullPathName( self->binary ); + Q_ASSERT(!recursive); + proc << "-c" << checksumFile << "1>" << stdoutFileName << "2>" << stderrFileName; +} + +QStringList sumFailedFunc(const QStringList& stdOut, const QStringList& stdErr) { + // md5sum and sha1sum print "...: FAILED" for failed files and display + // the number of failures to stderr. so if stderr is empty, we'll assume all is ok + QStringList result; + if (stdErr.size()==0) return result; + result += stdErr; + // grep for the ":FAILED" substring + const QString tmp = QString(": FAILED").local8Bit(); + for (uint i=0; ibinary ); + if (recursive) proc << "-r"; + proc << "-l" << files << "1>" << stdoutFileName << "2>" << stderrFileName; +} + +void deepVerifyFunc(KProcess& proc, CS_Tool *self, const QStringList& files, + const QString checksumFile, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString&) { + proc.setUseShell(true, "/bin/bash"); + proc << KrServices::fullPathName( self->binary ); + if (recursive) proc << "-r"; + proc << "-x" << checksumFile << files << "1>" << stdoutFileName << "2>" << stderrFileName; +} + +QStringList deepFailedFunc(const QStringList& stdOut, const QStringList&/* stdErr */) { + // *deep dumps (via -x) all failed hashes to stdout + return stdOut; +} + +// handles cfv binary +void cfvCreateFunc(KProcess& proc, CS_Tool *self, const QStringList& files, + const QString, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString& type) { + proc.setUseShell(true, "/bin/bash"); + proc << KrServices::fullPathName( self->binary ) << "-C" << "-VV"; + if (recursive) proc << "-rr"; + proc << "-t" << type << "-f-" << "-U" << files << "1>" << stdoutFileName << "2>" << stderrFileName; +} + +void cfvVerifyFunc(KProcess& proc, CS_Tool *self, const QStringList& /* files */, + const QString checksumFile, bool recursive, const QString& stdoutFileName, + const QString& stderrFileName, const QString&type) { + proc.setUseShell(true, "/bin/bash"); + proc << KrServices::fullPathName( self->binary ) << "-M"; + if (recursive) proc << "-rr"; + proc << "-U" << "-VV" << "-t" << type << "-f" << checksumFile << "1>" << stdoutFileName << "2>" << stderrFileName;// << files; +} + +QStringList cfvFailedFunc(const QStringList& /* stdOut */, const QStringList& stdErr) { + // cfv dumps all failed hashes to stderr + return stdErr; +} + +// important: this table should be ordered like so that all md5 tools should be +// one after another, and then all sha1 and so on and so forth. they tools must be grouped, +// since the code in getTools() counts on it! +CS_Tool cs_tools[] = { + // type binary recursive stdFmt create_func verify_func failed_func + {CS_Tool::MD5, "md5sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::MD5, "md5deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc}, + {CS_Tool::MD5, "cfv", true, true, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc}, + {CS_Tool::SHA1, "sha1sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::SHA1, "sha1deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc}, + {CS_Tool::SHA1, "cfv", true, true, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc}, + {CS_Tool::SHA224, "sha224sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::SHA256, "sha256sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::SHA256, "sha256deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc}, + {CS_Tool::SHA384, "sha384sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::SHA512, "sha512sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc}, + {CS_Tool::TIGER, "tigerdeep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc}, + {CS_Tool::WHIRLPOOL, "whirlpooldeep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc}, + {CS_Tool::SFV, "cfv", true, false, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc}, + {CS_Tool::CRC, "cfv", true, false, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc}, +}; + +QMap cs_textToType; +QMap cs_typeToText; + +void initChecksumModule() { + // prepare the dictionaries - pity it has to be manually + cs_textToType["md5"]=CS_Tool::MD5; + cs_textToType["sha1"]=CS_Tool::SHA1; + cs_textToType["sha256"]=CS_Tool::SHA256; + cs_textToType["sha224"]=CS_Tool::SHA224; + cs_textToType["sha384"]=CS_Tool::SHA384; + cs_textToType["sha512"]=CS_Tool::SHA512; + cs_textToType["tiger"]=CS_Tool::TIGER; + cs_textToType["whirlpool"]=CS_Tool::WHIRLPOOL; + cs_textToType["sfv"]=CS_Tool::SFV; + cs_textToType["crc"]=CS_Tool::CRC; + + cs_typeToText[CS_Tool::MD5]="md5"; + cs_typeToText[CS_Tool::SHA1]="sha1"; + cs_typeToText[CS_Tool::SHA256]="sha256"; + cs_typeToText[CS_Tool::SHA224]="sha224"; + cs_typeToText[CS_Tool::SHA384]="sha384"; + cs_typeToText[CS_Tool::SHA512]="sha512"; + cs_typeToText[CS_Tool::TIGER]="tiger"; + cs_typeToText[CS_Tool::WHIRLPOOL]="whirlpool"; + cs_typeToText[CS_Tool::SFV]="sfv"; + cs_typeToText[CS_Tool::CRC]="crc"; + + // build the checksumFilter (for usage in KRQuery) + QMap::Iterator it; + for (it=cs_textToType.begin(); it!=cs_textToType.end(); ++it) + MatchChecksumDlg::checksumTypesFilter += ("*."+it.key()+" "); +} + +// -------------------------------------------------- + +// returns a list of tools which can work with recursive or non-recursive mode and are installed +// note: only 1 tool from each type is suggested +static QPtrList getTools(bool folders) { + QPtrList result; + uint i; + for (i=0; i < sizeof(cs_tools)/sizeof(CS_Tool); ++i) { + if (result.last() && result.last()->type == cs_tools[i].type) continue; // 1 from each type please + if (folders && !cs_tools[i].recursive) continue; + if (KrServices::cmdExist(cs_tools[i].binary)) + result.append(&cs_tools[i]); + } + + return result; +} + +// ------------- CreateChecksumDlg + +CreateChecksumDlg::CreateChecksumDlg(const QStringList& files, bool containFolders, const QString& path): + KDialogBase(Plain, i18n("Create Checksum"), Ok | Cancel, Ok, krApp) { + + QPtrList tools = getTools(containFolders); + + if (tools.count() == 0) { // nothing was suggested?! + QString error = i18n("Can't calculate checksum since no supported tool was found. " + "Please check the Dependencies page in Krusader's settings."); + if (containFolders) + error += i18n("Note: you've selected directories, and probably have no recursive checksum tool installed." + " Krusader currently supports md5deep, sha1deep, sha256deep, tigerdeep and cfv"); + KMessageBox::error(0, error); + return; + } + + QGridLayout *layout = new QGridLayout( plainPage(), 1, 1, + KDialogBase::marginHint(), KDialogBase::spacingHint()); + + int row=0; + + // title (icon+text) + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel *p = new QLabel(plainPage()); + p->setPixmap(krLoader->loadIcon("binary", KIcon::Desktop, 32)); + hlayout->addWidget(p); + QLabel *l1 = new QLabel(i18n("About to calculate checksum for the following files") + + (containFolders ? i18n(" and folders:") : ":"), plainPage()); + hlayout->addWidget(l1); + layout->addMultiCellLayout(hlayout, row, row, 0, 1, Qt::AlignLeft); + ++row; + + // file list + KListBox *lb = new KListBox(plainPage()); + lb->insertStringList(files); + layout->addMultiCellWidget(lb, row, row, 0, 1); + ++row; + + // checksum method + QHBoxLayout *hlayout2 = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel *l2 = new QLabel(i18n("Select the checksum method:"), plainPage()); + hlayout2->addWidget(l2); + KComboBox *method = new KComboBox(plainPage()); + // -- fill the combo with available methods + uint i; + for ( i=0; iinsertItem( cs_typeToText[tools.at(i)->type], i); + method->setFocus(); + hlayout2->addWidget(method); + layout->addMultiCellLayout(hlayout2, row, row, 0, 1, Qt::AlignLeft); + ++row; + + if (exec() != Accepted) return; + // else implied: run the process + tmpOut = new KTempFile(locateLocal("tmp", "krusader"), ".stdout" ); + tmpErr = new KTempFile(locateLocal("tmp", "krusader"), ".stderr" ); + KProcess proc; + CS_Tool *mytool = tools.at(method->currentItem()); + mytool->create(proc, mytool, KrServices::quote(files), QString::null, containFolders, + tmpOut->name(), tmpErr->name(), method->currentText()); + + krApp->startWaiting(i18n("Calculating checksums ..."), 0, true); + QApplication::setOverrideCursor( KCursor::waitCursor() ); + bool r = proc.start(KProcess::NotifyOnExit, KProcess::AllOutput); + if (r) while ( proc.isRunning() ) { + usleep( 500 ); + qApp->processEvents(); + if (krApp->wasWaitingCancelled()) { // user cancelled + proc.kill(); + QApplication::restoreOverrideCursor(); + return; + } + }; + krApp->stopWait(); + QApplication::restoreOverrideCursor(); + if (!r || !proc.normalExit()) { + KMessageBox::error(0, i18n("There was an error while running %1.").arg(mytool->binary)); + return; + } + + // suggest a filename + QString suggestedFilename = path + '/'; + if (files.count() > 1) suggestedFilename += ("checksum." + cs_typeToText[mytool->type]); + else suggestedFilename += (files[0] + '.' + cs_typeToText[mytool->type]); + // send both stdout and stderr + QStringList stdOut, stdErr; + if (!KrServices::fileToStringList(tmpOut->textStream(), stdOut) || + !KrServices::fileToStringList(tmpErr->textStream(), stdErr)) { + KMessageBox::error(krApp, i18n("Error reading stdout or stderr")); + return; + } + + ChecksumResultsDlg dlg( stdOut, stdErr, suggestedFilename, mytool->binary, cs_typeToText[mytool->type], mytool->standardFormat); + tmpOut->unlink(); delete tmpOut; + tmpErr->unlink(); delete tmpErr; +} + +// ------------- MatchChecksumDlg + +QString MatchChecksumDlg::checksumTypesFilter; + +MatchChecksumDlg::MatchChecksumDlg(const QStringList& files, bool containFolders, + const QString& path, const QString& checksumFile): + KDialogBase(Plain, i18n("Verify Checksum"), Ok | Cancel, Ok, krApp) { + + QPtrList tools = getTools(containFolders); + + if (tools.count() == 0) { // nothing was suggested?! + QString error = i18n("Can't verify checksum since no supported tool was found. " + "Please check the Dependencies page in Krusader's settings."); + if (containFolders) + error += i18n("Note: you've selected directories, and probably have no recursive checksum tool installed." + " Krusader currently supports md5deep, sha1deep, sha256deep, tigerdeep and cfv"); + KMessageBox::error(0, error); + return; + } + + QGridLayout *layout = new QGridLayout( plainPage(), 1, 1, + KDialogBase::marginHint(), KDialogBase::spacingHint()); + + int row=0; + + // title (icon+text) + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel *p = new QLabel(plainPage()); + p->setPixmap(krLoader->loadIcon("binary", KIcon::Desktop, 32)); + hlayout->addWidget(p); + QLabel *l1 = new QLabel(i18n("About to verify checksum for the following files") + + (containFolders ? i18n(" and folders:") : ":"), plainPage()); + hlayout->addWidget(l1); + layout->addMultiCellLayout(hlayout, row, row, 0, 1, Qt::AlignLeft); + ++row; + + // file list + KListBox *lb = new KListBox(plainPage()); + lb->insertStringList(files); + layout->addMultiCellWidget(lb, row, row, 0, 1); + ++row; + + // checksum file + QHBoxLayout *hlayout2 = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel *l2 = new QLabel(i18n("Checksum file:"), plainPage()); + hlayout2->addWidget(l2); + KURLRequester *checksumFileReq = new KURLRequester( plainPage() ); + if (!checksumFile.isEmpty()) + checksumFileReq->setURL(checksumFile); + checksumFileReq->fileDialog()->setURL(path); + checksumFileReq->setFocus(); + hlayout2->addWidget(checksumFileReq); + layout->addMultiCellLayout(hlayout2, row, row, 0, 1, Qt::AlignLeft); + + if (exec() != Accepted) return; + QString file = checksumFileReq->url(); + QString extension; + if (!verifyChecksumFile(file, extension)) { + KMessageBox::error(0, i18n("Error reading checksum file %1.
Please specify a valid checksum file.
").arg(file)); + return; + } + + // do we have a tool for that extension? + uint i; + CS_Tool *mytool = 0; + for ( i=0; i < tools.count(); ++i ) + if (cs_typeToText[tools.at(i)->type] == extension.lower()) { + mytool = tools.at(i); + break; + } + if (!mytool) { + KMessageBox::error(0, i18n("Krusader can't find a checksum tool that handles %1 on your system. Please check the Dependencies page in Krusader's settings.").arg(extension)); + return; + } + + // else implied: run the process + tmpOut = new KTempFile(locateLocal("tmp", "krusader"), ".stdout" ); + tmpErr = new KTempFile(locateLocal("tmp", "krusader"), ".stderr" ); + KProcess proc; + mytool->verify(proc, mytool, KrServices::quote(files), KrServices::quote(file), containFolders, tmpOut->name(), tmpErr->name(), extension); + krApp->startWaiting(i18n("Verifying checksums ..."), 0, true); + QApplication::setOverrideCursor( KCursor::waitCursor() ); + bool r = proc.start(KProcess::NotifyOnExit, KProcess::AllOutput); + if (r) while ( proc.isRunning() ) { + usleep( 500 ); + qApp->processEvents(); + if (krApp->wasWaitingCancelled()) { // user cancelled + proc.kill(); + QApplication::restoreOverrideCursor(); + return; + } + }; + if (!r || !proc.normalExit()) { + KMessageBox::error(0, i18n("There was an error while running %1.").arg(mytool->binary)); + return; + } + QApplication::restoreOverrideCursor(); + krApp->stopWait(); + // send both stdout and stderr + QStringList stdOut,stdErr; + if (!KrServices::fileToStringList(tmpOut->textStream(), stdOut) || + !KrServices::fileToStringList(tmpErr->textStream(), stdErr)) { + KMessageBox::error(krApp, i18n("Error reading stdout or stderr")); + return; + } + VerifyResultDlg dlg(mytool->failed(stdOut, stdErr)); + tmpOut->unlink(); delete tmpOut; + tmpErr->unlink(); delete tmpErr; +} + +bool MatchChecksumDlg::verifyChecksumFile(QString path, QString& extension) { + QFileInfo f(path); + if (!f.exists() || f.isDir()) return false; + // find the extension + extension = path.mid(path.findRev(".")+1); + + // TODO: do we know the extension? if not, ask the user for one + + + return true; +} + +// ------------- VerifyResultDlg +VerifyResultDlg::VerifyResultDlg(const QStringList& failed): + KDialogBase(Plain, i18n("Verify Checksum"), Close, Close, krApp) { + QGridLayout *layout = new QGridLayout( plainPage(), 1, 1, + KDialogBase::marginHint(), KDialogBase::spacingHint()); + + bool errors = failed.size()>0; + int row = 0; + + // create the icon and title + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel p(plainPage()); + p.setPixmap(krLoader->loadIcon(errors ? "messagebox_critical" : "messagebox_info", KIcon::Desktop, 32)); + hlayout->addWidget(&p); + + QLabel *l1 = new QLabel((errors ? i18n("Errors were detected while verifying the checksums") : + i18n("Checksums were verified successfully")), plainPage()); + hlayout->addWidget(l1); + layout->addMultiCellLayout(hlayout,row,row,0,1, Qt::AlignLeft); + ++row; + + if (errors) { + QLabel *l3 = new QLabel(i18n("The following files have failed:"), plainPage()); + layout->addMultiCellWidget(l3, row, row, 0, 1); + ++row; + KListBox *lb2 = new KListBox(plainPage()); + lb2->insertStringList(failed); + layout->addMultiCellWidget(lb2, row, row, 0, 1); + ++row; + } + + exec(); +} + +// ------------- ChecksumResultsDlg + +ChecksumResultsDlg::ChecksumResultsDlg(const QStringList& stdOut, const QStringList& stdErr, + const QString& suggestedFilename, const QString& binary, const QString& /* type */, bool standardFormat): + KDialogBase(Plain, i18n("Create Checksum"), Ok | Cancel, Ok, krApp), _binary(binary) { + QGridLayout *layout = new QGridLayout( plainPage(), 1, 1, + KDialogBase::marginHint(), KDialogBase::spacingHint()); + + // md5 tools display errors into stderr, so we'll use that to determine the result of the job + bool errors = stdErr.size()>0; + bool successes = stdOut.size()>0; + int row = 0; + + // create the icon and title + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialogBase::spacingHint()); + QLabel p(plainPage()); + p.setPixmap(krLoader->loadIcon(errors ? "messagebox_critical" : "messagebox_info", KIcon::Desktop, 32)); + hlayout->addWidget(&p); + + QLabel *l1 = new QLabel((errors ? i18n("Errors were detected while creating the checksums") : + i18n("Checksums were created successfully")), plainPage()); + hlayout->addWidget(l1); + layout->addMultiCellLayout(hlayout,row,row,0,1, Qt::AlignLeft); + ++row; + + if (successes) { + if (errors) { + QLabel *l2 = new QLabel(i18n("Here are the calculated checksums:"), plainPage()); + layout->addMultiCellWidget(l2, row, row, 0, 1); + ++row; + } + KListView *lv = new KListView(plainPage()); + if(standardFormat){ + lv->addColumn(i18n("Hash")); + lv->addColumn(i18n("File")); + lv->setAllColumnsShowFocus(true); + } else { + lv->addColumn(i18n("File and hash")); + } + for ( QStringList::ConstIterator it = stdOut.begin(); it != stdOut.end(); ++it ) { + QString line = (*it); + if(standardFormat) { + int space = line.find(' '); + new KListViewItem(lv, line.left(space), line.mid(space+2)); + } else { + new KListViewItem(lv, line); + } + } + layout->addMultiCellWidget(lv, row, row, 0, 1); + ++row; + } + + if (errors) { + QFrame *line1 = new QFrame( plainPage() ); + line1->setGeometry( QRect( 60, 210, 501, 20 ) ); + line1->setFrameShape( QFrame::HLine ); + line1->setFrameShadow( QFrame::Sunken ); + layout->addMultiCellWidget(line1, row, row, 0, 1); + ++row; + + QLabel *l3 = new QLabel(i18n("Here are the errors received:"), plainPage()); + layout->addMultiCellWidget(l3, row, row, 0, 1); + ++row; + KListBox *lb = new KListBox(plainPage()); + lb->insertStringList(stdErr); + layout->addMultiCellWidget(lb, row, row, 0, 1); + ++row; + } + + // save checksum to disk, if any hashes are found + KURLRequester *checksumFile=0; + QCheckBox *saveFileCb=0; + if (successes) { + QHBoxLayout *hlayout2 = new QHBoxLayout(layout, KDialogBase::spacingHint()); + saveFileCb = new QCheckBox(i18n("Save checksum to file:"), plainPage()); + saveFileCb->setChecked(true); + hlayout2->addWidget(saveFileCb); + + checksumFile = new KURLRequester( suggestedFilename, plainPage() ); + hlayout2->addWidget(checksumFile, Qt::AlignLeft); + layout->addMultiCellLayout(hlayout2, row, row,0,1, Qt::AlignLeft); + ++row; + connect(saveFileCb, SIGNAL(toggled(bool)), checksumFile, SLOT(setEnabled(bool))); + checksumFile->setFocus(); + } + + QCheckBox *onePerFile=0; + if (stdOut.size() > 1 && standardFormat) { + onePerFile = new QCheckBox(i18n("Checksum file for each source file"), plainPage()); + onePerFile->setChecked(false); + // clicking this, disables the 'save as' part + connect(onePerFile, SIGNAL(toggled(bool)), saveFileCb, SLOT(toggle())); + connect(onePerFile, SIGNAL(toggled(bool)), saveFileCb, SLOT(setDisabled(bool))); + connect(onePerFile, SIGNAL(toggled(bool)), checksumFile, SLOT(setDisabled(bool))); + layout->addMultiCellWidget(onePerFile, row, row,0,1, Qt::AlignLeft); + ++row; + } + + if (exec() == Accepted && successes) { + if (stdOut.size()>1 && standardFormat && onePerFile->isChecked()) { + savePerFile(stdOut, suggestedFilename.mid(suggestedFilename.findRev('.'))); + } else if (saveFileCb->isEnabled() && saveFileCb->isChecked() && !checksumFile->url().simplifyWhiteSpace().isEmpty()) { + saveChecksum(stdOut, checksumFile->url()); + } + } +} + +bool ChecksumResultsDlg::saveChecksum(const QStringList& data, QString filename) { + if (QFile::exists(filename) && + KMessageBox::warningContinueCancel(this, + i18n("File %1 already exists.\nAre you sure you want to overwrite it?").arg(filename), + i18n("Warning"), i18n("Overwrite")) != KMessageBox::Continue) { + // find a better name to save to + filename = KFileDialog::getSaveFileName(QString::null, "*", 0, i18n("Select a file to save to")); + if (filename.simplifyWhiteSpace().isEmpty()) return false; + } + QFile file(filename); + if (!file.open(IO_WriteOnly)) { + KMessageBox::detailedError(0, i18n("Error saving file %1").arg(filename), + file.errorString()); + return false; + } + QTextStream stream(&file); + for ( QStringList::ConstIterator it = data.constBegin(); it != data.constEnd(); ++it) + stream << *it << "\n"; + file.close(); + return true; +} + +void ChecksumResultsDlg::savePerFile(const QStringList& data, const QString& type) { + krApp->startWaiting(i18n("Saving checksum files..."), 0); + for ( QStringList::ConstIterator it = data.begin(); it != data.end(); ++it ) { + QString line = (*it); + QString filename = line.mid(line.find(' ')+2)+type; + if (!saveChecksum(*it, filename)) { + KMessageBox::error(0, i18n("Errors occured while saving multiple checksums. Stopping")); + krApp->stopWait(); + return; + } + } + krApp->stopWait(); +} diff --git a/krusader/Dialogs/checksumdlg.h b/krusader/Dialogs/checksumdlg.h new file mode 100644 index 0000000..41bb1ad --- /dev/null +++ b/krusader/Dialogs/checksumdlg.h @@ -0,0 +1,54 @@ +#ifndef CHECKSUMDLG_H +#define CHECKSUMDLG_H + +#include +#include + +class KTempFile; +extern void initChecksumModule(); + +class CreateChecksumDlg: public KDialogBase { +public: + CreateChecksumDlg(const QStringList& files, bool containFolders, const QString& path); + +private: + KTempFile *tmpOut, *tmpErr; +}; + + +class MatchChecksumDlg: public KDialogBase { +public: + MatchChecksumDlg(const QStringList& files, bool containFolders, + const QString& path, const QString& checksumFile=QString::null); + + static QString checksumTypesFilter; + +protected: + bool verifyChecksumFile(QString path, QString& extension); + +private: + KTempFile *tmpOut, *tmpErr; +}; + + +class ChecksumResultsDlg: public KDialogBase { +public: + ChecksumResultsDlg(const QStringList& stdOut, const QStringList& stdErr, + const QString& suggestedFilename, const QString& binary, const QString& type, + bool standardFormat); + +protected: + bool saveChecksum(const QStringList& data, QString filename); + void savePerFile(const QStringList& data, const QString& type); + +private: + QString _binary; +}; + + +class VerifyResultDlg: public KDialogBase { +public: + VerifyResultDlg(const QStringList& failed); +}; + +#endif // CHECKSUMDLG_H diff --git a/krusader/Dialogs/krdialogs.cpp b/krusader/Dialogs/krdialogs.cpp new file mode 100644 index 0000000..cbcc294 --- /dev/null +++ b/krusader/Dialogs/krdialogs.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** + krdialogs.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +// Krusader includes +#include "krdialogs.h" +// QT includes +#include +#include +#include +#include +#include +// KDE includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// Krusader includes +#include "../krusader.h" +#include "../resources.h" +#include "../VFS/vfs.h" +#include "../defaults.h" +#include + +KURL KChooseDir::getDir(QString text,const KURL& url, const KURL& cwd) { + KURLRequesterDlg *dlg = new KURLRequesterDlg( vfs::pathOrURL( url, 1 ),text,krApp,""); + dlg->urlRequester()->completionObject()->setDir(cwd.url()); + KURL u; + if (dlg->exec() == QDialog::Accepted) { + u = vfs::fromPathOrURL(dlg->urlRequester()->completionObject()->replacedPath( + dlg->urlRequester()->lineEdit()->text())); + if (u.isRelativeURL(u.url())) { + KURL temp = u; + u = cwd; + u.addPath(temp.url()); + u.cleanPath(); + if( u.protocol() == "zip" || u.protocol() == "krarc" || u.protocol() == "tar" || u.protocol() == "iso" ) { + if( QDir( u.path() ).exists() ) + u.setProtocol( "file" ); + } + } + } + delete dlg; + return u; +} + +KURL KChooseDir::getDir(QString text,const KURL& url, const KURL& cwd, bool &preserveAttrs ) { + KURLRequesterDlgForCopy *dlg = new KURLRequesterDlgForCopy( vfs::pathOrURL( url, 1 ),text, preserveAttrs, krApp,"" ); + dlg->urlRequester()->completionObject()->setDir(cwd.url()); + KURL u; + if (dlg->exec() == QDialog::Accepted) { + u = vfs::fromPathOrURL(dlg->urlRequester()->completionObject()->replacedPath( + dlg->urlRequester()->lineEdit()->text())); + if (u.isRelativeURL(u.url())) { + KURL temp = u; + u = cwd; + u.addPath(temp.url()); + u.cleanPath(); + if( u.protocol() == "zip" || u.protocol() == "krarc" || u.protocol() == "tar" || u.protocol() == "iso" ) { + if( QDir( u.path() ).exists() ) + u.setProtocol( "file" ); + } + } + } + preserveAttrs = dlg->preserveAttrs(); + delete dlg; + return u; +} + +KURL KChooseDir::getDir(QString text,const KURL& url, const KURL& cwd, bool &preserveAttrs, KURL &baseURL ) { + KURLRequesterDlgForCopy *dlg = new KURLRequesterDlgForCopy( vfs::pathOrURL( url, 1 ),text, preserveAttrs, krApp,"", true, baseURL ); + dlg->urlRequester()->completionObject()->setDir(cwd.url()); + KURL u; + if (dlg->exec() == QDialog::Accepted) { + u = vfs::fromPathOrURL(dlg->urlRequester()->completionObject()->replacedPath( + dlg->urlRequester()->lineEdit()->text())); + if (u.isRelativeURL(u.url())) { + KURL temp = u; + u = cwd; + u.addPath(temp.url()); + u.cleanPath(); + if( u.protocol() == "zip" || u.protocol() == "krarc" || u.protocol() == "tar" || u.protocol() == "iso" ) { + if( QDir( u.path() ).exists() ) + u.setProtocol( "file" ); + } + } + + if( dlg->copyDirStructure() ) { + baseURL = dlg->baseURL(); + } else { + baseURL = KURL(); + } + } + preserveAttrs = dlg->preserveAttrs(); + delete dlg; + return u; +} + +KURLRequesterDlgForCopy::KURLRequesterDlgForCopy( const QString& urlName, const QString& _text, bool presAttrs, QWidget *parent, + const char *name, bool modal, KURL baseURL ) + : KDialogBase( Plain, QString::null, Ok|Cancel|User1, Ok, parent, name, modal, true, KStdGuiItem::clear() ), + baseUrlCombo( 0 ), copyDirStructureCB( 0 ) { + + QVBoxLayout * topLayout = new QVBoxLayout( plainPage(), 0, spacingHint() ); + + QLabel * label = new QLabel( _text, plainPage() ); + topLayout->addWidget( label ); + + urlRequester_ = new KURLRequester( urlName, plainPage(), "urlRequester" ); + urlRequester_->setMinimumWidth( urlRequester_->sizeHint().width() * 3 ); + topLayout->addWidget( urlRequester_ ); + preserveAttrsCB = new QCheckBox(i18n("Preserve attributes (only for local targets)"), plainPage()); + preserveAttrsCB->setChecked( presAttrs ); + topLayout->addWidget( preserveAttrsCB ); + if( !baseURL.isEmpty() ) { + QFrame *line = new QFrame( plainPage(), "sepLine" ); + line->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + topLayout->addWidget( line ); + copyDirStructureCB = new QCheckBox(i18n("Keep virtual directory structure"), plainPage()); + connect( copyDirStructureCB, SIGNAL( toggled( bool ) ), this, SLOT( slotDirStructCBChanged() ) ); + copyDirStructureCB->setChecked( false ); + topLayout->addWidget( copyDirStructureCB ); + QHBox * hbox = new QHBox( plainPage(), "copyDirStructure" ); + new QLabel( i18n("Base URL:"), hbox, "baseURLLabel" ); + + baseUrlCombo = new QComboBox( hbox, "baseUrlRequester" ); + baseUrlCombo->setMinimumWidth( baseUrlCombo->sizeHint().width() * 3 ); + baseUrlCombo->setEnabled( copyDirStructureCB->isChecked() ); + KURL temp = baseURL, tempOld; + do { + QString baseURLText = vfs::pathOrURL( temp ); + baseUrlCombo->insertItem( baseURLText ); + tempOld = temp; + temp = temp.upURL(); + }while( !tempOld.equals( temp, true ) ); + baseUrlCombo->setCurrentItem( 0 ); + + topLayout->addWidget( hbox ); + } + urlRequester_->setFocus(); + connect( urlRequester_->lineEdit(), SIGNAL(textChanged(const QString&)), + SLOT(slotTextChanged(const QString&)) ); + bool state = !urlName.isEmpty(); + enableButtonOK( state ); + enableButton( KDialogBase::User1, state ); + connect( this, SIGNAL( user1Clicked() ), SLOT( slotClear() ) ); +} + +KURLRequesterDlgForCopy::KURLRequesterDlgForCopy() { +} + +bool KURLRequesterDlgForCopy::preserveAttrs() { + return preserveAttrsCB->isChecked(); +} + +bool KURLRequesterDlgForCopy::copyDirStructure() { + if( copyDirStructureCB == 0 ) + return false; + return copyDirStructureCB->isChecked(); +} + +void KURLRequesterDlgForCopy::slotTextChanged(const QString & text) { + bool state = !text.stripWhiteSpace().isEmpty(); + enableButtonOK( state ); + enableButton( KDialogBase::User1, state ); +} + +void KURLRequesterDlgForCopy::slotClear() { + urlRequester_->clear(); +} + +void KURLRequesterDlgForCopy::slotDirStructCBChanged() { + baseUrlCombo->setEnabled( copyDirStructureCB->isChecked() ); +} + +KURL KURLRequesterDlgForCopy::selectedURL() const { + if ( result() == QDialog::Accepted ) { + KURL url = KURL::fromPathOrURL( urlRequester_->url() ); + if( url.isValid() ) + KRecentDocument::add(url); + return url; + } + else + return KURL(); +} + +KURLRequester * KURLRequesterDlgForCopy::urlRequester() { + return urlRequester_; +} + +KURL KURLRequesterDlgForCopy::baseURL() const { + if( baseUrlCombo == 0 ) + return KURL(); + return vfs::fromPathOrURL( baseUrlCombo->currentText() ); +} + +KRGetDate::KRGetDate(QDate date, QWidget *parent, const char *name) : KDialog(parent, name,true,WStyle_DialogBorder) { + dateWidget = new KDatePicker(this, date); + dateWidget->resize(dateWidget->sizeHint()); + setMinimumSize(dateWidget->sizeHint()); + setMaximumSize(dateWidget->sizeHint()); + resize(minimumSize()); + connect(dateWidget, SIGNAL(dateSelected(QDate)), this, SLOT(setDate(QDate))); + connect(dateWidget, SIGNAL(dateEntered(QDate)), this, SLOT(setDate(QDate))); + + // keep the original date - incase ESC is pressed + originalDate = date; +} + +QDate KRGetDate::getDate() { + if (exec() == QDialog::Rejected) chosenDate.setYMD(0,0,0); + hide(); + return chosenDate; +} + +void KRGetDate::setDate(QDate date) { + chosenDate = date; + accept(); +} + +#include "krdialogs.moc" diff --git a/krusader/Dialogs/krdialogs.h b/krusader/Dialogs/krdialogs.h new file mode 100644 index 0000000..9f85131 --- /dev/null +++ b/krusader/Dialogs/krdialogs.h @@ -0,0 +1,115 @@ +/*************************************************************************** + krdialogs.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + email : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KCHOSEDIR_H +#define KCHOSEDIR_H + +// KDE includes +#include +#include +#include +#include +#include +// QT includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** \class KChooseDir + * Used for asking the user for a folder. + * example: + * \code + * KURL u = KChooseDir::getDir("target folder", "/suggested/path", ACTIVE_PANEL->virtualPath()); + * if (u.isEmpty()) { + * // user canceled (either by pressing cancel, or esc + * } else { + * // do you thing here: you've got a safe url to use + * } + * \endcode + */ +class KChooseDir { +public: + /** + * \param text - description of the info requested from the user + * \param url - a suggested url to appear in the box as a default choice + * \param cwd - a path which is the current working directory (usually ACTIVE_PANEL->virtualPath()). + * this is used for completion of partial urls + */ + static KURL getDir(QString text,const KURL& url, const KURL& cwd); + static KURL getDir(QString text,const KURL& url, const KURL& cwd, bool & preserveAttrs ); + static KURL getDir(QString text,const KURL& url, const KURL& cwd, bool & preserveAttrs, KURL &baseURL ); +}; + +class KURLRequesterDlgForCopy : public KDialogBase { + Q_OBJECT +public: + KURLRequesterDlgForCopy( const QString& url, const QString& text, bool presAttrs, + QWidget *parent, const char *name, bool modal=true, KURL baseURL = KURL() ); + KURLRequesterDlgForCopy(); + + KURL selectedURL() const; + KURL baseURL() const; + bool preserveAttrs(); + bool copyDirStructure(); + + KURLRequester *urlRequester(); +private slots: + void slotClear(); + void slotTextChanged(const QString &); + void slotDirStructCBChanged(); +private: + KURLRequester *urlRequester_; + QComboBox *baseUrlCombo; + QCheckBox *preserveAttrsCB; + QCheckBox *copyDirStructureCB; +}; + +class KRGetDate : public KDialog { + Q_OBJECT +public: + KRGetDate(QDate date=QDate::currentDate(), QWidget *parent = 0, const char *name = 0); + QDate getDate(); + +private slots: + void setDate(QDate); + +private: + KDatePicker *dateWidget; + QDate chosenDate, originalDate; +}; + +#endif diff --git a/krusader/Dialogs/krkeydialog.cpp b/krusader/Dialogs/krkeydialog.cpp new file mode 100644 index 0000000..70e6273 --- /dev/null +++ b/krusader/Dialogs/krkeydialog.cpp @@ -0,0 +1,157 @@ +// +// C++ Implementation: krkeydialog +// +// Description: +// +// +// Author: Jonas Bähr , (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "krkeydialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../krusader.h" + +//This is the filter in the KFileDialog of Import/Export: +static const char* FILE_FILTER = I18N_NOOP("*.keymap|Krusader keymaps\n*|all files"); + + +KrKeyDialog::KrKeyDialog( QWidget * parent ) : KKeyDialog( false /* allow letter shortcuts */, parent ) { + insert( krApp->actionCollection() ); + + // HACK This fetches the layout of the buttonbox from KDialogBase, although it is not accessable with KDialogBase's API + // None the less it's quite save to use since this implementation hasn't changed since KDE-3.3 (I haven't looked at earlier + // versions since we don't support them) and now all work is done in KDE-4. + QWidget* buttonBox = static_cast( actionButton(KDialogBase::Ok)->parent() ); + QBoxLayout* buttonBoxLayout = static_cast( buttonBox->layout() ); + + KPushButton* importButton = new KPushButton( i18n("Import shortcuts"), buttonBox ); + QWhatsThis::add( importButton, i18n( "Load a keybinding profile, e.g., total_commander.keymap" ) ); + buttonBoxLayout->insertWidget( 1, importButton ); // the defaults-button should stay on position 0 + connect( importButton, SIGNAL( clicked() ), SLOT( slotImportShortcuts() ) ); + + KPushButton* exportButton = new KPushButton( i18n("Export shortcuts"), buttonBox ); + QWhatsThis::add( exportButton, i18n( "Save current keybindings in a keymap file." ) ); + buttonBoxLayout->insertWidget( 2, exportButton ); + connect( exportButton, SIGNAL( clicked() ), SLOT( slotExportShortcuts() ) ); + + // Also quite HACK 'isch but unfortunately KKeyDialog don't giveus access to this widget + _chooser = static_cast( mainWidget() ); + + configure( true /* SaveSettings */ ); // this runs the dialog +} + +KrKeyDialog::~KrKeyDialog() { +} + +void KrKeyDialog::slotImportShortcuts() { + // find $KDEDIR/share/apps/krusader + QString basedir = KGlobal::dirs()->findResourceDir("appdata", "total_commander.keymap"); + // let the user select a file to load + QString filename = KFileDialog::getOpenFileName(basedir, i18n(FILE_FILTER), 0, i18n("Select a keymap file")); + if ( filename.isEmpty() ) + return; + + KConfig conf( filename, true /*read only*/, false /*no KDEGlobal*/ ); + if ( ! conf.hasGroup("Shortcuts") ) { + int answer = KMessageBox::warningContinueCancel( this, //parent + i18n("This file does not seem to be a valid keymap.\n" + "It may be a keymap using a legacy format. The import can't be undone!"), //text + i18n("Try to import legacy format?"), //caption + i18n("Import anyway"), //Label for the continue-button + "Confirm Import Legacy Shortcuts" //dontAskAgainName (for the config-file) + ); + if ( answer == KMessageBox::Continue ) + importLegacyShortcuts( filename ); + else + return; + } + else + _chooser->syncToConfig( "Shortcuts", &conf, false /* don't delete shortcuts of actions not listed in conf */ ); +} + +void KrKeyDialog::importLegacyShortcuts( const QString& file ) { +/* + * This is basicaly Shie's code. It's copied from Kronfigurator's loog&feel page and adapted to the dialog + */ + // check if there's an info file with the keymap + QFile info(file+".info"); + if (info.open(IO_ReadOnly)) { + QTextStream stream(&info); + QStringList infoText = QStringList::split("\n", stream.read()); + if (KMessageBox::questionYesNoList(krApp, i18n("The following information was attached to the keymap. Do you really want to import this keymap?"), infoText)!=KMessageBox::Yes) + return; + } + + // ok, import away + QFile f(file); + if (!f.open(IO_ReadOnly)) { + krOut << "Error opening " << file << endl; + return; + } + char *actionName; + QDataStream stream(&f); + int key; + KAction *action; + while (!stream.atEnd()) { + stream >> actionName >> key; + action = krApp->actionCollection()->action(actionName); + if (action) { + action->setShortcut(key); +// krOut << "set shortcut for " << actionName <File %1 already exists. Do you really want to overwrite it?").arg(filename), + i18n("Warning"), i18n("Overwrite") ) + != KMessageBox::Continue) + return; + if ( f.open( IO_WriteOnly ) ) + // This is the only way to detect if the file is writable since we don't get feetback from KConfig's sync + // Additionaly this prevents merging if the file already contains some shortcuts + f.close(); + else { + KMessageBox::error( this, i18n("Can't open %1 for writing!").arg(filename) ); + return; + } + + KConfig conf( filename, false /*read only*/, false /*no KDEGlobal*/ ); + + // unfortunately we can't use this function since it only writes the actions which are different from default. + //krApp->actionCollection()->writeShortcutSettings( "Shortcuts", &conf ); + KActionShortcutList list( krApp->actionCollection() ); + list.writeSettings( "Shortcuts", &conf, true /* write all actions */ ); + // That does KActionShortcutList::writeSettings for us + //conf.sync(); // write back all changes +} + +#include "krkeydialog.moc" diff --git a/krusader/Dialogs/krkeydialog.h b/krusader/Dialogs/krkeydialog.h new file mode 100644 index 0000000..3731ce5 --- /dev/null +++ b/krusader/Dialogs/krkeydialog.h @@ -0,0 +1,37 @@ +// +// C++ Interface: krkeydialog +// +// Description: +// +// +// Author: Jonas Bähr , (C) 2006 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef KRKEYDIALOG_H +#define KRKEYDIALOG_H + +#include + +/** + * @short KDE's KKeyDialog extended by the ability to export/import shortcuts + * @author Jonas Bähr + */ +class KrKeyDialog : protected KKeyDialog +{ +Q_OBJECT +public: + KrKeyDialog( QWidget* parent = 0 ); + ~KrKeyDialog(); + +private slots: + void slotImportShortcuts(); + void slotExportShortcuts(); + +private: + void importLegacyShortcuts( const QString& file ); + KKeyChooser* _chooser; +}; + +#endif diff --git a/krusader/Dialogs/krmaskchoice.cpp b/krusader/Dialogs/krmaskchoice.cpp new file mode 100644 index 0000000..6e55518 --- /dev/null +++ b/krusader/Dialogs/krmaskchoice.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** + krmaskchoice.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "krmaskchoice.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a KRMaskChoice which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +KRMaskChoice::KRMaskChoice( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "KRMaskChoice" ); + resize( 401, 314 ); + setCaption( i18n( "Choose Files" ) ); + setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5 ) ); + + selection = new QComboBox( FALSE, this, "selection" ); + int height = QFontMetrics( selection->font() ).height(); + height = height + 5*(height > 14) + 6; + selection->setGeometry( QRect( 12, 48, 377, height) ); + selection->setEditable( TRUE ); + selection->setInsertionPolicy( QComboBox::AtTop ); + selection->setAutoCompletion( TRUE ); + + QWidget* Layout7 = new QWidget( this, "Layout7" ); + Layout7->setGeometry( QRect( 10, 10, 380, 30 ) ); + hbox = new QHBoxLayout( Layout7 ); + hbox->setSpacing( 6 ); + hbox->setMargin( 0 ); + + PixmapLabel1 = new QLabel( Layout7, "PixmapLabel1" ); + PixmapLabel1->setScaledContents( TRUE ); + PixmapLabel1->setMaximumSize( QSize( 31, 31 ) ); + // now, add space for the pixmap + hbox->addWidget( PixmapLabel1 ); + + label = new QLabel( Layout7, "label" ); + label->setText( i18n( "Select the following files:" ) ); + hbox->addWidget( label ); + + GroupBox1 = new QGroupBox( this, "GroupBox1" ); + GroupBox1->setGeometry( QRect( 11, 77, 379, 190 ) ); + GroupBox1->setTitle( i18n( "Predefined Selections" ) ); + + QWidget* Layout6 = new QWidget( GroupBox1, "Layout6" ); + Layout6->setGeometry( QRect( 10, 20, 360, 160 ) ); + hbox_2 = new QHBoxLayout( Layout6 ); + hbox_2->setSpacing( 6 ); + hbox_2->setMargin( 0 ); + + preSelections = new QListBox( Layout6, "preSelections" ); + preSelections->setVScrollBarMode( QListBox::AlwaysOn ); + QWhatsThis::add( preSelections, i18n( "A predefined selection is a file-mask which you use often.\nSome examples are: \"*.c, *.h\", \"*.c, *.o\", etc.\nYou can add these masks to the list by typing them and pressing the Add button.\nDelete removes a predefined selection and Clear removes all of them.\nNotice that the line in which you edit the mask has it's own history, you can scroll it, if needed." ) ); + hbox_2->addWidget( preSelections ); + + vbox = new QVBoxLayout; + vbox->setSpacing( 6 ); + vbox->setMargin( 0 ); + + PushButton7 = new QPushButton( Layout6, "PushButton7" ); + PushButton7->setText( i18n( "Add" ) ); + QToolTip::add( PushButton7, i18n( "Adds the selection in the line-edit to the list" ) ); + vbox->addWidget( PushButton7 ); + + PushButton7_2 = new QPushButton( Layout6, "PushButton7_2" ); + PushButton7_2->setText( i18n( "Delete" ) ); + QToolTip::add( PushButton7_2, i18n( "Delete the marked selection from the list" ) ); + vbox->addWidget( PushButton7_2 ); + + PushButton7_3 = new QPushButton( Layout6, "PushButton7_3" ); + PushButton7_3->setText( i18n( "Clear" ) ); + QToolTip::add( PushButton7_3, i18n( "Clears the entire list of selections" ) ); + vbox->addWidget( PushButton7_3 ); + QSpacerItem* spacer = new QSpacerItem( 20, 54, QSizePolicy::Fixed, QSizePolicy::Expanding ); + vbox->addItem( spacer ); + hbox_2->addLayout( vbox ); + + QWidget* Layout18 = new QWidget( this, "Layout18" ); + Layout18->setGeometry( QRect( 10, 280, 379, 30 ) ); + hbox_3 = new QHBoxLayout( Layout18 ); + hbox_3->setSpacing( 6 ); + hbox_3->setMargin( 0 ); + QSpacerItem* spacer_2 = new QSpacerItem( 205, 20, QSizePolicy::Expanding, QSizePolicy::Fixed ); + hbox_3->addItem( spacer_2 ); + + PushButton3 = new QPushButton( Layout18, "PushButton3" ); + PushButton3->setText( i18n( "OK" ) ); + hbox_3->addWidget( PushButton3 ); + + PushButton3_2 = new QPushButton( Layout18, "PushButton3_2" ); + PushButton3_2->setText( i18n( "Cancel" ) ); + hbox_3->addWidget( PushButton3_2 ); + + // signals and slots connections + connect( PushButton3_2, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( PushButton3, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( PushButton7, SIGNAL( clicked() ), this, SLOT( addSelection() ) ); + connect( PushButton7_2, SIGNAL( clicked() ), this, SLOT( deleteSelection() ) ); + connect( PushButton7_3, SIGNAL( clicked() ), this, SLOT( clearSelections() ) ); + connect( selection, SIGNAL( activated(const QString&) ), selection, SLOT( setEditText(const QString &) ) ); + connect( selection->lineEdit(), SIGNAL( returnPressed() ), this, SLOT( accept() )); + connect( preSelections, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( acceptFromList(QListBoxItem *) ) ); + connect( preSelections, SIGNAL( highlighted(const QString&) ), selection, SLOT( setEditText(const QString &) ) ); + connect( preSelections, SIGNAL( returnPressed(QListBoxItem*) ), this, SLOT( acceptFromList(QListBoxItem *) ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +KRMaskChoice::~KRMaskChoice() +{ + // no need to delete child widgets, Qt does it all for us +} + +void KRMaskChoice::addSelection() +{ + qWarning( "KRMaskChoice::addSelection(): Not implemented yet!" ); +} + +void KRMaskChoice::clearSelections() +{ + qWarning( "KRMaskChoice::clearSelections(): Not implemented yet!" ); +} + +void KRMaskChoice::deleteSelection() +{ + qWarning( "KRMaskChoice::deleteSelection(): Not implemented yet!" ); +} + +void KRMaskChoice::acceptFromList(QListBoxItem *) +{ + qWarning( "KRMaskChoice::acceptFromList(QListBoxItem *): Not implemented yet!" ); +} + +#include "krmaskchoice.moc" diff --git a/krusader/Dialogs/krmaskchoice.h b/krusader/Dialogs/krmaskchoice.h new file mode 100644 index 0000000..16be845 --- /dev/null +++ b/krusader/Dialogs/krmaskchoice.h @@ -0,0 +1,76 @@ +/*************************************************************************** + krmaskchoice.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + email : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef KRMASKCHOICE_H +#define KRMASKCHOICE_H + +#include +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QComboBox; +class QGroupBox; +class QLabel; +class QListBox; +class QListBoxItem; +class QPushButton; + +class KRMaskChoice : public QDialog +{ + Q_OBJECT + +public: + KRMaskChoice( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~KRMaskChoice(); + + QComboBox* selection; + QLabel* PixmapLabel1; + QLabel* label; + QGroupBox* GroupBox1; + QListBox* preSelections; + QPushButton* PushButton7; + QPushButton* PushButton7_2; + QPushButton* PushButton7_3; + QPushButton* PushButton3; + QPushButton* PushButton3_2; + +public slots: + virtual void addSelection(); + virtual void clearSelections(); + virtual void deleteSelection(); + virtual void acceptFromList(QListBoxItem *); + +protected: + QHBoxLayout* hbox; + QHBoxLayout* hbox_2; + QHBoxLayout* hbox_3; + QVBoxLayout* vbox; +}; + +#endif // KRMASKCHOICE_H diff --git a/krusader/Dialogs/krpleasewait.cpp b/krusader/Dialogs/krpleasewait.cpp new file mode 100644 index 0000000..c61b61a --- /dev/null +++ b/krusader/Dialogs/krpleasewait.cpp @@ -0,0 +1,153 @@ +/*************************************************************************** + krpleasewait.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "krpleasewait.h" +#include +#include +#include +#include +#include +#include "../krusader.h" +#include "klocale.h" +#include + +KRPleaseWait::KRPleaseWait( QString msg, int count, bool cancel ): + QProgressDialog( cancel ? 0 : krApp,0, !cancel) , inc(true) { + + timer = new QTimer(this); + setCaption( i18n( "Krusader::Wait" ) ); + + setMinimumDuration(500); + setAutoClose(false); + setAutoReset(false); + + connect( timer,SIGNAL(timeout()), this, SLOT(cycleProgress())); + + QProgressBar* progress = new QProgressBar(count,this); + progress->setCenterIndicator(true); + setBar(progress); + + QLabel* label = new QLabel(this); + setLabel(label); + + QPushButton* btn = new QPushButton(i18n("&Cancel"),this); + setCancelButton(btn); + + btn->setEnabled(canClose = cancel); + setLabelText(msg); + + show(); +} + +void KRPleaseWait::closeEvent ( QCloseEvent * e ) +{ + if( canClose ) { + emit cancelled(); + e->accept(); + } else /* if cancel is not allowed, we disable */ + e->ignore(); /* the window closing [x] also */ +} + +void KRPleaseWait::incProgress(int howMuch){ + setProgress(progress()+howMuch); +} + +void KRPleaseWait::cycleProgress(){ + if (inc) setProgress(progress()+1); + else setProgress(progress()-1); + if ( progress() >= 9 ) inc = false; + if ( progress() <= 0 ) inc = true; +} + +KRPleaseWaitHandler::KRPleaseWaitHandler() : QObject(), job(), dlg( 0 ) { +} + +void KRPleaseWaitHandler::stopWait(){ + if( dlg != 0 ) delete dlg; + dlg=0; + cycleMutex=incMutex=false; + // return cursor to normal arrow + krApp->setCursor(KCursor::arrowCursor()); +} + + +void KRPleaseWaitHandler::startWaiting( QString msg, int count , bool cancel){ + if ( dlg == 0 ){ + dlg = new KRPleaseWait( msg , count, cancel); + connect( dlg,SIGNAL(cancelled()),this,SLOT(killJob()) ); + } + incMutex=cycleMutex=_wasCancelled=false; + dlg->setProgress(0); + + dlg->setLabelText(msg); + if ( count == 0) { + dlg->setTotalSteps(10); + cycle = true ; + cycleProgress(); + } + else { + dlg->setTotalSteps(count); + cycle = false; + } +} + +void KRPleaseWaitHandler::cycleProgress(){ + if (cycleMutex) return; + cycleMutex=true; + if (dlg) dlg->cycleProgress(); + if (cycle) QTimer::singleShot(2000,this,SLOT(cycleProgress())); + cycleMutex=false; +} + +void KRPleaseWaitHandler::killJob(){ + if( !job.isNull() ) job->kill(false); + stopWait(); + _wasCancelled = true; +} + +void KRPleaseWaitHandler::setJob(KIO::Job* j){ job=j; } + +void KRPleaseWaitHandler::incProgress(int i){ + if (incMutex) return; + incMutex=true; + if(dlg) dlg->incProgress(i); + incMutex=false; +} + +void KRPleaseWaitHandler::incProgress( KProcess *, char *buffer, int buflen ) { + int howMuch = 0; + for ( int i = 0 ; i < buflen; ++i ) + if ( buffer[ i ] == '\n' ) + ++howMuch; + + incProgress( howMuch ); +} + +#include "krpleasewait.moc" diff --git a/krusader/Dialogs/krpleasewait.h b/krusader/Dialogs/krpleasewait.h new file mode 100644 index 0000000..30b19f8 --- /dev/null +++ b/krusader/Dialogs/krpleasewait.h @@ -0,0 +1,82 @@ +/*************************************************************************** + krpleasewait.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRPLEASEWAIT_H +#define KRPLEASEWAIT_H + +#include +#include +#include +#include + +class KProcess; +class KRPleaseWait; + +class KRPleaseWaitHandler : public QObject { + Q_OBJECT + +public: + KRPleaseWaitHandler(); + +public slots: + + void startWaiting(QString msg, int count = 0, bool cancel = false); + void stopWait(); + void cycleProgress(); + void incProgress(int i); + void incProgress( KProcess *, char *buffer, int buflen ); + void killJob(); + void setJob(KIO::Job* j); + bool wasCancelled() const { return _wasCancelled; } + +private: + QGuardedPtr job; + KRPleaseWait * dlg; + bool cycle, cycleMutex, incMutex, _wasCancelled; +}; + + +class KRPleaseWait : public QProgressDialog { + Q_OBJECT +public: + KRPleaseWait( QString msg, int count = 0 ,bool cancel = false ); + +public slots: + void incProgress(int howMuch); + void cycleProgress(); + +protected: + bool inc; + QTimer* timer; + virtual void closeEvent ( QCloseEvent * e ); + bool canClose; +}; + +#endif diff --git a/krusader/Dialogs/krprogress.cpp b/krusader/Dialogs/krprogress.cpp new file mode 100644 index 0000000..94f8c8c --- /dev/null +++ b/krusader/Dialogs/krprogress.cpp @@ -0,0 +1,270 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Matej Koss + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "krprogress.h" +#include "../krusader.h" + +KrProgress::KrProgress( KIO::Job* job ) + : ProgressBase( krApp ), + m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0), + m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0){ + +#ifdef Q_WS_X11 //FIXME(E): Remove once all the KWin::foo calls have been ported to QWS + // Set a useful icon for this window! + KWin::setIcons( winId(), + KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 32 ), + KGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 16 ) ); +#endif + + QVBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(), + KDialog::spacingHint() ); + topLayout->addStrut( 360 ); // makes dlg at least that wide + + QGridLayout *grid = new QGridLayout( 2, 3 ); + topLayout->addLayout(grid); + grid->addColSpacing(1, KDialog::spacingHint()); + // filenames or action name + grid->addWidget(new QLabel(i18n("Source:"), this), 0, 0); + + sourceLabel = new KSqueezedTextLabel(this); + grid->addWidget(sourceLabel, 0, 2); + + destInvite = new QLabel(i18n("Destination:"), this); + grid->addWidget(destInvite, 1, 0); + + destLabel = new KSqueezedTextLabel(this); + grid->addWidget(destLabel, 1, 2); + + m_pProgressBar = new KProgress(this); + topLayout->addWidget( m_pProgressBar ); + + // processed info + QHBoxLayout *hBox = new QHBoxLayout(); + topLayout->addLayout(hBox); + + sizeLabel = new QLabel(this); + hBox->addWidget(sizeLabel); + + resumeLabel = new QLabel(this); + hBox->addWidget(resumeLabel); + + progressLabel = new QLabel( this ); +/* progressLabel->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::Preferred ) );*/ + progressLabel->setAlignment( QLabel::AlignRight ); + hBox->addWidget( progressLabel ); + + hBox = new QHBoxLayout(); + topLayout->addLayout(hBox); + + speedLabel = new QLabel(this); + hBox->addWidget(speedLabel, 1); + + QFrame *line = new QFrame( this ); + line->setFrameShape( QFrame::HLine ); + line->setFrameShadow( QFrame::Sunken ); + topLayout->addWidget( line ); + + hBox = new QHBoxLayout(); + topLayout->addLayout(hBox); + + hBox->addStretch(1); + + KPushButton *pb = new KPushButton( KStdGuiItem::cancel(), this ); + connect( pb, SIGNAL( clicked() ), SLOT( slotStop() ) ); + hBox->addWidget( pb ); + + resize( sizeHint() ); + setMaximumHeight(sizeHint().height()); + + setCaption(i18n("Krusader Progress")); // show something better than kio_uiserver + + setJob(job); + setOnlyClean(false); + setStopOnClose(true); + // Connect global progress info signals + connect( job, SIGNAL( percent( KIO::Job*, unsigned long ) ), + SLOT( slotPercent( KIO::Job*, unsigned long ) ) ); + connect( job, SIGNAL( infoMessage( KIO::Job*, const QString & ) ), + SLOT( slotInfoMessage( KIO::Job*, const QString & ) ) ); + connect( job, SIGNAL( totalSize( KIO::Job*, KIO::filesize_t ) ), + SLOT( slotTotalSize( KIO::Job*, KIO::filesize_t ) ) ); + connect( job, SIGNAL( processedSize( KIO::Job*, KIO::filesize_t ) ), + SLOT( slotProcessedSize( KIO::Job*, KIO::filesize_t ) ) ); + connect( job, SIGNAL( speed( KIO::Job*, unsigned long ) ), + SLOT( slotSpeed( KIO::Job*, unsigned long ) ) ); + + // change to modal & move to Krusader's center + QPoint center((krApp->width()-width())/2,(krApp->height()-height())/2); + center = center+(krApp->pos()); + reparent(krApp,WType_Modal,center); + //setWFlags(WType_Modal); + //move((krApp->width()-width())/2,(krApp->height()-height())/2); + show(); +} + +KrProgress::~KrProgress(){} + +void KrProgress::slotTotalSize( KIO::Job*, KIO::filesize_t bytes ){ + m_iTotalSize = bytes; +} + + +void KrProgress::slotTotalFiles( KIO::Job*, unsigned long files ){ + m_iTotalFiles = files; + showTotals(); +} + + +void KrProgress::slotTotalDirs( KIO::Job*, unsigned long dirs ){ + m_iTotalDirs = dirs; + showTotals(); +} + +void KrProgress::showTotals(){ + // Show the totals in the progress label, if we still haven't + // processed anything. This is useful when the stat'ing phase + // of CopyJob takes a long time (e.g. over networks). + if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 ) + { + QString tmps; + if ( m_iTotalDirs > 1 ) + // that we have a singular to translate looks weired but is only logical + tmps = i18n("%n directory", "%n directories", m_iTotalDirs) + " "; + tmps += i18n("%n file", "%n files", m_iTotalFiles); + progressLabel->setText( tmps ); + } +} + +void KrProgress::slotPercent( KIO::Job*, unsigned long percent ){ + QString tmp(i18n( "%1% of %2 ").arg( percent ).arg( KIO::convertSize(m_iTotalSize))); + m_pProgressBar->setValue( percent ); + tmp.append(i18n(" (Reading)")); + + setCaption( tmp ); +} + + +void KrProgress::slotInfoMessage( KIO::Job*, const QString & msg ) +{ + speedLabel->setText( msg ); + speedLabel->setAlignment( speedLabel->alignment() & ~Qt::WordBreak ); +} + + +void KrProgress::slotProcessedSize( KIO::Job*, KIO::filesize_t bytes ) { + m_iProcessedSize = bytes; + + QString tmp; + tmp = i18n( "%1 of %2 complete").arg( KIO::convertSize(bytes) ).arg( KIO::convertSize(m_iTotalSize)); + sizeLabel->setText( tmp ); +} + + +void KrProgress::slotProcessedDirs( KIO::Job*, unsigned long dirs ) +{ + m_iProcessedDirs = dirs; + + QString tmps; + tmps = i18n("%1 / %n directory", "%1 / %n directories", m_iTotalDirs).arg( m_iProcessedDirs ); + tmps += " "; + tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles ); + progressLabel->setText( tmps ); +} + + +void KrProgress::slotProcessedFiles( KIO::Job*, unsigned long files ) +{ + m_iProcessedFiles = files; + + QString tmps; + if ( m_iTotalDirs > 1 ) { + tmps = i18n("%1 / %n directory", "%1 / %n directories", m_iTotalDirs).arg( m_iProcessedDirs ); + tmps += " "; + } + tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles ); + progressLabel->setText( tmps ); +} + + +void KrProgress::slotSpeed( KIO::Job*, unsigned long bytes_per_second ) +{ + if ( bytes_per_second == 0 ) { + speedLabel->setText( i18n( "Working") ); + } else { +#if KDE_IS_VERSION(3,4,0) + unsigned int seconds = KIO::calculateRemainingSeconds( m_iTotalSize, m_iProcessedSize, bytes_per_second ); + QString remaining = KIO::convertSeconds(seconds); +#else + QString remaining = KIO::calculateRemaining( m_iTotalSize, m_iProcessedSize, bytes_per_second ).toString(); +#endif + speedLabel->setText( i18n( "%1/s ( %2 remaining )").arg( KIO::convertSize( bytes_per_second )).arg( remaining ) ); + } +} + + +void KrProgress::setDestVisible( bool visible ) +{ + // We can't hide the destInvite/destLabel labels, + // because it screws up the QGridLayout. + if (visible) + { + destInvite->setText( i18n("Destination:") ); + } + else + { + destInvite->setText( QString::null ); + destLabel->setText( QString::null ); + } +} + +void KrProgress::virtual_hook( int id, void* data ){ + ProgressBase::virtual_hook( id, data ); +} + +void KrProgress::slotStop(){ + if ( m_pJob ) { + m_pJob->kill(false); // this will call slotFinished + m_pJob = 0L; + } else { + slotFinished( 0 ); // here we call it ourselves + } + + emit stopped(); +} + +void KrProgress::closeEvent( QCloseEvent* ) { hide(); slotStop(); } + +#include "krprogress.moc" diff --git a/krusader/Dialogs/krprogress.h b/krusader/Dialogs/krprogress.h new file mode 100644 index 0000000..a8731b1 --- /dev/null +++ b/krusader/Dialogs/krprogress.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Matej Koss + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/** This file was modified for Krusader by Shie Erlich & Rafi Yanai **/ + +#ifndef __kr_progress_h__ +#define __kr_progress_h__ + +#include + +#include + +#include +#include + +#include + +#include + +class KrProgress : public KIO::ProgressBase { + Q_OBJECT +public: + + KrProgress(KIO::Job* job); + virtual ~KrProgress(); + +public slots: + virtual void slotTotalSize( KIO::Job*, KIO::filesize_t bytes ); + virtual void slotTotalFiles( KIO::Job*, unsigned long files ); + virtual void slotTotalDirs( KIO::Job*, unsigned long dirs ); + + virtual void slotProcessedSize( KIO::Job*, KIO::filesize_t bytes ); + virtual void slotProcessedFiles( KIO::Job*, unsigned long files ); + virtual void slotProcessedDirs( KIO::Job*, unsigned long dirs ); + + virtual void slotSpeed( KIO::Job*, unsigned long bytes_per_second ); + virtual void slotPercent( KIO::Job*, unsigned long percent ); + virtual void slotInfoMessage( KIO::Job*, const QString & msg ); + + virtual void slotStop(); + virtual void closeEvent( QCloseEvent* ); + +protected: + void showTotals(); + void setDestVisible( bool visible ); + + KSqueezedTextLabel* sourceLabel; + KSqueezedTextLabel* destLabel; + QLabel* progressLabel; + QLabel* destInvite; + QLabel* speedLabel; + QLabel* sizeLabel; + QLabel* resumeLabel; + + KProgress* m_pProgressBar; + + KIO::filesize_t m_iTotalSize; + unsigned long m_iTotalFiles; + unsigned long m_iTotalDirs; + + KIO::filesize_t m_iProcessedSize; + unsigned long m_iProcessedDirs; + unsigned long m_iProcessedFiles; + +protected: + virtual void virtual_hook( int id, void* data ); +}; + + +#endif // __kr_progress_h__ + diff --git a/krusader/Dialogs/krspecialwidgets.cpp b/krusader/Dialogs/krspecialwidgets.cpp new file mode 100644 index 0000000..f7027de --- /dev/null +++ b/krusader/Dialogs/krspecialwidgets.cpp @@ -0,0 +1,239 @@ +/*************************************************************************** + krspecialwidgets.cpp + ------------------- +copyright : (C) 2000 by Shie Erlich & Rafi Yanai +e-mail : krusader@users.sourceforge.net +web site : http://krusader.sourceforge.net +--------------------------------------------------------------------------- +Description +*************************************************************************** + +A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + + + +#include "krspecialwidgets.h" +#include "krmaskchoice.h" +#include "newftpgui.h" +#include "../krusader.h" +#include "../MountMan/kmountman.h" +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +/////////////////////// Pie related widgets ///////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// The pie-related widgets use hard-coded coordinates to create the look. +// This is ok since the whole widget is fitted into an existing view and thus +// no re-alignments are needed. + +#define LEFT 10 +#define BOTTOM 150 +#define WIDTH 120 +#define HEIGHT 40 +#define Z_HEIGHT 10 +#define STARTANGLE 0 +#define DEG(x) (16*(x)) + +QColor KRPie::colors[ 12 ] = {Qt::red, Qt::blue, Qt::green, Qt::cyan, Qt::magenta, Qt::gray, + Qt::black, Qt::white, Qt::darkRed, Qt::darkBlue, Qt::darkMagenta, + Qt::darkCyan}; + +////////////////////////////////////////////////////////////////////////////// +/////////////// KRFSDisplay - Filesystem / Freespace Display ///////////////// +////////////////////////////////////////////////////////////////////////////// +// This is the full constructor: use it for a mounted filesystem +KRFSDisplay::KRFSDisplay( QWidget *parent, QString _alias, QString _realName, + KIO::filesize_t _total, KIO::filesize_t _free ) : QWidget( parent ), totalSpace( _total ), + freeSpace( _free ), alias( _alias ), realName( _realName ), mounted( true ), +empty( false ), supermount( false ) { + resize( 150, 200 ); + show(); +} + +// Use this one for an unmounted filesystem +KRFSDisplay::KRFSDisplay( QWidget *parent, QString _alias, QString _realName, bool sm ) : + QWidget( parent ), alias( _alias ), realName( _realName ), mounted( false ), +empty( false ), supermount( sm ) { + resize( 150, 200 ); + show(); +} + +// This is used only when an empty widget needs to be displayed (for example: +// when filesystem statistics haven't been calculated yet) +KRFSDisplay::KRFSDisplay( QWidget *parent ) : QWidget( parent ), empty( true ) { + resize( 150, 200 ); + show(); +} + + +// The main painter! +void KRFSDisplay::paintEvent( QPaintEvent * ) { + QPainter paint( this ); + if ( !empty ) { + // create the text + // first, name and location + paint.setFont( QFont( "helvetica", 12, QFont::Bold ) ); + paint.drawText( 10, 20, alias ); + paint.setFont( QFont( "helvetica", 12, QFont::Normal ) ); + paint.drawText( 10, 37, "(" + realName + ")" ); + if ( mounted ) { // incase the filesystem is already mounted + // second, the capacity + paint.drawText( 10, 70, i18n( "Capacity: " ) + KIO::convertSizeFromKB( totalSpace ) ); + // third, the 2 boxes (used, free) + QPen systemPen = paint.pen(); + paint.setPen( Qt::black ); + paint.drawRect( 10, 90, 10, 10 ); + paint.fillRect( 11, 91, 8, 8, QBrush( Qt::gray ) ); + paint.drawRect( 10, 110, 10, 10 ); + paint.fillRect( 11, 111, 8, 8, QBrush( Qt::white ) ); + // now, the text for the boxes + paint.setPen( systemPen ); + paint.drawText( 25, 100, i18n( "Used: " ) + KIO::convertSizeFromKB( totalSpace - freeSpace ) ); + paint.drawText( 25, 120, i18n( "Free: " ) + KIO::convertSizeFromKB( freeSpace ) ); + // first, create the empty pie + // bottom... + paint.setPen( Qt::black ); + paint.setBrush( Qt::white ); + paint.drawPie( LEFT, BOTTOM, WIDTH, HEIGHT, STARTANGLE, DEG( 360 ) ); + // body... + paint.setPen( Qt::lightGray ); + for ( int i = 1; i < Z_HEIGHT; ++i ) + paint.drawPie( LEFT, BOTTOM - i, WIDTH, HEIGHT, STARTANGLE, DEG( 360 ) ); + // side lines... + paint.setPen( Qt::black ); + paint.drawLine( LEFT, BOTTOM + HEIGHT / 2, LEFT, BOTTOM + HEIGHT / 2 - Z_HEIGHT ); + paint.drawLine( LEFT + WIDTH, BOTTOM + HEIGHT / 2, LEFT + WIDTH, BOTTOM + HEIGHT / 2 - Z_HEIGHT ); + // top of the pie + paint.drawPie( LEFT, BOTTOM - Z_HEIGHT, WIDTH, HEIGHT, STARTANGLE, DEG( 360 ) ); + // the "used space" slice + float i = ( ( float ) ( totalSpace - freeSpace ) / ( totalSpace ) ) * 360.0; + paint.setBrush( Qt::gray ); + paint.drawPie( LEFT, BOTTOM - Z_HEIGHT, WIDTH, HEIGHT, STARTANGLE, ( int ) DEG( i ) ); + // if we need to draw a 3d stripe ... + if ( i > 180.0 ) { + for ( int j = 1; j < Z_HEIGHT; ++j ) + paint.drawArc( LEFT, BOTTOM - j, WIDTH, HEIGHT, STARTANGLE - 16 * 180, ( int ) ( DEG( i - 180.0 ) ) ); + } + } else { // if the filesystem is unmounted... + paint.setFont( QFont( "helvetica", 12, QFont::Bold ) ); + paint.drawText( 10, 60, i18n( "Not mounted." ) ); + } + } else { // if the widget is in empty situation... + + } +} + +//////////////////////////////////////////////////////////////////////////////// +KRPie::KRPie( KIO::filesize_t _totalSize, QWidget *parent ) : QWidget( parent, 0 ), totalSize( _totalSize ) { + slices.setAutoDelete( true ); // kill items when they are removed + slices.append( new KRPieSlice( 100, Qt::yellow, "DEFAULT" ) ); + sizeLeft = totalSize; + resize( 300, 300 ); +} + +void KRPie::paintEvent( QPaintEvent * ) { + QPainter paint( this ); + // now create the slices + KRPieSlice *slice; + float sAngle = STARTANGLE; + for ( slice = slices.first(); slice != 0; slice = slices.next() ) { + paint.setBrush( slice->getColor() ); + paint.setPen( slice->getColor() ); + // angles are negative to create a clock-wise drawing of slices + float angle = -( slice->getPerct() / 100 * 360 ) * 16; + for ( int i = 1; i < Z_HEIGHT; ++i ) + paint.drawPie( LEFT, BOTTOM + i, WIDTH, HEIGHT, ( int ) sAngle, ( int ) angle ); + sAngle += angle; + } + paint.setPen( Qt::yellow ); // pen + paint.setBrush( Qt::yellow ); // fill + // for (int i=1; igetColor() ); + paint.setPen( slice->getColor() ); + // angles are negative to create a clock-wise drawing of slices + float angle = -( slice->getPerct() / 100 * 360 ) * 16; + paint.drawPie( LEFT, BOTTOM, WIDTH, HEIGHT, ( int ) sAngle, ( int ) angle ); + sAngle += angle; + } + + + paint.setPen( Qt::black ); + // the pie + // paint.drawPie(LEFT,BOTTOM,WIDTH,HEIGHT,STARTANGLE,360*16); + ///////////////////////// end of empty pie ///////////////////////// + // now, the pie is ready to draw slices on... + // to make a good look on the perimiter, draw another black circle + paint.setPen( Qt::black ); + paint.drawArc( LEFT, BOTTOM, WIDTH, HEIGHT, STARTANGLE, 360 * 16 ); + +} + +void KRPie::addSlice( KIO::filesize_t size, QString label ) { + int i = ( slices.count() % 12 ); + slices.removeLast(); + slices.append( new KRPieSlice( size * 100 / totalSize, colors[ i ], label ) ); + sizeLeft -= size; + slices.append( new KRPieSlice( sizeLeft * 100 / totalSize, Qt::yellow, "DEFAULT" ) ); +} + +//////////////////////////////////////////////////// +/////////////////// KrQuickSearch ///////////////// +//////////////////////////////////////////////////// +KrQuickSearch::KrQuickSearch( QWidget *parent, const char * name ) : KLineEdit( parent, name ) {} + +void KrQuickSearch::myKeyPressEvent( QKeyEvent *e ) { + switch ( e->key() ) { + case Key_Escape: + emit stop( 0 ); + break; + case Key_Return: + case Key_Enter: + case Key_Tab: + case Key_Right: + case Key_Left: + emit stop( e ); + break; + case Key_Down: + otherMatching( text(), 1 ); + break; + case Key_Up: + otherMatching( text(), -1 ); + break; + case Key_Insert: + case Key_Home: + case Key_End: + process( e ); + break; + default: + keyPressEvent( e ); + } +} + + + +#include "krspecialwidgets.moc" diff --git a/krusader/Dialogs/krspecialwidgets.h b/krusader/Dialogs/krspecialwidgets.h new file mode 100644 index 0000000..9d0a36a --- /dev/null +++ b/krusader/Dialogs/krspecialwidgets.h @@ -0,0 +1,126 @@ +/*************************************************************************** + krspecialwidgets.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net +--------------------------------------------------------------------------- +Description +*************************************************************************** + +A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + + +#ifndef KRSPECIALWIDGETS_H +#define KRSPECIALWIDGETS_H + +#include +#include +#include +#include +#include +#include +#include + +class KRPieSlice; + +class KRPie : public QWidget { + Q_OBJECT + public: + KRPie( KIO::filesize_t _totalSize, QWidget *parent = 0 ); + void addSlice( KIO::filesize_t size, QString label ); + + protected: + void paintEvent( QPaintEvent * ); + + private: + QList slices; + KIO::filesize_t totalSize, sizeLeft; + static QColor colors[ 12 ]; +}; + +class KRFSDisplay : public QWidget { + Q_OBJECT + public: + // this constructor is used for a mounted filesystem + KRFSDisplay( QWidget *parent, QString _alias, QString _realName, + KIO::filesize_t _total, KIO::filesize_t _free ); + // this one is for an unmounted/supermount file system + KRFSDisplay( QWidget *parent, QString _alias, QString _realName, bool sm = false ); + // the last one is used inside MountMan(R), when no filesystem is selected + KRFSDisplay( QWidget *parent ); + inline void setTotalSpace( KIO::filesize_t t ) { totalSpace = t; } + inline void setFreeSpace( KIO::filesize_t t ) { freeSpace = t; } + inline void setAlias( QString a ) { alias = a; } + inline void setRealName( QString r ) { realName = r; } + inline void setMounted( bool m ) { mounted = m; } + inline void setEmpty( bool e ) { empty = e; } + inline void setSupermount( bool s ) { supermount = s; } + + protected: + void paintEvent( QPaintEvent * ); + + private: + KIO::filesize_t totalSpace, freeSpace; + QString alias, realName; + bool mounted, empty, supermount; +}; + +class KRPieSlice { + public: + KRPieSlice( float _perct, QColor _color, QString _label ) : + perct( _perct ), color( _color ), label( _label ) {} + inline QColor getColor() { return color; } + inline float getPerct() { return perct; } + inline QString getLabel() { return label; } + inline void setPerct( float _perct ) { perct = _perct; } + inline void setLabel( QString _label ) { label = _label; } + + private: + float perct; + QColor color; + QString label; +}; + +class KrQuickSearch: public KLineEdit { + Q_OBJECT + public: + KrQuickSearch(QWidget *parent, const char * name = 0); + void addText(const QString &str) { setText(text()+str); } + void myKeyPressEvent(QKeyEvent *e); + void myIMStartEvent(QIMEvent* e) { + imStartEvent(e); + } + void myIMEndEvent(QIMEvent* e) { + imEndEvent(e); + } + void myIMComposeEvent(QIMEvent* e) { + imComposeEvent(e); + } + + signals: + void stop(QKeyEvent *e); + void process(QKeyEvent *e); + void otherMatching(const QString &, int); + +}; + +#endif diff --git a/krusader/Dialogs/krspwidgets.cpp b/krusader/Dialogs/krspwidgets.cpp new file mode 100644 index 0000000..64da41f --- /dev/null +++ b/krusader/Dialogs/krspwidgets.cpp @@ -0,0 +1,316 @@ +/*************************************************************************** + krspwidgets.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "krspwidgets.h" +#include "../krusader.h" +#include "../krusaderview.h" +#include "../Panel/listpanel.h" +#include "../kicons.h" +#include "../Filter/filtertabs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../resources.h" + +///////////////////// initiation of the static members //////////////////////// +QStrList KRSpWidgets::maskList; + +/////////////////////////////////////////////////////////////////////////////// + +KRSpWidgets::KRSpWidgets(){ +} + +KRQuery KRSpWidgets::getMask(QString caption, bool nameOnly ) { + if( !nameOnly ) { + return FilterTabs::getQuery(); + } + else { + KRMaskChoiceSub *p=new KRMaskChoiceSub(); + p->setCaption(caption); + p->exec(); + if (p->selection->currentText()=="") return KRQuery(); + else return KRQuery( p->selection->currentText() ); + } +} + +/////////////////////////// newFTP //////////////////////////////////////// +KURL KRSpWidgets::newFTP() { + newFTPSub *p=new newFTPSub(); + p->exec(); + if (p->url->currentText()=="") return KURL(); // empty url + KURL url; + + QString protocol = p->prefix->currentText(); + protocol.truncate(protocol.length() - 3); // remove the trailing :// + QString username = p->username->text().simplifyWhiteSpace(); + QString password = p->password->text().simplifyWhiteSpace(); + QString uri = p->url->currentText(); + + int uriStart = uri.findRev( '@' ); /* lets the user enter user and password in the URI field */ + if( uriStart != -1 ) { + QString uriUser = uri.left( uriStart ); + QString uriPsw = QString::null; + uri = uri.mid( uriStart + 1 ); + + int pswStart = uriUser.find( ':' ); /* getting the password name from the URL */ + if( pswStart != -1 ) { + uriPsw = uriUser.mid( pswStart + 1 ); + uriUser = uriUser.left( pswStart ); + } + + if( !uriUser.isEmpty() ) /* handling the ftp proxy username and password also */ + username = username.isEmpty() ? uriUser : username + "@" + uriUser; + + if( !uriPsw.isEmpty() ) /* handling the ftp proxy username and password also */ + password = password.isEmpty() ? uriPsw : password + "@" + uriPsw; + } + + QString host = uri; /* separating the hostname and path from the uri */ + QString path = QString::null; + int pathStart = uri.find( "/" ); + if( pathStart != -1 ) { + path = host.mid( pathStart ); + host = host.left( pathStart ); + } + + /* setting the parameters of the URL */ + url.setProtocol(protocol); + url.setHost( host ); + url.setPath( path ); + if ( protocol == "ftp" || protocol == "fish" || protocol == "sftp" ) + url.setPort(p->port->cleanText().toInt()); + if (!username.isEmpty()) + url.setUser( username ); + if (!password.isEmpty()) + url.setPass( password ); + + return url; +} + +newFTPSub::newFTPSub() : newFTPGUI(0,0,true) { + url->setFocus(); + setGeometry(krApp->x()+krApp->width()/2-width()/2,krApp->y()+krApp->height()/2-height()/2,width(),height()); +} + +void newFTPSub::accept() { + url->addToHistory( url->currentText() ); + // save the history and completion list when the history combo is + // destroyed + krConfig->setGroup("Private"); + QStringList list = url->completionObject()->items(); + krConfig->writeEntry( "newFTP Completion list", list ); + list = url->historyItems(); + krConfig->writeEntry( "newFTP History list", list ); + + newFTPGUI::accept(); +} + +void newFTPSub::reject() { + url->setCurrentText(""); + newFTPGUI::reject(); +} + +/////////////////////////// KRMaskChoiceSub /////////////////////////////// +KRMaskChoiceSub::KRMaskChoiceSub() : KRMaskChoice(0,0,true) { + PixmapLabel1->setPixmap(krLoader->loadIcon("kr_select", KIcon::Desktop, 32)); + label->setText(i18n("Enter a selection:")); + // the predefined selections list + krConfig->setGroup("Private"); + QStrList lst; + int i=krConfig->readListEntry("Predefined Selections",lst); + if (i>0) preSelections->insertStrList(lst); + // the combo-box tweaks + selection->setDuplicatesEnabled(false); + selection->insertStrList(KRSpWidgets::maskList); + selection->lineEdit()->setText("*"); + selection->lineEdit()->selectAll(); + selection->setFocus(); +} + +void KRMaskChoiceSub::reject() { + selection->clear(); + KRMaskChoice::reject(); +} + +void KRMaskChoiceSub::accept() { + bool add = true; + char *tmp; + // make sure we don't have that already + for ( tmp = KRSpWidgets::maskList.first(); tmp ; tmp = KRSpWidgets::maskList.next() ) + if (QString(tmp).simplifyWhiteSpace() == selection->currentText().simplifyWhiteSpace()) { + // break if we found one such as this + add = false; + break; + } + + if (add) + KRSpWidgets::maskList.insert(0,selection->currentText().local8Bit()); + // write down the predefined selections list + QStrList list; + QListBoxItem *i=preSelections->firstItem(); + while (i!=0) { + if (i->text().find(i18n("compare mode"))==-1) + list.append(i->text().local8Bit()); + i=i->next(); + } + krConfig->setGroup("Private"); + krConfig->writeEntry("Predefined Selections",list); + KRMaskChoice::accept(); +} + +void KRMaskChoiceSub::addSelection() { + QString temp=selection->currentText(); + bool itemExists=false; + QListBoxItem *i=preSelections->firstItem(); + // check if the selection already exists + while (i!=0) + if (i->text()==temp) { + itemExists=true; + break; + } else i=i->next(); + if (temp!="" && !itemExists) { + preSelections->insertItem(selection->currentText()); + preSelections->update(); + } +} + +void KRMaskChoiceSub::deleteSelection() { + if (preSelections->currentItem()!=-1 && + preSelections->currentText().find(i18n("compare mode"))==-1) { + preSelections->removeItem(preSelections->currentItem()); + preSelections->update(); + } +} + +void KRMaskChoiceSub::clearSelections() { + preSelections->clear(); + preSelections->update(); +} + +void KRMaskChoiceSub::acceptFromList(QListBoxItem *i) { + selection->insertItem(i->text(),0); + accept(); +} + +////////////////////////// QuickNavLineEdit //////////////////// + +QuickNavLineEdit::QuickNavLineEdit(const QString &string, QWidget *parent, const char *name): + KLineEdit(string, parent, name) { init(); } + +QuickNavLineEdit::QuickNavLineEdit(QWidget *parent, const char *name): + KLineEdit(parent, name) { init(); } + +int QuickNavLineEdit::findCharFromPos(const QString & str, const QFontMetrics & metrics, int pos) +{ + if (pos < 0) + return -1; + for (int i = 1; i <= (int)str.length(); ++i) + if (metrics.width(str, i) > pos) + return i; + return str.length(); +} + +void QuickNavLineEdit::init() { + _numOfSelectedChars=0; + _dummyDisplayed=false; + _pop=0; + //setCompletionMode( KGlobalSettings::CompletionPopupAuto ); ==> removed by public demand +} + +void QuickNavLineEdit::leaveEvent(QEvent *) { + clearAll(); +} + +void QuickNavLineEdit::mousePressEvent( QMouseEvent *m ) { + if (m->state()!=ControlButton) clearAll(); + else + { + if (!_numOfSelectedChars) + { + _numOfSelectedChars = charCount(m); + if (_numOfSelectedChars < 0) + _numOfSelectedChars = 0; + } + if (_numOfSelectedChars) + emit returnPressed(text().left(_numOfSelectedChars)); + } + KLineEdit::mousePressEvent(m); +} + +int QuickNavLineEdit::charCount(const QMouseEvent * const m,QString * const str) { + // find how much of the string we've selected (approx) + // and select from from the start to the closet slash (on the right) + const QString tx = text().simplifyWhiteSpace(); + if (tx.isEmpty()) { + clearAll(); + return -1; + } + + int numOfChars = findCharFromPos(tx, fontMetrics(), m->x() - 5); + if(str) *str=tx; + return tx.find('/', numOfChars); +} + +void QuickNavLineEdit::mouseMoveEvent( QMouseEvent *m) { + if (m->state()!=ControlButton) { // works only with ctrl pressed + clearAll(); + KLineEdit::mouseMoveEvent(m); + return; + } + QString tx; + int idx=charCount(m,&tx); + if (idx == -1 && !_dummyDisplayed) { // pointing on or after the current directory + if (_pop) delete _pop; + _pop = KPassivePopup::message( i18n("Quick Navigation"), + "" + i18n("Already at %1").arg(tx.left(idx)) + "", + *(KCursor::handCursor().bitmap()), this); + + _dummyDisplayed=true; + _numOfSelectedChars=0; + } else if (idx>0 && idx!=_numOfSelectedChars) { + _numOfSelectedChars=idx; + if (_pop) delete _pop; + _dummyDisplayed=false; + + _pop = KPassivePopup::message( i18n("Quick Navigation"), + "" + i18n("Click to go to %1").arg(tx.left(idx)) + "", + *(KCursor::handCursor().bitmap()), this ); + } + KLineEdit::mouseMoveEvent(m); +} + diff --git a/krusader/Dialogs/krspwidgets.h b/krusader/Dialogs/krspwidgets.h new file mode 100644 index 0000000..d1466cb --- /dev/null +++ b/krusader/Dialogs/krspwidgets.h @@ -0,0 +1,110 @@ +/*************************************************************************** + krspwidgets.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef KRSPWIDGETS_H +#define KRSPWIDGETS_H + +#include +#include +#include "krmaskchoice.h" +#include "newftpgui.h" +#include "../VFS/krquery.h" +#include +#include + +class newFTPGUI; + +class KRMaskChoiceSub; + +class KRSpWidgets { + friend class KRMaskChoiceSub; + +public: + KRSpWidgets(); + + static KRQuery getMask( QString caption, bool nameOnly=false ); // get file-mask for (un)selecting files + static KURL newFTP(); + +private: + static QStrList maskList; // used by KRMaskChoiceSub +}; + +/////////////////////////// newFTPSub /////////////////////////////////////// +class newFTPSub : public newFTPGUI { +public: + newFTPSub(); + +protected: + void reject(); + void accept(); +}; + +/////////////////////////// KRMaskChoiceSub ///////////////////////////////// +// Inherits KRMaskChoice's generated code to fully implement the functions // +///////////////////////////////////////////////////////////////////////////// +class KRMaskChoiceSub : public KRMaskChoice { +public: + KRMaskChoiceSub(); + +public slots: + void addSelection(); + void deleteSelection(); + void clearSelections(); + void acceptFromList(QListBoxItem *i); + +protected: + void reject(); + void accept(); +}; + +/////////////////////////// QuickNavLineEdit ////////////////////////// +// same as line edit, but hold ctrl while pointing to it... and see! // +/////////////////////////////////////////////////////////////////////// + +class QuickNavLineEdit: public KLineEdit { +public: + QuickNavLineEdit(const QString &string, QWidget *parent, const char *name=0); + QuickNavLineEdit(QWidget *parent=0, const char *name=0); + virtual ~QuickNavLineEdit() {} + static int findCharFromPos(const QString &, const QFontMetrics &, int pos); +protected: + void mouseMoveEvent( QMouseEvent *m); + void leaveEvent( QEvent * ); + void mousePressEvent( QMouseEvent *m ); + inline void clearAll() { _numOfSelectedChars = 0; if (_pop) delete _pop; _dummyDisplayed=false; } + void init(); + +private: + int charCount(const QMouseEvent * const , QString* const =0) ; + int _numOfSelectedChars; + bool _dummyDisplayed; + QGuardedPtr _pop; +}; + +#endif diff --git a/krusader/Dialogs/krsqueezedtextlabel.cpp b/krusader/Dialogs/krsqueezedtextlabel.cpp new file mode 100644 index 0000000..5d93269 --- /dev/null +++ b/krusader/Dialogs/krsqueezedtextlabel.cpp @@ -0,0 +1,80 @@ +#include "krsqueezedtextlabel.h" +#include +#include +#include + +KrSqueezedTextLabel::KrSqueezedTextLabel(QWidget *parent, const char *name): + KSqueezedTextLabel(parent, name), acceptDrops( false ), _index(-1), _length(-1) { +} + + +KrSqueezedTextLabel::~KrSqueezedTextLabel() { +} + +void KrSqueezedTextLabel::mousePressEvent(QMouseEvent *) { + emit clicked(); + +} + +void KrSqueezedTextLabel::enableDrops( bool flag ) +{ + setAcceptDrops( acceptDrops = flag ); +} + +void KrSqueezedTextLabel::dropEvent(QDropEvent *e) { + emit dropped(e); +} + +void KrSqueezedTextLabel::dragEnterEvent(QDragEnterEvent *e) { + if( acceptDrops ) + e->accept( KURLDrag::canDecode( e ) ); + else + KSqueezedTextLabel::dragEnterEvent( e ); +} + +void KrSqueezedTextLabel::squeezeTextToLabel(int index, int length) { + if (index==-1 || length==-1) + KSqueezedTextLabel::squeezeTextToLabel(); + else { + QString sqtext=fullText; + QFontMetrics fm(fontMetrics()); + int labelWidth = size().width(); + int textWidth = fm.width(sqtext); + if (textWidth > labelWidth) { + int avgCharSize = textWidth / sqtext.length(); + int numOfExtraChars = (textWidth-labelWidth)/avgCharSize; + int delta; + + // remove as much as possible from the left, and then from the right + if (index>3) { + delta=QMIN(index, numOfExtraChars); + numOfExtraChars -= delta; + sqtext.replace(0, delta, "..."); + } + + if (numOfExtraChars>0 && ((int)sqtext.length() > length+3)) { + delta = QMIN(numOfExtraChars, (int)sqtext.length() - (length+3)); + sqtext.replace(sqtext.length()-delta, delta, "..."); + } + QLabel::setText(sqtext); + + QToolTip::remove( this ); + QToolTip::add( this, fullText ); + } else { + QLabel::setText(fullText); + + QToolTip::remove( this ); + QToolTip::hide(); + } + } +} + +void KrSqueezedTextLabel::setText( const QString &text, int index, int length ) { + _index=index; + _length=length; + fullText = text; + squeezeTextToLabel(_index,_length); +} + +#include "krsqueezedtextlabel.moc" + diff --git a/krusader/Dialogs/krsqueezedtextlabel.h b/krusader/Dialogs/krsqueezedtextlabel.h new file mode 100644 index 0000000..8f81389 --- /dev/null +++ b/krusader/Dialogs/krsqueezedtextlabel.h @@ -0,0 +1,44 @@ +#ifndef KRSQUEEZEDTEXTLABEL_H +#define KRSQUEEZEDTEXTLABEL_H + +#include + +class QMouseEvent; +class QDropEvent; +class QDragEnterEvent; + +/** +This class overloads KSqueezedTextLabel and simply adds a clicked signal, +so that users will be able to click the label and switch focus between panels. + +NEW: a special setText() method allows to choose which part of the string should + be displayed (example: make sure that search results won't be cut out) +*/ +class KrSqueezedTextLabel : public KSqueezedTextLabel { +Q_OBJECT + public: + KrSqueezedTextLabel(QWidget *parent = 0, const char *name = 0); + ~KrSqueezedTextLabel(); + + void enableDrops( bool flag ); + + public slots: + void setText( const QString &text, int index=-1, int length=-1 ); + + signals: + void clicked(); /**< emitted when someone clicks on the label */ + void dropped(QDropEvent *); /**< emitted when someone drops URL onto the label */ + + protected: + void resizeEvent( QResizeEvent * ) { squeezeTextToLabel(_index, _length); } + virtual void mousePressEvent(QMouseEvent *e); + virtual void dropEvent(QDropEvent *e); + virtual void dragEnterEvent(QDragEnterEvent *e); + void squeezeTextToLabel(int index=-1, int length=-1); + + private: + bool acceptDrops; + int _index, _length; +}; + +#endif diff --git a/krusader/Dialogs/kurllistrequester.cpp b/krusader/Dialogs/kurllistrequester.cpp new file mode 100644 index 0000000..4575555 --- /dev/null +++ b/krusader/Dialogs/kurllistrequester.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + kurllistrequester.cpp - description + ------------------- + copyright : (C) 2005 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kurllistrequester.h" +#include "../VFS/vfs.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define DELETE_ITEM_ID 100 + +KURLListRequester::KURLListRequester( QWidget *parent, const char * name ) : QWidget( parent, name ) +{ + KIconLoader *iconLoader = new KIconLoader(); + QPixmap imageAdd = iconLoader->loadIcon( "1downarrow", KIcon::Panel, 16 ); + QPixmap imageFolder = iconLoader->loadIcon( "folder", KIcon::Panel, 16 ); + + // Creating the widget + + QGridLayout *urlListRequesterGrid = new QGridLayout( this ); + urlListRequesterGrid->setSpacing( 0 ); + urlListRequesterGrid->setMargin( 0 ); + + urlLineEdit = new KLineEdit( this, "urlLineEdit" ); + urlListRequesterGrid->addWidget( urlLineEdit, 0, 0 ); + + urlListBox = new QListBox( this, "urlListBox" ); + urlListBox->setSelectionMode( QListBox::Extended ); + urlListRequesterGrid->addMultiCellWidget( urlListBox, 1, 1, 0, 2 ); + + urlAddBtn = new QToolButton( this, "urlAddBtn" ); + urlAddBtn->setText( "" ); + urlAddBtn->setPixmap( imageAdd ); + urlListRequesterGrid->addWidget( urlAddBtn, 0, 1 ); + + urlBrowseBtn = new QToolButton( this, "urlBrowseBtn" ); + urlBrowseBtn->setText( "" ); + urlBrowseBtn->setPixmap( imageFolder ); + urlListRequesterGrid->addWidget( urlBrowseBtn, 0, 2 ); + + // add shell completion + + completion.setMode( KURLCompletion::FileCompletion ); + urlLineEdit->setCompletionObject( &completion ); + + // connection table + + connect( urlAddBtn, SIGNAL( clicked() ), this, SLOT( slotAdd() ) ); + connect( urlBrowseBtn, SIGNAL( clicked() ), this, SLOT( slotBrowse() ) ); + connect( urlLineEdit, SIGNAL( returnPressed(const QString&) ), this, SLOT( slotAdd() ) ); + connect( urlListBox, SIGNAL( rightButtonClicked ( QListBoxItem *, const QPoint & ) ), this, + SLOT( slotRightClicked( QListBoxItem * ) ) ); +} + +void KURLListRequester::slotAdd() +{ + QString text = urlLineEdit->text().simplifyWhiteSpace(); + if( text.length() ) + { + QString error = QString::null; + emit checkValidity( text, error ); + + if( !error.isNull() ) + KMessageBox::error( this, error ); + else + { + urlListBox->insertItem( text ); + urlLineEdit->clear(); + } + } +} + +void KURLListRequester::slotBrowse() +{ + KURL url = KFileDialog::getExistingURL( QString::null, this ); + if( !url.isEmpty()) + urlLineEdit->setText( vfs::pathOrURL( url ) ); + urlLineEdit->setFocus(); +} + +void KURLListRequester::keyPressEvent(QKeyEvent *e) +{ + if( e->key() == Key_Delete ) + { + if( urlListBox->hasFocus() ) + { + deleteSelectedItems(); + return; + } + } + + QWidget::keyPressEvent( e ); +} + +void KURLListRequester::deleteSelectedItems() +{ + int i=0; + QListBoxItem *item; + + while( (item = urlListBox->item(i)) ) + { + if( item->isSelected() ) + { + urlListBox->removeItem( i ); + continue; + } + i++; + } +} + +void KURLListRequester::slotRightClicked( QListBoxItem *item ) +{ + if( item == 0 ) + return; + + KPopupMenu popupMenu( this ); + popupMenu.insertItem( i18n( "Delete" ), DELETE_ITEM_ID ); + + switch( popupMenu.exec( QCursor::pos() ) ) + { + case DELETE_ITEM_ID: + if( item->isSelected() ) + deleteSelectedItems(); + else + urlListBox->removeItem( urlListBox->index( item ) ); + break; + } +} + +KURL::List KURLListRequester::urlList() +{ + KURL::List urls; + + QString text = urlLineEdit->text().simplifyWhiteSpace(); + if (!text.isEmpty()) + { + QString error = QString::null; + emit checkValidity( text, error ); + if( error.isNull() ) + urls.append( vfs::fromPathOrURL( text ) ); + } + + QListBoxItem *item = urlListBox->firstItem(); + while ( item ) + { + QString text = item->text().simplifyWhiteSpace(); + + QString error = QString::null; + emit checkValidity( text, error ); + if( error.isNull() ) + urls.append( vfs::fromPathOrURL( text ) ); + + item = item->next(); + } + + return urls; +} + +void KURLListRequester::setUrlList( KURL::List urlList ) +{ + urlLineEdit->clear(); + urlListBox->clear(); + + KURL::List::iterator it; + + for ( it = urlList.begin(); it != urlList.end(); ++it ) + urlListBox->insertItem( vfs::pathOrURL(*it) ); +} + +#include "kurllistrequester.moc" diff --git a/krusader/Dialogs/kurllistrequester.h b/krusader/Dialogs/kurllistrequester.h new file mode 100644 index 0000000..06afe52 --- /dev/null +++ b/krusader/Dialogs/kurllistrequester.h @@ -0,0 +1,76 @@ +/*************************************************************************** + kurllistrequester.h - description + ------------------- + copyright : (C) 2005 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __KURLLISTREQUESTER_H__ +#define __KURLLISTREQUESTER_H__ + +#include +#include +#include +#include +#include +#include + +class KURLListRequester : public QWidget +{ + Q_OBJECT + +public: + KURLListRequester( QWidget *parent = 0, const char * name = 0 ); + + KURL::List urlList(); + void setUrlList( KURL::List ); + + KLineEdit *lineEdit() {return urlLineEdit;} + QListBox *listBox() {return urlListBox;} + + void setCompletionDir( QString dir ) { completion.setDir( dir ); } + +signals: + void checkValidity( QString &text, QString &error ); + +protected slots: + void slotAdd(); + void slotBrowse(); + void slotRightClicked( QListBoxItem * ); + +protected: + virtual void keyPressEvent(QKeyEvent *e); + void deleteSelectedItems(); + + KLineEdit *urlLineEdit; + QListBox *urlListBox; + QToolButton *urlAddBtn; + QToolButton *urlBrowseBtn; + + KURLCompletion completion; +}; + +#endif /* __KURLLISTREQUESTER_H__ */ diff --git a/krusader/Dialogs/newftpgui.cpp b/krusader/Dialogs/newftpgui.cpp new file mode 100644 index 0000000..1e8c3ed --- /dev/null +++ b/krusader/Dialogs/newftpgui.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'newftpgui.ui' +** +** Created: Fri Oct 27 23:47:10 2000 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#include "newftpgui.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../krusader.h" + + +/* + * Constructs a newFTPGUI which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ + + #define SIZE_MINIMUM QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0 ) + +newFTPGUI::newFTPGUI( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ){ + + QVBoxLayout * layout = new QVBoxLayout( this, 11, 6, "newFTPGUI_layout" ); + layout->setAutoAdd(true); + + if ( !name ) + setName( "newFTPGUI" ); + resize( 342, 261 ); + setCaption( i18n( "New Network Connection" ) ); +// setSizeGripEnabled( TRUE ); + setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, sizePolicy().hasHeightForWidth() ) ); + setMinimumSize( QSize( 342, 261 ) ); + + + QHBox* hbox_image = new QHBox( this, "hbox_image" ); + hbox_image->setSpacing( 6 ); + + PixmapLabel1 = new QLabel( hbox_image, "PixmapLabel1" ); + PixmapLabel1->setPixmap( krLoader->loadIcon("network", KIcon::Desktop, 32) ); + PixmapLabel1->setSizePolicy( SIZE_MINIMUM ); + + TextLabel3 = new QLabel( i18n( "About to connect to..." ), hbox_image, "TextLabel3" ); + QFont TextLabel3_font( TextLabel3->font() ); + TextLabel3_font.setBold( TRUE ); + TextLabel3->setFont( TextLabel3_font ); + + + QGrid* grid_host = new QGrid( 3, this, "grid_host" ); + + TextLabel1 = new QLabel( i18n( "Protocol:" ), grid_host, "TextLabel1" ); + TextLabel1_22 = new QLabel( i18n( "Host:"), grid_host, "TextLabel_2" ); + TextLabel1_3 = new QLabel( i18n( "Port:" ), grid_host, "TextLabel1_3" ); + + QStringList protocols = KProtocolInfo::protocols(); + + prefix = new KComboBox( FALSE, grid_host, "protocol" ); + if( protocols.contains("ftp") ) + prefix->insertItem( i18n( "ftp://" ) ); + if( protocols.contains("smb") ) + prefix->insertItem( i18n( "smb://" ) ); + if( protocols.contains("fish") ) + prefix->insertItem( i18n( "fish://" )); + if( protocols.contains("sftp") ) + prefix->insertItem( i18n( "sftp://" )); + prefix->setAcceptDrops( FALSE ); + prefix->setEnabled( TRUE ); + prefix->setSizePolicy( SIZE_MINIMUM ); + connect( prefix,SIGNAL(activated(const QString& )), + this,SLOT(slotTextChanged(const QString& ))); + + url = new KHistoryCombo( grid_host, "url" ); + url->setMaximumHeight( 20 ); + url->setMaxCount( 25 ); + url->setDuplicatesEnabled( false ); + connect( url, SIGNAL( activated( const QString& )), + url, SLOT( addToHistory( const QString& ))); + // load the history and completion list after creating the history combo + krConfig->setGroup("Private"); + QStringList list = krConfig->readListEntry( "newFTP Completion list" ); + url->completionObject()->setItems( list ); + list = krConfig->readListEntry( "newFTP History list" ); + url->setHistoryItems( list ); + + port = new QSpinBox( grid_host, "port" ); + port->setMaxValue( 65535 ); +#if QT_VERSION < 300 + port->setFrameShadow( QSpinBox::Sunken ); +#endif + port->setValue( 21 ); + port->setSizePolicy( SIZE_MINIMUM ); + + + TextLabel1_2 = new QLabel( i18n( "Username:" ), this, "TextLabel1_2" ); + username = new QLineEdit( this, "username" ); + TextLabel1_2_2 = new QLabel( i18n( "Password:" ), this, "TextLabel1_2_2" ); + password = new QLineEdit( this, "password" ); + password->setEchoMode( QLineEdit::Password ); + + + QWidget* Layout6 = new QWidget( this, "Layout6" ); + hbox = new QHBoxLayout( Layout6 ); + hbox->setSpacing( 6 ); + hbox->setMargin( 0 ); + + hbox->addItem(new QSpacerItem(1,1,QSizePolicy::Expanding)); + + connectBtn = new QPushButton( i18n( "&Connect" ), Layout6, "connectBtn" ); + connectBtn->setAutoDefault( TRUE ); + connectBtn->setDefault( TRUE ); + hbox->addWidget( connectBtn ); + + //saveBtn = new QPushButton( i18n( "&Save" ), Layout6, "saveBtn" ); + //saveBtn->setAutoDefault( TRUE ); + //hbox->addWidget( saveBtn ); + + cancelBtn = new QPushButton( i18n( "&Cancel" ), Layout6, "cancelBtn" ); + cancelBtn->setAutoDefault( TRUE ); + hbox->addWidget( cancelBtn ); + + // signals and slots connections + connect( connectBtn, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( cancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + + // tab order + setTabOrder( url, username ); + setTabOrder( username, password ); + setTabOrder( password, connectBtn ); + setTabOrder( connectBtn, cancelBtn ); + setTabOrder( cancelBtn, prefix ); + setTabOrder( prefix, url ); +} + +/* + * Destroys the object and frees any allocated resources + */ +newFTPGUI::~newFTPGUI(){ + // no need to delete child widgets, Qt does it all for us +} + +void newFTPGUI::slotTextChanged(const QString& string){ + if( string.startsWith("ftp") || string.startsWith("sftp") || string.startsWith("fish") ) + { + if( port->value() == 21 || port->value() == 22 ) + port->setValue( string.startsWith("ftp") ? 21 : 22 ); + port->setEnabled(true); + } + else + port->setEnabled(false); +} + +/* + * Main event handler. Reimplemented to handle application + * font changes + */ +bool newFTPGUI::event( QEvent* ev ) { + bool ret = QDialog::event( ev ); + if ( ev->type() == QEvent::ApplicationFontChange ) { + QFont TextLabel3_font( TextLabel3->font() ); + TextLabel3_font.setBold( TRUE ); + TextLabel3->setFont( TextLabel3_font ); + } + return ret; +} + +#include "newftpgui.moc" diff --git a/krusader/Dialogs/newftpgui.h b/krusader/Dialogs/newftpgui.h new file mode 100644 index 0000000..2291d4f --- /dev/null +++ b/krusader/Dialogs/newftpgui.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'newftpgui.ui' +** +** Created: Fri Oct 27 23:47:08 2000 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#ifndef NEWFTPGUI_H +#define NEWFTPGUI_H + +#include +#include +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QLabel; +class QLineEdit; +class QPushButton; +class QSpinBox; +class KComboBox; +class KHistoryCombo; + +class newFTPGUI : public QDialog { + Q_OBJECT +public: + newFTPGUI( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~newFTPGUI(); + + QLabel* TextLabel1; + KComboBox* prefix; + QLabel* TextLabel1_2_2; + QLabel* TextLabel1_22; + QLabel* TextLabel1_2; + QLabel* TextLabel1_3; + QSpinBox* port; + QLineEdit* password; + QPushButton* connectBtn; + QPushButton* saveBtn; + QPushButton* cancelBtn; + QLabel* PixmapLabel1; + QLabel* TextLabel3; + QLineEdit* username; + KHistoryCombo* url; + +public slots: + void slotTextChanged(const QString& string); + +protected: + QHBoxLayout* hbox; + bool event( QEvent* ); +}; + +#endif // NEWFTPGUI_H diff --git a/krusader/Dialogs/packgui.cpp b/krusader/Dialogs/packgui.cpp new file mode 100644 index 0000000..7036a3e --- /dev/null +++ b/krusader/Dialogs/packgui.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + packgui.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "packgui.h" +#include +#include "../krusader.h" +#include "../defaults.h" +#include +#include +#include +#include +#include + +#define PS(x) lst.contains(x)>0 + +// clear the statics first +QString PackGUI::filename=0; +QString PackGUI::destination=0; +QString PackGUI::type=0; +QMap PackGUI::extraProps; + +PackGUI::PackGUI(QString defaultName, QString defaultPath, int noOfFiles, QString filename) : + PackGUIBase(0,0,true) { + // first, fill the WhatToPack textfield with information + if(noOfFiles == 1) + TextLabel1->setText( i18n("Pack %1").arg(filename) ); + else + TextLabel1->setText( i18n("Pack %n file", "Pack %n files", noOfFiles) ); + + // now, according to the Konfigurator, fill the combobox with the information + // about what kind of packing we can do + krConfig->setGroup("Archives"); + QStringList lst=krConfig->readListEntry("Supported Packers"); + // now, clear the type combo and begin... + typeData->clear(); + if (PS("tar")) typeData->insertItem("tar"); + if (PS("tar") && PS("gzip")) typeData->insertItem("tar.gz"); + if (PS("tar") && PS("bzip2")) typeData->insertItem("tar.bz2"); + if (PS("zip")) typeData->insertItem("zip"); + if (PS("rar")) typeData->insertItem("rar"); + if (PS("lha")) typeData->insertItem("lha"); + if (PS("arj")) typeData->insertItem("arj"); + if (PS("7z")) typeData->insertItem("7z"); + // set the last used packer as the top one + QString tmp=krConfig->readEntry("lastUsedPacker",QString::null); + if (tmp!=QString::null) { + for (unsigned int i=0; i< typeData->listBox()->count(); ++i) + if (typeData->listBox()->item(i)->text() == tmp) { + typeData->listBox()->removeItem(i); + typeData->listBox()->insertItem(tmp,0); + break; + } + } + checkConsistency(); + + // and go on with the normal stuff + dirData->setText(defaultPath); + nameData->setText(defaultName); + nameData->setFocus(); + if (typeData->listBox()->count()==0) // if no packers are availble + okButton->setEnabled(false); + setGeometry(krApp->x()+krApp->width()/2-width()/2,krApp->y()+krApp->height()/2-height()/2,width(),height()); + exec(); +} + +void PackGUI::browse() { + QString temp=KFileDialog::getExistingDirectory(dirData->text(),0,i18n("Please select a directory")); + if (temp != QString::null) + dirData->setText(temp); +} + +void PackGUI::accept() { + if( !extraProperties( extraProps ) ) + return; + + filename=nameData->text(); + destination=dirData->text(); + type=typeData->currentText(); + // write down the packer chosen, to be lastUsedPacker + krConfig->setGroup("Archives"); + krConfig->writeEntry("lastUsedPacker",type); + krConfig->sync(); + PackGUIBase::accept(); +} + +void PackGUI::reject() { + filename=QString::null; + destination=QString::null; + type=QString::null; + PackGUIBase::reject(); +} + +#include "packgui.moc" diff --git a/krusader/Dialogs/packgui.h b/krusader/Dialogs/packgui.h new file mode 100644 index 0000000..d88c831 --- /dev/null +++ b/krusader/Dialogs/packgui.h @@ -0,0 +1,53 @@ +/*************************************************************************** + packgui.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PACKGUI_H +#define PACKGUI_H + +#include "packguibase.h" + +class PackGUI : public PackGUIBase { + Q_OBJECT +public: + PackGUI(QString defaultName, QString defaultPath, int noOfFiles, QString filename=""); + +public slots: + void browse(); + +protected slots: + void accept(); + void reject(); + +public: + static QString filename, destination, type; + static QMap extraProps; +}; + +#endif diff --git a/krusader/Dialogs/packguibase.cpp b/krusader/Dialogs/packguibase.cpp new file mode 100644 index 0000000..ace6078 --- /dev/null +++ b/krusader/Dialogs/packguibase.cpp @@ -0,0 +1,468 @@ +/*************************************************************************** + packguibase.cpp + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "packguibase.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../krusader.h" + +/* + * Constructs a PackGUIBase which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +PackGUIBase::PackGUIBase( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ), expanded( false ) +{ + if ( !name ) + setName( "PackGUIBase" ); + resize( 430, 140 ); + setCaption( i18n( "Pack" ) ); + grid = new QGridLayout( this ); + grid->setSpacing( 6 ); + grid->setMargin( 11 ); + + hbox = new QHBoxLayout; + hbox->setSpacing( 6 ); + hbox->setMargin( 0 ); + + TextLabel3 = new QLabel( this, "TextLabel3" ); + TextLabel3->setText( i18n( "To archive" ) ); + hbox->addWidget( TextLabel3 ); + + nameData = new QLineEdit( this, "nameData" ); + hbox->addWidget( nameData ); + + typeData = new QComboBox( FALSE, this, "typeData" ); + typeData->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0 ) ); + connect( typeData, SIGNAL( activated( const QString & ) ), this, SLOT( checkConsistency() ) ); + connect( typeData, SIGNAL( highlighted( const QString & ) ), this, SLOT( checkConsistency() ) ); + hbox->addWidget( typeData ); + + grid->addLayout( hbox, 1, 0 ); + + hbox_2 = new QHBoxLayout; + hbox_2->setSpacing( 6 ); + hbox_2->setMargin( 0 ); + + TextLabel5 = new QLabel( this, "TextLabel5" ); + TextLabel5->setText( i18n( "In directory" ) ); + hbox_2->addWidget( TextLabel5 ); + + dirData = new QLineEdit( this, "dirData" ); + hbox_2->addWidget( dirData ); + + browseButton = new QToolButton( this, "browseButton" ); + browseButton->setIconSet( SmallIcon( "fileopen" ) ); + hbox_2->addWidget( browseButton ); + QSpacerItem* spacer = new QSpacerItem( 48, 20, QSizePolicy::Fixed, QSizePolicy::Fixed ); + hbox_2->addItem( spacer ); + + grid->addLayout( hbox_2, 2, 0 ); + + hbox_3 = new QHBoxLayout; + hbox_3->setSpacing( 6 ); + hbox_3->setMargin( 0 ); + + PixmapLabel1 = new QLabel( this, "PixmapLabel1" ); + PixmapLabel1->setPixmap( krLoader->loadIcon("package", KIcon::Desktop, 32) ); + PixmapLabel1->setScaledContents( TRUE ); + PixmapLabel1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0 ) ); + hbox_3->addWidget( PixmapLabel1 ); + + TextLabel1 = new QLabel( this, "TextLabel1" ); + TextLabel1->setText( i18n( "Pack" ) ); + hbox_3->addWidget( TextLabel1 ); + + grid->addLayout( hbox_3, 0, 0 ); + + + hbox_4 = new QHBoxLayout; + hbox_4->setSpacing( 6 ); + hbox_4->setMargin( 0 ); + + QSpacerItem* spacer_3 = new QSpacerItem( 20, 26, QSizePolicy::Fixed, QSizePolicy::Expanding ); + hbox_4->addItem( spacer_3 ); + grid->addLayout( hbox_4, 3, 0 ); + + advancedWidget = new QWidget( this, "advancedWidget" ); + + hbox_5 = new QGridLayout( advancedWidget ); + hbox_5->setSpacing( 6 ); + hbox_5->setMargin( 0 ); + + + QVBoxLayout *compressLayout = new QVBoxLayout; + compressLayout->setSpacing( 6 ); + compressLayout->setMargin( 0 ); + + multipleVolume = new QCheckBox( i18n( "Multiple volume archive" ), advancedWidget, "multipleVolume" ); + connect( multipleVolume, SIGNAL( toggled( bool ) ), this, SLOT( checkConsistency() ) ); + compressLayout->addWidget( multipleVolume, 0, 0 ); + + QHBoxLayout * volumeHbox = new QHBoxLayout; + + QSpacerItem* spacer_5 = new QSpacerItem( 20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed ); + volumeHbox->addItem( spacer_5 ); + + TextLabel7 = new QLabel( i18n("Size:" ), advancedWidget, "TextLabel7" ); + volumeHbox->addWidget( TextLabel7 ); + + volumeSpinBox = new QSpinBox( advancedWidget, "volumeSpinBox" ); + volumeSpinBox->setMinValue( 1 ); + volumeSpinBox->setMaxValue( 9999 ); + volumeSpinBox->setValue( 1440 ); + volumeHbox->addWidget( volumeSpinBox ); + + volumeUnitCombo = new QComboBox( FALSE, advancedWidget, "volumeUnitCombo" ); + volumeUnitCombo->insertItem( "B" ); + volumeUnitCombo->insertItem( "KB" ); + volumeUnitCombo->insertItem( "MB" ); + volumeUnitCombo->setCurrentItem( 1 ); + volumeHbox->addWidget( volumeUnitCombo ); + + compressLayout->addLayout ( volumeHbox ); + + setCompressionLevel = new QCheckBox( i18n( "Set compression level" ), advancedWidget, "multipleVolume" ); + connect( setCompressionLevel, SIGNAL( toggled( bool ) ), this, SLOT( checkConsistency() ) ); + compressLayout->addWidget( setCompressionLevel, 0, 0 ); + + QHBoxLayout * sliderHbox = new QHBoxLayout; + + QSpacerItem* spacer_6 = new QSpacerItem( 20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed ); + sliderHbox->addItem( spacer_6 ); + + QVBox * sliderVBox = new QVBox( advancedWidget ); + + compressionSlider = new QSlider( 1, 9, 1, 5, Qt::Horizontal, sliderVBox, "compressionSlider" ); + compressionSlider->setTickmarks( QSlider::Below ); + + QHBox * minmaxHBox = new QHBox( sliderVBox ); + minLabel = new QLabel( i18n("MIN"), minmaxHBox ); + maxLabel = new QLabel( i18n("MAX"), minmaxHBox ); + maxLabel->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + sliderHbox->addWidget( sliderVBox ); + + compressLayout->addLayout( sliderHbox ); + + compressLayout->addStretch( 0 ); + hbox_5->addLayout( compressLayout, 0, 0 ); + + QFrame *vline = new QFrame( advancedWidget, "vline" ); + vline->setFrameStyle( QFrame::VLine | QFrame::Sunken ); + vline->setMinimumWidth( 20 ); + hbox_5->addWidget( vline, 0, 1 ); + + + QGridLayout * passwordGrid = new QGridLayout; + passwordGrid->setSpacing( 6 ); + passwordGrid->setMargin( 0 ); + + TextLabel4 = new QLabel( advancedWidget, "TextLabel4" ); + TextLabel4->setText( i18n( "Password" ) ); + passwordGrid->addWidget( TextLabel4, 0, 0 ); + + password = new QLineEdit( advancedWidget, "password" ); + password->setEchoMode( QLineEdit::Password ); + connect( password, SIGNAL( textChanged ( const QString & ) ), this, SLOT( checkConsistency() ) ); + + passwordGrid->addWidget( password, 0, 1 ); + + TextLabel6 = new QLabel( advancedWidget, "TextLabel6" ); + TextLabel6->setText( i18n( "Again" ) ); + passwordGrid->addWidget( TextLabel6, 1, 0 ); + + passwordAgain = new QLineEdit( advancedWidget, "password" ); + passwordAgain->setEchoMode( QLineEdit::Password ); + connect( passwordAgain, SIGNAL( textChanged ( const QString & ) ), this, SLOT( checkConsistency() ) ); + + passwordGrid->addWidget( passwordAgain, 1, 1 ); + + QHBoxLayout *consistencyHbox = new QHBoxLayout; + + QSpacerItem* spacer_cons = new QSpacerItem( 48, 20, QSizePolicy::Expanding, QSizePolicy::Fixed ); + consistencyHbox->addItem( spacer_cons ); + + passwordConsistencyLabel = new QLabel( advancedWidget, "passwordConsistencyLabel" ); + consistencyHbox->addWidget( passwordConsistencyLabel ); + passwordGrid->addMultiCellLayout ( consistencyHbox, 2, 2, 0, 1 ); + + encryptHeaders = new QCheckBox( i18n( "Encrypt headers" ), advancedWidget, "encryptHeaders" ); + passwordGrid->addMultiCellWidget ( encryptHeaders, 3, 3, 0, 1 ); + + QSpacerItem* spacer_psw = new QSpacerItem( 20, 20, QSizePolicy::Fixed, QSizePolicy::Expanding ); + passwordGrid->addItem( spacer_psw, 4, 0 ); + + hbox_5->addLayout( passwordGrid, 0, 2 ); + + hbox_7 = new QHBoxLayout; + hbox_7->setSpacing( 6 ); + hbox_7->setMargin( 0 ); + + TextLabel8 = new QLabel( i18n( "Command line switches:" ), advancedWidget, "TextLabel8" ); + TextLabel8->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + hbox_7->addWidget( TextLabel8 ); + + commandLineSwitches = new KHistoryCombo( advancedWidget, "commandLineSwitches" ); + commandLineSwitches->setMaxCount(25); // remember 25 items + commandLineSwitches->setDuplicatesEnabled(false); + krConfig->setGroup("Archives"); + QStringList list = krConfig->readListEntry("Command Line Switches"); + commandLineSwitches->setHistoryItems(list); + + hbox_7->addWidget( commandLineSwitches ); + + hbox_5->addMultiCellLayout( hbox_7, 1, 1, 0, 2 ); + + + advancedWidget->hide(); + checkConsistency(); + + grid->addWidget( advancedWidget, 4, 0 ); + + hbox_6 = new QHBoxLayout; + hbox_6->setSpacing( 6 ); + hbox_6->setMargin( 0 ); + + advancedButton = new QPushButton( this, "advancedButton" ); + advancedButton->setText( i18n( "&Advanced" ) + " >>" ); + hbox_6->addWidget( advancedButton ); + + QSpacerItem* spacer_2 = new QSpacerItem( 140, 20, QSizePolicy::Expanding, QSizePolicy::Fixed ); + hbox_6->addItem( spacer_2 ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setText( i18n( "Ok" ) ); + okButton->setDefault( true ); + hbox_6->addWidget( okButton ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setText( i18n( "Cancel" ) ); + hbox_6->addWidget( cancelButton ); + + grid->addLayout( hbox_6, 6, 0 ); + + // signals and slots connections + connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( advancedButton, SIGNAL( clicked() ), this, SLOT( expand() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( browseButton, SIGNAL( clicked() ), this, SLOT( browse() ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +PackGUIBase::~PackGUIBase() +{ + // no need to delete child widgets, Qt does it all for us +} + +void PackGUIBase::browse() +{ + qWarning( "PackGUIBase::browse(): Not implemented yet!" ); +} + +void PackGUIBase::expand() { + expanded = !expanded; + + advancedButton->setText( i18n( "&Advanced" ) + ( expanded ? " <<" : " >>" ) ); + + if( expanded ) + advancedWidget->show(); + else { + advancedWidget->hide(); + layout()->activate(); + QSize minSize = minimumSize(); + resize( width(), minSize.height() ); + } + show(); +} + +void PackGUIBase::checkConsistency() { + if( password->text().isEmpty() && passwordAgain->text().isEmpty()) { + passwordConsistencyLabel->setPaletteForegroundColor( KGlobalSettings::textColor() ); + passwordConsistencyLabel->setText( i18n( "No password specified" ) ); + } + else + if( password->text() == passwordAgain->text() ) { + passwordConsistencyLabel->setPaletteForegroundColor( KGlobalSettings::textColor() ); + passwordConsistencyLabel->setText( i18n( "The passwords are equal" ) ); + } + else { + passwordConsistencyLabel->setPaletteForegroundColor( Qt::red ); + passwordConsistencyLabel->setText( i18n( "The passwords are different" ) ); + } + + QString packer = typeData->currentText(); + + bool passworded = false; + if( packer == "7z" || packer == "rar" || packer == "zip" || packer == "arj" ) + passworded = true; + + passwordConsistencyLabel->setEnabled( passworded ); + password->setEnabled( passworded ); + passwordAgain->setEnabled( passworded ); + TextLabel4->setEnabled( passworded ); + TextLabel6->setEnabled( passworded ); + + encryptHeaders->setEnabled( packer == "rar" ); + + multipleVolume->setEnabled( packer == "rar" || packer == "arj" ); + bool volumeEnabled = multipleVolume->isEnabled() && multipleVolume->isChecked(); + volumeSpinBox->setEnabled( volumeEnabled ); + volumeUnitCombo->setEnabled( volumeEnabled ); + TextLabel7->setEnabled( volumeEnabled ); + + /* TODO */ + setCompressionLevel->setEnabled( packer == "rar" || packer == "arj" || packer == "zip" || + packer == "7z" ); + bool sliderEnabled = setCompressionLevel->isEnabled() && setCompressionLevel->isChecked(); + compressionSlider->setEnabled( sliderEnabled ); + minLabel->setEnabled( sliderEnabled ); + maxLabel->setEnabled( sliderEnabled ); +} + +bool PackGUIBase::extraProperties( QMap & inMap ) { + inMap.clear(); + + if( password->isEnabled() && passwordAgain->isEnabled() ) { + if( password->text() != passwordAgain->text() ) { + KMessageBox::error( this, i18n( "Cannot pack! The passwords are different!" ) ); + return false; + } + + if( !password->text().isEmpty() ) { + inMap[ "Password" ] = password->text(); + + if( encryptHeaders->isEnabled() && encryptHeaders->isChecked() ) + inMap[ "EncryptHeaders" ] = "1"; + } + } + + if( multipleVolume->isEnabled() && multipleVolume->isChecked() ) { + KIO::filesize_t size = volumeSpinBox->value(); + + switch( volumeUnitCombo->currentItem() ) { + case 2: + size *= 1000; + case 1: + size *= 1000; + default: + break; + } + + if( size < 10000 ) { + KMessageBox::error( this, i18n( "Invalid volume size!" ) ); + return false; + } + + QString sbuffer; + sbuffer.sprintf("%llu",size); + + inMap[ "VolumeSize" ] = sbuffer; + } + + if( setCompressionLevel->isEnabled() && setCompressionLevel->isChecked() ) { + inMap[ "CompressionLevel" ] = QString("%1").arg( compressionSlider->value() ); + } + + QString cmdArgs = commandLineSwitches->currentText().stripWhiteSpace(); + if( !cmdArgs.isEmpty() ) { + bool firstChar = true; + QChar quote = '\0'; + + for( unsigned i=0; i < cmdArgs.length(); i++ ) { + QChar ch( cmdArgs[ i ] ); + if( ch.isSpace() ) + continue; + + if( ch == quote ) { + quote = '\0'; + continue; + } + + if( firstChar && ch != '-' ) { + KMessageBox::error( this, i18n( "Invalid command line switch!\nSwitch must start with '-'!" ) ); + return false; + } + + firstChar = false; + + if( quote == '"' ) + continue; + if( quote == '\0' && ( ch == '\'' || ch == '"' ) ) + quote = ch; + if( ch == '\\' ) { + if( i == cmdArgs.length() - 1 ) { + KMessageBox::error( this, i18n( "Invalid command line switch!\nBackslash cannot be the last character" ) ); + return false; + } + i++; + } + } + + if( quote != '\0' ) { + KMessageBox::error( this, i18n( "Invalid command line switch!\nUnclosed quotation mark!" ) ); + return false; + } + + commandLineSwitches->addToHistory( cmdArgs ); + QStringList list = commandLineSwitches->historyItems(); + krConfig->setGroup("Archives"); + krConfig->writeEntry("Command Line Switches", list); + + inMap[ "CommandLineSwitches" ] = cmdArgs; + } + return true; +} + +#include "packguibase.moc" diff --git a/krusader/Dialogs/packguibase.h b/krusader/Dialogs/packguibase.h new file mode 100644 index 0000000..74364a6 --- /dev/null +++ b/krusader/Dialogs/packguibase.h @@ -0,0 +1,109 @@ +/*************************************************************************** + packguibase.h + ------------------- + copyright : (C) 2000 by Shie Erlich & Rafi Yanai + email : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef PACKGUIBASE_H +#define PACKGUIBASE_H + +#include +#include +#include + + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QCheckBox; +class QComboBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QToolButton; +class QSpinBox; +class QSlider; +class KHistoryCombo; + +class PackGUIBase : public QDialog +{ + Q_OBJECT + +public: + PackGUIBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~PackGUIBase(); + + QLabel* TextLabel3; + QLineEdit* nameData; + QComboBox* typeData; + QLabel* TextLabel5; + QLineEdit* dirData; + QToolButton* browseButton; + QWidget* advancedWidget; + QLabel* PixmapLabel1; + QLabel* TextLabel1; + QLabel* TextLabel4; + QLabel* TextLabel6; + QLabel* TextLabel7; + QLabel* TextLabel8; + QLabel* minLabel; + QLabel* maxLabel; + QLineEdit* password; + QLineEdit* passwordAgain; + QLabel* passwordConsistencyLabel; + QPushButton* okButton; + QPushButton* cancelButton; + QPushButton* advancedButton; + QCheckBox* encryptHeaders; + QCheckBox* multipleVolume; + QSpinBox* volumeSpinBox; + QComboBox* volumeUnitCombo; + QCheckBox* setCompressionLevel; + QSlider* compressionSlider; + KHistoryCombo *commandLineSwitches; + +public slots: + virtual void browse(); + virtual bool extraProperties( QMap & ); + + void expand(); + void checkConsistency(); + +protected: + QHBoxLayout* hbox; + QHBoxLayout* hbox_2; + QHBoxLayout* hbox_3; + QHBoxLayout* hbox_4; + QGridLayout* hbox_5; + QHBoxLayout* hbox_6; + QHBoxLayout* hbox_7; + QGridLayout* grid; + +private: + bool expanded; +}; + +#endif // PACKGUIBASE_H diff --git a/krusader/Dialogs/percentalsplitter.cpp b/krusader/Dialogs/percentalsplitter.cpp new file mode 100644 index 0000000..3a1354f --- /dev/null +++ b/krusader/Dialogs/percentalsplitter.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** + percentalsplitter.h - description + ------------------- + copyright : (C) 2006 + by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "percentalsplitter.h" +#include +#include +#include + +class PercentalSplitterToolTip : public QToolTip { +public: + PercentalSplitterToolTip( QWidget * parent ) : QToolTip( parent ) { + } + + virtual ~PercentalSplitterToolTip() { + remove( parentWidget() ); + } + + void maybeTip( const QPoint & point ) { + if( parentWidget()->inherits( "PercentalSplitter" ) ) { + PercentalSplitter *splitter = (PercentalSplitter *)parentWidget(); + + QString tipString = splitter->toolTipString(); + QRect rect = QRect( parentWidget()->rect() ); + + if( splitter->orientation() == Qt::Vertical ) { + rect.setY( splitter->sizes()[ 0 ] ); + rect.setHeight( splitter->handleWidth() ); + } + else { + rect.setX( splitter->sizes()[ 0 ] ); + rect.setWidth( splitter->handleWidth() ); + } + if( rect.contains( point ) ) + tip( rect, tipString ); + } + } +}; + +PercentalSplitter::PercentalSplitter( QWidget * parent, const char * name ) : QSplitter( parent, name ), label( 0 ), opaqueOldPos( -1 ) { + toolTip = new PercentalSplitterToolTip( this ); +} + +PercentalSplitter::~PercentalSplitter() { + delete toolTip; +} + +QString PercentalSplitter::toolTipString( int p ) { + QValueList values = sizes(); + if( values.count() == 2 && ( values[ 0 ] + values[ 1 ] != 0 ) ) { + if( p < 0 ) + p = values[ 0 ]; + int percent = (int)(((double)p / (double)( values[ 0 ] + values[ 1 ] )) * 10000. + 0.5); + return QString( "%1.%2%3" ).arg( percent / 100 ).arg( ( percent / 10 )%10 ).arg( percent % 10 ) + "%"; + } + return QString::null; +} + +void PercentalSplitter::setRubberband ( int p ) { + if( p == opaqueOldPos ) + return; + + QPainter paint( this ); + paint.setPen( gray ); + paint.setBrush( gray ); + paint.setRasterOp( XorROP ); + QRect r = contentsRect(); + const int rBord = 3; // customizable? + int hw = handleWidth(); + + if( orientation() == Qt::Horizontal ) { + if ( opaqueOldPos >= 0 ) { + if( label == 0 ) + paint.drawRect( opaqueOldPos + hw / 2 - rBord, r.y(), 2 * rBord, r.height() ); + else { + QPoint labelLoc = mapFromGlobal( labelLocation ); + if( labelLoc.y() > r.y() ) + paint.drawRect( opaqueOldPos + hw / 2 - rBord, r.y(), 2 * rBord, labelLoc.y() ); + if( labelLoc.y() + label->height() < r.height() ) + paint.drawRect( opaqueOldPos + hw / 2 - rBord, labelLoc.y() + label->height(), 2 * rBord, r.height() - labelLoc.y() - label->height() ); + } + } + } else { + if ( opaqueOldPos >= 0 ) { + if( label == 0 ) + paint.drawRect( r.x(), opaqueOldPos + hw / 2 - rBord, r.width(), 2 * rBord ); + else { + QPoint labelLoc = mapFromGlobal( labelLocation ); + if( labelLoc.x() > r.x() ) + paint.drawRect( r.x(), opaqueOldPos + hw / 2 - rBord, labelLoc.x(), 2 * rBord ); + if( labelLoc.x() + label->width() < r.width() ) + paint.drawRect( labelLoc.x() + label->width(), opaqueOldPos + hw / 2 - rBord, r.width() - labelLoc.x() - label->width(), 2 * rBord ); + } + } + } + + if( p < 0 ) { + if( label ) { + delete label; + label = 0; + } + } + else { + int scr = QApplication::desktop()->screenNumber( this ); + + if( label == 0 ) { + label = new QLabel( QApplication::desktop()->screen( scr ), "SplitterPercent", WStyle_StaysOnTop | + WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM ); + label->setMargin(1); + label->setAutoMask( FALSE ); + label->setFrameStyle( QFrame::Plain | QFrame::Box ); + label->setLineWidth( 1 ); + label->setAlignment( AlignAuto | AlignTop ); + label->setIndent(0); + + QFontMetrics fm = label->fontMetrics(); + label->setMinimumWidth( fm.width( "99.99%" ) + 5 ); + + label->polish(); + } + + label->setText( toolTipString( p ) ); + label->adjustSize(); + + if( orientation() == Qt::Horizontal ) { + labelLocation = mapToGlobal( QPoint( p - label->width()/2, r.y() + r.height()/2 ) ); + if( labelLocation.x() < 0 ) + labelLocation.setX( 0 ); + } else { + labelLocation = mapToGlobal( QPoint( r.x() + r.width()/2, p - label->height()/2 ) ); + if( labelLocation.y() < 0 ) + labelLocation.setY( 0 ); + } + +#ifdef Q_WS_MAC + QRect screen = QApplication::desktop()->availableGeometry( scr ); +#else + QRect screen = QApplication::desktop()->screenGeometry( scr ); +#endif + + QPoint labelLoc = mapFromGlobal( labelLocation ); + if( orientation() == Qt::Horizontal ) { + if( labelLocation.x() + label->width() > screen.width() ) + labelLocation.setX( screen.width() - label->width() ); + label->move( labelLocation ); + label->show(); + + if( labelLoc.y() > r.y() ) + paint.drawRect( p + hw / 2 - rBord, r.y(), 2 * rBord, labelLoc.y() ); + if( labelLoc.y() + label->height() < r.height() ) + paint.drawRect( p + hw / 2 - rBord, labelLoc.y() + label->height(), 2 * rBord, r.height() - labelLoc.y() - label->height() ); + } else { + if( labelLocation.y() + label->height() > screen.height() ) + labelLocation.setY( screen.height() - label->height() ); + label->move( labelLocation ); + label->show(); + + if( labelLoc.x() > r.x() ) + paint.drawRect( r.x(), p + hw / 2 - rBord, labelLoc.x(), 2 * rBord ); + if( labelLoc.x() + label->width() < r.width() ) + paint.drawRect( labelLoc.x() + label->width(), p + hw / 2 - rBord, r.width() - labelLoc.x() - label->width(), 2 * rBord ); + } + } + opaqueOldPos = p; +} + +#include "percentalsplitter.moc" diff --git a/krusader/Dialogs/percentalsplitter.h b/krusader/Dialogs/percentalsplitter.h new file mode 100644 index 0000000..cdbfb4d --- /dev/null +++ b/krusader/Dialogs/percentalsplitter.h @@ -0,0 +1,58 @@ +/*************************************************************************** + percentalsplitter.h - description + ------------------- + copyright : (C) 2006 + by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __PERCENTAL_SPLITTER__ +#define __PERCENTAL_SPLITTER__ + +#include +#include + +class PercentalSplitterToolTip; + +class PercentalSplitter : public QSplitter { + Q_OBJECT + +public: + PercentalSplitter( QWidget * parent = 0, const char * name = 0 ); + virtual ~PercentalSplitter(); + + QString toolTipString( int p = -1 ); + +protected: + virtual void setRubberband ( int p ); + +private: + PercentalSplitterToolTip * toolTip; + QLabel * label; + int opaqueOldPos; + QPoint labelLocation; +}; + +#endif /* __PERCENTAL_SPLITTER__ */ diff --git a/krusader/Dialogs/popularurls.cpp b/krusader/Dialogs/popularurls.cpp new file mode 100644 index 0000000..45b6162 --- /dev/null +++ b/krusader/Dialogs/popularurls.cpp @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../krusader.h" +#include "../krslots.h" +#include "popularurls.h" + +#define STARTING_RANK 20 +#define INCREASE 2 +#define DECREASE 1 + +PopularUrls::PopularUrls(QObject *parent, const char *name) : QObject(parent, name), + head(0), tail(0), count(0) { + dlg = new PopularUrlsDlg(); +} + +PopularUrls::~PopularUrls() { + clearList(); + delete dlg; +} + +void PopularUrls::clearList() { + if (head) { + UrlNodeP p=head, tmp; + while (p) { + tmp = p; + p=p->next; + delete tmp; + } + } + ranks.clear(); + head = tail = 0; +} + +void PopularUrls::save() { + KConfigGroupSaver svr(krConfig, "Private"); + // prepare the string list containing urls and int list with ranks + QStringList urlList; + QValueList rankList; + UrlNodeP p = head; + while (p) { + urlList << p->url.prettyURL(); + rankList << p->rank; + p = p->next; + } + krConfig->writeEntry("PopularUrls", urlList); + krConfig->writeEntry("PopularUrlsRank", rankList); +} + +void PopularUrls::load() { + KConfigGroupSaver svr(krConfig, "Private"); + QStringList urlList = krConfig->readListEntry("PopularUrls"); + QValueList rankList = krConfig->readIntListEntry("PopularUrlsRank"); + if (urlList.count() != rankList.count()) { + KMessageBox::error(krApp, i18n("Saved 'Popular Urls' are invalid. List will be cleared")); + return; + } + clearList(); + count = 0; + // iterate through both lists and + QStringList::Iterator uit; + QValueList::Iterator rit; + for (uit=urlList.begin(), rit=rankList.begin(); uit!=urlList.end() && rit!=rankList.end(); ++uit, ++rit) { + UrlNodeP node = new UrlNode; + node->url = KURL::fromPathOrURL( *uit ); + node->rank = *rit; + appendNode(node); + ranks.insert(*uit, node); + } +} + + +// returns a url list with the 'max' top popular urls +KURL::List PopularUrls::getMostPopularUrls(int max) { + // get at most 'max' urls + KURL::List list; + UrlNodeP p = head; + int tmp = 0; + if (maxUrls < max) max = maxUrls; // don't give more than maxUrls + while (p && tmp < max) { + list << p->url; + p = p->next; + ++tmp; + } + + return list; +} + +// adds a url to the list, or increase rank of an existing url, making +// sure to bump it up the list if needed +void PopularUrls::addUrl(const KURL& url) { + KURL tmpurl = url; + tmpurl.adjustPath(1); // make a uniform trailing slash policy + UrlNodeP pnode; + + decreaseRanks(); + if (!head) { // if the list is empty ... (assumes dict to be empty as well) + pnode = new UrlNode; + pnode->rank = STARTING_RANK; + pnode->url = tmpurl; + appendNode(pnode); + ranks.insert(tmpurl.url(), head); + } else { + pnode = ranks.find(tmpurl.url()); + if (!pnode) { // is the added url new? if so, append it + pnode = new UrlNode; + pnode->rank = STARTING_RANK; + pnode->url = tmpurl; + appendNode(pnode); + ranks.insert(tmpurl.url(), pnode); + } else { + pnode->rank += INCREASE; + } + } + + // do we need to change location for this one? + relocateIfNeeded(pnode); + + // too many urls? + if (count > maxUrls) removeNode(tail); + + //dumpList(); +} + +// checks if 'node' needs to be bumped-up the ranking list and does it if needed +void PopularUrls::relocateIfNeeded(UrlNodeP node) { + if (node->prev && (node->prev->rank < node->rank)) { + // iterate until we find the correct place to put it + UrlNodeP tmp = node->prev->prev; + while (tmp) { + if (tmp->rank >= node->rank) + break; // found it! + else tmp = tmp->prev; + } + // now, if tmp isn't null, we need to move node to tmp->next + // else move it to become head + removeNode(node); + insertNode(node, tmp); + } +} + + +// iterate over the list, decreasing each url's rank +// this is very naive, but a 1..30 for loop is acceptable (i hope) +void PopularUrls::decreaseRanks() { + if (head) { + UrlNodeP p=head; + while (p) { + if (p->rank-DECREASE>=0) + p->rank -= DECREASE; + else p->rank = 0; + p=p->next; + } + } +} + +// removes a node from the list, but doesn't free memory! +// note: this will be buggy in case the list becomes empty (which should never happen) +void PopularUrls::removeNode(UrlNodeP node) { + if (node->prev) { + if (tail == node) tail = node->prev; + node->prev->next = node->next; + } + if (node->next) { + if (head == node) head = node->next; + node->next->prev = node->prev; + } + --count; +} + +void PopularUrls::insertNode(UrlNodeP node, UrlNodeP after) { + if (!after) { // make node head + node->next = head; + node->prev = 0; + head->prev = node; + head = node; + } else { + if (tail == after) tail = node; + node->prev = after; + node->next = after->next; + if( node->next ) { + after->next->prev = node; + after->next = node; + } + } + ++count; +} + +// appends 'node' to the end of the list, collecting garbage if needed +void PopularUrls::appendNode(UrlNodeP node) { + if (!tail) { // creating the first element + head = tail = node; + node->prev = node->next = 0; + } else { + node->next = 0; + node->prev = tail; + tail->next = node; + tail = node; + } + ++count; +} + +void PopularUrls::dumpList() { + UrlNodeP p = head; + printf("====start %d====\n",count); + while (p) { + printf("%d : %s\n", p->rank, p->url.url().latin1()); + p = p->next; + } + fflush(stdout); +} + +void PopularUrls::showDialog() { + KURL::List list = getMostPopularUrls(maxUrls); + dlg->run(list); + if (dlg->result() == -1) return; + SLOTS->refresh(list[dlg->result()]); + //printf("running %s\n", list[dlg->result()].url().latin1());fflush(stdout); +} + +// ===================================== PopularUrlsDlg ====================================== +PopularUrlsDlg::PopularUrlsDlg(): + KDialogBase(Plain, i18n("Popular Urls"), Close, KDialogBase::NoDefault, krApp) { + QGridLayout *layout = new QGridLayout( plainPage(), 0, KDialog::spacingHint() ); + + // listview to contain the urls + urls = new KListView(plainPage()); + urls->header()->hide(); + urls->addColumn(""); + urls->setSorting(-1); + urls->setVScrollBarMode(QScrollView::AlwaysOn); + + // quick search + QToolButton *btn = new QToolButton(plainPage()); + btn->setIconSet(SmallIcon("locationbar_erase")); + search = new KListViewSearchLine(plainPage(), urls); + search->setTrapReturnKey(true); + QLabel *lbl = new QLabel(search, i18n(" &Search: "), plainPage()); + + layout->addWidget(btn,0,0); + layout->addWidget(lbl,0,1); + layout->addWidget(search,0,2); + layout->addMultiCellWidget(urls,1,1,0,2); + setMaximumSize(600, 500); + + setTabOrder(search, urls); + setTabOrder(urls, actionButton(Close)); + + connect(urls, SIGNAL(executed(QListViewItem*)), + this, SLOT(slotItemSelected(QListViewItem*))); + connect(urls, SIGNAL(returnPressed(QListViewItem*)), + this, SLOT(slotItemSelected(QListViewItem*))); + connect(btn, SIGNAL(clicked()), search, SLOT(clear())); + connect(search, SIGNAL(returnPressed(const QString&)), + this, SLOT(slotSearchReturnPressed(const QString&))); +} + +void PopularUrlsDlg::slotItemSelected(QListViewItem *it) { + selection = urls->itemIndex(it); + accept(); +} + +void PopularUrlsDlg::slotSearchReturnPressed(const QString&) { + urls->setFocus(); + // select the first visible item + QListViewItemIterator it( urls ); + while ( it.current() ) { + if ( it.current()->isVisible() ) { + urls->setSelected(it.current(), true); + urls->setCurrentItem(it.current()); + break; + } else ++it; + } +} + +PopularUrlsDlg::~PopularUrlsDlg() { + delete search; + delete urls; +} + +void PopularUrlsDlg::run(KURL::List list) { + // populate the listview + urls->clear(); + KURL::List::Iterator it; + for (it = list.begin(); it!=list.end(); ++it) { + KListViewItem *item = new KListViewItem(urls, urls->lastItem()); + item->setText(0, (*it).isLocalFile() ? (*it).path() : (*it).prettyURL()); + item->setPixmap(0, (*it).isLocalFile() ? SmallIcon("folder") : SmallIcon("folder_html")); + } + //urls->setCurrentItem(urls->firstChild()); + //urls->setSelected(urls->firstChild(), true); + setMinimumSize(urls->sizeHint().width()+45, 400); + + search->clear(); + search->setFocus(); + selection = -1; + exec(); +} + +#include "popularurls.moc" diff --git a/krusader/Dialogs/popularurls.h b/krusader/Dialogs/popularurls.h new file mode 100644 index 0000000..4b908ab --- /dev/null +++ b/krusader/Dialogs/popularurls.h @@ -0,0 +1,84 @@ +#ifndef POPULARURLS_H +#define POPULARURLS_H + +#include +#include +#include +#include + +// the class holds a list of most popular links in a dual data structure +// * linked list, with head and tail: for fast append/prepend support +// * dictionary that maps urls to list nodes: to save the need to iterate +// over the list in order to find the correct node for each new url +// +// also, the class holds a maximum number of urls. two variables affect this: +// * maxUrls - the num. of urls the user can see +// * hardLimit - the actual number of urls kept. +// when the number of urls reaches hardLimit, a garbage collection is done and +// the bottom (hardLimit-maxUrls) entries are removed from the list +typedef struct _UrlNode* UrlNodeP; +typedef struct _UrlNode { + UrlNodeP prev; + KURL url; + int rank; + UrlNodeP next; +} UrlNode; + +class PopularUrlsDlg; + +class PopularUrls : public QObject { + Q_OBJECT +public: + PopularUrls(QObject *parent = 0, const char *name = 0); + ~PopularUrls(); + void save(); + void load(); + void addUrl(const KURL& url); + KURL::List getMostPopularUrls(int max); + +public slots: + void showDialog(); + +protected: + // NOTE: the following methods append/insert/remove a node to the list + // but NEVER free memory or allocate memory! + void appendNode(UrlNodeP node); + void insertNode(UrlNodeP node, UrlNodeP after); + void removeNode(UrlNodeP node); + void relocateIfNeeded(UrlNodeP node); + void clearList(); + void dumpList(); + void decreaseRanks(); + +private: + UrlNodeP head, tail; + QDict ranks; // actually holds UrlNode* + int count; + static const int maxUrls = 30; + PopularUrlsDlg *dlg; +}; + +class KListView; +class KListViewSearchLine; + +class PopularUrlsDlg: public KDialogBase { + Q_OBJECT +public: + PopularUrlsDlg(); + ~PopularUrlsDlg(); + void run(KURL::List list); // use this to open the dialog + inline int result() const { return selection; } // returns index 0 - topmost, or -1 + + +protected slots: + void slotSearchReturnPressed(const QString&); + void slotItemSelected(QListViewItem *it); + +private: + KListView *urls; + KListViewSearchLine *search; + int selection; +}; + + +#endif diff --git a/krusader/DiskUsage/Makefile.am b/krusader/DiskUsage/Makefile.am new file mode 100644 index 0000000..691d045 --- /dev/null +++ b/krusader/DiskUsage/Makefile.am @@ -0,0 +1,17 @@ +SUBDIRS = \ + radialMap \ + filelightParts + + +noinst_LIBRARIES = libDiskUsage.a + +INCLUDES = $(all_includes) + +libDiskUsage_a_METASOURCES = AUTO + +libDiskUsage_a_SOURCES = \ + diskusagegui.cpp \ + diskusage.cpp \ + dulistview.cpp \ + dulines.cpp \ + dufilelight.cpp diff --git a/krusader/DiskUsage/diskusage.cpp b/krusader/DiskUsage/diskusage.cpp new file mode 100644 index 0000000..b58f2d6 --- /dev/null +++ b/krusader/DiskUsage/diskusage.cpp @@ -0,0 +1,1147 @@ +/*************************************************************************** + diskusage.cpp - description + ------------------- + copyright : (C) 2004 + by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "diskusage.h" +#include "../VFS/krpermhandler.h" +#include "../VFS/krvfshandler.h" +#include "../kicons.h" +#include "../defaults.h" +#include "../krusader.h" +#include "../krusaderview.h" +#include "../Panel/listpanel.h" +#include "../Panel/panelfunc.h" +#include "filelightParts/Config.h" + +#include "dulines.h" +#include "dulistview.h" +#include "dufilelight.h" + +// these are the values that will exist in the menu +#define DELETE_ID 90 +#define EXCLUDE_ID 91 +#define PARENT_DIR_ID 92 +#define NEW_SEARCH_ID 93 +#define REFRESH_ID 94 +#define STEP_INTO_ID 95 +#define INCLUDE_ALL_ID 96 +#define VIEW_POPUP_ID 97 +#define LINES_VIEW_ID 98 +#define DETAILED_VIEW_ID 99 +#define FILELIGHT_VIEW_ID 100 +#define NEXT_VIEW_ID 101 +#define PREVIOUS_VIEW_ID 102 +#define ADDITIONAL_POPUP_ID 103 + +#define MAX_FILENUM 100 + +LoaderWidget::LoaderWidget( QWidget *parent, const char *name ) : QScrollView( parent, name ), cancelled( false ) +{ + viewport()->setEraseColor( Qt::white ); + widget = new QWidget( parent ); + + QGridLayout *loaderLayout = new QGridLayout( widget ); + loaderLayout->setSpacing( 0 ); + loaderLayout->setMargin( 0 ); + + QGroupBox *loaderBox = new QGroupBox( widget, "loaderGroupBox" ); + loaderBox->setFrameShape( QGroupBox::Box ); + loaderBox->setFrameShadow( QGroupBox::Sunken ); + loaderBox->setColumnLayout(0, Qt::Vertical ); + loaderBox->layout()->setSpacing( 0 ); + loaderBox->layout()->setMargin( 0 ); + loaderBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + loaderBox->setFrameStyle( QFrame::Panel + QFrame::Raised ); + loaderBox->setLineWidth( 2 ); + + QGridLayout *synchGrid = new QGridLayout( loaderBox->layout() ); + synchGrid->setSpacing( 6 ); + synchGrid->setMargin( 11 ); + + QLabel *titleLabel = new QLabel( i18n( "Loading Usage Information" ), loaderBox, "titleLabel" ); + titleLabel->setAlignment( Qt::AlignHCenter ); + synchGrid->addMultiCellWidget( titleLabel, 0, 0, 0, 1 ); + + QLabel *filesLabel = new QLabel( i18n( "Files:" ), loaderBox, "filesLabel" ); + filesLabel->setFrameShape( QLabel::StyledPanel ); + filesLabel->setFrameShadow( QLabel::Sunken ); + synchGrid->addWidget( filesLabel, 1, 0 ); + + QLabel *directoriesLabel = new QLabel( i18n( "Directories:" ), loaderBox, "directoriesLabel" ); + directoriesLabel->setFrameShape( QLabel::StyledPanel ); + directoriesLabel->setFrameShadow( QLabel::Sunken ); + synchGrid->addWidget( directoriesLabel, 2, 0 ); + + QLabel *totalSizeLabel = new QLabel( i18n( "Total Size:" ), loaderBox, "totalSizeLabel" ); + totalSizeLabel->setFrameShape( QLabel::StyledPanel ); + totalSizeLabel->setFrameShadow( QLabel::Sunken ); + synchGrid->addWidget( totalSizeLabel, 3, 0 ); + + files = new QLabel( loaderBox, "files" ); + files->setFrameShape( QLabel::StyledPanel ); + files->setFrameShadow( QLabel::Sunken ); + files->setAlignment( Qt::AlignRight ); + synchGrid->addWidget( files, 1, 1 ); + + directories = new QLabel( loaderBox, "directories" ); + directories->setFrameShape( QLabel::StyledPanel ); + directories->setFrameShadow( QLabel::Sunken ); + directories->setAlignment( Qt::AlignRight ); + synchGrid->addWidget( directories, 2, 1 ); + + totalSize = new QLabel( loaderBox, "totalSize" ); + totalSize->setFrameShape( QLabel::StyledPanel ); + totalSize->setFrameShadow( QLabel::Sunken ); + totalSize->setAlignment( Qt::AlignRight ); + synchGrid->addWidget( totalSize, 3, 1 ); + + int width; + searchedDirectory = new KSqueezedTextLabel( loaderBox, "searchedDirectory" ); + searchedDirectory->setFrameShape( QLabel::StyledPanel ); + searchedDirectory->setFrameShadow( QLabel::Sunken ); + searchedDirectory->setMinimumWidth( width = QFontMetrics(searchedDirectory->font()).width("W") * 30 ); + searchedDirectory->setMaximumWidth( width ); + synchGrid->addMultiCellWidget( searchedDirectory, 4, 4, 0, 1 ); + + QFrame *line = new QFrame( loaderBox, "duLine" ); + line->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + synchGrid->addMultiCellWidget( line, 5, 5, 0, 1 ); + + QHBox *hbox = new QHBox( loaderBox, "hbox" ); + QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ); + hbox->layout()->addItem( spacer ); + QPushButton *cancelButton = new QPushButton( hbox, "cancelButton" ); + cancelButton->setText( i18n( "Cancel" ) ); + synchGrid->addWidget( hbox, 6, 1 ); + + loaderLayout->addWidget( loaderBox, 0, 0 ); + + addChild( widget ); + + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( slotCancelled() ) ); +} + +void LoaderWidget::resizeEvent ( QResizeEvent *e ) +{ + QScrollView::resizeEvent( e ); + + int x = ( viewport()->width() - widget->width() ) / 2; + int y = ( viewport()->height() - widget->height() ) / 2; + if( x < 0 ) x=0; + if( y < 0 ) y=0; + + moveChild( widget, x, y ); +} + +void LoaderWidget::init() +{ + cancelled = false; +} + +void LoaderWidget::setCurrentURL( KURL url ) +{ + searchedDirectory->setText( vfs::pathOrURL( url, 1) ); +} + +void LoaderWidget::setValues( int fileNum, int dirNum, KIO::filesize_t total ) +{ + files->setText( QString("%1").arg( fileNum ) ); + directories->setText( QString("%1").arg( dirNum ) ); + totalSize->setText( QString("%1").arg( KRpermHandler::parseSize( total ).stripWhiteSpace() ) ); +} + +void LoaderWidget::slotCancelled() +{ + cancelled = true; +} + +DiskUsage::DiskUsage( QString confGroup, QWidget *parent, char *name ) : QWidgetStack( parent, name ), + currentDirectory( 0 ), root( 0 ), configGroup( confGroup ), loading( false ), + abortLoading( false ), clearAfterAbort( false ), deleting( false ), searchVfs( 0 ) +{ + listView = new DUListView( this, "DU ListView" ); + lineView = new DULines( this, "DU LineView" ); + filelightView = new DUFilelight( this, "Filelight canvas" ); + loaderView = new LoaderWidget( this, "Loading view" ); + + addWidget( listView ); + addWidget( lineView ); + addWidget( filelightView ); + addWidget( loaderView ); + + setView( VIEW_LINES ); + + Filelight::Config::read(); + propertyMap.setAutoDelete( true ); + + connect( &loadingTimer, SIGNAL( timeout() ), this, SLOT( slotLoadDirectory() ) ); +} + +DiskUsage::~DiskUsage() +{ + if( root ) + delete root; + + if( listView ) // don't remove these lines. The module will crash at exit if removed + delete listView; + if( lineView ) + delete lineView; + if( filelightView ) + delete filelightView; +} + +void DiskUsage::load( KURL baseDir ) +{ + if( searchVfs && !searchVfs->vfs_canDelete() ) { + return; + } + + fileNum = dirNum = 0; + currentSize = 0; + + emit status( i18n( "Loading the disk usage information..." ) ); + + clear(); + + baseURL = baseDir; + baseURL.setPath( baseDir.path( -1 ) ); + + root = new Directory( baseURL.fileName(), vfs::pathOrURL( baseDir ) ); + + directoryStack.clear(); + parentStack.clear(); + + directoryStack.push( "" ); + parentStack.push( root ); + + if( searchVfs ) + { + delete searchVfs; + searchVfs = 0; + } + searchVfs = KrVfsHandler::getVfs( baseDir ); + if( searchVfs == 0 ) + { + loading = abortLoading = clearAfterAbort = false; + emit loadFinished( false ); + return; + } + + searchVfs->vfs_setQuiet( true ); + currentVfile = 0; + + if( !loading ) + { + viewBeforeLoad = activeView; + setView( VIEW_LOADER ); + } + + loading = true; + + loaderView->init(); + loaderView->setCurrentURL( baseURL ); + loaderView->setValues( fileNum, dirNum, currentSize ); + + loadingTimer.start( 0, true ); +} + +void DiskUsage::slotLoadDirectory() +{ + if( searchVfs && !searchVfs->vfs_canDelete() ) { // recursive call from slotLoadDirectory? + loadingTimer.start( 100, true ); // as it can cause crash, ignore it and wait while + return; // the recursion finishes + } + if( ( currentVfile == 0 && directoryStack.isEmpty() ) || loaderView->wasCancelled() || abortLoading ) + { + if( searchVfs ) + delete searchVfs; + + searchVfs = 0; + currentVfile = 0; + + setView( viewBeforeLoad ); + + if( clearAfterAbort ) + clear(); + else { + calculateSizes(); + changeDirectory( root ); + } + + emit loadFinished( !( loaderView->wasCancelled() || abortLoading ) ); + + loading = abortLoading = clearAfterAbort = false; + } + else if( loading ) + { + for( int counter = 0; counter != MAX_FILENUM; counter ++ ) + { + if( currentVfile == 0 ) + { + if( directoryStack.isEmpty() ) + break; + + dirToCheck = directoryStack.pop(); + currentParent = parentStack.pop(); + + contentMap.insert( dirToCheck, currentParent ); + + KURL url = baseURL; + + if( !dirToCheck.isEmpty() ) + url.addPath( dirToCheck ); + +#if defined(BSD) + if ( url.isLocalFile() && url.path().left( 7 ) == "/procfs" ) + break; +#else + if ( url.isLocalFile() && url.path().left( 5 ) == "/proc" ) + break; +#endif + + loaderView->setCurrentURL( url ); + + if( !searchVfs->vfs_refresh( url ) ) + break; + + dirNum++; + + currentVfile = searchVfs->vfs_getFirstFile(); + } + else + { + fileNum++; + File *newItem = 0; + + QString mime = currentVfile->vfile_getMime(true); // fast == not using mimetype magic + + if( currentVfile->vfile_isDir() && !currentVfile->vfile_isSymLink() ) + { + newItem = new Directory( currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(), + currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(), + currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(), + mime ); + directoryStack.push( (dirToCheck.isEmpty() ? "" : dirToCheck + "/" )+ currentVfile->vfile_getName() ); + parentStack.push( dynamic_cast( newItem ) ); + } + else + { + newItem = new File( currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(), + currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(), + currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(), + mime ); + currentSize += currentVfile->vfile_getSize(); + } + currentParent->append( newItem ); + + currentVfile = searchVfs->vfs_getNextFile(); + } + } + + loaderView->setValues( fileNum, dirNum, currentSize ); + loadingTimer.start( 0, true ); + } +} + +void DiskUsage::stopLoad() +{ + abortLoading = true; +} + +void DiskUsage::close() +{ + if( loading ) + { + abortLoading = true; + clearAfterAbort = true; + } +} + +void DiskUsage::dirUp() +{ + if( currentDirectory != 0 ) + { + if ( currentDirectory->parent() != 0 ) + changeDirectory( (Directory *)(currentDirectory->parent()) ); + else + { + KURL up = baseURL.upURL(); + + if( KMessageBox::questionYesNo( this, i18n( "Stepping into the parent directory requires " + "loading the content of the \"%1\" URL. Do you wish " + "to continue?" ) + .arg( vfs::pathOrURL( up ) ), + i18n( "Krusader::DiskUsage" ), KStdGuiItem::yes(), + KStdGuiItem::no(), "DiskUsageLoadParentDir" + ) == KMessageBox::Yes ) + load( up ); + } + } +} + +Directory * DiskUsage::getDirectory( QString dir ) +{ + while( dir.endsWith( "/" ) ) + dir.truncate( dir.length() - 1 ); + + if( dir.isEmpty() ) + return root; + + return contentMap.find( dir ); +} + +File * DiskUsage::getFile( QString path ) +{ + if( path == "" ) + return root; + + QString dir = path; + + int ndx = path.findRev( '/' ); + QString file = path.mid( ndx + 1 ); + + if( ndx == -1 ) + dir = ""; + else + dir.truncate( ndx ); + + Directory *dirEntry = getDirectory( dir ); + if( dirEntry == 0 ) + return 0; + + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + if( (*it)->name() == file ) + return *it; + + return 0; +} + +void DiskUsage::clear() +{ + baseURL = KURL(); + emit clearing(); + propertyMap.clear(); + contentMap.clear(); + if( root ) + delete root; + root = currentDirectory = 0; +} + +int DiskUsage::calculateSizes( Directory *dirEntry, bool emitSig, int depth ) +{ + int changeNr = 0; + + if( dirEntry == 0 ) + dirEntry = root; + + KIO::filesize_t own = 0, total = 0; + + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + { + File * item = *it; + + if( !item->isExcluded() ) + { + if( item->isDir() ) + changeNr += calculateSizes( dynamic_cast( item ), emitSig, depth + 1 ); + else + own += item->size(); + + total += item->size(); + } + } + + KIO::filesize_t oldOwn = dirEntry->ownSize(), oldTotal = dirEntry->size(); + dirEntry->setSizes( total, own ); + + if( dirEntry == currentDirectory ) + currentSize = total; + + if( emitSig && ( own != oldOwn || total != oldTotal ) ) { + emit changed( dirEntry ); + changeNr++; + } + + if( depth == 0 && changeNr != 0 ) + emit changeFinished(); + return changeNr; +} + +int DiskUsage::exclude( File *file, bool calcPercents, int depth ) +{ + int changeNr = 0; + + if( !file->isExcluded() ) + { + file->exclude( true ); + emit changed( file ); + changeNr++; + + if( file->isDir() ) + { + Directory *dir = dynamic_cast( file ); + for( Iterator it = dir->iterator(); it != dir->end(); ++it ) + changeNr += exclude( *it, false, depth + 1 ); + } + } + + if( calcPercents ) + { + calculateSizes( root, true ); + calculatePercents( true ); + createStatus(); + } + + if( depth == 0 && changeNr != 0 ) + emit changeFinished(); + + return changeNr; +} + +int DiskUsage::include( Directory *dir, int depth ) +{ + int changeNr = 0; + + if( dir == 0 ) + return 0; + + for( Iterator it = dir->iterator(); it != dir->end(); ++it ) + { + File *item = *it; + + if( item->isDir() ) + changeNr += include( dynamic_cast( item ), depth + 1 ); + + if( item->isExcluded() ) + { + item->exclude( false ); + emit changed( item ); + changeNr++; + } + } + + if( depth == 0 && changeNr != 0 ) + emit changeFinished(); + + return changeNr; +} + +void DiskUsage::includeAll() +{ + include( root ); + calculateSizes( root, true ); + calculatePercents( true ); + createStatus(); +} + +int DiskUsage::del( File *file, bool calcPercents, int depth ) +{ + int deleteNr = 0; + + if( file == root ) + return 0; + + krConfig->setGroup( "General" ); + bool trash = krConfig->readBoolEntry( "Move To Trash", _MoveToTrash ); + KURL url = vfs::fromPathOrURL( file->fullPath() ); + + if( calcPercents ) + { + // now ask the user if he want to delete: + krConfig->setGroup( "Advanced" ); + if ( krConfig->readBoolEntry( "Confirm Delete", _ConfirmDelete ) ) { + QString s, b; + if ( trash && url.isLocalFile() ) { + s = i18n( "Do you really want to move this item to the trash?" ); + b = i18n( "&Trash" ); + } else { + s = i18n( "Do you really want to delete this item?" ); + b = i18n( "&Delete" ); + } + + QStringList name; + name.append( file->fullPath() ); + // show message + // note: i'm using continue and not yes/no because the yes/no has cancel as default button + if ( KMessageBox::warningContinueCancelList( krApp, s, name, i18n( "Warning" ), b ) != KMessageBox::Continue ) + return 0; + } + + emit status( i18n( "Deleting %1..." ).arg( file->name() ) ); + } + + if( file == currentDirectory ) + dirUp(); + + if( file->isDir() ) + { + Directory *dir = dynamic_cast( file ); + + Iterator it; + while( ( it = dir->iterator() ) != dir->end() ) + deleteNr += del( *it, false, depth + 1 ); + + QString path; + for( const Directory *d = (Directory*)file; d != root && d && d->parent() != 0; d = d->parent() ) + { + if( !path.isEmpty() ) + path = "/" + path; + + path = d->name() + path; + } + + contentMap.remove( path ); + } + + emit deleted( file ); + deleteNr++; + + QGuardedPtr job; + + if( trash ) + { +#if KDE_IS_VERSION(3,4,0) + job = KIO::trash( url, true ); +#else + job = new KIO::CopyJob( url,KGlobalSettings::trashPath(),KIO::CopyJob::Move,false,true ); +#endif + connect(job,SIGNAL(result(KIO::Job*)),krApp,SLOT(changeTrashIcon())); + } + else + { + job = new KIO::DeleteJob( vfs::fromPathOrURL( file->fullPath() ), false, false); + } + + deleting = true; // during qApp->processEvent strange things can occur + grabMouse(); // that's why we disable the mouse and keyboard events + grabKeyboard(); + + while( !job.isNull() ) + qApp->processEvents(); + + releaseMouse(); + releaseKeyboard(); + deleting = false; + + ((Directory *)(file->parent()))->remove( file ); + delete file; + + if( depth == 0 ) + createStatus(); + + if( calcPercents ) + { + calculateSizes( root, true ); + calculatePercents( true ); + createStatus(); + emit enteringDirectory( currentDirectory ); + } + + if( depth == 0 && deleteNr != 0 ) + emit deleteFinished(); + + return deleteNr; +} + +void * DiskUsage::getProperty( File *item, QString key ) +{ + Properties * props = propertyMap.find( item ); + if( props == 0 ) + return 0; + return props->find( key ); +} + +void DiskUsage::addProperty( File *item, QString key, void * prop ) +{ + Properties * props = propertyMap.find( item ); + if( props == 0 ) + { + props = new Properties(); + propertyMap.insert( item, props ); + } + props->insert( key, prop ); +} + +void DiskUsage::removeProperty( File *item, QString key ) +{ + Properties * props = propertyMap.find( item ); + if( props == 0 ) + return; + props->remove( key ); + if( props->count() == 0 ) + propertyMap.remove( item ); +} + +void DiskUsage::createStatus() +{ + Directory *dirEntry = currentDirectory; + + if( dirEntry == 0 ) + return; + + KURL url = baseURL; + if( dirEntry != root ) + url.addPath( dirEntry->directory() ); + + emit status( i18n( "Current directory:%1, Total size:%2, Own size:%3" ) + .arg( vfs::pathOrURL( url, -1 ) ) + .arg( " "+KRpermHandler::parseSize( dirEntry->size() ) ) + .arg( " "+KRpermHandler::parseSize( dirEntry->ownSize() ) ) ); +} + +void DiskUsage::changeDirectory( Directory *dir ) +{ + currentDirectory = dir; + + currentSize = dir->size(); + calculatePercents( true, dir ); + + createStatus(); + emit enteringDirectory( dir ); +} + +Directory* DiskUsage::getCurrentDir() +{ + return currentDirectory; +} + +void DiskUsage::rightClickMenu( File *fileItem, KPopupMenu *addPopup, QString addPopupName ) +{ + KPopupMenu popup( this ); + + popup.insertTitle( i18n("Disk Usage")); + + if( fileItem != 0 ) + { + popup.insertItem( i18n("Delete"), DELETE_ID); + popup.setAccel( Key_Delete, DELETE_ID ); + popup.insertItem( i18n("Exclude"), EXCLUDE_ID); + popup.setAccel( CTRL + Key_E, EXCLUDE_ID ); + popup.insertSeparator(); + } + + popup.insertItem( i18n("Up one directory"), PARENT_DIR_ID); + popup.setAccel( SHIFT + Key_Up, PARENT_DIR_ID ); + popup.insertItem( i18n("New search"), NEW_SEARCH_ID); + popup.setAccel( CTRL + Key_N, NEW_SEARCH_ID ); + popup.insertItem( i18n("Refresh"), REFRESH_ID); + popup.setAccel( CTRL + Key_R, REFRESH_ID ); + popup.insertItem( i18n("Include all"), INCLUDE_ALL_ID); + popup.setAccel( CTRL + Key_I, INCLUDE_ALL_ID ); + popup.insertItem( i18n("Step into"), STEP_INTO_ID); + popup.setAccel( SHIFT + Key_Down, STEP_INTO_ID ); + popup.insertSeparator(); + + + if( addPopup != 0 ) + { + popup.insertItem( QPixmap(), addPopup, ADDITIONAL_POPUP_ID ); + popup.changeItem( ADDITIONAL_POPUP_ID, addPopupName ); + } + + KPopupMenu viewPopup; + viewPopup.insertItem(i18n("Lines"), LINES_VIEW_ID); + viewPopup.setAccel( CTRL + Key_L, LINES_VIEW_ID ); + viewPopup.insertItem(i18n("Detailed"), DETAILED_VIEW_ID); + viewPopup.setAccel( CTRL + Key_D, DETAILED_VIEW_ID ); + viewPopup.insertItem(i18n("Filelight"), FILELIGHT_VIEW_ID); + viewPopup.setAccel( CTRL + Key_F, FILELIGHT_VIEW_ID ); + viewPopup.insertSeparator(); + viewPopup.insertItem(i18n("Next"), NEXT_VIEW_ID); + viewPopup.setAccel( SHIFT + Key_Right, NEXT_VIEW_ID ); + viewPopup.insertItem(i18n("Previous"), PREVIOUS_VIEW_ID); + viewPopup.setAccel( SHIFT + Key_Left, PREVIOUS_VIEW_ID ); + + popup.insertItem( QPixmap(), &viewPopup, VIEW_POPUP_ID ); + popup.changeItem( VIEW_POPUP_ID, i18n( "View" ) ); + + int result=popup.exec(QCursor::pos()); + + executeAction( result, fileItem ); +} + +void DiskUsage::executeAction( int action, File * fileItem ) +{ + // check out the user's option + switch ( action ) + { + case DELETE_ID: + if( fileItem ) + del( fileItem ); + break; + case EXCLUDE_ID: + if( fileItem ) + exclude( fileItem ); + break; + case PARENT_DIR_ID: + dirUp(); + break; + case NEW_SEARCH_ID: + emit newSearch(); + break; + case REFRESH_ID: + load( baseURL ); + break; + case INCLUDE_ALL_ID: + includeAll(); + break; + case STEP_INTO_ID: + { + QString uri; + if( fileItem && fileItem->isDir() ) + uri = fileItem->fullPath(); + else + uri = currentDirectory->fullPath(); + ACTIVE_FUNC->openUrl(vfs::fromPathOrURL( uri )); + } + break; + case LINES_VIEW_ID: + setView( VIEW_LINES ); + break; + case DETAILED_VIEW_ID: + setView( VIEW_DETAILED ); + break; + case FILELIGHT_VIEW_ID: + setView( VIEW_FILELIGHT ); + break; + case NEXT_VIEW_ID: + setView( ( activeView + 1 ) % 3 ); + break; + case PREVIOUS_VIEW_ID: + setView( ( activeView + 2 ) % 3 ); + break; + } + visibleWidget()->setFocus(); +} + +void DiskUsage::keyPressEvent( QKeyEvent *e ) +{ + if( activeView != VIEW_LOADER ) + { + switch ( e->key() ) + { + case Key_E: + if( e->state() == ControlButton ) + { + executeAction( EXCLUDE_ID, getCurrentFile() ); + return; + } + case Key_D: + if( e->state() == ControlButton ) + { + executeAction( DETAILED_VIEW_ID ); + return; + } + case Key_F: + if( e->state() == ControlButton ) + { + executeAction( FILELIGHT_VIEW_ID ); + return; + } + case Key_I: + if( e->state() == ControlButton ) + { + executeAction( INCLUDE_ALL_ID ); + return; + } + break; + case Key_L: + if( e->state() == ControlButton ) + { + executeAction( LINES_VIEW_ID ); + return; + } + case Key_N: + if( e->state() == ControlButton ) + { + executeAction( NEW_SEARCH_ID ); + return; + } + break; + case Key_R: + if( e->state() == ControlButton ) + { + executeAction( REFRESH_ID ); + return; + } + break; + case Key_Up: + if( e->state() == ShiftButton ) + { + executeAction( PARENT_DIR_ID ); + return; + } + break; + case Key_Down: + if( e->state() == ShiftButton ) + { + executeAction( STEP_INTO_ID ); + return; + } + break; + case Key_Left: + if( e->state() == ShiftButton ) + { + executeAction( PREVIOUS_VIEW_ID ); + return; + } + break; + case Key_Right: + if( e->state() == ShiftButton ) + { + executeAction( NEXT_VIEW_ID ); + return; + } + break; + case Key_Delete: + if( !e->state() ) + { + executeAction( DELETE_ID, getCurrentFile() ); + return; + } + case Key_Plus: + if( activeView == VIEW_FILELIGHT ) + { + filelightView->zoomIn(); + return; + } + break; + case Key_Minus: + if( activeView == VIEW_FILELIGHT ) + { + filelightView->zoomOut(); + return; + } + break; + } + } + QWidgetStack::keyPressEvent( e ); +} + +QPixmap DiskUsage::getIcon( QString mime ) +{ + QPixmap icon; + + if ( !QPixmapCache::find( mime, icon ) ) + { + // get the icon. + if ( mime == "Broken Link !" ) + icon = FL_LOADICON( "file_broken" ); + else + icon = FL_LOADICON( KMimeType::mimeType( mime ) ->icon( QString::null, true ) ); + + // insert it into the cache + QPixmapCache::insert( mime, icon ); + } + return icon; +} + +int DiskUsage::calculatePercents( bool emitSig, Directory *dirEntry, int depth ) +{ + int changeNr = 0; + + if( dirEntry == 0 ) + dirEntry = root; + + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + { + File *item = *it; + + if( !item->isExcluded() ) + { + int newPerc; + + if( dirEntry->size() == 0 && item->size() == 0 ) + newPerc = 0; + else if( dirEntry->size() == 0 ) + newPerc = -1; + else + newPerc = (int)((double)item->size() / (double)currentSize * 10000. + 0.5); + + int oldPerc = item->intPercent(); + item->setPercent( newPerc ); + + if( emitSig && newPerc != oldPerc ) { + emit changed( item ); + changeNr++; + } + + if( item->isDir() ) + changeNr += calculatePercents( emitSig, dynamic_cast( item ), depth + 1 ); + } + } + + if( depth == 0 && changeNr != 0 ) + emit changeFinished(); + return changeNr; +} + +QString DiskUsage::getToolTip( File *item ) +{ + KMimeType::Ptr mimePtr = KMimeType::mimeType( item->mime() ); + QString mime = mimePtr->comment(); + + time_t tma = item->time(); + struct tm* t=localtime((time_t *)&tma); + QDateTime tmp(QDate(t->tm_year+1900, t->tm_mon+1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); + QString date = KGlobal::locale()->formatDateTime(tmp); + + QString str = "
"+ + ""+ + ""; + + if( item->isDir() ) + str += ""; + + str += ""+ + ""+ + ""+ + "
" + i18n( "Name:" ) + "" + item->name() + "
" + i18n( "Type:" ) + "" + mime + "
" + i18n( "Size:" ) + "" + KRpermHandler::parseSize( item->size() ) + "
" + i18n( "Own size:" ) + "" + KRpermHandler::parseSize( item->ownSize() ) + "
" + i18n( "Last modified:" ) + "" + date + "
" + i18n( "Permissions:" ) + "" + item->perm() + "
" + i18n( "Owner:" ) + "" + item->owner() + " - " + item->group() + "
"; + str.replace( " ", " " ); + return str; +} + +void DiskUsage::setView( int view ) +{ + switch( view ) + { + case VIEW_LINES: + raiseWidget( lineView ); + break; + case VIEW_DETAILED: + raiseWidget( listView ); + break; + case VIEW_FILELIGHT: + raiseWidget( filelightView ); + break; + case VIEW_LOADER: + raiseWidget( loaderView ); + break; + } + + visibleWidget()->setFocus(); + emit viewChanged( activeView = view ); +} + +File * DiskUsage::getCurrentFile() +{ + File * file = 0; + + switch( activeView ) + { + case VIEW_LINES: + file = lineView->getCurrentFile(); + break; + case VIEW_DETAILED: + file = listView->getCurrentFile(); + break; + case VIEW_FILELIGHT: + file = filelightView->getCurrentFile(); + break; + } + + return file; +} + +bool DiskUsage::event( QEvent * e ) +{ + if( deleting ) { // if we are deleting, disable the mouse and + switch( e->type() ) { // keyboard events + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + return true; + default: + break; + } + } + + if ( e->type() == QEvent::AccelOverride ) + { + QKeyEvent* ke = (QKeyEvent*) e; + + if ( ke->state() == NoButton || ke->state() == Keypad ) + { + switch ( ke->key() ) + { + case Key_Delete: + case Key_Plus: + case Key_Minus: + ke->accept(); + break; + } + }else if( ke->state() == ShiftButton ) + { + switch ( ke->key() ) + { + case Key_Left: + case Key_Right: + case Key_Up: + case Key_Down: + ke->accept(); + break; + } + }else if ( ke->state() & ControlButton ) + { + switch ( ke->key() ) + { + case Key_D: + case Key_E: + case Key_F: + case Key_I: + case Key_L: + case Key_N: + case Key_R: + ke->accept(); + break; + } + } + } + return QWidgetStack::event( e ); +} + +#include "diskusage.moc" diff --git a/krusader/DiskUsage/diskusage.h b/krusader/DiskUsage/diskusage.h new file mode 100644 index 0000000..da5160e --- /dev/null +++ b/krusader/DiskUsage/diskusage.h @@ -0,0 +1,204 @@ +/*************************************************************************** + diskusage.h - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __DISK_USAGE_H__ +#define __DISK_USAGE_H__ + +#include "../VFS/vfs.h" +#include "filelightParts/fileTree.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VIEW_LINES 0 +#define VIEW_DETAILED 1 +#define VIEW_FILELIGHT 2 +#define VIEW_LOADER 3 + +typedef QDict Properties; + +class DUListView; +class DULines; +class DUFilelight; +class KPopupMenu; +class LoaderWidget; + +class DiskUsage : public QWidgetStack +{ + Q_OBJECT + +public: + DiskUsage( QString confGroup, QWidget *parent = 0, char *name = 0); + ~DiskUsage(); + + void load( KURL dirName ); + void close(); + void stopLoad(); + bool isLoading() { return loading; } + + void setView( int view ); + int getActiveView() { return activeView; } + + Directory* getDirectory( QString path ); + File * getFile( QString path ); + + QString getConfigGroup() { return configGroup; } + + void * getProperty( File *, QString ); + void addProperty( File *, QString, void * ); + void removeProperty( File *, QString ); + + int exclude( File *file, bool calcPercents = true, int depth = 0 ); + void includeAll(); + + int del( File *file, bool calcPercents = true, int depth = 0 ); + + QString getToolTip( File * ); + + void rightClickMenu( File *, KPopupMenu * = 0, QString = QString::null ); + + void changeDirectory( Directory *dir ); + + Directory* getCurrentDir(); + File* getCurrentFile(); + + QPixmap getIcon( QString mime ); + + KURL getBaseURL() { return baseURL; } + +public slots: + void dirUp(); + void clear(); + +signals: + void enteringDirectory( Directory * ); + void clearing(); + void changed( File * ); + void changeFinished(); + void deleted( File * ); + void deleteFinished(); + void status( QString ); + void viewChanged( int ); + void loadFinished( bool ); + void newSearch(); + +protected slots: + void slotLoadDirectory(); + +protected: + QDict< Directory > contentMap; + QPtrDict propertyMap; + + Directory* currentDirectory; + KIO::filesize_t currentSize; + + virtual void keyPressEvent( QKeyEvent * ); + virtual bool event( QEvent * ); + + int calculateSizes( Directory *dir = 0, bool emitSig = false, int depth = 0 ); + int calculatePercents( bool emitSig = false, Directory *dir = 0 , int depth = 0 ); + int include( Directory *dir, int depth = 0 ); + void createStatus(); + void executeAction( int, File * = 0 ); + + KURL baseURL; //< the base URL of loading + + DUListView *listView; + DULines *lineView; + DUFilelight *filelightView; + LoaderWidget *loaderView; + + Directory *root; + + int activeView; + + QString configGroup; + + bool first; + bool loading; + bool abortLoading; + bool clearAfterAbort; + bool deleting; + + QValueStack directoryStack; + QPtrStack parentStack; + + vfs * searchVfs; + vfile * currentVfile; + Directory * currentParent; + QString dirToCheck; + + int fileNum; + int dirNum; + int viewBeforeLoad; + + QTimer loadingTimer; +}; + + +class LoaderWidget : public QScrollView +{ + Q_OBJECT + +public: + LoaderWidget( QWidget *parent = 0, const char *name = 0 ); + + void init(); + void setCurrentURL( KURL url ); + void setValues( int fileNum, int dirNum, KIO::filesize_t total ); + bool wasCancelled() { return cancelled; } + +public slots: + void slotCancelled(); + +protected: + virtual void resizeEvent ( QResizeEvent *e ); + + QLabel *totalSize; + QLabel *files; + QLabel *directories; + + KSqueezedTextLabel *searchedDirectory; + QWidget *widget; + + bool cancelled; +}; + +#endif /* __DISK_USAGE_GUI_H__ */ diff --git a/krusader/DiskUsage/diskusagegui.cpp b/krusader/DiskUsage/diskusagegui.cpp new file mode 100644 index 0000000..f2bc140 --- /dev/null +++ b/krusader/DiskUsage/diskusagegui.cpp @@ -0,0 +1,227 @@ +/*************************************************************************** + diskusagegui.cpp - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "diskusagegui.h" +#include "../kicons.h" +#include "../krusader.h" +#include "../VFS/vfs.h" +#include "../Dialogs/krdialogs.h" + +#include +#include +#include +#include + +DiskUsageGUI::DiskUsageGUI( KURL openDir, QWidget* parent, const char *name ) + : QDialog( parent, name, false, 0 ), exitAtFailure( true ) +{ + setCaption( i18n("Krusader::Disk Usage") ); + + baseDirectory = openDir; + if( !newSearch() ) + return; + + QGridLayout *duGrid = new QGridLayout( this ); + duGrid->setSpacing( 6 ); + duGrid->setMargin( 11 ); + + QHBox *duTools = new QHBox( this, "duTools" ); + duTools->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + btnNewSearch = new QToolButton( duTools, "btnNewSearch" ); + btnNewSearch->setIconSet( QIconSet(krLoader->loadIcon("fileopen",KIcon::Desktop)) ); + QToolTip::add( btnNewSearch, i18n( "Start new disk usage search" ) ); + + btnRefresh = new QToolButton( duTools, "btnRefresh" ); + btnRefresh->setIconSet( QIconSet(krLoader->loadIcon("reload",KIcon::Desktop)) ); + QToolTip::add( btnRefresh, i18n( "Refresh" ) ); + + btnDirUp = new QToolButton( duTools, "btnDirUp" ); + btnDirUp->setIconSet( QIconSet(krLoader->loadIcon("up",KIcon::Desktop)) ); + QToolTip::add( btnDirUp, i18n( "Parent directory" ) ); + + QWidget * separatorWidget = new QWidget( duTools, "separatorWidget" ); + separatorWidget->setMinimumWidth( 10 ); + + btnLines = new QToolButton( duTools, "btnLines" ); + btnLines->setIconSet( QIconSet(krLoader->loadIcon("leftjust",KIcon::Desktop)) ); + btnLines->setToggleButton( true ); + QToolTip::add( btnLines, i18n( "Line view" ) ); + + btnDetailed = new QToolButton( duTools, "btnDetailed" ); + btnDetailed->setIconSet( QIconSet(krLoader->loadIcon("view_detailed",KIcon::Desktop)) ); + btnDetailed->setToggleButton( true ); + QToolTip::add( btnDetailed, i18n( "Detailed view" ) ); + + btnFilelight = new QToolButton( duTools, "btnFilelight" ); + btnFilelight->setIconSet( QIconSet(krLoader->loadIcon("kr_diskusage",KIcon::Desktop)) ); + btnFilelight->setToggleButton( true ); + QToolTip::add( btnFilelight, i18n( "Filelight view" ) ); + + QWidget *spacerWidget = new QWidget( duTools, "spacerWidget" ); + QHBoxLayout *hboxlayout = new QHBoxLayout( spacerWidget ); + QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed ); + hboxlayout->addItem( spacer ); + + duGrid->addWidget( duTools, 0, 0 ); + + diskUsage = new DiskUsage( "DiskUsage", this ); + duGrid->addWidget( diskUsage, 1, 0 ); + + status = new KSqueezedTextLabel( this ); + status->setFrameShape( QLabel::StyledPanel ); + status->setFrameShadow( QLabel::Sunken ); + duGrid->addWidget( status, 2, 0 ); + + connect( diskUsage, SIGNAL( status( QString ) ), this, SLOT( setStatus( QString ) ) ); + connect( diskUsage, SIGNAL( viewChanged( int ) ), this, SLOT( slotViewChanged( int ) ) ); + connect( diskUsage, SIGNAL( newSearch() ), this, SLOT( newSearch() ) ); + connect( diskUsage, SIGNAL( loadFinished( bool ) ), this, SLOT( slotLoadFinished( bool ) ) ); + connect( btnNewSearch, SIGNAL( clicked() ), this, SLOT( newSearch() ) ); + connect( btnRefresh, SIGNAL( clicked() ), this, SLOT( loadUsageInfo() ) ); + connect( btnDirUp, SIGNAL( clicked() ), diskUsage, SLOT( dirUp() ) ); + connect( btnLines, SIGNAL( clicked() ), this, SLOT( selectLinesView() ) ); + connect( btnDetailed, SIGNAL( clicked() ), this, SLOT( selectListView() ) ); + connect( btnFilelight, SIGNAL( clicked() ), this, SLOT( selectFilelightView() ) ); + + krConfig->setGroup( "DiskUsage" ); + + int view = krConfig->readNumEntry( "View", VIEW_LINES ); + if( view < VIEW_LINES || view > VIEW_FILELIGHT ) + view = VIEW_LINES; + diskUsage->setView( view ); + + sizeX = krConfig->readNumEntry( "Window Width", QFontMetrics(font()).width("W") * 70 ); + sizeY = krConfig->readNumEntry( "Window Height", QFontMetrics(font()).height() * 25 ); + resize( sizeX, sizeY ); + + if( krConfig->readBoolEntry( "Window Maximized", false ) ) + showMaximized(); + else + show(); + + exec(); +} + +DiskUsageGUI::~DiskUsageGUI() +{ +} + +void DiskUsageGUI::slotLoadFinished( bool result ) +{ + if( exitAtFailure && !result ) + reject(); + else + exitAtFailure = false; +} + +void DiskUsageGUI::enableButtons( bool isOn ) +{ + btnNewSearch->setEnabled( isOn ); + btnRefresh->setEnabled( isOn ); + btnDirUp->setEnabled( isOn ); + btnLines->setEnabled( isOn ); + btnDetailed->setEnabled( isOn ); + btnFilelight->setEnabled( isOn ); +} + +void DiskUsageGUI::resizeEvent( QResizeEvent *e ) +{ + if( !isMaximized() ) + { + sizeX = e->size().width(); + sizeY = e->size().height(); + } + QDialog::resizeEvent( e ); +} + +void DiskUsageGUI::reject() +{ + krConfig->setGroup( "DiskUsage" ); + krConfig->writeEntry("Window Width", sizeX ); + krConfig->writeEntry("Window Height", sizeY ); + krConfig->writeEntry("Window Maximized", isMaximized() ); + krConfig->writeEntry("View", diskUsage->getActiveView() ); + + QDialog::reject(); +} + +void DiskUsageGUI::loadUsageInfo() +{ + diskUsage->load( baseDirectory ); +} + +void DiskUsageGUI::setStatus( QString stat ) +{ + status->setText( stat ); +} + +void DiskUsageGUI::slotViewChanged( int view ) +{ + if( view == VIEW_LOADER ) + { + enableButtons( false ); + return; + } + enableButtons( true ); + + btnLines->setOn( false ); + btnDetailed->setOn( false ); + btnFilelight->setOn( false ); + + switch( view ) + { + case VIEW_LINES: + btnLines->setOn( true ); + break; + case VIEW_DETAILED: + btnDetailed->setOn( true ); + break; + case VIEW_FILELIGHT: + btnFilelight->setOn( true ); + break; + case VIEW_LOADER: + break; + } +} + +bool DiskUsageGUI::newSearch() +{ + // ask the user for the copy dest + + KURL tmp = KChooseDir::getDir(i18n( "Viewing the usage of directory:" ), baseDirectory, baseDirectory); + if (tmp.isEmpty()) return false; + baseDirectory = tmp; + + QTimer::singleShot( 0, this, SLOT( loadUsageInfo() ) ); + return true; +} + +#include "diskusagegui.moc" diff --git a/krusader/DiskUsage/diskusagegui.h b/krusader/DiskUsage/diskusagegui.h new file mode 100644 index 0000000..d243307 --- /dev/null +++ b/krusader/DiskUsage/diskusagegui.h @@ -0,0 +1,89 @@ +/*************************************************************************** + diskusagegui.h - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __DISK_USAGE_GUI_H__ +#define __DISK_USAGE_GUI_H__ + +#include +#include +#include +#include +#include + +#include "diskusage.h" + +class DiskUsageGUI : public QDialog +{ + Q_OBJECT + +public: + DiskUsageGUI( KURL openDir, QWidget* parent=0, const char *name = 0 ); + ~DiskUsageGUI(); + + +public slots: + void loadUsageInfo(); + bool newSearch(); + void setStatus( QString ); + + void selectLinesView() { diskUsage->setView( VIEW_LINES ); } + void selectListView() { diskUsage->setView( VIEW_DETAILED ); } + void selectFilelightView() { diskUsage->setView( VIEW_FILELIGHT ); } + +protected slots: + virtual void reject(); + void slotViewChanged( int view ); + void enableButtons( bool ); + void slotLoadFinished( bool ); + +protected: + virtual void resizeEvent( QResizeEvent *e ); + + DiskUsage *diskUsage; + KURL baseDirectory; + + KSqueezedTextLabel *status; + + QToolButton *btnNewSearch; + QToolButton *btnRefresh; + QToolButton *btnDirUp; + + QToolButton *btnLines; + QToolButton *btnDetailed; + QToolButton *btnFilelight; + + int sizeX; + int sizeY; + + bool exitAtFailure; +}; + +#endif /* __DISK_USAGE_GUI_H__ */ + diff --git a/krusader/DiskUsage/dufilelight.cpp b/krusader/DiskUsage/dufilelight.cpp new file mode 100644 index 0000000..6a6bee9 --- /dev/null +++ b/krusader/DiskUsage/dufilelight.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + dufilelight.cpp - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "dufilelight.h" +#include "radialMap/radialMap.h" +#include +#include +#include + +#define SCHEME_POPUP_ID 6730 + +DUFilelight::DUFilelight( DiskUsage *usage, const char *name ) + : RadialMap::Widget( usage, name ), diskUsage( usage ), currentDir( 0 ), refreshNeeded( true ) +{ + setFocusPolicy( QWidget::StrongFocus ); + + connect( diskUsage, SIGNAL( enteringDirectory( Directory * ) ), this, SLOT( slotDirChanged( Directory * ) ) ); + connect( diskUsage, SIGNAL( clearing() ), this, SLOT( clear() ) ); + connect( diskUsage, SIGNAL( changed( File * ) ), this, SLOT( slotChanged( File * ) ) ); + connect( diskUsage, SIGNAL( deleted( File * ) ), this, SLOT( slotChanged( File * ) ) ); + connect( diskUsage, SIGNAL( changeFinished() ), this, SLOT( slotRefresh() ) ); + connect( diskUsage, SIGNAL( deleteFinished() ), this, SLOT( slotRefresh() ) ); + connect( diskUsage, SIGNAL( aboutToShow( QWidget * ) ), this, SLOT( slotAboutToShow( QWidget * ) ) ); +} + +void DUFilelight::slotDirChanged( Directory *dir ) +{ + if( diskUsage->visibleWidget() != this ) + return; + + if( currentDir != dir ) + { + currentDir = dir; + + invalidate( false ); + create( dir ); + refreshNeeded = false; + } +} + +void DUFilelight::clear() +{ + invalidate( false ); + currentDir = 0; +} + +File * DUFilelight::getCurrentFile() +{ + const RadialMap::Segment * focus = focusSegment(); + + if( !focus || focus->isFake() || focus->file() == currentDir ) + return 0; + + return (File *)focus->file(); +} + +void DUFilelight::mousePressEvent( QMouseEvent *event ) +{ + if( event->button() == Qt::RightButton ) + { + File * file = 0; + + const RadialMap::Segment * focus = focusSegment(); + + if( focus && !focus->isFake() && focus->file() != currentDir ) + file = (File *)focus->file(); + + KPopupMenu filelightPopup; + filelightPopup.insertItem( i18n("Zoom In"), this, SLOT( zoomIn() ), Key_Plus ); + filelightPopup.insertItem( i18n("Zoom Out"), this, SLOT( zoomOut() ), Key_Minus ); + + KPopupMenu schemePopup; + schemePopup.insertItem( i18n("Rainbow"), this, SLOT( schemeRainbow() ) ); + schemePopup.insertItem( i18n("High Contrast"), this, SLOT( schemeHighContrast() ) ); + schemePopup.insertItem( i18n("KDE"), this, SLOT( schemeKDE() ) ); + + filelightPopup.insertItem( QPixmap(), &schemePopup, SCHEME_POPUP_ID ); + filelightPopup.changeItem( SCHEME_POPUP_ID, i18n( "Scheme" ) ); + + filelightPopup.insertItem( i18n("Increase contrast"), this, SLOT( increaseContrast() ) ); + filelightPopup.insertItem( i18n("Decrease contrast"), this, SLOT( decreaseContrast() ) ); + + int aid = filelightPopup.insertItem( i18n("Use anti-aliasing" ), this, SLOT( changeAntiAlias() ) ); + filelightPopup.setItemChecked( aid, Filelight::Config::antiAliasFactor > 1 ); + + int sid = filelightPopup.insertItem( i18n("Show small files" ), this, SLOT( showSmallFiles() ) ); + filelightPopup.setItemChecked( sid, Filelight::Config::showSmallFiles ); + + int vid = filelightPopup.insertItem( i18n("Vary label font sizes" ), this, SLOT( varyLabelFontSizes() ) ); + filelightPopup.setItemChecked( vid, Filelight::Config::varyLabelFontSizes ); + + filelightPopup.insertItem( i18n("Minimum font size"), this, SLOT( minFontSize() ) ); + + diskUsage->rightClickMenu( file, &filelightPopup, i18n( "Filelight" ) ); + return; + }else if( event->button() == Qt::LeftButton ) + { + const RadialMap::Segment * focus = focusSegment(); + + if( focus && !focus->isFake() && focus->file() == currentDir ) + { + diskUsage->dirUp(); + return; + } + else if( focus && !focus->isFake() && focus->file()->isDir() ) + { + diskUsage->changeDirectory( (Directory *)focus->file() ); + return; + } + } + + RadialMap::Widget::mousePressEvent( event ); +} + +void DUFilelight::setScheme( Filelight::MapScheme scheme ) +{ + Filelight::Config::scheme = scheme; + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::increaseContrast() +{ + if( ( Filelight::Config::contrast += 10 ) > 100 ) + Filelight::Config::contrast = 100; + + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::decreaseContrast() +{ + if( ( Filelight::Config::contrast -= 10 ) > 100 ) + Filelight::Config::contrast = 0; + + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::changeAntiAlias() +{ + Filelight::Config::antiAliasFactor = 1 + ( Filelight::Config::antiAliasFactor == 1 ); + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::showSmallFiles() +{ + Filelight::Config::showSmallFiles = !Filelight::Config::showSmallFiles; + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::varyLabelFontSizes() +{ + Filelight::Config::varyLabelFontSizes = !Filelight::Config::varyLabelFontSizes; + Filelight::Config::write(); + slotRefresh(); +} + +void DUFilelight::minFontSize() +{ + bool ok = false; + + int result = KInputDialog::getInteger( i18n( "Krusader::Filelight" ), + i18n( "Minimum font size" ), (int)Filelight::Config::minFontPitch, 1, 100, 1, &ok, this ); + + if ( ok ) + { + Filelight::Config::minFontPitch = (uint)result; + + Filelight::Config::write(); + slotRefresh(); + } +} + +void DUFilelight::slotAboutToShow( QWidget *widget ) +{ + if( widget == this && ( diskUsage->getCurrentDir() != currentDir || refreshNeeded ) ) + { + refreshNeeded = false; + if( ( currentDir = diskUsage->getCurrentDir() ) != 0 ) + { + invalidate( false ); + create( currentDir ); + } + } +} + +void DUFilelight::slotRefresh() +{ + if( diskUsage->visibleWidget() != this ) + return; + + refreshNeeded = false; + if( currentDir && currentDir == diskUsage->getCurrentDir() ) + { + invalidate( false ); + create( currentDir ); + } +} + +void DUFilelight::slotChanged( File * ) +{ + if( !refreshNeeded ) + refreshNeeded = true; +} + +#include "dufilelight.moc" diff --git a/krusader/DiskUsage/dufilelight.h b/krusader/DiskUsage/dufilelight.h new file mode 100644 index 0000000..556830e --- /dev/null +++ b/krusader/DiskUsage/dufilelight.h @@ -0,0 +1,80 @@ +/*************************************************************************** + dufilelight.h - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __DU_FILELIGHT_H__ +#define __DU_FILELIGHT_H__ + +#include "diskusage.h" +#include "radialMap/widget.h" +#include "filelightParts/Config.h" + +class DUFilelight : public RadialMap::Widget +{ + Q_OBJECT + +public: + DUFilelight( DiskUsage *usage, const char *name ); + + File * getCurrentFile(); + +public slots: + void slotDirChanged( Directory * ); + void clear(); + void slotChanged( File * ); + void slotRefresh(); + +protected slots: + void slotAboutToShow( QWidget *widget ); + + void schemeRainbow() { setScheme( Filelight::Rainbow ); } + void schemeHighContrast() { setScheme( Filelight::HighContrast ); } + void schemeKDE() { setScheme( Filelight::KDE ); } + + void increaseContrast(); + void decreaseContrast(); + void changeAntiAlias(); + void showSmallFiles(); + void varyLabelFontSizes(); + void minFontSize(); + +protected: + virtual void mousePressEvent( QMouseEvent* ); + + void setScheme( Filelight::MapScheme ); + + DiskUsage *diskUsage; + Directory *currentDir; + +private: + bool refreshNeeded; +}; + +#endif /* __DU_FILELIGHT_H__ */ + diff --git a/krusader/DiskUsage/dulines.cpp b/krusader/DiskUsage/dulines.cpp new file mode 100644 index 0000000..089a8a7 --- /dev/null +++ b/krusader/DiskUsage/dulines.cpp @@ -0,0 +1,522 @@ +/*************************************************************************** + dulines.cpp - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "dulines.h" +#include "../kicons.h" +#include "../krusader.h" +#include "../VFS/krpermhandler.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class DULinesItem : public QListViewItem +{ +public: + DULinesItem( DiskUsage *diskUsageIn, File *fileItem, QListView * parent, QString label1, + QString label2, QString label3, unsigned int italicPos ) : QListViewItem( parent, label1, label2, label3 ), + diskUsage( diskUsageIn ), file( fileItem ), isTruncated( false ), italicTextPos( italicPos ) {} + DULinesItem( DiskUsage *diskUsageIn, File *fileItem, QListView * parent, QListViewItem * after, + QString label1, QString label2, QString label3, unsigned int italicPos ) : QListViewItem( parent, after, label1, + label2, label3 ), diskUsage( diskUsageIn ), file( fileItem ), isTruncated( false ), italicTextPos( italicPos ) {} + + virtual int compare ( QListViewItem * i, int col, bool ascending ) const + { + if( text(0) == ".." ) return ascending ? -1 : 1; + if( i->text(0) == "..") return ascending ? 1 : -1; + + DULinesItem *compWith = dynamic_cast< DULinesItem * >( i ); + + QString buf1,buf2; + + switch( col ) + { + case 0: + case 1: + buf1.sprintf("%025llu",file->size()); + buf2.sprintf("%025llu",compWith->file->size()); + return -QString::compare( buf1, buf2 ); + default: + return QListViewItem::compare( i, col, ascending ); + } + } + + virtual void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int align ) + { + if( column == 2 ) + { + if ( isSelected() ) + p->fillRect( 0, 0, width, height(), cg.brush( QColorGroup::Highlight ) ); + else + p->fillRect( 0, 0, width, height(), cg.brush( QColorGroup::Base ) ); + + QListView *lv = listView(); + + int pos = lv->itemMargin(); + + const QPixmap *icon = pixmap( column ); + if( icon ) + { + int iconWidth = icon->width() + lv->itemMargin(); + int xo = pos; + int yo = ( height() - icon->height() ) / 2; + + p->drawPixmap( xo, yo, *icon ); + + pos += iconWidth; + } + + QFontMetrics fm( p->fontMetrics() ); + + if( isSelected() ) + p->setPen( cg.highlightedText() ); + else + p->setPen( cg.text() ); + + QString t = text( column ); + QString b; + + if( t.length() > italicTextPos ) + { + b = t.mid( italicTextPos ); + t.truncate( italicTextPos ); + } + + isTruncated = false; + if( !t.isEmpty() ) + { + int remWidth = width-pos; + + if( fm.width( t ) > remWidth ) + { + while( !t.isEmpty() ) + { + t.truncate( t.length() - 1 ); + if( fm.width( t + "..." ) <= remWidth ) + break; + } + t += "..."; + isTruncated = true; + } + + p->drawText( pos, 0, width, height(), align, t ); + pos += fm.width( t ); + } + + if( !b.isEmpty() && !isTruncated ) + { + QFont font( p->font() ); + font.setItalic( true ); + p->setFont( font ); + + QFontMetrics fm2( p->fontMetrics() ); + + int remWidth = width-pos; + + if( fm2.width( b ) > remWidth ) + { + while( !b.isEmpty() ) + { + b.truncate( b.length() - 1 ); + if( fm2.width( b + "..." ) <= remWidth ) + break; + } + b += "..."; + isTruncated = true; + } + + p->drawText( pos, 0, width, height(), align, b ); + } + } + else + QListViewItem::paintCell( p, cg, column, width, align ); + } + + inline File * getFile() { return file; } + +private: + DiskUsage *diskUsage; + File *file; + + bool isTruncated; + unsigned int italicTextPos; +}; + +class DULinesToolTip : public QToolTip +{ +public: + DULinesToolTip( DiskUsage *usage, QWidget *parent, QListView *lv ); + void maybeTip( const QPoint &pos ); + + virtual ~DULinesToolTip() {} +private: + QListView *view; + DiskUsage *diskUsage; +}; + +DULinesToolTip::DULinesToolTip( DiskUsage *usage, QWidget *parent, QListView *lv ) + : QToolTip( parent ), view( lv ), diskUsage( usage ) +{ +} + +void DULinesToolTip::maybeTip( const QPoint &pos ) +{ + QListViewItem *item = view->itemAt( pos ); + QPoint contentsPos = view->viewportToContents( pos ); + if ( !item ) + return; + + int col = view->header()->sectionAt( contentsPos.x() ); + + int width = item->width( QFontMetrics( view->font() ), view, col ); + + QRect r = view->itemRect( item ); + int headerPos = view->header()->sectionPos( col ); + r.setLeft( headerPos ); + r.setRight( headerPos + view->header()->sectionSize( col ) ); + + if( col != 0 && width > view->columnWidth( col ) ) + tip( r, item->text( col ) ); + else if( col == 1 && item->text( 0 ) != ".." ) + { + File *fileItem = ((DULinesItem *)item)->getFile(); + tip( r, diskUsage->getToolTip( fileItem ) ); + } +} + +DULines::DULines( DiskUsage *usage, const char *name ) + : QListView( usage, name ), diskUsage( usage ), refreshNeeded( false ) +{ + setAllColumnsShowFocus(true); + setVScrollBarMode(QScrollView::Auto); + setHScrollBarMode(QScrollView::Auto); + setShowSortIndicator(true); + setTreeStepSize( 10 ); + + int defaultSize = QFontMetrics(font()).width("W"); + + krConfig->setGroup( diskUsage->getConfigGroup() ); + + showFileSize = krConfig->readBoolEntry( "L Show File Size", true ); + + int lineWidth = krConfig->readNumEntry("L Line Width", defaultSize * 20 ); + addColumn( i18n("Line View"), lineWidth ); + setColumnWidthMode(0,QListView::Manual); + int precentWidth = krConfig->readNumEntry("L Percent Width", defaultSize * 6 ); + addColumn( i18n("Percent"), precentWidth ); + setColumnWidthMode(1,QListView::Manual); + int nameWidth = krConfig->readNumEntry("L Name Width", defaultSize * 20 ); + addColumn( i18n("Name"), nameWidth ); + setColumnWidthMode(2,QListView::Manual); + + setColumnAlignment( 1, Qt::AlignRight ); + + header()->setStretchEnabled( true, 0 ); + + setSorting( 1 ); + + toolTip = new DULinesToolTip( diskUsage, viewport(), this ); + + connect( diskUsage, SIGNAL( enteringDirectory( Directory * ) ), this, SLOT( slotDirChanged( Directory * ) ) ); + connect( diskUsage, SIGNAL( clearing() ), this, SLOT( clear() ) ); + + connect( header(), SIGNAL( sizeChange( int, int, int ) ), this, SLOT( sectionResized( int ) ) ); + + connect( this, SIGNAL(rightButtonPressed(QListViewItem *, const QPoint &, int)), + this, SLOT( slotRightClicked(QListViewItem *) ) ); + connect( diskUsage, SIGNAL( changed( File * ) ), this, SLOT( slotChanged( File * ) ) ); + connect( diskUsage, SIGNAL( deleted( File * ) ), this, SLOT( slotDeleted( File * ) ) ); +} + +DULines::~DULines() +{ + krConfig->setGroup( diskUsage->getConfigGroup() ); + krConfig->writeEntry("L Line Width", columnWidth( 0 ) ); + krConfig->writeEntry("L Percent Width", columnWidth( 1 ) ); + krConfig->writeEntry("L Name Width", columnWidth( 2 ) ); + krConfig->writeEntry("L Show File Size", showFileSize ); + + delete toolTip; +} + +void DULines::slotDirChanged( Directory *dirEntry ) +{ + clear(); + + QListViewItem * lastItem = 0; + + if( ! ( dirEntry->parent() == 0 ) ) + { + lastItem = new QListViewItem( this, ".." ); + lastItem->setPixmap( 0, FL_LOADICON( "up" ) ); + lastItem->setSelectable( false ); + } + + int maxPercent = -1; + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + { + File *item = *it; + if( !item->isExcluded() && item->intPercent() > maxPercent ) + maxPercent = item->intPercent(); + } + + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + { + File *item = *it; + + QString fileName = item->name(); + + unsigned int italicStart = fileName.length(); + + if( showFileSize ) + fileName += " [" + KIO::convertSize( item->size() ) + "]"; + + if( lastItem == 0 ) + lastItem = new DULinesItem( diskUsage, item, this, "", item->percent() + " ", fileName, italicStart ); + else + lastItem = new DULinesItem( diskUsage, item, this, lastItem, "", item->percent() + " ", fileName, italicStart ); + + if( item->isExcluded() ) + lastItem->setVisible( false ); + + lastItem->setPixmap( 2, diskUsage->getIcon( item->mime() ) ); + lastItem->setPixmap( 0, createPixmap( item->intPercent(), maxPercent, columnWidth( 0 ) - itemMargin() ) ); + } + + setCurrentItem( firstChild() ); +} + +QPixmap DULines::createPixmap( int percent, int maxPercent, int maxWidth ) +{ + if( percent < 0 || percent > maxPercent || maxWidth < 2 || maxPercent == 0 ) + return QPixmap(); + maxWidth -= 2; + + int actualWidth = maxWidth*percent/maxPercent; + if( actualWidth == 0 ) + return QPixmap(); + + QPen pen; + pen.setColor( Qt::black ); + QPainter painter; + + int size = QFontMetrics(font()).height()-2; + QRect rect( 0, 0, actualWidth, size ); + QPixmap pixmap( rect.width(), rect.height() ); + + painter.begin( &pixmap ); + painter.setPen( pen ); + + for( int i = 1; i < actualWidth - 1; i++ ) + { + int color = (511*i/maxWidth); + if( color < 256 ) + pen.setColor( QColor( 255-color, 255, 0 ) ); + else + pen.setColor( QColor( color-256, 511-color, 0 ) ); + + painter.setPen( pen ); + painter.drawLine( i, 1, i, size-1 ); + } + + pen.setColor( Qt::black ); + painter.setPen( pen ); + painter.drawRect( rect ); + painter.end(); + pixmap.detach(); + return pixmap; +} + +void DULines::sectionResized( int column ) +{ + if( childCount() == 0 || column != 0 ) + return; + + Directory * currentDir = diskUsage->getCurrentDir(); + if( currentDir == 0 ) + return; + + int maxPercent = -1; + for( Iterator it = currentDir->iterator(); it != currentDir->end(); ++it ) + { + File *item = *it; + + if( !item->isExcluded() && item->intPercent() > maxPercent ) + maxPercent = item->intPercent(); + } + + DULinesItem *duItem = (DULinesItem *)firstChild(); + while( duItem ) + { + if( duItem->text( 0 ) != ".." ) + duItem->setPixmap( 0, createPixmap( duItem->getFile()->intPercent(), maxPercent, columnWidth( 0 ) ) ); + duItem = (DULinesItem *)duItem->nextSibling(); + } +} + +bool DULines::doubleClicked( QListViewItem * item ) +{ + if( item ) + { + if( item->text( 0 ) != ".." ) + { + File *fileItem = ((DULinesItem *)item)->getFile(); + if( fileItem->isDir() ) + diskUsage->changeDirectory( dynamic_cast ( fileItem ) ); + return true; + } + else + { + Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); + + if( upDir ) + diskUsage->changeDirectory( upDir ); + return true; + } + } + return false; +} + +void DULines::contentsMouseDoubleClickEvent ( QMouseEvent * e ) +{ + if ( e || e->button() == LeftButton ) + { + QPoint vp = contentsToViewport(e->pos()); + QListViewItem * item = itemAt( vp ); + + if( doubleClicked( item ) ) + return; + + } + QListView::contentsMouseDoubleClickEvent( e ); +} + + +void DULines::keyPressEvent( QKeyEvent *e ) +{ + switch ( e->key() ) + { + case Key_Return : + case Key_Enter : + if( doubleClicked( currentItem() ) ) + return; + break; + case Key_Left : + case Key_Right : + case Key_Up : + case Key_Down : + if( e->state() == ShiftButton ) + { + e->ignore(); + return; + } + break; + case Key_Delete : + e->ignore(); + return; + } + QListView::keyPressEvent( e ); +} + +void DULines::slotRightClicked( QListViewItem *item ) +{ + File * file = 0; + + if ( item && item->text( 0 ) != ".." ) + file = ((DULinesItem *)item)->getFile(); + + KPopupMenu linesPopup; + int lid = linesPopup.insertItem( i18n("Show file sizes"), this, SLOT( slotShowFileSizes() ) ); + linesPopup.setItemChecked( lid, showFileSize ); + + diskUsage->rightClickMenu( file, &linesPopup, i18n( "Lines" ) ); +} + +void DULines::slotShowFileSizes() +{ + showFileSize = !showFileSize; + slotDirChanged( diskUsage->getCurrentDir() ); +} + +File * DULines::getCurrentFile() +{ + QListViewItem *item = currentItem(); + + if( item == 0 || item->text( 0 ) == ".." ) + return 0; + + return ((DULinesItem *)item)->getFile(); +} + +void DULines::slotChanged( File * item ) +{ + QListViewItem *lvitem = firstChild(); + while( lvitem ) + { + if( lvitem->text( 0 ) != ".." ) { + DULinesItem *duItem = (DULinesItem *)( lvitem ); + if( duItem->getFile() == item ) + { + duItem->setVisible( !item->isExcluded() ); + duItem->setText( 1, item->percent() ); + if( !refreshNeeded ) + { + refreshNeeded = true; + QTimer::singleShot( 0, this, SLOT( slotRefresh() ) ); + } + break; + } + } + lvitem = lvitem->nextSibling(); + } +} + +void DULines::slotDeleted( File * item ) +{ + QListViewItem *lvitem = firstChild(); + while( lvitem ) + { + if( lvitem->text( 0 ) != ".." ) { + DULinesItem *duItem = (DULinesItem *)( lvitem ); + if( duItem->getFile() == item ) + { + delete duItem; + break; + } + } + lvitem = lvitem->nextSibling(); + } +} + +#include "dulines.moc" diff --git a/krusader/DiskUsage/dulines.h b/krusader/DiskUsage/dulines.h new file mode 100644 index 0000000..aa83ad1 --- /dev/null +++ b/krusader/DiskUsage/dulines.h @@ -0,0 +1,78 @@ +/*************************************************************************** + dulines.h - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __DU_LINES_H__ +#define __DU_LINES_H__ + +#include +#include +#include "diskusage.h" + +class DULinesToolTip; + +class DULines : public QListView +{ + Q_OBJECT + +public: + DULines( DiskUsage *usage, const char *name ); + ~DULines(); + + File * getCurrentFile(); + +public slots: + void slotDirChanged( Directory *dirEntry ); + void sectionResized( int ); + void slotRightClicked(QListViewItem *); + void slotChanged( File * ); + void slotDeleted( File * ); + void slotShowFileSizes(); + void slotRefresh() { refreshNeeded = false; sectionResized( 0 ); } + +protected: + DiskUsage *diskUsage; + + virtual void contentsMouseDoubleClickEvent ( QMouseEvent * e ); + virtual void keyPressEvent( QKeyEvent *e ); + +private: + QPixmap createPixmap( int percent, int maxPercent, int maxWidth ); + + bool doubleClicked( QListViewItem * item ); + + bool refreshNeeded; + + bool showFileSize; + + DULinesToolTip *toolTip; +}; + +#endif /* __DU_LINES_H__ */ + diff --git a/krusader/DiskUsage/dulistview.cpp b/krusader/DiskUsage/dulistview.cpp new file mode 100644 index 0000000..62c1fcf --- /dev/null +++ b/krusader/DiskUsage/dulistview.cpp @@ -0,0 +1,293 @@ +/*************************************************************************** + dulistview.cpp - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "dulistview.h" +#include "../krusader.h" +#include "../kicons.h" +#include "../VFS/krpermhandler.h" +#include +#include +#include +#include +#include +#include + +DUListView::DUListView( DiskUsage *usage, const char *name ) + : QListView( usage, name ), diskUsage( usage ) +{ + setAllColumnsShowFocus(true); + setVScrollBarMode(QScrollView::Auto); + setHScrollBarMode(QScrollView::Auto); + setShowSortIndicator(true); + setRootIsDecorated( true ); + setTreeStepSize( 10 ); + + int defaultSize = QFontMetrics(font()).width("W"); + + krConfig->setGroup( diskUsage->getConfigGroup() ); + int nameWidth = krConfig->readNumEntry("D Name Width", defaultSize * 20 ); + addColumn( i18n("Name"), nameWidth ); + setColumnWidthMode(0,QListView::Manual); + int percentWidth = krConfig->readNumEntry("D Percent Width", defaultSize * 5 ); + addColumn( i18n("Percent"), percentWidth ); + setColumnWidthMode(1,QListView::Manual); + int totalSizeWidth = krConfig->readNumEntry("D Total Size Width", defaultSize * 10 ); + addColumn( i18n("Total size"), totalSizeWidth ); + setColumnWidthMode(1,QListView::Manual); + int ownSizeWidth = krConfig->readNumEntry("D Own Size Width", defaultSize * 10 ); + addColumn( i18n("Own size"), ownSizeWidth ); + setColumnWidthMode(2,QListView::Manual); + int typeWidth = krConfig->readNumEntry("D Type Width", defaultSize * 10 ); + addColumn( i18n("Type"), typeWidth ); + setColumnWidthMode(3,QListView::Manual); + int dateWidth = krConfig->readNumEntry("D Date Width", defaultSize * 10 ); + addColumn( i18n("Date"), dateWidth ); + setColumnWidthMode(4,QListView::Manual); + int permissionsWidth = krConfig->readNumEntry("D Permissions Width", defaultSize * 6 ); + addColumn( i18n("Permissions"), permissionsWidth ); + setColumnWidthMode(5,QListView::Manual); + int ownerWidth = krConfig->readNumEntry("D Owner Width", defaultSize * 5 ); + addColumn( i18n("Owner"), ownerWidth ); + setColumnWidthMode(6,QListView::Manual); + int groupWidth = krConfig->readNumEntry("D Group Width", defaultSize * 5 ); + addColumn( i18n("Group"), groupWidth ); + setColumnWidthMode(7,QListView::Manual); + + setColumnAlignment( 1, Qt::AlignRight ); + setColumnAlignment( 2, Qt::AlignRight ); + setColumnAlignment( 3, Qt::AlignRight ); + + setSorting( 2 ); + + connect( diskUsage, SIGNAL( enteringDirectory( Directory * ) ), this, SLOT( slotDirChanged( Directory * ) ) ); + connect( diskUsage, SIGNAL( clearing() ), this, SLOT( clear() ) ); + connect( diskUsage, SIGNAL( changed( File * ) ), this, SLOT( slotChanged( File * ) ) ); + connect( diskUsage, SIGNAL( deleted( File * ) ), this, SLOT( slotDeleted( File * ) ) ); + + connect( this, SIGNAL(rightButtonPressed(QListViewItem *, const QPoint &, int)), + this, SLOT( slotRightClicked(QListViewItem *) ) ); + connect( this, SIGNAL( expanded ( QListViewItem * ) ), + this, SLOT( slotExpanded( QListViewItem * ) ) ); +} + +DUListView::~ DUListView() +{ + krConfig->setGroup( diskUsage->getConfigGroup() ); + krConfig->writeEntry("D Name Width", columnWidth( 0 ) ); + krConfig->writeEntry("D Percent Width", columnWidth( 1 ) ); + krConfig->writeEntry("D Total Size Width", columnWidth( 2 ) ); + krConfig->writeEntry("D Own Size Width", columnWidth( 3 ) ); + krConfig->writeEntry("D Type Width", columnWidth( 4 ) ); + krConfig->writeEntry("D Date Width", columnWidth( 5 ) ); + krConfig->writeEntry("D Permissions Width", columnWidth( 6 ) ); + krConfig->writeEntry("D Owner Width", columnWidth( 7 ) ); + krConfig->writeEntry("D Group Width", columnWidth( 8 ) ); +} + +void DUListView::addDirectory( Directory *dirEntry, QListViewItem *parent ) +{ + QListViewItem * lastItem = 0; + + if( parent == 0 && ! ( dirEntry->parent() == 0 ) ) + { + lastItem = new QListViewItem( this, ".." ); + lastItem->setPixmap( 0, FL_LOADICON( "up" ) ); + lastItem->setSelectable( false ); + } + + for( Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it ) + { + File *item = *it; + + KMimeType::Ptr mimePtr = KMimeType::mimeType( item->mime() ); + QString mime = mimePtr->comment(); + + time_t tma = item->time(); + struct tm* t=localtime((time_t *)&tma); + QDateTime tmp(QDate(t->tm_year+1900, t->tm_mon+1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); + QString date = KGlobal::locale()->formatDateTime(tmp); + + QString totalSize = KRpermHandler::parseSize( item->size() ) + " "; + QString ownSize = KRpermHandler::parseSize( item->ownSize() ) + " "; + QString percent = item->percent(); + + if( lastItem == 0 && parent == 0 ) + lastItem = new DUListViewItem( diskUsage, item, this, item->name(), percent, totalSize, ownSize, + mime, date, item->perm(), item->owner(), item->group() ); + else if ( lastItem == 0 ) + lastItem = new DUListViewItem( diskUsage, item, parent, item->name(), percent, totalSize, ownSize, + mime, date, item->perm(), item->owner(), item->group() ); + else if ( parent == 0 ) + lastItem = new DUListViewItem( diskUsage, item, this, lastItem, item->name(), percent, totalSize, + ownSize, mime, date, item->perm(), item->owner(), item->group() ); + else + lastItem = new DUListViewItem( diskUsage, item, parent, lastItem, item->name(), percent, totalSize, + ownSize, mime, date, item->perm(), item->owner(), item->group() ); + + if( item->isExcluded() ) + lastItem->setVisible( false ); + + lastItem->setPixmap( 0, diskUsage->getIcon( item->mime() ) ); + + if( item->isDir() && !item->isSymLink() ) + lastItem->setExpandable( true ); + } + + QListViewItem *first = firstChild(); + if( first ) + setCurrentItem( first ); +} + +void DUListView::slotDirChanged( Directory *dirEntry ) +{ + clear(); + addDirectory( dirEntry, 0 ); +} + +File * DUListView::getCurrentFile() +{ + QListViewItem *item = currentItem(); + + if( item == 0 || item->text( 0 ) == ".." ) + return 0; + + return ((DUListViewItem *)item)->getFile(); +} + +void DUListView::slotChanged( File * item ) +{ + void * itemPtr = diskUsage->getProperty( item, "ListView-Ref" ); + if( itemPtr == 0 ) + return; + + DUListViewItem *duItem = (DUListViewItem *)itemPtr; + duItem->setVisible( !item->isExcluded() ); + duItem->setText( 1, item->percent() ); + duItem->setText( 2, KRpermHandler::parseSize( item->size() ) + " " ); + duItem->setText( 3, KRpermHandler::parseSize( item->ownSize() ) + " " ); +} + +void DUListView::slotDeleted( File * item ) +{ + void * itemPtr = diskUsage->getProperty( item, "ListView-Ref" ); + if( itemPtr == 0 ) + return; + + DUListViewItem *duItem = (DUListViewItem *)itemPtr; + delete duItem; +} + +void DUListView::slotRightClicked( QListViewItem *item ) +{ + File * file = 0; + + if ( item && item->text( 0 ) != ".." ) + file = ((DUListViewItem *)item)->getFile(); + + diskUsage->rightClickMenu( file ); +} + +bool DUListView::doubleClicked( QListViewItem * item ) +{ + if( item ) + { + if( item->text( 0 ) != ".." ) + { + File *fileItem = ((DUListViewItem *)item)->getFile(); + if( fileItem->isDir() ) + diskUsage->changeDirectory( dynamic_cast ( fileItem ) ); + return true; + } + else + { + Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); + + if( upDir ) + diskUsage->changeDirectory( upDir ); + return true; + } + } + return false; +} + +void DUListView::contentsMouseDoubleClickEvent ( QMouseEvent * e ) +{ + if ( e || e->button() == LeftButton ) + { + QPoint vp = contentsToViewport(e->pos()); + QListViewItem * item = itemAt( vp ); + + if( doubleClicked( item ) ) + return; + + } + QListView::contentsMouseDoubleClickEvent( e ); +} + +void DUListView::keyPressEvent( QKeyEvent *e ) +{ + switch ( e->key() ) + { + case Key_Return : + case Key_Enter : + if( doubleClicked( currentItem() ) ) + return; + break; + case Key_Left : + case Key_Right : + case Key_Up : + case Key_Down : + if( e->state() == ShiftButton ) + { + e->ignore(); + return; + } + break; + case Key_Delete : + e->ignore(); + return; + } + QListView::keyPressEvent( e ); +} + +void DUListView::slotExpanded( QListViewItem *item ) +{ + if( item == 0 || item->text( 0 ) == ".." ) + return; + + if( item->childCount() == 0 ) + { + File *fileItem = ((DUListViewItem *)item)->getFile(); + if( fileItem->isDir() ) + addDirectory( dynamic_cast( fileItem ), item ); + } +} + +#include "dulistview.moc" diff --git a/krusader/DiskUsage/dulistview.h b/krusader/DiskUsage/dulistview.h new file mode 100644 index 0000000..01ab59f --- /dev/null +++ b/krusader/DiskUsage/dulistview.h @@ -0,0 +1,144 @@ +/*************************************************************************** + dulistview.h - description + ------------------- + copyright : (C) 2004 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __DU_LISTVIEW_H__ +#define __DU_LISTVIEW_H__ + +#include +#include "diskusage.h" + +class DUListViewItem : public QListViewItem +{ +public: + DUListViewItem( DiskUsage *diskUsageIn, File *fileIn, QListView * parent, QString label1, + QString label2, QString label3, QString label4, QString label5, QString label6, + QString label7, QString label8, QString label9 ) + : QListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8), + diskUsage( diskUsageIn ), file( fileIn ) + { + setText( 8, label9 ); + diskUsage->addProperty( file, "ListView-Ref", this ); + } + DUListViewItem( DiskUsage *diskUsageIn, File *fileIn, QListViewItem * parent, QString label1, + QString label2, QString label3, QString label4, QString label5, QString label6, + QString label7, QString label8, QString label9 ) + : QListViewItem( parent, label1, label2, label3, label4, label5, label6, label7, label8), + diskUsage( diskUsageIn ), file( fileIn ) + { + setText( 8, label9 ); + diskUsage->addProperty( file, "ListView-Ref", this ); + } + DUListViewItem( DiskUsage *diskUsageIn, File *fileIn, QListView * parent, QListViewItem * after, + QString label1, QString label2, QString label3, QString label4, QString label5, + QString label6, QString label7, QString label8, QString label9 ) + : QListViewItem( parent, after, label1, label2, label3, label4, label5, label6, label7, label8), + diskUsage( diskUsageIn ), file( fileIn ) + { + setText( 8, label9 ); + diskUsage->addProperty( file, "ListView-Ref", this ); + } + DUListViewItem( DiskUsage *diskUsageIn, File *fileIn, QListViewItem * parent, QListViewItem * after, + QString label1, QString label2, QString label3, QString label4, QString label5, + QString label6, QString label7, QString label8, QString label9 ) + : QListViewItem( parent, after, label1, label2, label3, label4, label5, label6, label7, label8), + diskUsage( diskUsageIn ), file( fileIn ) + { + setText( 8, label9 ); + diskUsage->addProperty( file, "ListView-Ref", this ); + } + ~DUListViewItem() + { + diskUsage->removeProperty( file, "ListView-Ref" ); + } + + virtual int compare ( QListViewItem * i, int col, bool ascending ) const + { + if( text(0) == ".." ) return ascending ? -1 : 1; + if( i->text(0) == "..") return ascending ? 1 : -1; + + DUListViewItem *compWith = dynamic_cast< DUListViewItem * >( i ); + + QString buf1,buf2; + + switch( col ) + { + case 1: + case 2: + buf1.sprintf("%025llu",file->size()); + buf2.sprintf("%025llu",compWith->file->size()); + return -QString::compare( buf1, buf2 ); + case 3: + buf1.sprintf("%025llu",file->ownSize()); + buf2.sprintf("%025llu",compWith->file->ownSize()); + return -QString::compare( buf1, buf2 ); + case 5: + return QListViewItem::compare( i, col, !ascending ); + default: + return QListViewItem::compare( i, col, ascending ); + } + } + + inline File * getFile() { return file; } + +private: + DiskUsage *diskUsage; + File *file; +}; + +class DUListView : public QListView +{ + Q_OBJECT + +public: + DUListView( DiskUsage *usage, const char *name ); + ~DUListView(); + + File * getCurrentFile(); + +public slots: + void slotDirChanged( Directory * ); + void slotChanged( File * ); + void slotDeleted( File * ); + void slotRightClicked(QListViewItem *); + void slotExpanded( QListViewItem * ); + +protected: + DiskUsage *diskUsage; + + virtual void contentsMouseDoubleClickEvent ( QMouseEvent * e ); + virtual void keyPressEvent( QKeyEvent *e ); + +private: + void addDirectory( Directory *dirEntry, QListViewItem *parent ); + bool doubleClicked( QListViewItem * item ); +}; + +#endif /* __DU_LISTVIEW_H__ */ + diff --git a/krusader/DiskUsage/filelightParts/Config.cpp b/krusader/DiskUsage/filelightParts/Config.cpp new file mode 100644 index 0000000..777ec68 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/Config.cpp @@ -0,0 +1,50 @@ + +#include "Config.h" +#include +#include + + +bool Config::varyLabelFontSizes = true; +bool Config::showSmallFiles = false; +uint Config::contrast = 50; +uint Config::antiAliasFactor = 2; +uint Config::minFontPitch = 10; +uint Config::defaultRingDepth = 4; +Filelight::MapScheme Config::scheme; + + +inline KConfig& +Filelight::Config::kconfig() +{ + KConfig *config = KGlobal::config(); + config->setGroup( "DiskUsage" ); + return *config; +} + +void +Filelight::Config::read() +{ + const KConfig &config = kconfig(); + + varyLabelFontSizes = config.readBoolEntry( "varyLabelFontSizes", true ); + showSmallFiles = config.readBoolEntry( "showSmallFiles", false ); + contrast = config.readNumEntry( "contrast", 50 ); + antiAliasFactor = config.readNumEntry( "antiAliasFactor", 2 ); + minFontPitch = config.readNumEntry( "minFontPitch", QFont().pointSize() - 3); + scheme = (MapScheme) config.readNumEntry( "scheme", 0 ); + + defaultRingDepth = 4; +} + +void +Filelight::Config::write() +{ + KConfig &config = kconfig(); + + config.writeEntry( "varyLabelFontSizes", varyLabelFontSizes ); + config.writeEntry( "showSmallFiles", showSmallFiles); + config.writeEntry( "contrast", contrast ); + config.writeEntry( "antiAliasFactor", antiAliasFactor ); + config.writeEntry( "minFontPitch", minFontPitch ); + config.writeEntry( "scheme", scheme ); +} diff --git a/krusader/DiskUsage/filelightParts/Config.h b/krusader/DiskUsage/filelightParts/Config.h new file mode 100644 index 0000000..a0491b6 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/Config.h @@ -0,0 +1,37 @@ + +#ifndef Config_H +#define Config_H + +#include + +class KConfig; + + +namespace Filelight +{ + enum MapScheme { Rainbow, HighContrast, KDE, FileDensity, ModTime }; + + class Config + { + static KConfig& kconfig(); + + public: + static void read(); + static void write(); + + //keep everything positive, avoid using DON'T, NOT or NO + + static bool varyLabelFontSizes; + static bool showSmallFiles; + static uint contrast; + static uint antiAliasFactor; + static uint minFontPitch; + static uint defaultRingDepth; + + static MapScheme scheme; + }; +} + +using Filelight::Config; + +#endif diff --git a/krusader/DiskUsage/filelightParts/Makefile.am b/krusader/DiskUsage/filelightParts/Makefile.am new file mode 100644 index 0000000..002f461 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/Makefile.am @@ -0,0 +1,9 @@ +noinst_LIBRARIES = libfilelightparts.a + +INCLUDES = $(all_includes) + +METASOURCES = AUTO + +libfilelightparts_a_SOURCES = \ + Config.cpp \ + fileTree.cpp diff --git a/krusader/DiskUsage/filelightParts/debug.h b/krusader/DiskUsage/filelightParts/debug.h new file mode 100644 index 0000000..252a001 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/debug.h @@ -0,0 +1,14 @@ +//Author: Max Howell , (C) 2003-4 +//Copyright: See COPYING file that comes with this distribution + +#ifndef DEBUG_H +#define DEBUG_H + +#include + +#define debug kdDebug +#define error kdError +#define fatal kdFatal +#define warning kdWarning + +#endif diff --git a/krusader/DiskUsage/filelightParts/fileTree.cpp b/krusader/DiskUsage/filelightParts/fileTree.cpp new file mode 100644 index 0000000..b9409c3 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/fileTree.cpp @@ -0,0 +1,78 @@ +//Author: Max Howell , (C) 2004 +//Copyright: See COPYING file that comes with this distribution + +#include "fileTree.h" +#include +#include +#include + +//static definitions +const FileSize File::DENOMINATOR[4] = { 1ull, 1ull<<10, 1ull<<20, 1ull<<30 }; +const char File::PREFIX[5][2] = { "", "K", "M", "G", "T" }; + +QString +File::fullPath( const Directory *root /*= 0*/ ) const +{ + QString path; + + if( root == this ) root = 0; //prevent returning empty string when there is something we could return + + const File *d; + + for( d = this; d != root && d && d->parent() != 0; d = d->parent() ) + { + if( !path.isEmpty() ) + path = "/" + path; + + path = d->name() + path; + } + + if( d ) + { + while( d->parent() ) + d = d->parent(); + + if( d->directory().endsWith( "/" ) ) + return d->directory() + path; + else + return d->directory() + "/" + path; + } + else + return path; +} + +QString +File::humanReadableSize( UnitPrefix key /*= mega*/ ) const //FIXME inline +{ + return humanReadableSize( m_size, key ); +} + +QString +File::humanReadableSize( FileSize size, UnitPrefix key /*= mega*/ ) //static +{ + QString s; + double prettySize = (double)size / (double)DENOMINATOR[key]; + const KLocale &locale = *KGlobal::locale(); + + if( prettySize >= 0.01 ) + { + if( prettySize < 1 ) s = locale.formatNumber( prettySize, 2 ); + else if( prettySize < 100 ) s = locale.formatNumber( prettySize, 1 ); + else s = locale.formatNumber( prettySize, 0 ); + + s += ' '; + s += PREFIX[key]; + s += 'B'; + } + + if( prettySize < 0.1 ) + { + s += " ("; + s += locale.formatNumber( size / DENOMINATOR[ key ? key - 1 : 0 ], 0 ); + s += ' '; + s += PREFIX[key]; + s += "B)"; + } + + return s; +} diff --git a/krusader/DiskUsage/filelightParts/fileTree.h b/krusader/DiskUsage/filelightParts/fileTree.h new file mode 100644 index 0000000..f4d98b6 --- /dev/null +++ b/krusader/DiskUsage/filelightParts/fileTree.h @@ -0,0 +1,299 @@ +//Author: Max Howell , (C) 2004 +//Copyright: See COPYING file that comes with this distribution + +#ifndef FILETREE_H +#define FILETREE_H + +#include +#include +#include + +//TODO these are pointlessly general purpose now, make them incredibly specific + + + +typedef KIO::filesize_t FileSize; + +template class Iterator; +template class ConstIterator; +template class Chain; + +template +class Link +{ +public: + Link( T* const t ) : prev( this ), next( this ), data( t ) {} + Link() : prev( this ), next( this ), data( 0 ) {} + + //TODO unlinking is slow and you don't use it very much in this context. + // ** Perhaps you can make a faster deletion system that doesn't bother tidying up first + // ** and then you MUST call some kind of detach() function when you remove elements otherwise + ~Link() { delete data; unlink(); } + + friend class Iterator; + friend class ConstIterator; + friend class Chain; + +private: + void unlink() { prev->next = next; next->prev = prev; prev = next = this; } + + Link* prev; + Link* next; + + T* data; //ensure only iterators have access to this +}; + + +template +class Iterator +{ +public: + Iterator() : link( 0 ) { } //**** remove this, remove this REMOVE THIS!!! dangerous as your implementation doesn't test for null links, always assumes they can be derefenced + Iterator( Link *p ) : link( p ) { } + + bool operator==( const Iterator& it ) const { return link == it.link; } + bool operator!=( const Iterator& it ) const { return link != it.link; } + bool operator!=( const Link *p ) const { return p != link; } + + //here we have a choice, really I should make two classes one const the other not + const T* operator*() const { return link->data; } + T* operator*() { return link->data; } + + Iterator& operator++() { link = link->next; return *this; } //**** does it waste time returning in places where we don't use the retval? + + bool isNull() const { return (link == 0); } //REMOVE WITH ABOVE REMOVAL you don't want null iterators to be possible + + void transferTo( Chain &chain ) + { + chain.append( remove() ); + } + + T* const remove() //remove from list, delete Link, data is returned NOT deleted + { + T* const d = link->data; + Link* const p = link->prev; + + link->data = 0; + delete link; + link = p; //make iterator point to previous element, YOU must check this points to an element + + return d; + } + +private: + Link *link; +}; + + +template +class ConstIterator +{ +public: + ConstIterator( Link *p ) : link( p ) { } + + bool operator==( const Iterator& it ) const { return link == it.link; } + bool operator!=( const Iterator& it ) const { return link != it.link; } + bool operator!=( const Link *p ) const { return p != link; } + + const T* operator*() const { return link->data; } + + ConstIterator& operator++() { link = link->next; return *this; } + +private: + const Link *link; +}; + +//**** try to make a generic list class and then a brief full list template that inlines +// thus reducing code bloat +template +class Chain +{ +public: + Chain() { } + virtual ~Chain() { empty(); } + + void append( T* const data ) + { + Link* const link = new Link( data ); + + link->prev = head.prev; + link->next = &head; + + head.prev->next = link; + head.prev = link; + } + + void transferTo( Chain &c ) + { + if( isEmpty() ) return; + + Link* const first = head.next; + Link* const last = head.prev; + + head.unlink(); + + first->prev = c.head.prev; + c.head.prev->next = first; + + last->next = &c.head; + c.head.prev = last; + } + + void empty() { while( head.next != &head ) { delete head.next; } } + + Iterator iterator() const { return Iterator( head.next ); } + ConstIterator constIterator() const { return ConstIterator( head.next ); } + const Link *end() const { return &head; } + bool isEmpty() const { return ( head.next == &head ); } + +private: + Link head; + void operator=( const Chain& ) {} +}; + + +class Directory; +class QString; +class KURL; + +class File +{ +protected: + Directory *m_parent; //0 if this is treeRoot + QString m_name; //< file name + QString m_directory;//< the directory of the file + FileSize m_size; //< size with subdirectories + FileSize m_ownSize; //< size without subdirectories + mode_t m_mode; //< file mode + QString m_owner; //< file owner name + QString m_group; //< file group name + QString m_perm; //< file permissions string + time_t m_time; //< file modification in time_t format + bool m_symLink; //< true if the file is a symlink + QString m_mimeType; //< file mimetype + bool m_excluded; //< flag if the file is excluded from du + int m_percent; //< percent flag + +public: + File( Directory *parentIn, const QString &nameIn, const QString &dir, FileSize sizeIn, mode_t modeIn, + const QString &ownerIn, const QString &groupIn, const QString &permIn, time_t timeIn, bool symLinkIn, + const QString &mimeTypeIn ) + : m_parent( parentIn ), m_name( nameIn ), m_directory( dir ), m_size( sizeIn ), m_ownSize( sizeIn ), m_mode( modeIn ), + m_owner( ownerIn ), m_group( groupIn ), m_perm( permIn ), m_time( timeIn ), m_symLink( symLinkIn ), + m_mimeType( mimeTypeIn ), m_excluded( false ), m_percent( -1 ) {} + + File( const QString &nameIn, FileSize sizeIn ) + : m_parent( 0 ), m_name( nameIn ), m_directory( QString::null ), m_size( sizeIn ), m_ownSize( sizeIn ), m_mode( 0 ), + m_owner( QString::null ), m_group( QString::null ), m_perm( QString::null ), m_time( -1 ), + m_symLink( false ), m_mimeType( QString::null ), m_excluded( false ), m_percent( -1 ) + { + } + + virtual ~File() {} + + inline const QString & name() const {return m_name;} + inline const QString & directory() const {return m_directory;} + inline const FileSize size() const {return m_excluded ? 0 : m_size;} + inline const FileSize ownSize() const {return m_excluded ? 0 : m_ownSize;} + inline const mode_t mode() const {return m_mode;} + inline const QString & owner() const {return m_owner;} + inline const QString & group() const {return m_group;} + inline const QString & perm() const {return m_perm;} + inline const time_t time() const {return m_time;} + inline const QString & mime() const {return m_mimeType;} + inline const bool isSymLink() const {return m_symLink;} + virtual const bool isDir() const {return false;} + inline const bool isExcluded() const {return m_excluded;} + inline void exclude( bool flag ) {m_excluded = flag;} + inline const int intPercent() const {return m_percent;} + inline const QString percent() const {if( m_percent < 0 ) + return "INV"; + QString buf; + buf.sprintf( "%d.%02d%%", m_percent / 100, m_percent % 100 ); + return buf;} + inline void setPercent( int p ) {m_percent = p;} + inline const Directory* parent() const {return m_parent;} + + inline void setSizes( KIO::filesize_t totalSize, KIO::filesize_t ownSize ) + { + m_ownSize = ownSize; + m_size = totalSize; + } + + enum UnitPrefix { kilo, mega, giga, tera }; + + static const FileSize DENOMINATOR[4]; + static const char PREFIX[5][2]; + + QString fullPath( const Directory* = 0 ) const; + QString humanReadableSize( UnitPrefix key = mega ) const; + + static QString humanReadableSize( FileSize size, UnitPrefix Key = mega ); + + friend class Directory; +}; + + +//TODO when you modify this to take into account hardlinks you should make the Chain layered not inherited +class Directory : public Chain, public File +{ +public: + Directory( Directory *parentIn, const QString &nameIn, const QString &dir, FileSize sizeIn, mode_t modeIn, + const QString &ownerIn, const QString &groupIn, const QString &permIn, time_t timeIn, bool symLinkIn, + const QString &mimeTypeIn ) + : File( parentIn, nameIn, dir, sizeIn, modeIn, ownerIn, groupIn, permIn, timeIn, symLinkIn, mimeTypeIn ), + m_fileCount( 0 ) + {} + + Directory( const QString &name, QString url ) : File( name, 0 ), m_fileCount( 0 ) + { + m_directory = url; + } + + virtual ~Directory() {} + virtual const bool isDir() const {return true;} + + void append( File *p ) + { + ++m_fileCount; + + Directory *parent = m_parent; + while( parent ) + { + parent->m_fileCount++; + parent = parent->m_parent; + } + + Chain::append( p ); + p->m_parent = this; + } + + void remove( File *p ) + { + for( Iterator it = Chain::iterator(); it != Chain::end(); ++it ) + if( (*it) == p ) + { + --m_fileCount; + + Directory *parent = m_parent; + while( parent ) + { + parent->m_fileCount--; + parent = parent->m_parent; + } + + it.remove(); + break; + } + } + + uint fileCount() const { return m_fileCount; } + +private: + Directory( const Directory& ); + void operator=( const Directory& ); + + uint m_fileCount; +}; + +#endif diff --git a/krusader/DiskUsage/radialMap/Makefile.am b/krusader/DiskUsage/radialMap/Makefile.am new file mode 100644 index 0000000..a3a3e74 --- /dev/null +++ b/krusader/DiskUsage/radialMap/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libradialmap.a + +INCLUDES = -I$(top_srcdir)/krusader/DiskUsage/filelightParts \ + $(all_includes) + +METASOURCES = AUTO + +libradialmap_a_SOURCES = \ + widget.cpp \ + builder.cpp \ + map.cpp \ + widgetEvents.cpp \ + labels.cpp \ + segmentTip.cpp diff --git a/krusader/DiskUsage/radialMap/builder.cpp b/krusader/DiskUsage/radialMap/builder.cpp new file mode 100644 index 0000000..5a827af --- /dev/null +++ b/krusader/DiskUsage/radialMap/builder.cpp @@ -0,0 +1,139 @@ +//Author: Max Howell , (C) 2003-4 +//Copyright: See COPYING file that comes with this distribution + +#include "builder.h" +#include "Config.h" +#include "fileTree.h" +#include //locale object +#include +#include "widget.h" + + +//**** REMOVE NEED FOR the +1 with MAX_RING_DEPTH uses +//**** add some angle bounds checking (possibly in Segment ctor? can I delete in a ctor?) +//**** this class is a mess + +RadialMap::Builder::Builder( RadialMap::Map *m, const Directory* const d, bool fast ) + : m_map( m ) + , m_root( d ) + , m_minSize( static_cast((d->size() * 3) / (PI * m->height() - m->MAP_2MARGIN )) ) + , m_depth( &m->m_visibleDepth ) +{ + m_signature = new Chain [*m_depth + 1]; + + if( !fast )//|| *m_depth == 0 ) //depth 0 is special case usability-wise //**** WHY?! + { + //determine depth rather than use old one + findVisibleDepth( d ); //sets m_depth + } + + m_map->setRingBreadth(); + setLimits( m_map->m_ringBreadth ); + build( d ); + + m_map->m_signature = m_signature; + + delete []m_limits; +} + + +void +RadialMap::Builder::findVisibleDepth( const Directory* const dir, const unsigned int depth ) +{ + //**** because I don't use the same minimumSize criteria as in the visual function + // this can lead to incorrect visual representation + //**** BUT, you can't set those limits until you know m_depth! + + //**** also this function doesn't check to see if anything is actually visible + // it just assumes that when it reaches a new level everything in it is visible + // automatically. This isn't right especially as there might be no files in the + // dir provided to this function! + + static uint stopDepth = 0; + + if( dir == m_root ) + { + stopDepth = *m_depth; + *m_depth = 0; + } + + if( *m_depth < depth ) *m_depth = depth; + if( *m_depth >= stopDepth ) return; + + for( ConstIterator it = dir->constIterator(); it != dir->end(); ++it ) + if( (*it)->isDir() && (*it)->size() > m_minSize ) + findVisibleDepth( (Directory *)*it, depth + 1 ); //if no files greater than min size the depth is still recorded +} + +void +RadialMap::Builder::setLimits( const uint &b ) //b = breadth? +{ + double size3 = m_root->size() * 3; + double pi2B = PI * 2 * b; + + m_limits = new FileSize [*m_depth + 1]; //FIXME delete! + + for( unsigned int d = 0; d <= *m_depth; ++d ) + m_limits[d] = (FileSize)(size3 / (double)(pi2B * (d + 1))); //min is angle that gives 3px outer diameter for that depth +} + + +//**** segments currently overlap at edges (i.e. end of first is start of next) +bool +RadialMap::Builder::build( const Directory* const dir, const unsigned int depth, unsigned int a_start, const unsigned int a_end ) +{ + //first iteration: dir == m_root + + if( dir->fileCount() == 0 ) //we do fileCount rather than size to avoid chance of divide by zero later + return false; + + FileSize hiddenSize = 0; + uint hiddenFileCount = 0; + + for( ConstIterator it = dir->constIterator(); it != dir->end(); ++it ) + { + if( (*it)->size() > m_limits[depth] ) + { + unsigned int a_len = (unsigned int)(5760 * ((double)(*it)->size() / (double)m_root->size())); + + Segment *s = new Segment( *it, a_start, a_len ); + + (m_signature + depth)->append( s ); + + if( (*it)->isDir() ) + { + if( depth != *m_depth ) + { + //recurse + s->m_hasHiddenChildren = build( (Directory*)*it, depth + 1, a_start, a_start + a_len ); + } + else s->m_hasHiddenChildren = true; + } + + a_start += a_len; //**** should we add 1? + + } else { + + hiddenSize += (*it)->size(); + + if( (*it)->isDir() ) //**** considered virtual, but dir wouldn't count itself! + hiddenFileCount += static_cast(*it)->fileCount(); //need to add one to count the dir as well + + ++hiddenFileCount; + } + } + + if( hiddenFileCount == dir->fileCount() && !Config::showSmallFiles ) + + return true; + + else if( (Config::showSmallFiles && hiddenSize > m_limits[depth]) || (depth == 0 && (hiddenSize > dir->size()/8)) /*|| > size() * 0.75*/ ) + { + //append a segment for unrepresented space - a "fake" segment + + const QString s = i18n( "%1 files: ~ %2" ).arg( KGlobal::locale()->formatNumber( hiddenFileCount, 0 ) ).arg( File::humanReadableSize( hiddenSize/hiddenFileCount ) ); + (m_signature + depth)->append( new Segment( new File( s, hiddenSize ), a_start, a_end - a_start, true ) ); + } + + return false; +} diff --git a/krusader/DiskUsage/radialMap/builder.h b/krusader/DiskUsage/radialMap/builder.h new file mode 100644 index 0000000..2fddbe0 --- /dev/null +++ b/krusader/DiskUsage/radialMap/builder.h @@ -0,0 +1,37 @@ +//Author: Max Howell , (C) 2003-4 +//Copyright: See COPYING file that comes with this distribution + +#ifndef BUILDER_H +#define BUILDER_H + +#include "radialMap.h" //Segment, defines +#include "fileTree.h" + +template class Chain; + +namespace RadialMap +{ + class Map; + + //temporary class that builds the Map signature + + class Builder + { + public: + Builder( Map*, const Directory* const, bool fast=false ); + + private: + void findVisibleDepth( const Directory* const dir, const uint=0 ); + void setLimits( const uint& ); + bool build( const Directory* const, const uint=0, uint=0, const uint=5760 ); + + Map *m_map; + const Directory* const m_root; + const FileSize m_minSize; + uint *m_depth; + Chain *m_signature; + FileSize *m_limits; + }; +} + +#endif diff --git a/krusader/DiskUsage/radialMap/labels.cpp b/krusader/DiskUsage/radialMap/labels.cpp new file mode 100644 index 0000000..5ba77ac --- /dev/null +++ b/krusader/DiskUsage/radialMap/labels.cpp @@ -0,0 +1,342 @@ +//Author: Max Howell , (C) 2003-4 +//Copyright: See COPYING file that comes with this distribution + +#include +#include +#include +#include +#include + +#include "Config.h" +#include "fileTree.h" +#include "radialMap.h" +#include "sincos.h" +#include "widget.h" + + + +namespace RadialMap +{ + struct Label + { + Label( const RadialMap::Segment *s, int l ) : segment( s ), lvl( l ), a( segment->start() + (segment->length() / 2) ) { } + + bool tooClose( const int &aa ) const { return ( a > aa - LABEL_ANGLE_MARGIN && a < aa + LABEL_ANGLE_MARGIN ); } + + const RadialMap::Segment *segment; + const unsigned int lvl; + const int a; + + int x1, y1, x2, y2, x3; + int tx, ty; + + QString qs; + }; + + class LabelList : public QPtrList