summaryrefslogtreecommitdiffstats
path: root/konqueror
diff options
context:
space:
mode:
Diffstat (limited to 'konqueror')
-rw-r--r--konqueror/AUTHORS16
-rw-r--r--konqueror/ChangeLog433
-rw-r--r--konqueror/DESIGN99
-rw-r--r--konqueror/DESIGN_config43
-rw-r--r--konqueror/Home.desktop170
-rw-r--r--konqueror/IDEAS223
-rw-r--r--konqueror/KonqMainWindowIface.cc175
-rw-r--r--konqueror/KonqMainWindowIface.h95
-rw-r--r--konqueror/KonqViewIface.cc141
-rw-r--r--konqueror/KonqViewIface.h136
-rw-r--r--konqueror/KonquerorIface.cc295
-rw-r--r--konqueror/KonquerorIface.h189
-rw-r--r--konqueror/Makefile.am105
-rw-r--r--konqueror/TODO49
-rw-r--r--konqueror/about/Makefile.am17
-rw-r--r--konqueror/about/box-centre-konqueror.pngbin0 -> 34202 bytes
-rw-r--r--konqueror/about/intro.html89
-rw-r--r--konqueror/about/konq.css21
-rw-r--r--konqueror/about/konq_aboutpage.cc518
-rw-r--r--konqueror/about/konq_aboutpage.desktop86
-rw-r--r--konqueror/about/konq_aboutpage.h63
-rw-r--r--konqueror/about/konqaboutpage.desktop4
-rw-r--r--konqueror/about/launch.html119
-rw-r--r--konqueror/about/lightning.pngbin0 -> 203 bytes
-rw-r--r--konqueror/about/plugins.html48
-rw-r--r--konqueror/about/plugins_rtl.html51
-rw-r--r--konqueror/about/specs.html206
-rw-r--r--konqueror/about/tips.html126
-rw-r--r--konqueror/about/top-right-konqueror.pngbin0 -> 16195 bytes
-rw-r--r--konqueror/client/ChangeLog14
-rw-r--r--konqueror/client/Makefile.am23
-rw-r--r--konqueror/client/kfmclient.cc643
-rw-r--r--konqueror/client/kfmclient.h51
-rw-r--r--konqueror/client/kfmclient_3_2.upd4
-rw-r--r--konqueror/client/kfmclient_3_2_update.sh21
-rwxr-xr-xkonqueror/convert_kdelnk.sh27
-rw-r--r--konqueror/delayedinitializer.cc55
-rw-r--r--konqueror/delayedinitializer.h45
-rw-r--r--konqueror/iconview/Makefile.am17
-rw-r--r--konqueror/iconview/konq_iconview.cc1539
-rw-r--r--konqueror/iconview/konq_iconview.desktop92
-rw-r--r--konqueror/iconview/konq_iconview.h299
-rw-r--r--konqueror/iconview/konq_iconview.rc51
-rw-r--r--konqueror/iconview/konq_multicolumnview.desktop92
-rw-r--r--konqueror/iconview/konq_multicolumnview.rc47
-rw-r--r--konqueror/keditbookmarks/DESIGN20
-rw-r--r--konqueror/keditbookmarks/Makefile.am34
-rw-r--r--konqueror/keditbookmarks/TODO120
-rw-r--r--konqueror/keditbookmarks/actionsimpl.cpp638
-rw-r--r--konqueror/keditbookmarks/actionsimpl.h83
-rw-r--r--konqueror/keditbookmarks/bookmarkinfo.cpp293
-rw-r--r--konqueror/keditbookmarks/bookmarkinfo.h111
-rw-r--r--konqueror/keditbookmarks/bookmarkiterator.cpp105
-rw-r--r--konqueror/keditbookmarks/bookmarkiterator.h74
-rw-r--r--konqueror/keditbookmarks/commands.cpp745
-rw-r--r--konqueror/keditbookmarks/commands.h256
-rw-r--r--konqueror/keditbookmarks/cr16-app-keditbookmarks.pngbin0 -> 916 bytes
-rw-r--r--konqueror/keditbookmarks/cr32-app-keditbookmarks.pngbin0 -> 1636 bytes
-rw-r--r--konqueror/keditbookmarks/cr48-app-keditbookmarks.pngbin0 -> 2663 bytes
-rw-r--r--konqueror/keditbookmarks/cr64-app-keditbookmarks.pngbin0 -> 5042 bytes
-rw-r--r--konqueror/keditbookmarks/dcop.cpp67
-rw-r--r--konqueror/keditbookmarks/dcop.h36
-rw-r--r--konqueror/keditbookmarks/exporters.cpp90
-rw-r--r--konqueror/keditbookmarks/exporters.h39
-rw-r--r--konqueror/keditbookmarks/favicons.cpp100
-rw-r--r--konqueror/keditbookmarks/favicons.h69
-rw-r--r--konqueror/keditbookmarks/importers.cpp293
-rw-r--r--konqueror/keditbookmarks/importers.h192
-rw-r--r--konqueror/keditbookmarks/kbookmarkmerger.cpp138
-rw-r--r--konqueror/keditbookmarks/kebsearchline.cpp82
-rw-r--r--konqueror/keditbookmarks/kebsearchline.h52
-rw-r--r--konqueror/keditbookmarks/keditbookmarks-genui.rc146
-rw-r--r--konqueror/keditbookmarks/keditbookmarks.kcfg42
-rw-r--r--konqueror/keditbookmarks/keditbookmarksui.rc218
-rw-r--r--konqueror/keditbookmarks/kinsertionsort.h59
-rw-r--r--konqueror/keditbookmarks/listview.cpp968
-rw-r--r--konqueror/keditbookmarks/listview.h217
-rw-r--r--konqueror/keditbookmarks/main.cpp199
-rw-r--r--konqueror/keditbookmarks/settings.kcfgc4
-rw-r--r--konqueror/keditbookmarks/testlink.cpp395
-rw-r--r--konqueror/keditbookmarks/testlink.h75
-rw-r--r--konqueror/keditbookmarks/toplevel.cpp356
-rw-r--r--konqueror/keditbookmarks/toplevel.h175
-rw-r--r--konqueror/keditbookmarks/uninstall.desktop2
-rw-r--r--konqueror/keditbookmarks/updater.cpp180
-rw-r--r--konqueror/keditbookmarks/updater.h91
-rw-r--r--konqueror/kfmclient.desktop22
-rw-r--r--konqueror/kfmclient_dir.desktop20
-rw-r--r--konqueror/kfmclient_html.desktop21
-rw-r--r--konqueror/kfmclient_war.desktop21
-rw-r--r--konqueror/konq-simplebrowser.rc99
-rw-r--r--konqueror/konq_actions.cc504
-rw-r--r--konqueror/konq_actions.h158
-rw-r--r--konqueror/konq_browseriface.cc22
-rw-r--r--konqueror/konq_browseriface.h24
-rw-r--r--konqueror/konq_combo.cc892
-rw-r--r--konqueror/konq_combo.h115
-rw-r--r--konqueror/konq_extensionmanager.cc147
-rw-r--r--konqueror/konq_extensionmanager.h57
-rw-r--r--konqueror/konq_factory.cc263
-rw-r--r--konqueror/konq_factory.h86
-rw-r--r--konqueror/konq_frame.cc670
-rw-r--r--konqueror/konq_frame.h410
-rw-r--r--konqueror/konq_guiclients.cc358
-rw-r--r--konqueror/konq_guiclients.h97
-rw-r--r--konqueror/konq_main.cc222
-rw-r--r--konqueror/konq_main.h27
-rw-r--r--konqueror/konq_mainwindow.cc5907
-rw-r--r--konqueror/konq_mainwindow.h771
-rw-r--r--konqueror/konq_mainwindow_p.h40
-rw-r--r--konqueror/konq_misc.cc281
-rw-r--r--konqueror/konq_misc.h135
-rw-r--r--konqueror/konq_openurlrequest.h64
-rw-r--r--konqueror/konq_profiledlg.cc266
-rw-r--r--konqueror/konq_profiledlg.h83
-rw-r--r--konqueror/konq_run.cc195
-rw-r--r--konqueror/konq_run.h73
-rw-r--r--konqueror/konq_settingsxt.kcfgc4
-rw-r--r--konqueror/konq_tabs.cc539
-rw-r--r--konqueror/konq_tabs.h130
-rw-r--r--konqueror/konq_view.cc1398
-rw-r--r--konqueror/konq_view.h479
-rw-r--r--konqueror/konq_viewmgr.cc1831
-rw-r--r--konqueror/konq_viewmgr.h367
-rw-r--r--konqueror/konqbrowser.desktop98
-rw-r--r--konqueror/konqfilemgr.desktop90
-rw-r--r--konqueror/konqueror.desktop100
-rw-r--r--konqueror/konqueror.kcfg620
-rw-r--r--konqueror/konqueror.rc152
-rw-r--r--konqueror/konquerorsu.desktop90
-rw-r--r--konqueror/kttsplugin/Makefile.am16
-rw-r--r--konqueror/kttsplugin/khtmlkttsd.cpp138
-rw-r--r--konqueror/kttsplugin/khtmlkttsd.desktop75
-rw-r--r--konqueror/kttsplugin/khtmlkttsd.h46
-rw-r--r--konqueror/kttsplugin/khtmlkttsd.rc13
-rw-r--r--konqueror/listview/Makefile.am30
-rw-r--r--konqueror/listview/konq_detailedlistview.desktop89
-rw-r--r--konqueror/listview/konq_detailedlistview.rc52
-rw-r--r--konqueror/listview/konq_infolistview.desktop87
-rw-r--r--konqueror/listview/konq_infolistview.rc39
-rw-r--r--konqueror/listview/konq_infolistviewitem.cc281
-rw-r--r--konqueror/listview/konq_infolistviewitem.h79
-rw-r--r--konqueror/listview/konq_infolistviewwidget.cc383
-rw-r--r--konqueror/listview/konq_infolistviewwidget.h89
-rw-r--r--konqueror/listview/konq_listview.cc691
-rw-r--r--konqueror/listview/konq_listview.h210
-rw-r--r--konqueror/listview/konq_listview.kcfg37
-rw-r--r--konqueror/listview/konq_listviewitems.cc449
-rw-r--r--konqueror/listview/konq_listviewitems.h123
-rw-r--r--konqueror/listview/konq_listviewsettings.kcfgc4
-rw-r--r--konqueror/listview/konq_listviewwidget.cc1416
-rw-r--r--konqueror/listview/konq_listviewwidget.h270
-rw-r--r--konqueror/listview/konq_textview.desktop90
-rw-r--r--konqueror/listview/konq_textview.rc35
-rw-r--r--konqueror/listview/konq_textviewitem.cc232
-rw-r--r--konqueror/listview/konq_textviewitem.h75
-rw-r--r--konqueror/listview/konq_textviewwidget.cc223
-rw-r--r--konqueror/listview/konq_textviewwidget.h54
-rw-r--r--konqueror/listview/konq_treeview.desktop90
-rw-r--r--konqueror/listview/konq_treeview.rc52
-rw-r--r--konqueror/listview/konq_treeviewitem.cc96
-rw-r--r--konqueror/listview/konq_treeviewitem.h79
-rw-r--r--konqueror/listview/konq_treeviewwidget.cc307
-rw-r--r--konqueror/listview/konq_treeviewwidget.h67
-rw-r--r--konqueror/pics/Makefile.am3
-rw-r--r--konqueror/pics/actions/Makefile.am3
-rw-r--r--konqueror/pics/actions/cr16-action-kde1.pngbin0 -> 880 bytes
-rw-r--r--konqueror/pics/actions/cr16-action-kde2.pngbin0 -> 867 bytes
-rw-r--r--konqueror/pics/actions/cr16-action-kde3.pngbin0 -> 880 bytes
-rw-r--r--konqueror/pics/actions/cr16-action-kde4.pngbin0 -> 867 bytes
-rw-r--r--konqueror/pics/actions/cr16-action-kde5.pngbin0 -> 880 bytes
-rw-r--r--konqueror/pics/actions/cr16-action-kde6.pngbin0 -> 867 bytes
-rw-r--r--konqueror/pics/hi128-app-konqueror.pngbin0 -> 19548 bytes
-rw-r--r--konqueror/pics/hi16-app-kfm.pngbin0 -> 995 bytes
-rw-r--r--konqueror/pics/hi16-app-konqueror.pngbin0 -> 959 bytes
-rw-r--r--konqueror/pics/hi22-app-kfm.pngbin0 -> 1411 bytes
-rw-r--r--konqueror/pics/hi22-app-konqueror.pngbin0 -> 1663 bytes
-rw-r--r--konqueror/pics/hi32-app-kfm.pngbin0 -> 2691 bytes
-rw-r--r--konqueror/pics/hi32-app-konqueror.pngbin0 -> 2680 bytes
-rw-r--r--konqueror/pics/hi48-app-kfm.pngbin0 -> 4693 bytes
-rw-r--r--konqueror/pics/hi48-app-konqueror.pngbin0 -> 5009 bytes
-rw-r--r--konqueror/pics/hi64-app-kfm.pngbin0 -> 6521 bytes
-rw-r--r--konqueror/pics/hi64-app-konqueror.pngbin0 -> 7776 bytes
-rw-r--r--konqueror/pics/hisc-app-konqueror.svgzbin0 -> 12489 bytes
-rw-r--r--konqueror/pics/indicators/Makefile.am4
-rw-r--r--konqueror/pics/indicators/indicator_connect.pngbin0 -> 496 bytes
-rw-r--r--konqueror/pics/indicators/indicator_empty.pngbin0 -> 591 bytes
-rw-r--r--konqueror/pics/indicators/indicator_noconnect.pngbin0 -> 233 bytes
-rw-r--r--konqueror/pics/indicators/indicator_viewactive.pngbin0 -> 654 bytes
-rw-r--r--konqueror/pics/tiles/Makefile.am3
-rw-r--r--konqueror/pics/tiles/bluemorning.pngbin0 -> 13747 bytes
-rw-r--r--konqueror/pics/tiles/canvas.pngbin0 -> 35031 bytes
-rw-r--r--konqueror/pics/tiles/kde4ever.pngbin0 -> 15428 bytes
-rw-r--r--konqueror/pics/tiles/kenwimer.pngbin0 -> 422 bytes
-rw-r--r--konqueror/pics/tiles/noise.pngbin0 -> 44973 bytes
-rw-r--r--konqueror/pics/tiles/paper_flieder.pngbin0 -> 60601 bytes
-rw-r--r--konqueror/pics/tiles/redfiber.pngbin0 -> 72488 bytes
-rw-r--r--konqueror/preloader/Makefile.am21
-rw-r--r--konqueror/preloader/configure.in.in151
-rw-r--r--konqueror/preloader/konqy_preload.desktop75
-rw-r--r--konqueror/preloader/konqy_preloader.desktop146
-rw-r--r--konqueror/preloader/preloader.cc151
-rw-r--r--konqueror/preloader/preloader.h58
-rw-r--r--konqueror/profile_filemanagement.desktop95
-rw-r--r--konqueror/profile_filepreview.desktop110
-rw-r--r--konqueror/profile_kde_devel.desktop112
-rw-r--r--konqueror/profile_midnightcommander.desktop45
-rw-r--r--konqueror/profile_simplebrowser.desktop79
-rw-r--r--konqueror/profile_tabbedbrowsing.desktop106
-rw-r--r--konqueror/profile_webbrowsing.desktop86
-rw-r--r--konqueror/quickprint/Makefile.am7
-rw-r--r--konqueror/quickprint/TODO18
-rw-r--r--konqueror/quickprint/text-ada-print.desktop79
-rw-r--r--konqueror/quickprint/text-c++-print.desktop79
-rw-r--r--konqueror/quickprint/text-c++h-print.desktop79
-rw-r--r--konqueror/quickprint/text-c-print.desktop79
-rw-r--r--konqueror/quickprint/text-ch-print.desktop79
-rw-r--r--konqueror/quickprint/text-css-print.desktop79
-rw-r--r--konqueror/quickprint/text-diff-print.desktop79
-rw-r--r--konqueror/quickprint/text-html-print.desktop79
-rw-r--r--konqueror/quickprint/text-java-print.desktop79
-rw-r--r--konqueror/quickprint/text-log-print.desktop79
-rw-r--r--konqueror/quickprint/text-makefile-print.desktop79
-rw-r--r--konqueror/quickprint/text-pas-print.desktop79
-rw-r--r--konqueror/quickprint/text-perl-print.desktop79
-rw-r--r--konqueror/quickprint/text-print.desktop79
-rw-r--r--konqueror/quickprint/text-python-print.desktop79
-rw-r--r--konqueror/quickprint/text-tcl-print.desktop79
-rw-r--r--konqueror/quickprint/text-tex-print.desktop79
-rw-r--r--konqueror/quickprint/text-xml-print.desktop79
-rw-r--r--konqueror/quickprint/text-xslt-print.desktop79
-rw-r--r--konqueror/remoteencodingplugin/Makefile.am13
-rw-r--r--konqueror/remoteencodingplugin/kremoteencodingplugin.cpp266
-rw-r--r--konqueror/remoteencodingplugin/kremoteencodingplugin.desktop135
-rw-r--r--konqueror/remoteencodingplugin/kremoteencodingplugin.h63
-rw-r--r--konqueror/remoteencodingplugin/kremoteencodingplugin.rc8
-rw-r--r--konqueror/shellcmdplugin/Makefile.am14
-rw-r--r--konqueror/shellcmdplugin/kshellcmddialog.cpp90
-rw-r--r--konqueror/shellcmdplugin/kshellcmddialog.h48
-rw-r--r--konqueror/shellcmdplugin/kshellcmdexecutor.cpp156
-rw-r--r--konqueror/shellcmdplugin/kshellcmdexecutor.h50
-rw-r--r--konqueror/shellcmdplugin/kshellcmdplugin.cpp90
-rw-r--r--konqueror/shellcmdplugin/kshellcmdplugin.desktop135
-rw-r--r--konqueror/shellcmdplugin/kshellcmdplugin.h36
-rw-r--r--konqueror/shellcmdplugin/kshellcmdplugin.rc8
-rw-r--r--konqueror/sidebar/.version1
-rw-r--r--konqueror/sidebar/Makefile.am44
-rw-r--r--konqueror/sidebar/konq_sidebartng.desktop93
-rw-r--r--konqueror/sidebar/konqsidebar.cpp127
-rw-r--r--konqueror/sidebar/konqsidebar.h126
-rw-r--r--konqueror/sidebar/konqsidebariface_p.h9
-rw-r--r--konqueror/sidebar/konqsidebarplugin.cpp59
-rw-r--r--konqueror/sidebar/konqsidebarplugin.h97
-rw-r--r--konqueror/sidebar/konqsidebartng.rc7
-rw-r--r--konqueror/sidebar/konqsidebartng.upd12
-rw-r--r--konqueror/sidebar/move_konqsidebartng_entries.sh18
-rw-r--r--konqueror/sidebar/sidebar_widget.cpp1310
-rw-r--r--konqueror/sidebar/sidebar_widget.h225
-rw-r--r--konqueror/sidebar/test/Makefile.am23
-rw-r--r--konqueror/sidebar/test/konqsidebartest.cpp26
-rw-r--r--konqueror/sidebar/test/konqsidebartest.h43
-rw-r--r--konqueror/sidebar/test/test.desktop68
-rw-r--r--konqueror/sidebar/trees/Makefile.am17
-rw-r--r--konqueror/sidebar/trees/bookmark_module/Makefile.am10
-rw-r--r--konqueror/sidebar/trees/bookmark_module/bookmark_item.cpp81
-rw-r--r--konqueror/sidebar/trees/bookmark_module/bookmark_item.h62
-rw-r--r--konqueror/sidebar/trees/bookmark_module/bookmark_module.cpp583
-rw-r--r--konqueror/sidebar/trees/bookmark_module/bookmark_module.h98
-rw-r--r--konqueror/sidebar/trees/dirtree_module/Makefile.am10
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp245
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_item.h73
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp649
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_module.h82
-rw-r--r--konqueror/sidebar/trees/history_module/Makefile.am16
-rw-r--r--konqueror/sidebar/trees/history_module/history_dlg.ui239
-rw-r--r--konqueror/sidebar/trees/history_module/history_item.cpp246
-rw-r--r--konqueror/sidebar/trees/history_module/history_item.h111
-rw-r--r--konqueror/sidebar/trees/history_module/history_module.cpp369
-rw-r--r--konqueror/sidebar/trees/history_module/history_module.h108
-rw-r--r--konqueror/sidebar/trees/history_module/history_settings.cpp111
-rw-r--r--konqueror/sidebar/trees/history_module/history_settings.h66
-rw-r--r--konqueror/sidebar/trees/history_module/kcmhistory.cpp272
-rw-r--r--konqueror/sidebar/trees/history_module/kcmhistory.desktop233
-rw-r--r--konqueror/sidebar/trees/history_module/kcmhistory.h64
-rw-r--r--konqueror/sidebar/trees/init/Makefile.am16
-rw-r--r--konqueror/sidebar/trees/init/README6
-rw-r--r--konqueror/sidebar/trees/init/bookmarks.desktop165
-rw-r--r--konqueror/sidebar/trees/init/bookmarks_module.desktop166
-rw-r--r--konqueror/sidebar/trees/init/dirtree_module.desktop82
-rw-r--r--konqueror/sidebar/trees/init/history.desktop164
-rw-r--r--konqueror/sidebar/trees/init/history_module.desktop165
-rw-r--r--konqueror/sidebar/trees/init/home.desktop158
-rw-r--r--konqueror/sidebar/trees/init/remote.desktop87
-rw-r--r--konqueror/sidebar/trees/init/remote/.directory84
-rw-r--r--konqueror/sidebar/trees/init/remote/Makefile.am4
-rw-r--r--konqueror/sidebar/trees/init/remote/ftp/.directory56
-rw-r--r--konqueror/sidebar/trees/init/remote/ftp/Makefile.am3
-rw-r--r--konqueror/sidebar/trees/init/remote/ftp/kde_ftp.desktop88
-rw-r--r--konqueror/sidebar/trees/init/remote/web/.directory56
-rw-r--r--konqueror/sidebar/trees/init/remote/web/Makefile.am2
-rw-r--r--konqueror/sidebar/trees/init/remote/web/apps_web.desktop87
-rw-r--r--konqueror/sidebar/trees/init/remote/web/dot_web.desktop86
-rw-r--r--konqueror/sidebar/trees/init/remote/web/kde_web.desktop88
-rw-r--r--konqueror/sidebar/trees/init/remote/web/look_web.desktop54
-rw-r--r--konqueror/sidebar/trees/init/root.desktop158
-rw-r--r--konqueror/sidebar/trees/init/services.desktop85
-rw-r--r--konqueror/sidebar/trees/init/services/.directory81
-rw-r--r--konqueror/sidebar/trees/init/services/Makefile.am2
-rw-r--r--konqueror/sidebar/trees/init/services/applications.desktop79
-rw-r--r--konqueror/sidebar/trees/init/services/audiocd.desktop85
-rw-r--r--konqueror/sidebar/trees/init/services/media.desktop74
-rw-r--r--konqueror/sidebar/trees/init/services/printsystem.desktop85
-rw-r--r--konqueror/sidebar/trees/init/services/settings.desktop81
-rw-r--r--konqueror/sidebar/trees/init/system.desktop139
-rw-r--r--konqueror/sidebar/trees/init/virtualfolderadd.desktop81
-rw-r--r--konqueror/sidebar/trees/konq_sidebartree.cpp1048
-rw-r--r--konqueror/sidebar/trees/konq_sidebartree.h225
-rw-r--r--konqueror/sidebar/trees/konq_sidebartreeitem.cpp65
-rw-r--r--konqueror/sidebar/trees/konq_sidebartreeitem.h116
-rw-r--r--konqueror/sidebar/trees/konq_sidebartreemodule.h65
-rw-r--r--konqueror/sidebar/trees/konq_sidebartreetoplevelitem.cpp208
-rw-r--r--konqueror/sidebar/trees/konq_sidebartreetoplevelitem.h101
-rw-r--r--konqueror/sidebar/trees/konqsidebar_tree.cpp167
-rw-r--r--konqueror/sidebar/trees/konqsidebar_tree.h47
-rw-r--r--konqueror/sidebar/web_module/Makefile.am19
-rw-r--r--konqueror/sidebar/web_module/TODO6
-rw-r--r--konqueror/sidebar/web_module/web_module.cpp220
-rw-r--r--konqueror/sidebar/web_module/web_module.h202
-rw-r--r--konqueror/sidebar/web_module/webmodule_add.desktop79
-rw-r--r--konqueror/sidebar/web_module/websidebar.desktop78
-rw-r--r--konqueror/sidebar/web_module/websidebar.html11
-rw-r--r--konqueror/uninstall.desktop2
-rw-r--r--konqueror/version.h3
333 files changed, 52414 insertions, 0 deletions
diff --git a/konqueror/AUTHORS b/konqueror/AUTHORS
new file mode 100644
index 000000000..1f3975c45
--- /dev/null
+++ b/konqueror/AUTHORS
@@ -0,0 +1,16 @@
+Started by Torben Weis <weis@kde.org>
+Maintained by David Faure <faure@kde.org>
+Current team :
+ Simon Hausmann <hausmann@kde.org>
+ Matthias Welk <welk@fokus.gmd.de>
+ Michael Reiher <michael.reiher@gmx.de>
+ Alexander Neundorf <neundorf@kde.org> (List views)
+ Michael Brade <brade@kde.org> (List Views, I/O lib)
+ Lars Knoll <knoll@kde.org> (HTML rendering engine)
+ Antti Koivisto <koivisto@kde.org> (HTML rendering engine)
+ Waldo Bastian <bastian@kde.org> (HTML rendering engine)
+ Matt Koss <koss@miesto.sk> (I/O lib)
+ Stephan Kulow <coolo@kde.org> (I/O lib)
+ Richard Moore <rich@kde.org> (Java applet support)
+ Dina Rogozin <dima@mercury.co.il> (Java applet support)
+
diff --git a/konqueror/ChangeLog b/konqueror/ChangeLog
new file mode 100644
index 000000000..438da0d69
--- /dev/null
+++ b/konqueror/ChangeLog
@@ -0,0 +1,433 @@
+2001-05-10 Mark Deneen <deneen@bucknell.edu>
+
+ * Implemented header of vertical toggle views, with support for
+ a caption text and a close-button
+
+2001-05-05 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc: Set WDestructiveClose again when going
+ to fullscreen mode (Qt bug), to prevent Alt+F4 from crashing.
+ * konq_misc.cc: Only abort full-screen mode for windows on the
+ current desktop.
+
+2001-05-01 Simon Hausmann <simon@kde.org>
+
+ * konq_mainwindow.cc : moved the connect and disconnect calls
+ to/from the highlighting signals of the actioncollections into
+ two separate methods, for cleanup, and use the qt child deletion
+ mechanism to delete the bookmark actioncollection
+
+2001-04-28 Simon Hausmann <simon@kde.org>
+
+ * konq_actions.h (class KonqGoURLAction): new class, derived
+ from KAction, used for the 'go url' action. when plugging the
+ action into a toolbar make sure to align the button right.
+ Otherwise the toolbar layout completely fucks up and QToolBar
+ starts flickering like mad, when the window width is getting
+ small than the lenght of the url in the combobox.
+
+ * konq_mainwindow.cc (initActions): use KonqGoURLAction
+
+2001-04-27 Simon Hausmann <simon@kde.org>
+
+ * konq_mainwindow.cc (goURL): new slot, sending a fake key
+ event to the lineedit, acting like the user pressing return
+ (initActions): allocate a "Go" action and connect it to the
+ new goURL slot
+
+ * konqueror.rc: inserted go action into the locationbar
+
+2001-04-07 Simon Hausmann <simon@kde.org>
+
+ * konq_mainwindow.cc (slotReload): call m_currentView->lockHistory(),
+ to fix #23818
+ * konq_view.cc/h (reload): removed obsolete method
+
+2001-03-31 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc(slotRunFinished): Stop wheel animation when a
+ konqrun fails and we have no view.
+
+2001-03-25 Simon Hausmann <simon@kde.org>
+
+ * iconview/konq_iconview.cc (KonqKfmIconView): specify a status text for
+ some actions. Likewise for some actions in KonqDirPart. Also call
+ setHighlightingEnabled in the KonqDirPart constructor
+
+ * konq_mainwindow.cc (slotShowMenuBar): call saveMainWindowSettings and
+ KGlobal::config()->sync() after toggling the visiblity of the menubar,
+ just like it is done for toolbars.
+ (slotPartActivated): connect and disconnect to/from the actionStatusText
+ and clearStatusText signals of the part's actioncollection
+
+2001-03-02 Simon Hausmann <simon@kde.org>
+
+ * konq_view.cc, konq_browseriface.cc/h: Utilize and implement the newly
+ added KParts::BrowserInterface
+
+2001-02-06 Simon Hausmann <simon@kde.org>
+
+ * konq_mainwindow.cc (openBookmarkURL): Patch by
+ Marco Krohn <Marco.Krohn@stud.uni-hannover.de> to call openFilteredURL
+ instead of openURL. Allows environment variables in bookmarks and
+ other sugar.
+
+2001-01-28 Stephan Kulow <coolo@kde.org>
+
+ * konq_mainwindow.cc (initActions): Plug the actions into a KAccel to
+ fix short cuts in full screen mode
+
+2001-01-16 Simon Hausmann <simon@kde.org>
+
+ * konq_actions.cc (fillHistoryPopup),
+ libkonq/kbookmarkmenu.cc (fillBookmarkMenu): When a Website has
+ "&" in the Title, make sure to transform it into "&&" before
+ inserting it into a QPopupMenu (for history or for bookmarks) , to
+ avoid QPopupMenu interpreting it as accelerator.
+
+
+2001-01-15 David Faure <faure@kde.org>
+
+ * konq_aboutpage.cc, konq_mainwindow.cc: Support for "about:konqueror".
+ Credits to Simon for the part, and Torsten for the icons.
+
+2001-01-14 David Faure <faure@kde.org>
+
+ * konq_viewmgr.cc (loadItem): Use openView instead of view->openURL,
+ so that "view-follows-view" is also applied on startup. Fixes #17679.
+
+ * konq_mainwindow.cc etc.: Lock to current location doesn't make the
+ view passive anymore. This allows to e.g. change the view mode.
+
+ * konq_frame.cc: Added Lock / Unlock to view statusbar's popupmenu.
+
+2001-01-13 David Faure <faure@kde.org>
+
+ * konq_dirpart.cc etc.: Always paste to current directory, even
+ when an item is selected.
+
+2001-01-12 David Faure <faure@kde.org>
+
+ * konq_viewmgr.cc (loadViewProfile): Set active part before loading
+ URL, so that the URL appears in the location bar.
+
+ * konq_mainwindow.cc, konq_dirpart.cc: Store find part into history,
+ in order to restore it when pressing back.
+
+2001-01-11 David Faure <faure@kde.org>
+
+ * konq_mainwindow.*, konq_view.*: Store caption in the view,
+ fixes caption when switching parts or removing one.
+
+2001-01-11 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ * konq_historymgr.*: KonqHistoryManager now implements the new
+ HistoryProvider (from KParts)
+
+2001-01-09 Alexander Neundorf <neundorf@kde.org>
+
+ * konq_mainwindow.*, konq_dirpart.*: Copy (F7) and move (F8) are now
+ available as soon as some files are selected in a directory view.
+ A dialog asks for the destination.
+
+2001-01-08 Simon Hausmann <simon@kde.org>
+
+ * KonquerorIface.cc (openBrowserWindow),
+ (createNewWindow),
+ (createNewWindow),
+ (createBrowserWindowFromProfile),
+ (createBrowserWindowFromProfile),
+ (createBrowserWindowFromProfileAndURL),
+ (createBrowserWindowFromProfileAndURL): changed return type from void
+ to DCOPRef
+
+2001-01-07 David Faure <faure@kde.org>
+
+ * konq_mainwindow.*: One KonqRun per view (del the old one in setRun),
+ only one with no view associated (KonqMainWindow::m_initialKonqRun).
+ This fixes "clicking on two bookmarks very fast opens both URLs,
+ splitting the view".
+
+2000-12-28 Simon Hausmann <simon@kde.org>
+
+ * konq_viewmgr.cc (loadViewProfile): When loading an empty profile
+ (in particular the webbrowsing one) , activate the clear_location
+ action. This gives the focus to the location bar -> the user can
+ type in an url right away when loading the webbrowsing profile
+
+2000-12-27 Simon Hausmann <simon@kde.org>
+
+ * konq_mainwindow.cc (enableAllActions): for iterating over all actions
+ don't use the action( int index ) method of KActionCollection but instead
+ retrieve a QValueList<KAction *> and iterate over that, as the =+(int)
+ operator of QDictIterator isn't really fast
+
+ ----- KDE 2.1 BETA 1 RELEASE ----
+
+2000-12-12 David Faure <faure@kde.org>
+
+ * konq_viewmgr.cc: Fixed saving of profiles containing views
+ "locked to their current location". The attribute was missing from
+ the profile.
+
+ * konq_mainwindow.cc: Save and restore the preferred service in for
+ each toolbar 'viewmode' button.
+
+2000-12-10 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc, konq_view.*, browserextension.*: Fixed
+ the initial state of the common actions (cut,copy,paste etc.).
+ Had to move all the handling of the action states to browserextension.
+
+2000-12-10 Simon Hausmann <simon@kde.org>
+
+ * konqview_example.tar.gz: removed outdated example.
+
+ * konq_frame.h, konq_view.{cc,h},
+ konq_factory.{cc,h}, konq_mainwindow.{cc,h} : Code cleanups,
+ added missing const's here and there, removed some old unused
+ code.
+
+2000-12-09 Simon Hausmann <simon@kde.org>
+
+ * konq_actions.{cc,h}: Added KonqViewModeAction, a KRadioAction
+ with an additional delayed popupmenu
+
+ * konq_mainwindow.{cc,h}: Changed the toolbar viewmode buttons to
+ show the available viewmodes grouped. For directories they are
+ grouped by iconview and listview. This way one can quickly
+ switch between the favourite list and iconview while still having
+ the complete choice of viewmodes via delayed popupmenus
+ (idea by Torsten and David)
+
+
+2000-12-08 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc (openURL): Support for about:blank
+ Fix for severe problems with the activation of the standard actions.
+ The state of the action is now stored in each KonqView.
+
+2000-12-08 Malte Starostik <malte@kde.org>
+
+ * libkonq/, iconview/: Preview for HTML files implemented.
+
+2000-12-08 David Faure <faure@kde.org> and Carsten Pfeiffer <pfeiffer@kde.org>
+
+ * dirtree/*: Major rewrite of the directory tree, to make it generic.
+ It can now handle toplevel items over to specific modules. Current
+ modules available are the dirtree module (directory listing) and the
+ history module (for a way to visualize the persistent history).
+
+2000-12-06 Matthias Elter <elter@kde.org>
+
+ * konq_mainwindow.cc: Turned the Configure submenu into a single dialog.
+
+2000-12-02 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc (slotToolFind): "Find Files" now embeds the kfind
+ part, and the result of the search is connected to the current directory
+ part. "Close" or opening any other URL closes the 'find' part.
+ Thanks to Eric Coquelle for the kfind classes, and to jpmartin for
+ pushing us to do this :)
+
+ * konq_viewmgr.cc: Support for suicidal passive views, more arguments
+ to splitView and splitWindow.
+
+ * konq_guiclients.cc: Duplicated code removed, uses splitWindow now.
+
+2000-11-30 David Faure <faure@kde.org>
+
+ * konq_mainwindow.cc: Use current profile in "New Window" to fix #16283.
+
+2000-11-28 David Faure <faure@kde.org>
+
+ * konq_actions.cc: Accel (Alt+O in English) to give focus to location bar,
+ shown by the label.
+
+ * konq_profiledlg.cc: Ported to KListView to fix problems with selection.
+
+2000-11-26 David Faure <faure@kde.org>
+
+ * konq_misc.cc, kfmclient.cc, KonquerorIface.cc: Speed up for URLs opened
+ from another process using KRun (e.g. kdesktop's Minicli), by passing the
+ mimetype through to konqueror.
+
+2000-11-25 David Faure <faure@kde.org>
+
+ * konq_misc.cc: Fixed location bar not showing the URL asap.
+
+ * konq_mainwindow.cc : Icons for the configure submenu.
+
+ * konq_actions.cc : KonqHistoryAction turned into KToolBarPopupAction.
+ Drag the "Location" label to start a drag with the current URL.
+
+2000-11-25 Simon Hausmann <simon@kde.org>
+
+ * konq_view.cc (connectPart): Install new url event filter for plain
+ krops and for browserviews with the enableURLDropHandling property enabled
+ (eventFilter): New eventfilter which listens for url drop events
+
+Sat Nov 25 17:38:27 2000 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ * konq_mainwindow.cc: Completion handling overhauled. We have
+ one KonqHistoryManager, which holds a KCompletion object and syncs
+ the history with the completion.
+
+ * konq_view.cc:
+ set m_bAborted before calling slotCompleted in slotCanceled()
+ feed the history manager
+
+ * konq_actions.cc: use KonqHistoryCombo that doesn't mess with the
+ competion-object, we do our own synchronization now.
+
+ * libkonq/ added konq_history*
+
+2000-11-22 David Faure <faure@kde.org>
+
+ * konq_listview.cc: Added "Default" Icon Size, which corresponds to
+ KIcon::Small (but when switching to icon view, it becomes whatever's
+ configured for the "Desktop" group).
+
+2000-11-21 David Faure <faure@kde.org>
+
+ * konq_listview.cc: Case Insensitive Sort option, on by default.
+
+ * Views: Major rework of the "delayed mimetypes determination" feature,
+ to make it available to the list view. This makes the list view
+ MUCH faster in big directories.
+ This also showed a bug in the listview background painting -> fixed.
+
+2000-11-19 David Faure <faure@kde.org>
+
+ * Views: Implemented in-place renaming of items ("Rename" in menus, F2)
+
+2000-11-17 David Faure <faure@kde.org>
+
+ * konq_profiledlg.cc: Made checkbox states persistent (saved to config)
+
+ * konq_run.cc: Check that when we call KRun from KonqRun, it's not going
+ to launch another konqueror.
+ * konq_guiclients.cc: Build toggle-view actions in the actioncollection
+ of the mainwindow, so that it's possible to assign them a shortcut.
+
+2000-11-16 David Faure <faure@kde.org>
+
+ * konq_viewmgr.cc: Patch by Keunwoo Lee <klee@cs.washington.edu> to
+ implement dynamic accels for the profile submenu.
+
+2000-11-15 David Faure <faure@kde.org>
+
+ * konq_drag.cc: Export URLs as text/plain as well.
+
+ * konq_mainwindow.cc: Implemented auto-saving of toolbars (KMainWindow),
+ removed "Save Settings".
+ Fixed "clicking on directory in dirtree uses wrong view mode for dirs".
+ * konq_iconview.cc: Added +/- buttons for changing the icon size.
+
+2000-11-06 David Faure <faure@kde.org>
+
+ * konq_operations.cc: statURL, calls a slot when it stat'ed
+ the url and created a kfileitem for it.
+ Used in doDrop when the destination's kfileitem is unknown. Fixes #14739.
+ Also, KPropsDlg now does a similar thing when called with a KURL.
+
+2000-11-05 David Faure <faure@kde.org>
+
+ * konqueror.rc: Moved the "open with" actions to the Location menu,
+ and added a separator to the action list.
+
+ * konq_view.cc (connectPart): moved call to setSaveViewPropertiesLocally
+ (used to be in various places in KonqMW) so that the flag is
+ also correct when switching views.
+
+ * konq_dirpart.cc and directory views: apply background color and pixmap
+ to the viewport(), and updated konq_iconview to do the same. This fixes
+ many inconsistencies, and makes resizing a window much faster & smoother.
+ Note that it has to be the viewport and not the widget, otherwise in the
+ listview, the box between the scrollbars appears colored/pixmap-ed.
+
+ * konq_mainwindow.cc: action renamed View Properties Saved In Directory
+
+2000-11-04 David Faure <faure@kde.org>
+
+ * konq_viewmgr.cc: now takes care of enableAllActions.
+ Show led and active statusbar even in the tree+icon configuration
+ (the rule is now "more than one view", not "more than one activeable
+ view"). This should remove some confusion.
+
+ * konq_frame.cc: "Remove View" in RMB on statusbar.
+ Don't try to activate passive views when clicking statusbar.
+ Different background color on statusbar for active view.
+
+ * konq_mainwindow.cc: Fixes for "Remove Active View" enabling,
+ to avoid ending up with a lonely embedded konsole, and some
+ cleanup of code for enabling other view-related actions.
+ Introducing updateViewActions for common code between enableAllActions
+ and slotPartActivated. Fixes a few glitches in action activation.
+
+2000-10-31 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ * libkonq: Implemented "Text preview" functionality
+
+2000-10-26 David Faure <faure@kde.org>
+
+ * keditbookmarks/*: Finally, a bookmark editor for konqueror.
+
+ * kbookmarkmanager.*: Separated from kbookmark.* after dcopidl dying on
+ "mutable" :). Implemented DCOP notifications between processes.
+ Implemented "internal bookmark address". KonqBookmarkManager is no more.
+
+ * kbookmarkbar.*: Update for XML bookmarks, fill in aboutToShow, update
+ sub-menus upon changed() signal, enabled "Add Bookmark" and "New Folder"
+
+2000-10-24 David Faure <faure@kde.org>
+
+ * kbookmark*: Reimplemented the bookmarks, they are now saved in XML.
+ Desktop files are imported if the XML file doesn't exist (it's
+ immediately saved, so this should happen only once).
+
+2000-10-22 Simon Hausmann <simon@kde.org>
+
+ * konq_view.{cc,h} : changed part->child( 0, "KParts::BE" ) calls to
+ use the new childObject method in BrowserExtension
+
+2000-10-22 David Faure <faure@kde.org>
+
+ * dirtree/konq_dirtree.cc: Fixed support for devices in the directory
+ tree. It currently requires MountPoint in the device desktop file.
+
+ * listview/konq_textviewwidget.cc: Only the Name column is now
+ selected, and used as a drop area - like in other listviews.
+ This requires the fix in KListView to work properly.
+
+2000-10-21 David Faure <faure@kde.org>
+
+ * Fix for linked views saved in profile, introducing isLoadingProfile().
+
+2000-10-20 David Faure <faure@kde.org>
+
+ * konq_misc.cc: Use webbrowsing profile for *.html *.htm as well.
+
+2000-10-20 Simon Hausmann <hausmann@kde.org>
+
+ * Duplicate window duplicates the history as well.
+
+[...... long period of development up to KDE 2.0 ommitted .....]
+
+1999-03-15 Michael Reiher <michael.reiher@gmx.de>
+
+ * Implemented an ActiveViewIndicator : KonqFrame
+
+1999-02-28 Simon Hausmann <tronical@gmx.net>
+
+ * Rewrite from scratch, with completely new IDL
+
+1999-02-09 David Faure <faure@kde.org>
+
+ * Source imported in kdebase/konqueror
+
+1999-01-25 Torben Weis <weis@kde.org>
+
+ * Initial import of kfmIII in corba/kfm
+
+
diff --git a/konqueror/DESIGN b/konqueror/DESIGN
new file mode 100644
index 000000000..fb2628aaa
--- /dev/null
+++ b/konqueror/DESIGN
@@ -0,0 +1,99 @@
+Konqueror Design Document
+
+Author:
+ David Faure, faure@kde.org
+
+Last modified: 16 June 2000
+
+Overall design of konqueror :
+=============================
+
+The design of konqueror is based on the KParts part/mainwindow mechanism
+(basically, konqueror can embed several parts, putting each one inside a view :
+icon views, tree views, html views...)
+
+The main(), including all the startup mechanism is in konq_main.*
+
+The main window contains several "views", in order to show several URLs
+at once, possibly using several modes. Each view is a KonqView.
+The KonqView contains the child part, which can be :
+- an icon view (KonqIconView)
+- a list view / tree view (KonqListView/KonqTreeView)
+- an HTML view (KHTMLPart)
+- any other ReadOnlyPart with or without Browserextension
+
+Where to find those classes
+===========================
+
+konq_run.* : Re-implementation of KRun (see libkio) for konqueror.
+ Responsible for finding appropriate view<->mimetype bindings.
+konq_view.* : KonqView, class used by KonqMainView to handle child views
+konq_frame.* : KonqFrame and KonqFrameHeader (handles view-statusbar).
+konq_main.* : The main()
+konq_mainwindow.* : KonqMainWindow, the main window :)
+konq_viewmgr.*: View manager. Handles view creation, activation, splitters etc.
+iconview/* : KonqIconView, for icon views
+listview/* : KonqTreeView, KonqListView...
+dirtree/* : KonqDirTree, the directory tree
+
+Libs used by konqueror
+======================
+
+kdecore, kdeui, kfile, khtml, kparts - usual stuff :)
+libkio - I/O stuff, mimetypes, services
+libkonq - bookmarks, properties dialog, templates ("new") menu, icon view widget
+
+How konqueror opens URLs
+========================
+
+KonqMainWindow:
+
+ openFilteredURL or slotOpenURLRequest
+ |
+ |
+ -----openURL----
+ | | |
+ | | |
+ | KonqRun KRun
+ | |
+ | |
+ openView
+ | \----- splitView to create a new one
+KonqView: |
+ changeViewMode
+ |
+ [switchView if different mode required]
+ |
+ openURL [emits openURLEvent (after calling openURL)]
+Part: |
+ |
+ openURL [emits started, progress info, completed]
+ ...
+
+
+How history is implemented
+==========================
+
+From the konqueror side:
+
+* KonqView has a list of history items. Each item contains a URL,
+and a QByteArray for the view to store its stuff in the format that suits it best.
+It calls saveState() at various points of time (right after starting loading the URL,
+when the loading is completed, and right before loading another URL). Reason:
+among other things, many views store the x and y offset of their scrollview in there.
+It calls restoreState() when restoring a particular item out of the history list.
+
+From the khtml side:
+
+* Site with no frames: no problem, it just obeys to saveState/restoreState.
+
+* Site with frames:
+KHTMLPart saves the whole structure (all frames, and their URL) in the
+history buffer (saveState/restoreState).
+Every time a frame changes its URL, we want a new item in the history.
+But when this happens, since it's internal to khtml, konqueror wouldn't know
+about it. That's why there is the openURLNotify() signal in browser extension
+(see there for extensive docu about it).
+When khtml emits it, KonqView creates a new history entry and fills it
+(calling saveState).
+
diff --git a/konqueror/DESIGN_config b/konqueror/DESIGN_config
new file mode 100644
index 000000000..d482107fa
--- /dev/null
+++ b/konqueror/DESIGN_config
@@ -0,0 +1,43 @@
+Date: Thu, 1 Apr 1999 11:51:03 +0200
+From: David Faure <faure@kde.org>
+To: kfm-devel@kde.org
+Subject: How to choose between builtin and external application : proposal
+
+How to configure between builtin and external viewers ?
+I discussed this with a friend, and here is what we come up with :
+
+* global defaults, set in kcontrol, for each mimetype group:
+
+text : use builtin viewer (yes/no) [checkbox]
+image : use builtin viewer (yes/no) [checkbox]
+other : use builtin viewer (yes/no) [checkbox] (i.e. application/*, like dvi, ps...)
+
+* then, in the properties dialog for every mimetype:
+- use default (checkbox as "no change")
+- use builtin viewer (checkbox as "on")
+- use external application (checkbox as "off")
+
+(=> saved as X-KDE-AutoEmbed=true/false or no entry)
+
+This way, one can set choose between builtin and external for all text /
+images files, and set individual values too (e.g. an icon-team artist would
+set up external for xpm, to edit them, and builtin for jpeg, gif, ... to
+simply view them). I would personnally set normal-text and english-text to
+builtin (to view READMEs) but c++, h, java, ... to my editor.
+
+And one that doesn't like embedded viewers (like Martin ;)) can set
+defaults to 'no' without having to change all mimetypes (text, c, c++, ...)
+but still use libkhtml for HTML pages, by setting 'use builtin' in the
+mimetype text/html - this is the way to keep the exact (though
+inconsistent) behaviour of 1.1-kfm.
+
+I suggest that factory defaults (i.e. configuration for first-time users)
+would be set to 'yes' for the three groups (-> use builtin)
+and would be 'use default' for mimetypes.
+This for speed reasons (embedded viewers are really fast) and also to show
+the new features ;)
+KOffice mimetypes have it set to no, though -> click edits.
+
+Implemented on 09-04-2000
+David FAURE <faure@kde.org>
+
diff --git a/konqueror/Home.desktop b/konqueror/Home.desktop
new file mode 100644
index 000000000..f128ac748
--- /dev/null
+++ b/konqueror/Home.desktop
@@ -0,0 +1,170 @@
+[Desktop Entry]
+Type=Application
+Exec=kfmclient openProfile filemanagement
+Icon=folder_home
+Terminal=false
+
+Name=Home
+Name[af]=Tuiste
+Name[ar]=المنزل
+Name[az]=Başlanğıc
+Name[be]=Хатняя тэчка
+Name[bg]=Домашна директория
+Name[bn]=ব্যক্তিগত ফোল্ডার
+Name[br]=Er-gêr
+Name[bs]=Početak
+Name[ca]=Inici
+Name[cs]=Můj adresář
+Name[csb]=Dodóm
+Name[cy]=Cartref
+Name[da]=Hjem
+Name[de]=Persönlicher Ordner
+Name[el]=Προσωπικός φάκελος
+Name[eo]=Hejmo
+Name[es]=Personal
+Name[et]=Kodu
+Name[eu]=Etxea
+Name[fa]=آغازه
+Name[fi]=Koti
+Name[fr]=Dossier personnel
+Name[fy]=Thús
+Name[ga]=Baile
+Name[gl]=Persoal
+Name[he]=בית
+Name[hi]=घर
+Name[hr]=Početak
+Name[hu]=Saját könyvtár
+Name[id]=Rumah
+Name[is]=Heimasvæðið þitt
+Name[ja]=ホーム
+Name[ka]=სახლში
+Name[kk]=Мекен
+Name[km]=ផ្ទះ
+Name[ko]=홈
+Name[lo]=ພື້ນທີ່ສ່ວນຕົວ
+Name[lt]=Pradžia
+Name[lv]=Mājas
+Name[mk]=Дома
+Name[mn]=Гэр
+Name[ms]=Laman Utama
+Name[mt]=Direttorju Personali
+Name[nb]=Hjem
+Name[nds]=Tohuus
+Name[ne]=गृह
+Name[nn]=Heim
+Name[nso]=Gae
+Name[oc]=Inici
+Name[pa]=ਘਰ
+Name[pl]=Katalog domowy
+Name[pt]=Pasta Pessoal
+Name[pt_BR]=Pasta do Usuário
+Name[ro]=Acasă
+Name[ru]=Домой
+Name[rw]=Urugo
+Name[se]=Ruoktu
+Name[sk]=Domov
+Name[sl]=Domov
+Name[sr]=Домаће
+Name[sr@Latn]=Domaće
+Name[ss]=Ekhaya
+Name[sv]=Hem
+Name[ta]=தொடக்கம்
+Name[te]=ఇల్లు
+Name[tg]=Компютери Ман
+Name[th]=พื้นที่ส่วนตัว
+Name[tr]=Başlangıç
+Name[tt]=Anabit
+Name[uk]=Домівка
+Name[uz]=Uy
+Name[uz@cyrillic]=Уй
+Name[ven]=Haya
+Name[vi]=Nhà
+Name[wa]=Måjhon
+Name[xh]=Ikhaya
+Name[zh_CN]=主文件夹
+Name[zh_TW]=家目錄
+Name[zu]=Ikhaya
+
+GenericName=Personal Files
+GenericName[af]=Persoonlike Lêers
+GenericName[ar]=الملفات الشخصية
+GenericName[az]=Şəxsi Fayllar
+GenericName[be]=Персанальныя файлы
+GenericName[bg]=Лични файлове
+GenericName[bn]=ব্যক্তিগত ফাইলসমূহ
+GenericName[br]=Restroù deoc'h
+GenericName[bs]=Osobne datoteke
+GenericName[ca]=Fitxers personals
+GenericName[cs]=Osobní soubory
+GenericName[csb]=Swòje lopczi
+GenericName[cy]=Ffeiliau Personol
+GenericName[da]=Personlige filer
+GenericName[de]=Eigene Dateien
+GenericName[el]=Προσωπικά αρχεία
+GenericName[eo]=Personaj dosieroj
+GenericName[es]=Archivos personales
+GenericName[et]=Isiklikud failid
+GenericName[eu]=Fitxategi pertsonalak
+GenericName[fa]=پرونده‌های شخصی
+GenericName[fi]=Omat tiedostot
+GenericName[fr]=Fichiers personnels
+GenericName[fy]=Persoanlike map
+GenericName[ga]=Comhaid Phearsanta
+GenericName[gl]=Ficheiros Persoais
+GenericName[he]=קבצים אישיים
+GenericName[hi]=निजी फ़ाइलें
+GenericName[hr]=Osobne datoteke
+GenericName[hu]=Személyes fájlok
+GenericName[id]=File Pribadi
+GenericName[is]=Skrárnar þínar
+GenericName[it]=File personali
+GenericName[ja]=個人のファイル
+GenericName[ka]=პირადი საქაღალდეები
+GenericName[kk]=Дербес файлдар
+GenericName[km]=ឯកសារ​ផ្ទាល់​ខ្លួន
+GenericName[ko]=개인적인 파일
+GenericName[lo]=ທີ່ເກັບແຟ້ມແລະເອກະສານສວ່ນຕົວຫລືອື່ນຯ
+GenericName[lt]=Asmeninės bylos
+GenericName[lv]=Personālie Faili
+GenericName[mk]=Лични датотеки
+GenericName[mn]=Өөрийн файлууд
+GenericName[ms]=Fail Peribadi
+GenericName[mt]=Fajls Personali
+GenericName[nb]=Personlige filer
+GenericName[nds]=De egen Dateien
+GenericName[ne]=व्यक्तिगत फाइल
+GenericName[nl]=Persoonlijke map
+GenericName[nn]=Personlege filer
+GenericName[nso]=Difaele tsa Botho
+GenericName[oc]=FiquièRs personals
+GenericName[pa]=ਨਿੱਜੀ ਫਾਇਲ਼ਾਂ
+GenericName[pl]=Pliki osobiste
+GenericName[pt]=Ficheiros Pessoais
+GenericName[pt_BR]=Arquivos Pessoais
+GenericName[ro]=Fișiere personale
+GenericName[ru]=Личные файлы
+GenericName[rw]=Amadosiye Yihariye
+GenericName[se]=Iežat fiillat
+GenericName[sk]=Osobné súbory
+GenericName[sl]=Osebne datoteke
+GenericName[sr]=Лични фајлови
+GenericName[sr@Latn]=Lični fajlovi
+GenericName[sv]=Personliga filer
+GenericName[ta]=சொந்த கோப்புகள்
+GenericName[te]=వ్యక్తిగత దస్త్రాలు
+GenericName[tg]=Файлҳои шахсӣ
+GenericName[th]=แฟ้มส่วนตัว
+GenericName[tr]=Kişisel Dosyalar
+GenericName[tt]=Şäxsi Biremnär
+GenericName[uk]=Особисті файли
+GenericName[uz]=Shaxsiy fayllar
+GenericName[uz@cyrillic]=Шахсий файллар
+GenericName[ven]=Dzifaela dza vhune
+GenericName[vi]=Tập tin Cá nhân
+GenericName[wa]=Fitchîs da vosse
+GenericName[xh]=Iifayile Zobuqu
+GenericName[zh_CN]=个人文件
+GenericName[zh_TW]=個人檔案
+GenericName[zu]=Amafayela Omuntu siqu
+Categories=Qt;KDE;Core;
+OnlyShowIn=KDE;
diff --git a/konqueror/IDEAS b/konqueror/IDEAS
new file mode 100644
index 000000000..426b4d006
--- /dev/null
+++ b/konqueror/IDEAS
@@ -0,0 +1,223 @@
+Konqueror "Ideas" Document (specification, general ideas)
+
+Authors:
+ Waldo Bastian
+ David Faure
+ Simon Hausmann
+
+Last modified: 7 Mar 1999
+
+Intro
+=====
+I am trying to create a picture of how Konqueror should look
+like in KDE 2.0. If such a picture is clear, it is easier to
+build Konqueror such that it will feel like a consistent piece
+of software. This is of course only my view of the things. If
+someone has other views please let this know. It will help if
+a sort of common idea about the future of Konqueror exists.
+
+KDE 2.0
+=======
+I think we should keep Konqueror a "browser": You can browse
+with it, and look at things. But when you want to _DO_ things,
+you will need a full-fledged application.
+
+So you can view HTML with it.
+You can view directories with it.
+You can view text-files with it (read-only). (basically kless)
+You can view images with it.
+You can view mail-folders with it.
+You can view newsgroups with it.
+You can view xxx....
+
+When you want more advanced manipulating options, modify things,
+or create things (writing a mail for instance) the "Real (tm)"
+application should pop up with its own menubars etc.
+
+There is of course a thin line between viewing and modifying.
+With the file browser you want to be able to move/rename/delete
+files. So if we allow this functionality for file-browsing, we
+should also allow it for mail-browsing or news-browsing.
+(e.g. move/delete message cq. postings).
+
+Creating does not really belong in a browser (apart from
+directories) because you will almost always need an application
+for this anyway. I seldom go to a directory to select "create xyz".
+Most of the time you start an application to create "xyz" and
+when you are done, you think of a nice place to store it.
+(I think Microsoft wants us to believe otherwise, with their
+"document-orientated" Windows95 marketing)
+((Well, sometimes you are browsing and have a sudden urge to put
+a text-file like README in a directory. But for that you still
+need a text-editor. Just creating an empty file is of little use.))
+
+Why is this important?
+======================
+There must be a clear distinction between what can be done with
+Konqueror and what can be done with the application self. If there
+is no distinction we don't need Konqueror.
+
+Smooth integration
+==================
+With this Konqueror thing we have to tell the user a thing or
+two. We have to tell the user what he/she is doing:
+"Viewing a text-file", "Viewing a web-page", "Viewing a FTP-site",
+"Viewing e-mail". Because the options available to the user, depend
+on what he is doing: You can reply to e-mail. But you can't reply
+to a FTP-site. You can sort the entries of a FTP directory, but
+you can't sort a web-page.
+
+At the same time, we have to tell the user that he/she is "Viewing".
+If you want to edit the web-page, the web-editor comes up. If you
+want to reply to the e-mail, the mail-composer comes up. At that
+time the user is editing/changing/modyfying.
+
+From the users point of view, the "viewing" part is konqueror. The
+editing part is the application.
+
+From the developers point of view, this can be different. The view
+e-mail mode of Konqueror could (but it doesn't have to) be handled
+by the same instance of kmail as the "edit" mode of kmail. If this
+will be indeed the case should depend on programming considerations.
+
+What should not depend on programming considerations, is how it is
+presented to the user.
+
+An Example
+==========
+Teodor Romeo Mihai wrote:
+> Well, I've been working for a few months now on a Outloook-clone for
+> KDE, handling mail/contacts/schedule/journal/notes/groups. It is a bit
+> different from all KDE applications I've seen, being very close to
+> Outlook in look&feel rather than KMail - which I find unusable.
+> If you are seriously planning to put mail in kfm, maybe you should
+> consider some kind of integration with an external mailer, in
+> Explorer/Outlook style.
+
+I'm serious about integrating mail-viewing in Konqueror.
+(From a user point of view).
+
+I think it is a very bad idea to put mail-reading code in
+Konqueror. (From a developers point of view).
+
+Konqueror should be able to display mail/mailboxes by embedding
+a mail-viewer. This mail-viewer should (in the case of a mail-viewer)
+be a seperate application from a developers point of view, but should
+integrate seemless with Konqueror from the user point of view. This
+application can be kmail, a light version of kmail, or any other
+application that can display mails and supports this embedded KFM-view
+idea.
+
+For viewing HTML or GIF files, Konqueror will most likely implement
+the functionality itself. For the user it should not make any difference
+if a view is implemented in Konqueror itself or in a seperate
+application.
+
+The technology to embed the mail-viewer should be something CORBA based.
+Most likely KOM/Openparts.
+
+Konqueror should not become a program like Netscape Communicator:
+A program that tries to do everything itself, and as result, does
+everything very poorly.
+
+Konqueror should do it better and the Unix way: Have speciliazed
+components which are very good in their task. Konqueror provides
+the seemless integration of them and provides easy navigation
+abilities.
+
+
+<tfischer> This means i can create an application (container) which host two parts,
+which are both ACTIVE, that
+ means i do not need to click the parts before they start repsonding.
+
+
+Konqueror Views
+===============
+When an embedded part gets the focus (e.g. when the users clicks on it)
+the mainwindow (shell) gets notified about this (the focus change).
+You can "manually" activate a part by calling a method in the mainwindow
+interface. There can be only part that has the focus.
+If you click on a non-activated part the click action itself is not "eaten up"
+An activated part means the part has focus (keyboard, ...)
+When you have "plain" parts they usually "have" their own GUI which get's
+"enabled" (created dynamically) when the part gets the focus
+Normally this would bring a big problem inside konqueror
+Because then we'd have lots of duplicated *bar creation code and
+stuff like this. That is the reason why in konqueror functionality is
+implemented in openparts to have so called child parts.
+A child part does _not_ have it's own GUI (as a normal openpart has)
+instead the part part's gui is used.
+We still allow konqueror views to have their own view specific gui elements
+When a konqueror view (=part child) gets the focus the part parent
+(the mainwindow) will receive an event (eventChildGotFocus)
+and this helps the mainwindow to send yet another event to the just
+activated view (=part) , an konqueror specific event
+these events are described in konqueror.idl
+
+The result is:
+A konqueror view (that's important, the view must support this interface)
+can now specify it's own, view specific, menu entries in the edit/view menu
+plus it's own toolbar.
+
+This integration is in fact not sooo seamless because:
+whenever the use activates your khelpcenter part
+a complete GUI "switch" will take place, meaning all the *bars from
+konqueror will be replaced by the *bars from the child view
+
+Therefor another approach is developed:
+The *bars of konqueror will contain entries for all child-views which are
+inside the main-view.
+
+Care should be taken when multiple views want to add the same entries to
+one of the *bars.
+
+In the case of a toolbar, only one entry could be added, the child-view which
+has supplied this entry will be made active when his entry is used and will
+get the event. If multiple child-views have provided this entry, the currently
+active child will get the event.
+
+For the menubar, the entries will be presented grouped per child-view. The same
+entry could be listed twice in the same menu, but listed under two differents
+views.
+
+Transcript
+==========
+<tronical> we have a usual mainwindow (looks/behaves quite like a current kfm window on the screen)
+<tronical> now we have two views inside, on the left we've got an iconview
+<tronical> and on the right we've got an htmlview
+<tronical> now let's say the iconview wants to add a special entry in the common view menu
+<tronical> no, let's say three entries: mini-/medium-/large icons
+<tronical> and for the htmlview we've got (in the view menu as well):
+<tronical> whatevery...hm...*thinking*, perhaps charset-selection of stuff like this
+<tronical> now when the iconview is active the view menu will contain
+<tronical> all the usual konqueror (mainwindow) entries (what could this be for example?) plus the three iconview
+ entries
+<tronical> and when the users activates the htmlview then view menu will silently change
+<Zogje> I think it makes sense to have both sets of entries in the view-menu at the sma time
+<tronical> ok, well, it's possible to do this
+* tfischer thinks zogje is right.
+<tronical> there's no change in the design necessary
+<Zogje> because the user just has a html-view and an inco-view on his screen, and has no idea which one is
+ "active"
+<tronical> hm, you're right
+<tronical> ok, but I think we can easily solve this:
+<tronical> first we create the common konqueror menu entries
+<tronical> then insertSeparator( -1 );
+<Zogje> ack
+<tronical> and then the first views' entries
+<tronical> then another separator, ...and so on
+<Zogje> yes
+<Zogje> that seems quite good
+<tronical> we might do something like this:
+<tronical> common konqy entries
+<tronical> separator
+<tronical> dummy-not-doing-anything-entry named viewName()
+<tronical> separator
+<tronical> view entries
+<tronical> yet another separator
+<tronical> second view's name as dummy entries
+<tronical> and so on
+<Zogje> yes.. because if we have two html-views... you want to be able to select things for both independntly
+
+
+
diff --git a/konqueror/KonqMainWindowIface.cc b/konqueror/KonqMainWindowIface.cc
new file mode 100644
index 000000000..00233d883
--- /dev/null
+++ b/konqueror/KonqMainWindowIface.cc
@@ -0,0 +1,175 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KonqMainWindowIface.h"
+#include "KonqViewIface.h"
+#include "konq_view.h"
+
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kdcopactionproxy.h>
+#include <kdcoppropertyproxy.h>
+#include <kdebug.h>
+#include <kstartupinfo.h>
+#include <kwin.h>
+
+KonqMainWindowIface::KonqMainWindowIface( KonqMainWindow * mainWindow )
+ :
+ // ARGL I hate this "virtual public DCOPObject" stuff!
+ DCOPObject( mainWindow->name() ),
+ KMainWindowInterface( mainWindow ), m_pMainWindow( mainWindow )
+{
+ m_dcopActionProxy = new KDCOPActionProxy( mainWindow->actionCollection(), this );
+}
+
+KonqMainWindowIface::~KonqMainWindowIface()
+{
+ delete m_dcopActionProxy;
+}
+
+void KonqMainWindowIface::openURL( QString url )
+{
+ m_pMainWindow->openFilteredURL( url );
+}
+
+void KonqMainWindowIface::newTab( QString url )
+{
+ m_pMainWindow->openFilteredURL( url, true );
+}
+
+void KonqMainWindowIface::openURL( QString url, bool tempFile )
+{
+ m_pMainWindow->openFilteredURL( url, false, tempFile );
+}
+
+void KonqMainWindowIface::newTab( QString url, bool tempFile )
+{
+ m_pMainWindow->openFilteredURL( url, true, tempFile );
+}
+
+void KonqMainWindowIface::newTabASN( QString url, const QCString& startup_id, bool tempFile )
+{
+ KStartupInfo::setNewStartupId( m_pMainWindow, startup_id );
+ m_pMainWindow->openFilteredURL( url, true, tempFile );
+}
+
+
+void KonqMainWindowIface::splitViewHorizontally()
+{
+ m_pMainWindow->slotSplitViewHorizontal();
+}
+
+void KonqMainWindowIface::splitViewVertically()
+{
+ m_pMainWindow->slotSplitViewVertical();
+}
+
+void KonqMainWindowIface::reload()
+{
+ m_pMainWindow->slotReload();
+}
+
+DCOPRef KonqMainWindowIface::currentView()
+{
+ KonqView *view = m_pMainWindow->currentView();
+ if ( !view )
+ return DCOPRef();
+
+ return DCOPRef( kapp->dcopClient()->appId(), view->dcopObject()->objId() );
+}
+
+DCOPRef KonqMainWindowIface::currentPart()
+{
+ DCOPRef res;
+
+ KonqView *view = m_pMainWindow->currentView();
+ if ( !view )
+ return res;
+
+ return view->dcopObject()->part();
+}
+
+DCOPRef KonqMainWindowIface::view(int viewNumber)
+{
+ KonqMainWindow::MapViews viewMap = m_pMainWindow->viewMap();
+ KonqMainWindow::MapViews::const_iterator it = viewMap.begin();
+ for ( int i = 0; it != viewMap.end() && i < viewNumber; ++i )
+ ++it;
+ if ( it == viewMap.end() )
+ return DCOPRef();
+ return DCOPRef( kapp->dcopClient()->appId(), (*it)->dcopObject()->objId() );
+}
+
+DCOPRef KonqMainWindowIface::part(int viewNumber)
+{
+ KonqMainWindow::MapViews viewMap = m_pMainWindow->viewMap();
+ KonqMainWindow::MapViews::const_iterator it = viewMap.begin();
+ for ( int i = 0; it != viewMap.end() && i < viewNumber; ++i )
+ ++it;
+ if ( it == viewMap.end() )
+ return DCOPRef();
+ return (*it)->dcopObject()->part();
+}
+
+DCOPRef KonqMainWindowIface::action( const QCString &name )
+{
+ return DCOPRef( kapp->dcopClient()->appId(), m_dcopActionProxy->actionObjectId( name ) );
+}
+
+QCStringList KonqMainWindowIface::actions()
+{
+ QCStringList res;
+ QValueList<KAction *> lst = m_dcopActionProxy->actions();
+ QValueList<KAction *>::ConstIterator it = lst.begin();
+ QValueList<KAction *>::ConstIterator end = lst.end();
+ for (; it != end; ++it )
+ res.append( (*it)->name() );
+
+ return res;
+}
+
+QMap<QCString,DCOPRef> KonqMainWindowIface::actionMap()
+{
+ return m_dcopActionProxy->actionMap();
+}
+
+QCStringList KonqMainWindowIface::functionsDynamic()
+{
+ return DCOPObject::functionsDynamic() + KDCOPPropertyProxy::functions( m_pMainWindow );
+}
+
+bool KonqMainWindowIface::processDynamic( const QCString &fun, const QByteArray &data, QCString &replyType, QByteArray &replyData )
+{
+ if ( KDCOPPropertyProxy::isPropertyRequest( fun, m_pMainWindow ) )
+ return KDCOPPropertyProxy::processPropertyRequest( fun, data, replyType, replyData, m_pMainWindow );
+
+ return DCOPObject::processDynamic( fun, data, replyType, replyData );
+}
+
+bool KonqMainWindowIface::windowCanBeUsedForTab()
+{
+ KWin::WindowInfo winfo = KWin::windowInfo( m_pMainWindow->winId(), NET::WMDesktop );
+ if( !winfo.isOnCurrentDesktop() )
+ return false; // this window shows on different desktop
+ if( KonqMainWindow::isPreloaded() )
+ return false; // we want a tab in an already shown window
+ return true;
+}
diff --git a/konqueror/KonqMainWindowIface.h b/konqueror/KonqMainWindowIface.h
new file mode 100644
index 000000000..334307cb0
--- /dev/null
+++ b/konqueror/KonqMainWindowIface.h
@@ -0,0 +1,95 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KonqMainWindowIface_h__
+#define __KonqMainWindowIface_h__
+
+#include <dcopobject.h>
+#include <qvaluelist.h>
+#include <dcopref.h>
+#include <kmainwindowiface.h>
+
+class KonqMainWindow;
+class KDCOPActionProxy;
+
+/**
+ * DCOP interface for a konqueror main window
+ */
+class KonqMainWindowIface : public KMainWindowInterface
+{
+ K_DCOP
+public:
+
+ KonqMainWindowIface( KonqMainWindow * mainWindow );
+ ~KonqMainWindowIface();
+
+k_dcop:
+
+ void openURL( QString url );
+ void newTab( QString url );
+
+ void openURL( QString url, bool tempFile );
+ void newTab( QString url, bool tempFile );
+
+ void newTabASN( QString url, const QCString& startup_id, bool tempFile );
+
+ void splitViewHorizontally();
+ void splitViewVertically();
+
+ /**
+ * Reloads the current view.
+ */
+ void reload();
+
+ /**
+ * @return reference to the current KonqView
+ */
+ DCOPRef currentView();
+ /**
+ * @return reference to the current part
+ */
+ DCOPRef currentPart();
+
+ // viewCount is already exposed via the KonqMainWindow property
+ DCOPRef view(int viewNumber);
+ DCOPRef part(int partNumber);
+
+ DCOPRef action( const QCString &name );
+ QCStringList actions();
+ QMap<QCString,DCOPRef> actionMap();
+
+ /**
+ * Used by kfmclient when searching a window to open a tab within
+ */
+ bool windowCanBeUsedForTab();
+
+public:
+ virtual QCStringList functionsDynamic();
+ virtual bool processDynamic( const QCString &fun, const QByteArray &data, QCString &replyType, QByteArray &replyData );
+
+private:
+
+ KonqMainWindow * m_pMainWindow;
+ KDCOPActionProxy *m_dcopActionProxy;
+
+};
+
+#endif
+
diff --git a/konqueror/KonqViewIface.cc b/konqueror/KonqViewIface.cc
new file mode 100644
index 000000000..0aeffda1a
--- /dev/null
+++ b/konqueror/KonqViewIface.cc
@@ -0,0 +1,141 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KonqViewIface.h"
+#include "konq_view.h"
+
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+
+KonqViewIface::KonqViewIface( KonqView * view, const QCString& name )
+ : DCOPObject( name ), m_pView ( view )
+{
+}
+
+KonqViewIface::~KonqViewIface()
+{
+}
+
+void KonqViewIface::openURL( QString url, const QString & locationBarURL, const QString & nameFilter )
+{
+ KURL u(url);
+ m_pView->openURL( u, locationBarURL, nameFilter );
+}
+
+bool KonqViewIface::changeViewMode( const QString &serviceType,
+ const QString &serviceName )
+{
+ return m_pView->changeViewMode( serviceType, serviceName );
+}
+
+void KonqViewIface::lockHistory()
+
+{
+ m_pView->lockHistory();
+}
+
+void KonqViewIface::stop()
+{
+ m_pView->stop();
+}
+
+QString KonqViewIface::url()
+{
+ return m_pView->url().url();
+}
+
+QString KonqViewIface::locationBarURL()
+{
+ return m_pView->locationBarURL();
+}
+
+QString KonqViewIface::serviceType()
+{
+ return m_pView->serviceType();
+}
+
+QStringList KonqViewIface::serviceTypes()
+{
+ return m_pView->serviceTypes();
+}
+
+DCOPRef KonqViewIface::part()
+{
+ DCOPRef res;
+
+ KParts::ReadOnlyPart *part = m_pView->part();
+
+ if ( !part )
+ return res;
+
+ QVariant dcopProperty = part->property( "dcopObjectId" );
+
+ if ( dcopProperty.type() != QVariant::CString )
+ return res;
+
+ res.setRef( kapp->dcopClient()->appId(), dcopProperty.toCString() );
+ return res;
+}
+
+void KonqViewIface::enablePopupMenu( bool b )
+{
+ m_pView->enablePopupMenu( b );
+}
+
+uint KonqViewIface::historyLength()const
+{
+ return m_pView->historyLength();
+}
+
+bool KonqViewIface::allowHTML() const
+{
+ return m_pView->allowHTML();
+}
+
+void KonqViewIface::goForward()
+{
+ m_pView->go(-1);
+}
+
+void KonqViewIface::goBack()
+{
+ m_pView->go(+1);
+}
+
+bool KonqViewIface::isPopupMenuEnabled() const
+{
+ return m_pView->isPopupMenuEnabled();
+}
+
+bool KonqViewIface::canGoBack()const
+{
+ return m_pView->canGoBack();
+}
+
+bool KonqViewIface::canGoForward()const
+{
+ return m_pView->canGoForward();
+}
+
+void KonqViewIface::reload()
+{
+ return m_pView->mainWindow()->slotReload( m_pView );
+}
diff --git a/konqueror/KonqViewIface.h b/konqueror/KonqViewIface.h
new file mode 100644
index 000000000..43630f7f5
--- /dev/null
+++ b/konqueror/KonqViewIface.h
@@ -0,0 +1,136 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KonqViewIface_h__
+#define __KonqViewIface_h__
+
+#include <dcopobject.h>
+#include <qstringlist.h>
+#include <dcopref.h>
+
+class KonqView;
+
+/**
+ * DCOP interface for a konqueror main window
+ */
+class KonqViewIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+
+ KonqViewIface( KonqView * view, const QCString& name );
+ ~KonqViewIface();
+
+k_dcop:
+
+ /**
+ * Displays another URL, but without changing the view mode
+ * (Make sure the part can display this URL)
+ */
+ void openURL( QString url,
+ const QString & locationBarURL,
+ const QString & nameFilter );
+
+ /** Reload */
+ void reload();
+
+ /**
+ * Change the type of view (i.e. loads a new konqueror view)
+ * @param serviceType the service type we want to show
+ * @param serviceName allows to enforce a particular service to be chosen,
+ * @see KonqFactory.
+ */
+ bool changeViewMode( const QString &serviceType,
+ const QString &serviceName );
+
+ /**
+ * Call this to prevent next openURL() call from changing history lists
+ * Used when the same URL is reloaded (for instance with another view mode)
+ */
+ void lockHistory();
+
+ /**
+ * Stop loading
+ */
+ void stop();
+
+ /**
+ * Retrieve view's URL
+ */
+ QString url();
+
+ /**
+ * Get view's location bar URL, i.e. the one that the view signals
+ * It can be different from url(), for instance if we display a index.html
+ */
+ QString locationBarURL();
+
+ /**
+ * @return the servicetype this view is currently displaying
+ */
+ QString serviceType();
+
+ /**
+ * @return the servicetypes this view is capable to display
+ */
+ QStringList serviceTypes();
+
+ /**
+ * @return the part embedded into this view
+ */
+ DCOPRef part();
+
+ /**
+ * Enable/Disable the context popup menu for this view.
+ */
+ void enablePopupMenu( bool b );
+
+
+ bool isPopupMenuEnabled() const;
+
+ /*
+ * Return length of history
+ */
+ uint historyLength()const;
+ /*
+ * Return true if "Use index HTML" is checked
+ */
+ bool allowHTML() const;
+
+ /*
+ * Move forward in history "-1"
+ */
+ void goForward();
+ /*
+ * Move back in history "+1"
+ */
+ void goBack();
+
+ bool canGoBack()const;
+ bool canGoForward()const;
+
+private:
+
+ KonqView * m_pView;
+
+};
+
+#endif
+
diff --git a/konqueror/KonquerorIface.cc b/konqueror/KonquerorIface.cc
new file mode 100644
index 000000000..3656512f7
--- /dev/null
+++ b/konqueror/KonquerorIface.cc
@@ -0,0 +1,295 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KonquerorIface.h"
+#include "konq_misc.h"
+#include "KonqMainWindowIface.h"
+#include "konq_mainwindow.h"
+#include "konq_viewmgr.h"
+#include "konq_view.h"
+#include <konq_settings.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <qfile.h>
+#include "konq_settingsxt.h"
+
+// these DCOP calls come from outside, so any windows created by these
+// calls would have old user timestamps (for KWin's no-focus-stealing),
+// it's better to reset the timestamp and rely on other means
+// of detecting the time when the user action that triggered all this
+// happened
+// TODO a valid timestamp should be passed in the DCOP calls that
+// are not for user scripting
+#include <X11/Xlib.h>
+extern Time qt_x_user_time;
+
+KonquerorIface::KonquerorIface()
+ : DCOPObject( "KonquerorIface" )
+{
+}
+
+KonquerorIface::~KonquerorIface()
+{
+}
+
+DCOPRef KonquerorIface::openBrowserWindow( const QString &url )
+{
+ qt_x_user_time = 0;
+ KonqMainWindow *res = KonqMisc::createSimpleWindow( KURL(url) );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::openBrowserWindowASN( const QString &url, const QCString& startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return openBrowserWindow( url );
+}
+
+DCOPRef KonquerorIface::createNewWindow( const QString &url )
+{
+ return createNewWindow( url, QString::null, false );
+}
+
+DCOPRef KonquerorIface::createNewWindowASN( const QString &url, const QCString& startup_id, bool tempFile )
+{
+ kapp->setStartupId( startup_id );
+ return createNewWindow( url, QString::null, tempFile );
+}
+
+DCOPRef KonquerorIface::createNewWindowWithSelection( const QString &url, QStringList filesToSelect )
+{
+ qt_x_user_time = 0;
+ KonqMainWindow *res = KonqMisc::createNewWindow( KURL(url), KParts::URLArgs(), false, filesToSelect );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createNewWindowWithSelectionASN( const QString &url, QStringList filesToSelect, const QCString &startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return createNewWindowWithSelection( url, filesToSelect );
+}
+
+DCOPRef KonquerorIface::createNewWindow( const QString &url, const QString &mimetype, bool tempFile )
+{
+ qt_x_user_time = 0;
+ KParts::URLArgs args;
+ args.serviceType = mimetype;
+ // Filter the URL, so that "kfmclient openURL gg:foo" works also when konq is already running
+ KURL finalURL = KonqMisc::konqFilteredURL( 0, url );
+ KonqMainWindow *res = KonqMisc::createNewWindow( finalURL, args, false, QStringList(), tempFile );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createNewWindowASN( const QString &url, const QString &mimetype,
+ const QCString& startup_id, bool tempFile )
+{
+ kapp->setStartupId( startup_id );
+ return createNewWindow( url, mimetype, tempFile );
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfile( const QString &path )
+{
+ qt_x_user_time = 0;
+ kdDebug(1202) << "void KonquerorIface::createBrowserWindowFromProfile( const QString &path ) " << endl;
+ kdDebug(1202) << path << endl;
+ KonqMainWindow *res = KonqMisc::createBrowserWindowFromProfile( path, QString::null );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileASN( const QString &path, const QCString& startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return createBrowserWindowFromProfile( path );
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfile( const QString & path, const QString &filename )
+{
+ qt_x_user_time = 0;
+ kdDebug(1202) << "void KonquerorIface::createBrowserWindowFromProfile( path, filename ) " << endl;
+ kdDebug(1202) << path << "," << filename << endl;
+ KonqMainWindow *res = KonqMisc::createBrowserWindowFromProfile( path, filename );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileASN( const QString &path, const QString &filename,
+ const QCString& startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return createBrowserWindowFromProfile( path, filename );
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileAndURL( const QString & path, const QString &filename, const QString &url )
+{
+ qt_x_user_time = 0;
+ KonqMainWindow *res = KonqMisc::createBrowserWindowFromProfile( path, filename, KURL(url) );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileAndURLASN( const QString & path, const QString &filename, const QString &url,
+ const QCString& startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return createBrowserWindowFromProfileAndURL( path, filename, url );
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileAndURL( const QString &path, const QString &filename, const QString &url, const QString &mimetype )
+{
+ qt_x_user_time = 0;
+ KParts::URLArgs args;
+ args.serviceType = mimetype;
+ KonqMainWindow *res = KonqMisc::createBrowserWindowFromProfile( path, filename, KURL(url), args );
+ if ( !res )
+ return DCOPRef();
+ return res->dcopObject();
+}
+
+DCOPRef KonquerorIface::createBrowserWindowFromProfileAndURLASN( const QString & path, const QString &filename, const QString &url, const QString &mimetype,
+ const QCString& startup_id )
+{
+ kapp->setStartupId( startup_id );
+ return createBrowserWindowFromProfileAndURL( path, filename, url, mimetype );
+}
+
+
+void KonquerorIface::reparseConfiguration()
+{
+ KGlobal::config()->reparseConfiguration();
+ KonqFMSettings::reparseConfiguration();
+
+ QPtrList<KonqMainWindow> *mainWindows = KonqMainWindow::mainWindowList();
+ if ( mainWindows )
+ {
+ QPtrListIterator<KonqMainWindow> it( *mainWindows );
+ for (; it.current(); ++it )
+ it.current()->reparseConfiguration();
+ }
+}
+
+void KonquerorIface::updateProfileList()
+{
+ QPtrList<KonqMainWindow> *mainWindows = KonqMainWindow::mainWindowList();
+ if ( !mainWindows )
+ return;
+
+ QPtrListIterator<KonqMainWindow> it( *mainWindows );
+ for (; it.current(); ++it )
+ it.current()->viewManager()->profileListDirty( false );
+}
+
+QString KonquerorIface::crashLogFile()
+{
+ return KonqMainWindow::s_crashlog_file->name();
+}
+
+QValueList<DCOPRef> KonquerorIface::getWindows()
+{
+ QValueList<DCOPRef> lst;
+ QPtrList<KonqMainWindow> *mainWindows = KonqMainWindow::mainWindowList();
+ if ( mainWindows )
+ {
+ QPtrListIterator<KonqMainWindow> it( *mainWindows );
+ for (; it.current(); ++it )
+ lst.append( DCOPRef( kapp->dcopClient()->appId(), it.current()->dcopObject()->objId() ) );
+ }
+ return lst;
+}
+
+void KonquerorIface::addToCombo( QString url, QCString objId )
+{
+ KonqMainWindow::comboAction( KonqMainWindow::ComboAdd, url, objId );
+}
+
+void KonquerorIface::removeFromCombo( QString url, QCString objId )
+{
+ KonqMainWindow::comboAction( KonqMainWindow::ComboRemove, url, objId );
+}
+
+void KonquerorIface::comboCleared( QCString objId )
+{
+ KonqMainWindow::comboAction( KonqMainWindow::ComboClear,
+ QString::null, objId );
+}
+
+bool KonquerorIface::processCanBeReused( int screen )
+{
+ if( qt_xscreen() != screen )
+ return false; // this instance run on different screen, and Qt apps can't migrate
+ if( KonqMainWindow::isPreloaded())
+ return false; // will be handled by preloading related code instead
+ QPtrList<KonqMainWindow>* windows = KonqMainWindow::mainWindowList();
+ if( windows == NULL )
+ return true;
+ QStringList allowed_parts = KonqSettings::safeParts();
+ bool all_parts_allowed = false;
+
+ if( allowed_parts.count() == 1 && allowed_parts.first() == QString::fromLatin1( "SAFE" ))
+ {
+ allowed_parts.clear();
+ // is duplicated in client/kfmclient.cc
+ allowed_parts << QString::fromLatin1( "konq_iconview.desktop" )
+ << QString::fromLatin1( "konq_multicolumnview.desktop" )
+ << QString::fromLatin1( "konq_sidebartng.desktop" )
+ << QString::fromLatin1( "konq_infolistview.desktop" )
+ << QString::fromLatin1( "konq_treeview.desktop" )
+ << QString::fromLatin1( "konq_detailedlistview.desktop" );
+ }
+ else if( allowed_parts.count() == 1 && allowed_parts.first() == QString::fromLatin1( "ALL" ))
+ {
+ allowed_parts.clear();
+ all_parts_allowed = true;
+ }
+ if( all_parts_allowed )
+ return true;
+ for( QPtrListIterator<KonqMainWindow> it1( *windows );
+ it1 != NULL;
+ ++it1 )
+ {
+ kdDebug(1202) << "processCanBeReused: count=" << (*it1)->viewCount() << endl;
+ const KonqMainWindow::MapViews& views = (*it1)->viewMap();
+ for( KonqMainWindow::MapViews::ConstIterator it2 = views.begin();
+ it2 != views.end();
+ ++it2 )
+ {
+ kdDebug(1202) << "processCanBeReused: part=" << (*it2)->service()->desktopEntryPath() << ", URL=" << (*it2)->url().prettyURL() << endl;
+ if( !allowed_parts.contains( (*it2)->service()->desktopEntryPath()))
+ return false;
+ }
+ }
+ return true;
+}
+
+void KonquerorIface::terminatePreloaded()
+{
+ if( KonqMainWindow::isPreloaded())
+ kapp->exit();
+}
diff --git a/konqueror/KonquerorIface.h b/konqueror/KonquerorIface.h
new file mode 100644
index 000000000..ba5fd41dd
--- /dev/null
+++ b/konqueror/KonquerorIface.h
@@ -0,0 +1,189 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KonquerorIface_h__
+#define __KonquerorIface_h__
+
+#include <dcopobject.h>
+#include <qvaluelist.h>
+#include <dcopref.h>
+
+#include <qstringlist.h>
+/**
+ * DCOP interface for konqueror
+ */
+class KonquerorIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+
+ KonquerorIface();
+ ~KonquerorIface();
+
+k_dcop:
+
+ /**
+ * Opens a new window for the given @p url (using createSimpleWindow, i.e. a single view)
+ */
+ DCOPRef openBrowserWindow( const QString &url );
+ /**
+ * Like @ref openBrowserWindow , with setting the application startup notification ( ASN )
+ * property on the window.
+ */
+ DCOPRef openBrowserWindowASN( const QString &url, const QCString &startup_id );
+
+ /**
+ * Opens a new window for the given @p url (using createNewWindow, i.e. with an appropriate profile)
+ */
+ DCOPRef createNewWindow( const QString &url );
+ /**
+ * Like @ref createNewWindow , with setting the application startup notification ( ASN )
+ * property on the window.
+ */
+ DCOPRef createNewWindowASN( const QString &url, const QCString &startup_id, bool tempFile );
+
+ /**
+ * Opens a new window like @ref createNewWindow, then selects the given @p filesToSelect
+ */
+ DCOPRef createNewWindowWithSelection( const QString &url, QStringList filesToSelect );
+ /**
+ * Like @ref createNewWindowWithSelection, with setting the application startup notification ( ASN )
+ * property on the window.
+ */
+ DCOPRef createNewWindowWithSelectionASN( const QString &url, QStringList filesToSelect, const QCString &startup_id );
+
+ /**
+ * Opens a new window for the given @p url (using createNewWindow, i.e. with an appropriate profile)
+ * @param mimetype to speed it up.
+ */
+ DCOPRef createNewWindow( const QString &url, const QString & mimetype, bool tempFile );
+ /**
+ * Like @ref createNewWindow , with setting the application startup notification ( ASN )
+ * property on the window.
+ */
+ DCOPRef createNewWindowASN( const QString &url, const QString & mimetype,
+ const QCString &startup_id, bool tempFile );
+
+ /**
+ * As the name says, this creates a window from a profile.
+ * Used for instance by khelpcenter.
+ */
+ DCOPRef createBrowserWindowFromProfile( const QString &path );
+ /**
+ * Like @ref createBrowserWindowFromProfile , with setting the application startup
+ * notification ( ASN ) property on the window.
+ */
+ DCOPRef createBrowserWindowFromProfileASN( const QString &path, const QCString &startup_id );
+
+ /**
+ * As the name says, this creates a window from a profile.
+ * Used for instance by kfmclient.
+ * @param path full path to the profile file
+ * @param filename name of the profile file, if under the profiles dir
+ */
+ DCOPRef createBrowserWindowFromProfile( const QString &path, const QString &filename );
+ /**
+ * Like @ref createBrowserWindowFromProfile , with setting the application startup
+ * notification ( ASN ) property on the window.
+ */
+ DCOPRef createBrowserWindowFromProfileASN( const QString &path, const QString &filename,
+ const QCString &startup_id );
+
+ /**
+ * Creates a window from a profile and a URL.
+ * Used by kfmclient to open http URLs with the webbrowsing profile
+ * and others with the filemanagement profile.
+ * @param path full path to the profile file
+ * @param filename name of the profile file, if under the profiles dir
+ * @param url the URL to open
+ */
+ DCOPRef createBrowserWindowFromProfileAndURL( const QString &path, const QString &filename, const QString &url );
+ /**
+ * Like @ref createBrowserWindowFromProfileAndURL , with setting the application startup
+ * notification ( ASN ) property on the window.
+ */
+ DCOPRef createBrowserWindowFromProfileAndURLASN( const QString &path, const QString &filename, const QString &url,
+ const QCString &startup_id );
+
+ /**
+ * Creates a window the fastest way : the caller has to provide
+ * profile, URL, and mimetype.
+ * @param path full path to the profile file
+ * @param filename name of the profile file, if under the profiles dir
+ * @param url the URL to open
+ * @param mimetype the mimetype that the URL we want to open has
+ */
+ DCOPRef createBrowserWindowFromProfileAndURL( const QString &path, const QString &filename, const QString &url, const QString &mimetype );
+ /**
+ * Like @ref createBrowserWindowFromProfileAndURL , with setting the application startup
+ * notification ( ASN ) property on the window.
+ */
+ DCOPRef createBrowserWindowFromProfileAndURLASN( const QString &path, const QString &filename, const QString &url, const QString &mimetype,
+ const QCString& startup_id );
+
+ /**
+ * Called by kcontrol when the global configuration changes
+ */
+ ASYNC reparseConfiguration();
+
+ /**
+ * @return the name of the instance's crash log file
+ */
+ QString crashLogFile();
+
+ /**
+ * @return a list of references to all the windows
+ */
+ QValueList<DCOPRef> getWindows();
+
+ /**
+ * Called internally as broadcast when the user adds/removes/renames a view profile
+ */
+ ASYNC updateProfileList();
+
+ /**
+ * Called internally as broadcast when a URL is to be added to the combobox.
+ */
+ ASYNC addToCombo( QString, QCString );
+
+ /**
+ * Called internall as broadcast when a URL has to be removed from the combo.
+ */
+ ASYNC removeFromCombo( QString, QCString );
+
+ /**
+ * Called internally as a broadcast when the combobox was cleared.
+ */
+ ASYNC comboCleared( QCString );
+
+ /**
+ * Used by kfmclient when the 'minimize memory usage' setting is set
+ * to find out if this konqueror can be used.
+ */
+ bool processCanBeReused( int screen );
+
+ /**
+ * Called from konqy_preloader to terminate this Konqueror instance,
+ * if it's in the preloaded mode, and there are too many preloaded Konqy's
+ */
+ ASYNC terminatePreloaded();
+};
+
+#endif
diff --git a/konqueror/Makefile.am b/konqueror/Makefile.am
new file mode 100644
index 000000000..0fd86b2f5
--- /dev/null
+++ b/konqueror/Makefile.am
@@ -0,0 +1,105 @@
+AM_CPPFLAGS = -D_LARGEFILE64_SOURCE
+
+INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/kcontrol/input $(all_includes)
+
+SUBDIRS = . client iconview listview keditbookmarks shellcmdplugin about pics sidebar preloader quickprint remoteencodingplugin kttsplugin
+
+bin_PROGRAMS =
+lib_LTLIBRARIES =
+kdeinit_LTLIBRARIES = konqueror.la
+
+noinst_LTLIBRARIES = libkonqueror_intern.la
+konqdatadir = $(kde_datadir)/konqueror
+konqdata_DATA = konqueror.rc konq-simplebrowser.rc
+
+kde_apps_DATA = konqueror.desktop
+
+# servicetypedir = $(kde_servicetypesdir)
+# servicetype_DATA = konq_metaview.desktop
+
+METASOURCES = AUTO
+
+include_HEADERS = KonquerorIface.h
+
+libkonqueror_intern_la_SOURCES = konq_settingsxt.kcfgc
+konqueror_la_SOURCES = konq_main.cc \
+ KonquerorIface.cc KonquerorIface.skel \
+ KonqMainWindowIface.cc KonqMainWindowIface.skel \
+ KonqViewIface.cc KonqViewIface.skel \
+ konq_guiclients.cc \
+ konq_run.cc konq_view.cc konq_viewmgr.cc \
+ konq_misc.cc \
+ konq_frame.cc \
+ konq_tabs.cc \
+ konq_actions.cc \
+ konq_profiledlg.cc \
+ konq_factory.cc \
+ konq_combo.cc \
+ konq_browseriface.cc \
+ delayedinitializer.cc \
+ konq_mainwindow.cc \
+ konq_extensionmanager.cc
+
+konqueror_la_PCH = AUTO
+
+noinst_HEADERS = KonqMainWindowIface.h KonqViewIface.h delayedinitializer.h \
+ konq_actions.h konq_browseriface.h konq_combo.h konq_factory.h \
+ konq_frame.h konq_tabs.h konq_guiclients.h konq_main.h konq_mainwindow.h \
+ konq_misc.h konq_openurlrequest.h konq_profiledlg.h konq_run.h \
+ konq_view.h konq_viewmgr.h konq_extensionmanager.h version.h
+
+konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+konqueror_la_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS)
+
+# Hmm, this experiment of a static konq failed, don't trust it...
+# (but feel free to fix it :)
+
+# Note that you need to --enable-debug in kdelibs and kdebase,
+# then make clean ; make install in kdelibs and libkonq,
+# and make clean ; make konqueror_static in here.
+#check_PROGRAMS = konqueror_static
+#
+#konqueror_static_SOURCES = dummy.cc
+#konqueror_static_LDADD = konqueror.la *view/*.la dirtree/*.la $(libdir)/libkhtml.la
+#konqueror_static_LDFLAGS = $(all_libraries) -static
+
+messages: rc.cpp
+ $(EXTRACTRC) *.rc */*.rc >> rc.cpp
+ $(EXTRACTRC) sidebar/trees/history_module/history_dlg.ui >> rc.cpp
+ $(XGETTEXT) -kaliasLocal rc.cpp *.h *.cc *view/*h *view/*cc kedit*/*.h kedit*/*.cpp about/*.h about/*.cc remoteencodingplugin/*.cpp remoteencodingplugin/*.h shellcmdplugin/*.cpp -o `find sidebar -name "*.cpp"` `find sidebar -name "*.h"` -o $(podir)/konqueror.pot
+
+xdg_apps_DATA = kfmclient.desktop kfmclient_dir.desktop kfmclient_html.desktop \
+ kfmclient_war.desktop konqbrowser.desktop konquerorsu.desktop Home.desktop
+
+konq_data4_DATA = konqfilemgr.desktop
+konq_data4dir = $(kde_appsdir)/.hidden
+
+kde_kcfg_DATA = konqueror.kcfg
+
+####### Build rules
+KonquerorIface.lo: konq_settingsxt.h
+konq_actions.lo: konq_settingsxt.h
+konq_guiclients.lo: konq_settingsxt.h
+konq_main.lo: konq_settingsxt.h
+konq_mainwindow.lo: konq_settingsxt.h
+konq_profiledlg.lo: konq_settingsxt.h
+konq_settingsxt.lo: konq_settingsxt.h
+konq_tabs.lo: konq_settingsxt.h
+konq_view.lo: konq_settingsxt.h
+konq_viewmgr.lo: konq_settingsxt.h
+
+# Use a hand-made rule for profiles because they are renamed upon installation
+profiledir = $(kde_datadir)/konqueror/profiles
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(profiledir)
+ $(INSTALL_DATA) $(srcdir)/profile_webbrowsing.desktop $(DESTDIR)$(profiledir)/webbrowsing
+ $(INSTALL_DATA) $(srcdir)/profile_filemanagement.desktop $(DESTDIR)$(profiledir)/filemanagement
+ $(INSTALL_DATA) $(srcdir)/profile_midnightcommander.desktop $(DESTDIR)$(profiledir)/midnightcommander
+ $(INSTALL_DATA) $(srcdir)/profile_tabbedbrowsing.desktop $(DESTDIR)$(profiledir)/tabbedbrowsing
+ $(INSTALL_DATA) $(srcdir)/profile_kde_devel.desktop $(DESTDIR)$(profiledir)/kde_devel
+ $(INSTALL_DATA) $(srcdir)/profile_simplebrowser.desktop $(DESTDIR)$(profiledir)/simplebrowser
+
+# $(INSTALL_DATA) $(srcdir)/profile_filepreview.desktop $(DESTDIR)$(profiledir)/filepreview
+
+uninstall-local:
+ -rm -f $(DESTDIR)$(profiledir)/webbrowsing $(DESTDIR)$(profiledir)/filemanagement $(DESTDIR)$(profiledir)/midnightcommander $(DESTDIR)$(profiledir)/filepreview
diff --git a/konqueror/TODO b/konqueror/TODO
new file mode 100644
index 000000000..725abeb4a
--- /dev/null
+++ b/konqueror/TODO
@@ -0,0 +1,49 @@
+KIconView:
+==========
+
+- When you are adding to the selection (eg. by shift + LMB)
+ then change the mouse cursor to indicate this. Several drawing programs do
+ this by adding a '+' to the normal mouse cursor and it makes them a lot more usable.
+ [ I'm not sure this is necessary, and if yes it's a QIconView issue anyway - David ]
+
+libkonq:
+========
+
+- delete file : if image, remove from thumbnails dir
+
+- ordering templates: Find a way to use KServiceGroup for this,
+ or "borrow" the code...
+
+konqueror framework:
+====================
+
+- Remove highlighted text color and text color from kcmkonq, and settings.
+
+- Do we want "[X] Use directory properties" ?
+
+iconview+listviews:
+===================
+
+- Hide backup files (files ending in ~ or #) - see #3212
+
+- if we keep "background color for this directory" should we have "text color for
+this directory" too... ?
+
+dirtree:
+========
+
+- Create dynamic items when browsing non-local URLs (FTP etc.)
+
+kpropsdlg (kfile):
+======
+
+- Maybe add GUI (in kpropertiesdialog probably) for user defined actions in .desktop
+files (example: see eject action in the CDROM template) ?
+
+- Maybe a checkbox for the appstart-notification thing ?
+
+kdesktop:
+=========
+
+- Different icons on different desktops (i.e. different directories, Desktop[1-N],
+the Desktop one being the 'sticky' icons)
diff --git a/konqueror/about/Makefile.am b/konqueror/about/Makefile.am
new file mode 100644
index 000000000..b8293c098
--- /dev/null
+++ b/konqueror/about/Makefile.am
@@ -0,0 +1,17 @@
+kde_module_LTLIBRARIES = konq_aboutpage.la
+
+INCLUDES = -I$(srcdir)/.. -I$(top_srcdir)/libkonq $(all_includes)
+konq_aboutpage_la_SOURCES = konq_aboutpage.cc
+konq_aboutpage_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+konq_aboutpage_la_LIBADD = $(LIB_KHTML)
+
+kde_services_DATA = konq_aboutpage.desktop
+kde_servicetypes_DATA = konqaboutpage.desktop
+
+METASOURCES = AUTO
+
+konq_aboutpage_datadir = $(kde_datadir)/konqueror/about
+konq_aboutpage_data_DATA = \
+ box-centre-konqueror.png top-right-konqueror.png lightning.png \
+ launch.html intro.html specs.html tips.html \
+ plugins.html plugins_rtl.html konq.css
diff --git a/konqueror/about/box-centre-konqueror.png b/konqueror/about/box-centre-konqueror.png
new file mode 100644
index 000000000..2bc6e9fa8
--- /dev/null
+++ b/konqueror/about/box-centre-konqueror.png
Binary files differ
diff --git a/konqueror/about/intro.html b/konqueror/about/intro.html
new file mode 100644
index 000000000..a8cfb5af5
--- /dev/null
+++ b/konqueror/about/intro.html
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st August 2004), see www.w3.org" />
+
+ <style type="text/css">
+ /*<![CDATA[*/
+ @import "%1"; /* kde_infopage.css */
+ %1 /* maybe @import "kde_infopage_rtl.css"; */
+ @import "konq.css";
+ /*]]>*/
+ </style>
+
+ <title>%1</title>
+</head>
+
+<body>
+ <div id="header">
+ <div id="headerL"/>
+ <div id="headerR"/>
+
+ <div id="title">
+ %1 <!-- Konqueror -->
+ </div>
+
+ <div id="tagline">
+ %1 <!-- Conquer your Desktop -->
+ </div>
+ </div>
+
+ <!-- the bar -->
+ <div id="bar">
+ <div id="barT"><div id="barTL"/><div id="barTR"/><div id="barTC"/></div>
+ <div id="barL">
+ <div id="barR">
+ <div id="barCenter" class="bar_text">
+ %1<br />
+ <!-- Konqueror is your file manager, web browser and universal document viewer. -->
+ <ul>
+ <li><a href="launch.html">%1</a><!--launch--></li>
+ <li><a class="selected">%1<!-- introduction --></a></li>
+ <li><a href="tips.html">%1<!--tips--></a></li>
+ <li><a href="specs.html">%1<!-- specs --></a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div id="barB"><div id="barBL"/><div id="barBR"/><div id="barBC"/></div>
+ </div>
+
+ <!-- the main text box -->
+ <div id="box">
+ <div id="boxT"><div id="boxTL"/><div id="boxTR"/><div id="boxTC"/></div>
+ <div id="boxL">
+ <div id="boxR">
+ <div id="boxCenter">
+
+ %1<!--
+ With Konqueror you have ...
+ -->
+
+ <p>%1</p>
+ <!-- Simply enter the internet address ...-->
+ <p>%1
+ <!--If you want to go back to ...-->
+ %1<!--To go back to the home-directory...-->
+ %1</p>
+ <p><!--For more detailed documentation on Konqueror click here --></p>
+
+ <p><table><tr><td valign=middle><img width="32" height="32" border="0" src=
+ "lightning.png" align="left" alt="" /></td><td valign=top>%1</td></tr></table>
+ <!--Tuning tip...--></p>
+
+ <p id="nextlink"><a href="tips.html">%1&nbsp;%1
+ <!-- Continue --></a></p>
+ </div>
+ </div>
+ </div>
+ <div id="boxB"><div id="boxBL"/><div id="boxBR"/><div id="boxBC"/></div>
+ </div>
+
+ <div id="footer"><div id="footerL"/><div id="footerR"/></div>
+</body>
+</html>
+<!-- vim:set sw=2 et nocindent smartindent: -->
diff --git a/konqueror/about/konq.css b/konqueror/about/konq.css
new file mode 100644
index 000000000..735861d9e
--- /dev/null
+++ b/konqueror/about/konq.css
@@ -0,0 +1,21 @@
+
+#headerR {
+ width: 430px;
+ height: 131px;
+ background-image: url(top-right-konqueror.png);
+}
+
+#title {
+ right: 100px;
+}
+
+#tagline {
+ right: 100px;
+}
+
+#boxCenter {
+ background-image: url(box-centre-konqueror.png);
+ background-repeat: no-repeat;
+}
+
+
diff --git a/konqueror/about/konq_aboutpage.cc b/konqueror/about/konq_aboutpage.cc
new file mode 100644
index 000000000..03da9a060
--- /dev/null
+++ b/konqueror/about/konq_aboutpage.cc
@@ -0,0 +1,518 @@
+#include "konq_aboutpage.h"
+
+#include <qtextcodec.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ksavefile.h>
+#include <kstandarddirs.h>
+#include <kaction.h>
+#include <kiconloader.h>
+
+#include <assert.h>
+#include <qfile.h>
+#include <qdir.h>
+
+K_EXPORT_COMPONENT_FACTORY( konq_aboutpage, KonqAboutPageFactory )
+
+KInstance *KonqAboutPageFactory::s_instance = 0;
+QString *KonqAboutPageFactory::s_launch_html = 0;
+QString *KonqAboutPageFactory::s_intro_html = 0;
+QString *KonqAboutPageFactory::s_specs_html = 0;
+QString *KonqAboutPageFactory::s_tips_html = 0;
+QString *KonqAboutPageFactory::s_plugins_html = 0;
+
+KonqAboutPageFactory::KonqAboutPageFactory( QObject *parent, const char *name )
+ : KParts::Factory( parent, name )
+{
+ s_instance = new KInstance( "konqaboutpage" );
+}
+
+KonqAboutPageFactory::~KonqAboutPageFactory()
+{
+ delete s_instance;
+ s_instance = 0;
+ delete s_launch_html;
+ s_launch_html = 0;
+ delete s_intro_html;
+ s_intro_html = 0;
+ delete s_specs_html;
+ s_specs_html = 0;
+ delete s_tips_html;
+ s_tips_html = 0;
+ delete s_plugins_html;
+ s_plugins_html = 0;
+}
+
+KParts::Part *KonqAboutPageFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *, const QStringList & )
+{
+ //KonqFrame *frame = dynamic_cast<KonqFrame *>( parentWidget );
+ //if ( !frame ) return 0;
+
+ return new KonqAboutPage( //frame->childView()->mainWindow(),
+ parentWidget, widgetName, parent, name );
+}
+
+QString KonqAboutPageFactory::loadFile( const QString& file )
+{
+ QString res;
+ if ( file.isEmpty() )
+ return res;
+
+ QFile f( file );
+
+ if ( !f.open( IO_ReadOnly ) )
+ return res;
+
+ QTextStream t( &f );
+
+ res = t.read();
+
+ // otherwise all embedded objects are referenced as about:/...
+ QString basehref = QString::fromLatin1("<BASE HREF=\"file:") +
+ file.left( file.findRev( '/' )) +
+ QString::fromLatin1("/\">\n");
+ QRegExp reg("<head>");
+ reg.setCaseSensitive(FALSE);
+ res.replace(reg, "<head>\n\t" + basehref);
+ return res;
+}
+
+QString KonqAboutPageFactory::launch()
+{
+ if ( s_launch_html )
+ return *s_launch_html;
+
+ QString res = loadFile( locate( "data", "konqueror/about/launch.html" ));
+ if ( res.isEmpty() )
+ return res;
+
+ KIconLoader *iconloader = KGlobal::iconLoader();
+ int iconSize = iconloader->currentSize(KIcon::Desktop);
+ QString home_icon_path = iconloader->iconPath("kfm_home", KIcon::Desktop );
+ QString storage_icon_path = iconloader->iconPath("system", KIcon::Desktop );
+ QString remote_icon_path = iconloader->iconPath("network", KIcon::Desktop );
+ QString wastebin_icon_path = iconloader->iconPath("trashcan_full", KIcon::Desktop );
+ QString applications_icon_path = iconloader->iconPath("kmenu", KIcon::Desktop );
+ QString settings_icon_path = iconloader->iconPath("kcontrol", KIcon::Desktop );
+ QString home_folder = QDir::homeDirPath();
+ QString continue_icon_path = QApplication::reverseLayout()?iconloader->iconPath("1leftarrow", KIcon::Small ):iconloader->iconPath("1rightarrow", KIcon::Small );
+
+ res = res.arg( locate( "data", "kdeui/about/kde_infopage.css" ) );
+ if ( kapp->reverseLayout() )
+ res = res.arg( "@import \"%1\";" ).arg( locate( "data", "kdeui/about/kde_infopage_rtl.css" ) );
+ else
+ res = res.arg( "" );
+
+ res = res.arg( i18n("Conquer your Desktop!") )
+ .arg( i18n( "Konqueror" ) )
+ .arg( i18n("Conquer your Desktop!") )
+ .arg( i18n("Konqueror is your file manager, web browser and universal document viewer.") )
+ .arg( i18n( "Starting Points" ) )
+ .arg( i18n( "Introduction" ) )
+ .arg( i18n( "Tips" ) )
+ .arg( i18n( "Specifications" ) )
+ .arg( home_folder )
+ .arg( home_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( home_folder )
+ .arg( i18n( "Home Folder" ) )
+ .arg( i18n( "Your personal files" ) )
+ .arg( storage_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( i18n( "Storage Media" ) )
+ .arg( i18n( "Disks and removable media" ) )
+ .arg( remote_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( i18n( "Network Folders" ) )
+ .arg( i18n( "Shared files and folders" ) )
+ .arg( wastebin_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( i18n( "Trash" ) )
+ .arg( i18n( "Browse and restore the trash" ) )
+ .arg( applications_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( i18n( "Applications" ) )
+ .arg( i18n( "Installed programs" ) )
+ .arg( settings_icon_path )
+ .arg(iconSize).arg(iconSize)
+ .arg( i18n( "Settings" ) )
+ .arg( i18n( "Desktop configuration" ) )
+ .arg( continue_icon_path )
+ .arg( KIcon::SizeSmall ).arg( KIcon::SizeSmall )
+ .arg( i18n( "Next: An Introduction to Konqueror" ) )
+ ;
+ i18n("Search the Web");//i18n for possible future use
+
+ s_launch_html = new QString( res );
+
+ return res;
+}
+
+QString KonqAboutPageFactory::intro()
+{
+ if ( s_intro_html )
+ return *s_intro_html;
+
+ QString res = loadFile( locate( "data", "konqueror/about/intro.html" ));
+ if ( res.isEmpty() )
+ return res;
+
+ KIconLoader *iconloader = KGlobal::iconLoader();
+ QString back_icon_path = QApplication::reverseLayout()?iconloader->iconPath("forward", KIcon::Small ):iconloader->iconPath("back", KIcon::Small );
+ QString gohome_icon_path = iconloader->iconPath("gohome", KIcon::Small );
+ QString continue_icon_path = QApplication::reverseLayout()?iconloader->iconPath("1leftarrow", KIcon::Small ):iconloader->iconPath("1rightarrow", KIcon::Small );
+
+ res = res.arg( locate( "data", "kdeui/about/kde_infopage.css" ) );
+ if ( kapp->reverseLayout() )
+ res = res.arg( "@import \"%1\";" ).arg( locate( "data", "kdeui/about/kde_infopage_rtl.css" ) );
+ else
+ res = res.arg( "" );
+
+ res = res.arg( i18n("Conquer your Desktop!") )
+ .arg( i18n( "Konqueror" ) )
+ .arg( i18n( "Conquer your Desktop!") )
+ .arg( i18n( "Konqueror is your file manager, web browser and universal document viewer.") )
+ .arg( i18n( "Starting Points" ) )
+ .arg( i18n( "Introduction" ) )
+ .arg( i18n( "Tips" ) )
+ .arg( i18n( "Specifications" ) )
+ .arg( i18n( "Konqueror makes working with and managing your files easy. You can browse "
+ "both local and networked folders while enjoying advanced features "
+ "such as the powerful sidebar and file previews."
+ ) )
+ .arg( i18n( "Konqueror is also a full featured and easy to use web browser which you "
+ "can use to explore the Internet. "
+ "Enter the address (e.g. <a href=\"http://www.kde.org\">http://www.kde.org</A>) "
+ "of a web page you would like to visit in the location bar and press Enter, "
+ "or choose an entry from the Bookmarks menu.") )
+ .arg( i18n( "To return to the previous "
+ "location, press the back button <img width='16' height='16' src=\"%1\"> "
+ "in the toolbar. ").arg( back_icon_path ) )
+ .arg( i18n( "To quickly go to your Home folder press the "
+ " home button <img width='16' height='16' src=\"%1\">." ).arg(gohome_icon_path) )
+ .arg( i18n( "For more detailed documentation on Konqueror click <a href=\"%1\">here</a>." )
+ .arg("exec:/khelpcenter") )
+ .arg( i18n( "<em>Tuning Tip:</em> If you want the Konqueror web browser to start faster,"
+ " you can turn off this information screen by clicking <a href=\"%1\">here</a>. You can re-enable it"
+ " by choosing the Help -> Konqueror Introduction menu option, and then pressing "
+ "Settings -> Save View Profile \"Web Browsing\".").arg("config:/disable_overview") )
+ .arg( "<img width='16' height='16' src=\"%1\">" ).arg( continue_icon_path )
+ .arg( i18n( "Next: Tips &amp; Tricks" ) )
+ ;
+
+
+ s_intro_html = new QString( res );
+
+ return res;
+}
+
+QString KonqAboutPageFactory::specs()
+{
+ if ( s_specs_html )
+ return *s_specs_html;
+
+ KIconLoader *iconloader = KGlobal::iconLoader();
+ QString res = loadFile( locate( "data", "konqueror/about/specs.html" ));
+ QString continue_icon_path = QApplication::reverseLayout()?iconloader->iconPath("1leftarrow", KIcon::Small ):iconloader->iconPath("1rightarrow", KIcon::Small );
+ if ( res.isEmpty() )
+ return res;
+
+ res = res.arg( locate( "data", "kdeui/about/kde_infopage.css" ) );
+ if ( kapp->reverseLayout() )
+ res = res.arg( "@import \"%1\";" ).arg( locate( "data", "kdeui/about/kde_infopage_rtl.css" ) );
+ else
+ res = res.arg( "" );
+
+ res = res.arg( i18n("Conquer your Desktop!") )
+ .arg( i18n( "Konqueror" ) )
+ .arg( i18n("Conquer your Desktop!") )
+ .arg( i18n("Konqueror is your file manager, web browser and universal document viewer.") )
+ .arg( i18n( "Starting Points" ) )
+ .arg( i18n( "Introduction" ) )
+ .arg( i18n( "Tips" ) )
+ .arg( i18n( "Specifications" ) )
+ .arg( i18n("Specifications") )
+ .arg( i18n("Konqueror is designed to embrace and support Internet standards. "
+ "The aim is to fully implement the officially sanctioned standards "
+ "from organizations such as the W3 and OASIS, while also adding "
+ "extra support for other common usability features that arise as "
+ "de facto standards across the Internet. Along with this support, "
+ "for such functions as favicons, Internet Keywords, and <A HREF=\"%1\">XBEL bookmarks</A>, "
+ "Konqueror also implements:").arg("http://pyxml.sourceforge.net/topics/xbel/") )
+ .arg( i18n("Web Browsing") )
+ .arg( i18n("Supported standards") )
+ .arg( i18n("Additional requirements*") )
+ .arg( i18n("<A HREF=\"%1\">DOM</A> (Level 1, partially Level 2) based "
+ "<A HREF=\"%2\">HTML 4.01</A>").arg("http://www.w3.org/DOM").arg("http://www.w3.org/TR/html4/") )
+ .arg( i18n("built-in") )
+ .arg( i18n("<A HREF=\"%1\">Cascading Style Sheets</A> (CSS 1, partially CSS 2)").arg("http://www.w3.org/Style/CSS/") )
+ .arg( i18n("built-in") )
+ .arg( i18n("<A HREF=\"%1\">ECMA-262</A> Edition 3 (roughly equals JavaScript 1.5)").arg("http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM") )
+ .arg( i18n("JavaScript disabled (globally). Enable JavaScript <A HREF=\"%1\">here</A>.").arg("exec:/kcmshell khtml_java_js") )
+ .arg( i18n("JavaScript enabled (globally). Configure JavaScript <A HREF=\\\"%1\\\">here</A>.").arg("exec:/kcmshell khtml_java_js") ) // leave the double backslashes here, they are necessary for javascript !
+ .arg( i18n("Secure <A HREF=\"%1\">Java</A><SUP>&reg;</SUP> support").arg("http://java.sun.com") )
+ .arg( i18n("JDK 1.2.0 (Java 2) compatible VM (<A HREF=\"%1\">Blackdown</A>, <A HREF=\"%2\">IBM</A> or <A HREF=\"%3\">Sun</A>)")
+ .arg("http://www.blackdown.org").arg("http://www.ibm.com").arg("http://java.sun.com") )
+ .arg( i18n("Enable Java (globally) <A HREF=\"%1\">here</A>.").arg("exec:/kcmshell khtml_java_js") ) // TODO Maybe test if Java is enabled ?
+ .arg( i18n("Netscape Communicator<SUP>&reg;</SUP> <A HREF=\"%4\">plugins</A> (for viewing <A HREF=\"%1\">Flash<SUP>&reg;</SUP></A>, <A HREF=\"%2\">Real<SUP>&reg;</SUP></A>Audio, <A HREF=\"%3\">Real<SUP>&reg;</SUP></A>Video, etc.)")
+ .arg("http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash")
+ .arg("http://www.real.com").arg("http://www.real.com")
+ .arg("about:plugins") )
+ .arg( i18n("built-in") )
+ .arg( i18n("Secure Sockets Layer") )
+ .arg( i18n("(TLS/SSL v2/3) for secure communications up to 168bit") )
+ .arg( i18n("OpenSSL") )
+ .arg( i18n("Bidirectional 16bit unicode support") )
+ .arg( i18n("built-in") )
+ .arg( i18n("AutoCompletion for forms") )
+ .arg( i18n("built-in") )
+ .arg( i18n("G E N E R A L") )
+ .arg( i18n("Feature") )
+ .arg( i18n("Details") )
+ .arg( i18n("Image formats") )
+ .arg( i18n("Transfer protocols") )
+ .arg( i18n("HTTP 1.1 (including gzip/bzip2 compression)") )
+ .arg( i18n("FTP") )
+ .arg( i18n("and <A HREF=\"%1\">many more...</A>").arg("exec:/kcmshell ioslaveinfo") )
+ .arg( i18n("URL-Completion") )
+ .arg( i18n("Manual"))
+ .arg( i18n("Popup"))
+ .arg( i18n("(Short-) Automatic"))
+ .arg( "<img width='16' height='16' src=\"%1\">" ).arg( continue_icon_path )
+ .arg( i18n("<a href=\"%1\">Return to Starting Points</a>").arg("launch.html") )
+
+ ;
+
+ s_specs_html = new QString( res );
+
+ return res;
+}
+
+QString KonqAboutPageFactory::tips()
+{
+ if ( s_tips_html )
+ return *s_tips_html;
+
+ QString res = loadFile( locate( "data", "konqueror/about/tips.html" ));
+ if ( res.isEmpty() )
+ return res;
+
+ KIconLoader *iconloader = KGlobal::iconLoader();
+ QString viewmag_icon_path =
+ iconloader->iconPath("viewmag", KIcon::Small );
+ QString history_icon_path =
+ iconloader->iconPath("history", KIcon::Small );
+ QString openterm_icon_path =
+ iconloader->iconPath("openterm", KIcon::Small );
+ QString locationbar_erase_rtl_icon_path =
+ iconloader->iconPath("clear_left", KIcon::Small );
+ QString locationbar_erase_icon_path =
+ iconloader->iconPath("locationbar_erase", KIcon::Small );
+ QString window_fullscreen_icon_path =
+ iconloader->iconPath("window_fullscreen", KIcon::Small );
+ QString view_left_right_icon_path =
+ iconloader->iconPath("view_left_right", KIcon::Small );
+ QString continue_icon_path = QApplication::reverseLayout()?iconloader->iconPath("1leftarrow", KIcon::Small ):iconloader->iconPath("1rightarrow", KIcon::Small );
+
+ res = res.arg( locate( "data", "kdeui/about/kde_infopage.css" ) );
+ if ( kapp->reverseLayout() )
+ res = res.arg( "@import \"%1\";" ).arg( locate( "data", "kdeui/about/kde_infopage_rtl.css" ) );
+ else
+ res = res.arg( "" );
+
+ res = res.arg( i18n("Conquer your Desktop!") )
+ .arg( i18n( "Konqueror" ) )
+ .arg( i18n("Conquer your Desktop!") )
+ .arg( i18n("Konqueror is your file manager, web browser and universal document viewer.") )
+ .arg( i18n( "Starting Points" ) )
+ .arg( i18n( "Introduction" ) )
+ .arg( i18n( "Tips" ) )
+ .arg( i18n( "Specifications" ) )
+ .arg( i18n( "Tips &amp; Tricks" ) )
+ .arg( i18n( "Use Internet-Keywords and Web-Shortcuts: by typing \"gg: KDE\" one can search the Internet, "
+ "using Google, for the search phrase \"KDE\". There are a lot of "
+ "Web-Shortcuts predefined to make searching for software or looking "
+ "up certain words in an encyclopedia a breeze. You can even "
+ "<a href=\"%1\">create your own</a> Web-Shortcuts." ).arg("exec:/kcmshell ebrowsing") )
+ .arg( i18n( "Use the magnifier button <img width='16' height='16' src=\"%1\"> in the"
+ " toolbar to increase the font size on your web page.").arg(viewmag_icon_path) )
+ .arg( i18n( "When you want to paste a new address into the Location toolbar you might want to "
+ "clear the current entry by pressing the black arrow with the white cross "
+ "<img width='16' height='16' src=\"%1\"> in the toolbar.")
+ .arg(QApplication::reverseLayout() ? locationbar_erase_rtl_icon_path : locationbar_erase_icon_path))
+ .arg( i18n( "To create a link on your desktop pointing to the current page, "
+ "simply drag the \"Location\" label that is to the left of the Location toolbar, drop it on to "
+ "the desktop, and choose \"Link\"." ) )
+ .arg( i18n( "You can also find <img width='16' height='16' src=\"%1\"> \"Full-Screen Mode\" "
+ "in the Settings menu. This feature is very useful for \"Talk\" "
+ "sessions.").arg(window_fullscreen_icon_path) )
+ .arg( i18n( "Divide et impera (lat. \"Divide and conquer\") - by splitting a window "
+ "into two parts (e.g. Window -> <img width='16' height='16' src=\"%1\"> Split View "
+ "Left/Right) you can make Konqueror appear the way you like. You"
+ " can even load some example view-profiles (e.g. Midnight Commander)"
+ ", or create your own ones." ).arg(view_left_right_icon_path))
+ .arg( i18n( "Use the <a href=\"%1\">user-agent</a> feature if the website you are visiting "
+ "asks you to use a different browser "
+ "(and do not forget to send a complaint to the webmaster!)" ).arg("exec:/kcmshell useragent") )
+ .arg( i18n( "The <img width='16' height='16' src=\"%1\"> History in your SideBar ensures "
+ "that you can keep track of the pages you have visited recently.").arg(history_icon_path) )
+ .arg( i18n( "Use a caching <a href=\"%1\">proxy</a> to speed up your"
+ " Internet connection.").arg("exec:/kcmshell proxy") )
+ .arg( i18n( "Advanced users will appreciate the Konsole which you can embed into "
+ "Konqueror (Window -> <img width='16' height='16' SRC=\"%1\"> Show "
+ "Terminal Emulator).").arg(openterm_icon_path))
+ .arg( i18n( "Thanks to <a href=\"%1\">DCOP</a> you can have full control over Konqueror using a script."
+).arg("exec:/kdcop") )
+ .arg( i18n( "<img width='16' height='16' src=\"%1\">" ).arg( continue_icon_path ) )
+ .arg( i18n( "Next: Specifications" ) )
+ ;
+
+
+ s_tips_html = new QString( res );
+
+ return res;
+}
+
+
+QString KonqAboutPageFactory::plugins()
+{
+ if ( s_plugins_html )
+ return *s_plugins_html;
+
+ QString res = loadFile( locate( "data", kapp->reverseLayout() ? "konqueror/about/plugins_rtl.html" : "konqueror/about/plugins.html" ))
+ .arg(i18n("Installed Plugins"))
+ .arg(i18n("<td>Plugin</td><td>Description</td><td>File</td><td>Types</td>"))
+ .arg(i18n("Installed"))
+ .arg(i18n("<td>Mime Type</td><td>Description</td><td>Suffixes</td><td>Plugin</td>"));
+ if ( res.isEmpty() )
+ return res;
+
+ s_plugins_html = new QString( res );
+
+ return res;
+}
+
+
+KonqAboutPage::KonqAboutPage( //KonqMainWindow *
+ QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name )
+ : KHTMLPart( parentWidget, widgetName, parent, name, BrowserViewGUI )
+{
+ //m_mainWindow = mainWindow;
+ QTextCodec* codec = KGlobal::locale()->codecForEncoding();
+ if (codec)
+ setCharset(codec->name(), true);
+ else
+ setCharset("iso-8859-1", true);
+ // about:blah isn't a kioslave -> disable View source
+ KAction * act = actionCollection()->action("viewDocumentSource");
+ if ( act )
+ act->setEnabled( false );
+}
+
+KonqAboutPage::~KonqAboutPage()
+{
+}
+
+bool KonqAboutPage::openURL( const KURL &u )
+{
+ if (u.url() == "about:plugins")
+ serve( KonqAboutPageFactory::plugins(), "plugins" );
+ else serve( KonqAboutPageFactory::launch(), "konqueror" );
+ return true;
+}
+
+bool KonqAboutPage::openFile()
+{
+ return true;
+}
+
+void KonqAboutPage::saveState( QDataStream &stream )
+{
+ stream << m_htmlDoc;
+ stream << m_what;
+}
+
+void KonqAboutPage::restoreState( QDataStream &stream )
+{
+ stream >> m_htmlDoc;
+ stream >> m_what;
+ serve( m_htmlDoc, m_what );
+}
+
+void KonqAboutPage::serve( const QString& html, const QString& what )
+{
+ m_what = what;
+ begin( KURL( QString("about:%1").arg(what) ) );
+ write( html );
+ end();
+ m_htmlDoc = html;
+}
+
+void KonqAboutPage::urlSelected( const QString &url, int button, int state, const QString &target, KParts::URLArgs _args )
+{
+ KURL u( url );
+ if ( u.protocol() == "exec" )
+ {
+ QStringList args = QStringList::split( QChar( ' ' ), url.mid( 6 ) );
+ QString executable = args[ 0 ];
+ args.remove( args.begin() );
+ KApplication::kdeinitExec( executable, args );
+ return;
+ }
+
+ if ( url == QString::fromLatin1("launch.html") )
+ {
+ emit browserExtension()->openURLNotify();
+ serve( KonqAboutPageFactory::launch(), "konqueror" );
+ return;
+ }
+ else if ( url == QString::fromLatin1("intro.html") )
+ {
+ emit browserExtension()->openURLNotify();
+ serve( KonqAboutPageFactory::intro(), "konqueror" );
+ return;
+ }
+ else if ( url == QString::fromLatin1("specs.html") )
+ {
+ emit browserExtension()->openURLNotify();
+ serve( KonqAboutPageFactory::specs(), "konqueror" );
+ return;
+ }
+ else if ( url == QString::fromLatin1("tips.html") )
+ {
+ emit browserExtension()->openURLNotify();
+ serve( KonqAboutPageFactory::tips(), "konqueror" );
+ return;
+ }
+
+ else if ( url == QString::fromLatin1("config:/disable_overview") )
+ {
+ if ( KMessageBox::questionYesNo( widget(),
+ i18n("Do you want to disable showing "
+ "the introduction in the webbrowsing profile?"),
+ i18n("Faster Startup?"),i18n("Disable"),i18n("Keep") )
+ == KMessageBox::Yes )
+ {
+ QString profile = locateLocal("data", "konqueror/profiles/webbrowsing");
+ KSaveFile file( profile );
+ if ( file.status() == 0 ) {
+ QCString content = "[Profile]\n"
+ "Name=Web-Browser";
+ fputs( content.data(), file.fstream() );
+ file.close();
+ }
+ }
+ return;
+ }
+
+ KHTMLPart::urlSelected( url, button, state, target, _args );
+}
+
+#include "konq_aboutpage.moc"
diff --git a/konqueror/about/konq_aboutpage.desktop b/konqueror/about/konq_aboutpage.desktop
new file mode 100644
index 000000000..9c59069cb
--- /dev/null
+++ b/konqueror/about/konq_aboutpage.desktop
@@ -0,0 +1,86 @@
+[Desktop Entry]
+Type=Service
+Name=About-Page for Konqueror
+Name[af]=About-Page vir Konqueror
+Name[ar]=ضفحة حول لِــ Konqueror
+Name[az]=Konqueror Haqqında Səhifəsi
+Name[be]=Інфармацыйная старонка Konqueror
+Name[bg]=Страница с информация за Konqueror
+Name[bn]=কনকরার পরিচিতি পৃষ্ঠা
+Name[br]=Pajenn diwar-benn Konqueror
+Name[bs]=About-stranica za Konqueror
+Name[ca]=Pàgina quant al Konqueror
+Name[cs]=O aplikaci Konqueror
+Name[csb]=Starna "Ò programie" Konquerora
+Name[cy]=Tudalen Ynghylch i Konqueror
+Name[da]='Om'-side for Konqueror
+Name[de]=Über Konqueror
+Name[el]=Σελίδα πληροφοριών για τον Konqueror
+Name[eo]=Informpaĝo por Konkeranto
+Name[es]=Página 'Acerca de' para Konqueror
+Name[et]=Konquerori info
+Name[eu]='Honi buruzko orria' Konquerorrerako
+Name[fa]=صفحۀ درباره برای Konqueror
+Name[fi]=Konquerorin tietoja-sivu
+Name[fr]=À propos de Konqueror
+Name[fy]=Ynformaasjeside foar Konqueror
+Name[ga]=Leathanach Eolais le haghaidh Konqueror
+Name[gl]=Páxina Acerca de Konqueror
+Name[he]=דף אודות Konqueror
+Name[hi]=के-बारे में पृष्ठ कॉन्करर के लिए
+Name[hr]=O programu Konqueror
+Name[hu]=A Konqueror névjegye
+Name[id]=Tentang halaman untuk Konqueror
+Name[is]=Upplýsingasíða Konqueror
+Name[it]=Pagina di informazioni di Konqueror
+Name[ja]=Konqueror のバージョン情報ページ
+Name[ka]=Konqueror-ის ცნობათა ფურცელი
+Name[kk]=Konqueror туралы парақ
+Name[km]=ទំព័រ​អំពី របស់ Konqueror
+Name[ko]=Konqueror 정보 페이지
+Name[lo]=ຫນ້າກ່ງວກັບສຳລັບ Konqueror
+Name[lt]=Apie Konqueror
+Name[lv]=Par-Lapa priekš Iekarotāja
+Name[mk]=Страница за Konqueror
+Name[mn]=Конкюрорын тухай
+Name[ms]=Tentang Halaman untuk Konqueror
+Name[mt]=Paġna dwar Konqueror
+Name[nb]=Om-side for Konqueror
+Name[nds]=Infosiet över Konqueror
+Name[ne]=कन्क्वेररका लागि पृष्ठका बारेमा
+Name[nl]=Informatiepagina voor Konqueror
+Name[nn]=Om-side Konqueror
+Name[nso]=Kaga letlakala la Konqueror
+Name[pa]=ਕੋਨਕਿਉਰੋਰ ਬਾਰੇ ਸਫਾ
+Name[pl]=Strona "O programie" Konquerora
+Name[pt]=Página Acerca do Konqueror
+Name[pt_BR]=Página "Sobre" do Konqueror
+Name[ro]=Pagină informații pentru Konqueror
+Name[ru]=Страница сведений о Konqueror
+Name[rw]=Ibijyanye-Ipaji ya Konqueror
+Name[se]=Diehtusiidu Konqueror várás
+Name[sk]=Stránka o programe Konqueror
+Name[sl]=Stran o Konquerorju
+Name[sr]=Информативна страница о Konqueror-у
+Name[sr@Latn]=Informativna stranica o Konqueror-u
+Name[sv]=Om-sida för Konqueror
+Name[ta]=கான்கொரர்க்கான பக்கம்-பற்றி
+Name[te]=కాంకెరర్ కొరకు గురించి పుట
+Name[tg]=Саҳифаи маълумот дар бораи Konqueror
+Name[th]=หน้าเกี่ยวกับคอนเควอร์เรอร์
+Name[tr]=Konqueror Hakkında Sayfası
+Name[tt]=Konqueror Turında
+Name[uk]=Сторінка "Про" для Konqueror
+Name[uz]=Konqueror haqida sahifa
+Name[uz@cyrillic]=Konqueror ҳақида саҳифа
+Name[ven]=Nga ha siatari la Konqueror
+Name[vi]=Trang giới thiệu của Konqueror
+Name[wa]=Pådje åd fait di Konqueror
+Name[xh]=Malunga-Nephepha le Konqueror
+Name[zh_CN]=Konqueror 的关于页面
+Name[zh_TW]=Konqueror 相關資訊
+Name[zu]=Mayelana-nekhasi le-Konqueror
+ServiceTypes=KonqAboutPage,KParts/ReadOnlyPart
+X-KDE-Library=konq_aboutpage
+X-KDE-BrowserView-HideFromMenus=true
+X-KDE-BrowserView-Built-Into=konqueror
diff --git a/konqueror/about/konq_aboutpage.h b/konqueror/about/konq_aboutpage.h
new file mode 100644
index 000000000..9ec77b5d5
--- /dev/null
+++ b/konqueror/about/konq_aboutpage.h
@@ -0,0 +1,63 @@
+#ifndef __konq_aboutpage_h__
+#define __konq_aboutpage_h__
+
+#include <kparts/factory.h>
+#include <khtml_part.h>
+
+class KHTMLPart;
+class KInstance;
+
+class KonqAboutPageFactory : public KParts::Factory
+{
+public:
+ KonqAboutPageFactory( QObject *parent = 0, const char *name = 0 );
+ virtual ~KonqAboutPageFactory();
+
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name,
+ const char *classname, const QStringList &args );
+
+ static KInstance *instance() { return s_instance; }
+
+ static QString launch();
+ static QString intro();
+ static QString specs();
+ static QString tips();
+ static QString plugins();
+
+private:
+ static QString loadFile( const QString& file );
+
+ static KInstance *s_instance;
+ static QString *s_launch_html, *s_intro_html, *s_specs_html, *s_tips_html, *s_plugins_html;
+};
+
+class KonqAboutPage : public KHTMLPart
+{
+ Q_OBJECT
+public:
+ KonqAboutPage( /*KonqMainWindow *mainWindow,*/
+ QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name );
+ ~KonqAboutPage();
+
+ virtual bool openURL( const KURL &url );
+
+ virtual bool openFile();
+
+ virtual void saveState( QDataStream &stream );
+ virtual void restoreState( QDataStream &stream );
+
+protected:
+ virtual void urlSelected( const QString &url, int button, int state, const QString &target, KParts::URLArgs args = KParts::URLArgs() );
+
+private:
+ void serve( const QString&, const QString& );
+
+ KHTMLPart *m_doc;
+ //KonqMainWindow *m_mainWindow;
+ QString m_htmlDoc;
+ QString m_what;
+};
+
+#endif
diff --git a/konqueror/about/konqaboutpage.desktop b/konqueror/about/konqaboutpage.desktop
new file mode 100644
index 000000000..06d69b794
--- /dev/null
+++ b/konqueror/about/konqaboutpage.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KonqAboutPage
+# No real need for a comment
diff --git a/konqueror/about/launch.html b/konqueror/about/launch.html
new file mode 100644
index 000000000..80ad01eaa
--- /dev/null
+++ b/konqueror/about/launch.html
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st August 2004), see www.w3.org" />
+
+ <style type="text/css">
+ /*<![CDATA[*/
+ @import "%1"; /* kde_infopage.css */
+ %1 /* maybe @import "kde_infopage_rtl.css"; */
+ @import "konq.css";
+ /*]]>*/
+ </style>
+
+ <title>%1</title>
+</head>
+
+<body>
+ <div id="header">
+ <div id="headerL"/>
+ <div id="headerR"/>
+
+ <div id="title">
+ %1 <!-- Konqueror -->
+ </div>
+
+ <div id="tagline">
+ %1 <!-- Conquer your Desktop -->
+ </div>
+ </div>
+
+ <!-- the bar -->
+ <div id="bar">
+ <div id="barT"><div id="barTL"/><div id="barTR"/><div id="barTC"/></div>
+ <div id="barL">
+ <div id="barR">
+ <div id="barCenter" class="bar_text">
+ %1<br />
+ <!-- Konqueror is your file manager, web browser and universal document viewer. -->
+ <ul>
+ <li><a class="selected">%1<!--launch--></a></li>
+ <li><a href="intro.html">%1<!-- intro --></a></li>
+ <li><a href="tips.html">%1</a><!--tips--></li>
+ <li><a href="specs.html">%1<!-- specs --></a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div id="barB"><div id="barBL"/><div id="barBR"/><div id="barBC"/></div>
+ </div>
+
+ <!-- the main text box -->
+ <div id="box">
+ <div id="boxT"><div id="boxTL"/><div id="boxTR"/><div id="boxTC"/></div>
+ <div id="boxL">
+ <div id="boxR">
+ <div id="boxCenter">
+
+ <table border="0" align="center">
+ <tr>
+ <td valign="bottom">
+ <a href="%1"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="%1">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ <td valign="bottom">
+ <a href="media:/"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="media:/">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="remote:/"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="remote:/">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ <td>
+ <a href="trash:/"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="trash:/">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="applications:/"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="applications:/">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ <td>
+ <a href="settings:/"><img src="%1" height="%1" width="%1" /></a>
+ </td>
+ <td valign="bottom">
+ <a href="settings:/">%1</a><br><span id="subtext"><nobr>%1</span>
+ </td>
+ </tr>
+ </table>
+
+ <p id="nextlink"><a href="intro.html"><img src="%1" width="%1" height="%1">&nbsp;%1
+ <!-- Continue --></a></p>
+
+ </div>
+ </div>
+ </div>
+ <div id="boxB"><div id="boxBL"/><div id="boxBR"/><div id="boxBC"/></div>
+ </div>
+
+ <div id="footer"><div id="footerL"/><div id="footerR"/></div>
+</body>
+</html>
+<!-- vim:set sw=2 et nocindent smartindent: -->
diff --git a/konqueror/about/lightning.png b/konqueror/about/lightning.png
new file mode 100644
index 000000000..40bfbcfbb
--- /dev/null
+++ b/konqueror/about/lightning.png
Binary files differ
diff --git a/konqueror/about/plugins.html b/konqueror/about/plugins.html
new file mode 100644
index 000000000..e49b1cf29
--- /dev/null
+++ b/konqueror/about/plugins.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+<title>%1</title>
+<script language="Javascript"> <!--
+function listPlugins() {
+document.write("<table border=\"1\">");
+document.write("<tr>%2</tr>");
+for (i = 0; i < navigator.plugins.length; i++)
+{
+ document.write("<tr><td>"+navigator.plugins[i].name);
+ document.write("</td><td>"+navigator.plugins[i].description);
+ document.write("</td><td>"+navigator.plugins[i].filename);
+ document.write("</td><td><ul>");
+ for (j = 0; j < navigator.plugins[i].length; j++)
+ {
+ document.write("<li>"+navigator.plugins[i][j].type+" - "
+ +navigator.plugins[i][j].description+" ("
+ +navigator.plugins[i][j].suffixes+")</li>");
+ }
+ document.write("</ul></td></tr>");
+}
+document.write("</table>");
+
+document.write("<br/><br/>");
+
+document.write("<table border=\"1\">");
+document.write("<tr>%4</tr>");
+for (i = 0; i < navigator.mimeTypes.length; i++)
+{
+ document.write("<tr><td>"+navigator.mimeTypes[i].type);
+ document.write("</td><td>"+navigator.mimeTypes[i].description);
+ document.write("</td><td>"+navigator.mimeTypes[i].suffixes);
+ if (navigator.mimeTypes[i].enabledPlugin) {
+ document.write("</td><td>");
+ // This could be enhanced to write the plugin name(s) by
+ // searching through navigator.plugins[][]
+ document.write("%3");
+ }
+ document.write("</td></tr>");
+}
+document.write("</table>");
+}
+//--></script>
+</head>
+<body onload="listPlugins();">
+</body>
+</html>
+
diff --git a/konqueror/about/plugins_rtl.html b/konqueror/about/plugins_rtl.html
new file mode 100644
index 000000000..ec7f32a56
--- /dev/null
+++ b/konqueror/about/plugins_rtl.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<style type="text/css"> <!--
+body { direction: rtl; }
+//--></style>
+<title>%1</title>
+<script language="Javascript"> <!--
+function listPlugins() {
+document.write("<table border=\"1\">");
+document.write("<tr>%2</tr>");
+for (i = 0; i < navigator.plugins.length; i++)
+{
+ document.write("<tr><td>"+navigator.plugins[i].name);
+ document.write("</td><td>"+navigator.plugins[i].description);
+ document.write("</td><td>"+navigator.plugins[i].filename);
+ document.write("</td><td><ul>");
+ for (j = 0; j < navigator.plugins[i].length; j++)
+ {
+ document.write("<li>"+navigator.plugins[i][j].type+" - "
+ +navigator.plugins[i][j].description+" ("
+ +navigator.plugins[i][j].suffixes+")</li>");
+ }
+ document.write("</ul></td></tr>");
+}
+document.write("</table>");
+
+document.write("<br/><br/>");
+
+document.write("<table border=\"1\">");
+document.write("<tr>%4</tr>");
+for (i = 0; i < navigator.mimeTypes.length; i++)
+{
+ document.write("<tr><td>"+navigator.mimeTypes[i].type);
+ document.write("</td><td>"+navigator.mimeTypes[i].description);
+ document.write("</td><td>"+navigator.mimeTypes[i].suffixes);
+ if (navigator.mimeTypes[i].enabledPlugin) {
+ document.write("</td><td>");
+ // This could be enhanced to write the plugin name(s) by
+ // searching through navigator.plugins[][]
+ document.write("%3");
+ }
+ document.write("</td></tr>");
+}
+document.write("</table>");
+}
+//--></script>
+</head>
+<body onload="listPlugins();">
+</body>
+</html>
+
diff --git a/konqueror/about/specs.html b/konqueror/about/specs.html
new file mode 100644
index 000000000..b04212067
--- /dev/null
+++ b/konqueror/about/specs.html
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st August 2004), see www.w3.org" />
+
+ <style type="text/css">
+ /*<![CDATA[*/
+ @import "%1"; /* kde_infopage.css */
+ %1 /* maybe @import "kde_infopage_rtl.css"; */
+ @import "konq.css";
+ /*]]>*/
+ </style>
+
+ <title>%1</title>
+</head>
+
+<body>
+ <div id="header">
+ <div id="headerL"/>
+ <div id="headerR"/>
+
+ <div id="title">
+ %1 <!-- Konqueror -->
+ </div>
+
+ <div id="tagline">
+ %1 <!-- Conquer your Desktop -->
+ </div>
+ </div>
+
+ <!-- the bar -->
+ <div id="bar">
+ <div id="barT"><div id="barTL"/><div id="barTR"/><div id="barTC"/></div>
+ <div id="barL">
+ <div id="barR">
+ <div id="barCenter" class="bar_text">
+ %1<br />
+ <!-- Konqueror is your file manager, web browser and universal document viewer. -->
+ <ul>
+ <li><a href="launch.html">%1</a><!--launch--></li>
+ <li><a href="intro.html">%1<!-- intro --></a></li>
+ <li><a href="tips.html">%1<!--tips--></a></li>
+ <li><a class="selected">%1<!-- specs --></a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div id="barB"><div id="barBL"/><div id="barBR"/><div id="barBC"/></div>
+ </div>
+
+ <!-- the main text box -->
+ <div id="box">
+ <div id="boxT"><div id="boxTL"/><div id="boxTR"/><div id="boxTC"/></div>
+ <div id="boxL">
+ <div id="boxR">
+ <div id="boxCenter">
+ <h2 style="margin-top: 0px;">%1<h2><!-- Specifications -->
+ <p>%1 <!-- Konqueror is designed to embrace and support Internet standards.
+ The aim is to fully implement the officially sanctioned standards from
+ organisations such as the W3 and OASIS, while also adding extra support for other
+ common usability features that arise as de facto standards across the internet.
+ Along with this support, for such functions as favicons, Internet Keywords,
+ and XBEL bookmarks, Konqueror also implements: -->
+ </p>
+
+ <table bgcolor="#ffffff" border="1" cellspacing="0" cellpadding="1"
+ width="100%">
+ <tr align="left" valign="middle" bgcolor="#505050" height="6">
+ <td style="color: white">
+ &nbsp;%1 <!-- Web Browsing -->
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr bgcolor="#DADADA">
+ <th width="40%">%1 <!--Supported standards--></th>
+ <th width="2%">&nbsp;</th>
+ <th width="58%">%1 <!--Additional requirements*--></th>
+ </tr>
+ <tr bgcolor="#fff4c9">
+ <td valign="top">%1 <!--DOM (Level 1, partially Level 2) based HTML 4.01</A>--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">%1 <!--built-in--></td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td valign="top">%1 <!--Cascading Style Sheets (CSS 1, partially CSS 2)--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">%1 <!--built-in--></td>
+ </tr>
+ <tr bgcolor="#fff4c9">
+ <td valign="top">%1 <!--ECMA-262 Edition 3 (equals roughly Javascript 1.5)--></td>
+ <td valign="top">&nbsp;</td>
+ <noscript>
+ <td valign="top">%1 <!-- Javascript disabled [...] --></td>
+ </noscript>
+ <script language="Javascript">
+ document.write("<td>%1</td>"); // Javascript enabled [...]
+ </script>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td valign="top">%1 <!--Secure Java support--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">
+ %1<!--JDK 1.2.0 (Java 2) compatible VM (Blackdown, IBM or Sun)--><br>
+ %1<!--Enable Java (globally) here-->
+ </td>
+ </tr>
+ <tr bgcolor="#fff4c9">
+ <td valign="top">%1<!-- Netscape Communicator plugins (for viewing Flash, RealAudio, RealVideo etc.)--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">%1<!-- built-in--></t#d>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td valign="top"><a href="http://www.netscape.com/eng/ssl3/">%1<!--Secure Sockets Layer--></a> %1<!--(TLS/SSL v2/3) for secure communications up to 168bit--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top"><a href="http://www.openssl.org">%1<!--OpenSSL--></a></td>
+ </tr>
+ <tr bgcolor="#fff4c9">
+ <td valign="top">%1<!--Bidirectional 16bit unicode support--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">%1<!--built-in--></td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td valign="top">%1<!--AutoCompletion for forms--></td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">%1<!--built-in--></a></td>
+ </tr>
+ </table>
+ </td>
+ </td>
+ </table>
+ <p/>
+ <table bgcolor="#ffffff" border="1" cellspacing="0" cellpadding="1"
+ width="100%">
+ <tr align="left" valign="middle" bgcolor="#505050" height="6">
+ <td style="color: white">
+ %1 <!-- G E N E R A L -->
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr bgcolor="#dadada">
+ <th width="40%">%1 <!--Supported standards--></th>
+ <th width="2%">&nbsp;</th>
+ <th width="58%">%1 <!--Additional requirements*--></th>
+ </tr>
+
+ <tr bgcolor="#ffffff">
+ <td valign="top">
+ %1<!--Image formats:-->
+ </td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">
+ PNG<br>
+ MNG<br>
+ JPG<br>
+ GIF
+ </td>
+ </tr>
+ <tr bgcolor="#fff4c9">
+ <td valign="top"> %1<!--Transfer protocols:-->
+ </td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">
+ %1<!--HTTP 1.1 (including gzip/bzip2 compression)--><br>
+ %1<!--FTP--><br>
+ %1<!--and many more...--></li>
+ </ul>
+ </td>
+ </tr>
+ <tr bgcolor="#ffffff">
+ <td valign="top">
+ %1<!--URL Completion:-->
+ </td>
+ <td valign="top">&nbsp;</td>
+ <td valign="top">
+ %1<!-- Manual --><br>
+ %1<!-- Popup --><br>
+ %1<!-- (Short-) Automatic --></li></ul>
+ </td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+ </table>
+
+ <p id="nextlink">
+ <a href="intro.html">%1&nbsp;%1<!-- Back to the Introduction --></a>
+ </p>
+ </div>
+ </div>
+ </div>
+ <div id="boxB"><div id="boxBL"/><div id="boxBR"/><div id="boxBC"/></div>
+ </div>
+
+ <div id="footer"><div id="footerL"/><div id="footerR"/></div>
+</body>
+</html>
+<!-- vim:set sw=2 et nocindent smartindent: -->
diff --git a/konqueror/about/tips.html b/konqueror/about/tips.html
new file mode 100644
index 000000000..7679d9807
--- /dev/null
+++ b/konqueror/about/tips.html
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st August 2004), see www.w3.org" />
+
+ <style type="text/css">
+ /*<![CDATA[*/
+ @import "%1"; /* kde_infopage.css */
+ %1 /* maybe @import "kde_infopage_rtl.css"; */
+ @import "konq.css";
+ /*]]>*/
+ </style>
+
+ <title>%1</title>
+</head>
+
+<body>
+ <div id="header">
+ <div id="headerL"/>
+ <div id="headerR"/>
+
+ <div id="title">
+ %1 <!-- Konqueror -->
+ </div>
+
+ <div id="tagline">
+ %1 <!-- Conquer your Desktop -->
+ </div>
+ </div>
+
+ <!-- the bar -->
+ <div id="bar">
+ <div id="barT"><div id="barTL"/><div id="barTR"/><div id="barTC"/></div>
+ <div id="barL">
+ <div id="barR">
+ <div id="barCenter" class="bar_text">
+ %1<br />
+ <!-- Konqueror is your file manager, web browser and universal document viewer. -->
+ <ul>
+ <li><a href="launch.html">%1</a><!--launch--></li>
+ <li><a href="intro.html">%1<!-- intro --></a></li>
+ <li><a class="selected">%1<!--tips--></a></li>
+ <li><a href="specs.html">%1<!-- specs --></a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div id="barB"><div id="barBL"/><div id="barBR"/><div id="barBC"/></div>
+ </div>
+
+ <!-- the main text box -->
+ <div id="box">
+ <div id="boxT"><div id="boxTL"/><div id="boxTR"/><div id="boxTC"/></div>
+ <div id="boxL">
+ <div id="boxR">
+ <div id="boxCenter">
+ <h2 style="margin-top: 0px;">%1<!--Tips--></h2>
+
+ <ul>
+ <li>%1
+ <!--Use Internet-Keywords! By typing "gg:KDE" one can search the internet
+ using google for the search phrase "KDE". There are a lot of
+ internet-shortcuts predefined to make searching for software or looking up
+ certain words in an encyclopedia a breeze. And you can even
+ create your own internet-keywords!--></li>
+
+ <li>%1
+ <!--Use the magnifier toolbar-buttons to increase the
+ fontsize on your webpage.--></li>
+
+ <li>%1
+ <!--When you want to paste a new address into the URL-bar you might want to
+ clear the current entry by pressing the white-crossed black arrow in the
+ toolbar.--></li>
+
+ <li>%1
+ <!--To create a link on your desktop pointing to the current page,
+ simply drag the "Location" label that is on the left of the Location Toolbar, drop it onto
+ the desktop, and choose "Link"--></li>
+
+ <li>%1
+ <!--You can also find the "Fullscreen Mode" in the Settings-Menu. This Feature
+ is very useful for "talk" sessions.--></li>
+
+ <li>%1
+ <!--Divide et impera (lat. "Divide and Konquer") - by splitting a window
+ into two Parts (e.g. Window -> Split View Left/Right) you can make konqueror
+ appear the way you like. You can even Load some example view-profiles
+ (e.g. Midnight-Commander), or create your own ones.--></li>
+
+ <li>%1
+ <!--Use the user-agent feature if the website you're visiting asks you to
+ use a different browser (and don't forget to send a complaint to the
+ webmaster!)--></li>
+
+ <li>%1
+ <!--The History in your Sidebar makes sure that you will keep track of the
+ pages you have visited recently.--></li>
+
+ <li>%1
+ <!--Use a caching proxy to speed up your internet-connection.--></li>
+
+ <li>%1
+ <!--Advanced users will appreciate the konsole which you can embed into
+ konqueror (Window -> Show Terminal Emulator).--></li>
+
+ <li>%1
+ <!--Thanks to DCOP you can have full control over Konqueror using a script.--></li>
+ </ul>
+
+ <p id="nextlink"><a href="specs.html">%1&nbsp;%1
+ <!-- Continue --></a></p>
+ </div>
+ </div>
+ </div>
+ <div id="boxB"><div id="boxBL"/><div id="boxBR"/><div id="boxBC"/></div>
+ </div>
+
+ <div id="footer"><div id="footerL"/><div id="footerR"/></div>
+</body>
+</html>
+<!-- vim:set sw=2 et nocindent smartindent: -->
diff --git a/konqueror/about/top-right-konqueror.png b/konqueror/about/top-right-konqueror.png
new file mode 100644
index 000000000..7c4c5ab58
--- /dev/null
+++ b/konqueror/about/top-right-konqueror.png
Binary files differ
diff --git a/konqueror/client/ChangeLog b/konqueror/client/ChangeLog
new file mode 100644
index 000000000..a32836ebf
--- /dev/null
+++ b/konqueror/client/ChangeLog
@@ -0,0 +1,14 @@
+1999-11-08 Kurt Granroth <granroth@kde.org>
+ * if 'exec' has no parameters, popup the Execute Command
+ dialog from kdesktop
+
+1999-05-28 Simon Hausmann <hausmann@kde.org>
+
+ * use kded instead of the ior file
+ * use KOMApplication instead of OPApplication (no need for
+ OpenParts at all)
+
+1999-04-28 Christophe Prud'homme <Christophe.Prudhomme@ann.jussieu.fr>
+
+ * Makefile.am: $(top_srcdir) to $(top_builddir)
+
diff --git a/konqueror/client/Makefile.am b/konqueror/client/Makefile.am
new file mode 100644
index 000000000..97a5b66e4
--- /dev/null
+++ b/konqueror/client/Makefile.am
@@ -0,0 +1,23 @@
+AM_CPPFLAGS = -DQT_NO_CAST_ASCII
+
+bin_PROGRAMS=
+lib_LTLIBRARIES =
+kdeinit_LTLIBRARIES = kfmclient.la
+
+INCLUDES= -I.. $(all_includes)
+kfmclient_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kfmclient_la_LIBADD = $(LIB_KIO)
+kfmclient_la_SOURCES = kfmclient.cc KonquerorIface.stub KDesktopIface.stub
+
+noinst_HEADERS = kfmclient.h
+METASOURCES = AUTO
+
+KonquerorIface_DIR = $(srcdir)/..
+KDesktopIface_DIR = $(top_srcdir)/kdesktop
+
+messages:
+ $(XGETTEXT) -kaliasLocal *.h *.cc -o $(podir)/kfmclient.pot
+
+updatedir = $(kde_datadir)/kconf_update
+update_DATA = kfmclient_3_2.upd
+update_SCRIPTS = kfmclient_3_2_update.sh
diff --git a/konqueror/client/kfmclient.cc b/konqueror/client/kfmclient.cc
new file mode 100644
index 000000000..f60c48dbe
--- /dev/null
+++ b/konqueror/client/kfmclient.cc
@@ -0,0 +1,643 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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 <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <qdir.h>
+
+#include <kio/job.h>
+#include <kcmdlineargs.h>
+#include <kpropertiesdialog.h>
+#include <klocale.h>
+#include <ktrader.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <kopenwith.h>
+#include <kurlrequesterdlg.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <kdebug.h>
+#include <dcopclient.h>
+#include <kservice.h>
+#include <qregexp.h>
+
+#include "kfmclient.h"
+#include "KonquerorIface_stub.h"
+#include "KDesktopIface_stub.h"
+#include "kwin.h"
+
+#include <X11/Xlib.h>
+
+static const char appName[] = "kfmclient";
+static const char programName[] = I18N_NOOP("kfmclient");
+
+static const char description[] = I18N_NOOP("KDE tool for opening URLs from the command line");
+
+static const char version[] = "2.0";
+
+QCString clientApp::startup_id_str;
+bool clientApp::m_ok = true;
+bool s_interactive = true;
+
+static const KCmdLineOptions options[] =
+{
+ { "noninteractive", I18N_NOOP("Non interactive use: no message boxes"), 0},
+ { "commands", I18N_NOOP("Show available commands"), 0},
+ { "+command", I18N_NOOP("Command (see --commands)"), 0},
+ { "+[URL(s)]", I18N_NOOP("Arguments for command"), 0},
+ KCmdLineLastOption
+};
+
+extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
+{
+ KCmdLineArgs::init(argc, argv, appName, programName, description, version, false);
+
+ KCmdLineArgs::addCmdLineOptions( options );
+ KCmdLineArgs::addTempFileOption();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if ( args->isSet("commands") )
+ {
+ KCmdLineArgs::enable_i18n();
+ puts(i18n("\nSyntax:\n").local8Bit());
+ puts(i18n(" kfmclient openURL 'url' ['mimetype']\n"
+ " # Opens a window showing 'url'.\n"
+ " # 'url' may be a relative path\n"
+ " # or file name, such as . or subdir/\n"
+ " # If 'url' is omitted, $HOME is used instead.\n\n").local8Bit());
+ puts(i18n(" # If 'mimetype' is specified, it will be used to determine the\n"
+ " # component that Konqueror should use. For instance, set it to\n"
+ " # text/html for a web page, to make it appear faster\n\n").local8Bit());
+
+ puts(i18n(" kfmclient newTab 'url' ['mimetype']\n"
+ " # Same as above but opens a new tab with 'url' in an existing Konqueror\n"
+ " # window on the current active desktop if possible.\n\n").local8Bit());
+
+ puts(i18n(" kfmclient openProfile 'profile' ['url']\n"
+ " # Opens a window using the given profile.\n"
+ " # 'profile' is a file under ~/.kde/share/apps/konqueror/profiles.\n"
+ " # 'url' is an optional URL to open.\n\n").local8Bit());
+
+ puts(i18n(" kfmclient openProperties 'url'\n"
+ " # Opens a properties menu\n\n").local8Bit());
+ puts(i18n(" kfmclient exec ['url' ['binding']]\n"
+ " # Tries to execute 'url'. 'url' may be a usual\n"
+ " # URL, this URL will be opened. You may omit\n"
+ " # 'binding'. In this case the default binding\n").local8Bit());
+ puts(i18n(" # is tried. Of course URL may be the URL of a\n"
+ " # document, or it may be a *.desktop file.\n").local8Bit());
+ puts(i18n(" # This way you could for example mount a device\n"
+ " # by passing 'Mount default' as binding to \n"
+ " # 'cdrom.desktop'\n\n").local8Bit());
+ puts(i18n(" kfmclient move 'src' 'dest'\n"
+ " # Moves the URL 'src' to 'dest'.\n"
+ " # 'src' may be a list of URLs.\n").local8Bit());
+ //puts(i18n(" # 'dest' may be \"trash:/\" to move the files\n"
+ // " # in the trash bin.\n\n").local8Bit());
+ puts(i18n(" kfmclient download ['src']\n"
+ " # Copies the URL 'src' to a user specified location'.\n"
+ " # 'src' may be a list of URLs, if not present then\n"
+ " # a URL will be requested.\n\n").local8Bit());
+ puts(i18n(" kfmclient copy 'src' 'dest'\n"
+ " # Copies the URL 'src' to 'dest'.\n"
+ " # 'src' may be a list of URLs.\n\n").local8Bit());
+ puts(i18n(" kfmclient sortDesktop\n"
+ " # Rearranges all icons on the desktop.\n\n").local8Bit());
+ puts(i18n(" kfmclient configure\n"
+ " # Re-read Konqueror's configuration.\n\n").local8Bit());
+ puts(i18n(" kfmclient configureDesktop\n"
+ " # Re-read kdesktop's configuration.\n\n").local8Bit());
+
+ puts(i18n("*** Examples:\n"
+ " kfmclient exec file:/root/Desktop/cdrom.desktop \"Mount default\"\n"
+ " // Mounts the CD-ROM\n\n").local8Bit());
+ puts(i18n(" kfmclient exec file:/home/weis/data/test.html\n"
+ " // Opens the file with default binding\n\n").local8Bit());
+ puts(i18n(" kfmclient exec file:/home/weis/data/test.html Netscape\n"
+ " // Opens the file with netscape\n\n").local8Bit());
+ puts(i18n(" kfmclient exec ftp://localhost/\n"
+ " // Opens new window with URL\n\n").local8Bit());
+ puts(i18n(" kfmclient exec file:/root/Desktop/emacs.desktop\n"
+ " // Starts emacs\n\n").local8Bit());
+ puts(i18n(" kfmclient exec file:/root/Desktop/cdrom.desktop\n"
+ " // Opens the CD-ROM's mount directory\n\n").local8Bit());
+ puts(i18n(" kfmclient exec .\n"
+ " // Opens the current directory. Very convenient.\n\n").local8Bit());
+ return 0;
+ }
+
+ return clientApp::doIt() ? 0 /*no error*/ : 1 /*error*/;
+}
+
+/*
+ Whether to start a new konqueror or reuse an existing process.
+
+ First of all, this concept is actually broken, as the view used to show
+ the data may change at any time, and therefore Konqy reused to browse
+ "safe" data may eventually browse something completely different.
+ Moreover, it's quite difficult to find out when to reuse, and thus this
+ function is an ugly hack. You've been warned.
+
+ Kfmclient will attempt to find an instance for reusing if either reusing
+ is configured to reuse always,
+ or it's not configured to never reuse, and the URL to-be-opened is "safe".
+ The URL is safe, if the view used to view it is listed in the allowed KPart's.
+ In order to find out the part, mimetype is needed, and KTrader is needed.
+ If mimetype is not known, KMimeType is used (which doesn't work e.g. for remote
+ URLs, but oh well). Since this function may be running without a KApplication
+ instance, I'm actually quite surprised it works, and it may sooner or later break.
+ Nice, isn't it?
+
+ If a profile is being used, and no url has been explicitly given, it needs to be
+ read from the profile. If there's more than one URL listed in the profile, no reusing
+ will be done (oh well), if there's no URL, no reusing will be done either (also
+ because the webbrowsing profile doesn't have any URL listed).
+*/
+static bool startNewKonqueror( QString url, QString mimetype, const QString& profile )
+{
+ KConfig cfg( QString::fromLatin1( "konquerorrc" ), true );
+ cfg.setGroup( "Reusing" );
+ QStringList allowed_parts;
+ // is duplicated in ../KonquerorIface.cc
+ allowed_parts << QString::fromLatin1( "konq_iconview.desktop" )
+ << QString::fromLatin1( "konq_multicolumnview.desktop" )
+ << QString::fromLatin1( "konq_sidebartng.desktop" )
+ << QString::fromLatin1( "konq_infolistview.desktop" )
+ << QString::fromLatin1( "konq_treeview.desktop" )
+ << QString::fromLatin1( "konq_detailedlistview.desktop" );
+ if( cfg.hasKey( "SafeParts" )
+ && cfg.readEntry( "SafeParts" ) != QString::fromLatin1( "SAFE" ))
+ allowed_parts = cfg.readListEntry( "SafeParts" );
+ if( allowed_parts.count() == 1 && allowed_parts.first() == QString::fromLatin1( "ALL" ))
+ return false; // all parts allowed
+ if( url.isEmpty())
+ {
+ if( profile.isEmpty())
+ return true;
+ QString profilepath = locate( "data", QString::fromLatin1("konqueror/profiles/") + profile );
+ if( profilepath.isEmpty())
+ return true;
+ KConfig cfg( profilepath, true );
+ cfg.setDollarExpansion( true );
+ cfg.setGroup( "Profile" );
+ QMap< QString, QString > entries = cfg.entryMap( QString::fromLatin1( "Profile" ));
+ QRegExp urlregexp( QString::fromLatin1( "^View[0-9]*_URL$" ));
+ QStringList urls;
+ for( QMap< QString, QString >::ConstIterator it = entries.begin();
+ it != entries.end();
+ ++it )
+ {
+ // don't read value from map, dollar expansion is needed
+ QString value = cfg.readEntry( it.key());
+ if( urlregexp.search( it.key()) >= 0 && !value.isEmpty())
+ urls << value;
+ }
+ if( urls.count() != 1 )
+ return true;
+ url = urls.first();
+ mimetype = QString::fromLatin1( "" );
+ }
+ if( mimetype.isEmpty())
+ mimetype = KMimeType::findByURL( KURL( url ) )->name();
+ KTrader::OfferList offers = KTrader::self()->query( mimetype, QString::fromLatin1( "KParts/ReadOnlyPart" ),
+ QString::null, QString::null );
+ KService::Ptr serv;
+ if( offers.count() > 0 )
+ serv = offers.first();
+ return serv == NULL || !allowed_parts.contains( serv->desktopEntryName() + QString::fromLatin1(".desktop") );
+}
+
+static int currentScreen()
+{
+ if( qt_xdisplay() != NULL )
+ return qt_xscreen();
+ // case when there's no KApplication instance
+ const char* env = getenv( "DISPLAY" );
+ if( env == NULL )
+ return 0;
+ const char* dotpos = strrchr( env, '.' );
+ const char* colonpos = strrchr( env, ':' );
+ if( dotpos != NULL && colonpos != NULL && dotpos > colonpos )
+ return atoi( dotpos + 1 );
+ return 0;
+}
+
+// when reusing a preloaded konqy, make sure your always use a DCOP call which opens a profile !
+static QCString getPreloadedKonqy()
+{
+ KConfig cfg( QString::fromLatin1( "konquerorrc" ), true );
+ cfg.setGroup( "Reusing" );
+ if( cfg.readNumEntry( "MaxPreloadCount", 1 ) == 0 )
+ return "";
+ DCOPRef ref( "kded", "konqy_preloader" );
+ QCString ret;
+ if( ref.callExt( "getPreloadedKonqy", DCOPRef::NoEventLoop, 3000, currentScreen()).get( ret ))
+ return ret;
+ return QCString();
+}
+
+
+static QCString konqyToReuse( const QString& url, const QString& mimetype, const QString& profile )
+{ // prefer(?) preloaded ones
+ QCString ret = getPreloadedKonqy();
+ if( !ret.isEmpty())
+ return ret;
+ if( startNewKonqueror( url, mimetype, profile ))
+ return "";
+ QCString appObj;
+ QByteArray data;
+ QDataStream str( data, IO_WriteOnly );
+ str << currentScreen();
+ if( !KApplication::dcopClient()->findObject( "konqueror*", "KonquerorIface",
+ "processCanBeReused( int )", data, ret, appObj, false, 3000 ) )
+ return "";
+ return ret;
+}
+
+static bool krun_has_error = false;
+
+void clientApp::sendASNChange()
+{
+ KStartupInfoId id;
+ id.initId( startup_id_str );
+ KStartupInfoData data;
+ data.addPid( 0 ); // say there's another process for this ASN with unknown PID
+ data.setHostname(); // ( no need to bother to get this konqy's PID )
+ Display* dpy = qt_xdisplay();
+ if( dpy == NULL ) // we may be running without QApplication here
+ dpy = XOpenDisplay( NULL );
+ if( dpy != NULL )
+ KStartupInfo::sendChangeX( dpy, id, data );
+ if( dpy != NULL && dpy != qt_xdisplay())
+ XCloseDisplay( dpy );
+}
+
+bool clientApp::createNewWindow(const KURL & url, bool newTab, bool tempFile, const QString & mimetype)
+{
+ kdDebug( 1202 ) << "clientApp::createNewWindow " << url.url() << " mimetype=" << mimetype << endl;
+ // check if user wants to use external browser
+ // ###### this option seems to have no GUI and to be redundant with BrowserApplication now.
+ // ###### KDE4: remove
+ KConfig config( QString::fromLatin1("kfmclientrc"));
+ config.setGroup( QString::fromLatin1("Settings"));
+ QString strBrowser = config.readPathEntry("ExternalBrowser");
+ if (!strBrowser.isEmpty())
+ {
+ if ( tempFile )
+ kdWarning() << "kfmclient used with --tempfile but is passing to an external browser! Tempfile will never be deleted" << endl;
+ KProcess proc;
+ proc << strBrowser << url.url();
+ proc.start( KProcess::DontCare );
+ return true;
+ }
+
+ if (url.protocol().startsWith(QString::fromLatin1("http")))
+ {
+ config.setGroup("General");
+ if (!config.readEntry("BrowserApplication").isEmpty())
+ {
+ clientApp app;
+ KStartupInfo::appStarted();
+
+ KRun * run = new KRun( url, 0, 0, false, false /* no progress window */ ); // TODO pass tempFile [needs support in the KRun ctor]
+ QObject::connect( run, SIGNAL( finished() ), &app, SLOT( delayedQuit() ));
+ QObject::connect( run, SIGNAL( error() ), &app, SLOT( delayedQuit() ));
+ app.exec();
+ return !krun_has_error;
+ }
+ }
+
+ KConfig cfg( QString::fromLatin1( "konquerorrc" ), true );
+ cfg.setGroup( "FMSettings" );
+ if ( newTab || cfg.readBoolEntry( "KonquerorTabforExternalURL", false ) )
+ {
+ QCString foundApp, foundObj;
+ QByteArray data;
+ QDataStream str( data, IO_WriteOnly );
+ if( KApplication::dcopClient()->findObject( "konqueror*", "konqueror-mainwindow*",
+ "windowCanBeUsedForTab()", data, foundApp, foundObj, false, 3000 ) )
+ {
+ DCOPRef ref( foundApp, foundObj );
+ DCOPReply reply = ref.call( "newTabASN", url.url(), startup_id_str, tempFile );
+ if ( reply.isValid() ) {
+ sendASNChange();
+ return true;
+ }
+ }
+ }
+
+ QCString appId = konqyToReuse( url.url(), mimetype, QString::null );
+ if( !appId.isEmpty())
+ {
+ kdDebug( 1202 ) << "clientApp::createNewWindow using existing konqueror" << endl;
+ KonquerorIface_stub konqy( appId, "KonquerorIface" );
+ konqy.createNewWindowASN( url.url(), mimetype, startup_id_str, tempFile );
+ sendASNChange();
+ }
+ else
+ {
+ QString error;
+ /* Well, we can't pass a mimetype through startServiceByDesktopPath !
+ if ( KApplication::startServiceByDesktopPath( QString::fromLatin1("konqueror.desktop"),
+ url.url(), &error ) > 0 )
+ {
+ kdError() << "Couldn't start konqueror from konqueror.desktop: " << error << endl;
+ */
+ // pass kfmclient's startup id to konqueror using kshell
+ KStartupInfoId id;
+ id.initId( startup_id_str );
+ id.setupStartupEnv();
+ KProcess proc;
+ proc << "kshell" << "konqueror";
+ if ( !mimetype.isEmpty() )
+ proc << "-mimetype" << mimetype;
+ if ( tempFile )
+ proc << "-tempfile";
+ proc << url.url();
+ proc.start( KProcess::DontCare );
+ KStartupInfo::resetStartupEnv();
+ kdDebug( 1202 ) << "clientApp::createNewWindow KProcess started" << endl;
+ //}
+ }
+ return true;
+}
+
+bool clientApp::openProfile( const QString & profileName, const QString & url, const QString & mimetype )
+{
+ QCString appId = konqyToReuse( url, mimetype, profileName );
+ if( appId.isEmpty())
+ {
+ QString error;
+ if ( KApplication::startServiceByDesktopPath( QString::fromLatin1("konqueror.desktop"),
+ QString::fromLatin1("--silent"), &error, &appId, NULL, startup_id_str ) > 0 )
+ {
+ kdError() << "Couldn't start konqueror from konqueror.desktop: " << error << endl;
+ return false;
+ }
+ // startServiceByDesktopPath waits for the app to register with DCOP
+ // so when we arrive here, konq is up and running already, and appId contains the identification
+ }
+
+ QString profile = locate( "data", QString::fromLatin1("konqueror/profiles/") + profileName );
+ if ( profile.isEmpty() )
+ {
+ fprintf( stderr, "%s", i18n("Profile %1 not found\n").arg(profileName).local8Bit().data() );
+ ::exit( 0 );
+ }
+ KonquerorIface_stub konqy( appId, "KonquerorIface" );
+ if ( url.isEmpty() )
+ konqy.createBrowserWindowFromProfileASN( profile, profileName, startup_id_str );
+ else if ( mimetype.isEmpty() )
+ konqy.createBrowserWindowFromProfileAndURLASN( profile, profileName, url, startup_id_str );
+ else
+ konqy.createBrowserWindowFromProfileAndURLASN( profile, profileName, url, mimetype, startup_id_str );
+ sleep(2); // Martin Schenk <martin@schenk.com> says this is necessary to let the server read from the socket
+ sendASNChange();
+ return true;
+}
+
+void clientApp::delayedQuit()
+{
+ // Quit in 2 seconds. This leaves time for KRun to pop up
+ // "app not found" in KProcessRunner, if that was the case.
+ QTimer::singleShot( 2000, this, SLOT(deref()) );
+ // don't access the KRun instance later, it will be deleted after calling slots
+ if( static_cast< const KRun* >( sender())->hasError())
+ krun_has_error = true;
+}
+
+static void checkArgumentCount(int count, int min, int max)
+{
+ if (count < min)
+ {
+ fputs( i18n("Syntax Error: Not enough arguments\n").local8Bit(), stderr );
+ ::exit(1);
+ }
+ if (max && (count > max))
+ {
+ fputs( i18n("Syntax Error: Too many arguments\n").local8Bit(), stderr );
+ ::exit(1);
+ }
+}
+
+bool clientApp::doIt()
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ int argc = args->count();
+ checkArgumentCount(argc, 1, 0);
+
+ if ( !args->isSet( "ninteractive" ) ) {
+ s_interactive = false;
+ }
+ QCString command = args->arg(0);
+
+ // read ASN env. variable for non-KApp cases
+ startup_id_str = KStartupInfo::currentStartupIdEnv().id();
+
+ if ( command == "openURL" || command == "newTab" )
+ {
+ KInstance inst(appName);
+ if( !KApplication::dcopClient()->attach())
+ {
+ KApplication::startKdeinit();
+ KApplication::dcopClient()->attach();
+ }
+ checkArgumentCount(argc, 1, 3);
+ bool tempFile = KCmdLineArgs::isTempFileSet();
+ if ( argc == 1 )
+ {
+ KURL url;
+ url.setPath(QDir::homeDirPath());
+ return createNewWindow( url, command == "newTab", tempFile );
+ }
+ if ( argc == 2 )
+ {
+ return createNewWindow( args->url(1), command == "newTab", tempFile );
+ }
+ if ( argc == 3 )
+ {
+ return createNewWindow( args->url(1), command == "newTab", tempFile, QString::fromLatin1(args->arg(2)) );
+ }
+ }
+ else if ( command == "openProfile" )
+ {
+ KInstance inst(appName);
+ if( !KApplication::dcopClient()->attach())
+ {
+ KApplication::startKdeinit();
+ KApplication::dcopClient()->attach();
+ }
+ checkArgumentCount(argc, 2, 3);
+ QString url;
+ if ( argc == 3 )
+ url = args->url(2).url();
+ return openProfile( QString::fromLocal8Bit(args->arg(1)), url );
+ }
+
+ // the following commands need KApplication
+ clientApp app;
+
+ if ( command == "openProperties" )
+ {
+ checkArgumentCount(argc, 2, 2);
+ KPropertiesDialog * p = new KPropertiesDialog( args->url(1) );
+ QObject::connect( p, SIGNAL( destroyed() ), &app, SLOT( quit() ));
+ QObject::connect( p, SIGNAL( canceled() ), &app, SLOT( slotDialogCanceled() ));
+ app.exec();
+ return m_ok;
+ }
+ else if ( command == "exec" )
+ {
+ checkArgumentCount(argc, 1, 3);
+ if ( argc == 1 )
+ {
+ KDesktopIface_stub kdesky( "kdesktop", "KDesktopIface" );
+ kdesky.popupExecuteCommand();
+ }
+ else if ( argc == 2 )
+ {
+ KRun * run = new KRun( args->url(1), 0, 0, false, false /* no progress window */ );
+ QObject::connect( run, SIGNAL( finished() ), &app, SLOT( delayedQuit() ));
+ QObject::connect( run, SIGNAL( error() ), &app, SLOT( delayedQuit() ));
+ app.exec();
+ return !krun_has_error;
+ }
+ else if ( argc == 3 )
+ {
+ KURL::List urls;
+ urls.append( args->url(1) );
+ const KTrader::OfferList offers = KTrader::self()->query( QString::fromLocal8Bit( args->arg( 2 ) ), QString::fromLatin1( "Application" ), QString::null, QString::null );
+ if (offers.isEmpty()) return 1;
+ KService::Ptr serv = offers.first();
+ return KRun::run( *serv, urls );
+ }
+ }
+ else if ( command == "move" )
+ {
+ checkArgumentCount(argc, 2, 0);
+ KURL::List srcLst;
+ for ( int i = 1; i <= argc - 2; i++ )
+ srcLst.append( args->url(i) );
+
+ KIO::Job * job = KIO::move( srcLst, args->url(argc - 1) );
+ if ( !s_interactive )
+ job->setInteractive( false );
+ connect( job, SIGNAL( result( KIO::Job * ) ), &app, SLOT( slotResult( KIO::Job * ) ) );
+ app.exec();
+ return m_ok;
+ }
+ else if ( command == "download" )
+ {
+ checkArgumentCount(argc, 0, 0);
+ KURL::List srcLst;
+ if (argc == 1) {
+ while(true) {
+ KURL src = KURLRequesterDlg::getURL();
+ if (!src.isEmpty()) {
+ if (!src.isValid()) {
+ KMessageBox::error(0, i18n("Unable to download from an invalid URL."));
+ continue;
+ }
+ srcLst.append(src);
+ }
+ break;
+ }
+ } else {
+ for ( int i = 1; i <= argc - 1; i++ )
+ srcLst.append( args->url(i) );
+ }
+ if (srcLst.count() == 0)
+ return m_ok;
+ QString dst =
+ KFileDialog::getSaveFileName( (argc<2) ? (QString::null) : (args->url(1).filename()) );
+ if (dst.isEmpty()) // cancelled
+ return m_ok; // AK - really okay?
+ KURL dsturl;
+ dsturl.setPath( dst );
+ KIO::Job * job = KIO::copy( srcLst, dsturl );
+ if ( !s_interactive )
+ job->setInteractive( false );
+ connect( job, SIGNAL( result( KIO::Job * ) ), &app, SLOT( slotResult( KIO::Job * ) ) );
+ app.exec();
+ return m_ok;
+ }
+ else if ( command == "copy" )
+ {
+ checkArgumentCount(argc, 2, 0);
+ KURL::List srcLst;
+ for ( int i = 1; i <= argc - 2; i++ )
+ srcLst.append( args->url(i) );
+
+ KIO::Job * job = KIO::copy( srcLst, args->url(argc - 1) );
+ if ( !s_interactive )
+ job->setInteractive( false );
+ connect( job, SIGNAL( result( KIO::Job * ) ), &app, SLOT( slotResult( KIO::Job * ) ) );
+ app.exec();
+ return m_ok;
+ }
+ else if ( command == "sortDesktop" )
+ {
+ checkArgumentCount(argc, 1, 1);
+
+ KDesktopIface_stub kdesky( "kdesktop", "KDesktopIface" );
+ kdesky.rearrangeIcons( (int)false );
+
+ return true;
+ }
+ else if ( command == "configure" )
+ {
+ checkArgumentCount(argc, 1, 1);
+ QByteArray data;
+ kapp->dcopClient()->send( "*", "KonqMainViewIface", "reparseConfiguration()", data );
+ // Warning. In case something is added/changed here, keep kcontrol/konq/main.cpp in sync.
+ }
+ else if ( command == "configureDesktop" )
+ {
+ checkArgumentCount(argc, 1, 1);
+ KDesktopIface_stub kdesky( "kdesktop", "KDesktopIface" );
+ kdesky.configure();
+ }
+ else
+ {
+ fprintf( stderr, "%s", i18n("Syntax Error: Unknown command '%1'\n").arg(QString::fromLocal8Bit(command)).local8Bit().data() );
+ return false;
+ }
+ return true;
+}
+
+void clientApp::slotResult( KIO::Job * job )
+{
+ if (job->error() && s_interactive)
+ job->showErrorDialog();
+ m_ok = !job->error();
+ quit();
+}
+
+void clientApp::slotDialogCanceled()
+{
+ m_ok = false;
+ quit();
+}
+
+#include "kfmclient.moc"
diff --git a/konqueror/client/kfmclient.h b/konqueror/client/kfmclient.h
new file mode 100644
index 000000000..0d13a6e8c
--- /dev/null
+++ b/konqueror/client/kfmclient.h
@@ -0,0 +1,51 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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.
+*/
+
+#ifndef __kfmclient_h
+#define __kfmclient_h
+
+#include <kapplication.h>
+#include <krun.h>
+
+class clientApp : public KApplication
+{
+ Q_OBJECT
+public:
+ /** Parse command-line arguments and "do it" */
+ static bool doIt();
+
+ /** Make konqueror open a window for @p url */
+ static bool createNewWindow(const KURL & url, bool newTab, bool tempFile, const QString & mimetype = QString::null);
+
+ /** Make konqueror open a window for @p profile, @p url and @p mimetype */
+ static bool openProfile(const QString & profile, const QString & url, const QString & mimetype = QString::null);
+
+protected slots:
+ void slotResult( KIO::Job * );
+ void delayedQuit();
+ void slotDialogCanceled();
+
+private:
+ static void sendASNChange();
+ static bool m_ok;
+ static QCString startup_id_str;
+
+};
+
+#endif
diff --git a/konqueror/client/kfmclient_3_2.upd b/konqueror/client/kfmclient_3_2.upd
new file mode 100644
index 000000000..0b66c1f19
--- /dev/null
+++ b/konqueror/client/kfmclient_3_2.upd
@@ -0,0 +1,4 @@
+Id=kfmclient_3_2
+File=kfmclientrc,konquerorrc
+Group=Settings,Reusing
+Script=kfmclient_3_2_update.sh,sh
diff --git a/konqueror/client/kfmclient_3_2_update.sh b/konqueror/client/kfmclient_3_2_update.sh
new file mode 100644
index 000000000..6c3adbd15
--- /dev/null
+++ b/konqueror/client/kfmclient_3_2_update.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+while read ln; do
+ if (echo $ln | grep -v "^StartNewKonqueror="); then
+ continue
+ fi
+ if test "$ln" = "StartNewKonqueror=Local only"; then
+ echo "SafeParts=khtml.desktop"
+ elif test "$ln" = "StartNewKonqueror=Web only"; then
+ echo "SafeParts=SAFE"
+ elif test "$ln" = "StartNewKonqueror=Always" \
+ -o "$ln" = "StartNewKonqueror=TRUE" \
+ -o "$ln" = "StartNewKonqueror=true" \
+ -o "$ln" = "StartNewKonqueror=1"; then
+ echo "SafeParts="
+ else # =Never
+ echo "SafeParts=ALL"
+ fi
+done
+
+echo '# DELETE StartNewKonqueror'
diff --git a/konqueror/convert_kdelnk.sh b/konqueror/convert_kdelnk.sh
new file mode 100755
index 000000000..02ed247e6
--- /dev/null
+++ b/konqueror/convert_kdelnk.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# Converts all user's .kdelnk files to .desktop
+# Necessary to avoid duplication when saving a mimetype or an applnk
+
+find ~/.kde/share/mimelnk ~/.kde/share/applnk -name "*.kdelnk" -print |
+ while read k; do
+ d=`echo $k|sed -e 's/\.kdelnk/\.desktop/'`
+ echo "Renaming $k to $d"
+ mv "$k" "$d"
+ done
+
+# Convert user's bookmarks to .desktop and to remove .xpm from icons
+find ~/.kde/share/apps/kfm/bookmarks -type f -print |
+ while read k; do
+ if echo $k | grep -q kdelnk; then # kdelnk file
+ d=`echo $k|sed -e 's/\.kdelnk/\.desktop/'`
+ echo "Renaming $k to $d"
+ else
+ d=$k
+ k=$d".tmp"
+ mv "$d" "$k"
+ fi
+ sed -e 's/\.xpm//' "$k" > "$d"
+ rm -f "$k"
+ done
+
diff --git a/konqueror/delayedinitializer.cc b/konqueror/delayedinitializer.cc
new file mode 100644
index 000000000..87d405ac4
--- /dev/null
+++ b/konqueror/delayedinitializer.cc
@@ -0,0 +1,55 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Simon Hausmann <hausmann@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include "delayedinitializer.h"
+#include <qtimer.h>
+
+DelayedInitializer::DelayedInitializer( int eventType, QObject *parent, const char *name )
+ : QObject( parent, name ), m_eventType( eventType ), m_signalEmitted( false )
+{
+ parent->installEventFilter( this );
+}
+
+bool DelayedInitializer::eventFilter( QObject *receiver, QEvent *event )
+{
+ if ( m_signalEmitted || event->type() != m_eventType )
+ return false;
+
+ m_signalEmitted = true;
+ receiver->removeEventFilter( this );
+
+ // Move the emitting of the event to the end of the eventQueue
+ // so we are absolutely sure the event we get here is handled before
+ // the initialize is fired.
+ QTimer::singleShot( 0, this, SLOT( slotInitialize() ) );
+
+ return false;
+}
+
+void DelayedInitializer::slotInitialize()
+{
+ emit initialize();
+ deleteLater();
+}
+
+#include "delayedinitializer.moc"
+
+/* vim: et sw=4
+ */
diff --git a/konqueror/delayedinitializer.h b/konqueror/delayedinitializer.h
new file mode 100644
index 000000000..493ed6dd0
--- /dev/null
+++ b/konqueror/delayedinitializer.h
@@ -0,0 +1,45 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Simon Hausmann <hausmann@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __delayedinitializer_h__
+#define __delayedinitializer_h__
+
+#include <qobject.h>
+
+class DelayedInitializer : public QObject
+{
+ Q_OBJECT
+public:
+ DelayedInitializer( int eventType, QObject *parent, const char *name = 0 );
+
+ virtual bool eventFilter( QObject *receiver, QEvent *event );
+
+signals:
+ void initialize();
+
+private slots:
+ void slotInitialize();
+private:
+ int m_eventType;
+ bool m_signalEmitted;
+};
+
+#endif
+/* vim: et sw=4
+ */
diff --git a/konqueror/iconview/Makefile.am b/konqueror/iconview/Makefile.am
new file mode 100644
index 000000000..bc685d997
--- /dev/null
+++ b/konqueror/iconview/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/konqueror $(all_includes)
+
+kde_module_LTLIBRARIES = konq_iconview.la
+
+METASOURCES = AUTO
+
+konq_iconview_la_SOURCES = konq_iconview.cc
+konq_iconview_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+konq_iconview_la_LIBADD = $(top_builddir)/libkonq/libkonq.la
+
+noinst_HEADERS = konq_iconview.h
+
+kde_services_DATA = konq_iconview.desktop konq_multicolumnview.desktop
+
+rcdir = $(kde_datadir)/konqiconview
+rc_DATA = konq_iconview.rc konq_multicolumnview.rc
diff --git a/konqueror/iconview/konq_iconview.cc b/konqueror/iconview/konq_iconview.cc
new file mode 100644
index 000000000..672ac80e8
--- /dev/null
+++ b/konqueror/iconview/konq_iconview.cc
@@ -0,0 +1,1539 @@
+/* This file is part of the KDE projects
+ Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "konq_iconview.h"
+#include "konq_propsview.h"
+
+#include <assert.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <qfile.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdirlister.h>
+#include <kglobalsettings.h>
+#include <kinputdialog.h>
+#include <konq_settings.h>
+#include <kpropertiesdialog.h>
+#include <kstdaction.h>
+#include <kparts/factory.h>
+#include <ktrader.h>
+#include <klocale.h>
+#include <kivdirectoryoverlay.h>
+#include <kmessagebox.h>
+#include <kstaticdeleter.h>
+
+#include <qregexp.h>
+#include <qdatetime.h>
+
+#include <config.h>
+
+template class QPtrList<KFileIVI>;
+//template class QValueList<int>;
+
+class KonqIconViewFactory : public KParts::Factory
+{
+public:
+ KonqIconViewFactory()
+ {
+ s_defaultViewProps = 0;
+ s_instance = 0;
+ }
+
+ virtual ~KonqIconViewFactory()
+ {
+ if ( s_instance )
+ delete s_instance;
+
+ if ( s_defaultViewProps )
+ delete s_defaultViewProps;
+
+ s_instance = 0;
+ s_defaultViewProps = 0;
+ }
+
+ virtual KParts::Part* createPartObject( QWidget *parentWidget, const char *,
+ QObject *parent, const char *name, const char*, const QStringList &args )
+ {
+ if( args.count() < 1 )
+ kdWarning() << "KonqKfmIconView: Missing Parameter" << endl;
+
+ KonqKfmIconView *obj = new KonqKfmIconView( parentWidget, parent, name,args.first() );
+ return obj;
+ }
+
+ static KInstance *instance()
+ {
+ if ( !s_instance )
+ s_instance = new KInstance( "konqiconview" );
+ return s_instance;
+ }
+
+ static KonqPropsView *defaultViewProps()
+ {
+ if ( !s_defaultViewProps )
+ s_defaultViewProps = new KonqPropsView( instance(), 0L );
+
+ return s_defaultViewProps;
+ }
+
+ private:
+ static KInstance *s_instance;
+ static KonqPropsView *s_defaultViewProps;
+};
+
+KInstance *KonqIconViewFactory::s_instance = 0;
+KonqPropsView *KonqIconViewFactory::s_defaultViewProps = 0;
+
+
+K_EXPORT_COMPONENT_FACTORY( konq_iconview, KonqIconViewFactory )
+
+
+IconViewBrowserExtension::IconViewBrowserExtension( KonqKfmIconView *iconView )
+ : KonqDirPartBrowserExtension( iconView )
+{
+ m_iconView = iconView;
+ m_bSaveViewPropertiesLocally = false;
+}
+
+int IconViewBrowserExtension::xOffset()
+{
+ return m_iconView->iconViewWidget()->contentsX();
+}
+
+int IconViewBrowserExtension::yOffset()
+{
+ return m_iconView->iconViewWidget()->contentsY();
+}
+
+void IconViewBrowserExtension::reparseConfiguration()
+{
+ KonqFMSettings::reparseConfiguration();
+ // m_pProps is a problem here (what is local, what is global ?)
+ // but settings is easy :
+ if ( m_iconView->iconViewWidget()->initConfig( false ) )
+ m_iconView->iconViewWidget()->arrangeItemsInGrid(); // called if the font changed.
+}
+
+void IconViewBrowserExtension::trash()
+{
+ KonqOperations::del(m_iconView->iconViewWidget(),
+ KonqOperations::TRASH,
+ m_iconView->iconViewWidget()->selectedUrls( KonqIconViewWidget::MostLocalUrls ));
+}
+
+void IconViewBrowserExtension::properties()
+{
+ (void) new KPropertiesDialog( m_iconView->iconViewWidget()->selectedFileItems() );
+}
+
+void IconViewBrowserExtension::editMimeType()
+{
+ KFileItem * item = m_iconView->iconViewWidget()->selectedFileItems().first();
+ KonqOperations::editMimeType( item->mimetype() );
+}
+
+void IconViewBrowserExtension::setSaveViewPropertiesLocally( bool value )
+{
+ m_iconView->m_pProps->setSaveViewPropertiesLocally( value );
+}
+
+void IconViewBrowserExtension::setNameFilter( const QString &nameFilter )
+{
+ //kdDebug(1202) << "IconViewBrowserExtension::setNameFilter " << nameFilter << endl;
+ m_iconView->m_nameFilter = nameFilter;
+}
+
+KonqKfmIconView::KonqKfmIconView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode )
+ : KonqDirPart( parent, name )
+ , m_bNeedSetCurrentItem( false )
+ , m_pEnsureVisible( 0 )
+ , m_paOutstandingOverlaysTimer( 0 )
+ , m_pTimeoutRefreshTimer( 0 )
+ , m_itemDict( 43 )
+{
+ kdDebug(1202) << "+KonqKfmIconView" << endl;
+
+ setBrowserExtension( new IconViewBrowserExtension( this ) );
+
+ // Create a properties instance for this view
+ m_pProps = new KonqPropsView( KonqIconViewFactory::instance(), KonqIconViewFactory::defaultViewProps() );
+
+ m_pIconView = new KonqIconViewWidget( parentWidget, "qiconview" );
+ m_pIconView->initConfig( true );
+
+ connect( m_pIconView, SIGNAL(imagePreviewFinished()),
+ this, SLOT(slotRenderingFinished()));
+
+ // connect up the icon inc/dec signals
+ connect( m_pIconView, SIGNAL(incIconSize()),
+ this, SLOT(slotIncIconSize()));
+ connect( m_pIconView, SIGNAL(decIconSize()),
+ this, SLOT(slotDecIconSize()));
+
+ // pass signals to the extension
+ connect( m_pIconView, SIGNAL( enableAction( const char *, bool ) ),
+ m_extension, SIGNAL( enableAction( const char *, bool ) ) );
+
+ // signals from konqdirpart (for BC reasons)
+ connect( this, SIGNAL( findOpened( KonqDirPart * ) ), SLOT( slotKFindOpened() ) );
+ connect( this, SIGNAL( findClosed( KonqDirPart * ) ), SLOT( slotKFindClosed() ) );
+
+ setWidget( m_pIconView );
+ m_mimeTypeResolver = new KMimeTypeResolver<KFileIVI,KonqKfmIconView>(this);
+
+ setInstance( KonqIconViewFactory::instance() );
+
+ setXMLFile( "konq_iconview.rc" );
+
+ // Don't repaint on configuration changes during construction
+ m_bInit = true;
+
+ m_paDotFiles = new KToggleAction( i18n( "Show &Hidden Files" ), 0, this, SLOT( slotShowDot() ),
+ actionCollection(), "show_dot" );
+// m_paDotFiles->setCheckedState(i18n("Hide &Hidden Files"));
+ m_paDotFiles->setToolTip( i18n( "Toggle displaying of hidden dot files" ) );
+
+ m_paDirectoryOverlays = new KToggleAction( i18n( "&Folder Icons Reflect Contents" ), 0, this, SLOT( slotShowDirectoryOverlays() ),
+ actionCollection(), "show_directory_overlays" );
+
+ m_pamPreview = new KActionMenu( i18n( "&Preview" ), actionCollection(), "iconview_preview" );
+
+ m_paEnablePreviews = new KToggleAction( i18n("Enable Previews"), 0, actionCollection(), "iconview_preview_all" );
+ m_paEnablePreviews->setCheckedState( i18n("Disable Previews") );
+ connect( m_paEnablePreviews, SIGNAL( toggled( bool ) ), this, SLOT( slotPreview( bool ) ) );
+ m_paEnablePreviews->setIcon("thumbnail");
+ m_pamPreview->insert( m_paEnablePreviews );
+ m_pamPreview->insert( new KActionSeparator(this) );
+
+ KTrader::OfferList plugins = KTrader::self()->query( "ThumbCreator" );
+ QMap< QString, KToggleAction* > previewActions;
+ for ( KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it )
+ {
+ if ( KToggleAction*& preview = previewActions[ ( *it )->name() ] )
+ preview->setName( QCString( preview->name() ) + ',' + ( *it )->desktopEntryName().latin1() );
+ else
+ {
+ preview = new KToggleAction( (*it)->name(), 0, actionCollection(), (*it)->desktopEntryName().latin1() );
+ connect( preview, SIGNAL( toggled( bool ) ), this, SLOT( slotPreview( bool ) ) );
+ m_pamPreview->insert( preview );
+ m_paPreviewPlugins.append( preview );
+ }
+ }
+ KToggleAction *soundPreview = new KToggleAction( i18n("Sound Files"), 0, actionCollection(), "audio/" );
+ connect( soundPreview, SIGNAL( toggled( bool ) ), this, SLOT( slotPreview( bool ) ) );
+ m_pamPreview->insert( soundPreview );
+ m_paPreviewPlugins.append( soundPreview );
+
+ // m_pamSort = new KActionMenu( i18n( "Sort..." ), actionCollection(), "sort" );
+
+ KToggleAction *aSortByNameCS = new KRadioAction( i18n( "By Name (Case Sensitive)" ), 0, actionCollection(), "sort_nc" );
+ KToggleAction *aSortByNameCI = new KRadioAction( i18n( "By Name (Case Insensitive)" ), 0, actionCollection(), "sort_nci" );
+ KToggleAction *aSortBySize = new KRadioAction( i18n( "By Size" ), 0, actionCollection(), "sort_size" );
+ KToggleAction *aSortByType = new KRadioAction( i18n( "By Type" ), 0, actionCollection(), "sort_type" );
+ KToggleAction *aSortByDate = new KRadioAction( i18n( "By Date" ), 0, actionCollection(), "sort_date" );
+
+ aSortByNameCS->setExclusiveGroup( "sorting" );
+ aSortByNameCI->setExclusiveGroup( "sorting" );
+ aSortBySize->setExclusiveGroup( "sorting" );
+ aSortByType->setExclusiveGroup( "sorting" );
+ aSortByDate->setExclusiveGroup( "sorting" );
+
+ aSortByNameCS->setChecked( false );
+ aSortByNameCI->setChecked( false );
+ aSortBySize->setChecked( false );
+ aSortByType->setChecked( false );
+ aSortByDate->setChecked( false );
+
+ connect( aSortByNameCS, SIGNAL( toggled( bool ) ), this, SLOT( slotSortByNameCaseSensitive( bool ) ) );
+ connect( aSortByNameCI, SIGNAL( toggled( bool ) ), this, SLOT( slotSortByNameCaseInsensitive( bool ) ) );
+ connect( aSortBySize, SIGNAL( toggled( bool ) ), this, SLOT( slotSortBySize( bool ) ) );
+ connect( aSortByType, SIGNAL( toggled( bool ) ), this, SLOT( slotSortByType( bool ) ) );
+ connect( aSortByDate, SIGNAL( toggled( bool ) ), this, SLOT( slotSortByDate( bool ) ) );
+
+ //enable menu item representing the saved sorting criterion
+ QString sortcrit = KonqIconViewFactory::defaultViewProps()->sortCriterion();
+ KRadioAction *sort_action = dynamic_cast<KRadioAction *>(actionCollection()->action(sortcrit.latin1()));
+ if(sort_action!=NULL) sort_action->activate();
+
+ m_paSortDirsFirst = new KToggleAction( i18n( "Folders First" ), 0, actionCollection(), "sort_directoriesfirst" );
+ KToggleAction *aSortDescending = new KToggleAction( i18n( "Descending" ), 0, actionCollection(), "sort_descend" );
+
+ m_paSortDirsFirst->setChecked( KonqIconViewFactory::defaultViewProps()->isDirsFirst() );
+
+ connect( aSortDescending, SIGNAL( toggled( bool ) ), this, SLOT( slotSortDescending() ) );
+ connect( m_paSortDirsFirst, SIGNAL( toggled( bool ) ), this, SLOT( slotSortDirsFirst() ) );
+
+ //enable stored settings
+ slotSortDirsFirst();
+ if (KonqIconViewFactory::defaultViewProps()->isDescending())
+ {
+ aSortDescending->setChecked(true);
+ m_pIconView->setSorting(true,true);//enable sort ascending in QIconview
+ slotSortDescending();//invert sorting (now descending) and actually resort items
+ }
+
+ /*
+ m_pamSort->insert( aSortByNameCS );
+ m_pamSort->insert( aSortByNameCI );
+ m_pamSort->insert( aSortBySize );
+
+ m_pamSort->popupMenu()->insertSeparator();
+
+ m_pamSort->insert( aSortDescending );
+ */
+ m_paSelect = new KAction( i18n( "Se&lect..." ), CTRL+Key_Plus, this, SLOT( slotSelect() ),
+ actionCollection(), "select" );
+ m_paUnselect = new KAction( i18n( "Unselect..." ), CTRL+Key_Minus, this, SLOT( slotUnselect() ),
+ actionCollection(), "unselect" );
+ m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectall" );
+ m_paUnselectAll = new KAction( i18n( "Unselect All" ), CTRL+Key_U, this, SLOT( slotUnselectAll() ),
+ actionCollection(), "unselectall" );
+ m_paInvertSelection = new KAction( i18n( "&Invert Selection" ), CTRL+Key_Asterisk,
+ this, SLOT( slotInvertSelection() ),
+ actionCollection(), "invertselection" );
+
+ m_paSelect->setToolTip( i18n( "Allows selecting of file or folder items based on a given mask" ) );
+ m_paUnselect->setToolTip( i18n( "Allows unselecting of file or folder items based on a given mask" ) );
+ m_paSelectAll->setToolTip( i18n( "Selects all items" ) );
+ m_paUnselectAll->setToolTip( i18n( "Unselects all selected items" ) );
+ m_paInvertSelection->setToolTip( i18n( "Inverts the current selection of items" ) );
+
+ //m_paBottomText = new KToggleAction( i18n( "Text at &Bottom" ), 0, actionCollection(), "textbottom" );
+ //m_paRightText = new KToggleAction( i18n( "Text at &Right" ), 0, actionCollection(), "textright" );
+ //m_paBottomText->setExclusiveGroup( "TextPos" );
+ //m_paRightText->setExclusiveGroup( "TextPos" );
+ //connect( m_paBottomText, SIGNAL( toggled( bool ) ), this, SLOT( slotTextBottom( bool ) ) );
+ //connect( m_paRightText, SIGNAL( toggled( bool ) ), this, SLOT( slotTextRight( bool ) ) );
+
+ connect( m_pIconView, SIGNAL( executed( QIconViewItem * ) ),
+ this, SLOT( slotReturnPressed( QIconViewItem * ) ) );
+ connect( m_pIconView, SIGNAL( returnPressed( QIconViewItem * ) ),
+ this, SLOT( slotReturnPressed( QIconViewItem * ) ) );
+
+ connect( m_pIconView, SIGNAL( onItem( QIconViewItem * ) ),
+ this, SLOT( slotOnItem( QIconViewItem * ) ) );
+
+ connect( m_pIconView, SIGNAL( onViewport() ),
+ this, SLOT( slotOnViewport() ) );
+
+ connect( m_pIconView, SIGNAL( mouseButtonPressed(int, QIconViewItem*, const QPoint&)),
+ this, SLOT( slotMouseButtonPressed(int, QIconViewItem*, const QPoint&)) );
+ connect( m_pIconView, SIGNAL( mouseButtonClicked(int, QIconViewItem*, const QPoint&)),
+ this, SLOT( slotMouseButtonClicked(int, QIconViewItem*, const QPoint&)) );
+ connect( m_pIconView, SIGNAL( contextMenuRequested(QIconViewItem*, const QPoint&)),
+ this, SLOT( slotContextMenuRequested(QIconViewItem*, const QPoint&)) );
+
+ // Signals needed to implement the spring loading folders behavior
+ connect( m_pIconView, SIGNAL( held( QIconViewItem * ) ),
+ this, SLOT( slotDragHeld( QIconViewItem * ) ) );
+ connect( m_pIconView, SIGNAL( dragEntered( bool ) ),
+ this, SLOT( slotDragEntered( bool ) ) );
+ connect( m_pIconView, SIGNAL( dragLeft() ),
+ this, SLOT( slotDragLeft() ) );
+ connect( m_pIconView, SIGNAL( dragMove( bool ) ),
+ this, SLOT( slotDragMove( bool ) ) );
+ connect( m_pIconView, SIGNAL( dragFinished() ),
+ this, SLOT( slotDragFinished() ) );
+
+ // Create the directory lister
+ m_dirLister = new KDirLister( true );
+ setDirLister( m_dirLister );
+ m_dirLister->setMainWindow(m_pIconView->topLevelWidget());
+
+ connect( m_dirLister, SIGNAL( started( const KURL & ) ),
+ this, SLOT( slotStarted() ) );
+ connect( m_dirLister, SIGNAL( completed() ), this, SLOT( slotCompleted() ) );
+ connect( m_dirLister, SIGNAL( canceled( const KURL& ) ), this, SLOT( slotCanceled( const KURL& ) ) );
+ connect( m_dirLister, SIGNAL( clear() ), this, SLOT( slotClear() ) );
+ connect( m_dirLister, SIGNAL( newItems( const KFileItemList& ) ),
+ this, SLOT( slotNewItems( const KFileItemList& ) ) );
+ connect( m_dirLister, SIGNAL( deleteItem( KFileItem * ) ),
+ this, SLOT( slotDeleteItem( KFileItem * ) ) );
+ connect( m_dirLister, SIGNAL( refreshItems( const KFileItemList& ) ),
+ this, SLOT( slotRefreshItems( const KFileItemList& ) ) );
+ connect( m_dirLister, SIGNAL( redirection( const KURL & ) ),
+ this, SLOT( slotRedirection( const KURL & ) ) );
+ connect( m_dirLister, SIGNAL( itemsFilteredByMime(const KFileItemList& ) ),
+ SIGNAL( itemsFilteredByMime(const KFileItemList& ) ) );
+ connect( m_dirLister, SIGNAL( infoMessage( const QString& ) ),
+ extension(), SIGNAL( infoMessage( const QString& ) ) );
+ connect( m_dirLister, SIGNAL( percent( int ) ),
+ extension(), SIGNAL( loadingProgress( int ) ) );
+ connect( m_dirLister, SIGNAL( speed( int ) ),
+ extension(), SIGNAL( speedProgress( int ) ) );
+
+ // Now we may react to configuration changes
+ m_bInit = false;
+
+ m_bLoading = true;
+ m_bNeedAlign = false;
+ m_bNeedEmitCompleted = false;
+ m_bUpdateContentsPosAfterListing = false;
+ m_bDirPropertiesChanged = true;
+ m_bPreviewRunningBeforeCloseURL = false;
+ m_pIconView->setResizeMode( QIconView::Adjust );
+
+ connect( m_pIconView, SIGNAL( selectionChanged() ),
+ this, SLOT( slotSelectionChanged() ) );
+
+ // Respect kcmkonq's configuration for word-wrap icon text.
+ // If we want something else, we have to adapt the configuration or remove it...
+ m_pIconView->setIconTextHeight(KonqFMSettings::settings()->iconTextHeight());
+
+ // Finally, determine initial grid size again, with those parameters
+ // m_pIconView->calculateGridX();
+
+ setViewMode( mode );
+}
+
+KonqKfmIconView::~KonqKfmIconView()
+{
+ // Before anything else, stop the image preview. It might use our fileitems,
+ // and it will only be destroyed togetierh with our widget
+ m_pIconView->stopImagePreview();
+
+ kdDebug(1202) << "-KonqKfmIconView" << endl;
+ m_dirLister->disconnect( this );
+ delete m_dirLister;
+ delete m_mimeTypeResolver;
+ delete m_pProps;
+ //no need for that, KParts deletes our widget already ;-)
+ // delete m_pIconView;
+}
+
+const KFileItem * KonqKfmIconView::currentItem()
+{
+ return m_pIconView->currentItem() ? static_cast<KFileIVI *>(m_pIconView->currentItem())->item() : 0L;
+}
+
+void KonqKfmIconView::slotPreview( bool toggle )
+{
+ QCString name = sender()->name(); // e.g. clipartthumbnail (or audio/, special case)
+ if (name == "iconview_preview_all")
+ {
+ m_pProps->setShowingPreview( toggle );
+ m_pIconView->setPreviewSettings( m_pProps->previewSettings() );
+ if ( !toggle )
+ {
+ kdDebug() << "KonqKfmIconView::slotPreview stopping all previews for " << name << endl;
+ m_pIconView->disableSoundPreviews();
+
+ bool previewRunning = m_pIconView->isPreviewRunning();
+ if ( previewRunning )
+ m_pIconView->stopImagePreview();
+ m_pIconView->setIcons( m_pIconView->iconSize(), "*" );
+ }
+ else
+ {
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), true );
+ }
+ for ( m_paPreviewPlugins.first(); m_paPreviewPlugins.current(); m_paPreviewPlugins.next() )
+ m_paPreviewPlugins.current()->setEnabled( toggle );
+ }
+ else
+ {
+ QStringList types = QStringList::split( ',', name );
+ for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
+ {
+ m_pProps->setShowingPreview( *it, toggle );
+ m_pIconView->setPreviewSettings( m_pProps->previewSettings() );
+ if ( !toggle )
+ {
+ kdDebug() << "KonqKfmIconView::slotPreview stopping image preview for " << *it << endl;
+ if ( *it == "audio/" )
+ m_pIconView->disableSoundPreviews();
+ else
+ {
+ KService::Ptr serv = KService::serviceByDesktopName( *it );
+ Q_ASSERT( serv != 0L );
+ if ( serv ) {
+ bool previewRunning = m_pIconView->isPreviewRunning();
+ if ( previewRunning )
+ m_pIconView->stopImagePreview();
+ QStringList mimeTypes = serv->property("MimeTypes").toStringList();
+ m_pIconView->setIcons( m_pIconView->iconSize(), mimeTypes );
+ if ( previewRunning )
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), false );
+ }
+ }
+ }
+ else
+ {
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), true );
+ }
+ }
+ }
+}
+
+void KonqKfmIconView::slotShowDot()
+{
+ m_pProps->setShowingDotFiles( !m_pProps->isShowingDotFiles() );
+ m_dirLister->setShowingDotFiles( m_pProps->isShowingDotFiles() );
+ m_dirLister->emitChanges();
+ //we don't want the non-dot files to remain where they are
+ m_bNeedAlign = true;
+ slotCompleted();
+}
+
+void KonqKfmIconView::slotShowDirectoryOverlays()
+{
+ bool show = !m_pProps->isShowingDirectoryOverlays();
+
+ m_pProps->setShowingDirectoryOverlays( show );
+
+ for ( QIconViewItem *item = m_pIconView->firstItem(); item; item = item->nextItem() )
+ {
+ KFileIVI* kItem = static_cast<KFileIVI*>(item);
+ if ( !kItem->item()->isDir() ) continue;
+
+ if (show) {
+ showDirectoryOverlay(kItem);
+ } else {
+ kItem -> setShowDirectoryOverlay(false);
+ }
+ }
+
+ m_pIconView->updateContents();
+}
+
+void KonqKfmIconView::slotSelect()
+{
+ bool ok;
+ QString pattern = KInputDialog::getText( QString::null,
+ i18n( "Select files:" ), "*", &ok, m_pIconView );
+ if ( ok )
+ {
+ QRegExp re( pattern, true, true );
+
+ m_pIconView->blockSignals( true );
+
+ QIconViewItem *it = m_pIconView->firstItem();
+ while ( it )
+ {
+ if ( re.exactMatch( it->text() ) )
+ it->setSelected( true, true );
+ it = it->nextItem();
+ }
+
+ m_pIconView->blockSignals( false );
+
+ // do this once, not for each item
+ m_pIconView->slotSelectionChanged();
+ slotSelectionChanged();
+ }
+}
+
+void KonqKfmIconView::slotUnselect()
+{
+ bool ok;
+ QString pattern = KInputDialog::getText( QString::null,
+ i18n( "Unselect files:" ), "*", &ok, m_pIconView );
+ if ( ok )
+ {
+ QRegExp re( pattern, true, true );
+
+ m_pIconView->blockSignals( true );
+
+ QIconViewItem *it = m_pIconView->firstItem();
+ while ( it )
+ {
+ if ( re.exactMatch( it->text() ) )
+ it->setSelected( false, true );
+ it = it->nextItem();
+ }
+
+ m_pIconView->blockSignals( false );
+
+ // do this once, not for each item
+ m_pIconView->slotSelectionChanged();
+ slotSelectionChanged();
+ }
+}
+
+void KonqKfmIconView::slotSelectAll()
+{
+ m_pIconView->selectAll( true );
+}
+
+void KonqKfmIconView::slotUnselectAll()
+{
+ m_pIconView->selectAll( false );
+}
+
+void KonqKfmIconView::slotInvertSelection()
+{
+ m_pIconView->invertSelection( );
+}
+
+void KonqKfmIconView::slotSortByNameCaseSensitive( bool toggle )
+{
+ if ( !toggle )
+ return;
+
+ KonqIconViewFactory::defaultViewProps()->setSortCriterion("sort_nc");
+ setupSorting( NameCaseSensitive );
+}
+
+void KonqKfmIconView::slotSortByNameCaseInsensitive( bool toggle )
+{
+ if ( !toggle )
+ return;
+
+ KonqIconViewFactory::defaultViewProps()->setSortCriterion("sort_nci");
+ setupSorting( NameCaseInsensitive );
+}
+
+void KonqKfmIconView::slotSortBySize( bool toggle )
+{
+ if ( !toggle )
+ return;
+
+ KonqIconViewFactory::defaultViewProps()->setSortCriterion("sort_size");
+ setupSorting( Size );
+}
+
+void KonqKfmIconView::slotSortByType( bool toggle )
+{
+ if ( !toggle )
+ return;
+
+ KonqIconViewFactory::defaultViewProps()->setSortCriterion("sort_type");
+ setupSorting( Type );
+}
+
+void KonqKfmIconView::slotSortByDate( bool toggle )
+{
+ if( !toggle)
+ return;
+
+ KonqIconViewFactory::defaultViewProps()->setSortCriterion("sort_date");
+ setupSorting( Date );
+}
+
+void KonqKfmIconView::setupSorting( SortCriterion criterion )
+{
+ m_eSortCriterion = criterion;
+
+ setupSortKeys();
+
+ m_pIconView->sort( m_pIconView->sortDirection() );
+}
+
+void KonqKfmIconView::slotSortDescending()
+{
+ if ( m_pIconView->sortDirection() )
+ m_pIconView->setSorting( true, false );
+ else
+ m_pIconView->setSorting( true, true );
+
+ setupSortKeys(); // keys have to change, for directories
+
+ m_pIconView->sort( m_pIconView->sortDirection() );
+
+ KonqIconViewFactory::defaultViewProps()->setDescending( !m_pIconView->sortDirection() );
+}
+
+void KonqKfmIconView::slotSortDirsFirst()
+{
+ m_pIconView->setSortDirectoriesFirst( m_paSortDirsFirst->isChecked() );
+
+ setupSortKeys();
+
+ m_pIconView->sort( m_pIconView->sortDirection() );
+
+ KonqIconViewFactory::defaultViewProps()->setDirsFirst( m_paSortDirsFirst->isChecked() );
+}
+
+void KonqKfmIconView::newIconSize( int size )
+{
+ //Either of the sizes can be 0 to indicate the default (Desktop) size icons.
+ //check for that when checking whether the size changed
+ int effSize = size;
+ if (effSize == 0)
+ effSize = IconSize(KIcon::Desktop);
+
+ int oldEffSize = m_pIconView->iconSize();
+ if (oldEffSize == 0)
+ oldEffSize = IconSize(KIcon::Desktop);
+
+ // Make sure all actions are initialized.
+ KonqDirPart::newIconSize( size );
+
+ if ( effSize == oldEffSize )
+ return;
+
+ // Stop a preview job that might be running
+ m_pIconView->stopImagePreview();
+
+ // Set icons size, arrage items in grid and repaint the whole view
+ m_pIconView->setIcons( size );
+
+ // If previews are enabled start a new job
+ if ( m_pProps->isShowingPreview() )
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), true );
+}
+
+bool KonqKfmIconView::doCloseURL()
+{
+ m_dirLister->stop();
+
+ m_mimeTypeResolver->m_lstPendingMimeIconItems.clear();
+
+ m_bPreviewRunningBeforeCloseURL = m_pIconView->isPreviewRunning();
+ m_pIconView->stopImagePreview();
+ return true;
+}
+
+void KonqKfmIconView::slotReturnPressed( QIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ item->setSelected( false, true );
+ m_pIconView->visualActivate(item);
+
+ KFileItem *fileItem = (static_cast<KFileIVI*>(item))->item();
+ if ( !fileItem )
+ return;
+ lmbClicked( fileItem );
+}
+
+void KonqKfmIconView::slotDragHeld( QIconViewItem *item )
+{
+ kdDebug() << "KonqKfmIconView::slotDragHeld()" << endl;
+
+ // This feature is not usable if the user wants one window per folder
+ if ( KonqFMSettings::settings()->alwaysNewWin() )
+ return;
+
+ if ( !item )
+ return;
+
+ KFileItem *fileItem = (static_cast<KFileIVI*>(item))->item();
+
+ SpringLoadingManager::self().springLoadTrigger(this, fileItem, item);
+}
+
+void KonqKfmIconView::slotDragEntered( bool )
+{
+ if ( SpringLoadingManager::exists() )
+ SpringLoadingManager::self().dragEntered(this);
+}
+
+void KonqKfmIconView::slotDragLeft()
+{
+ kdDebug() << "KonqKfmIconView::slotDragLeft()" << endl;
+
+ if ( SpringLoadingManager::exists() )
+ SpringLoadingManager::self().dragLeft(this);
+}
+
+void KonqKfmIconView::slotDragMove( bool accepted )
+{
+ if ( !accepted )
+ emit setStatusBarText( i18n( "You cannot drop any items in a directory in which you do not have write permission" ) );
+}
+
+void KonqKfmIconView::slotDragFinished()
+{
+ kdDebug() << "KonqKfmIconView::slotDragFinished()" << endl;
+
+ if ( SpringLoadingManager::exists() )
+ SpringLoadingManager::self().dragFinished(this);
+}
+
+
+void KonqKfmIconView::slotContextMenuRequested(QIconViewItem* _item, const QPoint& _global)
+{
+ const KFileItemList items = m_pIconView->selectedFileItems();
+ if ( items.isEmpty() )
+ return;
+
+ KParts::BrowserExtension::PopupFlags popupFlags = KParts::BrowserExtension::DefaultPopupItems;
+
+ KFileIVI* i = static_cast<KFileIVI*>(_item);
+ if (i)
+ i->setSelected( true, true /* don't touch other items */ );
+
+ KFileItem * rootItem = m_dirLister->rootItem();
+ if ( rootItem ) {
+ KURL parentDirURL = rootItem->url();
+ // Check if parentDirURL applies to the selected items (usually yes, but not with search results)
+ QPtrListIterator<KFileItem> kit( items );
+ for ( ; kit.current(); ++kit )
+ if ( kit.current()->url().directory( 1 ) != rootItem->url().path() )
+ parentDirURL = KURL();
+ // If rootItem is the parent of the selected items, then we can use isWritable() on it.
+ if ( !parentDirURL.isEmpty() && !rootItem->isWritable() )
+ popupFlags |= KParts::BrowserExtension::NoDeletion;
+ }
+
+ emit m_extension->popupMenu( 0L, _global, items, KParts::URLArgs(), popupFlags);
+}
+
+void KonqKfmIconView::slotMouseButtonPressed(int _button, QIconViewItem* _item, const QPoint&)
+{
+ if ( _button == RightButton && !_item )
+ {
+ // Right click on viewport
+ KFileItem * item = m_dirLister->rootItem();
+ bool delRootItem = false;
+ if ( ! item )
+ {
+ if ( m_bLoading )
+ {
+ kdDebug(1202) << "slotViewportRightClicked : still loading and no root item -> dismissed" << endl;
+ return; // too early, '.' not yet listed
+ }
+ else
+ {
+ // We didn't get a root item (e.g. over FTP)
+ // We have to create a dummy item. I tried using KonqOperations::statURL,
+ // but this was leading to a huge delay between the RMB and the popup. Bad.
+ // But KonqPopupMenu now takes care of stating before opening properties.
+ item = new KFileItem( S_IFDIR, (mode_t)-1, url() );
+ delRootItem = true;
+ }
+ }
+
+ KFileItemList items;
+ items.append( item );
+
+ KParts::BrowserExtension::PopupFlags popupFlags = KParts::BrowserExtension::ShowNavigationItems | KParts::BrowserExtension::ShowUp;
+
+ emit m_extension->popupMenu( 0L, QCursor::pos(), items, KParts::URLArgs(), popupFlags );
+
+ if ( delRootItem )
+ delete item; // we just created it
+ }
+}
+
+void KonqKfmIconView::slotMouseButtonClicked(int _button, QIconViewItem* _item, const QPoint& )
+{
+ if( _button == MidButton )
+ mmbClicked( _item ? static_cast<KFileIVI*>(_item)->item() : 0L );
+}
+
+void KonqKfmIconView::slotStarted()
+{
+ // Only emit started if this comes after openURL, i.e. it's not for an update.
+ // We don't want to start a spinning wheel during updates.
+ if ( m_bLoading )
+ emit started( 0 );
+
+ // An update may come in while we are still processing icons...
+ // So don't clear the list.
+ //m_mimeTypeResolver->m_lstPendingMimeIconItems.clear();
+}
+
+void KonqKfmIconView::slotCanceled()
+{
+ // Called by kfindpart. Not by kdirlister.
+ slotCanceled( m_pIconView->url() );
+}
+
+void KonqKfmIconView::slotCanceled( const KURL& url )
+{
+ // Check if this canceled() signal is about the URL we're listing.
+ // It could be about the URL we were listing, and openURL() aborted it.
+ if ( m_bLoading && url.equals( m_pIconView->url(), true ) )
+ {
+ emit canceled( QString::null );
+ m_bLoading = false;
+ }
+
+ // Stop the "refresh if busy too long" timer because a viewport
+ // update is coming.
+ if ( m_pTimeoutRefreshTimer && m_pTimeoutRefreshTimer->isActive() )
+ m_pTimeoutRefreshTimer->stop();
+
+ // See slotCompleted(). If a listing gets canceled, it doesn't emit
+ // the completed() signal, so handle that case.
+ if ( !m_pIconView->viewport()->isUpdatesEnabled() )
+ {
+ m_pIconView->viewport()->setUpdatesEnabled( true );
+ m_pIconView->viewport()->repaint();
+ }
+ if ( m_pEnsureVisible ){
+ m_pIconView->ensureItemVisible( m_pEnsureVisible );
+ m_pEnsureVisible = 0;
+ }
+}
+
+void KonqKfmIconView::slotCompleted()
+{
+ // Stop the "refresh if busy too long" timer because a viewport
+ // update is coming.
+ if ( m_pTimeoutRefreshTimer && m_pTimeoutRefreshTimer->isActive() )
+ m_pTimeoutRefreshTimer->stop();
+
+ // If updates to the viewport are still blocked (so slotNewItems() has
+ // not been called), a viewport repaint is forced.
+ if ( !m_pIconView->viewport()->isUpdatesEnabled() )
+ {
+ m_pIconView->viewport()->setUpdatesEnabled( true );
+ m_pIconView->viewport()->repaint();
+ }
+
+ // Root item ? Store root item in konqiconviewwidget (whether 0L or not)
+ m_pIconView->setRootItem( m_dirLister->rootItem() );
+
+ // only after initial listing, not after updates
+ // If we don't set a current item, the iconview has none (one more keypress needed)
+ // but it appears on focusin... qiconview bug, Reggie acknowledged it LONG ago (07-2000).
+ if ( m_bNeedSetCurrentItem )
+ {
+ m_pIconView->setCurrentItem( m_pIconView->firstItem() );
+ m_bNeedSetCurrentItem = false;
+ }
+
+ if ( m_bUpdateContentsPosAfterListing ) {
+ m_pIconView->setContentsPos( extension()->urlArgs().xOffset,
+ extension()->urlArgs().yOffset );
+ }
+
+ if ( m_pEnsureVisible ){
+ m_pIconView->ensureItemVisible( m_pEnsureVisible );
+ m_pEnsureVisible = 0;
+ }
+
+ m_bUpdateContentsPosAfterListing = false;
+
+ if ( !m_pIconView->firstItem() )
+ resetCount();
+
+ slotOnViewport();
+
+ // slotRenderingFinished will do it
+ m_bNeedEmitCompleted = true;
+
+ if (m_pProps->isShowingPreview())
+ m_mimeTypeResolver->start( 0 ); // We need the mimetypes asap
+ else
+ {
+ slotRenderingFinished(); // emit completed, we don't want the wheel...
+ // to keep turning while we find mimetypes in the background
+ m_mimeTypeResolver->start( 10 );
+ }
+
+ m_bLoading = false;
+
+ // Disable cut icons if any
+ slotClipboardDataChanged();
+}
+
+void KonqKfmIconView::slotNewItems( const KFileItemList& entries )
+{
+ // Stop the autorefresh timer since data to display has arrived and will
+ // be drawn in moments
+ if ( m_pTimeoutRefreshTimer && m_pTimeoutRefreshTimer->isActive() )
+ m_pTimeoutRefreshTimer->stop();
+ // We need to disable graphics updates on the iconview when
+ // inserting items, or else a blank paint operation will be
+ // performed on the top-left corner for each inserted item!
+ m_pIconView->setUpdatesEnabled( false );
+ for (KFileItemListIterator it(entries); it.current(); ++it)
+ {
+ //kdDebug(1202) << "KonqKfmIconView::slotNewItem(...)" << _fileitem->url().url() << endl;
+ KFileIVI* item = new KFileIVI( m_pIconView, *it, m_pIconView->iconSize() );
+ item->setRenameEnabled( false );
+
+ KFileItem* fileItem = item->item();
+
+ if ( !m_itemsToSelect.isEmpty() ) {
+ QStringList::Iterator tsit = m_itemsToSelect.find( fileItem->name() );
+ if ( tsit != m_itemsToSelect.end() ) {
+ m_itemsToSelect.remove( tsit );
+ m_pIconView->setSelected( item, true, true );
+ if ( m_bNeedSetCurrentItem ){
+ m_pIconView->setCurrentItem( item );
+ if( !m_pEnsureVisible )
+ m_pEnsureVisible = item;
+ m_bNeedSetCurrentItem = false;
+ }
+ }
+ }
+
+ if ( fileItem->isDir() && m_pProps->isShowingDirectoryOverlays() ) {
+ showDirectoryOverlay(item);
+ }
+
+ QString key;
+
+ switch ( m_eSortCriterion )
+ {
+ case NameCaseSensitive: key = item->text(); break;
+ case NameCaseInsensitive: key = item->text().lower(); break;
+ case Size: key = makeSizeKey( item ); break;
+ case Type: key = item->item()->mimetype()+ "\008" +item->text().lower(); break; // ### slows down listing :-(
+ case Date:
+ {
+ QDateTime dayt;
+ dayt.setTime_t(item->item()->time(KIO::UDS_MODIFICATION_TIME ));
+ key = dayt.toString("yyyyMMddhhmmss");
+ break;
+ }
+ default: Q_ASSERT(0);
+ }
+
+ item->setKey( key );
+
+ //kdDebug() << "KonqKfmIconView::slotNewItems " << (*it)->url().url() << " " << (*it)->mimeTypePtr()->name() << " mimetypeknown:" << (*it)->isMimeTypeKnown() << endl;
+ if ( !(*it)->isMimeTypeKnown() )
+ m_mimeTypeResolver->m_lstPendingMimeIconItems.append( item );
+
+ m_itemDict.insert( *it, item );
+ }
+ // After filtering out updates-on-insertions we can re-enable updates
+ m_pIconView->setUpdatesEnabled( true );
+ // Locking the viewport has filtered out blanking and now, since we
+ // have some items to draw, we can restore updating.
+ if ( !m_pIconView->viewport()->isUpdatesEnabled() )
+ m_pIconView->viewport()->setUpdatesEnabled( true );
+ KonqDirPart::newItems( entries );
+}
+
+void KonqKfmIconView::slotDeleteItem( KFileItem * _fileitem )
+{
+ // new in 3.5.5
+#ifdef KPARTS_BROWSEREXTENSION_HAS_ITEMS_REMOVED
+ KFileItemList list;
+ list.append( _fileitem );
+ emit m_extension->itemsRemoved( list );
+#else
+#error "Your kdelibs doesn't have KParts::BrowserExtension::itemsRemoved, please update it to at least 3.5.5"
+#endif
+
+ if ( _fileitem == m_dirLister->rootItem() )
+ {
+ m_pIconView->stopImagePreview();
+ m_pIconView->setRootItem( 0L );
+ return;
+ }
+
+ //kdDebug(1202) << "KonqKfmIconView::slotDeleteItem(...)" << endl;
+ // we need to find out the iconcontainer item containing the fileitem
+ KFileIVI * ivi = m_itemDict[ _fileitem ];
+ // It can be that we know nothing about this item, e.g. because it's filtered out
+ // (by default: dot files). KDirLister still tells us about it when it's modified, since
+ // it doesn't know if we showed it before, and maybe its mimetype changed so we
+ // might have to hide it now.
+ if (ivi)
+ {
+ m_pIconView->stopImagePreview();
+ KonqDirPart::deleteItem( _fileitem );
+
+ m_pIconView->takeItem( ivi );
+ m_mimeTypeResolver->m_lstPendingMimeIconItems.remove( ivi );
+ m_itemDict.remove( _fileitem );
+ if (m_paOutstandingOverlays.first() == ivi) // Being processed?
+ m_paOutstandingOverlaysTimer->start(20, true); // Restart processing...
+
+ m_paOutstandingOverlays.remove(ivi);
+ delete ivi;
+ }
+}
+
+void KonqKfmIconView::showDirectoryOverlay(KFileIVI* item)
+{
+ KFileItem* fileItem = item->item();
+
+ if ( KGlobalSettings::showFilePreview( fileItem->url() ) ) {
+ m_paOutstandingOverlays.append(item);
+ if (m_paOutstandingOverlays.count() == 1)
+ {
+ if (!m_paOutstandingOverlaysTimer)
+ {
+ m_paOutstandingOverlaysTimer = new QTimer(this);
+ connect(m_paOutstandingOverlaysTimer, SIGNAL(timeout()),
+ SLOT(slotDirectoryOverlayStart()));
+ }
+ m_paOutstandingOverlaysTimer->start(20, true);
+ }
+ }
+}
+
+void KonqKfmIconView::slotDirectoryOverlayStart()
+{
+ do
+ {
+ KFileIVI* item = m_paOutstandingOverlays.first();
+ if (!item)
+ return; // Nothing to do
+
+ KIVDirectoryOverlay* overlay = item->setShowDirectoryOverlay( true );
+
+ if (overlay)
+ {
+ connect( overlay, SIGNAL( finished() ), this, SLOT( slotDirectoryOverlayFinished() ) );
+ overlay->start(); // Watch out, may emit finished() immediately!!
+ return; // Let it run....
+ }
+ m_paOutstandingOverlays.removeFirst();
+ } while (true);
+}
+
+void KonqKfmIconView::slotDirectoryOverlayFinished()
+{
+ m_paOutstandingOverlays.removeFirst();
+
+ if (m_paOutstandingOverlays.count() > 0)
+ m_paOutstandingOverlaysTimer->start(0, true); // Don't call directly to prevent deep recursion.
+}
+
+// see also KDesktop::slotRefreshItems
+void KonqKfmIconView::slotRefreshItems( const KFileItemList& entries )
+{
+ bool bNeedRepaint = false;
+ bool bNeedPreviewJob = false;
+ KFileItemListIterator rit(entries);
+ for (; rit.current(); ++rit)
+ {
+ KFileIVI * ivi = m_itemDict[ rit.current() ];
+ Q_ASSERT(ivi);
+ kdDebug() << "KonqKfmIconView::slotRefreshItems '" << rit.current()->name() << "' ivi=" << ivi << endl;
+ if (ivi)
+ {
+ QSize oldSize = ivi->pixmap()->size();
+ if ( ivi->isThumbnail() ) {
+ bNeedPreviewJob = true;
+ ivi->invalidateThumbnail();
+ }
+ else
+ ivi->refreshIcon( true );
+ ivi->setText( rit.current()->text() );
+ if ( rit.current()->isMimeTypeKnown() )
+ ivi->setMouseOverAnimation( rit.current()->iconName() );
+ if ( !bNeedRepaint && oldSize != ivi->pixmap()->size() )
+ bNeedRepaint = true;
+ }
+ }
+
+ if ( bNeedPreviewJob && m_pProps->isShowingPreview() )
+ {
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), false );
+ }
+ else
+ {
+ // In case we replace a big icon with a small one, need to repaint.
+ if ( bNeedRepaint )
+ m_pIconView->updateContents();
+ }
+}
+
+void KonqKfmIconView::slotClear()
+{
+ resetCount();
+
+ // We're now going to update the view with new contents. To avoid
+ // meaningless paint operations (such as a clear() just before drawing
+ // fresh contents) we disable updating the viewport until we'll
+ // receive some data or a timeout timer expires.
+ m_pIconView->viewport()->setUpdatesEnabled( false );
+ if ( !m_pTimeoutRefreshTimer )
+ {
+ m_pTimeoutRefreshTimer = new QTimer( this );
+ connect( m_pTimeoutRefreshTimer, SIGNAL( timeout() ),
+ this, SLOT( slotRefreshViewport() ) );
+ }
+ m_pTimeoutRefreshTimer->start( 700, true );
+
+ // Clear contents but don't clear graphics as updates are disabled.
+ m_pIconView->clear();
+ // If directory properties are changed, apply pending changes
+ // changes are: view background or color, iconsize, enabled previews
+ if ( m_bDirPropertiesChanged )
+ {
+ m_pProps->applyColors( m_pIconView->viewport() );
+ newIconSize( m_pProps->iconSize() );
+ m_pIconView->setPreviewSettings( m_pProps->previewSettings() );
+ }
+
+ m_mimeTypeResolver->m_lstPendingMimeIconItems.clear();
+ m_itemDict.clear();
+ // Bug in QIconview IMHO - it should emit selectionChanged()
+ // (bug reported, but code seems to be that way on purpose)
+ m_pIconView->slotSelectionChanged();
+ slotSelectionChanged();
+}
+
+void KonqKfmIconView::slotRedirection( const KURL & url )
+{
+ const QString prettyURL = url.pathOrURL();
+ emit m_extension->setLocationBarURL( prettyURL );
+ emit setWindowCaption( prettyURL );
+ m_pIconView->setURL( url );
+ m_url = url;
+}
+
+void KonqKfmIconView::slotSelectionChanged()
+{
+ // Display statusbar info, and emit selectionInfo
+ KFileItemList lst = m_pIconView->selectedFileItems();
+ emitCounts( lst, true );
+
+ bool itemSelected = lst.count()>0;
+ m_paUnselect->setEnabled( itemSelected );
+ m_paUnselectAll->setEnabled( itemSelected );
+ m_paInvertSelection->setEnabled( itemSelected );
+}
+
+void KonqKfmIconView::determineIcon( KFileIVI * item )
+{
+ // kdDebug() << "KonqKfmIconView::determineIcon " << item->item()->name() << endl;
+ //int oldSerial = item->pixmap()->serialNumber();
+
+ (void) item->item()->determineMimeType();
+
+ item->setIcon( iconSize(), item->state(), true, true );
+ item->setMouseOverAnimation( item->item()->iconName() );
+}
+
+void KonqKfmIconView::mimeTypeDeterminationFinished()
+{
+ if ( m_pProps->isShowingPreview() )
+ {
+ // TODO if ( m_url.isLocalFile() || m_bAutoPreviewRemote )
+ {
+ // We can do this only when the mimetypes are fully determined,
+ // since we only do image preview... on images :-)
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), false );
+ return;
+ }
+ }
+ slotRenderingFinished();
+}
+
+void KonqKfmIconView::slotRenderingFinished()
+{
+ kdDebug(1202) << "KonqKfmIconView::slotRenderingFinished()" << endl;
+ if ( m_bNeedEmitCompleted )
+ {
+ kdDebug(1202) << "KonqKfmIconView completed() after rendering" << endl;
+ emit completed();
+ m_bNeedEmitCompleted = false;
+ }
+ if ( m_bNeedAlign )
+ {
+ m_bNeedAlign = false;
+ kdDebug(1202) << "arrangeItemsInGrid" << endl;
+ m_pIconView->arrangeItemsInGrid();
+ }
+}
+
+void KonqKfmIconView::slotRefreshViewport()
+{
+ kdDebug(1202) << "KonqKfmIconView::slotRefreshViewport()" << endl;
+ QWidget * vp = m_pIconView->viewport();
+ bool prevState = vp->isUpdatesEnabled();
+ vp->setUpdatesEnabled( true );
+ vp->repaint();
+ vp->setUpdatesEnabled( prevState );
+}
+
+bool KonqKfmIconView::doOpenURL( const KURL & url )
+{
+ // Store url in the icon view
+ m_pIconView->setURL( url );
+
+ m_bLoading = true;
+ m_bNeedSetCurrentItem = true;
+
+ // Check for new properties in the new dir
+ // enterDir returns true the first time, and any time something might
+ // have changed.
+ m_bDirPropertiesChanged = m_pProps->enterDir( url );
+
+ m_dirLister->setNameFilter( m_nameFilter );
+
+ m_dirLister->setMimeFilter( mimeFilter() );
+
+ // This *must* happen before m_dirLister->openURL because it emits
+ // clear() and QIconView::clear() calls setContentsPos(0,0)!
+ KParts::URLArgs args = m_extension->urlArgs();
+ if ( args.reload )
+ {
+ args.xOffset = m_pIconView->contentsX();
+ args.yOffset = m_pIconView->contentsY();
+ m_extension->setURLArgs( args );
+
+ m_filesToSelect.clear();
+ KFileItemList fil( selectedFileItems() );
+ for (KFileItemListIterator fi_it(fil); fi_it.current(); ++fi_it)
+ m_filesToSelect += (*fi_it)->name();
+ }
+
+ m_itemsToSelect = m_filesToSelect;
+
+ m_dirLister->setShowingDotFiles( m_pProps->isShowingDotFiles() );
+
+ m_bNeedAlign = false;
+ m_bUpdateContentsPosAfterListing = true;
+
+ m_paOutstandingOverlays.clear();
+
+ // Start the directory lister !
+ m_dirLister->openURL( url, false, args.reload );
+
+ // View properties (icon size, background, ..) will be applied into slotClear()
+ // if m_bDirPropertiesChanged is set. If so, here we update preview actions.
+ if ( m_bDirPropertiesChanged )
+ {
+ m_paDotFiles->setChecked( m_pProps->isShowingDotFiles() );
+ m_paDirectoryOverlays->setChecked( m_pProps->isShowingDirectoryOverlays() );
+ m_paEnablePreviews->setChecked( m_pProps->isShowingPreview() );
+ for ( m_paPreviewPlugins.first(); m_paPreviewPlugins.current(); m_paPreviewPlugins.next() )
+ {
+ QStringList types = QStringList::split( ',', m_paPreviewPlugins.current()->name() );
+ bool enabled = false;
+ for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
+ if ( m_pProps->isShowingPreview( *it ) )
+ {
+ enabled = true;
+ break;
+ }
+ m_paPreviewPlugins.current()->setChecked( enabled );
+ m_paPreviewPlugins.current()->setEnabled( m_pProps->isShowingPreview() );
+ }
+ }
+
+ const QString prettyURL = url.pathOrURL();
+ emit setWindowCaption( prettyURL );
+
+ return true;
+}
+
+void KonqKfmIconView::slotKFindOpened()
+{
+ m_dirLister->setAutoUpdate( false );
+}
+
+void KonqKfmIconView::slotKFindClosed()
+{
+ m_dirLister->setAutoUpdate( true );
+}
+
+void KonqKfmIconView::slotOnItem( QIconViewItem *item )
+{
+ emit setStatusBarText( static_cast<KFileIVI *>(item)->item()->getStatusBarInfo() );
+ emitMouseOver( static_cast<KFileIVI*>(item)->item());
+}
+
+void KonqKfmIconView::slotOnViewport()
+{
+ KFileItemList lst = m_pIconView->selectedFileItems();
+ emitCounts( lst, false );
+ emitMouseOver( 0 );
+}
+
+void KonqKfmIconView::setViewMode( const QString &mode )
+{
+ if ( mode == m_mode )
+ return;
+ // note: this should be moved to KonqIconViewWidget. It would make the code
+ // more readable :)
+
+ m_mode = mode;
+ if (mode=="MultiColumnView")
+ {
+ m_pIconView->setArrangement(QIconView::TopToBottom);
+ m_pIconView->setItemTextPos(QIconView::Right);
+ }
+ else
+ {
+ m_pIconView->setArrangement(QIconView::LeftToRight);
+ m_pIconView->setItemTextPos(QIconView::Bottom);
+ }
+
+ if ( m_bPreviewRunningBeforeCloseURL )
+ {
+ m_bPreviewRunningBeforeCloseURL = false;
+ // continue (param: false) a preview job interrupted by doCloseURL
+ m_pIconView->startImagePreview( m_pProps->previewSettings(), false );
+ }
+}
+
+void KonqKfmIconView::setupSortKeys()
+{
+ switch ( m_eSortCriterion )
+ {
+ case NameCaseSensitive:
+ m_pIconView->setCaseInsensitiveSort( false );
+ for ( QIconViewItem *it = m_pIconView->firstItem(); it; it = it->nextItem() )
+ it->setKey( it->text() );
+ break;
+ case NameCaseInsensitive:
+ m_pIconView->setCaseInsensitiveSort( true );
+ for ( QIconViewItem *it = m_pIconView->firstItem(); it; it = it->nextItem() )
+ it->setKey( it->text().lower() );
+ break;
+ case Size:
+ for ( QIconViewItem *it = m_pIconView->firstItem(); it; it = it->nextItem() )
+ it->setKey( makeSizeKey( (KFileIVI *)it ) );
+ break;
+ case Type:
+ // Sort by Type + Name (#17014)
+ for ( QIconViewItem *it = m_pIconView->firstItem(); it; it = it->nextItem() )
+ it->setKey( static_cast<KFileIVI *>( it )->item()->mimetype() + "\008" + it->text().lower() );
+ break;
+ case Date:
+ {
+ //Sorts by time of modification (#52750)
+ QDateTime dayt;
+ for ( QIconViewItem *it = m_pIconView->firstItem(); it; it = it->nextItem() )
+ {
+ dayt.setTime_t(static_cast<KFileIVI *>( it )->item()->time(KIO::UDS_MODIFICATION_TIME));
+ it->setKey(dayt.toString("yyyyMMddhhmmss"));
+ }
+ break;
+ }
+ }
+}
+
+QString KonqKfmIconView::makeSizeKey( KFileIVI *item )
+{
+ return KIO::number( item->item()->size() ).rightJustify( 20, '0' );
+}
+
+void KonqKfmIconView::disableIcons( const KURL::List & lst )
+{
+ m_pIconView->disableIcons( lst );
+}
+
+
+SpringLoadingManager *SpringLoadingManager::s_self = 0L;
+static KStaticDeleter<SpringLoadingManager> s_springManagerDeleter;
+
+SpringLoadingManager::SpringLoadingManager()
+ : m_startPart(0L)
+{
+ connect( &m_endTimer, SIGNAL( timeout() ),
+ this, SLOT( finished() ) );
+
+}
+
+SpringLoadingManager &SpringLoadingManager::self()
+{
+ if ( !s_self )
+ {
+ s_springManagerDeleter.setObject(s_self, new SpringLoadingManager());
+ }
+
+ return *s_self;
+}
+
+bool SpringLoadingManager::exists()
+{
+ return s_self!=0L;
+}
+
+
+void SpringLoadingManager::springLoadTrigger(KonqKfmIconView *view,
+ KFileItem *file,
+ QIconViewItem *item)
+{
+ if ( !file || !file->isDir() )
+ return;
+
+ // We start a new spring loading chain
+ if ( m_startPart==0L )
+ {
+ m_startURL = view->url();
+ m_startPart = view;
+ }
+
+ // Only the last part of the chain is allowed to trigger a spring load
+ // event (if a spring loading chain is in progress)
+ if ( view!=m_startPart )
+ return;
+
+
+ item->setSelected( false, true );
+ view->iconViewWidget()->visualActivate(item);
+
+ KURL url = file->url();
+
+ KParts::URLArgs args;
+ file->determineMimeType();
+ if ( file->isMimeTypeKnown() )
+ args.serviceType = file->mimetype();
+ args.trustedSource = true;
+
+ // Open the folder URL, we don't want to modify the browser
+ // history, hence the use of openURL and setLocationBarURL
+ view->openURL(url);
+ const QString prettyURL = url.pathOrURL();
+ emit view->extension()->setLocationBarURL( prettyURL );
+}
+
+void SpringLoadingManager::dragLeft(KonqKfmIconView */*view*/)
+{
+ // We leave a view maybe the user tries to cancel the current spring loading
+ if ( !m_startURL.isEmpty() )
+ {
+ m_endTimer.start(1000, true);
+ }
+}
+
+void SpringLoadingManager::dragEntered(KonqKfmIconView *view)
+{
+ // We enter a view involved in the spring loading chain
+ if ( !m_startURL.isEmpty() && m_startPart==view )
+ {
+ m_endTimer.stop();
+ }
+}
+
+void SpringLoadingManager::dragFinished(KonqKfmIconView */*view*/)
+{
+ if ( !m_startURL.isEmpty() )
+ {
+ finished();
+ }
+}
+
+
+void SpringLoadingManager::finished()
+{
+ kdDebug() << "SpringLoadManager::finished()" << endl;
+
+ KURL url = m_startURL;
+ m_startURL = KURL();
+
+ KParts::ReadOnlyPart *part = m_startPart;
+ m_startPart = 0L;
+
+ KonqKfmIconView *view = static_cast<KonqKfmIconView*>(part);
+ view->openURL(url);
+ const QString prettyURL = url.pathOrURL();
+ emit view->extension()->setLocationBarURL( prettyURL );
+
+ deleteLater();
+ s_self = 0L;
+ s_springManagerDeleter.setObject(s_self, static_cast<SpringLoadingManager*>(0L));
+}
+
+
+
+#include "konq_iconview.moc"
diff --git a/konqueror/iconview/konq_iconview.desktop b/konqueror/iconview/konq_iconview.desktop
new file mode 100644
index 000000000..2d355b771
--- /dev/null
+++ b/konqueror/iconview/konq_iconview.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Type=Service
+Name=Icon View
+Name[af]=Ikoon Besigtig
+Name[ar]=عرض أيقوني
+Name[az]=Timsal Görünüşü
+Name[be]=Значкі
+Name[bg]=Преглед с икони
+Name[bn]=আইকন ভিউ
+Name[br]=Gwel Arlun
+Name[bs]=Ikone
+Name[ca]=Vista d'icones
+Name[cs]=Pohled s ikonami
+Name[csb]=Wëzdrzatk ikònów
+Name[cy]=Golwg Eicon
+Name[da]=Ikonvisning
+Name[de]=Symbolansicht
+Name[el]=Προβολή εικονιδίων
+Name[eo]=Piktogramrigardo
+Name[es]=Vista de iconos
+Name[et]=Vaade ikoonidena
+Name[eu]=Koadro txikidun ikuspegia
+Name[fa]=شمایل‌نما
+Name[fi]=Kuvakenäkymä
+Name[fr]=Icônes
+Name[fy]=Byldkaike werjefte
+Name[ga]=Amharc Deilbhíní
+Name[gl]=Vista en Iconas
+Name[he]=תצוגת סמלים
+Name[hi]=प्रतीक दृश्य
+Name[hr]=Prikaz ikona
+Name[hu]=Ikonos
+Name[id]=Tampilan Ikon
+Name[is]=Táknmyndasýn
+Name[it]=Vista a icone
+Name[ja]=アイコンビュー
+Name[ka]=ხატულებით ჩვენება
+Name[kk]=Таңбаша түрінде
+Name[km]=ទិដ្ឋភាព​រូបតំណាង
+Name[lo]=ມຸມມອງແບບໄອຄອນ
+Name[lt]=Rodyti ženkliukus
+Name[lv]=Ikonu Skatījums
+Name[mk]=Приказ со икони
+Name[mn]=Тэмдэгээр харах
+Name[ms]=Paparan Ikon
+Name[mt]=Ikoni
+Name[nb]=Ikonvisning
+Name[nds]=Lüttbildansicht
+Name[ne]=प्रतिमा दृश्य
+Name[nl]=Pictogramweergave
+Name[nn]=Ikon-vising
+Name[nso]=Pono ya Seemedi
+Name[pa]=ਆਈਕਾਨ ਝਲਕ
+Name[pl]=Widok ikon
+Name[pt]=Vista por Ícones
+Name[pt_BR]=Visão em Ícones
+Name[ro]=Vizualizare iconică
+Name[ru]=В виде значков
+Name[rw]=Igaragaza ry'Agashushondanga
+Name[se]=Govaščájeheapmi
+Name[sk]=Prehliadač ikon
+Name[sl]=Ikoniziran pogled
+Name[sr]=Приказ са иконама
+Name[sr@Latn]=Prikaz sa ikonama
+Name[sv]=Ikonvy
+Name[ta]=குறும்படக் காட்சி
+Name[te]=ప్రతిమ విక్షణ
+Name[tg]=Ба намуди нишона
+Name[th]=มุมมองแบบไอคอน
+Name[tr]=Simge Görünümü
+Name[tt]=İkonlı Küreneş
+Name[uk]=Вигляд піктограмами
+Name[uz]=Nishoncha koʻrinishida
+Name[uz@cyrillic]=Нишонча кўринишида
+Name[ven]=Mbonalelo ya aikhono
+Name[vi]=Xem kiểu Biểu tượng
+Name[wa]=Vey en imådjetes
+Name[xh]=Imboniselo Yophawu lomfanekiso
+Name[zh_CN]=图标视图
+Name[zh_TW]=圖示瀏覽
+Name[zu]=Umbukiso wophawu lwesithombe
+MimeType=inode/directory
+ServiceTypes=KParts/ReadOnlyPart,Browser/View
+X-KDE-Library=konq_iconview
+X-KDE-BrowserView-AllowAsDefault=true
+X-KDE-BrowserView-HideFromMenus=true
+X-KDE-BrowserView-Args=IconView
+X-KDE-BrowserView-ModeProperty=viewMode
+X-KDE-BrowserView-ModePropertyValue=IconView
+X-KDE-BrowserView-Built-Into=konqueror
+Icon=view_icon
+InitialPreference=10
diff --git a/konqueror/iconview/konq_iconview.h b/konqueror/iconview/konq_iconview.h
new file mode 100644
index 000000000..7563fedcd
--- /dev/null
+++ b/konqueror/iconview/konq_iconview.h
@@ -0,0 +1,299 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+
+ 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.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __konq_iconview_h__
+#define __konq_iconview_h__
+
+#include <kparts/browserextension.h>
+#include <konq_iconviewwidget.h>
+#include <konq_operations.h>
+#include <konq_dirpart.h>
+#include <kmimetyperesolver.h>
+#include <qptrdict.h>
+#include <qptrlist.h>
+#include <kfileivi.h>
+
+class KonqPropsView;
+class KFileItem;
+class KDirLister;
+class KAction;
+class KToggleAction;
+class KActionMenu;
+class QIconViewItem;
+class IconViewBrowserExtension;
+
+/**
+ * The Icon View for konqueror.
+ * The "Kfm" in the name stands for file management since it shows files :)
+ */
+class KonqKfmIconView : public KonqDirPart
+{
+ friend class IconViewBrowserExtension; // to access m_pProps
+ Q_OBJECT
+ Q_PROPERTY( bool supportsUndo READ supportsUndo )
+ Q_PROPERTY( QString viewMode READ viewMode WRITE setViewMode )
+public:
+
+ enum SortCriterion { NameCaseSensitive, NameCaseInsensitive, Size, Type, Date };
+
+ KonqKfmIconView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode );
+ virtual ~KonqKfmIconView();
+
+ virtual const KFileItem * currentItem();
+ virtual KFileItemList selectedFileItems() {return m_pIconView->selectedFileItems();};
+
+
+ KonqIconViewWidget *iconViewWidget() const { return m_pIconView; }
+
+ bool supportsUndo() const { return true; }
+
+ void setViewMode( const QString &mode );
+ QString viewMode() const { return m_mode; }
+
+ // "Cut" icons : disable those whose URL is in lst, enable the rest
+ virtual void disableIcons( const KURL::List & lst );
+
+ // See KMimeTypeResolver
+ void mimeTypeDeterminationFinished();
+ void determineIcon( KFileIVI * item );
+ int iconSize() { return m_pIconView->iconSize(); }
+
+public slots:
+ void slotPreview( bool toggle );
+ void slotShowDirectoryOverlays();
+ void slotShowDot();
+ void slotSelect();
+ void slotUnselect();
+ void slotSelectAll();
+ void slotUnselectAll();
+ void slotInvertSelection();
+
+ void slotSortByNameCaseSensitive( bool toggle );
+ void slotSortByNameCaseInsensitive( bool toggle );
+ void slotSortBySize( bool toggle );
+ void slotSortByType( bool toggle );
+ void slotSortByDate( bool toggle );
+ void slotSortDescending();
+ void slotSortDirsFirst();
+
+protected slots:
+ // slots connected to QIconView
+ void slotReturnPressed( QIconViewItem *item );
+ void slotMouseButtonPressed(int, QIconViewItem*, const QPoint&);
+ void slotMouseButtonClicked(int, QIconViewItem*, const QPoint&);
+ void slotContextMenuRequested(QIconViewItem*, const QPoint&);
+ void slotOnItem( QIconViewItem *item );
+ void slotOnViewport();
+ void slotSelectionChanged();
+
+ // Slot used for spring loading folders
+ void slotDragHeld( QIconViewItem *item );
+ void slotDragMove( bool accepted );
+ void slotDragEntered( bool accepted );
+ void slotDragLeft();
+ void slotDragFinished();
+
+ // slots connected to the directory lister - or to the kfind interface
+ // They are reimplemented from KonqDirPart.
+ virtual void slotStarted();
+ virtual void slotCanceled();
+ void slotCanceled( const KURL& url );
+ virtual void slotCompleted();
+ virtual void slotNewItems( const KFileItemList& );
+ virtual void slotDeleteItem( KFileItem * );
+ virtual void slotRefreshItems( const KFileItemList& );
+ virtual void slotClear();
+ virtual void slotRedirection( const KURL & );
+ virtual void slotDirectoryOverlayStart();
+ virtual void slotDirectoryOverlayFinished();
+
+ /**
+ * This is the 'real' finished slot, where we emit the completed() signal
+ * after everything was done.
+ */
+ void slotRenderingFinished();
+ // (Re)Draws m_pIconView's contents. Connected to m_pTimeoutRefreshTimer.
+ void slotRefreshViewport();
+
+ // Connected to KonqDirPart
+ void slotKFindOpened();
+ void slotKFindClosed();
+
+protected:
+ virtual bool openFile() { return true; }
+ virtual bool doOpenURL( const KURL& );
+ virtual bool doCloseURL();
+
+ virtual void newIconSize( int size );
+
+ void setupSorting( SortCriterion criterion );
+
+ /** */
+ void setupSortKeys();
+
+ QString makeSizeKey( KFileIVI *item );
+
+ /** The directory lister for this URL */
+ KDirLister* m_dirLister;
+
+ /**
+ * Set to true while the constructor is running.
+ * @ref #initConfig needs to know about that.
+ */
+ bool m_bInit:1;
+
+ /**
+ * Set to true while the dirlister is running, _if_ we asked it
+ * explicitly (openURL). If it is auto-updating, this is not set to true.
+ */
+ bool m_bLoading:1;
+
+ /**
+ * Set to true if we still need to emit completed() at some point
+ * (after the loading is finished and after the visible icons have been
+ * processed)
+ */
+ bool m_bNeedEmitCompleted:1;
+
+ /**
+ * Set to true if slotCompleted needs to realign the icons
+ */
+ bool m_bNeedAlign:1;
+
+ bool m_bUpdateContentsPosAfterListing:1;
+
+ bool m_bDirPropertiesChanged:1;
+
+ /**
+ * Set in doCloseURL and used in setViewMode to restart a preview
+ * job interrupted when switching to IconView or MultiColumnView.
+ * Hacks like this must be removed in KDE4!
+ */
+ bool m_bPreviewRunningBeforeCloseURL:1;
+
+ bool m_bNeedSetCurrentItem:1;
+
+ KFileIVI * m_pEnsureVisible;
+
+ QStringList m_itemsToSelect;
+
+ SortCriterion m_eSortCriterion;
+
+ KToggleAction *m_paDotFiles;
+ KToggleAction *m_paDirectoryOverlays;
+ KToggleAction *m_paEnablePreviews;
+ QPtrList<KFileIVI> m_paOutstandingOverlays;
+ QTimer *m_paOutstandingOverlaysTimer;
+/* KToggleAction *m_paImagePreview;
+ KToggleAction *m_paTextPreview;
+ KToggleAction *m_paHTMLPreview;*/
+ KActionMenu *m_pamPreview;
+ QPtrList<KToggleAction> m_paPreviewPlugins;
+ KActionMenu *m_pamSort;
+
+ KAction *m_paSelect;
+ KAction *m_paUnselect;
+ KAction *m_paSelectAll;
+ KAction *m_paUnselectAll;
+ KAction *m_paInvertSelection;
+
+ KToggleAction *m_paSortDirsFirst;
+
+ KonqIconViewWidget *m_pIconView;
+
+ QTimer *m_pTimeoutRefreshTimer;
+
+ QPtrDict<KFileIVI> m_itemDict; // maps KFileItem * -> KFileIVI *
+
+ KMimeTypeResolver<KFileIVI,KonqKfmIconView> * m_mimeTypeResolver;
+
+ QString m_mode;
+
+ private:
+ void showDirectoryOverlay(KFileIVI* item);
+};
+
+class IconViewBrowserExtension : public KonqDirPartBrowserExtension
+{
+ Q_OBJECT
+ friend class KonqKfmIconView; // so that it can emit our signals
+public:
+ IconViewBrowserExtension( KonqKfmIconView *iconView );
+
+ virtual int xOffset();
+ virtual int yOffset();
+
+public slots:
+ // Those slots are automatically connected by the shell
+ void reparseConfiguration();
+ void setSaveViewPropertiesLocally( bool value );
+ void setNameFilter( const QString &nameFilter );
+
+ void refreshMimeTypes() { m_iconView->iconViewWidget()->refreshMimeTypes(); }
+
+ void rename() { m_iconView->iconViewWidget()->renameSelectedItem(); }
+ void cut() { m_iconView->iconViewWidget()->cutSelection(); }
+ void copy() { m_iconView->iconViewWidget()->copySelection(); }
+ void paste() { m_iconView->iconViewWidget()->pasteSelection(); }
+ void pasteTo( const KURL &u ) { m_iconView->iconViewWidget()->paste( u ); }
+
+ void trash();
+ void del() { KonqOperations::del(m_iconView->iconViewWidget(),
+ KonqOperations::DEL,
+ m_iconView->iconViewWidget()->selectedUrls()); }
+ void properties();
+ void editMimeType();
+
+ // void print();
+
+private:
+ KonqKfmIconView *m_iconView;
+ bool m_bSaveViewPropertiesLocally;
+};
+
+class SpringLoadingManager : public QObject
+{
+ Q_OBJECT
+private:
+ SpringLoadingManager();
+ static SpringLoadingManager *s_self;
+public:
+ static SpringLoadingManager &self();
+ static bool exists();
+
+ void springLoadTrigger(KonqKfmIconView *view, KFileItem *file,
+ QIconViewItem *item);
+
+ void dragLeft(KonqKfmIconView *view);
+ void dragEntered(KonqKfmIconView *view);
+ void dragFinished(KonqKfmIconView *view);
+
+private slots:
+ void finished();
+
+private:
+ KURL m_startURL;
+ KParts::ReadOnlyPart *m_startPart;
+
+ // Timer allowing to know the user wants to abort the spring loading
+ // and go back to his start url (closing the opened window if needed)
+ QTimer m_endTimer;
+};
+
+
+#endif
diff --git a/konqueror/iconview/konq_iconview.rc b/konqueror/iconview/konq_iconview.rc
new file mode 100644
index 000000000..20551e0a7
--- /dev/null
+++ b/konqueror/iconview/konq_iconview.rc
@@ -0,0 +1,51 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="KonqIconView" version="13">
+<MenuBar>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Menu name="selection"><text>Selection</text>
+ <Action name="select"/>
+ <Action name="unselect"/>
+ <Separator/>
+ <Action name="selectall"/>
+ <Action name="unselectall"/>
+ <Action name="invertselection"/>
+ </Menu>
+ </Menu>
+ <Menu name="view"><text>&amp;View</text>
+ <Menu name="iconview_mode"><text>&amp;Icon Size</text>
+ <Action name="modedefault"/>
+ <Separator/>
+ <Action name="modeenormous"/>
+ <Action name="modehuge"/>
+ <Action name="modelarge"/>
+ <Action name="modemedium"/>
+ <Action name="modesmallmedium"/>
+ <Action name="modesmall"/>
+ </Menu>
+ <Menu name="iconview_sort"><text>S&amp;ort</text>
+ <Action name="sort_nc"/>
+ <Action name="sort_nci"/>
+ <Action name="sort_size"/>
+ <Action name="sort_type"/>
+ <Action name="sort_date"/>
+ <Separator/>
+ <Action name="sort_descend"/>
+ <Separator/>
+ <Action name="sort_directoriesfirst" />
+ </Menu>
+ <Action name="iconview_preview" />
+ <Action name="show_dot"/>
+ <Action name="show_directory_overlays"/>
+ <Separator/>
+ <Action name="bgsettings"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar"><text>Iconview Toolbar</text>
+ <Separator/>
+ <Action name="incIconSize" />
+ <Action name="decIconSize" />
+</ToolBar>
+<ToolBar name="extraToolBar"><text>Iconview Extra Toolbar</text>
+ <Action name="iconview_preview_all" />
+</ToolBar>
+</kpartgui>
diff --git a/konqueror/iconview/konq_multicolumnview.desktop b/konqueror/iconview/konq_multicolumnview.desktop
new file mode 100644
index 000000000..94b6c7288
--- /dev/null
+++ b/konqueror/iconview/konq_multicolumnview.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Type=Service
+Name=MultiColumn View
+Name[af]=Multi-kolom Besigtig
+Name[ar]=عرض متعدد الأعمدة
+Name[az]=Çoxlu Sütun Görünüşü
+Name[be]=Шмат слупкоў
+Name[bg]=Многоколонен преглед
+Name[bn]=মাল্টিকলাম ভিউ
+Name[br]=Gwel liesbann
+Name[bs]=Višekolonski pogled
+Name[ca]=Vista multicolumna
+Name[cs]=Vícesloupcový pohled
+Name[csb]=Wieloszpaltowi wëzdrzatk
+Name[cy]=Golwg Aml-golofn
+Name[da]=Multisøjlevisning
+Name[de]=Mehrspaltige Ansicht
+Name[el]=Προβολή πολλαπλών στηλών
+Name[eo]=Multkolumna rigardo
+Name[es]=Vista multicolumna
+Name[et]=Vaade mitme tulbana
+Name[eu]=Zutabe aniztun ikuspegia
+Name[fa]=نمای چند ستونی
+Name[fi]=Monipalstanäkymä
+Name[fr]=Multicolonne
+Name[fy]=Multykolomwerjefte
+Name[ga]=Amharc Il-cholúin
+Name[gl]=Vista en Múltiplas Colunas
+Name[he]=תצוגת טורים
+Name[hi]=अनेक-स्तम्भ दृश्य
+Name[hr]=Prikaz s više stupaca
+Name[hu]=Lista
+Name[id]=Tampilan Multi kolom
+Name[is]=Dálkskipt sýn
+Name[it]=Vista a colonne multiple
+Name[ja]=マルチカラムビュー
+Name[ka]=რამდენიმე სვეტად
+Name[kk]=Бірнеше баған
+Name[km]=ទិដ្ឋភាព​ច្រើន​ជួរឈរ
+Name[lo]=ມຸນມອງແບບຫລາຍຄໍລຳ
+Name[lt]=Rodyti keliais stulpeliais
+Name[lv]=Daudzkolonu Skatījums
+Name[mk]=Приказ со повеќе колони
+Name[mn]=Олон баганаар харах
+Name[ms]=Paparan MultiColumn
+Name[mt]=Kolonni
+Name[nb]=Flerkolonnevisning
+Name[nds]=Mehrstriepen-Ansicht
+Name[ne]=बहुविध स्तम्भ दृश्य
+Name[nl]=Multikolomweergave
+Name[nn]=Multikolonne-vising
+Name[nso]=Pono ya Kholomo ya Bontshi
+Name[pa]=ਬਹੁ-ਕਾਲਮ ਝਲਕ
+Name[pl]=Widok wielokolumnowy
+Name[pt]=Vista por Multi-colunas
+Name[pt_BR]=Visão Multicolunas
+Name[ro]=Vizualizare multicoloană
+Name[ru]=В несколько колонок
+Name[rw]=Igaragaza InkingiZitandukanye
+Name[se]=Moanábálsttá-čájeheapmi
+Name[sk]=Multi-stĺpcový pohľad
+Name[sl]=Večstolpčni pogled
+Name[sr]=Приказ са више колона
+Name[sr@Latn]=Prikaz sa više kolona
+Name[sv]=Flerkolumnsvy
+Name[ta]=பலநெடுவரிசை காட்சி
+Name[te]=ఎక్కువ నిలువవరుసల విక్షణ
+Name[tg]=Ба намуди чанд сутун
+Name[th]=มุมมองแบบหลายคอลัมน์
+Name[tr]=Çoklu Sütun Görünümü
+Name[tt]=Berniçä Asma belän
+Name[uk]=Вигляд стовпчиками
+Name[uz]=Koʻp ustun koʻrinishida
+Name[uz@cyrillic]=Кўп устун кўринишида
+Name[ven]=Mbonalelo ya kholomu dzo fhambananho
+Name[vi]=Xem kiểu Nhiều cột
+Name[wa]=Vey e colones
+Name[xh]=Imboniselo Enemihlathi emininzie
+Name[zh_CN]=多列视图
+Name[zh_TW]=多列瀏覽
+Name[zu]=Umbukiso onamakholumu amaningi
+MimeType=inode/directory
+ServiceTypes=KParts/ReadOnlyPart,Browser/View
+X-KDE-Library=konq_iconview
+X-KDE-BrowserView-AllowAsDefault=true
+X-KDE-BrowserView-HideFromMenus=true
+X-KDE-BrowserView-Args=MultiColumnView
+X-KDE-BrowserView-ModeProperty=viewMode
+X-KDE-BrowserView-ModePropertyValue=MultiColumnView
+X-KDE-BrowserView-Built-Into=konqueror
+Icon=view_multicolumn
+InitialPreference=9
diff --git a/konqueror/iconview/konq_multicolumnview.rc b/konqueror/iconview/konq_multicolumnview.rc
new file mode 100644
index 000000000..7da55beb6
--- /dev/null
+++ b/konqueror/iconview/konq_multicolumnview.rc
@@ -0,0 +1,47 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd" >
+<kpartgui name="KonqIconView" version="11">
+<MenuBar>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Menu name="selection"><text>Selection</text>
+ <Action name="select"/>
+ <Action name="unselect"/>
+ <Separator/>
+ <Action name="selectall"/>
+ <Action name="unselectall"/>
+ <Action name="invertselection"/>
+ </Menu>
+ </Menu>
+ <Menu name="view"><text>&amp;View</text>
+ <Menu name="iconview_mode"><text>Icon Size</text>
+ <Action name="modedefault"/>
+ <Separator/>
+ <Action name="modeenormous"/>
+ <Action name="modehuge"/>
+ <Action name="modelarge"/>
+ <Action name="modemedium"/>
+ <Action name="modesmallmedium"/>
+ <Action name="modesmall"/>
+ </Menu>
+ <Menu name="iconview_sort"><text>Sort</text>
+ <Action name="sort_nc"/>
+ <Action name="sort_nci"/>
+ <Action name="sort_size"/>
+ <Action name="sort_type"/>
+ <Action name="sort_date"/>
+ <Separator/>
+ <Action name="sort_descend"/>
+ <Separator/>
+ <Action name="sort_directoriesfirst" />
+ </Menu>
+ <Action name="iconview_preview" />
+ <Action name="show_dot"/>
+ <Separator/>
+ <Action name="bgsettings"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar"><text>Multicolumn View Toolbar</text>
+ <Separator/>
+ <Action name="incIconSize" />
+ <Action name="decIconSize" />
+</ToolBar>
+</kpartgui>
diff --git a/konqueror/keditbookmarks/DESIGN b/konqueror/keditbookmarks/DESIGN
new file mode 100644
index 000000000..9ef300f81
--- /dev/null
+++ b/konqueror/keditbookmarks/DESIGN
@@ -0,0 +1,20 @@
+four main layers:
+ toplevel : startup, initialisation
+ listview : listview, selection, action forwarding
+ commands : bookmark undo/redo mechanism implementation
+ actionsimpl : the actual slots, almost all of 'em
+
+various other thingies:
+ search : incremental search implementation
+ favicons : iterating action implementation using bookmarkiterator
+ importers : forwarders to kio/bookmarks code
+ exporters : forwarders to kio/bookmarks code, and html export code
+ dcop : dcop handling, internal interface
+ bookmarkiterator : is a baseclass for iterating actions, of sorts...
+ updater : favicon updating base stuff - kio/khtml crap
+ testlink : link testing stuff
+
+3 different selection styles:
+ bookmark iterators (ITR_ACTION)
+ single bookmark (ITEM_ACTION)
+ normal selection (SELC_ACTION)
diff --git a/konqueror/keditbookmarks/Makefile.am b/konqueror/keditbookmarks/Makefile.am
new file mode 100644
index 000000000..3987d5944
--- /dev/null
+++ b/konqueror/keditbookmarks/Makefile.am
@@ -0,0 +1,34 @@
+INCLUDES= -I$(top_srcdir)/libkonq $(all_includes)
+
+METASOURCES = AUTO
+
+bin_PROGRAMS = kbookmarkmerger
+lib_LTLIBRARIES =
+kdeinit_LTLIBRARIES = keditbookmarks.la
+
+kbookmarkmerger_SOURCES = kbookmarkmerger.cpp
+kbookmarkmerger_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kbookmarkmerger_LDADD = $(LIB_KIO)
+
+dcop_DCOPIDLNG = true
+keditbookmarks_la_SOURCES = main.cpp listview.cpp toplevel.cpp actionsimpl.cpp commands.cpp importers.cpp dcop.skel dcop.cpp bookmarkiterator.cpp \
+ testlink.cpp favicons.cpp updater.cpp exporters.cpp kbookmarknotifier.stub bookmarkinfo.cpp kebsearchline.cpp settings.kcfgc
+kbookmarknotifier_DIR = $(includedir)
+keditbookmarks_la_LIBADD = $(top_builddir)/libkonq/libkonq.la
+keditbookmarks_la_LDFLAGS = $(all_libraries) -module -avoid-version
+
+rcdir = $(kde_datadir)/keditbookmarks
+rc_DATA = keditbookmarksui.rc keditbookmarks-genui.rc
+
+install-data-local: uninstall.desktop
+ $(mkinstalldirs) $(DESTDIR)$(kde_appsdir)/Internet
+ $(INSTALL_DATA) $(srcdir)/uninstall.desktop $(DESTDIR)$(kde_appsdir)/Internet/keditbookmarks.desktop
+
+KDE_ICON = AUTO
+
+kde_kcfg_DATA = keditbookmarks.kcfg
+
+####### Build rules
+listview.lo: settings.h
+settings.lo: settings.h
+toplevel.lo: settings.h
diff --git a/konqueror/keditbookmarks/TODO b/konqueror/keditbookmarks/TODO
new file mode 100644
index 000000000..875dea715
--- /dev/null
+++ b/konqueror/keditbookmarks/TODO
@@ -0,0 +1,120 @@
+toolbar is not updating on save in editor
+editor does not have undo after save
+deleting folders from the quick actions menu is b0rked
+
+(#1)
+68161 : Favicons are lost on upgrade
+ - nothing to do with bookmarks, but, no idea where to put it,
+ so, whatever, i'll handle it anyways...
+
+ - problem: .kde/share/cache/favicons moved to .kde/`hostname`-cache/favicons
+
+ - fix: either 1) a symlink, 2) upgrade path
+
+67635 : Bookmarks toolbar edits don't take effect until restart
+ - completely unable to confirm, and can't recall fixing this in the past.. umm..
+
+67614 : abort bookmark's context menu causes bookmark to load
+ - can't reproduce... maybe a new / old qt bug...
+
+67686 : bookmark bar first displayed empty
+ - can't reproduce, maybe need to check from an empty .kde, thus no previous
+
+67958 : bookmark toolbar intermittenly disappears
+ - maybe just another dup of tokoe's bug
+
+67685 : crash often kills bookmarks AND backup
+ - how the heck does a crash wipe the bookmarks.xml in the first place?
+ well, whatever. i admit this can be improved, but only through new i18n's
+ so thats not going to happen until i get permission for 3.2.1...
+
+somehow multi selected deletes are broken again:
+ no longer crashes, but doesn't select current well
+ TODO note added to program, quite a difficult problem...
+a selected folder only takes one click to get a rename???
+tbcache: don't create a tbcache file when its gonna be empty in any case!!!
+historymgr: get dirtyness working for the kbookmarkmap
+proper readonly support - rmb should work but things should be disabled? no addbookmark, etc.
+general xbel bug: http://bugzilla.gnome.org/show_bug.cgi?id=69702
+
+possible qt bug:
+ multi selection deletion then shift down selects roots
+ valgrind doesn't show anything either
+ logging all the setSelected calls i can see doesn't help
+
+STUFF FROM BEINERI:
+
+ And the "Cancel" entries in the "Bookmark" menus looks strange too. How about
+ a KMail-like progress bar (in a status bar?) with an "X" button to stop them?
+ And "Advanced Add Bookmark" doesn't work for "Add Bookmark" in context menu?
+
+---
+
+ Btw, I think when you have no tab and call "Bookmarks Tabs as Folder..."
+ it should not only create a folder but bookmark the current page within
+ the folder unconditional if it's a tab or not. :-)
+
+CHECKS
+------
+
+valgrind report:
+
+on startup:
+ ==31246== Conditional jump or move depends on uninitialised value(s)
+ ==31246== at 0x4026A4DF: KEBListViewItem::paintCell(QPainter*, QColorGroup const&, int, int, int) (listview.cpp:786)
+ ==31246== by 0x40FD9CA7: QListView::drawContentsOffset(QPainter*, int, int, int, int, int, int) (qlistview.cpp:2905)
+ ==31246== by 0x41013A5D: QScrollView::viewportPaintEvent(QPaintEvent*) (qscrollview.cpp:1702)
+ ==31246== by 0x407E7051: KListView::viewportPaintEvent(QPaintEvent*) (klistview.cpp:1872)
+ ==31246==
+ ==31246== Conditional jump or move depends on uninitialised value(s)
+ ==31246== at 0x4026A4E4: KEBListViewItem::paintCell(QPainter*, QColorGroup const&, int, int, int) (listview.cpp:786)
+ ==31246== by 0x40FD9CA7: QListView::drawContentsOffset(QPainter*, int, int, int, int, int, int) (qlistview.cpp:2905)
+ ==31246== by 0x41013A5D: QScrollView::viewportPaintEvent(QPaintEvent*) (qscrollview.cpp:1702)
+ ==31246== by 0x407E7051: KListView::viewportPaintEvent(QPaintEvent*) (klistview.cpp:1872)
+ ==31246==
+ ==31246== Conditional jump or move depends on uninitialised value(s)
+ ==31246== at 0x4026A4E8: KEBListViewItem::paintCell(QPainter*, QColorGroup const&, int, int, int) (listview.cpp:786)
+ ==31246== by 0x40FD9CA7: QListView::drawContentsOffset(QPainter*, int, int, int, int, int, int) (qlistview.cpp:2905)
+ ==31246== by 0x41013A5D: QScrollView::viewportPaintEvent(QPaintEvent*) (qscrollview.cpp:1702)
+ ==31246== by 0x407E7051: KListView::viewportPaintEvent(QPaintEvent*) (klistview.cpp:1872)
+ ==31246==
+
+lots of crap when using file->open
+
+with memcheck
+ ==20415== 420 bytes in 14 blocks are definitely lost in loss record 107 of 146
+ ==20415== at 0x40029B01: __builtin_new (in /usr/lib/valgrind/vgskin_memcheck.so)
+ ==20415== by 0x40029B6C: operator new(unsigned) (in /usr/lib/valgrind/vgskin_memcheck.so)
+ ==20415== by 0x402669AA: KEBListView::itemList() (listview.cpp:682)
+ ==20415== by 0x402634EA: ListView::selectedItems() const (qptrlist.h:157)
+
+
+DONE TESTING:
+------------
+
+ favicon and status check updates:
+ removal of items while checks are happening
+ program exit with checks and updates are still going on
+ random deletion of all items - TODO
+
+THINGS FOR 3.3+
+------------------
+
+tools:
+ recursive 404 finder
+ duplicate finder
+
+basic gui:
+ split view stuff - including filtered views
+ need to get keyboard shortcut changes working somehow (wheels)
+ have to get dynamic filtering (e.g sorting, pruning),
+
+main bookmark config:
+ make the keditbookmarks prefs persistant
+ and make a simple include selector using
+ for example kautoconfig, including a
+ simple dynamic menu config gui
+
+bookmarklets: add some examples!
+
+tips dialog - fixes bugs - shortcuts for keyboard selection are wierd
diff --git a/konqueror/keditbookmarks/actionsimpl.cpp b/konqueror/keditbookmarks/actionsimpl.cpp
new file mode 100644
index 000000000..f0e8426d9
--- /dev/null
+++ b/konqueror/keditbookmarks/actionsimpl.cpp
@@ -0,0 +1,638 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "actionsimpl.h"
+
+#include "toplevel.h"
+#include "commands.h"
+#include "importers.h"
+#include "favicons.h"
+#include "testlink.h"
+#include "listview.h"
+#include "exporters.h"
+#include "bookmarkinfo.h"
+
+#include <stdlib.h>
+
+#include <qclipboard.h>
+#include <qpopupmenu.h>
+#include <qpainter.h>
+
+#include <klocale.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kkeydialog.h>
+#include <kmessagebox.h>
+#include <kinputdialog.h>
+#include <krun.h>
+
+#include <kdatastream.h>
+#include <ktempfile.h>
+#include <kstandarddirs.h>
+
+#include <kparts/part.h>
+#include <kparts/componentfactory.h>
+
+#include <kicondialog.h>
+#include <kiconloader.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+#include <kbookmarkimporter.h>
+
+#include <kbookmarkimporter_ie.h>
+#include <kbookmarkimporter_opera.h>
+#include <kbookmarkexporter.h>
+
+ActionsImpl* ActionsImpl::s_self = 0;
+
+// decoupled from resetActions in toplevel.cpp
+// as resetActions simply uses the action groups
+// specified in the ui.rc file
+void KEBApp::createActions() {
+
+ ActionsImpl *actn = ActionsImpl::self();
+
+ // save and quit should probably not be in the toplevel???
+ (void) KStdAction::quit(
+ this, SLOT( close() ), actionCollection());
+ KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection());
+ (void) KStdAction::configureToolbars(
+ this, SLOT( slotConfigureToolbars() ), actionCollection());
+
+ if (m_browser) {
+ (void) KStdAction::open(
+ actn, SLOT( slotLoad() ), actionCollection());
+ (void) KStdAction::saveAs(
+ actn, SLOT( slotSaveAs() ), actionCollection());
+ }
+
+ (void) KStdAction::cut(actn, SLOT( slotCut() ), actionCollection());
+ (void) KStdAction::copy(actn, SLOT( slotCopy() ), actionCollection());
+ (void) KStdAction::paste(actn, SLOT( slotPaste() ), actionCollection());
+ (void) KStdAction::print(actn, SLOT( slotPrint() ), actionCollection());
+
+ // settings menu
+ (void) new KToggleAction(
+ i18n("&Show Netscape Bookmarks in Konqueror"), 0,
+ actn, SLOT( slotShowNS() ), actionCollection(),
+ "settings_showNS");
+
+ // actions
+ (void) new KAction(
+ i18n("&Delete"), "editdelete", Key_Delete,
+ actn, SLOT( slotDelete() ), actionCollection(), "delete");
+ (void) new KAction(
+ i18n("Rename"), "text", Key_F2,
+ actn, SLOT( slotRename() ), actionCollection(), "rename");
+ (void) new KAction(
+ i18n("C&hange URL"), "text", Key_F3,
+ actn, SLOT( slotChangeURL() ), actionCollection(), "changeurl");
+ (void) new KAction(
+ i18n("C&hange Comment"), "text", Key_F4,
+ actn, SLOT( slotChangeComment() ), actionCollection(), "changecomment");
+ (void) new KAction(
+ i18n("Chan&ge Icon..."), "icons", 0,
+ actn, SLOT( slotChangeIcon() ), actionCollection(), "changeicon");
+ (void) new KAction(
+ i18n("Update Favicon"), 0,
+ actn, SLOT( slotUpdateFavIcon() ), actionCollection(), "updatefavicon");
+ (void) new KAction(
+ i18n("Recursive Sort"), 0,
+ actn, SLOT( slotRecursiveSort() ), actionCollection(), "recursivesort");
+ (void) new KAction(
+ i18n("&New Folder..."), "folder_new", CTRL+Key_N,
+ actn, SLOT( slotNewFolder() ), actionCollection(), "newfolder");
+ (void) new KAction(
+ i18n("&New Bookmark"), "www", 0,
+ actn, SLOT( slotNewBookmark() ), actionCollection(), "newbookmark");
+ (void) new KAction(
+ i18n("&Insert Separator"), CTRL+Key_I,
+ actn, SLOT( slotInsertSeparator() ), actionCollection(),
+ "insertseparator");
+ (void) new KAction(
+ i18n("&Sort Alphabetically"), 0,
+ actn, SLOT( slotSort() ), actionCollection(), "sort");
+ (void) new KAction(
+ i18n("Set as T&oolbar Folder"), "bookmark_toolbar", 0,
+ actn, SLOT( slotSetAsToolbar() ), actionCollection(), "setastoolbar");
+ (void) new KAction(
+ i18n("Show in T&oolbar"), "bookmark_toolbar", 0,
+ actn, SLOT( slotShowInToolbar() ), actionCollection(), "showintoolbar");
+ (void) new KAction(
+ i18n("Hide in T&oolbar"), "bookmark_toolbar", 0,
+ actn, SLOT( slotHideInToolbar() ), actionCollection(), "hideintoolbar");
+ (void) new KAction(
+ i18n("&Expand All Folders"), 0,
+ actn, SLOT( slotExpandAll() ), actionCollection(), "expandall");
+ (void) new KAction(
+ i18n("Collapse &All Folders"), 0,
+ actn, SLOT( slotCollapseAll() ), actionCollection(), "collapseall" );
+ (void) new KAction(
+ i18n("&Open in Konqueror"), "fileopen", 0,
+ actn, SLOT( slotOpenLink() ), actionCollection(), "openlink" );
+ (void) new KAction(
+ i18n("Check &Status"), "bookmark", 0,
+ actn, SLOT( slotTestSelection() ), actionCollection(), "testlink" );
+
+ (void) new KAction(
+ i18n("Check Status: &All"), 0,
+ actn, SLOT( slotTestAll() ), actionCollection(), "testall" );
+ (void) new KAction(
+ i18n("Update All &Favicons"), 0,
+ actn, SLOT( slotUpdateAllFavIcons() ), actionCollection(),
+ "updateallfavicons" );
+ (void) new KAction(
+ i18n("Cancel &Checks"), 0,
+ actn, SLOT( slotCancelAllTests() ), actionCollection(), "canceltests" );
+ (void) new KAction(
+ i18n("Cancel &Favicon Updates"), 0,
+ actn, SLOT( slotCancelFavIconUpdates() ), actionCollection(),
+ "cancelfaviconupdates" );
+ (void) new KAction(
+ i18n("Import &Netscape Bookmarks..."), "netscape", 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importNS");
+ (void) new KAction(
+ i18n("Import &Opera Bookmarks..."), "opera", 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importOpera");
+ (void) new KAction(
+ i18n("Import All &Crash Sessions as Bookmarks..."), 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importCrashes");
+ (void) new KAction(
+ i18n("Import &Galeon Bookmarks..."), 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importGaleon");
+ (void) new KAction(
+ i18n("Import &KDE2/KDE3 Bookmarks..."), 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importKDE2");
+ (void) new KAction(
+ i18n("Import &IE Bookmarks..."), 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importIE");
+ (void) new KAction(
+ i18n("Import &Mozilla Bookmarks..."), "mozilla", 0,
+ actn, SLOT( slotImport() ), actionCollection(), "importMoz");
+ (void) new KAction(
+ i18n("Export to &Netscape Bookmarks"), "netscape", 0,
+ actn, SLOT( slotExportNS() ), actionCollection(), "exportNS");
+ (void) new KAction(
+ i18n("Export to &Opera Bookmarks..."), "opera", 0,
+ actn, SLOT( slotExportOpera() ), actionCollection(), "exportOpera");
+ (void) new KAction(
+ i18n("Export to &HTML Bookmarks..."), "html", 0,
+ actn, SLOT( slotExportHTML() ), actionCollection(), "exportHTML");
+ (void) new KAction(
+ i18n("Export to &IE Bookmarks..."), 0,
+ actn, SLOT( slotExportIE() ), actionCollection(), "exportIE");
+ (void) new KAction(
+ i18n("Export to &Mozilla Bookmarks..."), "mozilla", 0,
+ actn, SLOT( slotExportMoz() ), actionCollection(), "exportMoz");
+}
+
+void ActionsImpl::slotLoad() {
+ QString bookmarksFile
+ = KFileDialog::getOpenFileName(QString::null, "*.xml", KEBApp::self());
+ if (bookmarksFile.isNull())
+ return;
+ KEBApp::self()->m_caption = QString::null;
+ KEBApp::self()->m_bookmarksFilename = bookmarksFile;
+ KEBApp::self()->construct();
+}
+
+void ActionsImpl::slotSaveAs() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ QString saveFilename
+ = KFileDialog::getSaveFileName(QString::null, "*.xml", KEBApp::self());
+ if (!saveFilename.isEmpty())
+ CurrentMgr::self()->saveAs(saveFilename);
+}
+
+void CurrentMgr::doExport(ExportType type, const QString & _path) {
+ if(KEBApp::self())
+ KEBApp::self()->bkInfo()->commitChanges();
+ QString path(_path);
+ // TODO - add a factory and make all this use the base class
+ if (type == OperaExport) {
+ if (path.isNull())
+ path = KOperaBookmarkImporterImpl().findDefaultLocation(true);
+ KOperaBookmarkExporterImpl exporter(mgr(), path);
+ exporter.write(mgr()->root());
+ return;
+
+ } else if (type == HTMLExport) {
+ if (path.isNull())
+ path = KFileDialog::getSaveFileName(
+ QDir::homeDirPath(),
+ i18n("*.html|HTML Bookmark Listing") );
+ HTMLExporter exporter;
+ exporter.write(mgr()->root(), path);
+ return;
+
+ } else if (type == IEExport) {
+ if (path.isNull())
+ path = KIEBookmarkImporterImpl().findDefaultLocation(true);
+ KIEBookmarkExporterImpl exporter(mgr(), path);
+ exporter.write(mgr()->root());
+ return;
+ }
+
+ bool moz = (type == MozillaExport);
+
+ if (path.isNull())
+ path = (moz) ? KNSBookmarkImporter::mozillaBookmarksFile(true)
+ : KNSBookmarkImporter::netscapeBookmarksFile(true);
+
+ if (!path.isEmpty()) {
+ KNSBookmarkExporter exporter(mgr(), path);
+ exporter.write(moz);
+ }
+}
+
+void KEBApp::setActionsEnabled(SelcAbilities sa) {
+ KActionCollection * coll = actionCollection();
+
+ QStringList toEnable;
+
+ if (sa.multiSelect || (sa.singleSelect && !sa.root))
+ toEnable << "edit_copy";
+
+ if (sa.multiSelect || (sa.singleSelect && !sa.root && !sa.urlIsEmpty && !sa.group && !sa.separator))
+ toEnable << "openlink";
+
+ if (!m_readOnly) {
+ if (sa.notEmpty)
+ toEnable << "testall" << "updateallfavicons";
+
+ if ( sa.multiSelect || (sa.singleSelect && !sa.root) )
+ toEnable << "delete" << "edit_cut";
+
+ if( sa.singleSelect)
+ if (m_canPaste)
+ toEnable << "edit_paste";
+
+ if( sa.multiSelect || (sa.singleSelect && !sa.root && (sa.group || !sa.urlIsEmpty) && !sa.separator))
+ toEnable << "testlink" << "updatefavicon";
+
+ if(sa.multiSelect)
+ toEnable << "showintoolbar" << "hideintoolbar";
+ else if(sa.itemSelected)
+ toEnable << (sa.tbShowState ? "hideintoolbar" : "showintoolbar");
+
+ if (sa.singleSelect && !sa.root && !sa.separator) {
+ toEnable << "rename" << "changeicon" << "changecomment";
+ if (!sa.group)
+ toEnable << "changeurl";
+ }
+
+ if (sa.singleSelect) {
+ toEnable << "newfolder" << "newbookmark" << "insertseparator";
+ if (sa.group)
+ toEnable << "sort" << "recursivesort" << "setastoolbar";
+ }
+ }
+
+ for ( QStringList::Iterator it = toEnable.begin();
+ it != toEnable.end(); ++it )
+ {
+ coll->action((*it).ascii())->setEnabled(true);
+ // kdDebug() << (*it) << endl;
+ }
+}
+
+void KEBApp::setCancelFavIconUpdatesEnabled(bool enabled) {
+ actionCollection()->action("cancelfaviconupdates")->setEnabled(enabled);
+}
+
+void KEBApp::setCancelTestsEnabled(bool enabled) {
+ actionCollection()->action("canceltests")->setEnabled(enabled);
+}
+
+void ActionsImpl::slotCut() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ slotCopy();
+ DeleteManyCommand *mcmd = new DeleteManyCommand( i18n("Cut Items"), ListView::self()->selectedAddresses() );
+ CmdHistory::self()->addCommand(mcmd);
+
+}
+
+void ActionsImpl::slotCopy() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ // this is not a command, because it can't be undone
+ Q_ASSERT(ListView::self()->selectedItemsMap().count() != 0);
+ QValueList<KBookmark> bookmarks
+ = ListView::self()->itemsToBookmarks(ListView::self()->selectedItemsMap());
+ KBookmarkDrag* data = KBookmarkDrag::newDrag(bookmarks, 0 /* not this ! */);
+ kapp->clipboard()->setData(data, QClipboard::Clipboard);
+}
+
+void ActionsImpl::slotPaste() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ KEBMacroCommand *mcmd =
+ CmdGen::insertMimeSource(
+ i18n("Paste"),
+ kapp->clipboard()->data(QClipboard::Clipboard),
+ ListView::self()->userAddress());
+ CmdHistory::self()->didCommand(mcmd);
+}
+
+/* -------------------------------------- */
+
+void ActionsImpl::slotNewFolder() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ bool ok;
+ QString str = KInputDialog::getText( i18n( "Create New Bookmark Folder" ),
+ i18n( "New folder:" ), QString::null, &ok );
+ if (!ok)
+ return;
+
+ CreateCommand *cmd = new CreateCommand(
+ ListView::self()->userAddress(),
+ str, "bookmark_folder", /*open*/ true);
+ CmdHistory::self()->addCommand(cmd);
+}
+
+void ActionsImpl::slotNewBookmark() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ // TODO - make a setCurrentItem(Command *) which uses finaladdress interface
+ CreateCommand * cmd = new CreateCommand(
+ ListView::self()->userAddress(),
+ QString::null, "www", KURL("http://"));
+ CmdHistory::self()->addCommand(cmd);
+}
+
+void ActionsImpl::slotInsertSeparator() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CreateCommand * cmd = new CreateCommand(ListView::self()->userAddress());
+ CmdHistory::self()->addCommand(cmd);
+}
+
+void ActionsImpl::slotImport() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ // kdDebug() << "ActionsImpl::slotImport() where sender()->name() == "
+ // << sender()->name() << endl;
+ ImportCommand* import
+ = ImportCommand::performImport(sender()->name()+6, KEBApp::self());
+ if (!import)
+ return;
+ CmdHistory::self()->addCommand(import);
+ ListView::self()->setCurrent( ListView::self()->getItemAtAddress(import->groupAddress()), true);
+}
+
+// TODO - this is getting ugly and repetitive. cleanup!
+
+void ActionsImpl::slotExportOpera() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CurrentMgr::self()->doExport(CurrentMgr::OperaExport); }
+void ActionsImpl::slotExportHTML() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CurrentMgr::self()->doExport(CurrentMgr::HTMLExport); }
+void ActionsImpl::slotExportIE() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CurrentMgr::self()->doExport(CurrentMgr::IEExport); }
+void ActionsImpl::slotExportNS() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CurrentMgr::self()->doExport(CurrentMgr::NetscapeExport); }
+void ActionsImpl::slotExportMoz() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ CurrentMgr::self()->doExport(CurrentMgr::MozillaExport); }
+
+/* -------------------------------------- */
+
+static QCString s_appId, s_objId;
+static KParts::ReadOnlyPart *s_part;
+
+void ActionsImpl::slotPrint() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ s_part = KParts::ComponentFactory
+ ::createPartInstanceFromQuery<KParts::ReadOnlyPart>(
+ "text/html", QString::null);
+ s_part->setProperty("pluginsEnabled", QVariant(false, 1));
+ s_part->setProperty("javaScriptEnabled", QVariant(false, 1));
+ s_part->setProperty("javaEnabled", QVariant(false, 1));
+
+ // doc->openStream( "text/html", KURL() );
+ // doc->writeStream( QCString( "<HTML><BODY>FOO</BODY></HTML>" ) );
+ // doc->closeStream();
+
+ HTMLExporter exporter;
+ KTempFile tmpf(locateLocal("tmp", "print_bookmarks"), ".html");
+ QTextStream *tstream = tmpf.textStream();
+ tstream->setEncoding(QTextStream::Unicode);
+ (*tstream) << exporter.toString(CurrentMgr::self()->mgr()->root(), true);
+ tmpf.close();
+
+ s_appId = kapp->dcopClient()->appId();
+ s_objId = s_part->property("dcopObjectId").toString().latin1();
+ connect(s_part, SIGNAL(completed()), this, SLOT(slotDelayedPrint()));
+
+ s_part->openURL(KURL( tmpf.name() ));
+}
+
+void ActionsImpl::slotDelayedPrint() {
+ Q_ASSERT(s_part);
+ DCOPRef(s_appId, s_objId).send("print", false);
+ delete s_part;
+ s_part = 0;
+}
+
+/* -------------------------------------- */
+
+void ActionsImpl::slotShowNS() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ bool shown = KEBApp::self()->nsShown();
+ CurrentMgr::self()->mgr()->setShowNSBookmarks(shown);
+ // TODO - need to force a save here
+ CurrentMgr::self()->reloadConfig();
+}
+
+void ActionsImpl::slotCancelFavIconUpdates() {
+ FavIconsItrHolder::self()->cancelAllItrs();
+}
+
+void ActionsImpl::slotCancelAllTests() {
+ TestLinkItrHolder::self()->cancelAllItrs();
+}
+
+void ActionsImpl::slotTestAll() {
+ TestLinkItrHolder::self()->insertItr(
+ new TestLinkItr(ListView::self()->allBookmarks()));
+}
+
+void ActionsImpl::slotUpdateAllFavIcons() {
+ FavIconsItrHolder::self()->insertItr(
+ new FavIconsItr(ListView::self()->allBookmarks()));
+}
+
+ActionsImpl::~ActionsImpl() {
+ delete FavIconsItrHolder::self();
+ delete TestLinkItrHolder::self();
+}
+
+/* -------------------------------------- */
+
+void ActionsImpl::slotTestSelection() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ TestLinkItrHolder::self()->insertItr(new TestLinkItr(ListView::self()->selectedBookmarksExpanded()));
+}
+
+void ActionsImpl::slotUpdateFavIcon() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ FavIconsItrHolder::self()->insertItr(new FavIconsItr(ListView::self()->selectedBookmarksExpanded()));
+}
+
+/* -------------------------------------- */
+
+class KBookmarkGroupList : private KBookmarkGroupTraverser {
+public:
+ KBookmarkGroupList(KBookmarkManager *);
+ QValueList<KBookmark> getList(const KBookmarkGroup &);
+private:
+ virtual void visit(const KBookmark &) { ; }
+ virtual void visitEnter(const KBookmarkGroup &);
+ virtual void visitLeave(const KBookmarkGroup &) { ; }
+private:
+ KBookmarkManager *m_manager;
+ QValueList<KBookmark> m_list;
+};
+
+KBookmarkGroupList::KBookmarkGroupList( KBookmarkManager *manager ) {
+ m_manager = manager;
+}
+
+QValueList<KBookmark> KBookmarkGroupList::getList( const KBookmarkGroup &grp ) {
+ traverse(grp);
+ return m_list;
+}
+
+void KBookmarkGroupList::visitEnter(const KBookmarkGroup &grp) {
+ m_list << grp;
+}
+
+void ActionsImpl::slotRecursiveSort() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ KBookmark bk = ListView::self()->firstSelected()->bookmark();
+ Q_ASSERT(bk.isGroup());
+ KEBMacroCommand *mcmd = new KEBMacroCommand(i18n("Recursive Sort"));
+ KBookmarkGroupList lister(CurrentMgr::self()->mgr());
+ QValueList<KBookmark> bookmarks = lister.getList(bk.toGroup());
+ bookmarks << bk.toGroup();
+ for (QValueListConstIterator<KBookmark> it = bookmarks.begin(); it != bookmarks.end(); ++it) {
+ SortCommand *cmd = new SortCommand("", (*it).address());
+ cmd->execute();
+ mcmd->addCommand(cmd);
+ }
+ CmdHistory::self()->didCommand(mcmd);
+}
+
+void ActionsImpl::slotSort() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ KBookmark bk = ListView::self()->firstSelected()->bookmark();
+ Q_ASSERT(bk.isGroup());
+ SortCommand *cmd = new SortCommand(i18n("Sort Alphabetically"), bk.address());
+ CmdHistory::self()->addCommand(cmd);
+}
+
+/* -------------------------------------- */
+
+void ActionsImpl::slotDelete() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ DeleteManyCommand *mcmd = new DeleteManyCommand(i18n("Delete Items"), ListView::self()->selectedAddresses());
+ CmdHistory::self()->addCommand(mcmd);
+}
+
+void ActionsImpl::slotOpenLink() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ QValueList<KBookmark> bks = ListView::self()->itemsToBookmarks(ListView::self()->selectedItemsMap());
+ QValueListIterator<KBookmark> it;
+ for (it = bks.begin(); it != bks.end(); ++it) {
+ if ((*it).isGroup() || (*it).isSeparator())
+ continue;
+ (void)new KRun((*it).url());
+ }
+}
+
+/* -------------------------------------- */
+
+void ActionsImpl::slotRename() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ ListView::self()->rename(KEBListView::NameColumn);
+}
+
+void ActionsImpl::slotChangeURL() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ ListView::self()->rename(KEBListView::UrlColumn);
+}
+
+void ActionsImpl::slotChangeComment() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ ListView::self()->rename(KEBListView::CommentColumn);
+}
+
+void ActionsImpl::slotSetAsToolbar() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ KBookmark bk = ListView::self()->firstSelected()->bookmark();
+ Q_ASSERT(bk.isGroup());
+ KEBMacroCommand *mcmd = CmdGen::setAsToolbar(bk);
+ CmdHistory::self()->addCommand(mcmd);
+}
+
+void ActionsImpl::slotShowInToolbar() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ QValueList<KBookmark> bks = ListView::self()->itemsToBookmarks(ListView::self()->selectedItemsMap());
+ KEBMacroCommand *mcmd = CmdGen::setShownInToolbar(bks, true);
+ CmdHistory::self()->addCommand(mcmd);
+}
+
+void ActionsImpl::slotHideInToolbar() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ QValueList<KBookmark> bks = ListView::self()->itemsToBookmarks(ListView::self()->selectedItemsMap());
+ KEBMacroCommand *mcmd = CmdGen::setShownInToolbar(bks, false);
+ CmdHistory::self()->addCommand(mcmd);
+}
+
+void ActionsImpl::slotChangeIcon() {
+ KEBApp::self()->bkInfo()->commitChanges();
+ KBookmark bk = ListView::self()->firstSelected()->bookmark();
+ KIconDialog dlg(KEBApp::self());
+ QString newIcon = dlg.selectIcon(KIcon::Small, KIcon::FileSystem);
+ if (newIcon.isEmpty())
+ return;
+ EditCommand *cmd = new EditCommand(
+ bk.address(),
+ EditCommand::Edition("icon", newIcon),
+ i18n("Icon"));
+ CmdHistory::self()->addCommand(cmd);
+}
+
+void ActionsImpl::slotExpandAll() {
+ ListView::self()->setOpen(true);
+}
+
+void ActionsImpl::slotCollapseAll() {
+ ListView::self()->setOpen(false);
+}
+
+#include "actionsimpl.moc"
diff --git a/konqueror/keditbookmarks/actionsimpl.h b/konqueror/keditbookmarks/actionsimpl.h
new file mode 100644
index 000000000..c10b8e12c
--- /dev/null
+++ b/konqueror/keditbookmarks/actionsimpl.h
@@ -0,0 +1,83 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __actionsimpl_h
+#define __actionsimpl_h
+
+#include <qobject.h>
+
+class ActionsImpl : public QObject
+{
+ Q_OBJECT
+
+public:
+ bool save();
+
+public slots:
+ void slotLoad();
+ void slotSaveAs();
+ void slotCut();
+ void slotCopy();
+ void slotPaste();
+ void slotRename();
+ void slotPrint();
+ void slotChangeURL();
+ void slotChangeComment();
+ void slotChangeIcon();
+ void slotDelete();
+ void slotNewFolder();
+ void slotNewBookmark();
+ void slotInsertSeparator();
+ void slotSort();
+ void slotSetAsToolbar();
+ void slotShowInToolbar();
+ void slotHideInToolbar();
+ void slotOpenLink();
+ void slotShowNS();
+ void slotTestSelection();
+ void slotTestAll();
+ void slotCancelAllTests();
+ void slotUpdateFavIcon();
+ void slotRecursiveSort();
+ void slotUpdateAllFavIcons();
+ void slotCancelFavIconUpdates();
+ void slotExpandAll();
+ void slotCollapseAll();
+ void slotImport();
+ void slotExportOpera();
+ void slotExportHTML();
+ void slotExportIE();
+ void slotExportNS();
+ void slotExportMoz();
+
+ // ugly hack really...
+ void slotDelayedPrint();
+
+ static ActionsImpl* self() { if (!s_self) { s_self = new ActionsImpl(); }; return s_self; }
+
+public:
+ ~ActionsImpl();
+
+private:
+ ActionsImpl() { }
+ static ActionsImpl *s_self;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/bookmarkinfo.cpp b/konqueror/keditbookmarks/bookmarkinfo.cpp
new file mode 100644
index 000000000..9d2d23f28
--- /dev/null
+++ b/konqueror/keditbookmarks/bookmarkinfo.cpp
@@ -0,0 +1,293 @@
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "bookmarkinfo.h"
+#include "commands.h"
+#include "toplevel.h"
+
+#include <stdlib.h>
+
+#include <qtimer.h>
+#include <qclipboard.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <kkeydialog.h>
+#include <kedittoolbar.h>
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <kfiledialog.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+
+// SHUFFLE all these functions around, the order is just plain stupid
+
+BookmarkLineEdit::BookmarkLineEdit( QWidget *parent )
+ : KLineEdit( parent )
+{
+}
+
+void BookmarkLineEdit::cut()
+{
+ QString select( selectedText() );
+ int pos( selectionStart() );
+ QString newText( text().remove( pos, select.length() ) );
+ KLineEdit::cut();
+ setEdited( true ); //KDE 4 setModified( true );
+ emit textChanged( newText );
+ setText( newText );
+}
+
+
+void BookmarkInfoWidget::showBookmark(const KBookmark &bk) {
+ commitChanges();
+ m_bk = bk;
+
+ if (m_bk.isNull()) {
+ // all read only and blank
+
+ m_title_le->setReadOnly(true);
+ m_title_le->setText(QString::null);
+
+ m_url_le->setReadOnly(true);
+ m_url_le->setText(QString::null);
+
+ m_comment_le->setReadOnly(true);
+ m_comment_le->setText(QString::null);
+
+ m_visitdate_le->setReadOnly(true);
+ m_visitdate_le->setText(QString::null);
+
+ m_credate_le->setReadOnly(true);
+ m_credate_le->setText(QString::null);
+
+ m_visitcount_le->setReadOnly(true);
+ m_visitcount_le->setText(QString::null);
+
+ return;
+ }
+
+ // read/write fields
+ m_title_le->setReadOnly( (bk.isSeparator()|| !bk.hasParent() )? true : false);
+ m_title_le->setText(bk.fullText());
+
+ m_url_le->setReadOnly(bk.isGroup() || bk.isSeparator());
+ m_url_le->setText(bk.isGroup() ? QString::null : bk.url().pathOrURL());
+
+ m_comment_le->setReadOnly((bk.isSeparator()|| !bk.hasParent()) ? true : false );
+ m_comment_le->setText(
+ NodeEditCommand::getNodeText(bk, QStringList() << "desc"));
+
+ // readonly fields
+ updateStatus();
+
+}
+
+void BookmarkInfoWidget::updateStatus()
+{
+ QString visitDate =
+ CurrentMgr::makeTimeStr( NodeEditCommand::getNodeText(m_bk, QStringList() << "info" << "metadata"
+ << "time_visited" ));
+ m_visitdate_le->setReadOnly(true);
+ m_visitdate_le->setText(visitDate);
+
+ QString creationDate =
+ CurrentMgr::makeTimeStr( NodeEditCommand::getNodeText(m_bk, QStringList() << "info" << "metadata"
+ << "time_added" ));
+ m_credate_le->setReadOnly(true);
+ m_credate_le->setText(creationDate);
+
+ // TODO - get the actual field name from the spec if it exists, else copy galeon
+ m_visitcount_le->setReadOnly(true);
+ m_visitcount_le->setText(
+ NodeEditCommand::getNodeText(m_bk, QStringList() << "info" << "metadata"
+ << "visit_count" ));
+}
+
+void BookmarkInfoWidget::commitChanges()
+{
+ commitTitle();
+ commitURL();
+ commitComment();
+}
+
+void BookmarkInfoWidget::commitTitle()
+{
+ if(titlecmd)
+ {
+ emit updateListViewItem();
+ CurrentMgr::self()->notifyManagers(CurrentMgr::bookmarkAt(titlecmd->affectedBookmarks()).toGroup());
+ titlecmd = 0;
+ }
+}
+
+void BookmarkInfoWidget::slotTextChangedTitle(const QString &str)
+{
+ if (m_bk.isNull() || !m_title_le->isModified())
+ return;
+
+ timer->start(1000, true);
+
+ if(titlecmd)
+ {
+ NodeEditCommand::setNodeText(m_bk, QStringList() << "title", str);
+ titlecmd->modify(str);
+ }
+ else
+ {
+ titlecmd = new NodeEditCommand(m_bk.address(), str, "title");
+ titlecmd->execute();
+ CmdHistory::self()->addInFlightCommand(titlecmd);
+ }
+}
+
+void BookmarkInfoWidget::commitURL()
+{
+ if(urlcmd)
+ {
+ emit updateListViewItem();
+ CurrentMgr::self()->notifyManagers(CurrentMgr::bookmarkAt(urlcmd->affectedBookmarks()).toGroup());
+ urlcmd = 0;
+ }
+}
+
+void BookmarkInfoWidget::slotTextChangedURL(const QString &str) {
+ if (m_bk.isNull() || !m_url_le->isModified())
+ return;
+
+ timer->start(1000, true);
+
+ if(urlcmd)
+ {
+ KURL u = KURL::fromPathOrURL(str);
+ m_bk.internalElement().setAttribute("href", u.url(0, 106));
+ urlcmd->modify("href", u.url(0, 106));
+ }
+ else
+ {
+ KURL u = KURL::fromPathOrURL(str);
+ urlcmd = new EditCommand(m_bk.address(), EditCommand::Edition("href", u.url(0, 106)), i18n("URL"));
+ urlcmd->execute();
+ CmdHistory::self()->addInFlightCommand(urlcmd);
+ }
+}
+
+void BookmarkInfoWidget::commitComment()
+{
+ if(commentcmd)
+ {
+ emit updateListViewItem();
+ CurrentMgr::self()->notifyManagers( CurrentMgr::bookmarkAt( commentcmd->affectedBookmarks() ).toGroup());
+ commentcmd = 0;
+ }
+}
+
+void BookmarkInfoWidget::slotTextChangedComment(const QString &str) {
+ if (m_bk.isNull() || !m_comment_le->isModified())
+ return;
+
+ timer->start(1000, true);
+
+ if(commentcmd)
+ {
+ NodeEditCommand::setNodeText(m_bk, QStringList() << "desc", str);
+ commentcmd->modify(str);
+ }
+ else
+ {
+ commentcmd = new NodeEditCommand(m_bk.address(), str, "desc");
+ commentcmd->execute();
+ CmdHistory::self()->addInFlightCommand(commentcmd);
+ }
+}
+
+BookmarkInfoWidget::BookmarkInfoWidget(QWidget *parent, const char *name)
+ : QWidget(parent, name), m_connected(false) {
+
+ timer = new QTimer(this);
+ connect(timer, SIGNAL( timeout() ), SLOT( commitChanges()));
+
+ titlecmd = 0;
+ urlcmd = 0;
+ commentcmd = 0;
+
+ QBoxLayout *vbox = new QVBoxLayout(this);
+ QGridLayout *grid = new QGridLayout(vbox, 3, 4, 4);
+
+ m_title_le = new BookmarkLineEdit(this);
+ grid->addWidget(m_title_le, 0, 1);
+ grid->addWidget(
+ new QLabel(m_title_le, i18n("Name:"), this),
+ 0, 0);
+
+ connect(m_title_le, SIGNAL( textChanged(const QString &) ),
+ SLOT( slotTextChangedTitle(const QString &) ));
+ connect(m_title_le, SIGNAL( lostFocus() ), SLOT( commitTitle() ));
+
+ m_url_le = new BookmarkLineEdit(this);
+ grid->addWidget(m_url_le, 1, 1);
+ grid->addWidget(
+ new QLabel(m_url_le, i18n("Location:"), this),
+ 1, 0);
+
+ connect(m_url_le, SIGNAL( textChanged(const QString &) ),
+ SLOT( slotTextChangedURL(const QString &) ));
+ connect(m_url_le, SIGNAL( lostFocus() ), SLOT( commitURL() ));
+
+ m_comment_le = new BookmarkLineEdit(this);
+ grid->addWidget(m_comment_le, 2, 1);
+ grid->addWidget(
+ new QLabel(m_comment_le, i18n("Comment:"), this),
+ 2, 0);
+ connect(m_comment_le, SIGNAL( textChanged(const QString &) ),
+ SLOT( slotTextChangedComment(const QString &) ));
+ connect(m_comment_le, SIGNAL( lostFocus() ), SLOT( commitComment() ));
+
+ m_credate_le = new KLineEdit(this);
+ grid->addWidget(m_credate_le, 0, 3);
+ grid->addWidget(
+ new QLabel(m_credate_le, i18n("First viewed:"), this),
+ 0, 2);
+
+ m_visitdate_le = new KLineEdit(this);
+ grid->addWidget(m_visitdate_le, 1, 3);
+ grid->addWidget(
+ new QLabel(m_visitdate_le, i18n("Viewed last:"), this),
+ 1, 2 );
+
+ m_visitcount_le = new KLineEdit(this);
+ grid->addWidget(m_visitcount_le, 2, 3);
+ grid->addWidget(
+ new QLabel(m_visitcount_le, i18n("Times visited:"), this),
+ 2, 2);
+}
+
+#include "bookmarkinfo.moc"
+
diff --git a/konqueror/keditbookmarks/bookmarkinfo.h b/konqueror/keditbookmarks/bookmarkinfo.h
new file mode 100644
index 000000000..51661959a
--- /dev/null
+++ b/konqueror/keditbookmarks/bookmarkinfo.h
@@ -0,0 +1,111 @@
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __bookmarkinfo_h
+#define __bookmarkinfo_h
+
+#include "commands.h"
+
+#include <kbookmark.h>
+#include <qwidget.h>
+#include <klineedit.h>
+
+class QTimer;
+
+class BookmarkLineEdit : public KLineEdit {
+ Q_OBJECT
+public:
+ BookmarkLineEdit( QWidget * );
+public slots:
+ virtual void cut ();
+};
+
+
+class BookmarkInfoWidget : public QWidget {
+ Q_OBJECT
+public:
+ BookmarkInfoWidget(QWidget * = 0, const char * = 0);
+ void showBookmark(const KBookmark &bk);
+ void saveBookmark(const KBookmark &bk);
+ KBookmark bookmark() { return m_bk; }
+ bool connected() { return m_connected; };
+ void setConnected(bool b) { m_connected = b; };
+ void updateStatus();
+
+public slots:
+ void slotTextChangedURL(const QString &);
+ void slotTextChangedTitle(const QString &);
+ void slotTextChangedComment(const QString &);
+
+ // _The deal with all those commitChanges() calls_
+ // First a short example how all the components
+ // normally fit together:
+ // Note: not all details are included
+ // For example: The user clicks on "New Bookmark"
+ // This constructs a cmd = new CreateCommand( .. )
+ // CmdHistory::self()->addCommand( cmd ) is called
+ // CmdHistory executes the command
+ // and enables the undo button
+ // and emits slotCommandExecuted
+ // We catch the signal and call
+ // CurrentMgr::self()->notifyManagers( .. );
+
+ // The bookmarkinfo widget is special, because
+ // we don't want to send a notification
+ // for every change, but want to enable the undo
+ // button and need to send the notification
+ // if the user has stopped typing
+
+ // So as soon as the user starts typing
+ // we create a command
+ // and call CmdHistory::self()->addInFlightCommand( cmd );
+ // addInFlightCommand() doesn't execute the command, it just
+ // adds it to the command history (To enable the undo button)
+ // For every keystroke after that the command is modified
+ // and we change our internal state to reflect the change
+ // (Basically changing it in the same way, executing would have.)
+
+ // At this point we have a modified state, but haven't send it
+ // to the other bookmarkmanagers
+ // That is done in commitChanges()
+ // commitChanges() should be called everywhere, where we are
+ // sure that the user has stopped typing.
+ // And a few other cleanups are done in commitChanges()
+ void commitChanges();
+ void commitTitle();
+ void commitURL();
+ void commitComment();
+
+signals:
+ void updateListViewItem();
+private:
+ NodeEditCommand *titlecmd;
+ EditCommand *urlcmd;
+ NodeEditCommand *commentcmd;
+ QTimer * timer;
+ BookmarkLineEdit *m_title_le, *m_url_le,
+ *m_comment_le;
+ KLineEdit *m_visitdate_le, *m_credate_le,
+ *m_visitcount_le;
+ KBookmark m_bk;
+ bool m_connected;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/bookmarkiterator.cpp b/konqueror/keditbookmarks/bookmarkiterator.cpp
new file mode 100644
index 000000000..588adb86c
--- /dev/null
+++ b/konqueror/keditbookmarks/bookmarkiterator.cpp
@@ -0,0 +1,105 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "bookmarkiterator.h"
+
+#include "toplevel.h"
+#include "listview.h"
+
+#include <kdebug.h>
+
+#include <qtimer.h>
+
+BookmarkIterator::BookmarkIterator(QValueList<KBookmark> bks) : m_bklist(bks) {
+ connect(this, SIGNAL( deleteSelf(BookmarkIterator *) ),
+ SLOT( slotCancelTest(BookmarkIterator *) ));
+ delayedEmitNextOne();
+}
+
+BookmarkIterator::~BookmarkIterator() {
+ ;
+}
+
+void BookmarkIterator::delayedEmitNextOne() {
+ QTimer::singleShot(1, this, SLOT( nextOne() ));
+}
+
+void BookmarkIterator::slotCancelTest(BookmarkIterator *test) {
+ holder()->removeItr(test);
+}
+
+KEBListViewItem* BookmarkIterator::curItem() const {
+ if (!m_bk.hasParent())
+ return 0;
+ return ListView::self()->getItemAtAddress(m_bk.address());
+}
+
+const KBookmark BookmarkIterator::curBk() const {
+ assert(m_bk.hasParent());
+ return m_bk;
+}
+
+void BookmarkIterator::nextOne() {
+ // kdDebug() << "BookmarkIterator::nextOne" << endl;
+
+ if (m_bklist.isEmpty()) {
+ emit deleteSelf(this);
+ return;
+ }
+
+ QValueListIterator<KBookmark> head = m_bklist.begin();
+ KBookmark bk = (*head);
+
+ bool viable = bk.hasParent() && isApplicable(bk);
+
+ if (viable) {
+ m_bk = bk;
+ doAction();
+ }
+
+ m_bklist.remove(head);
+
+ if (!viable)
+ delayedEmitNextOne();
+}
+
+/* --------------------------- */
+
+BookmarkIteratorHolder::BookmarkIteratorHolder() {
+ m_itrs.setAutoDelete(true);
+}
+
+void BookmarkIteratorHolder::insertItr(BookmarkIterator *itr) {
+ m_itrs.insert(0, itr);
+ doItrListChanged();
+}
+
+void BookmarkIteratorHolder::removeItr(BookmarkIterator *itr) {
+ m_itrs.remove(itr);
+ doItrListChanged();
+}
+
+void BookmarkIteratorHolder::cancelAllItrs() {
+ m_itrs.clear();
+ doItrListChanged();
+}
+
+#include "bookmarkiterator.moc"
diff --git a/konqueror/keditbookmarks/bookmarkiterator.h b/konqueror/keditbookmarks/bookmarkiterator.h
new file mode 100644
index 000000000..baafb3486
--- /dev/null
+++ b/konqueror/keditbookmarks/bookmarkiterator.h
@@ -0,0 +1,74 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __bookmarkiterator_h
+#define __bookmarkiterator_h
+
+#include <qobject.h>
+#include <qptrlist.h>
+#include <kbookmark.h>
+
+class KEBListViewItem;
+class BookmarkIteratorHolder;
+
+class BookmarkIterator : public QObject
+{
+ Q_OBJECT
+
+public:
+ BookmarkIterator(QValueList<KBookmark> bks);
+ virtual ~BookmarkIterator();
+ virtual BookmarkIteratorHolder* holder() const = 0;
+
+public slots:
+ void nextOne();
+ void delayedEmitNextOne();
+ void slotCancelTest(BookmarkIterator *t);
+
+signals:
+ void deleteSelf(BookmarkIterator *);
+
+protected:
+ virtual void doAction() = 0;
+ virtual bool isApplicable(const KBookmark &bk) const = 0;
+ KEBListViewItem* curItem() const;
+ const KBookmark curBk() const;
+
+private:
+ KBookmark m_bk;
+ QValueList<KBookmark> m_bklist;
+};
+
+class BookmarkIteratorHolder
+{
+public:
+ void cancelAllItrs();
+ void removeItr(BookmarkIterator*);
+ void insertItr(BookmarkIterator*);
+protected:
+ BookmarkIteratorHolder();
+ virtual ~BookmarkIteratorHolder() {};
+ virtual void doItrListChanged() = 0;
+ int count() const { return m_itrs.count(); }
+private:
+ QPtrList<BookmarkIterator> m_itrs;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/commands.cpp b/konqueror/keditbookmarks/commands.cpp
new file mode 100644
index 000000000..e545df54e
--- /dev/null
+++ b/konqueror/keditbookmarks/commands.cpp
@@ -0,0 +1,745 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "commands.h"
+
+#include "kinsertionsort.h"
+
+#include "toplevel.h"
+#include "listview.h"
+
+#include <assert.h>
+#include <qvaluevector.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+
+#include <kurldrag.h>
+#include <kdesktopfile.h>
+
+QString KEBMacroCommand::affectedBookmarks() const
+{
+ QPtrListIterator<KCommand> it(m_commands);
+ QString affectBook;
+ if(it.current())
+ affectBook = dynamic_cast<IKEBCommand *>(it.current())->affectedBookmarks();
+ ++it;
+ for ( ; it.current() ; ++it )
+ affectBook = KBookmark::commonParent( affectBook, dynamic_cast<IKEBCommand *>(it.current())->affectedBookmarks());
+ return affectBook;
+}
+
+QString DeleteManyCommand::prevOrParentAddress(QString addr)
+{
+ QString prev = KBookmark::previousAddress( addr );
+ if( CurrentMgr::bookmarkAt(prev).hasParent())
+ return prev;
+ else
+ return KBookmark::parentAddress( addr );
+}
+
+QString DeleteManyCommand::preOrderNextAddress(QString addr)
+{
+ QString rootAdr = CurrentMgr::self()->mgr()->root().address();
+ while(addr != rootAdr)
+ {
+ QString next = KBookmark::nextAddress(addr);
+ if(CurrentMgr::bookmarkAt( next ).hasParent() )
+ return next;
+ addr = KBookmark::parentAddress( addr );
+ }
+ return QString::null;
+}
+
+bool DeleteManyCommand::isConsecutive(const QValueList<QString> & addresses)
+{
+ QValueList<QString>::const_iterator it, end;
+ it = addresses.begin();
+ end = addresses.end();
+ QString addr = *(addresses.begin());
+ for( ; it != end; ++it)
+ {
+ if( *it != addr )
+ return false;
+ addr = KBookmark::nextAddress(addr);
+ }
+ return true;
+}
+
+
+DeleteManyCommand::DeleteManyCommand(const QString &name, const QValueList<QString> & addresses)
+ : KEBMacroCommand(name)
+{
+ QValueList<QString>::const_iterator it, begin;
+ begin = addresses.begin();
+ it = addresses.end();
+ while(begin != it)
+ {
+ --it;
+ DeleteCommand * dcmd = new DeleteCommand(*it);
+ addCommand(dcmd);
+ }
+
+ // Set m_currentAddress
+ if( addresses.count() == 1)
+ {
+ // First try next bookmark
+ if( CurrentMgr::bookmarkAt( KBookmark::nextAddress( *begin ) ).hasParent() )
+ m_currentAddress = *begin;
+ else
+ {
+ m_currentAddress = preOrderNextAddress( KBookmark::parentAddress( *begin ) );
+ if(m_currentAddress == QString::null)
+ m_currentAddress = prevOrParentAddress( *begin );
+ }
+ }
+ else // multi selection
+ {
+ // Check if all bookmarks are consecutive
+ if(isConsecutive(addresses)) // Mark next bookmark after all selected
+ { // That's a little work...
+ QValueList<QString>::const_iterator last = addresses.end();
+ --last;
+ if( CurrentMgr::bookmarkAt( KBookmark::nextAddress(*last) ).hasParent() )
+ m_currentAddress = *begin;
+ else
+ {
+ m_currentAddress = preOrderNextAddress( KBookmark::parentAddress( *begin ) );
+ if( m_currentAddress == QString::null)
+ m_currentAddress = prevOrParentAddress( *begin );
+ }
+ }
+ else // not consecutive, select the common parent (This could be more clever)
+ {
+ QValueList<QString>::const_iterator jt, end;
+ end = addresses.end();
+ m_currentAddress = *begin;
+ for( jt = addresses.begin(); jt != end; ++jt)
+ m_currentAddress = KBookmark::commonParent(m_currentAddress, *jt);
+ }
+ }
+}
+
+QString DeleteManyCommand::currentAddress() const
+{
+ return m_currentAddress;
+}
+
+
+QString CreateCommand::name() const {
+ if (m_separator) {
+ return i18n("Insert Separator");
+ } else if (m_group) {
+ return i18n("Create Folder");
+ } else if (!m_originalBookmark.isNull()) {
+ return i18n("Copy %1").arg(m_mytext);
+ } else {
+ return i18n("Create Bookmark");
+ }
+}
+
+void CreateCommand::execute() {
+ QString parentAddress = KBookmark::parentAddress(m_to);
+ KBookmarkGroup parentGroup =
+ CurrentMgr::bookmarkAt(parentAddress).toGroup();
+
+ QString previousSibling = KBookmark::previousAddress(m_to);
+
+ // kdDebug() << "CreateCommand::execute previousSibling="
+ // << previousSibling << endl;
+ KBookmark prev = (previousSibling.isEmpty())
+ ? KBookmark(QDomElement())
+ : CurrentMgr::bookmarkAt(previousSibling);
+
+ KBookmark bk = KBookmark(QDomElement());
+
+ if (m_separator) {
+ bk = parentGroup.createNewSeparator();
+
+ } else if (m_group) {
+ Q_ASSERT(!m_text.isEmpty());
+ bk = parentGroup.createNewFolder(CurrentMgr::self()->mgr(),
+ m_text, false);
+ bk.internalElement().setAttribute("folded", (m_open ? "no" : "yes"));
+ if (!m_iconPath.isEmpty()) {
+ bk.internalElement().setAttribute("icon", m_iconPath);
+ }
+
+ } else if (!m_originalBookmark.isNull()) {
+ // umm.. moveItem needs bk to be a child already!
+ bk = m_originalBookmark;
+
+ } else {
+ bk = parentGroup.addBookmark(CurrentMgr::self()->mgr(),
+ m_text, m_url,
+ m_iconPath, false);
+ }
+
+ // move to right position
+ parentGroup.moveItem(bk, prev);
+ if (!(name().isEmpty()) && !parentAddress.isEmpty() ) {
+ // open the parent (useful if it was empty) - only for manual commands
+ Q_ASSERT( parentGroup.internalElement().tagName() != "xbel" );
+ parentGroup.internalElement().setAttribute("folded", "no");
+ }
+
+ Q_ASSERT(bk.address() == m_to);
+}
+
+QString CreateCommand::finalAddress() const {
+ Q_ASSERT( !m_to.isEmpty() );
+ return m_to;
+}
+
+void CreateCommand::unexecute() {
+ // kdDebug() << "CreateCommand::unexecute deleting " << m_to << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_to);
+ Q_ASSERT(!bk.isNull() && !bk.parentGroup().isNull());
+
+ ListView::self()->invalidate(bk.address());
+
+ bk.parentGroup().deleteBookmark(bk);
+}
+
+QString CreateCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_to);
+}
+
+QString CreateCommand::currentAddress() const
+{
+ QString bk = KBookmark::previousAddress( m_to );
+ if(CurrentMgr::bookmarkAt( bk).hasParent())
+ return bk;
+ else
+ return KBookmark::parentAddress( m_to );
+}
+
+/* -------------------------------------- */
+
+QString EditCommand::name() const {
+ return i18n("%1 Change").arg(m_mytext);
+}
+
+void EditCommand::execute() {
+ KBookmark bk = CurrentMgr::bookmarkAt(m_address);
+ Q_ASSERT(!bk.isNull());
+
+ m_reverseEditions.clear();
+
+ QValueList<Edition>::Iterator it = m_editions.begin();
+
+ for ( ; it != m_editions.end() ; ++it) {
+ // backup current value
+ m_reverseEditions.append( Edition((*it).attr,
+ bk.internalElement().attribute((*it).attr)));
+ // set new value
+ bk.internalElement().setAttribute((*it).attr, (*it).value);
+ }
+}
+
+void EditCommand::unexecute() {
+ // code reuse
+ EditCommand cmd(m_address, m_reverseEditions);
+ cmd.execute();
+ // get the editions back from it,
+ // in case they changed
+ // (hmm, shouldn't happen - TODO CHECK!)
+ m_editions = cmd.m_reverseEditions;
+}
+
+QString EditCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_address);
+}
+
+void EditCommand::modify(const QString & a, const QString & v)
+{
+ QValueList<Edition>::Iterator it = m_editions.begin();
+ QValueList<Edition>::Iterator end = m_editions.end();
+ for ( ; it != end; ++it)
+ {
+ if( (*it).attr == a)
+ (*it).value = v;
+ }
+}
+
+/* -------------------------------------- */
+
+QString NodeEditCommand::name() const {
+ // TODO - make dynamic
+ return i18n("Renaming");
+}
+
+QString NodeEditCommand::getNodeText(KBookmark bk, const QStringList &nodehier) {
+ QDomNode subnode = bk.internalElement();
+ for (QStringList::ConstIterator it = nodehier.begin();
+ it != nodehier.end(); ++it)
+ {
+ subnode = subnode.namedItem((*it));
+ if (subnode.isNull())
+ return QString::null;
+ }
+ return (subnode.firstChild().isNull())
+ ? QString::null
+ : subnode.firstChild().toText().data();
+}
+
+QString NodeEditCommand::setNodeText(KBookmark bk, const QStringList &nodehier,
+ const QString newValue) {
+ QDomNode subnode = bk.internalElement();
+ for (QStringList::ConstIterator it = nodehier.begin();
+ it != nodehier.end(); ++it)
+ {
+ subnode = subnode.namedItem((*it));
+ if (subnode.isNull()) {
+ subnode = bk.internalElement().ownerDocument().createElement((*it));
+ bk.internalElement().appendChild(subnode);
+ }
+ }
+
+ if (subnode.firstChild().isNull()) {
+ QDomText domtext = subnode.ownerDocument().createTextNode("");
+ subnode.appendChild(domtext);
+ }
+
+ QDomText domtext = subnode.firstChild().toText();
+
+ QString oldText = domtext.data();
+ domtext.setData(newValue);
+ return oldText;
+}
+
+void NodeEditCommand::execute() {
+ // DUPLICATED HEAVILY FROM KIO/BOOKMARKS
+ KBookmark bk = CurrentMgr::bookmarkAt(m_address);
+ Q_ASSERT(!bk.isNull());
+ m_oldText = setNodeText(bk, QStringList() << m_nodename, m_newText);
+}
+
+void NodeEditCommand::unexecute() {
+ // reuse code
+ NodeEditCommand cmd(m_address, m_oldText, m_nodename);
+ cmd.execute();
+ // get the old text back from it, in case they changed
+ // (hmm, shouldn't happen)
+ // AK - DUP'ed from above???
+ m_newText = cmd.m_oldText;
+}
+
+void NodeEditCommand::modify(const QString & newText)
+{
+ m_newText = newText;
+}
+
+QString NodeEditCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_address);
+}
+
+/* -------------------------------------- */
+
+void DeleteCommand::execute() {
+ // kdDebug() << "DeleteCommand::execute " << m_from << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_from);
+ Q_ASSERT(!bk.isNull());
+
+ if (m_contentOnly) {
+ QDomElement groupRoot = bk.internalElement();
+
+ QDomNode n = groupRoot.firstChild();
+ while (!n.isNull()) {
+ QDomElement e = n.toElement();
+ if (!e.isNull()) {
+ // kdDebug() << e.tagName() << endl;
+ }
+ QDomNode next = n.nextSibling();
+ groupRoot.removeChild(n);
+ n = next;
+ }
+ return;
+ }
+
+ // TODO - bug - unparsed xml is lost after undo,
+ // we must store it all therefore
+ if (!m_cmd) {
+ if (bk.isGroup()) {
+ m_cmd = new CreateCommand(
+ m_from, bk.fullText(), bk.icon(),
+ bk.internalElement().attribute("folded") == "no");
+ m_subCmd = deleteAll(bk.toGroup());
+ m_subCmd->execute();
+
+ } else {
+ m_cmd = (bk.isSeparator())
+ ? new CreateCommand(m_from)
+ : new CreateCommand(m_from, bk.fullText(),
+ bk.icon(), bk.url());
+ }
+ }
+
+ m_cmd->unexecute();
+}
+
+void DeleteCommand::unexecute() {
+ // kdDebug() << "DeleteCommand::unexecute " << m_from << endl;
+
+ if (m_contentOnly) {
+ // TODO - recover saved metadata
+ return;
+ }
+
+ m_cmd->execute();
+
+ if (m_subCmd) {
+ m_subCmd->unexecute();
+ }
+}
+
+QString DeleteCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_from);
+}
+
+KEBMacroCommand* DeleteCommand::deleteAll(const KBookmarkGroup & parentGroup) {
+ KEBMacroCommand *cmd = new KEBMacroCommand(QString::null);
+ QStringList lstToDelete;
+ // we need to delete from the end, to avoid index shifting
+ for (KBookmark bk = parentGroup.first();
+ !bk.isNull(); bk = parentGroup.next(bk))
+ lstToDelete.prepend(bk.address());
+ for (QStringList::Iterator it = lstToDelete.begin();
+ it != lstToDelete.end(); ++it)
+ cmd->addCommand(new DeleteCommand((*it)));
+ return cmd;
+}
+
+/* -------------------------------------- */
+
+QString MoveCommand::name() const {
+ return i18n("Move %1").arg(m_mytext);
+}
+
+void MoveCommand::execute() {
+ // kdDebug() << "MoveCommand::execute moving from=" << m_from
+ // << " to=" << m_to << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_from);
+ Q_ASSERT(!bk.isNull());
+
+ // look for m_from in the QDom tree
+ KBookmark oldParent =
+ CurrentMgr::bookmarkAt(KBookmark::parentAddress(m_from));
+ bool wasFirstChild = (KBookmark::positionInParent(m_from) == 0);
+
+ KBookmark oldPreviousSibling = wasFirstChild
+ ? KBookmark(QDomElement())
+ : CurrentMgr::bookmarkAt(
+ KBookmark::previousAddress(m_from));
+
+ // look for m_to in the QDom tree
+ QString parentAddress = KBookmark::parentAddress(m_to);
+
+ KBookmark newParent = CurrentMgr::bookmarkAt(parentAddress);
+ Q_ASSERT(!newParent.isNull());
+ Q_ASSERT(newParent.isGroup());
+
+ bool isFirstChild = (KBookmark::positionInParent(m_to) == 0);
+
+ if (isFirstChild) {
+ newParent.toGroup().moveItem(bk, QDomElement());
+
+ } else {
+ QString afterAddress = KBookmark::previousAddress(m_to);
+
+ // kdDebug() << "MoveCommand::execute afterAddress="
+ // << afterAddress << endl;
+ KBookmark afterNow = CurrentMgr::bookmarkAt(afterAddress);
+ Q_ASSERT(!afterNow.isNull());
+
+ bool movedOkay = newParent.toGroup().moveItem(bk, afterNow);
+ Q_ASSERT(movedOkay);
+
+ // kdDebug() << "MoveCommand::execute after moving in the dom tree"
+ // ": item=" << bk.address() << endl;
+ }
+
+ // because we moved stuff around, the from/to
+ // addresses can have changed, update
+ m_to = bk.address();
+ m_from = (wasFirstChild)
+ ? (oldParent.address() + "/0")
+ : KBookmark::nextAddress(oldPreviousSibling.address());
+ // kdDebug() << "MoveCommand::execute : new addresses from="
+ // << m_from << " to=" << m_to << endl;
+}
+
+QString MoveCommand::finalAddress() const {
+ Q_ASSERT( !m_to.isEmpty() );
+ return m_to;
+}
+
+void MoveCommand::unexecute() {
+ // let's not duplicate code.
+ MoveCommand undoCmd(m_to, m_from);
+ undoCmd.execute();
+ // get the addresses back from that command, in case they changed
+ m_from = undoCmd.m_to;
+ m_to = undoCmd.m_from;
+}
+
+QString MoveCommand::affectedBookmarks() const
+{
+ return KBookmark::commonParent(KBookmark::parentAddress(m_from), KBookmark::parentAddress(m_to));
+}
+
+/* -------------------------------------- */
+
+class SortItem {
+ public:
+ SortItem(const KBookmark & bk) : m_bk(bk) { ; }
+
+ bool operator == (const SortItem & s) {
+ return (m_bk.internalElement() == s.m_bk.internalElement()); }
+
+ bool isNull() const {
+ return m_bk.isNull(); }
+
+ SortItem previousSibling() const {
+ return m_bk.parentGroup().previous(m_bk); }
+
+ SortItem nextSibling() const {
+ return m_bk.parentGroup().next(m_bk); }
+
+ const KBookmark& bookmark() const {
+ return m_bk; }
+
+ private:
+ KBookmark m_bk;
+};
+
+class SortByName {
+ public:
+ static QString key(const SortItem &item) {
+ return (item.bookmark().isGroup() ? "a" : "b")
+ + (item.bookmark().fullText().lower());
+ }
+};
+
+/* -------------------------------------- */
+
+void SortCommand::execute() {
+ if (m_commands.isEmpty()) {
+ KBookmarkGroup grp = CurrentMgr::bookmarkAt(m_groupAddress).toGroup();
+ Q_ASSERT(!grp.isNull());
+ SortItem firstChild(grp.first());
+ // this will call moveAfter, which will add
+ // the subcommands for moving the items
+ kInsertionSort<SortItem, SortByName, QString, SortCommand>
+ (firstChild, (*this));
+
+ } else {
+ // don't execute for second time on addCommand(cmd)
+ KEBMacroCommand::execute();
+ }
+}
+
+void SortCommand::moveAfter(const SortItem &moveMe,
+ const SortItem &afterMe) {
+ QString destAddress =
+ afterMe.isNull()
+ // move as first child
+ ? KBookmark::parentAddress(moveMe.bookmark().address()) + "/0"
+ // move after "afterMe"
+ : KBookmark::nextAddress(afterMe.bookmark().address());
+
+ MoveCommand *cmd = new MoveCommand(moveMe.bookmark().address(),
+ destAddress);
+ cmd->execute();
+ this->addCommand(cmd);
+}
+
+void SortCommand::unexecute() {
+ KEBMacroCommand::unexecute();
+}
+
+QString SortCommand::affectedBookmarks() const
+{
+ return m_groupAddress;
+}
+
+/* -------------------------------------- */
+
+KEBMacroCommand* CmdGen::setAsToolbar(const KBookmark &bk) {
+ KEBMacroCommand *mcmd = new KEBMacroCommand(i18n("Set as Bookmark Toolbar"));
+
+ KBookmarkGroup oldToolbar = CurrentMgr::self()->mgr()->toolbar();
+ if (!oldToolbar.isNull()) {
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("toolbar", "no"));
+ lst.append(EditCommand::Edition("icon", ""));
+ EditCommand *cmd1 = new EditCommand(oldToolbar.address(), lst);
+ mcmd->addCommand(cmd1);
+ }
+
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("toolbar", "yes"));
+ lst.append(EditCommand::Edition("icon", "bookmark_toolbar"));
+ // TODO - see below
+ EditCommand *cmd2 = new EditCommand(bk.address(), lst);
+ mcmd->addCommand(cmd2);
+
+ return mcmd;
+}
+
+bool CmdGen::shownInToolbar(const KBookmark &bk) {
+ return (bk.internalElement().attribute("showintoolbar") == "yes");
+}
+
+KEBMacroCommand* CmdGen::setShownInToolbar(const QValueList<KBookmark> &bks, bool show) {
+ QString i18n_name = i18n("%1 in Bookmark Toolbar").arg(show ? i18n("Show")
+ : i18n("Hide"));
+ KEBMacroCommand *mcmd = new KEBMacroCommand(i18n_name);
+
+ QValueList<KBookmark>::ConstIterator it, end;
+ end = bks.end();
+ for(it = bks.begin(); it != end; ++it)
+ {
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("showintoolbar", show ? "yes" : "no"));
+ EditCommand *cmd = new EditCommand((*it).address(), lst);
+ mcmd->addCommand(cmd);
+ }
+ return mcmd;
+}
+
+KEBMacroCommand* CmdGen::insertMimeSource(
+ const QString &cmdName, QMimeSource *_data, const QString &addr
+) {
+ QMimeSource *data = _data;
+ bool modified = false;
+ const char *format = 0;
+ for (int i = 0; format = data->format(i), format; i++) {
+ // qt docs don't say if encodedData(blah) where
+ // blah is not a stored mimetype should return null
+ // or not. so, we search. sucky...
+ if (strcmp(format, "GALEON_BOOKMARK") == 0) {
+ modified = true;
+ QStoredDrag *mydrag = new QStoredDrag("application/x-xbel");
+ mydrag->setEncodedData(data->encodedData("GALEON_BOOKMARK"));
+ data = mydrag;
+ break;
+ } else if( strcmp(format, "application/x-xbel" )==0) {
+ /* nothing we created a kbbookmarks drag when we copy element (slotcopy/slotpaste)*/
+ break;
+ } else if (strcmp(format, "text/uri-list") == 0) {
+ KURL::List uris;
+ if (!KURLDrag::decode(data, uris))
+ continue; // break out of format loop
+ KURL::List::ConstIterator uit = uris.begin();
+ KURL::List::ConstIterator uEnd = uris.end();
+ QValueList<KBookmark> urlBks;
+ for ( ; uit != uEnd ; ++uit ) {
+ if (!(*uit).url().endsWith(".desktop")) {
+ urlBks << KBookmark::standaloneBookmark((*uit).prettyURL(), (*uit));
+ continue;
+ }
+ KDesktopFile df((*uit).path(), true);
+ QString title = df.readName();
+ KURL url(df.readURL());
+ if (title.isNull())
+ title = url.prettyURL();
+ urlBks << KBookmark::standaloneBookmark(title, url, df.readIcon());
+ }
+ KBookmarkDrag *mydrag = KBookmarkDrag::newDrag(urlBks, 0);
+ modified = true;
+ data = mydrag;
+ }
+ }
+ if (!KBookmarkDrag::canDecode(data))
+ {
+ if (modified) // Shouldn't happen
+ delete data;
+ return 0;
+ }
+ KEBMacroCommand *mcmd = new KEBMacroCommand(cmdName);
+ QString currentAddress = addr;
+ QValueList<KBookmark> bookmarks = KBookmarkDrag::decode(data);
+ for (QValueListConstIterator<KBookmark> it = bookmarks.begin();
+ it != bookmarks.end(); ++it) {
+ CreateCommand *cmd = new CreateCommand(currentAddress, (*it));
+ cmd->execute();
+ mcmd->addCommand(cmd);
+ currentAddress = KBookmark::nextAddress(currentAddress);
+ }
+ if (modified)
+ delete data;
+ return mcmd;
+}
+
+KEBMacroCommand* CmdGen::itemsMoved(const QValueVector<KEBListViewItem *> & items,
+ const QString &newAddress, bool copy) {
+ KEBMacroCommand *mcmd = new KEBMacroCommand(copy ? i18n("Copy Items")
+ : i18n("Move Items"));
+
+ QValueList<KBookmark> list = ListView::self()->itemsToBookmarks( items );
+ QValueList<KBookmark>::const_iterator it, end;
+ it = list.begin();
+ end = list.end();
+
+ QString bkInsertAddr = newAddress;
+ for (; it != end; ++it) {
+ if (copy) {
+ CreateCommand *cmd;
+ cmd = new CreateCommand(
+ bkInsertAddr,
+ (*it).internalElement()
+ .cloneNode(true).toElement(),
+ (*it).text());
+
+ cmd->execute();
+ mcmd->addCommand(cmd);
+
+ bkInsertAddr = cmd->finalAddress();
+
+ } else /* if (move) */ {
+ QString oldAddress = (*it).address();
+ if (bkInsertAddr.startsWith(oldAddress)) //FIXME uses internal representation of address
+ continue;
+
+ MoveCommand *cmd = new MoveCommand(oldAddress, bkInsertAddr,
+ (*it).text());
+ cmd->execute();
+ mcmd->addCommand(cmd);
+
+ bkInsertAddr = cmd->finalAddress();
+ }
+
+ bkInsertAddr = KBookmark::nextAddress(bkInsertAddr);
+ }
+
+ return mcmd;
+}
diff --git a/konqueror/keditbookmarks/commands.h b/konqueror/keditbookmarks/commands.h
new file mode 100644
index 000000000..61363f9dd
--- /dev/null
+++ b/konqueror/keditbookmarks/commands.h
@@ -0,0 +1,256 @@
+// kate: space-indent on; indent-width 3; replace-tabs on;
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __commands_h
+#define __commands_h
+
+#include <kcommand.h>
+#include <kbookmark.h>
+#include <qvaluevector.h>
+
+// Interface adds the affectedBookmarks method
+// Any class should on call add those bookmarks which are
+// affected by executing or unexecuting the command
+// Or a common parent of the affected bookmarks
+// see KBookmarkManager::notifyChange(KBookmarkGroup)
+class IKEBCommand
+{
+public:
+ IKEBCommand() {};
+ virtual ~IKEBCommand() {};
+ virtual QString affectedBookmarks() const = 0;
+ virtual QString currentAddress() const { return QString::null; }
+};
+
+class KEBMacroCommand : public KMacroCommand, public IKEBCommand
+{
+public:
+ KEBMacroCommand(const QString &name)
+ : KMacroCommand(name) {};
+ virtual ~KEBMacroCommand() {};
+ virtual QString affectedBookmarks() const;
+};
+
+class DeleteManyCommand : public KEBMacroCommand
+{
+public:
+ DeleteManyCommand(const QString &name, const QValueList<QString> & addresses);
+ virtual ~DeleteManyCommand() {};
+ virtual QString currentAddress() const;
+private:
+ QString prevOrParentAddress(QString addr);
+ QString preOrderNextAddress(QString addr);
+ bool isConsecutive(const QValueList<QString> & addresses);
+ QString m_currentAddress;
+};
+
+class CreateCommand : public KCommand, public IKEBCommand
+{
+public:
+ // separator
+ CreateCommand(const QString &address)
+ : KCommand(), m_to(address),
+ m_group(false), m_separator(true), m_originalBookmark(QDomElement())
+ { ; }
+
+ // bookmark
+ CreateCommand(const QString &address,
+ const QString &text, const QString &iconPath,
+ const KURL &url)
+ : KCommand(), m_to(address), m_text(text), m_iconPath(iconPath), m_url(url),
+ m_group(false), m_separator(false), m_originalBookmark(QDomElement())
+ { ; }
+
+ // folder
+ CreateCommand(const QString &address,
+ const QString &text, const QString &iconPath,
+ bool open)
+ : KCommand(), m_to(address), m_text(text), m_iconPath(iconPath),
+ m_group(true), m_separator(false), m_open(open), m_originalBookmark(QDomElement())
+ { ; }
+
+ // clone existing bookmark
+ CreateCommand(const QString &address,
+ const KBookmark &original, const QString &name = QString::null)
+ : KCommand(), m_to(address), m_group(false), m_separator(false),
+ m_open(false), m_originalBookmark(original), m_mytext(name)
+ { ; }
+
+ QString finalAddress() const;
+
+ virtual ~CreateCommand() { ; }
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+ virtual QString affectedBookmarks() const;
+ virtual QString currentAddress() const;
+private:
+ QString m_to;
+ QString m_text;
+ QString m_iconPath;
+ KURL m_url;
+ bool m_group:1;
+ bool m_separator:1;
+ bool m_open:1;
+ KBookmark m_originalBookmark;
+ QString m_mytext;
+};
+
+class EditCommand : public KCommand, public IKEBCommand
+{
+public:
+
+ struct Edition {
+ Edition() { ; } // needed for QValueList
+ Edition(const QString &a, const QString &v) : attr(a), value(v) {}
+ QString attr;
+ QString value;
+ };
+
+ // change one attribute
+ EditCommand(const QString &address, Edition edition, const QString &name = QString::null)
+ : KCommand(), m_address(address), m_mytext(name)
+ {
+ m_editions.append(edition);
+ }
+
+ // change multiple attributes
+ EditCommand(const QString &address,
+ const QValueList<Edition> &editions,
+ const QString &name = QString::null)
+ : KCommand(), m_address(address), m_editions(editions), m_mytext(name)
+ { ; }
+
+ void modify(const QString & a, const QString & v);
+
+ virtual ~EditCommand() { ; }
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+ virtual QString affectedBookmarks() const;
+private:
+ QString m_address;
+ QValueList<Edition> m_editions;
+ QValueList<Edition> m_reverseEditions;
+ QString m_mytext;
+};
+
+class NodeEditCommand : public KCommand, public IKEBCommand
+{
+public:
+ NodeEditCommand(const QString &address,
+ const QString &newText,
+ const QString &nodeName)
+ : KCommand(), m_address(address), m_newText(newText), m_nodename(nodeName)
+ { ; }
+
+ void modify(const QString & newText);
+
+ virtual ~NodeEditCommand() { ; }
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString affectedBookmarks() const;
+ virtual QString name() const;
+ static QString getNodeText(KBookmark bk, const QStringList &nodehier);
+ static QString setNodeText(KBookmark bk, const QStringList &nodehier,
+ QString newValue);
+private:
+ QString m_address;
+ QString m_newText;
+ QString m_oldText;
+ QString m_nodename;
+};
+
+class DeleteCommand : public KCommand, public IKEBCommand
+{
+public:
+ DeleteCommand(const QString &from, bool contentOnly = false)
+ : KCommand(), m_from(from), m_cmd(0L), m_subCmd(0L), m_contentOnly(contentOnly)
+ { ; }
+ virtual ~DeleteCommand() { delete m_cmd; delete m_subCmd;}
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const {
+ // NOTE - DeleteCommand needs no name, its always embedded in a macrocommand
+ return "";
+ };
+ virtual QString affectedBookmarks() const;
+ static KEBMacroCommand* deleteAll(const KBookmarkGroup &parentGroup);
+private:
+ QString m_from;
+ KCommand *m_cmd;
+ KEBMacroCommand *m_subCmd;
+ bool m_contentOnly;
+};
+
+class MoveCommand : public KCommand, public IKEBCommand
+{
+public:
+ // "Create it with itemsAlreadyMoved=true since
+ // "KListView moves the item before telling us about it."
+ MoveCommand(const QString &from, const QString &to, const QString &name = QString::null)
+ : KCommand(), m_from(from), m_to(to), m_mytext(name)
+ { ; }
+ QString finalAddress() const;
+ virtual ~MoveCommand() { ; }
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+ virtual QString affectedBookmarks() const;
+private:
+ QString m_from;
+ QString m_to;
+ QString m_mytext;
+};
+
+class SortItem;
+
+class SortCommand : public KEBMacroCommand
+{
+public:
+ SortCommand(const QString &name, const QString &groupAddress)
+ : KEBMacroCommand(name), m_groupAddress(groupAddress)
+ { ; }
+ virtual ~SortCommand()
+ { ; }
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString affectedBookmarks() const;
+ // internal
+ void moveAfter(const SortItem &moveMe, const SortItem &afterMe);
+private:
+ QString m_groupAddress;
+};
+
+class KEBListViewItem;
+
+class CmdGen {
+public:
+ static KEBMacroCommand* setAsToolbar(const KBookmark &bk);
+ static KEBMacroCommand* setShownInToolbar(const QValueList<KBookmark> &bk, bool show);
+ static bool shownInToolbar(const KBookmark &bk);
+ static KEBMacroCommand* deleteItems(const QString &commandName, const QValueVector<KEBListViewItem *> & items);
+ static KEBMacroCommand* insertMimeSource(const QString &cmdName, QMimeSource *data, const QString &addr);
+ static KEBMacroCommand* itemsMoved(const QValueVector<KEBListViewItem *> & items, const QString &newAddress, bool copy);
+private:
+ CmdGen() { ; }
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/cr16-app-keditbookmarks.png b/konqueror/keditbookmarks/cr16-app-keditbookmarks.png
new file mode 100644
index 000000000..6a3fc5efe
--- /dev/null
+++ b/konqueror/keditbookmarks/cr16-app-keditbookmarks.png
Binary files differ
diff --git a/konqueror/keditbookmarks/cr32-app-keditbookmarks.png b/konqueror/keditbookmarks/cr32-app-keditbookmarks.png
new file mode 100644
index 000000000..b7e10c47f
--- /dev/null
+++ b/konqueror/keditbookmarks/cr32-app-keditbookmarks.png
Binary files differ
diff --git a/konqueror/keditbookmarks/cr48-app-keditbookmarks.png b/konqueror/keditbookmarks/cr48-app-keditbookmarks.png
new file mode 100644
index 000000000..d1f5e91cc
--- /dev/null
+++ b/konqueror/keditbookmarks/cr48-app-keditbookmarks.png
Binary files differ
diff --git a/konqueror/keditbookmarks/cr64-app-keditbookmarks.png b/konqueror/keditbookmarks/cr64-app-keditbookmarks.png
new file mode 100644
index 000000000..8f2504942
--- /dev/null
+++ b/konqueror/keditbookmarks/cr64-app-keditbookmarks.png
Binary files differ
diff --git a/konqueror/keditbookmarks/dcop.cpp b/konqueror/keditbookmarks/dcop.cpp
new file mode 100644
index 000000000..76b27b9b6
--- /dev/null
+++ b/konqueror/keditbookmarks/dcop.cpp
@@ -0,0 +1,67 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "dcop.h"
+
+#include "listview.h"
+#include "toplevel.h"
+
+#include <stdlib.h>
+
+#include <qclipboard.h>
+#include <qpopupmenu.h>
+#include <qpainter.h>
+
+#include <klocale.h>
+#include <kbookmarkmanager.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+
+KBookmarkEditorIface::KBookmarkEditorIface()
+ : QObject(), DCOPObject("KBookmarkEditor") {
+ // connect(KBookmarkNotifier_stub, SIGNAL( updatedAccessMetadata(QString,QString) ),
+ // this, SLOT( slotDcopUpdatedAccessMetadata(QString,QString) ));
+ connectDCOPSignal(0, "KBookmarkNotifier", "updatedAccessMetadata(QString,QString)", "slotDcopUpdatedAccessMetadata(QString,QString)", false);
+}
+
+void KBookmarkEditorIface::slotDcopUpdatedAccessMetadata(QString filename, QString url) {
+ // evil hack, konqi gets updates by way of historymgr,
+ // therefore konqi does'nt want "save" notification,
+ // unfortunately to stop konqi getting it is difficult
+ // and probably not needed until more notifier events
+ // are added. therefore, we always updateaccessmetadata
+ // without caring about our modified state like normal
+ // and thusly there is no need to the bkmgr to do a "save"
+
+ // TODO - i'm not sure this is really true :)
+
+ if (/*KEBApp::self()->modified() &&*/ filename == CurrentMgr::self()->path()) {
+ kdDebug() << "slotDcopUpdatedAccessMetadata(" << url << ")" << endl;
+ // no undo
+ CurrentMgr::self()->mgr()->updateAccessMetadata(url, false);
+ ListView::self()->updateStatus(url);
+ KEBApp::self()->updateStatus(url);
+ // notice - no save here! see! :)
+ }
+}
+#include "dcop.moc"
diff --git a/konqueror/keditbookmarks/dcop.h b/konqueror/keditbookmarks/dcop.h
new file mode 100644
index 000000000..3e8e545d8
--- /dev/null
+++ b/konqueror/keditbookmarks/dcop.h
@@ -0,0 +1,36 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __dcop_h
+#define __dcop_h
+
+#include <dcopobject.h>
+
+class KBookmarkEditorIface : public QObject, public DCOPObject
+{
+ Q_OBJECT
+ K_DCOP
+public:
+ KBookmarkEditorIface();
+k_dcop_hidden:
+ void slotDcopUpdatedAccessMetadata(QString filename, QString url);
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/exporters.cpp b/konqueror/keditbookmarks/exporters.cpp
new file mode 100644
index 000000000..4b1bbb5e7
--- /dev/null
+++ b/konqueror/keditbookmarks/exporters.cpp
@@ -0,0 +1,90 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "exporters.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+#include <qfile.h>
+
+HTMLExporter::HTMLExporter()
+ : m_out(&m_string, IO_WriteOnly) {
+}
+
+void HTMLExporter::write(const KBookmarkGroup &grp, const QString &filename, bool showAddress) {
+ QFile file(filename);
+ if (!file.open(IO_WriteOnly)) {
+ kdError(7043) << "Can't write to file " << filename << endl;
+ return;
+ }
+ QTextStream tstream(&file);
+ tstream.setEncoding(QTextStream::UnicodeUTF8);
+ tstream << toString(grp, showAddress);
+}
+
+QString HTMLExporter::toString(const KBookmarkGroup &grp, bool showAddress)
+{
+ m_showAddress = showAddress;
+ traverse(grp);
+ return "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
+ "<html><head><title>"+i18n("My Bookmarks")+"</title>\n"
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
+ "</head>\n"
+ "<body>\n"
+ "<div>"
+ + m_string +
+ "</div>\n"
+ "</body>\n</html>\n";
+}
+
+void HTMLExporter::visit(const KBookmark &bk) {
+ // kdDebug() << "visit(" << bk.text() << ")" << endl;
+ if(bk.isSeparator())
+ {
+ m_out << bk.fullText() << "<br>"<<endl;
+ }
+ else
+ {
+ if(m_showAddress)
+ {
+ m_out << bk.fullText() <<"<br>"<< endl;
+ m_out << "<i><div style =\"margin-left: 1em\">" << bk.url().url().utf8() << "</div></i>";
+ }
+ else
+ {
+ m_out << "<a href=\"" << bk.url().url().utf8() << "\">";
+ m_out << bk.fullText() << "</a><br>" << endl;
+ }
+ }
+}
+
+void HTMLExporter::visitEnter(const KBookmarkGroup &grp) {
+ // kdDebug() << "visitEnter(" << grp.text() << ")" << endl;
+ m_out << "<b>" << grp.fullText() << "</b><br>" << endl;
+ m_out << "<div style=\"margin-left: 2em\">"<< endl;
+}
+
+void HTMLExporter::visitLeave(const KBookmarkGroup &) {
+ // kdDebug() << "visitLeave()" << endl;
+ m_out << "</div>" << endl;
+}
+
diff --git a/konqueror/keditbookmarks/exporters.h b/konqueror/keditbookmarks/exporters.h
new file mode 100644
index 000000000..cdc3844ba
--- /dev/null
+++ b/konqueror/keditbookmarks/exporters.h
@@ -0,0 +1,39 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __exporters_h
+#define __exporters_h
+
+#include <kbookmark.h>
+
+class HTMLExporter : private KBookmarkGroupTraverser {
+public:
+ HTMLExporter();
+ QString toString(const KBookmarkGroup &, bool showAddress = false);
+ void write(const KBookmarkGroup &, const QString &, bool showAddress = false);
+private:
+ virtual void visit(const KBookmark &);
+ virtual void visitEnter(const KBookmarkGroup &);
+ virtual void visitLeave(const KBookmarkGroup &);
+private:
+ QString m_string;
+ QTextStream m_out;
+ bool m_showAddress;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/favicons.cpp b/konqueror/keditbookmarks/favicons.cpp
new file mode 100644
index 000000000..b99371324
--- /dev/null
+++ b/konqueror/keditbookmarks/favicons.cpp
@@ -0,0 +1,100 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "favicons.h"
+
+#include "bookmarkiterator.h"
+#include "listview.h"
+#include "toplevel.h"
+#include "updater.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+FavIconsItrHolder *FavIconsItrHolder::s_self = 0;
+
+FavIconsItrHolder::FavIconsItrHolder()
+ : BookmarkIteratorHolder() {
+ // do stuff
+}
+
+void FavIconsItrHolder::doItrListChanged() {
+ kdDebug()<<"FavIconsItrHolder::doItrListChanged() "<<count()<<" iterators"<<endl;
+ KEBApp::self()->setCancelFavIconUpdatesEnabled(count() > 0);
+ if(count() == 0)
+ {
+ kdDebug()<<"Notifing managers "<<m_affectedBookmark<<endl;
+ CurrentMgr::self()->notifyManagers(CurrentMgr::bookmarkAt(m_affectedBookmark).toGroup());
+ m_affectedBookmark = QString::null;
+ }
+}
+
+void FavIconsItrHolder::addAffectedBookmark( const QString & address )
+{
+ kdDebug()<<"addAffectedBookmark "<<address<<endl;
+ if(m_affectedBookmark.isNull())
+ m_affectedBookmark = address;
+ else
+ m_affectedBookmark = KBookmark::commonParent(m_affectedBookmark, address);
+ kdDebug()<<" m_affectedBookmark is now "<<m_affectedBookmark<<endl;
+}
+
+/* -------------------------- */
+
+FavIconsItr::FavIconsItr(QValueList<KBookmark> bks)
+ : BookmarkIterator(bks) {
+ m_updater = 0;
+}
+
+FavIconsItr::~FavIconsItr() {
+ if (curItem())
+ curItem()->restoreStatus();
+ delete m_updater;
+}
+
+void FavIconsItr::slotDone(bool succeeded) {
+ // kdDebug() << "FavIconsItr::slotDone()" << endl;
+ curItem()->setTmpStatus(succeeded ? i18n("OK") : i18n("No favicon found"));
+ holder()->addAffectedBookmark(KBookmark::parentAddress(curBk().address()));
+ delayedEmitNextOne();
+}
+
+bool FavIconsItr::isApplicable(const KBookmark &bk) const {
+ return (!bk.isGroup() && !bk.isSeparator());
+}
+
+void FavIconsItr::doAction() {
+ // kdDebug() << "FavIconsItr::doAction()" << endl;
+ curItem()->setTmpStatus(i18n("Updating favicon..."));
+ if (!m_updater) {
+ m_updater = new FavIconUpdater(kapp, "FavIconUpdater");
+ connect(m_updater, SIGNAL( done(bool) ),
+ this, SLOT( slotDone(bool) ) );
+ }
+ if (curBk().url().protocol().startsWith("http")) {
+ m_updater->downloadIcon(curBk());
+ } else {
+ curItem()->setTmpStatus(i18n("Local file"));
+ delayedEmitNextOne();
+ }
+}
+
+#include "favicons.moc"
diff --git a/konqueror/keditbookmarks/favicons.h b/konqueror/keditbookmarks/favicons.h
new file mode 100644
index 000000000..81f7ed923
--- /dev/null
+++ b/konqueror/keditbookmarks/favicons.h
@@ -0,0 +1,69 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __favicons_h
+#define __favicons_h
+
+#include <kbookmark.h>
+#include <konq_faviconmgr.h>
+
+#include <kparts/part.h>
+#include <kparts/browserinterface.h>
+
+#include "bookmarkiterator.h"
+
+class FavIconsItrHolder : public BookmarkIteratorHolder {
+public:
+ static FavIconsItrHolder* self() {
+ if (!s_self) { s_self = new FavIconsItrHolder(); }; return s_self;
+ }
+ void addAffectedBookmark( const QString & address );
+protected:
+ virtual void doItrListChanged();
+private:
+ FavIconsItrHolder();
+ static FavIconsItrHolder *s_self;
+ QString m_affectedBookmark;
+};
+
+class FavIconUpdater;
+
+class FavIconsItr : public BookmarkIterator
+{
+ Q_OBJECT
+
+public:
+ FavIconsItr(QValueList<KBookmark> bks);
+ ~FavIconsItr();
+ virtual FavIconsItrHolder* holder() const { return FavIconsItrHolder::self(); }
+
+public slots:
+ void slotDone(bool succeeded);
+
+protected:
+ virtual void doAction();
+ virtual bool isApplicable(const KBookmark &bk) const;
+
+private:
+ FavIconUpdater *m_updater;
+};
+
+#endif
+
diff --git a/konqueror/keditbookmarks/importers.cpp b/konqueror/keditbookmarks/importers.cpp
new file mode 100644
index 000000000..6b59f04cd
--- /dev/null
+++ b/konqueror/keditbookmarks/importers.cpp
@@ -0,0 +1,293 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "importers.h"
+
+#include "commands.h"
+#include "toplevel.h"
+#include "listview.h"
+
+#include <qregexp.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+
+#include <kbookmarkmanager.h>
+
+#include <kbookmarkimporter.h>
+#include <kbookmarkimporter_ie.h>
+#include <kbookmarkimporter_opera.h>
+#include <kbookmarkimporter_crash.h>
+#include <kbookmarkdombuilder.h>
+
+QString ImportCommand::name() const {
+ return i18n("Import %1 Bookmarks").arg(visibleName());
+}
+
+QString ImportCommand::folder() const {
+ return m_folder ? i18n("%1 Bookmarks").arg(visibleName()) : QString::null;
+}
+
+ImportCommand* ImportCommand::importerFactory(const QCString &type) {
+ if (type == "Galeon") return new GaleonImportCommand();
+ else if (type == "IE") return new IEImportCommand();
+ else if (type == "KDE2") return new KDE2ImportCommand();
+ else if (type == "Opera") return new OperaImportCommand();
+ else if (type == "Crashes") return new CrashesImportCommand();
+ else if (type == "Moz") return new MozImportCommand();
+ else if (type == "NS") return new NSImportCommand();
+ else {
+ kdError() << "ImportCommand::importerFactory() - invalid type (" << type << ")!" << endl;
+ return 0;
+ }
+}
+
+ImportCommand* ImportCommand::performImport(const QCString &type, QWidget *top) {
+ ImportCommand *importer = ImportCommand::importerFactory(type);
+
+ QString mydirname = importer->requestFilename();
+ if (mydirname.isEmpty()) {
+ delete importer;
+ return 0;
+ }
+
+ int answer =
+ KMessageBox::questionYesNoCancel(
+ top, i18n("Import as a new subfolder or replace all the current bookmarks?"),
+ i18n("%1 Import").arg(importer->visibleName()),
+ i18n("As New Folder"), i18n("Replace"));
+
+ if (answer == KMessageBox::Cancel) {
+ delete importer;
+ return 0;
+ }
+
+ importer->import(mydirname, answer == KMessageBox::Yes);
+ return importer;
+}
+
+void ImportCommand::doCreateHoldingFolder(KBookmarkGroup &bkGroup) {
+ bkGroup = CurrentMgr::self()->mgr()
+ ->root().createNewFolder(CurrentMgr::self()->mgr(), folder(), false);
+ bkGroup.internalElement().setAttribute("icon", m_icon);
+ m_group = bkGroup.address();
+}
+
+void ImportCommand::execute() {
+ KBookmarkGroup bkGroup;
+
+ if (!folder().isNull()) {
+ doCreateHoldingFolder(bkGroup);
+
+ } else {
+ // import into the root, after cleaning it up
+ bkGroup = CurrentMgr::self()->mgr()->root();
+ delete m_cleanUpCmd;
+ m_cleanUpCmd = DeleteCommand::deleteAll(bkGroup);
+
+ KMacroCommand *mcmd = (KMacroCommand*) m_cleanUpCmd;
+ mcmd->addCommand(new DeleteCommand(bkGroup.address(),
+ true /* contentOnly */));
+ m_cleanUpCmd->execute();
+
+ // import at the root
+ m_group = "";
+ }
+
+ doExecute(bkGroup);
+}
+
+void ImportCommand::unexecute() {
+ if ( !folder().isEmpty() ) {
+ // we created a group -> just delete it
+ DeleteCommand cmd(m_group);
+ cmd.execute();
+
+ } else {
+ // we imported at the root -> delete everything
+ KBookmarkGroup root = CurrentMgr::self()->mgr()->root();
+ KCommand *cmd = DeleteCommand::deleteAll(root);
+
+ cmd->execute();
+ delete cmd;
+
+ // and recreate what was there before
+ m_cleanUpCmd->unexecute();
+ }
+}
+
+QString ImportCommand::affectedBookmarks() const
+{
+ QString rootAdr = CurrentMgr::self()->mgr()->root().address();
+ if(m_group == rootAdr)
+ return m_group;
+ else
+ return KBookmark::parentAddress(m_group);
+}
+
+/* -------------------------------------- */
+
+QString MozImportCommand::requestFilename() const {
+ static KMozillaBookmarkImporterImpl importer;
+ return importer.findDefaultLocation();
+}
+
+QString NSImportCommand::requestFilename() const {
+ static KNSBookmarkImporterImpl importer;
+ return importer.findDefaultLocation();
+}
+
+QString OperaImportCommand::requestFilename() const {
+ static KOperaBookmarkImporterImpl importer;
+ return importer.findDefaultLocation();
+}
+
+QString CrashesImportCommand::requestFilename() const {
+ static KCrashBookmarkImporterImpl importer;
+ return importer.findDefaultLocation();
+}
+
+QString IEImportCommand::requestFilename() const {
+ static KIEBookmarkImporterImpl importer;
+ return importer.findDefaultLocation();
+}
+
+// following two are really just xbel
+
+QString GaleonImportCommand::requestFilename() const {
+ return KFileDialog::getOpenFileName(
+ QDir::homeDirPath() + "/.galeon",
+ i18n("*.xbel|Galeon Bookmark Files (*.xbel)"));
+}
+
+#include "kstandarddirs.h"
+
+QString KDE2ImportCommand::requestFilename() const {
+ return KFileDialog::getOpenFileName(
+ locateLocal("data", "konqueror"),
+ i18n("*.xml|KDE Bookmark Files (*.xml)"));
+}
+
+/* -------------------------------------- */
+
+static void parseInto(const KBookmarkGroup &bkGroup, KBookmarkImporterBase *importer) {
+ KBookmarkDomBuilder builder(bkGroup, CurrentMgr::self()->mgr());
+ builder.connectImporter(importer);
+ importer->parse();
+}
+
+void OperaImportCommand::doExecute(const KBookmarkGroup &bkGroup) {
+ KOperaBookmarkImporterImpl importer;
+ importer.setFilename(m_fileName);
+ parseInto(bkGroup, &importer);
+}
+
+void CrashesImportCommand::doExecute(const KBookmarkGroup &bkGroup) {
+ KCrashBookmarkImporterImpl importer;
+ importer.setShouldDelete(true);
+ importer.setFilename(m_fileName);
+ parseInto(bkGroup, &importer);
+}
+
+void IEImportCommand::doExecute(const KBookmarkGroup &bkGroup) {
+ KIEBookmarkImporterImpl importer;
+ importer.setFilename(m_fileName);
+ parseInto(bkGroup, &importer);
+}
+
+void HTMLImportCommand::doExecute(const KBookmarkGroup &bkGroup) {
+ KNSBookmarkImporterImpl importer;
+ importer.setFilename(m_fileName);
+ importer.setUtf8(m_utf8);
+ parseInto(bkGroup, &importer);
+}
+
+/* -------------------------------------- */
+
+void XBELImportCommand::doCreateHoldingFolder(KBookmarkGroup &) {
+ // rather than reuse the old group node we transform the
+ // root xbel node into the group when doing an xbel import
+}
+
+void XBELImportCommand::doExecute(const KBookmarkGroup &/*bkGroup*/) {
+ // check if already open first???
+ KBookmarkManager *pManager = KBookmarkManager::managerForFile(m_fileName, false);
+
+ QDomDocument doc = CurrentMgr::self()->mgr()->internalDocument();
+
+ // get the xbel
+ QDomNode subDoc = pManager->internalDocument().namedItem("xbel").cloneNode();
+ if (subDoc.isProcessingInstruction())
+ subDoc = subDoc.nextSibling();
+ if (subDoc.isDocumentType())
+ subDoc = subDoc.nextSibling();
+ if (subDoc.nodeName() != "xbel")
+ return;
+
+ if (!folder().isEmpty()) {
+ // transform into folder
+ subDoc.toElement().setTagName("folder");
+
+ // clear attributes
+ QStringList tags;
+ for (uint i = 0; i < subDoc.attributes().count(); i++)
+ tags << subDoc.attributes().item(i).toAttr().name();
+ for (QStringList::Iterator it = tags.begin(); it != tags.end(); ++it)
+ subDoc.attributes().removeNamedItem((*it));
+
+ subDoc.toElement().setAttribute("icon", m_icon);
+
+ // give the folder a name
+ QDomElement textElem = doc.createElement("title");
+ subDoc.insertBefore(textElem, subDoc.firstChild());
+ textElem.appendChild(doc.createTextNode(folder()));
+ }
+
+ // import and add it
+ QDomNode node = doc.importNode(subDoc, true);
+
+ if (!folder().isEmpty()) {
+ CurrentMgr::self()->mgr()->root().internalElement().appendChild(node);
+ m_group = KBookmarkGroup(node.toElement()).address();
+
+ } else {
+ QDomElement root = CurrentMgr::self()->mgr()->root().internalElement();
+
+ QValueList<QDomElement> childList;
+
+ QDomNode n = subDoc.firstChild().toElement();
+ while (!n.isNull()) {
+ QDomElement e = n.toElement();
+ if (!e.isNull())
+ childList.append(e);
+ n = n.nextSibling();
+ }
+
+ QValueList<QDomElement>::Iterator it = childList.begin();
+ QValueList<QDomElement>::Iterator end = childList.end();
+ for (; it!= end ; ++it)
+ root.appendChild((*it));
+ }
+}
+
+#include "importers.moc"
diff --git a/konqueror/keditbookmarks/importers.h b/konqueror/keditbookmarks/importers.h
new file mode 100644
index 000000000..929bf249a
--- /dev/null
+++ b/konqueror/keditbookmarks/importers.h
@@ -0,0 +1,192 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __importers_h
+#define __importers_h
+
+#include "commands.h"
+#include <klocale.h>
+#include <kio/job.h>
+
+#include <kcommand.h>
+#include <kbookmark.h>
+
+#include <qptrstack.h>
+#include <qobject.h>
+
+// part pure
+class ImportCommand : public QObject, public KCommand, public IKEBCommand
+{
+ Q_OBJECT
+public:
+ ImportCommand()
+ : KCommand(), m_utf8(false), m_folder(false), m_cleanUpCmd(0L)
+ { ; }
+
+ virtual void import(const QString &fileName, bool folder) = 0;
+
+ virtual QString name() const;
+ virtual QString visibleName() const { return m_visibleName; }
+ virtual QString requestFilename() const = 0;
+
+ static ImportCommand* performImport(const QCString &, QWidget *);
+ static ImportCommand* importerFactory(const QCString &);
+
+ virtual ~ImportCommand()
+ { ; }
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString affectedBookmarks() const;
+
+ QString groupAddress() const { return m_group; }
+ QString folder() const;
+
+protected:
+ /**
+ * @param fileName HTML file to import
+ * @param folder name of the folder to create. Empty for no creation (root()).
+ * @param icon icon for the new folder, if @p folder isn't empty
+ * @param utf8 true if the HTML is in utf-8 encoding
+ */
+ void init(const QString &fileName, bool folder, const QString &icon, bool utf8)
+ {
+ m_fileName = fileName;
+ m_folder = folder;
+ m_icon = icon;
+ m_utf8 = utf8;
+ }
+
+ virtual void doCreateHoldingFolder(KBookmarkGroup &bkGroup);
+ virtual void doExecute(const KBookmarkGroup &) = 0;
+
+protected:
+ QString m_visibleName;
+ QString m_fileName;
+ QString m_icon;
+ QString m_group;
+ bool m_utf8;
+
+private:
+ bool m_folder;
+ KMacroCommand *m_cleanUpCmd;
+};
+
+// part pure
+class XBELImportCommand : public ImportCommand
+{
+public:
+ XBELImportCommand() : ImportCommand() { ; }
+ virtual void import(const QString &fileName, bool folder) = 0;
+ virtual QString requestFilename() const = 0;
+private:
+ virtual void doCreateHoldingFolder(KBookmarkGroup &bkGroup);
+ virtual void doExecute(const KBookmarkGroup &);
+};
+
+class GaleonImportCommand : public XBELImportCommand
+{
+public:
+ GaleonImportCommand() : XBELImportCommand() { m_visibleName = i18n("Galeon"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "", false);
+ }
+ virtual QString requestFilename() const;
+};
+
+class KDE2ImportCommand : public XBELImportCommand
+{
+public:
+ KDE2ImportCommand() : XBELImportCommand() { m_visibleName = i18n("KDE"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "", false);
+ }
+ virtual QString requestFilename() const;
+};
+
+// part pure
+class HTMLImportCommand : public ImportCommand
+{
+public:
+ HTMLImportCommand() : ImportCommand() { ; }
+ virtual void import(const QString &fileName, bool folder) = 0;
+ virtual QString requestFilename() const = 0;
+private:
+ virtual void doExecute(const KBookmarkGroup &);
+};
+
+class NSImportCommand : public HTMLImportCommand
+{
+public:
+ NSImportCommand() : HTMLImportCommand() { m_visibleName = i18n("Netscape"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "netscape", false);
+ }
+ virtual QString requestFilename() const;
+};
+
+class MozImportCommand : public HTMLImportCommand
+{
+public:
+ MozImportCommand() : HTMLImportCommand() { m_visibleName = i18n("Mozilla"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "mozilla", true);
+ }
+ virtual QString requestFilename() const;
+};
+
+class IEImportCommand : public ImportCommand
+{
+public:
+ IEImportCommand() : ImportCommand() { m_visibleName = i18n("IE"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "", false);
+ }
+ virtual QString requestFilename() const;
+private:
+ virtual void doExecute(const KBookmarkGroup &);
+};
+
+class OperaImportCommand : public ImportCommand
+{
+public:
+ OperaImportCommand() : ImportCommand() { m_visibleName = i18n("Opera"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "opera", false);
+ }
+ virtual QString requestFilename() const;
+private:
+ virtual void doExecute(const KBookmarkGroup &);
+};
+
+class CrashesImportCommand : public ImportCommand
+{
+public:
+ CrashesImportCommand() : ImportCommand() { m_visibleName = i18n("Crashes"); }
+ virtual void import(const QString &fileName, bool folder) {
+ init(fileName, folder, "core", false);
+ }
+ virtual QString requestFilename() const;
+private:
+ virtual void doExecute(const KBookmarkGroup &);
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/kbookmarkmerger.cpp b/konqueror/keditbookmarks/kbookmarkmerger.cpp
new file mode 100644
index 000000000..f1e4ad741
--- /dev/null
+++ b/konqueror/keditbookmarks/kbookmarkmerger.cpp
@@ -0,0 +1,138 @@
+/**
+ * kbookmarkmerger.cpp - Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kbookmarkmanager.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+#include <dcopclient.h>
+
+#include <qdir.h>
+#include <qdom.h>
+#include <qfile.h>
+
+#include <X11/Xlib.h>
+
+static const KCmdLineOptions cmdLineOptions[] =
+{
+ { "+directory", I18N_NOOP( "Directory to scan for extra bookmarks" ), 0 },
+ KCmdLineLastOption
+};
+
+// The code for this function was taken from kdesktop/kcheckrunning.cpp
+static bool kdeIsRunning()
+{
+ Display *dpy = XOpenDisplay( NULL );
+ if ( !dpy ) {
+ return false;
+ }
+
+ Atom atom = XInternAtom( dpy, "_KDE_RUNNING", False );
+ return XGetSelectionOwner( dpy, atom ) != None;
+}
+
+int main( int argc, char**argv )
+{
+ const bool kdeRunning = kdeIsRunning();
+
+ KAboutData aboutData( "kbookmarkmerger", I18N_NOOP( "KBookmarkMerger" ),
+ "1.0", I18N_NOOP( "Merges bookmarks installed by 3rd parties into the user's bookmarks" ),
+ KAboutData::License_BSD,
+ I18N_NOOP( "Copyright © 2005 Frerich Raabe" ) );
+ aboutData.addAuthor( "Frerich Raabe", I18N_NOOP( "Original author" ),
+ "raabe@kde.org" );
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( cmdLineOptions );
+
+ if ( !kdeRunning ) {
+ KApplication::disableAutoDcopRegistration();
+ }
+ KApplication app( false, false );
+ app.disableSessionManagement();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if ( args->count() != 1 ) {
+ kdError() << "No directory to scan for bookmarks specified." << endl;
+ return 1;
+ }
+
+ KBookmarkManager *konqBookmarks = KBookmarkManager::userBookmarksManager();
+ QStringList mergedFiles;
+ {
+ KBookmarkGroup root = konqBookmarks->root();
+ for ( KBookmark bm = root.first(); !bm.isNull(); bm = root.next( bm ) ) {
+ if ( bm.isGroup() ) {
+ continue;
+ }
+
+ QString mergedFrom = bm.metaDataItem( "merged_from" );
+ if ( !mergedFrom.isNull() ) {
+ mergedFiles << mergedFrom;
+ }
+ }
+ }
+
+ bool didMergeBookmark = false;
+
+ QString extraBookmarksDirName = QFile::decodeName( args->arg( 0 ) );
+ QDir extraBookmarksDir( extraBookmarksDirName, "*.xml" );
+ if ( !extraBookmarksDir.isReadable() ) {
+ kdError() << "Failed to read files in directory " << extraBookmarksDirName << endl;
+ return 1;
+ }
+
+ for ( unsigned int i = 0; i < extraBookmarksDir.count(); ++i ) {
+ const QString fileName = extraBookmarksDir[ i ];
+ if ( mergedFiles.find( fileName ) != mergedFiles.end() ) {
+ continue;
+ }
+
+ const QString absPath = extraBookmarksDir.filePath( fileName );
+ KBookmarkManager *mgr = KBookmarkManager::managerForFile( absPath, false );
+ KBookmarkGroup root = mgr->root();
+ for ( KBookmark bm = root.first(); !bm.isNull(); bm = root.next( bm ) ) {
+ if ( bm.isGroup() ) {
+ continue;
+ }
+ bm.setMetaDataItem( "merged_from", fileName );
+ konqBookmarks->root().addBookmark( konqBookmarks, bm , false );
+ didMergeBookmark = true;
+ }
+ }
+
+ if ( didMergeBookmark ) {
+ if ( !konqBookmarks->save() ) {
+ kdError() << "Failed to write merged bookmarks." << endl;
+ return 1;
+ }
+ if ( kdeRunning ) {
+ konqBookmarks->notifyChanged( "" );
+ }
+ }
+}
+
diff --git a/konqueror/keditbookmarks/kebsearchline.cpp b/konqueror/keditbookmarks/kebsearchline.cpp
new file mode 100644
index 000000000..5d0f07e59
--- /dev/null
+++ b/konqueror/keditbookmarks/kebsearchline.cpp
@@ -0,0 +1,82 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Daniel Teske <teske@squorn.de>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kebsearchline.h"
+#include "kebsearchline.moc"
+
+KEBSearchLine::KEBSearchLine(QWidget *parent, KListView *listView, const char *name)
+ : KListViewSearchLine(parent, listView, name)
+{
+ mmode = AND;
+}
+
+KEBSearchLine::KEBSearchLine(QWidget *parent, const char *name)
+ :KListViewSearchLine(parent, name)
+{
+ mmode = AND;
+}
+
+void KEBSearchLine::updateSearch(const QString &s)
+{
+ KListViewSearchLine::updateSearch(s);
+ emit searchUpdated();
+}
+
+KEBSearchLine::~KEBSearchLine()
+{
+}
+
+bool KEBSearchLine::itemMatches(const QListViewItem *item, const QString &s) const
+{
+ if(mmode == EXACTLY)
+ return KListViewSearchLine::itemMatches(item, s);
+
+ if(lastpattern != s)
+ {
+ splitted = QStringList::split(QChar(' '), s);
+ lastpattern = s;
+ }
+
+ QStringList::const_iterator it = splitted.begin();
+ QStringList::const_iterator end = splitted.end();
+
+ if(mmode == OR)
+ {
+ if(it == end) //Nothing to match
+ return true;
+ for( ; it != end; ++it)
+ if(KListViewSearchLine::itemMatches(item, *it))
+ return true;
+ }
+ else if(mmode == AND)
+ for( ; it != end; ++it)
+ if(! KListViewSearchLine::itemMatches(item, *it))
+ return false;
+
+ return (mmode == AND);
+}
+
+KEBSearchLine::modes KEBSearchLine::mode()
+{
+ return mmode;
+}
+
+void KEBSearchLine::setMode(modes m)
+{
+ mmode = m;
+}
diff --git a/konqueror/keditbookmarks/kebsearchline.h b/konqueror/keditbookmarks/kebsearchline.h
new file mode 100644
index 000000000..43248177e
--- /dev/null
+++ b/konqueror/keditbookmarks/kebsearchline.h
@@ -0,0 +1,52 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Daniel Teske <teske@squorn.de>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __kebsearchline_h
+#define __kebsearchline_h
+
+#include <klistviewsearchline.h>
+#include <qobject.h>
+
+class KEBSearchLine : public KListViewSearchLine
+{
+ Q_OBJECT
+public:
+ KEBSearchLine(QWidget *parent = 0, KListView *listView = 0, const char *name = 0);
+
+ KEBSearchLine(QWidget *parent, const char *name);
+
+ virtual ~KEBSearchLine();
+
+ enum modes { EXACTLY, AND, OR } mmode;
+ modes mode();
+ void setMode(modes m);
+ virtual void updateSearch(const QString &s = QString::null);
+
+signals:
+ void searchUpdated();
+
+protected:
+
+ virtual bool itemMatches(const QListViewItem *item, const QString &s) const;
+
+private:
+ mutable QString lastpattern; // what was cached
+ mutable QStringList splitted; // cache of the splitted string
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/keditbookmarks-genui.rc b/konqueror/keditbookmarks/keditbookmarks-genui.rc
new file mode 100644
index 000000000..3a88d720e
--- /dev/null
+++ b/konqueror/keditbookmarks/keditbookmarks-genui.rc
@@ -0,0 +1,146 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="keditbookmarks" version="25">
+
+<MenuBar>
+
+<Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+ <Separator/>
+ <Action name="file_print"/>
+ <Separator/>
+ <Action name="file_quit"/>
+</Menu>
+
+<Menu name="edit"><text>&amp;Edit</text>
+ <!-- undo/redo/cut/copy/paste stuff is
+ merged (?) at this point (ui_standards.rc) -->
+ <!-- Various things -->
+ <Action name="rename" append="edit_paste_merge"/>
+ <Action name="delete" append="edit_paste_merge"/>
+ <Separator/>
+ <Action name="changeurl"/>
+ <Action name="changecomment"/>
+ <Action name="changeicon"/>
+</Menu>
+
+<Menu name="view"><text>&amp;View</text>
+ <Action name="expandall"/>
+ <Action name="collapseall"/>
+</Menu>
+
+<Menu name="folder"><text>&amp;Folder</text>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ </Menu>
+
+<Menu name="bookmark"><text>&amp;Bookmark</text>
+ <Action name="newbookmark"/>
+</Menu>
+
+<Menu name="settings"><text>&amp;Settings</text>
+<!-- <Action name="settings_splitview" append="save_merge"/> -->
+</Menu>
+
+</MenuBar>
+
+<ToolBar name="mainToolBar" noMerge="1" fullWidth="true"><text>Main Toolbar</text>
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator/>
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+</ToolBar>
+
+<Menu name="popup_folder">
+ <!-- Stuff for folders -->
+ <Action name="setastoolbar"/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ <Separator/>
+ <Action name="testlink"/>
+ <Action name="updatefavicon"/>
+ <Separator/><!-- Clipboard -->
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/><!-- Edition -->
+ <Action name="rename"/>
+ <Action name="changeurl"/>
+ <Action name="changeicon"/>
+ <Separator/><!-- Creation -->
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/><!-- Dangerous actions :/ -->
+ <Action name="delete"/>
+</Menu>
+
+<Menu name="popup_bookmark">
+ <!-- Stuff for bookmarks -->
+ <Separator/><!-- Clipboard stuff -->
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/><!-- Edition -->
+ <Action name="rename"/>
+ <Action name="changeurl"/>
+ <Action name="changeicon"/>
+ <Separator/><!-- Creation -->
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/><!-- Dangerous actions :/ -->
+ <Action name="delete"/>
+</Menu>
+
+<!-- APPLICATION STATES -->
+
+<State name="notreadonly">
+ <Enable>
+ <Action name="settings_saveonclose"/>
+ </Enable>
+</State>
+
+<State name="normal">
+ <Enable>
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+ <Action name="file_quit"/>
+ <Action name="expandall"/>
+ <Action name="collapseall"/>
+ </Enable>
+</State>
+
+<State name="disablestuff">
+ <Disable>
+ <Action name="changecomment"/>
+ <Action name="changeicon"/>
+ <Action name="changeurl"/>
+ <Action name="delete"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_paste"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_undo"/>
+ <Action name="insertseparator"/>
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="nexthit"/>
+ <Action name="openlink"/>
+ <Action name="rename"/>
+ <Action name="setastoolbar"/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ <Action name="settings_saveonclose"/>
+ </Disable>
+</State>
+
+</kpartgui>
diff --git a/konqueror/keditbookmarks/keditbookmarks.kcfg b/konqueror/keditbookmarks/keditbookmarks.kcfg
new file mode 100644
index 000000000..16da3d8b9
--- /dev/null
+++ b/konqueror/keditbookmarks/keditbookmarks.kcfg
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="keditbookmarksrc" />
+
+ <group name="Columns">
+ <entry key="Name" type="Int">
+ <default>300</default>
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ <entry key="URL" type="Int">
+ <default>300</default>
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ <entry key="Comment" type="Int">
+ <default>300</default>
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ <entry key="Status" type="Int">
+ <default>300</default>
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ <entry key="Address" type="Int">
+ <default>300</default>
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ </group>
+ <group name="General">
+ <entry name="SaveOnClose" key="Save On Close" type="Bool">
+ <label></label>
+ <whatsthis></whatsthis>
+ </entry>
+ </group>
+
+</kcfg> \ No newline at end of file
diff --git a/konqueror/keditbookmarks/keditbookmarksui.rc b/konqueror/keditbookmarks/keditbookmarksui.rc
new file mode 100644
index 000000000..c6a559b39
--- /dev/null
+++ b/konqueror/keditbookmarks/keditbookmarksui.rc
@@ -0,0 +1,218 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="keditbookmarks" version="30">
+
+<MenuBar>
+
+<Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+ <Separator/>
+ <Action name="file_print"/>
+ <Separator/>
+ <Menu name="import" noMerge="1"><text>&amp;Import</text>
+ <Action name="importIE"/>
+ <Action name="importOpera"/>
+ <Action name="importMoz"/>
+ <Action name="importNS"/>
+ <Action name="importKDE2"/>
+ <Action name="importGaleon"/>
+ <Separator/>
+ <Action name="importCrashes"/>
+ </Menu>
+ <Menu name="export" noMerge="1"><text>&amp;Export</text>
+ <Action name="exportIE"/>
+ <Action name="exportOpera"/>
+ <Action name="exportMoz"/>
+ <Action name="exportNS"/>
+ <Separator/>
+ <Action name="exportHTML"/>
+ </Menu>
+ <Separator/>
+ <Action name="file_quit"/>
+</Menu>
+
+<Menu name="edit"><text>&amp;Edit</text>
+ <!-- undo/redo/cut/copy/paste stuff is
+ merged (?) at this point (ui_standards.rc) -->
+ <!-- Various things -->
+ <Action name="rename" append="edit_paste_merge"/>
+ <Action name="delete" append="edit_paste_merge"/>
+ <Separator/>
+ <Action name="changeurl"/>
+ <Action name="changecomment"/>
+ <Action name="changeicon"/>
+ <Separator/>
+ <Action name="showintoolbar"/>
+ <Action name="hideintoolbar"/>
+</Menu>
+
+<Menu name="view"><text>&amp;View</text>
+ <Action name="expandall"/>
+ <Action name="collapseall"/>
+</Menu>
+
+<Menu name="folder"><text>&amp;Folder</text>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/>
+ <Action name="setastoolbar"/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ </Menu>
+
+<Menu name="bookmark"><text>&amp;Bookmark</text>
+ <Action name="newbookmark"/>
+ <Action name="openlink"/>
+ <Separator/>
+ <Action name="testlink"/>
+ <Action name="updatefavicon"/>
+</Menu>
+
+<Menu name="tools"><text>&amp;Tools</text>
+ <Action name="testall"/>
+ <Action name="canceltests"/>
+ <Separator/>
+ <Action name="updateallfavicons"/>
+ <Action name="cancelfaviconupdates"/>
+</Menu>
+
+<Menu name="settings"><text>&amp;Settings</text>
+ <Action name="settings_saveonclose" append="save_merge"/>
+<!-- <Action name="settings_splitview" append="save_merge"/> -->
+ <Action name="settings_showNS" append="save_merge"/>
+</Menu>
+
+</MenuBar>
+
+<ToolBar name="mainToolBar" noMerge="1" fullWidth="true"><text>Main Toolbar</text>
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator/>
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Separator/>
+ <Action name="delete" />
+</ToolBar>
+
+<Menu name="popup_folder">
+ <!-- Stuff for folders -->
+ <Action name="setastoolbar"/>
+ <Action name="showintoolbar"/>
+ <Action name="hideintoolbar"/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ <Separator/>
+ <Action name="testlink"/>
+ <Action name="updatefavicon"/>
+ <Separator/><!-- Clipboard -->
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/><!-- Edition -->
+ <Action name="rename"/>
+ <Action name="changeurl"/>
+ <Action name="changeicon"/>
+ <Separator/><!-- Creation -->
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/><!-- Dangerous actions :/ -->
+ <Action name="delete"/>
+</Menu>
+
+<Menu name="popup_bookmark">
+ <!-- Stuff for bookmarks -->
+ <Action name="showintoolbar"/>
+ <Action name="hideintoolbar"/>
+ <Action name="openlink"/>
+ <Action name="testlink"/>
+ <Action name="updatefavicon"/>
+ <Separator/><!-- Clipboard stuff -->
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/><!-- Edition -->
+ <Action name="rename"/>
+ <Action name="changeurl"/>
+ <Action name="changeicon"/>
+ <Separator/><!-- Creation -->
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="insertseparator"/>
+ <Separator/><!-- Dangerous actions :/ -->
+ <Action name="delete"/>
+</Menu>
+
+<!-- APPLICATION STATES -->
+
+<State name="notreadonly">
+ <Enable>
+ <Action name="importGaleon"/>
+ <Action name="importKDE2"/>
+ <Action name="importOpera"/>
+ <Action name="importCrashes"/>
+ <Action name="importIE"/>
+ <Action name="importNS"/>
+ <Action name="importMoz"/>
+ <Action name="settings_showNS"/>
+ <Action name="settings_saveonclose"/>
+ </Enable>
+</State>
+
+<State name="normal">
+ <Enable>
+ <Action name="file_open"/>
+ <Action name="file_save_as"/>
+ <Action name="file_quit"/>
+ <Action name="exportOpera"/>
+ <Action name="exportHTML"/>
+ <Action name="exportIE"/>
+ <Action name="exportNS"/>
+ <Action name="exportMoz"/>
+ <Action name="expandall"/>
+ <Action name="collapseall"/>
+ </Enable>
+</State>
+
+<State name="disablestuff">
+ <Disable>
+ <Action name="changecomment"/>
+ <Action name="changeicon"/>
+ <Action name="changeurl"/>
+ <Action name="delete"/>
+ <Action name="edit_copy"/>
+ <Action name="edit_cut"/>
+ <Action name="edit_paste"/>
+ <!-- automated by KCommandHistory: <Action name="edit_redo"/> <Action name="edit_undo"/> -->
+ <Action name="importGaleon"/>
+ <Action name="importIE"/>
+ <Action name="importKDE2"/>
+ <Action name="importMoz"/>
+ <Action name="importNS"/>
+ <Action name="importOpera"/>
+ <Action name="importCrashes"/>
+ <Action name="insertseparator"/>
+ <Action name="newbookmark"/>
+ <Action name="newfolder"/>
+ <Action name="nexthit"/>
+ <Action name="openlink"/>
+ <Action name="rename"/>
+ <Action name="setastoolbar"/>
+ <Action name="showintoolbar"/>
+ <Action name="hideintoolbar"/>
+ <Action name="sort"/>
+ <Action name="recursivesort"/>
+ <Action name="testall"/>
+ <Action name="testlink"/>
+ <Action name="updateallfavicons"/>
+ <Action name="updatefavicon"/>
+ <Action name="settings_showNS"/>
+ <Action name="settings_saveonclose"/>
+ </Disable>
+</State>
+
+</kpartgui>
diff --git a/konqueror/keditbookmarks/kinsertionsort.h b/konqueror/keditbookmarks/kinsertionsort.h
new file mode 100644
index 000000000..5f71184ed
--- /dev/null
+++ b/konqueror/keditbookmarks/kinsertionsort.h
@@ -0,0 +1,59 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __kinsertionsort_h
+#define __kinsertionsort_h
+
+/**
+ * A template-based insertion sort algorithm, but not really 100%
+ * generic. It is mostly written for lists, not for arrays.
+ *
+ * A good reason to use insertion sort over faster algorithms like
+ * heap sort or quick sort, is that it minimizes the number of
+ * movements of the items. This is important in applications which support
+ * undo, because the number of commands is kept to a minimum.
+ */
+
+// Item must define isNull(), previousSibling(), nextSibling()
+// SortHelper must define moveAfter( const Item &, const Item & )
+// Criteria must define static Key key(const Item &)
+template <class Item, class Criteria, class Key, class SortHelper>
+inline void kInsertionSort( Item& firstChild, SortHelper& sortHelper )
+{
+ if (firstChild.isNull()) return;
+ Item j = firstChild.nextSibling();
+ while ( !j.isNull() )
+ {
+ Key key = Criteria::key(j);
+ // Insert A[j] into the sorted sequence A[1..j-1]
+ Item i = j.previousSibling();
+ bool moved = false;
+ while ( !i.isNull() && Criteria::key(i) > key )
+ {
+ i = i.previousSibling();
+ moved = true;
+ }
+ if ( moved )
+ sortHelper.moveAfter( j, i ); // move j right after i. If i is null, move to first position.
+ j = j.nextSibling();
+ }
+}
+
+#endif
diff --git a/konqueror/keditbookmarks/listview.cpp b/konqueror/keditbookmarks/listview.cpp
new file mode 100644
index 000000000..25f72afb2
--- /dev/null
+++ b/konqueror/keditbookmarks/listview.cpp
@@ -0,0 +1,968 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "listview.h"
+
+#include "toplevel.h"
+#include "bookmarkinfo.h"
+#include "commands.h"
+#include "testlink.h"
+#include "settings.h"
+
+#include <stdlib.h>
+
+#include <qclipboard.h>
+#include <qpopupmenu.h>
+#include <qpainter.h>
+#include <qheader.h>
+
+
+#include <klocale.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kkeydialog.h>
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <krun.h>
+#include <klistviewsearchline.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+
+// #define DEBUG_ADDRESSES
+
+ListView* ListView::s_self = 0;
+
+int ListView::s_myrenamecolumn = -1;
+KEBListViewItem *ListView::s_myrenameitem = 0;
+
+QStringList ListView::s_selected_addresses;
+QString ListView::s_current_address;
+
+ListView::ListView()
+ : m_needToFixUp(false)
+{
+}
+
+ListView::~ListView() {
+ self()->m_listView->saveColumnSetting();
+}
+
+void ListView::createListViews(QSplitter *splitter) {
+ s_self = new ListView();
+ self()->m_listView = new KEBListView(splitter, false);
+ splitter->setSizes(QValueList<int>() << 100 << 300);
+}
+
+void ListView::initListViews() {
+ self()->m_listView->init();
+}
+
+void ListView::updateListViewSetup(bool readonly) {
+ self()->m_listView->readonlyFlagInit(readonly);
+}
+
+void ListView::connectSignals() {
+ m_listView->makeConnections();
+}
+
+bool lessAddress(QString a, QString b)
+{
+ if(a == b)
+ return false;
+
+ QString error("ERROR");
+ if(a == error)
+ return false;
+ if(b == error)
+ return true;
+
+ a += "/";
+ b += "/";
+
+ uint aLast = 0;
+ uint bLast = 0;
+ uint aEnd = a.length();
+ uint bEnd = b.length();
+ // Each iteration checks one "/"-delimeted part of the address
+ // "" is treated correctly
+ while(true)
+ {
+ // Invariant: a[0 ... aLast] == b[0 ... bLast]
+ if(aLast + 1 == aEnd) //The last position was the last slash
+ return true; // That means a is shorter than b
+ if(bLast +1 == bEnd)
+ return false;
+
+ uint aNext = a.find("/", aLast + 1);
+ uint bNext = b.find("/", bLast + 1);
+
+ bool okay;
+ uint aNum = a.mid(aLast + 1, aNext - aLast - 1).toUInt(&okay);
+ if(!okay)
+ return false;
+ uint bNum = b.mid(bLast + 1, bNext - bLast - 1).toUInt(&okay);
+ if(!okay)
+ return true;
+
+ if(aNum != bNum)
+ return aNum < bNum;
+
+ aLast = aNext;
+ bLast = bNext;
+ }
+}
+
+bool operator<(const KBookmark & first, const KBookmark & second) //FIXME Using internal represantation
+{
+ return lessAddress(first.address(), second.address());
+}
+
+
+
+QValueList<KBookmark> ListView::itemsToBookmarks(const QValueVector<KEBListViewItem *> & items) const
+{
+ QValueList<KBookmark> bookmarks; //TODO optimize by using a QValueVector
+ QValueVector<KEBListViewItem *>::const_iterator it = items.constBegin();
+ QValueVector<KEBListViewItem *>::const_iterator end = items.constEnd();
+ for( ; it!=end; ++it)
+ {
+ if(*it != m_listView->rootItem() )
+ bookmarks.push_back( (*it)->bookmark() );
+ }
+ qHeapSort(bookmarks);
+ return bookmarks;
+}
+
+void ListView::invalidate(const QString & address)
+{
+ invalidate(getItemAtAddress(address));
+}
+
+void ListView::invalidate(QListViewItem * item)
+{
+ if(item->isSelected())
+ {
+ m_listView->setSelected(item, false);
+ m_needToFixUp = true;
+ }
+
+ if(m_listView->currentItem() == item)
+ {
+ // later overiden by fixUpCurrent
+ m_listView->setCurrentItem(m_listView->rootItem());
+ m_needToFixUp = true;
+ }
+
+ QListViewItem * child = item->firstChild();
+ while(child)
+ {
+ //invalidate(child);
+ child = child->nextSibling();
+ }
+}
+
+void ListView::fixUpCurrent(const QString & address)
+{
+ if(!m_needToFixUp)
+ return;
+ m_needToFixUp = false;
+
+ QListViewItem * item;
+ if(mSelectedItems.count() != 0)
+ {
+ QString least = mSelectedItems.begin().key()->bookmark().address();
+ QMap<KEBListViewItem *, bool>::iterator it, end;
+ end = mSelectedItems.end();
+ for(it = mSelectedItems.begin(); it != end; ++it)
+ if( lessAddress(it.key()->bookmark().address(), least))
+ least = it.key()->bookmark().address();
+ item = getItemAtAddress(least);
+ }
+ else
+ item = getItemAtAddress(address);
+ m_listView->setSelected( item, true );
+ m_listView->setCurrentItem( item );
+}
+
+
+void ListView::selected(KEBListViewItem * item, bool s)
+{
+ Q_ASSERT(item->bookmark().hasParent() || item == m_listView->rootItem());
+ QMap<KEBListViewItem *, bool>::iterator it;
+
+ if(s)
+ mSelectedItems[item] = item;
+ else
+ if((it = mSelectedItems.find(item)) != mSelectedItems.end())
+ mSelectedItems.remove(it);
+
+ KEBApp::self()->updateActions();
+
+ const QValueVector<KEBListViewItem *> & selected = selectedItemsMap();
+ if (selected.count() != 1)
+ {
+ KEBApp::self()->bkInfo()->showBookmark(KBookmark());
+ return;
+ }
+ //FIXME do it once somewhere
+ if (!KEBApp::self()->bkInfo()->connected()) {
+ connect(KEBApp::self()->bkInfo(), SIGNAL( updateListViewItem() ),
+ SLOT( slotBkInfoUpdateListViewItem() ));
+ KEBApp::self()->bkInfo()->setConnected(true);
+ }
+
+ KEBApp::self()->bkInfo()->showBookmark((*(selected.constBegin()))->bookmark());
+ firstSelected()->modUpdate();
+}
+
+QValueVector<KEBListViewItem *> ListView::selectedItemsMap() const
+{
+ QValueVector<KEBListViewItem *> selected;
+ QMap<KEBListViewItem *, bool>::ConstIterator it, end;
+ end = mSelectedItems.constEnd();
+ for(it = mSelectedItems.constBegin(); it != end; ++it)
+ {
+ if( it.key()->isVisible())
+ selected.push_back(it.key());
+ }
+ return selected;
+}
+
+KEBListViewItem * ListView::firstSelected() const
+{
+ if(mSelectedItems.isEmpty())
+ return 0L;
+
+ QValueVector<KEBListViewItem *> selected = selectedItemsMap();
+ if(selected.isEmpty())
+ return 0L;
+ else
+ return *(selected.constBegin());
+}
+
+void ListView::deselectAllChildren(KEBListViewItem *item)
+{
+ KEBListViewItem* child = static_cast<KEBListViewItem *>(item->firstChild());
+ while(child)
+ {
+ if (child)
+ {
+ if(child->isSelected())
+ child->listView()->setSelected(child, false); //calls deselectAllChildren
+ else
+ deselectAllChildren(child);
+ }
+ child->repaint();
+ child = static_cast<KEBListViewItem *>(child->nextSibling());
+ }
+}
+
+QValueList<QString> ListView::selectedAddresses()
+{
+ QValueList<QString> addresses;
+ QValueList<KBookmark> bookmarks = itemsToBookmarks( selectedItemsMap() );
+ QValueList<KBookmark>::const_iterator it, end;
+ end = bookmarks.end();
+ for( it = bookmarks.begin(); it != end; ++it)
+ addresses.append( (*it).address() );
+ return addresses;
+}
+
+
+QValueList<KBookmark> ListView::selectedBookmarksExpanded() const {
+ QValueList<KBookmark> bookmarks;
+ for (QListViewItemIterator it(m_listView); it.current() != 0; ++it) {
+ if (!it.current()->isSelected())
+ continue;
+ if(it.current() == m_listView->firstChild()) // root case
+ continue;
+ if(!it.current()->isVisible()) // skip over filtered bookmarks
+ continue;
+ if (it.current()->childCount() == 0) // non folder case
+ bookmarks.append(static_cast<KEBListViewItem *>(it.current())->bookmark());
+ else
+ selectedBookmarksExpandedHelper(static_cast<KEBListViewItem *>(it.current()), bookmarks);
+ }
+ return bookmarks;
+}
+
+
+void ListView::selectedBookmarksExpandedHelper(KEBListViewItem * item, QValueList<KBookmark> & bookmarks) const
+{
+ KEBListViewItem* child = static_cast<KEBListViewItem *>(item->firstChild());
+ while( child )
+ {
+ if(child->isVisible())
+ {
+ if (!child->isEmptyFolderPadder() && (child->childCount() == 0))
+ bookmarks.append(child->bookmark());
+ if(child->childCount())
+ selectedBookmarksExpandedHelper(child, bookmarks);
+ }
+ child = static_cast<KEBListViewItem *>(child->nextSibling());
+ }
+}
+
+QValueList<KBookmark> ListView::allBookmarks() const {
+ QValueList<KBookmark> bookmarks;
+ for (QListViewItemIterator it(m_listView); it.current() != 0; ++it)
+ {
+ KEBListViewItem * item = static_cast<KEBListViewItem *>(it.current());
+ if (!item->isEmptyFolderPadder() && (item->childCount() == 0))
+ bookmarks.append(static_cast<KEBListViewItem *>(it.current())->bookmark());
+ }
+ return bookmarks;
+}
+
+// DESIGN - make + "/0" a kbookmark:: thing?
+
+QString ListView::userAddress() const
+{
+ KBookmark current = firstSelected()->bookmark();
+ return (current.isGroup())
+ ? (current.address() + "/0") //FIXME internal represantation used
+ : KBookmark::nextAddress(current.address());
+}
+
+void ListView::setCurrent(KEBListViewItem *item, bool select) {
+ m_listView->setCurrentItem(item);
+ if(select)
+ {
+ m_listView->clearSelection();
+ m_listView->setSelected(item, true);
+ }
+}
+
+KEBListViewItem* ListView::getItemAtAddress(const QString &address) const {
+ //FIXME uses internal represantation of bookmark address
+ QListViewItem *item = m_listView->rootItem();
+
+ QStringList addresses = QStringList::split('/',address); // e.g /5/10/2
+
+ for (QStringList::Iterator it = addresses.begin(); it != addresses.end(); ++it) {
+ if (item = item->firstChild(), !item)
+ return 0;
+ for (unsigned int i = 0; i < (*it).toUInt(); ++i)
+ if (item = item->nextSibling(), !item)
+ return 0;
+ }
+ return static_cast<KEBListViewItem *>(item);
+}
+
+void ListView::setOpen(bool open) {
+ for (QListViewItemIterator it(m_listView); it.current() != 0; ++it)
+ if (it.current()->parent())
+ it.current()->setOpen(open);
+}
+
+SelcAbilities ListView::getSelectionAbilities() const {
+ SelcAbilities sa = { false, false, false, false, false, false, false, false, false };
+
+ if (mSelectedItems.count() > 0)
+ {
+ QValueVector<KEBListViewItem *> selected = selectedItemsMap();
+ if(!selected.isEmpty())
+ {
+ //Optimize
+ KBookmark nbk = (*(selected.constBegin()))->bookmark();
+ sa.itemSelected = true;
+ sa.group = nbk.isGroup();
+ sa.separator = nbk.isSeparator();
+ sa.urlIsEmpty = nbk.url().isEmpty();
+ sa.root = (*(selected.constBegin()) == m_listView->rootItem());
+ sa.multiSelect = (selected.count() > 1);
+ sa.singleSelect = (!sa.multiSelect && sa.itemSelected);
+ sa.tbShowState = CmdGen::shownInToolbar(nbk);
+ }
+ }
+
+ sa.notEmpty = (m_listView->rootItem()->childCount() > 0);
+
+ return sa;
+}
+
+void ListView::handleDropped(KEBListView *, QDropEvent *e, QListViewItem *newParent, QListViewItem *itemAfterQLVI) {
+ bool inApp = (e->source() == m_listView->viewport());
+
+ // drop before root item
+ if (!newParent)
+ return;
+
+ KEBListViewItem *itemAfter = static_cast<KEBListViewItem *>(itemAfterQLVI);
+
+ QString newAddress
+ = (!itemAfter || itemAfter->isEmptyFolderPadder())
+ ? (static_cast<KEBListViewItem *>(newParent)->bookmark().address() + "/0")
+ : (KBookmark::nextAddress(itemAfter->bookmark().address()));
+
+ KEBMacroCommand *mcmd = 0;
+
+ if (!inApp) {
+ mcmd = CmdGen::insertMimeSource(i18n("Drop Items"), e, newAddress);
+
+ } else {
+ const QValueVector<KEBListViewItem *> & selected = selectedItemsMap();
+ if (!(selected.count() > 0) || (*(selected.constBegin()) == itemAfterQLVI))
+ return;
+ bool copy = (e->action() == QDropEvent::Copy);
+ mcmd = CmdGen::itemsMoved(selected, newAddress, copy);
+ }
+
+ CmdHistory::self()->didCommand(mcmd);
+}
+
+void ListView::updateStatus(QString url) {
+ m_listView->updateByURL(url);
+}
+
+void ListView::updateListView()
+{
+ // this is upper border of the visible are
+ int lastCurrentY = m_listView->contentsY();
+
+ //Save selected items (restored in fillWithGroup)
+ s_selected_addresses.clear();
+ QMap<KEBListViewItem *, bool>::const_iterator it, end;
+ it = mSelectedItems.begin();
+ end = mSelectedItems.end();
+ for ( ; it != end; ++it)
+ s_selected_addresses << it.key()->bookmark().address();
+ if(m_listView->currentItem())
+ {
+ KEBListViewItem * item = static_cast<KEBListViewItem*>(m_listView->currentItem());
+ if(item->isEmptyFolderPadder())
+ s_current_address = static_cast<KEBListViewItem*>(item->parent())->bookmark().address();
+ else
+ s_current_address = item->bookmark().address();
+ }
+ else
+ s_current_address = QString::null;
+
+ updateTree();
+ m_searchline->updateSearch();
+
+ // ensureVisible wants to have the midpoint of the new visible area
+ m_listView->ensureVisible(0, lastCurrentY + m_listView->visibleHeight() / 2, 0, m_listView->visibleHeight() / 2 );
+}
+
+void ListView::updateTree() {
+ KBookmarkGroup root = CurrentMgr::self()->mgr()->root();
+ fillWithGroup(m_listView, root);
+}
+
+void ListView::fillWithGroup(KEBListView *lv, KBookmarkGroup group, KEBListViewItem *parentItem) {
+ KEBListViewItem *lastItem = 0;
+ if (!parentItem)
+ {
+ lv->clear();
+ KEBListViewItem *tree = new KEBListViewItem(lv, group);
+ fillWithGroup(lv, group, tree);
+ tree->QListViewItem::setOpen(true);
+ if (s_selected_addresses.contains(tree->bookmark().address()))
+ lv->setSelected(tree, true);
+ if(!s_current_address.isNull() && s_current_address == tree->bookmark().address())
+ lv->setCurrentItem(tree);
+ return;
+ }
+ for (KBookmark bk = group.first(); !bk.isNull(); bk = group.next(bk)) {
+ KEBListViewItem *item = 0;
+ if (bk.isGroup()) {
+ KBookmarkGroup grp = bk.toGroup();
+ item = (parentItem)
+ ? new KEBListViewItem(parentItem, lastItem, grp)
+ : new KEBListViewItem(lv, lastItem, grp);
+ fillWithGroup(lv, grp, item);
+ if (grp.isOpen())
+ item->QListViewItem::setOpen(true);
+ if (grp.first().isNull())
+ new KEBListViewItem(item, item); // empty folder
+ lastItem = item;
+
+ }
+ else
+ {
+ item = (parentItem)
+ ? ( (lastItem)
+ ? new KEBListViewItem(parentItem, lastItem, bk)
+ : new KEBListViewItem(parentItem, bk))
+ : ( (lastItem)
+ ? new KEBListViewItem(lv, lastItem, bk)
+ : new KEBListViewItem(lv, bk));
+ lastItem = item;
+ }
+ if (s_selected_addresses.contains(bk.address()))
+ lv->setSelected(item, true);
+ if(!s_current_address.isNull() && s_current_address == bk.address())
+ lv->setCurrentItem(item);
+ }
+}
+
+void ListView::handleMoved(KEBListView *) {
+ // kdDebug() << "ListView::handleMoved()" << endl;
+ /* TODO - neil's wishlist item - unfortunately handleMoved is not called sometimes...
+ * KMacroCommand *mcmd = CmdGen::self()->deleteItems( i18n("Moved Items"),
+ * ListView::self()->selectedItems());
+ * CmdHistory::self()->didCommand(mcmd);
+ */
+}
+
+void ListView::slotBkInfoUpdateListViewItem() {
+ // its not possible that the selection changed inbetween as
+ // handleSelectionChanged is the one that sets up bkInfo()
+ // to emit this signal, otoh. maybe this can cause various
+ // differing responses.
+ // kdDebug() << "slotBkInfoUpdateListViewItem()" << endl;
+ KEBListViewItem *i = firstSelected();
+ Q_ASSERT(i);
+ KBookmark bk = i->bookmark();
+ i->setText(KEBListView::NameColumn, bk.fullText());
+ i->setText(KEBListView::UrlColumn, bk.url().pathOrURL());
+ QString commentStr = NodeEditCommand::getNodeText(bk, QStringList() << "desc");
+ i->setText(KEBListView::CommentColumn, commentStr);
+}
+
+void ListView::handleContextMenu(KEBListView *, KListView *, QListViewItem *qitem, const QPoint &p) {
+ KEBListViewItem *item = static_cast<KEBListViewItem *>(qitem);
+ const char *type = ( !item
+ || (item == m_listView->rootItem())
+ || (item->bookmark().isGroup())
+ || (item->isEmptyFolderPadder()))
+ ? "popup_folder" : "popup_bookmark";
+ QWidget* popup = KEBApp::self()->popupMenuFactory(type);
+ if (popup)
+ static_cast<QPopupMenu*>(popup)->popup(p);
+}
+
+void ListView::handleDoubleClicked(KEBListView *lv, QListViewItem *item, const QPoint &, int column) {
+ lv->rename(item, column);
+}
+
+void ListView::handleItemRenamed(KEBListView *lv, QListViewItem *item, const QString &newText, int column) {
+ Q_ASSERT(item);
+ KBookmark bk = static_cast<KEBListViewItem *>(item)->bookmark();
+ KCommand *cmd = 0;
+ if (column == KEBListView::NameColumn) {
+ if (newText.isEmpty()) {
+ // can't have an empty name, therefore undo the user action
+ item->setText(KEBListView::NameColumn, bk.fullText());
+ } else if (bk.fullText() != newText) {
+ cmd = new NodeEditCommand(bk.address(), newText, "title");
+ }
+
+ } else if (column == KEBListView::UrlColumn && !lv->isFolderList()) {
+ if (bk.url().pathOrURL() != newText)
+ {
+ KURL u = KURL::fromPathOrURL(newText);
+ cmd = new EditCommand(bk.address(), EditCommand::Edition("href", u.url(0, 106)), i18n("URL"));
+ }
+
+ } else if (column == KEBListView::CommentColumn && !lv->isFolderList()) {
+ if (NodeEditCommand::getNodeText(bk, "desc") != newText)
+ cmd = new NodeEditCommand(bk.address(), newText, "desc");
+ }
+ CmdHistory::self()->addCommand(cmd);
+}
+
+// used by f2 and f3 shortcut slots - see actionsimpl
+void ListView::rename(int column) {
+ m_listView->rename(firstSelected(), column);
+}
+
+void ListView::clearSelection() {
+ m_listView->clearSelection();
+}
+
+void ListView::startRename(int column, KEBListViewItem *item) {
+ s_myrenamecolumn = column;
+ s_myrenameitem = item;
+}
+
+void ListView::renameNextCell(bool fwd) {
+ KEBListView *lv = m_listView;
+ while (1) {
+ if (fwd && s_myrenamecolumn < KEBListView::CommentColumn) {
+ s_myrenamecolumn++;
+ } else if (!fwd && s_myrenamecolumn > KEBListView::NameColumn) {
+ s_myrenamecolumn--;
+ } else {
+ s_myrenameitem =
+ static_cast<KEBListViewItem *>(
+ fwd ? ( s_myrenameitem->itemBelow()
+ ? s_myrenameitem->itemBelow() : lv->firstChild() )
+ : ( s_myrenameitem->itemAbove()
+ ? s_myrenameitem->itemAbove() : lv->lastItem() ) );
+ s_myrenamecolumn
+ = fwd ? KEBListView::NameColumn
+ : KEBListView::CommentColumn;
+ }
+ if (s_myrenameitem
+ && s_myrenameitem != m_listView->rootItem()
+ && !s_myrenameitem->isEmptyFolderPadder()
+ && !s_myrenameitem->bookmark().isSeparator()
+ && !(s_myrenamecolumn == KEBListView::UrlColumn && s_myrenameitem->bookmark().isGroup())
+ ) {
+ break;
+ }
+ }
+ lv->rename(s_myrenameitem, s_myrenamecolumn);
+}
+
+/* -------------------------------------- */
+
+class KeyPressEater : public QObject {
+ public:
+ KeyPressEater( QWidget *parent = 0, const char *name = 0 )
+ : QObject(parent, name) {
+ m_allowedToTab = true;
+ }
+ protected:
+ bool eventFilter(QObject *, QEvent *);
+ bool m_allowedToTab;
+};
+
+bool KeyPressEater::eventFilter(QObject *, QEvent *pe) {
+ if (pe->type() == QEvent::KeyPress) {
+ QKeyEvent *k = (QKeyEvent *) pe;
+ if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab)
+ && !(k->state() & ControlButton || k->state() & AltButton)
+ ) {
+ if (m_allowedToTab) {
+ bool fwd = (k->key() == Key_Tab && !(k->state() & ShiftButton));
+ ListView::self()->renameNextCell(fwd);
+ }
+ return true;
+ } else {
+ m_allowedToTab = (k->key() == Qt::Key_Escape || k->key() == Qt::Key_Enter);
+ }
+ }
+ return false;
+}
+
+/* -------------------------------------- */
+
+void KEBListView::loadColumnSetting()
+{
+ header()->resizeSection(KEBListView::NameColumn, KEBSettings::name());
+ header()->resizeSection(KEBListView::UrlColumn, KEBSettings::uRL());
+ header()->resizeSection(KEBListView::CommentColumn, KEBSettings::comment());
+ header()->resizeSection(KEBListView::StatusColumn, KEBSettings::status());
+#ifdef DEBUG_ADDRESSES
+ header()->resizeSection(KEBListView::AddressColumn, KEBSettings::address());
+#endif
+ m_widthsDirty = false;
+}
+
+void KEBListView::saveColumnSetting ()
+{
+ if (m_widthsDirty) {
+ KEBSettings::setName( header()->sectionSize(KEBListView::NameColumn));
+ KEBSettings::setURL( header()->sectionSize(KEBListView::UrlColumn));
+ KEBSettings::setComment( header()->sectionSize(KEBListView::CommentColumn));
+ KEBSettings::setStatus( header()->sectionSize(KEBListView::StatusColumn));
+#ifdef DEBUG_ADDRESSES
+ KEBSettings::setAddress( header()->sectionSize(KEBListView::AddressColumn));
+#endif
+ KEBSettings::writeConfig();
+ }
+}
+
+void KEBListView::slotColumnSizeChanged(int, int, int)
+{
+ m_widthsDirty = true;
+}
+
+void KEBListView::init() {
+ setRootIsDecorated(false);
+ if (!m_folderList) {
+ addColumn(i18n("Bookmark"), 0); // KEBListView::NameColumn
+ addColumn(i18n("URL"), 0);
+ addColumn(i18n("Comment"), 0);
+ addColumn(i18n("Status"), 0);
+#ifdef DEBUG_ADDRESSES
+ addColumn(i18n("Address"), 0);
+#endif
+ } else {
+ addColumn(i18n("Folder"), 0);
+ }
+ loadColumnSetting();
+ setRenameable(KEBListView::NameColumn);
+ setRenameable(KEBListView::UrlColumn);
+ setRenameable(KEBListView::CommentColumn);
+ setTabOrderedRenaming(false);
+ setSorting(-1, false);
+ setDragEnabled(true);
+ setSelectionModeExt((!m_folderList) ? KListView::Extended: KListView::Single);
+ setAllColumnsShowFocus(true);
+ connect(header(), SIGNAL(sizeChange(int, int, int)),
+ this, SLOT(slotColumnSizeChanged(int, int, int)));
+}
+
+void KEBListView::makeConnections() {
+ connect(this, SIGNAL( moved() ),
+ SLOT( slotMoved() ));
+ connect(this, SIGNAL( contextMenu(KListView *, QListViewItem*, const QPoint &) ),
+ SLOT( slotContextMenu(KListView *, QListViewItem *, const QPoint &) ));
+ connect(this, SIGNAL( itemRenamed(QListViewItem *, const QString &, int) ),
+ SLOT( slotItemRenamed(QListViewItem *, const QString &, int) ));
+ connect(this, SIGNAL( doubleClicked(QListViewItem *, const QPoint &, int) ),
+ SLOT( slotDoubleClicked(QListViewItem *, const QPoint &, int) ));
+ connect(this, SIGNAL( dropped(QDropEvent*, QListViewItem*, QListViewItem*) ),
+ SLOT( slotDropped(QDropEvent*, QListViewItem*, QListViewItem*) ));
+}
+
+void KEBListView::readonlyFlagInit(bool readonly) {
+ setItemsMovable(readonly); // we move items ourselves (for undo)
+ setItemsRenameable(!readonly);
+ setAcceptDrops(!readonly);
+ setDropVisualizer(!readonly);
+}
+
+void KEBListView::slotMoved()
+{ ListView::self()->handleMoved(this); }
+void KEBListView::slotContextMenu(KListView *a, QListViewItem *b, const QPoint &c)
+{ ListView::self()->handleContextMenu(this, a,b,c); }
+void KEBListView::slotItemRenamed(QListViewItem *a, const QString &b, int c)
+{ ListView::self()->handleItemRenamed(this, a,b,c); }
+void KEBListView::slotDoubleClicked(QListViewItem *a, const QPoint &b, int c)
+{ ListView::self()->handleDoubleClicked(this, a,b,c); }
+void KEBListView::slotDropped(QDropEvent *a, QListViewItem *b, QListViewItem *c)
+{ ListView::self()->handleDropped(this, a,b,c); }
+
+void KEBListView::rename(QListViewItem *qitem, int column) {
+ KEBListViewItem *item = static_cast<KEBListViewItem *>(qitem);
+ if ( !(column == NameColumn || column == UrlColumn || column == CommentColumn)
+ || KEBApp::self()->readonly()
+ || !item
+ || item == firstChild()
+ || item->isEmptyFolderPadder()
+ || item->bookmark().isSeparator()
+ || (column == UrlColumn && item->bookmark().isGroup())
+ ) {
+ return;
+ }
+ ListView::startRename(column, item);
+ KeyPressEater *keyPressEater = new KeyPressEater(this);
+ renameLineEdit()->installEventFilter(keyPressEater);
+ KListView::rename(item, column);
+}
+
+KEBListViewItem* KEBListView::rootItem() const {
+ return static_cast<KEBListViewItem *>(firstChild());
+}
+
+// Update display of bookmarks containing URL
+void KEBListView::updateByURL(QString url) {
+ for (QListViewItemIterator it(this); it.current(); it++) {
+ KEBListViewItem *p = static_cast<KEBListViewItem *>(it.current());
+ if (p->text(1) == url) {
+ p->modUpdate();
+ }
+ }
+}
+
+bool KEBListView::acceptDrag(QDropEvent * e) const {
+ return (e->source() == viewport() || KBookmarkDrag::canDecode(e));
+}
+
+QDragObject *KEBListView::dragObject() {
+ QValueList<KBookmark> bookmarks =
+ ListView::self()->itemsToBookmarks(ListView::self()->selectedItemsMap());
+ KBookmarkDrag *drag = KBookmarkDrag::newDrag(bookmarks, viewport());
+ const QString iconname =
+ (bookmarks.size() == 1) ? bookmarks.first().icon() : QString("bookmark");
+ drag->setPixmap(SmallIcon(iconname)) ;
+ return drag;
+}
+
+/* -------------------------------------- */
+
+bool KEBListViewItem::parentSelected(QListViewItem * item)
+{
+ QListViewItem *root = item->listView()->firstChild();
+ for( QListViewItem *parent = item->parent(); parent ; parent = parent->parent())
+ if (parent->isSelected() && parent != root)
+ return true;
+ return false;
+}
+
+void KEBListViewItem::setSelected(bool s)
+{
+ if( isEmptyFolderPadder())
+ {
+ parent()->setSelected(true);
+ return;
+ }
+
+ if(listView()->firstChild() == this)
+ {
+ ListView::self()->selected(this, s);
+ QListViewItem::setSelected( s );
+ return;
+ }
+
+ if(s == false)
+ {
+ ListView::self()->selected(this, false);
+ QListViewItem::setSelected( false );
+ ListView::deselectAllChildren( this ); //repaints
+ }
+ else if(parentSelected(this))
+ return;
+ else
+ {
+ ListView::self()->selected(this, true);
+ QListViewItem::setSelected( true );
+ ListView::deselectAllChildren(this);
+ }
+}
+
+void KEBListViewItem::normalConstruct(const KBookmark &bk) {
+#ifdef DEBUG_ADDRESSES
+ setText(KEBListView::AddressColumn, bk.address());
+#endif
+ setText(KEBListView::CommentColumn, NodeEditCommand::getNodeText(bk, "desc"));
+ bool shown = CmdGen::shownInToolbar(bk);
+ setPixmap(0, SmallIcon(shown ? QString("bookmark_toolbar") : bk.icon()));
+ // DESIGN - modUpdate badly needs a redesign
+ modUpdate();
+}
+
+// DESIGN - following constructors should be names classes or else just explicit
+
+// toplevel item (there should be only one!)
+KEBListViewItem::KEBListViewItem(QListView *parent, const KBookmarkGroup &gp)
+ : QListViewItem(parent, KEBApp::self()->caption().isNull()
+ ? i18n("Bookmarks")
+ : i18n("%1 Bookmarks").arg(KEBApp::self()->caption())),
+ m_bookmark(gp), m_emptyFolderPadder(false) {
+
+ setPixmap(0, SmallIcon("bookmark"));
+ setExpandable(true);
+}
+
+// empty folder item
+KEBListViewItem::KEBListViewItem(KEBListViewItem *parent, QListViewItem *after)
+ : QListViewItem(parent, after, i18n("Empty Folder") ), m_emptyFolderPadder(true) {
+ setPixmap(0, SmallIcon("bookmark"));
+}
+
+// group
+KEBListViewItem::KEBListViewItem(KEBListViewItem *parent, QListViewItem *after, const KBookmarkGroup &gp)
+ : QListViewItem(parent, after, gp.fullText()), m_bookmark(gp), m_emptyFolderPadder(false) {
+ setExpandable(true);
+ normalConstruct(gp);
+}
+
+// bookmark (first of its group)
+KEBListViewItem::KEBListViewItem(KEBListViewItem *parent, const KBookmark & bk)
+ : QListViewItem(parent, bk.fullText(), bk.url().pathOrURL()), m_bookmark(bk), m_emptyFolderPadder(false) {
+ normalConstruct(bk);
+}
+
+// bookmark (after another)
+KEBListViewItem::KEBListViewItem(KEBListViewItem *parent, QListViewItem *after, const KBookmark &bk)
+ : QListViewItem(parent, after, bk.fullText(), bk.url().pathOrURL()), m_bookmark(bk), m_emptyFolderPadder(false) {
+ normalConstruct(bk);
+}
+
+// root bookmark (first of its group)
+KEBListViewItem::KEBListViewItem(QListView *parent, const KBookmark & bk)
+ : QListViewItem(parent, bk.fullText(), bk.url().pathOrURL()), m_bookmark(bk), m_emptyFolderPadder(false) {
+ normalConstruct(bk);
+}
+
+// root bookmark (after another)
+KEBListViewItem::KEBListViewItem(QListView *parent, QListViewItem *after, const KBookmark &bk)
+ : QListViewItem(parent, after, bk.fullText(), bk.url().pathOrURL()), m_bookmark(bk), m_emptyFolderPadder(false) {
+ normalConstruct(bk);
+}
+
+// DESIGN - move this into kbookmark or into a helper
+void KEBListViewItem::setOpen(bool open) {
+ if (!parent())
+ return;
+ m_bookmark.internalElement().setAttribute("folded", open ? "no" : "yes");
+ QListViewItem::setOpen(open);
+}
+
+void KEBListViewItem::greyStyle(QColorGroup &cg) {
+ int h, s, v;
+ cg.background().hsv(&h, &s, &v);
+ QColor color = (v > 180 && v < 220) ? (Qt::darkGray) : (Qt::gray);
+ cg.setColor(QColorGroup::Text, color);
+}
+
+void KEBListViewItem::boldStyle(QPainter *p) {
+ QFont font = p->font();
+ font.setBold(true);
+ p->setFont(font);
+}
+
+void KEBListViewItem::paintCell(QPainter *p, const QColorGroup &ocg, int col, int w, int a) {
+ QColorGroup cg(ocg);
+ if (parentSelected(this)) {
+ int base_h, base_s, base_v;
+ cg.background().hsv(&base_h, &base_s, &base_v);
+
+ int hilite_h, hilite_s, hilite_v;
+ cg.highlight().hsv(&hilite_h, &hilite_s, &hilite_v);
+
+ QColor col(hilite_h,
+ (hilite_s + base_s + base_s ) / 3,
+ (hilite_v + base_v + base_v ) / 3,
+ QColor::Hsv);
+ cg.setColor(QColorGroup::Base, col);
+ }
+
+ if (col == KEBListView::StatusColumn) {
+ switch (m_paintStyle) {
+ case KEBListViewItem::GreyStyle:
+ {
+ greyStyle(cg);
+ break;
+ }
+ case KEBListViewItem::BoldStyle:
+ {
+ boldStyle(p);
+ break;
+ }
+ case KEBListViewItem::GreyBoldStyle:
+ {
+ greyStyle(cg);
+ boldStyle(p);
+ break;
+ }
+ case KEBListViewItem::DefaultStyle:
+ break;
+ }
+ }
+
+ QListViewItem::paintCell(p, cg, col, w,a);
+}
+
+#include "listview.moc"
diff --git a/konqueror/keditbookmarks/listview.h b/konqueror/keditbookmarks/listview.h
new file mode 100644
index 000000000..7741f5858
--- /dev/null
+++ b/konqueror/keditbookmarks/listview.h
@@ -0,0 +1,217 @@
+// kate: space-indent on; indent-width 3; replace-tabs on;
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __listview_h
+#define __listview_h
+
+#include <assert.h>
+
+#include <qlistview.h>
+#include <qmap.h>
+#include <qvaluevector.h>
+
+#include <klocale.h>
+#include <kbookmark.h>
+#include <klistview.h>
+#include <kiconloader.h>
+
+#include "toplevel.h"
+
+class QSplitter;
+class KListViewSearchLine;
+
+class KEBListViewItem : public QListViewItem
+{
+public:
+ KEBListViewItem(QListView *, const KBookmarkGroup &);
+ KEBListViewItem(KEBListViewItem *, QListViewItem *);
+ KEBListViewItem(KEBListViewItem *, QListViewItem *, const KBookmarkGroup &);
+ KEBListViewItem(KEBListViewItem *, const KBookmark &);
+ KEBListViewItem(KEBListViewItem *, QListViewItem *, const KBookmark &);
+
+ KEBListViewItem(QListView *, const KBookmark &);
+ KEBListViewItem(QListView *, QListViewItem *, const KBookmark &);
+
+ void nsPut(const QString &nm);
+
+ void modUpdate();
+
+ void setOldStatus(const QString &);
+ void setTmpStatus(const QString &);
+ void restoreStatus();
+
+ void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment);
+ void setSelected ( bool s );
+
+ virtual void setOpen(bool);
+
+ bool isEmptyFolderPadder() const { return m_emptyFolderPadder; }
+ const KBookmark bookmark() const { return m_bookmark; }
+
+ typedef enum { GreyStyle, BoldStyle, GreyBoldStyle, DefaultStyle } PaintStyle;
+
+ static bool parentSelected(QListViewItem * item);
+
+private:
+ const QString nsGet() const;
+ void normalConstruct(const KBookmark &);
+
+ KBookmark m_bookmark;
+ PaintStyle m_paintStyle;
+ bool m_emptyFolderPadder;
+ QString m_oldStatus;
+ void greyStyle(QColorGroup &);
+ void boldStyle(QPainter *);
+};
+
+class KEBListView : public KListView
+{
+ Q_OBJECT
+public:
+ enum {
+ NameColumn = 0,
+ UrlColumn = 1,
+ CommentColumn = 2,
+ StatusColumn = 3,
+ AddressColumn = 4
+ };
+ KEBListView(QWidget *parent, bool folderList)
+ : KListView(parent), m_folderList(folderList) {}
+ virtual ~KEBListView() {}
+
+ void init();
+ void makeConnections();
+ void readonlyFlagInit(bool);
+
+ void loadColumnSetting();
+ void saveColumnSetting();
+
+ void updateByURL(QString url);
+
+ bool isFolderList() const { return m_folderList; }
+
+ KEBListViewItem* rootItem() const;
+
+public slots:
+ virtual void rename(QListViewItem *item, int c);
+ void slotMoved();
+ void slotContextMenu(KListView *, QListViewItem *, const QPoint &);
+ void slotItemRenamed(QListViewItem *, const QString &, int);
+ void slotDoubleClicked(QListViewItem *, const QPoint &, int);
+ void slotDropped(QDropEvent*, QListViewItem*, QListViewItem*);
+ void slotColumnSizeChanged(int, int, int);
+
+protected:
+ virtual bool acceptDrag(QDropEvent *e) const;
+ virtual QDragObject* dragObject();
+
+private:
+ bool m_folderList;
+ bool m_widthsDirty;
+};
+
+// DESIGN - make some stuff private if possible
+class ListView : public QObject
+{
+ Q_OBJECT
+public:
+ // init stuff
+ void initListViews();
+ void updateListViewSetup(bool readOnly);
+ void connectSignals();
+ void setSearchLine(KListViewSearchLine * searchline) { m_searchline = searchline; };
+
+ // selected item stuff
+ void selected(KEBListViewItem * item, bool s);
+
+ void invalidate(const QString & address);
+ void invalidate(QListViewItem * item);
+ void fixUpCurrent(const QString & address);
+
+ KEBListViewItem * firstSelected() const;
+ QValueVector<KEBListViewItem *> selectedItemsMap() const;
+
+ QValueList<QString> selectedAddresses();
+
+ // bookmark helpers
+ QValueList<KBookmark> itemsToBookmarks(const QValueVector<KEBListViewItem *> & items) const;
+
+ // bookmark stuff
+ QValueList<KBookmark> allBookmarks() const;
+ QValueList<KBookmark> selectedBookmarksExpanded() const;
+
+ // address stuff
+ KEBListViewItem* getItemAtAddress(const QString &address) const;
+ QString userAddress() const;
+
+ // gui stuff - DESIGN - all of it???
+ SelcAbilities getSelectionAbilities() const;
+
+ void updateListView();
+ void setOpen(bool open); // DESIGN -rename to setAllOpenFlag
+ void setCurrent(KEBListViewItem *item, bool select);
+ void renameNextCell(bool dir);
+
+ QWidget *widget() const { return m_listView; }
+ void rename(int);
+ void clearSelection();
+
+ void updateStatus(QString url);
+
+ static ListView* self() { return s_self; }
+ static void createListViews(QSplitter *parent);
+
+ void handleMoved(KEBListView *);
+ void handleDropped(KEBListView *, QDropEvent *, QListViewItem *, QListViewItem *);
+ void handleContextMenu(KEBListView *, KListView *, QListViewItem *, const QPoint &);
+ void handleDoubleClicked(KEBListView *, QListViewItem *, const QPoint &, int);
+ void handleItemRenamed(KEBListView *, QListViewItem *, const QString &, int);
+
+ static void startRename(int column, KEBListViewItem *item);
+
+ static void deselectAllChildren(KEBListViewItem *item);
+
+ ~ListView();
+
+public slots:
+ void slotBkInfoUpdateListViewItem();
+
+private:
+ void updateTree();
+ void selectedBookmarksExpandedHelper(KEBListViewItem * item, QValueList<KBookmark> & bookmarks) const;
+ void fillWithGroup(KEBListView *, KBookmarkGroup, KEBListViewItem * = 0);
+
+ ListView();
+
+ KEBListView *m_listView;
+ KListViewSearchLine * m_searchline;
+
+// Actually this is a std:set, the bool is ignored
+ QMap<KEBListViewItem *, bool> mSelectedItems;
+ bool m_needToFixUp;
+
+ // statics
+ static ListView *s_self;
+ static int s_myrenamecolumn;
+ static KEBListViewItem *s_myrenameitem;
+ static QStringList s_selected_addresses;
+ static QString s_current_address;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/main.cpp b/konqueror/keditbookmarks/main.cpp
new file mode 100644
index 000000000..755a6f703
--- /dev/null
+++ b/konqueror/keditbookmarks/main.cpp
@@ -0,0 +1,199 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+
+#include "toplevel.h"
+#include "importers.h"
+
+#include <dcopclient.h>
+#include <dcopref.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kuniqueapplication.h>
+
+#include <kmessagebox.h>
+#include <kwin.h>
+
+#include <kbookmarkmanager.h>
+#include <kbookmarkexporter.h>
+
+static KCmdLineOptions options[] = {
+ {"importmoz <filename>", I18N_NOOP("Import bookmarks from a file in Mozilla format"), 0},
+ {"importns <filename>", I18N_NOOP("Import bookmarks from a file in Netscape (4.x and earlier) format"), 0},
+ {"importie <filename>", I18N_NOOP("Import bookmarks from a file in Internet Explorer's Favorites format"), 0},
+ {"importopera <filename>", I18N_NOOP("Import bookmarks from a file in Opera format"), 0},
+
+ {"exportmoz <filename>", I18N_NOOP("Export bookmarks to a file in Mozilla format"), 0},
+ {"exportns <filename>", I18N_NOOP("Export bookmarks to a file in Netscape (4.x and earlier) format"), 0},
+ {"exporthtml <filename>", I18N_NOOP("Export bookmarks to a file in a printable HTML format"), 0},
+ {"exportie <filename>", I18N_NOOP("Export bookmarks to a file in Internet Explorer's Favorites format"), 0},
+ {"exportopera <filename>", I18N_NOOP("Export bookmarks to a file in Opera format"), 0},
+
+ {"address <address>", I18N_NOOP("Open at the given position in the bookmarks file"), 0},
+ {"customcaption <caption>", I18N_NOOP("Set the user readable caption for example \"Konsole\""), 0},
+ {"nobrowser", I18N_NOOP("Hide all browser related functions"), 0},
+ {"+[file]", I18N_NOOP("File to edit"), 0},
+ KCmdLineLastOption
+};
+
+static void continueInWindow(QString _wname) {
+ QCString wname = _wname.latin1();
+ int id = -1;
+
+ QCStringList apps = kapp->dcopClient()->registeredApplications();
+ for (QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it) {
+ QCString &clientId = *it;
+
+ if (qstrncmp(clientId, wname, wname.length()) != 0)
+ continue;
+
+ DCOPRef client(clientId.data(), wname + "-mainwindow#1");
+ DCOPReply result = client.call("getWinID()");
+
+ if (result.isValid()) {
+ id = (int)result;
+ break;
+ }
+ }
+
+ KWin::activateWindow(id);
+}
+
+// TODO - make this register() or something like that and move dialog into main
+static int askUser(KApplication &app, QString filename, bool &readonly) {
+ QCString requestedName("keditbookmarks");
+
+ if (!filename.isEmpty())
+ requestedName += "-" + filename.utf8();
+
+ if (app.dcopClient()->registerAs(requestedName, false) == requestedName)
+ return true;
+
+ int ret = KMessageBox::warningYesNo(0,
+ i18n("Another instance of %1 is already running, do you really "
+ "want to open another instance or continue work in the same instance?\n"
+ "Please note that, unfortunately, duplicate views are read-only.").arg(kapp->caption()),
+ i18n("Warning"),
+ i18n("Run Another"), /* yes */
+ i18n("Continue in Same") /* no */);
+
+ if (ret == KMessageBox::No) {
+ continueInWindow(requestedName);
+ return false;
+ } else if (ret == KMessageBox::Yes) {
+ readonly = true;
+ }
+
+ return true;
+}
+
+#include <kactioncollection.h>
+
+extern "C" KDE_EXPORT int kdemain(int argc, char **argv) {
+ KLocale::setMainCatalogue("konqueror");
+ KAboutData aboutData("keditbookmarks", I18N_NOOP("Bookmark Editor"), VERSION,
+ I18N_NOOP("Konqueror Bookmarks Editor"),
+ KAboutData::License_GPL,
+ I18N_NOOP("(c) 2000 - 2003, KDE developers") );
+ aboutData.addAuthor("David Faure", I18N_NOOP("Initial author"), "faure@kde.org");
+ aboutData.addAuthor("Alexander Kellett", I18N_NOOP("Author"), "lypanov@kde.org");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KApplication::addCmdLineOptions();
+ KCmdLineArgs::addCmdLineOptions(options);
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ bool isGui = !(args->isSet("exportmoz") || args->isSet("exportns") || args->isSet("exporthtml")
+ || args->isSet("exportie") || args->isSet("exportopera")
+ || args->isSet("importmoz") || args->isSet("importns")
+ || args->isSet("importie") || args->isSet("importopera"));
+
+ bool browser = args->isSet("browser");
+
+ KApplication::disableAutoDcopRegistration();
+ KApplication app(isGui, isGui);
+
+ bool gotArg = (args->count() == 1);
+
+ QString filename = gotArg
+ ? QString::fromLatin1(args->arg(0))
+ : locateLocal("data", QString::fromLatin1("konqueror/bookmarks.xml"));
+
+ if (!isGui) {
+ CurrentMgr::self()->createManager(filename);
+ CurrentMgr::ExportType exportType = CurrentMgr::MozillaExport; // uumm.. can i just set it to -1 ?
+ int got = 0;
+ const char *arg, *arg2 = 0, *importType = 0;
+ if (arg = "exportmoz", args->isSet(arg)) { exportType = CurrentMgr::MozillaExport; arg2 = arg; got++; }
+ if (arg = "exportns", args->isSet(arg)) { exportType = CurrentMgr::NetscapeExport; arg2 = arg; got++; }
+ if (arg = "exporthtml", args->isSet(arg)) { exportType = CurrentMgr::HTMLExport; arg2 = arg; got++; }
+ if (arg = "exportie", args->isSet(arg)) { exportType = CurrentMgr::IEExport; arg2 = arg; got++; }
+ if (arg = "exportopera", args->isSet(arg)) { exportType = CurrentMgr::OperaExport; arg2 = arg; got++; }
+ if (arg = "importmoz", args->isSet(arg)) { importType = "Moz"; arg2 = arg; got++; }
+ if (arg = "importns", args->isSet(arg)) { importType = "NS"; arg2 = arg; got++; }
+ if (arg = "importie", args->isSet(arg)) { importType = "IE"; arg2 = arg; got++; }
+ if (arg = "importopera", args->isSet(arg)) { importType = "Opera"; arg2 = arg; got++; }
+ if (!importType && arg2) {
+ Q_ASSERT(arg2);
+ // TODO - maybe an xbel export???
+ if (got > 1) // got == 0 isn't possible as !isGui is dependant on "export.*"
+ KCmdLineArgs::usage(I18N_NOOP("You may only specify a single --export option."));
+ QString path = QString::fromLocal8Bit(args->getOption(arg2));
+ CurrentMgr::self()->doExport(exportType, path);
+ } else if (importType) {
+ if (got > 1) // got == 0 isn't possible as !isGui is dependant on "import.*"
+ KCmdLineArgs::usage(I18N_NOOP("You may only specify a single --import option."));
+ QString path = QString::fromLocal8Bit(args->getOption(arg2));
+ ImportCommand *importer = ImportCommand::importerFactory(importType);
+ importer->import(path, true);
+ importer->execute();
+ CurrentMgr::self()->managerSave();
+ CurrentMgr::self()->notifyManagers();
+ }
+ return 0; // error flag on exit?, 1?
+ }
+
+ QString address = args->isSet("address")
+ ? QString::fromLocal8Bit(args->getOption("address"))
+ : QString("/0");
+
+ QString caption = args->isSet("customcaption")
+ ? QString::fromLocal8Bit(args->getOption("customcaption"))
+ : QString::null;
+
+ args->clear();
+
+ bool readonly = false; // passed by ref
+
+ if (askUser(app, (gotArg ? filename : QString::null), readonly)) {
+ KEBApp *toplevel = new KEBApp(filename, readonly, address, browser, caption);
+ toplevel->show();
+ app.setMainWidget(toplevel);
+ return app.exec();
+ }
+
+ return 0;
+}
diff --git a/konqueror/keditbookmarks/settings.kcfgc b/konqueror/keditbookmarks/settings.kcfgc
new file mode 100644
index 000000000..663f5876f
--- /dev/null
+++ b/konqueror/keditbookmarks/settings.kcfgc
@@ -0,0 +1,4 @@
+File=keditbookmarks.kcfg
+ClassName=KEBSettings
+Singleton=true
+Mutators=true \ No newline at end of file
diff --git a/konqueror/keditbookmarks/testlink.cpp b/konqueror/keditbookmarks/testlink.cpp
new file mode 100644
index 000000000..84919ef27
--- /dev/null
+++ b/konqueror/keditbookmarks/testlink.cpp
@@ -0,0 +1,395 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "toplevel.h"
+#include "listview.h"
+#include "testlink.h"
+#include "commands.h"
+#include "bookmarkiterator.h"
+
+#include <qtimer.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+
+#include <krfcdate.h>
+#include <kcharsets.h>
+#include <kbookmarkmanager.h>
+
+#include <kaction.h>
+
+TestLinkItrHolder *TestLinkItrHolder::s_self = 0;
+
+TestLinkItrHolder::TestLinkItrHolder()
+ : BookmarkIteratorHolder() {
+ // do stuff
+}
+
+void TestLinkItrHolder::doItrListChanged() {
+ KEBApp::self()->setCancelTestsEnabled(count() > 0);
+ if(count() == 0)
+ {
+ kdDebug()<<"Notifing managers "<<m_affectedBookmark<<endl;
+ CurrentMgr::self()->notifyManagers(CurrentMgr::bookmarkAt(m_affectedBookmark).toGroup());
+ m_affectedBookmark = QString::null;
+ }
+}
+
+void TestLinkItrHolder::addAffectedBookmark( const QString & address )
+{
+ kdDebug()<<"addAffectedBookmark "<<address<<endl;
+ if(m_affectedBookmark.isNull())
+ m_affectedBookmark = address;
+ else
+ m_affectedBookmark = KBookmark::commonParent(m_affectedBookmark, address);
+ kdDebug()<<" m_affectedBookmark is now "<<m_affectedBookmark<<endl;
+}
+
+/* -------------------------- */
+
+TestLinkItr::TestLinkItr(QValueList<KBookmark> bks)
+ : BookmarkIterator(bks) {
+ m_job = 0;
+}
+
+TestLinkItr::~TestLinkItr() {
+ if (m_job) {
+ // kdDebug() << "JOB kill\n";
+ curItem()->restoreStatus();
+ m_job->disconnect();
+ m_job->kill(false);
+ }
+}
+
+bool TestLinkItr::isApplicable(const KBookmark &bk) const {
+ return (!bk.isGroup() && !bk.isSeparator());
+}
+
+void TestLinkItr::doAction() {
+ m_errSet = false;
+
+ m_job = KIO::get(curBk().url(), true, false);
+ m_job->addMetaData("errorPage", "true");
+ m_job->addMetaData( QString("cookies"), QString("none") );
+
+ connect(m_job, SIGNAL( result( KIO::Job *)),
+ this, SLOT( slotJobResult(KIO::Job *)));
+ connect(m_job, SIGNAL( data( KIO::Job *, const QByteArray &)),
+ this, SLOT( slotJobData(KIO::Job *, const QByteArray &)));
+
+ curItem()->setTmpStatus(i18n("Checking..."));
+ QString oldModDate = TestLinkItrHolder::self()->getMod(curBk().url().url());
+ curItem()->setOldStatus(oldModDate);
+ TestLinkItrHolder::self()->setMod(curBk().url().url(), i18n("Checking..."));
+}
+
+void TestLinkItr::slotJobData(KIO::Job *job, const QByteArray &data) {
+ KIO::TransferJob *transfer = (KIO::TransferJob *)job;
+
+ if (transfer->isErrorPage()) {
+ QStringList lines = QStringList::split('\n', data);
+ for (QStringList::Iterator it = lines.begin(); it != lines.end(); ++it) {
+ int open_pos = (*it).find("<title>", 0, false);
+ if (open_pos >= 0) {
+ QString leftover = (*it).mid(open_pos + 7);
+ int close_pos = leftover.findRev("</title>", -1, false);
+ if (close_pos >= 0) {
+ // if no end tag found then just
+ // print the first line of the <title>
+ leftover = leftover.left(close_pos);
+ }
+ curItem()->nsPut(KCharsets::resolveEntities(leftover));
+ m_errSet = true;
+ break;
+ }
+ }
+
+ } else {
+ QString modDate = transfer->queryMetaData("modified");
+ if (!modDate.isEmpty()) {
+ curItem()->nsPut(QString::number(KRFCDate::parseDate(modDate)));
+ }
+ }
+
+ transfer->kill(false);
+}
+
+void TestLinkItr::slotJobResult(KIO::Job *job) {
+ m_job = 0;
+ if ( !curItem() ) return;
+
+ KIO::TransferJob *transfer = (KIO::TransferJob *)job;
+ QString modDate = transfer->queryMetaData("modified");
+
+ bool chkErr = true;
+ if (transfer->error()) {
+ // can we assume that errorString will contain no entities?
+ QString jerr = job->errorString();
+ if (!jerr.isEmpty()) {
+ jerr.replace("\n", " ");
+ curItem()->nsPut(jerr);
+ chkErr = false;
+ }
+ }
+
+ if (chkErr) {
+ if (!modDate.isEmpty()) {
+ curItem()->nsPut(QString::number(KRFCDate::parseDate(modDate)));
+ } else if (!m_errSet) {
+ curItem()->nsPut(QString::number(KRFCDate::parseDate("0")));
+ }
+ }
+
+ curItem()->modUpdate();
+ holder()->addAffectedBookmark(KBookmark::parentAddress(curBk().address()));
+ delayedEmitNextOne();
+}
+
+/* -------------------------- */
+
+const QString TestLinkItrHolder::getMod(const QString &url) const {
+ return m_modify.contains(url)
+ ? m_modify[url]
+ : QString::null;
+}
+
+const QString TestLinkItrHolder::getOldVisit(const QString &url) const {
+ return self()->m_oldModify.contains(url)
+ ? self()->m_oldModify[url]
+ : QString::null;
+}
+
+void TestLinkItrHolder::setMod(const QString &url, const QString &val) {
+ m_modify[url] = val;
+}
+
+void TestLinkItrHolder::setOldVisit(const QString &url, const QString &val) {
+ m_oldModify[url] = val;
+}
+
+void TestLinkItrHolder::resetToValue(const QString &url, const QString &oldValue) {
+ if (!oldValue.isEmpty()) {
+ m_modify[url] = oldValue;
+ } else {
+ m_modify.remove(url);
+ }
+}
+
+/* -------------------------- */
+
+QString TestLinkItrHolder::calcPaintStyle(const QString &url, KEBListViewItem::PaintStyle &_style,
+ const QString &nVisit, const QString &Modify) {
+ bool newModValid = false;
+ int newMod = 0;
+ QString newModStr;
+ bool initial = false;
+ bool oldError = false;
+
+ if (!Modify.isNull() && Modify == "1") {
+ oldError = true;
+ }
+
+ // get new mod time if there is one
+ newModStr = self()->getMod(url);
+
+ // if no new mod time use previous one
+ if (newModStr.isNull()) {
+ newModStr = Modify;
+ initial = true;
+ }
+
+ if (!newModStr.isNull()) {
+ newMod = newModStr.toInt(&newModValid);
+ }
+
+
+// kdDebug() << "TestLink " << url << " " << "booktime=" << nVisit << " urltime=" << newModStr <<
+// " Modify=" << Modify << " init=" << initial << " newMod=" << newMod << "\n";
+
+ QString visitStr;
+
+ if (self()->getOldVisit(url).isNull()) {
+ // first time
+ visitStr = nVisit;
+ if (!nVisit.isEmpty())
+ self()->setOldVisit(url, visitStr);
+ } else {
+ // may be reading a second bookmark with same url
+ QString oom = nVisit;
+ visitStr = self()->getOldVisit(url);
+ if (oom.toInt() > visitStr.toInt()) {
+ self()->setOldVisit(url, oom);
+ visitStr = oom;
+ }
+ }
+
+ int visit = 0;
+ if (!visitStr.isNull())
+ visit = visitStr.toInt(); // TODO - check validity?
+
+ QString statusStr;
+ KEBListViewItem::PaintStyle style = KEBListViewItem::DefaultStyle;
+
+// kdDebug() << "TestLink " << "isNull=" << newModStr.isNull() << "newModValid="
+// << newModValid << "newMod > visit " << newMod << ">" << visit << "\n";
+
+ if (!newModStr.isNull() && !newModValid) {
+ // Current check has error
+ statusStr = newModStr;
+ if (oldError) {
+ style = KEBListViewItem::BoldStyle;
+ } else {
+ style = KEBListViewItem::DefaultStyle;
+ }
+
+ } else if (initial && oldError) {
+ // Previous check has error
+ style = KEBListViewItem::GreyStyle;
+ statusStr = i18n("Error ");
+
+ } else if (!initial && !newModStr.isNull() && (newMod == 0)) {
+ // Current check has no modify time
+ statusStr = i18n("Ok");
+
+ } else if (initial && !newModStr.isNull() && (newMod == 0)) {
+ // previous check has no modify time recorded
+ statusStr = QString::null;
+
+ } else if (!newModStr.isNull() && (newMod > visit)) {
+ // if modify time greater than last visit, show bold modify time
+ statusStr = CurrentMgr::makeTimeStr(newMod);
+ if (initial) {
+ style = KEBListViewItem::GreyBoldStyle;
+ } else {
+ style = KEBListViewItem::BoldStyle;
+ }
+
+ } else if (visit != 0) {
+ // modify time not greater than last visit, show last visit time
+ statusStr = CurrentMgr::makeTimeStr(visit);
+ if (initial) {
+ style = KEBListViewItem::GreyStyle;
+ } else {
+ style = KEBListViewItem::DefaultStyle;
+ }
+
+ } else {
+ statusStr = QString::null;
+ }
+
+ _style = style;
+ return statusStr;
+}
+
+static void parseInfo (KBookmark &bk, QString &nVisited) {
+ nVisited =
+ NodeEditCommand::getNodeText(bk, QStringList() << "info" << "metadata"
+ << "time_visited" );
+
+// kdDebug() << " Visited=" << nVisited << "\n";
+}
+
+static void parseNsInfo(const QString &nsinfo, QString &nCreate, QString &nAccess, QString &nModify) {
+ QStringList sl = QStringList::split(' ', nsinfo);
+
+ for (QStringList::Iterator it = sl.begin(); it != sl.end(); ++it) {
+ QStringList spl = QStringList::split('"', (*it));
+
+ if (spl[0] == "LAST_MODIFIED=") {
+ nModify = spl[1];
+ } else if (spl[0] == "ADD_DATE=") {
+ nCreate = spl[1];
+ } else if (spl[0] == "LAST_VISIT=") {
+ nAccess = spl[1];
+ }
+ }
+}
+
+// Still use nsinfo for storing old modify time
+static const QString updateNsInfoMod(const QString &_nsinfo, const QString &nm) {
+ QString nCreate, nAccess, nModify;
+ parseNsInfo(_nsinfo, nCreate, nAccess, nModify);
+
+ bool numValid = false;
+ nm.toInt(&numValid);
+
+ QString tmp;
+ tmp = "ADD_DATE=\"" + ((nCreate.isEmpty()) ? QString::number(time(0)) : nCreate) + "\"";
+ tmp += " LAST_VISIT=\"" + ((nAccess.isEmpty()) ? QString("0") : nAccess) + "\"";
+ tmp += " LAST_MODIFIED=\"" + ((numValid) ? nm : QString("1")) + "\"";
+
+// if (!numValid) kdDebug() << tmp << "\n";
+ return tmp;
+}
+
+// KEBListViewItem !!!!!!!!!!!
+void KEBListViewItem::nsPut(const QString &newModDate) {
+ static const QString NetscapeInfoAttribute = "netscapeinfo";
+ const QString info = m_bookmark.internalElement().attribute(NetscapeInfoAttribute);
+ QString blah = updateNsInfoMod(info, newModDate);
+ m_bookmark.internalElement().setAttribute(NetscapeInfoAttribute, blah);
+ TestLinkItrHolder::self()->setMod(m_bookmark.url().url(), newModDate);
+ setText(KEBListView::StatusColumn, newModDate);
+}
+
+// KEBListViewItem !!!!!!!!!!!
+void KEBListViewItem::modUpdate() {
+ QString nCreate, nAccess, oldModify;
+ QString iVisit;
+
+ QString nsinfo = m_bookmark.internalElement().attribute("netscapeinfo");
+ if (!nsinfo.isEmpty()) {
+ parseNsInfo(nsinfo, nCreate, nAccess, oldModify);
+ }
+
+ parseInfo(m_bookmark, iVisit);
+
+ QString statusLine;
+ statusLine = TestLinkItrHolder::calcPaintStyle(m_bookmark.url().url(), m_paintStyle, iVisit, oldModify);
+ if (statusLine != "Error")
+ setText(KEBListView::StatusColumn, statusLine);
+}
+
+/* -------------------------- */
+
+// KEBListViewItem !!!!!!!!!!!
+void KEBListViewItem::setOldStatus(const QString &oldStatus) {
+ // kdDebug() << "KEBListViewItem::setOldStatus" << endl;
+ m_oldStatus = oldStatus;
+}
+
+// KEBListViewItem !!!!!!!!!!!
+void KEBListViewItem::setTmpStatus(const QString &status) {
+ // kdDebug() << "KEBListViewItem::setTmpStatus" << endl;
+ m_paintStyle = KEBListViewItem::BoldStyle;
+ setText(KEBListView::StatusColumn, status);
+}
+
+// KEBListViewItem !!!!!!!!!!!
+void KEBListViewItem::restoreStatus() {
+ if (!m_oldStatus.isNull()) {
+ // kdDebug() << "KEBListViewItem::restoreStatus" << endl;
+ TestLinkItrHolder::self()->resetToValue(m_bookmark.url().url(), m_oldStatus);
+ modUpdate();
+ }
+}
+
+#include "testlink.moc"
diff --git a/konqueror/keditbookmarks/testlink.h b/konqueror/keditbookmarks/testlink.h
new file mode 100644
index 000000000..7b027edea
--- /dev/null
+++ b/konqueror/keditbookmarks/testlink.h
@@ -0,0 +1,75 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __testlink_h
+#define __testlink_h
+
+#include <qobject.h>
+
+#include <kio/job.h>
+#include <kbookmark.h>
+
+#include "listview.h"
+#include "bookmarkiterator.h"
+
+class TestLinkItrHolder : public BookmarkIteratorHolder {
+public:
+ static TestLinkItrHolder* self() {
+ if (!s_self) { s_self = new TestLinkItrHolder(); }; return s_self;
+ }
+ void addAffectedBookmark( const QString & address );
+ void resetToValue(const QString &url, const QString &val);
+ const QString getMod(const QString &url) const;
+ const QString getOldVisit(const QString &url) const;
+ void setMod(const QString &url, const QString &val);
+ void setOldVisit(const QString &url, const QString &val);
+ static QString calcPaintStyle(const QString &, KEBListViewItem::PaintStyle&,
+ const QString &, const QString &);
+protected:
+ virtual void doItrListChanged();
+private:
+ TestLinkItrHolder();
+ static TestLinkItrHolder *s_self;
+ QMap<QString, QString> m_modify;
+ QMap<QString, QString> m_oldModify;
+ QString m_affectedBookmark;
+};
+
+class TestLinkItr : public BookmarkIterator
+{
+ Q_OBJECT
+
+public:
+ TestLinkItr(QValueList<KBookmark> bks);
+ ~TestLinkItr();
+ virtual TestLinkItrHolder* holder() const { return TestLinkItrHolder::self(); }
+
+public slots:
+ void slotJobResult(KIO::Job *job);
+ void slotJobData(KIO::Job *job, const QByteArray &data);
+
+private:
+ virtual void doAction();
+ virtual bool isApplicable(const KBookmark &bk) const;
+
+ KIO::TransferJob *m_job;
+ bool m_errSet;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/toplevel.cpp b/konqueror/keditbookmarks/toplevel.cpp
new file mode 100644
index 000000000..3f49d893a
--- /dev/null
+++ b/konqueror/keditbookmarks/toplevel.cpp
@@ -0,0 +1,356 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "toplevel.h"
+
+#include "bookmarkinfo.h"
+#include "listview.h"
+#include "actionsimpl.h"
+#include "dcop.h"
+#include "exporters.h"
+#include "settings.h"
+#include "commands.h"
+#include "kebsearchline.h"
+
+#include <stdlib.h>
+
+#include <qclipboard.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <kedittoolbar.h>
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <kfiledialog.h>
+
+#include <kdebug.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+
+CmdHistory* CmdHistory::s_self = 0;
+
+CmdHistory::CmdHistory(KActionCollection *collection)
+ : m_commandHistory(collection) {
+ connect(&m_commandHistory, SIGNAL( commandExecuted(KCommand *) ),
+ SLOT( slotCommandExecuted(KCommand *) ));
+ assert(!s_self);
+ s_self = this; // this is hacky
+}
+
+CmdHistory* CmdHistory::self() {
+ assert(s_self);
+ return s_self;
+}
+
+void CmdHistory::slotCommandExecuted(KCommand *k) {
+ KEBApp::self()->notifyCommandExecuted();
+
+ IKEBCommand * cmd = dynamic_cast<IKEBCommand *>(k);
+ Q_ASSERT(cmd);
+
+ KBookmark bk = CurrentMgr::bookmarkAt(cmd->affectedBookmarks());
+ Q_ASSERT(bk.isGroup());
+ CurrentMgr::self()->notifyManagers(bk.toGroup());
+
+ // sets currentItem to something sensible
+ // if the currentItem was invalidated by executing
+ // CreateCommand or DeleteManyCommand
+ // otherwise does nothing
+ // sensible is either a already selected item or cmd->currentAddress()
+ ListView::self()->fixUpCurrent( cmd->currentAddress() );
+}
+
+void CmdHistory::notifyDocSaved() {
+ m_commandHistory.documentSaved();
+}
+
+void CmdHistory::didCommand(KCommand *cmd) {
+ if (!cmd)
+ return;
+ m_commandHistory.addCommand(cmd, false);
+ CmdHistory::slotCommandExecuted(cmd);
+}
+
+void CmdHistory::addCommand(KCommand *cmd) {
+ if (!cmd)
+ return;
+ m_commandHistory.addCommand(cmd);
+}
+
+void CmdHistory::addInFlightCommand(KCommand *cmd)
+{
+ if(!cmd)
+ return;
+ m_commandHistory.addCommand(cmd, false);
+}
+
+void CmdHistory::clearHistory() {
+ m_commandHistory.clear();
+}
+
+/* -------------------------- */
+
+CurrentMgr *CurrentMgr::s_mgr = 0;
+
+KBookmark CurrentMgr::bookmarkAt(const QString &a) {
+ return self()->mgr()->findByAddress(a);
+}
+
+bool CurrentMgr::managerSave() { return mgr()->save(); }
+void CurrentMgr::saveAs(const QString &fileName) { mgr()->saveAs(fileName); }
+void CurrentMgr::setUpdate(bool update) { mgr()->setUpdate(update); }
+QString CurrentMgr::path() const { return mgr()->path(); }
+bool CurrentMgr::showNSBookmarks() const { return mgr()->showNSBookmarks(); }
+
+void CurrentMgr::createManager(const QString &filename) {
+ if (m_mgr) {
+ kdDebug()<<"ERROR calling createManager twice"<<endl;
+ disconnect(m_mgr, 0, 0, 0);
+ // still todo - delete old m_mgr
+ }
+
+ m_mgr = KBookmarkManager::managerForFile(filename, false);
+
+ connect(m_mgr, SIGNAL( changed(const QString &, const QString &) ),
+ SLOT( slotBookmarksChanged(const QString &, const QString &) ));
+}
+
+void CurrentMgr::slotBookmarksChanged(const QString &, const QString &) {
+ if(ignorenext > 0) //We ignore the first changed signal after every change we did
+ {
+ --ignorenext;
+ return;
+ }
+
+ CmdHistory::self()->clearHistory();
+ ListView::self()->updateListView();
+ KEBApp::self()->updateActions();
+}
+
+void CurrentMgr::notifyManagers(KBookmarkGroup grp)
+{
+ ++ignorenext;
+ mgr()->emitChanged(grp);
+}
+
+void CurrentMgr::notifyManagers() {
+ notifyManagers( mgr()->root() );
+}
+
+void CurrentMgr::reloadConfig() {
+ mgr()->emitConfigChanged();
+}
+
+QString CurrentMgr::makeTimeStr(const QString & in)
+{
+ int secs;
+ bool ok;
+ secs = in.toInt(&ok);
+ if (!ok)
+ return QString::null;
+ return makeTimeStr(secs);
+}
+
+QString CurrentMgr::makeTimeStr(int b)
+{
+ QDateTime dt;
+ dt.setTime_t(b);
+ return (dt.daysTo(QDateTime::currentDateTime()) > 31)
+ ? KGlobal::locale()->formatDate(dt.date(), false)
+ : KGlobal::locale()->formatDateTime(dt, false);
+}
+
+/* -------------------------- */
+
+KEBApp *KEBApp::s_topLevel = 0;
+
+KEBApp::KEBApp(
+ const QString &bookmarksFile, bool readonly,
+ const QString &address, bool browser, const QString &caption
+) : KMainWindow(), m_dcopIface(0), m_bookmarksFilename(bookmarksFile),
+ m_caption(caption), m_readOnly(readonly), m_browser(browser) {
+
+ m_cmdHistory = new CmdHistory(actionCollection());
+
+ s_topLevel = this;
+
+ int h = 20;
+
+ QSplitter *vsplitter = new QSplitter(this);
+
+ KToolBar *quicksearch = new KToolBar(vsplitter, "search toolbar");
+
+ KAction *resetQuickSearch = new KAction( i18n( "Reset Quick Search" ),
+ QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
+ 0, actionCollection(), "reset_quicksearch" );
+ resetQuickSearch->setWhatsThis( i18n( "<b>Reset Quick Search</b><br>"
+ "Resets the quick search so that all bookmarks are shown again." ) );
+ resetQuickSearch->plug( quicksearch );
+
+ QLabel *lbl = new QLabel(i18n("Se&arch:"), quicksearch, "kde toolbar widget");
+
+ KListViewSearchLine *searchLineEdit = new KEBSearchLine(quicksearch, 0, "KListViewSearchLine");
+ quicksearch->setStretchableWidget(searchLineEdit);
+ lbl->setBuddy(searchLineEdit);
+ connect(resetQuickSearch, SIGNAL(activated()), searchLineEdit, SLOT(clear()));
+ connect(searchLineEdit, SIGNAL(searchUpdated()), SLOT(updateActions()));
+
+ ListView::createListViews(vsplitter);
+ ListView::self()->initListViews();
+ searchLineEdit->setListView(static_cast<KListView*>(ListView::self()->widget()));
+ ListView::self()->setSearchLine(searchLineEdit);
+
+ m_bkinfo = new BookmarkInfoWidget(vsplitter);
+
+ vsplitter->setOrientation(QSplitter::Vertical);
+ vsplitter->setSizes(QValueList<int>() << h << 380
+ << m_bkinfo->sizeHint().height() );
+
+ setCentralWidget(vsplitter);
+ resize(ListView::self()->widget()->sizeHint().width(),
+ vsplitter->sizeHint().height());
+
+ createActions();
+ if (m_browser)
+ createGUI();
+ else
+ createGUI("keditbookmarks-genui.rc");
+
+ m_dcopIface = new KBookmarkEditorIface();
+
+ connect(kapp->clipboard(), SIGNAL( dataChanged() ),
+ SLOT( slotClipboardDataChanged() ));
+
+ ListView::self()->connectSignals();
+
+ KGlobal::locale()->insertCatalogue("libkonq");
+
+ m_canPaste = false;
+
+ construct();
+
+ ListView::self()->setCurrent(ListView::self()->getItemAtAddress(address), true);
+
+ setCancelFavIconUpdatesEnabled(false);
+ setCancelTestsEnabled(false);
+ updateActions();
+}
+
+void KEBApp::construct() {
+ CurrentMgr::self()->createManager(m_bookmarksFilename);
+
+ ListView::self()->updateListViewSetup(m_readOnly);
+ ListView::self()->updateListView();
+ ListView::self()->widget()->setFocus();
+
+ slotClipboardDataChanged();
+ setAutoSaveSettings();
+}
+
+void KEBApp::updateStatus(QString url)
+{
+ if(m_bkinfo->bookmark().url() == url)
+ m_bkinfo->updateStatus();
+}
+
+KEBApp::~KEBApp() {
+ s_topLevel = 0;
+ delete m_cmdHistory;
+ delete m_dcopIface;
+ delete ActionsImpl::self();
+ delete ListView::self();
+}
+
+KToggleAction* KEBApp::getToggleAction(const char *action) const {
+ return static_cast<KToggleAction*>(actionCollection()->action(action));
+}
+
+void KEBApp::resetActions() {
+ stateChanged("disablestuff");
+ stateChanged("normal");
+
+ if (!m_readOnly)
+ stateChanged("notreadonly");
+
+ getToggleAction("settings_showNS")
+ ->setChecked(CurrentMgr::self()->showNSBookmarks());
+}
+
+bool KEBApp::nsShown() const {
+ return getToggleAction("settings_showNS")->isChecked();
+}
+
+// this should be pushed from listview, not pulled
+void KEBApp::updateActions() {
+ resetActions();
+ setActionsEnabled(ListView::self()->getSelectionAbilities());
+}
+
+void KEBApp::slotClipboardDataChanged() {
+ // kdDebug() << "KEBApp::slotClipboardDataChanged" << endl;
+ if (!m_readOnly) {
+ m_canPaste = KBookmarkDrag::canDecode(
+ kapp->clipboard()->data(QClipboard::Clipboard));
+ updateActions();
+ }
+}
+
+/* -------------------------- */
+
+void KEBApp::notifyCommandExecuted() {
+ // kdDebug() << "KEBApp::notifyCommandExecuted()" << endl;
+ if (!m_readOnly) {
+ ListView::self()->updateListView();
+ updateActions();
+ }
+}
+
+/* -------------------------- */
+
+void KEBApp::slotConfigureToolbars() {
+ saveMainWindowSettings(KGlobal::config(), "MainWindow");
+ KEditToolbar dlg(actionCollection());
+ connect(&dlg, SIGNAL( newToolbarConfig() ),
+ SLOT( slotNewToolbarConfig() ));
+ dlg.exec();
+}
+
+void KEBApp::slotNewToolbarConfig() {
+ // called when OK or Apply is clicked
+ createGUI();
+ applyMainWindowSettings(KGlobal::config(), "MainWindow");
+}
+
+/* -------------------------- */
+
+#include "toplevel.moc"
+
diff --git a/konqueror/keditbookmarks/toplevel.h b/konqueror/keditbookmarks/toplevel.h
new file mode 100644
index 000000000..192f56028
--- /dev/null
+++ b/konqueror/keditbookmarks/toplevel.h
@@ -0,0 +1,175 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __toplevel_h
+#define __toplevel_h
+
+#include <kmainwindow.h>
+#include <kcommand.h>
+#include <kbookmark.h>
+
+class KBookmarkManager;
+class KToggleAction;
+class KBookmarkEditorIface;
+class ImportCommand;
+class BookmarkInfoWidget;
+class IKEBCommand;
+
+struct SelcAbilities {
+ bool itemSelected:1;
+ bool group:1;
+ bool root:1;
+ bool separator:1;
+ bool urlIsEmpty:1;
+ bool multiSelect:1;
+ bool singleSelect:1;
+ bool notEmpty:1;
+ bool tbShowState:1;
+};
+
+class CmdHistory : public QObject {
+ Q_OBJECT
+public:
+ CmdHistory(KActionCollection *collection);
+ virtual ~CmdHistory() { ; }
+
+ void notifyDocSaved();
+
+ void clearHistory();
+ void addCommand(KCommand *);
+ void didCommand(KCommand *);
+
+ //For an explanation see bookmarkInfo::commitChanges()
+ void addInFlightCommand(KCommand *);
+
+ static CmdHistory *self();
+
+protected slots:
+ void slotCommandExecuted(KCommand *k);
+
+private:
+ KCommandHistory m_commandHistory;
+ static CmdHistory *s_self;
+};
+
+class KBookmark;
+class KBookmarkManager;
+
+class CurrentMgr : public QObject {
+ Q_OBJECT
+public:
+ typedef enum {HTMLExport, OperaExport, IEExport, MozillaExport, NetscapeExport} ExportType;
+
+ static CurrentMgr* self() { if (!s_mgr) { s_mgr = new CurrentMgr(); } return s_mgr; }
+ static KBookmark bookmarkAt(const QString & a);
+
+ KBookmarkManager* mgr() const { return m_mgr; }
+ bool showNSBookmarks() const;
+ QString path() const;
+
+ void createManager(const QString &filename);
+ void notifyManagers(KBookmarkGroup grp);
+ void notifyManagers();
+ bool managerSave();
+ void saveAs(const QString &fileName);
+ void doExport(ExportType type, const QString & path = QString::null);
+ void setUpdate(bool update);
+
+ void reloadConfig();
+
+ static QString makeTimeStr(const QString &);
+ static QString makeTimeStr(int);
+
+protected slots:
+ void slotBookmarksChanged(const QString &, const QString &);
+
+private:
+ CurrentMgr() : m_mgr(0), ignorenext(0) { ; }
+ KBookmarkManager *m_mgr;
+ static CurrentMgr *s_mgr;
+ uint ignorenext;
+};
+
+class KEBApp : public KMainWindow {
+ Q_OBJECT
+public:
+ static KEBApp* self() { return s_topLevel; }
+
+ KEBApp(const QString & bookmarksFile, bool readonly, const QString &address, bool browser, const QString &caption);
+ virtual ~KEBApp();
+
+ void updateStatus(QString url);
+ void setActionsEnabled(SelcAbilities);
+
+ void setCancelFavIconUpdatesEnabled(bool);
+ void setCancelTestsEnabled(bool);
+
+ void notifyCommandExecuted();
+ void findURL(QString url);
+
+ QWidget* popupMenuFactory(const char *type) {
+ return factory()->container(type, this);
+ }
+
+ KToggleAction* getToggleAction(const char *) const;
+
+ QString caption() const { return m_caption; }
+ bool readonly() const { return m_readOnly; }
+ bool browser() const { return m_browser; }
+ bool nsShown() const;
+
+ BookmarkInfoWidget *bkInfo() { return m_bkinfo; }
+
+public slots:
+ void updateActions();
+ void slotConfigureToolbars();
+
+protected slots:
+ void slotClipboardDataChanged();
+ void slotNewToolbarConfig();
+
+private:
+ static KBookmarkManager* bookmarkManager();
+
+ void resetActions();
+ void createActions();
+
+ void updateListView();
+
+ static KEBApp *s_topLevel;
+ KBookmarkEditorIface *m_dcopIface;
+
+public: // only temporary
+ CmdHistory *m_cmdHistory;
+ QString m_bookmarksFilename;
+ QString m_caption;
+
+ void construct();
+
+private:
+ BookmarkInfoWidget *m_bkinfo;
+
+ bool m_canPaste:1;
+ bool m_readOnly:1;
+ bool m_browser:1;
+};
+
+#endif
diff --git a/konqueror/keditbookmarks/uninstall.desktop b/konqueror/keditbookmarks/uninstall.desktop
new file mode 100644
index 000000000..e1e3e1732
--- /dev/null
+++ b/konqueror/keditbookmarks/uninstall.desktop
@@ -0,0 +1,2 @@
+[Desktop Entry]
+Hidden=true
diff --git a/konqueror/keditbookmarks/updater.cpp b/konqueror/keditbookmarks/updater.cpp
new file mode 100644
index 000000000..34c884617
--- /dev/null
+++ b/konqueror/keditbookmarks/updater.cpp
@@ -0,0 +1,180 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtimer.h>
+
+#include "updater.h"
+
+#include "bookmarkiterator.h"
+#include "listview.h"
+#include "toplevel.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+#include <kio/job.h>
+
+#include <kparts/part.h>
+#include <kparts/componentfactory.h>
+#include <kparts/browserextension.h>
+
+FavIconUpdater::FavIconUpdater(QObject *parent, const char *name)
+ : KonqFavIconMgr(parent, name) {
+ m_part = 0;
+ m_webGrabber = 0;
+ m_browserIface = 0;
+ m_timer = 0;
+}
+
+void FavIconUpdater::slotCompleted() {
+ // kdDebug() << "FavIconUpdater::slotCompleted" << endl;
+ // kdDebug() << "emit done(true)" << endl;
+ m_timer->stop();
+ emit done(true);
+}
+
+void FavIconUpdater::timerDone() {
+ // Timeout: set completed
+ kdDebug() << "FavIconUpdater: Timeout" << endl;
+ slotCompleted();
+}
+
+void FavIconUpdater::downloadIcon(const KBookmark &bk) {
+ QString favicon = KonqFavIconMgr::iconForURL(bk.url().url());
+ if (!favicon.isNull()) {
+ // kdDebug() << "downloadIcon() - favicon" << favicon << endl;
+ bk.internalElement().setAttribute("icon", favicon);
+ KEBApp::self()->notifyCommandExecuted();
+ // kdDebug() << "emit done(true)" << endl;
+ emit done(true);
+
+ } else {
+ KonqFavIconMgr::downloadHostIcon(bk.url());
+ favicon = KonqFavIconMgr::iconForURL(bk.url().url());
+ // kdDebug() << "favicon == " << favicon << endl;
+ if (favicon.isNull()) {
+ downloadIconActual(bk);
+ }
+ }
+}
+
+FavIconUpdater::~FavIconUpdater() {
+ // kdDebug() << "~FavIconUpdater" << endl;
+ delete m_browserIface;
+ delete m_webGrabber;
+ delete m_part;
+ delete m_timer;
+}
+
+void FavIconUpdater::downloadIconActual(const KBookmark &bk) {
+ m_bk = bk;
+
+ if (!m_part) {
+ KParts::ReadOnlyPart *part
+ = KParts::ComponentFactory
+ ::createPartInstanceFromQuery<KParts::ReadOnlyPart>("text/html", QString::null);
+
+ part->setProperty("pluginsEnabled", QVariant(false, 1));
+ part->setProperty("javaScriptEnabled", QVariant(false, 1));
+ part->setProperty("javaEnabled", QVariant(false, 1));
+ part->setProperty("autoloadImages", QVariant(false, 1));
+
+ connect(part, SIGNAL( canceled(const QString &) ),
+ this, SLOT( slotCompleted() ));
+ connect(part, SIGNAL( completed() ),
+ this, SLOT( slotCompleted() ));
+
+ KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(part);
+ assert(ext);
+
+ m_browserIface = new FavIconBrowserInterface(this, "browseriface");
+ ext->setBrowserInterface(m_browserIface);
+
+ connect(ext, SIGNAL( setIconURL(const KURL &) ),
+ this, SLOT( setIconURL(const KURL &) ));
+
+ m_part = part;
+ }
+
+ if (!m_timer) {
+ // Timeout to stop the updating hanging
+ m_timer = new QTimer(this);
+ connect( m_timer, SIGNAL(timeout()), this, SLOT(timerDone()) );
+ }
+ m_timer->start(15000,false);
+ m_webGrabber = new FavIconWebGrabber(m_part, bk.url());
+}
+
+// khtml callback
+void FavIconUpdater::setIconURL(const KURL &iconURL) {
+ setIconForURL(m_bk.url(), iconURL);
+}
+
+void FavIconUpdater::notifyChange(bool isHost, QString hostOrURL, QString iconName) {
+ // kdDebug() << "FavIconUpdater::notifyChange()" << endl;
+
+ Q_UNUSED(isHost);
+ // kdDebug() << isHost << endl;
+ Q_UNUSED(hostOrURL);
+ // kdDebug() << "FavIconUpdater::notifyChange" << hostOrURL << "==" << m_bk.url().url() << "-> " << iconName << endl;
+
+ m_bk.internalElement().setAttribute("icon", iconName);
+ KEBApp::self()->notifyCommandExecuted();
+}
+
+/* -------------------------- */
+
+FavIconWebGrabber::FavIconWebGrabber(KParts::ReadOnlyPart *part, const KURL &url)
+ : m_part(part), m_url(url) {
+
+ // kdDebug() << "FavIconWebGrabber::FavIconWebGrabber starting KIO::get() " << url << endl;
+
+// the use of KIO rather than directly using KHTML is to allow silently abort on error
+
+ KIO::Job *job = KIO::get(m_url, false, false);
+ job->addMetaData( QString("cookies"), QString("none") );
+ connect(job, SIGNAL( result( KIO::Job *)),
+ this, SLOT( slotFinished(KIO::Job *) ));
+ connect(job, SIGNAL( mimetype( KIO::Job *, const QString &) ),
+ this, SLOT( slotMimetype(KIO::Job *, const QString &) ));
+}
+
+void FavIconWebGrabber::slotMimetype(KIO::Job *job, const QString & /*type*/) {
+ KIO::SimpleJob *sjob = static_cast<KIO::SimpleJob *>(job);
+ m_url = sjob->url(); // allow for redirection
+ sjob->putOnHold();
+
+ // kdDebug() << "FavIconWebGrabber::slotMimetype " << m_url << "\n";
+
+ // QString typeLocal = typeUncopied; // local copy
+ // kdDebug() << "slotMimetype : " << typeLocal << endl;
+ // TODO - what to do if typeLocal is not text/html ??
+
+ m_part->openURL(m_url);
+}
+
+void FavIconWebGrabber::slotFinished(KIO::Job *job) {
+ if (job->error()) {
+ // kdDebug() << "FavIconWebGrabber::slotFinished() " << job->errorString() << endl;
+ }
+}
+
+#include "updater.moc"
diff --git a/konqueror/keditbookmarks/updater.h b/konqueror/keditbookmarks/updater.h
new file mode 100644
index 000000000..ff92ea55c
--- /dev/null
+++ b/konqueror/keditbookmarks/updater.h
@@ -0,0 +1,91 @@
+// -*- mode:cperl; cperl-indent-level:4; cperl-continued-statement-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __updater_h
+#define __updater_h
+
+#include <kbookmark.h>
+#include <konq_faviconmgr.h>
+
+#include <kparts/part.h>
+#include <kparts/browserinterface.h>
+
+class FavIconWebGrabber : public QObject
+{
+ Q_OBJECT
+public:
+ FavIconWebGrabber(KParts::ReadOnlyPart *part, const KURL &url);
+ ~FavIconWebGrabber() {}
+
+protected slots:
+ void slotMimetype(KIO::Job *job, const QString &_type);
+ void slotFinished(KIO::Job *job);
+
+private:
+ KParts::ReadOnlyPart *m_part;
+ KURL m_url;
+};
+
+class FavIconBrowserInterface;
+
+class FavIconUpdater : public KonqFavIconMgr
+{
+ Q_OBJECT
+
+public:
+ FavIconUpdater(QObject *parent, const char *name);
+ ~FavIconUpdater();
+ void downloadIcon(const KBookmark &bk);
+ void downloadIconActual(const KBookmark &bk);
+
+ virtual void notifyChange(bool isHost, QString hostOrURL,
+ QString iconName);
+
+protected slots:
+ void setIconURL(const KURL &iconURL);
+ void slotCompleted();
+ void timerDone();
+
+
+signals:
+ void done(bool succeeded);
+
+private:
+ KParts::ReadOnlyPart *m_part;
+ FavIconBrowserInterface *m_browserIface;
+ FavIconWebGrabber *m_webGrabber;
+ QTimer *m_timer;
+ KBookmark m_bk;
+};
+
+class FavIconBrowserInterface : public KParts::BrowserInterface
+{
+ Q_OBJECT
+public:
+ FavIconBrowserInterface(FavIconUpdater *view, const char *name)
+ : KParts::BrowserInterface(view, name), m_view(view) {
+ ;
+ }
+private:
+ FavIconUpdater *m_view;
+};
+
+#endif
+
diff --git a/konqueror/kfmclient.desktop b/konqueror/kfmclient.desktop
new file mode 100644
index 000000000..2d64d47b8
--- /dev/null
+++ b/konqueror/kfmclient.desktop
@@ -0,0 +1,22 @@
+[Desktop Entry]
+# This desktop file is the one used by KApplication::invokeBrowser
+Type=Application
+Exec=kfmclient openURL %u
+Icon=konqueror
+Terminal=false
+InitialPreference=9
+NoDisplay=true
+Name=Konqueror
+Name[bn]=কনকরার
+Name[eo]=Konkeranto
+Name[hi]=कॉन्करर
+Name[lv]=Iekarotājs
+Name[mn]=Конкюрор
+Name[ne]=कन्क्वेरर
+Name[pa]=ਕੋਨਕਿਉਰੋਰ
+Name[ta]=கான்கொரர்
+Name[te]=కాంకెరర్
+Name[th]=คอนเควอร์เรอร์
+X-DCOP-ServiceType=None
+Categories=Qt;KDE;System;
+X-KDE-HasTempFileOption=true
diff --git a/konqueror/kfmclient_dir.desktop b/konqueror/kfmclient_dir.desktop
new file mode 100644
index 000000000..d35cc860e
--- /dev/null
+++ b/konqueror/kfmclient_dir.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Type=Application
+Exec=kfmclient openURL %u inode/directory
+Icon=konqueror
+Terminal=false
+MimeType=inode/directory;
+InitialPreference=9
+NoDisplay=true
+Name=Konqueror
+Name[bn]=কনকরার
+Name[eo]=Konkeranto
+Name[hi]=कॉन्करर
+Name[lv]=Iekarotājs
+Name[mn]=Конкюрор
+Name[ne]=कन्क्वेरर
+Name[pa]=ਕੋਨਕਿਉਰੋਰ
+Name[ta]=கான்கொரர்
+Name[te]=కాంకెరర్
+Name[th]=คอนเควอร์เรอร์
+Categories=Qt;KDE;System;
diff --git a/konqueror/kfmclient_html.desktop b/konqueror/kfmclient_html.desktop
new file mode 100644
index 000000000..e522a5246
--- /dev/null
+++ b/konqueror/kfmclient_html.desktop
@@ -0,0 +1,21 @@
+[Desktop Entry]
+Type=Application
+Exec=kfmclient openURL %u text/html
+Icon=konqueror
+Terminal=false
+MimeType=text/html;application/xhtml+xml;text/xml;
+InitialPreference=9
+NoDisplay=true
+Name=Konqueror
+Name[bn]=কনকরার
+Name[eo]=Konkeranto
+Name[hi]=कॉन्करर
+Name[lv]=Iekarotājs
+Name[mn]=Конкюрор
+Name[ne]=कन्क्वेरर
+Name[pa]=ਕੋਨਕਿਉਰੋਰ
+Name[ta]=கான்கொரர்
+Name[te]=కాంకెరర్
+Name[th]=คอนเควอร์เรอร์
+Categories=Qt;KDE;System;
+X-KDE-HasTempFileOption=true
diff --git a/konqueror/kfmclient_war.desktop b/konqueror/kfmclient_war.desktop
new file mode 100644
index 000000000..46ea85805
--- /dev/null
+++ b/konqueror/kfmclient_war.desktop
@@ -0,0 +1,21 @@
+[Desktop Entry]
+Type=Application
+Exec=kfmclient openURL %u application/x-webarchive
+Icon=konqueror
+Terminal=false
+MimeType=application/x-webarchive;
+InitialPreference=9
+NoDisplay=true
+Name=Konqueror
+Name[bn]=কনকরার
+Name[eo]=Konkeranto
+Name[hi]=कॉन्करर
+Name[lv]=Iekarotājs
+Name[mn]=Конкюрор
+Name[ne]=कन्क्वेरर
+Name[pa]=ਕੋਨਕਿਉਰੋਰ
+Name[ta]=கான்கொரர்
+Name[te]=కాంకెరర్
+Name[th]=คอนเควอร์เรอร์
+Categories=Qt;KDE;System;
+X-KDE-HasTempFileOption=true
diff --git a/konqueror/konq-simplebrowser.rc b/konqueror/konq-simplebrowser.rc
new file mode 100644
index 000000000..911a14070
--- /dev/null
+++ b/konqueror/konq-simplebrowser.rc
@@ -0,0 +1,99 @@
+<?xml version = '1.0'?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui version="52" name="Konqueror" >
+ <MenuBar>
+ <Menu noMerge="1" name="file" >
+ <text>&amp;Location</text>
+ <Action name="new_window" />
+ <Action name="newtab" />
+ <Action name="open_location" />
+ <Separator/>
+ <Action name="sendURL" />
+ <Action name="sendPage" />
+ <Separator/>
+ <Merge/>
+ <Action name="print" />
+ <DefineGroup name="print" />
+ <Separator/>
+ <ActionList name="openwith" />
+ <Action name="quit" />
+ </Menu>
+ <Menu noMerge="1" name="edit" >
+ <text>&amp;Edit</text>
+ <Action name="copy" />
+ <Action name="paste" />
+ <Action name="del" />
+ <ActionList name="operations" />
+ <Separator/>
+ <Action name="properties" />
+ <WeakSeparator/>
+ <Merge/>
+ </Menu>
+ <Menu noMerge="1" name="view" >
+ <text>&amp;View</text>
+ <Action name="go_most_often" />
+ <ActionList name="viewmode" />
+ <Separator/>
+ <Merge/>
+ </Menu>
+ <Action name="bookmarks" />
+ <Menu name="tools" >
+ <text>&amp;Tools</text>
+ <WeakSeparator/>
+ <Merge/>
+ </Menu>
+ <Menu noMerge="1" name="settings" >
+ <text>&amp;Settings</text>
+ <Merge name="StandardToolBarMenuHandler" />
+ <Action name="saveviewprofile" />
+ <Action name="options_show_menubar" />
+ <Action name="fullscreen" />
+ <Separator/>
+ <Action name="options_configure_keybinding" />
+ <Action name="options_configure_toolbars" />
+ <Action name="options_configure_extensions" />
+ <Action name="options_configure" />
+ <Action name="configurespellcheck" />
+ </Menu>
+ <Menu append="about_merge" name="help" >
+ <text>&amp;Help</text>
+ <Action name="konqintro" />
+ </Menu>
+ <Merge/>
+ </MenuBar>
+ <ToolBar newline="true" hidden="true" name="mainToolBar">
+ <text>Main Toolbar</text>
+ <Action name="konq_sidebartng" />
+ <Separator name="separator_0" />
+ <Action name="print" />
+ <WeakSeparator/>
+ <Merge/>
+ <ActionList name="viewmode_toolbar" />
+ <ActionList name="fullscreen" />
+ <WeakSeparator/>
+ </ToolBar>
+ <ToolBar newline="false" hidden="true" index="1" name="extraToolBar" >
+ <text>Extra Toolbar</text>
+ </ToolBar>
+ <ToolBar newline="true" noMerge="1" name="locationToolBar" fullWidth="true" >
+ <text>Location Toolbar</text>
+ <Action name="back" />
+ <Action name="forward" />
+ <Action name="up" />
+ <Action name="home" />
+ <Action name="reload" />
+ <Action name="stop" />
+ <Action name="security" />
+ <Action name="clear_location" />
+ <Action name="location_label" />
+ <Action name="toolbar_url_combo" />
+ <Action name="go_url" />
+ <Action name="animated_logo" />
+ </ToolBar>
+ <ToolBar newline="true" noEdit="true" iconText="icontextright" name="bookmarkToolBar" fullWidth="true" >
+ <text>Bookmark Toolbar</text>
+ </ToolBar>
+ <ActionProperties>
+ <Action shortcut="F9" name="konq_sidebartng" />
+ </ActionProperties>
+</gui>
diff --git a/konqueror/konq_actions.cc b/konqueror/konq_actions.cc
new file mode 100644
index 000000000..ce0bafd03
--- /dev/null
+++ b/konqueror/konq_actions.cc
@@ -0,0 +1,504 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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 "konq_actions.h"
+
+#include <assert.h>
+
+#include <ktoolbarbutton.h>
+#include <kanimwidget.h>
+#include <kdebug.h>
+#include <kstringhandler.h>
+
+#include <konq_pixmapprovider.h>
+#include <kiconloader.h>
+#include <kpopupmenu.h>
+#include <kapplication.h>
+
+#include "konq_view.h"
+#include "konq_settingsxt.h"
+
+template class QPtrList<KonqHistoryEntry>;
+
+/////////////////
+
+//static - used by KonqHistoryAction and KonqBidiHistoryAction
+void KonqBidiHistoryAction::fillHistoryPopup( const QPtrList<HistoryEntry> &history,
+ QPopupMenu * popup,
+ bool onlyBack,
+ bool onlyForward,
+ bool checkCurrentItem,
+ uint startPos )
+{
+ assert ( popup ); // kill me if this 0... :/
+
+ //kdDebug(1202) << "fillHistoryPopup position: " << history.at() << endl;
+ HistoryEntry * current = history.current();
+ QPtrListIterator<HistoryEntry> it( history );
+ if (onlyBack || onlyForward)
+ {
+ it += history.at(); // Jump to current item
+ if ( !onlyForward ) --it; else ++it; // And move off it
+ } else if ( startPos )
+ it += startPos; // Jump to specified start pos
+
+ uint i = 0;
+ while ( it.current() )
+ {
+ QString text = it.current()->title;
+ text = KStringHandler::cEmSqueeze(text, popup->fontMetrics(), 30); //CT: squeeze
+ text.replace( "&", "&&" );
+ if ( checkCurrentItem && it.current() == current )
+ {
+ int id = popup->insertItem( text ); // no pixmap if checked
+ popup->setItemChecked( id, true );
+ } else
+ popup->insertItem( KonqPixmapProvider::self()->pixmapFor(
+ it.current()->url.url() ), text );
+ if ( ++i > 10 )
+ break;
+ if ( !onlyForward ) --it; else ++it;
+ }
+ //kdDebug(1202) << "After fillHistoryPopup position: " << history.at() << endl;
+}
+
+///////////////////////////////
+
+KonqBidiHistoryAction::KonqBidiHistoryAction ( const QString & text, QObject* parent, const char* name )
+ : KAction( text, 0, parent, name )
+{
+ setShortcutConfigurable(false);
+ m_firstIndex = 0;
+ m_goMenu = 0L;
+}
+
+int KonqBidiHistoryAction::plug( QWidget *widget, int index )
+{
+ if (kapp && !kapp->authorizeKAction(name()))
+ return -1;
+
+ // Go menu
+ if ( widget->inherits("QPopupMenu") )
+ {
+ m_goMenu = (QPopupMenu*)widget;
+ // Forward signal (to main view)
+ connect( m_goMenu, SIGNAL( aboutToShow() ),
+ this, SIGNAL( menuAboutToShow() ) );
+ connect( m_goMenu, SIGNAL( activated( int ) ),
+ this, SLOT( slotActivated( int ) ) );
+ //kdDebug(1202) << "m_goMenu->count()=" << m_goMenu->count() << endl;
+ // Store how many items the menu already contains.
+ // This means, the KonqBidiHistoryAction has to be plugged LAST in a menu !
+ m_firstIndex = m_goMenu->count();
+ return m_goMenu->count(); // hmmm, what should this be ?
+ }
+ return KAction::plug( widget, index );
+}
+
+void KonqBidiHistoryAction::fillGoMenu( const QPtrList<HistoryEntry> & history )
+{
+ if (history.isEmpty())
+ return; // nothing to do
+
+ //kdDebug(1202) << "fillGoMenu position: " << history.at() << endl;
+ if ( m_firstIndex == 0 ) // should never happen since done in plug
+ m_firstIndex = m_goMenu->count();
+ else
+ { // Clean up old history (from the end, to avoid shifts)
+ for ( uint i = m_goMenu->count()-1 ; i >= m_firstIndex; i-- )
+ m_goMenu->removeItemAt( i );
+ }
+ // TODO perhaps smarter algorithm (rename existing items, create new ones only if not enough) ?
+
+ // Ok, we want to show 10 items in all, among which the current url...
+
+ if ( history.count() <= 9 )
+ {
+ // First case: limited history in both directions -> show it all
+ m_startPos = history.count() - 1; // Start right from the end
+ } else
+ // Second case: big history, in one or both directions
+ {
+ // Assume both directions first (in this case we place the current URL in the middle)
+ m_startPos = history.at() + 4;
+
+ // Forward not big enough ?
+ if ( history.at() > (int)history.count() - 4 )
+ m_startPos = history.count() - 1;
+ }
+ Q_ASSERT( m_startPos >= 0 && (uint)m_startPos < history.count() );
+ if ( m_startPos < 0 || (uint)m_startPos >= history.count() )
+ {
+ kdWarning() << "m_startPos=" << m_startPos << " history.count()=" << history.count() << endl;
+ return;
+ }
+ m_currentPos = history.at(); // for slotActivated
+ KonqBidiHistoryAction::fillHistoryPopup( history, m_goMenu, false, false, true, m_startPos );
+}
+
+void KonqBidiHistoryAction::slotActivated( int id )
+{
+ // 1 for first item in the list, etc.
+ int index = m_goMenu->indexOf(id) - m_firstIndex + 1;
+ if ( index > 0 )
+ {
+ kdDebug(1202) << "Item clicked has index " << index << endl;
+ // -1 for one step back, 0 for don't move, +1 for one step forward, etc.
+ int steps = ( m_startPos+1 ) - index - m_currentPos; // make a drawing to understand this :-)
+ kdDebug(1202) << "Emit activated with steps = " << steps << endl;
+ emit activated( steps );
+ }
+}
+
+///////////////////////////////
+
+KonqLogoAction::KonqLogoAction( const QString& text, int accel, QObject* parent, const char* name )
+ : KAction( text, accel, parent, name )
+{
+}
+
+KonqLogoAction::KonqLogoAction( const QString& text, int accel,
+ QObject* receiver, const char* slot, QObject* parent, const char* name )
+ : KAction( text, accel, receiver, slot, parent, name )
+{
+}
+
+KonqLogoAction::KonqLogoAction( const QString& text, const QIconSet& pix, int accel, QObject* parent, const char* name )
+ : KAction( text, pix, accel, parent, name )
+{
+}
+
+KonqLogoAction::KonqLogoAction( const QString& text, const QIconSet& pix,int accel, QObject* receiver, const char* slot, QObject* parent, const char* name )
+ : KAction( text, pix, accel, receiver, slot, parent, name )
+{
+}
+
+KonqLogoAction::KonqLogoAction( const QStringList& icons, QObject* receiver,
+ const char* slot, QObject* parent,
+ const char* name )
+ : KAction( 0L, 0, receiver, slot, parent, name ) // text missing !
+{
+ iconList = icons;
+}
+
+void KonqLogoAction::start()
+{
+ int len = containerCount();
+ for ( int i = 0; i < len; i++ )
+ {
+ QWidget *w = container( i );
+
+ if ( w->inherits( "KToolBar" ) )
+ {
+ KAnimWidget *anim = ((KToolBar *)w)->animatedWidget( menuId( i ) );
+ anim->start();
+ }
+ }
+}
+
+void KonqLogoAction::stop()
+{
+ int len = containerCount();
+ for ( int i = 0; i < len; i++ )
+ {
+ QWidget *w = container( i );
+
+ if ( w->inherits( "KToolBar" ) )
+ {
+ KAnimWidget *anim = ((KToolBar *)w)->animatedWidget( menuId( i ) );
+ anim->stop();
+ }
+ }
+}
+
+void KonqLogoAction::updateIcon(int id)
+{
+ QWidget *w = container( id );
+
+ if ( w->inherits( "KToolBar" ) )
+ {
+ KAnimWidget *anim = ((KToolBar *)w)->animatedWidget( menuId( id ) );
+ anim->setIcons(icon());
+ }
+}
+
+
+
+int KonqLogoAction::plug( QWidget *widget, int index )
+{
+ if (kapp && !kapp->authorizeKAction(name()))
+ return -1;
+
+/*
+ if ( widget->inherits( "KMainWindow" ) )
+ {
+ ((KMainWindow*)widget)->setIndicatorWidget(m_logoLabel);
+
+ addContainer( widget, -1 );
+
+ return containerCount() - 1;
+ }
+*/
+ if ( widget->inherits( "KToolBar" ) )
+ {
+ KToolBar *bar = (KToolBar *)widget;
+
+ int id_ = getToolButtonID();
+
+ bar->insertAnimatedWidget( id_, this, SIGNAL(activated()), QString("kde"), index );
+ bar->alignItemRight( id_ );
+
+ addContainer( bar, id_ );
+
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ return containerCount() - 1;
+ }
+
+ int containerId = KAction::plug( widget, index );
+
+ return containerId;
+}
+
+///////////
+
+KonqViewModeAction::KonqViewModeAction( const QString &text, const QString &icon,
+ QObject *parent, const char *name )
+ : KRadioAction( text, icon, 0, parent, name )
+{
+ m_menu = new QPopupMenu;
+
+ connect( m_menu, SIGNAL( aboutToShow() ),
+ this, SLOT( slotPopupAboutToShow() ) );
+ connect( m_menu, SIGNAL( activated( int ) ),
+ this, SLOT( slotPopupActivated() ) );
+ connect( m_menu, SIGNAL( aboutToHide() ),
+ this, SLOT( slotPopupAboutToHide() ) );
+}
+
+KonqViewModeAction::~KonqViewModeAction()
+{
+ delete m_menu;
+}
+
+int KonqViewModeAction::plug( QWidget *widget, int index )
+{
+ int res = KRadioAction::plug( widget, index );
+
+ if ( widget->inherits( "KToolBar" ) && (res != -1) )
+ {
+ KToolBar *toolBar = static_cast<KToolBar *>( widget );
+
+ KToolBarButton *button = toolBar->getButton( itemId( res ) );
+
+ if ( m_menu->count() > 1 )
+ button->setDelayedPopup( m_menu, false );
+ }
+
+ return res;
+}
+
+void KonqViewModeAction::slotPopupAboutToShow()
+{
+ m_popupActivated = false;
+}
+
+void KonqViewModeAction::slotPopupActivated()
+{
+ m_popupActivated = true;
+}
+
+void KonqViewModeAction::slotPopupAboutToHide()
+{
+ if ( !m_popupActivated )
+ {
+ int i = 0;
+ for (; i < containerCount(); ++i )
+ {
+ QWidget *widget = container( i );
+ if ( !widget->inherits( "KToolBar" ) )
+ continue;
+
+ KToolBar *tb = static_cast<KToolBar *>( widget );
+
+ KToolBarButton *button = tb->getButton( itemId( i ) );
+
+ button->setDown( isChecked() );
+ }
+ }
+}
+
+
+MostOftenList * KonqMostOftenURLSAction::s_mostEntries = 0L;
+uint KonqMostOftenURLSAction::s_maxEntries = 0;
+
+KonqMostOftenURLSAction::KonqMostOftenURLSAction( const QString& text,
+ QObject *parent,
+ const char *name )
+ : KActionMenu( text, "goto", parent, name )
+{
+ setDelayed( false );
+
+ connect( popupMenu(), SIGNAL( aboutToShow() ), SLOT( slotFillMenu() ));
+ //connect( popupMenu(), SIGNAL( aboutToHide() ), SLOT( slotClearMenu() ));
+ connect( popupMenu(), SIGNAL( activated( int ) ),
+ SLOT( slotActivated(int) ));
+ // Need to do all this upfront for a correct initial state
+ init();
+}
+
+KonqMostOftenURLSAction::~KonqMostOftenURLSAction()
+{
+}
+
+void KonqMostOftenURLSAction::init()
+{
+ s_maxEntries = KonqSettings::numberofmostvisitedURLs();
+
+ KonqHistoryManager *mgr = KonqHistoryManager::kself();
+ setEnabled( !mgr->entries().isEmpty() && s_maxEntries > 0 );
+}
+
+void KonqMostOftenURLSAction::parseHistory() // only ever called once
+{
+ KonqHistoryManager *mgr = KonqHistoryManager::kself();
+ KonqHistoryIterator it( mgr->entries() );
+
+ connect( mgr, SIGNAL( entryAdded( const KonqHistoryEntry * )),
+ SLOT( slotEntryAdded( const KonqHistoryEntry * )));
+ connect( mgr, SIGNAL( entryRemoved( const KonqHistoryEntry * )),
+ SLOT( slotEntryRemoved( const KonqHistoryEntry * )));
+ connect( mgr, SIGNAL( cleared() ), SLOT( slotHistoryCleared() ));
+
+ s_mostEntries = new MostOftenList; // exit() will clean this up for now
+ for ( uint i = 0; it.current() && i < s_maxEntries; i++ ) {
+ s_mostEntries->append( it.current() );
+ ++it;
+ }
+ s_mostEntries->sort();
+
+ while ( it.current() ) {
+ KonqHistoryEntry *leastOften = s_mostEntries->first();
+ KonqHistoryEntry *entry = it.current();
+ if ( leastOften->numberOfTimesVisited < entry->numberOfTimesVisited ) {
+ s_mostEntries->removeFirst();
+ s_mostEntries->inSort( entry );
+ }
+
+ ++it;
+ }
+}
+
+void KonqMostOftenURLSAction::slotEntryAdded( const KonqHistoryEntry *entry )
+{
+ // if it's already present, remove it, and inSort it
+ s_mostEntries->removeRef( entry );
+
+ if ( s_mostEntries->count() >= s_maxEntries ) {
+ KonqHistoryEntry *leastOften = s_mostEntries->first();
+ if ( leastOften->numberOfTimesVisited < entry->numberOfTimesVisited ) {
+ s_mostEntries->removeFirst();
+ s_mostEntries->inSort( entry );
+ }
+ }
+
+ else
+ s_mostEntries->inSort( entry );
+ setEnabled( !s_mostEntries->isEmpty() );
+}
+
+void KonqMostOftenURLSAction::slotEntryRemoved( const KonqHistoryEntry *entry )
+{
+ s_mostEntries->removeRef( entry );
+ setEnabled( !s_mostEntries->isEmpty() );
+}
+
+void KonqMostOftenURLSAction::slotHistoryCleared()
+{
+ s_mostEntries->clear();
+ setEnabled( false );
+}
+
+void KonqMostOftenURLSAction::slotFillMenu()
+{
+ if ( !s_mostEntries ) // first time
+ parseHistory();
+
+ popupMenu()->clear();
+ m_popupList.clear();
+
+ int id = s_mostEntries->count() -1;
+ KonqHistoryEntry *entry = s_mostEntries->at( id );
+ while ( entry ) {
+ // we take either title, typedURL or URL (in this order)
+ QString text = entry->title.isEmpty() ? (entry->typedURL.isEmpty() ?
+ entry->url.prettyURL() :
+ entry->typedURL) :
+ entry->title;
+
+ popupMenu()->insertItem(
+ KonqPixmapProvider::self()->pixmapFor( entry->url.url() ),
+ text, id );
+ // Keep a copy of the URLs being shown in the menu
+ // This prevents crashes when another process tells us to remove an entry.
+ m_popupList.prepend( entry->url );
+
+ entry = (id > 0) ? s_mostEntries->at( --id ) : 0L;
+ }
+ setEnabled( !s_mostEntries->isEmpty() );
+ Q_ASSERT( s_mostEntries->count() == m_popupList.count() );
+}
+
+#if 0
+void KonqMostOftenURLSAction::slotClearMenu()
+{
+ // Warning this is called _before_ slotActivated, when activating a menu item.
+ // So e.g. don't clear m_popupList here.
+}
+#endif
+
+void KonqMostOftenURLSAction::slotActivated( int id )
+{
+ Q_ASSERT( !m_popupList.isEmpty() ); // can not happen
+ Q_ASSERT( id < (int)m_popupList.count() );
+
+ KURL url = m_popupList[ id ];
+ if ( url.isValid() )
+ emit activated( url );
+ else
+ kdWarning() << "Invalid url: " << url.prettyURL() << endl;
+ m_popupList.clear();
+}
+
+// sort by numberOfTimesVisited (least often goes first)
+int MostOftenList::compareItems( QPtrCollection::Item item1,
+ QPtrCollection::Item item2)
+{
+ KonqHistoryEntry *entry1 = static_cast<KonqHistoryEntry *>( item1 );
+ KonqHistoryEntry *entry2 = static_cast<KonqHistoryEntry *>( item2 );
+
+ if ( entry1->numberOfTimesVisited > entry2->numberOfTimesVisited )
+ return 1;
+ else if ( entry1->numberOfTimesVisited < entry2->numberOfTimesVisited )
+ return -1;
+ else
+ return 0;
+}
+
+#include "konq_actions.moc"
diff --git a/konqueror/konq_actions.h b/konqueror/konq_actions.h
new file mode 100644
index 000000000..d4fb343e7
--- /dev/null
+++ b/konqueror/konq_actions.h
@@ -0,0 +1,158 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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.
+*/
+
+#ifndef __konq_actions_h__
+#define __konq_actions_h__
+
+#include <konq_historymgr.h>
+#include <kaction.h>
+#include <qptrlist.h>
+
+class HistoryEntry;
+class QPopupMenu;
+
+/**
+ * Plug this action into a menu to get a bidirectional history
+ * (both back and forward, including current location)
+ */
+class KonqBidiHistoryAction : public KAction
+{
+ Q_OBJECT
+public:
+ KonqBidiHistoryAction( const QString & text, QObject* parent = 0, const char* name = 0 );
+
+ virtual ~KonqBidiHistoryAction() {};
+
+ virtual int plug( QWidget *widget, int index = -1 );
+ //virtual void unplug( QWidget *widget );
+
+ void fillGoMenu( const QPtrList<HistoryEntry> &history );
+
+ // Used by KonqHistoryAction and KonqBidiHistoryAction
+ static void fillHistoryPopup( const QPtrList<HistoryEntry> &history,
+ QPopupMenu * popup,
+ bool onlyBack = false,
+ bool onlyForward = false,
+ bool checkCurrentItem = false,
+ uint startPos = 0 );
+
+protected slots:
+ void slotActivated( int );
+
+signals:
+ void menuAboutToShow();
+ // -1 for one step back, 0 for don't move, +1 for one step forward, etc.
+ void activated( int );
+private:
+ uint m_firstIndex; // first index in the Go menu
+ int m_startPos;
+ int m_currentPos; // == history.at()
+ QPopupMenu *m_goMenu; // hack
+};
+
+/////
+
+class KonqLogoAction : public KAction
+{
+ Q_OBJECT
+public:
+ KonqLogoAction( const QString& text, int accel = 0, QObject* parent = 0, const char* name = 0 );
+ KonqLogoAction( const QString& text, int accel,
+ QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
+ KonqLogoAction( const QString& text, const QIconSet& pix, int accel = 0,
+ QObject* parent = 0, const char* name = 0 );
+ KonqLogoAction( const QString& text, const QIconSet& pix, int accel,
+ QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
+ // text missing !
+ KonqLogoAction( const QStringList& icons, QObject* receiver,
+ const char* slot, QObject* parent, const char* name = 0 );
+
+ virtual int plug( QWidget *widget, int index = -1 );
+ virtual void updateIcon(int id);
+
+ void start();
+ void stop();
+
+private:
+ QStringList iconList;
+};
+
+class KonqViewModeAction : public KRadioAction
+{
+ Q_OBJECT
+public:
+ KonqViewModeAction( const QString &text, const QString &icon,
+ QObject *parent, const char *name );
+ virtual ~KonqViewModeAction();
+
+ virtual int plug( QWidget *widget, int index = -1 );
+
+ QPopupMenu *popupMenu() const { return m_menu; }
+
+private slots:
+ void slotPopupAboutToShow();
+ void slotPopupActivated();
+ void slotPopupAboutToHide();
+
+private:
+ bool m_popupActivated;
+ QPopupMenu *m_menu;
+};
+
+class MostOftenList : public KonqBaseHistoryList
+{
+protected:
+ /**
+ * Ensures that the items are sorted by numberOfTimesVisited
+ */
+ virtual int compareItems( QPtrCollection::Item, QPtrCollection::Item );
+};
+
+class KonqMostOftenURLSAction : public KActionMenu
+{
+ Q_OBJECT
+
+public:
+ KonqMostOftenURLSAction( const QString& text, QObject *parent,
+ const char *name );
+ virtual ~KonqMostOftenURLSAction();
+
+signals:
+ void activated( const KURL& );
+
+private slots:
+ void slotHistoryCleared();
+ void slotEntryAdded( const KonqHistoryEntry *entry );
+ void slotEntryRemoved( const KonqHistoryEntry *entry );
+
+ void slotFillMenu();
+ //void slotClearMenu();
+
+ void slotActivated( int );
+
+private:
+ void init();
+ void parseHistory();
+
+ static MostOftenList *s_mostEntries;
+ static uint s_maxEntries;
+ KURL::List m_popupList;
+};
+
+#endif
diff --git a/konqueror/konq_browseriface.cc b/konqueror/konq_browseriface.cc
new file mode 100644
index 000000000..ebec2ef04
--- /dev/null
+++ b/konqueror/konq_browseriface.cc
@@ -0,0 +1,22 @@
+
+#include "konq_browseriface.h"
+#include "konq_view.h"
+
+KonqBrowserInterface::KonqBrowserInterface( KonqView *view, const char *name )
+ : KParts::BrowserInterface( view, name )
+{
+ m_view = view;
+}
+
+uint KonqBrowserInterface::historyLength() const
+{
+ return m_view->historyLength();
+}
+
+void KonqBrowserInterface::goHistory( int steps )
+{
+ m_view->goHistory( steps );
+}
+
+#include "konq_browseriface.moc"
+
diff --git a/konqueror/konq_browseriface.h b/konqueror/konq_browseriface.h
new file mode 100644
index 000000000..57f2fc05b
--- /dev/null
+++ b/konqueror/konq_browseriface.h
@@ -0,0 +1,24 @@
+#ifndef __konq_browseriface_h__
+#define __konq_browseriface_h__
+
+#include <kparts/browserinterface.h>
+
+class KonqView;
+
+class KonqBrowserInterface : public KParts::BrowserInterface
+{
+ Q_OBJECT
+ Q_PROPERTY( uint historyLength READ historyLength )
+public:
+ KonqBrowserInterface( KonqView *view, const char *name );
+
+ uint historyLength() const;
+
+public slots:
+ void goHistory( int );
+
+private:
+ KonqView *m_view;
+};
+
+#endif
diff --git a/konqueror/konq_combo.cc b/konqueror/konq_combo.cc
new file mode 100644
index 000000000..2e5279474
--- /dev/null
+++ b/konqueror/konq_combo.cc
@@ -0,0 +1,892 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qpainter.h>
+#include <qstyle.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcompletionbox.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kicontheme.h>
+#include <klineedit.h>
+#include <konq_pixmapprovider.h>
+#include <kstdaccel.h>
+#include <kurldrag.h>
+#include <konq_mainwindow.h>
+#include <kstringhandler.h>
+
+#include <dcopclient.h>
+
+#include "konq_combo.h"
+
+KConfig * KonqCombo::s_config = 0L;
+const int KonqCombo::temporary = 0;
+
+static QString titleOfURL( const QString& urlStr )
+{
+ KURL url = KURL::fromPathOrURL( urlStr );
+ KonqHistoryList& historylist = const_cast<KonqHistoryList&>( KonqHistoryManager::kself()->entries() );
+ KonqHistoryEntry *historyentry = historylist.findEntry( url );
+ if ( !historyentry && !url.url().endsWith( "/" ) ) {
+ url.setPath( url.path()+'/' );
+ historyentry = historylist.findEntry( url );
+ }
+ return ( historyentry ? historyentry->title : QString::null );
+}
+
+class Q_EXPORT KonqComboListBoxPixmap : public QListBoxItem
+{
+public:
+ KonqComboListBoxPixmap( const QString& text );
+ KonqComboListBoxPixmap( const QPixmap &, const QString& text, const QString& title );
+
+ const QPixmap *pixmap() const { return &pm; }
+
+ int height( const QListBox * ) const;
+ int width( const QListBox * ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+ bool reuse( const QString& newText );
+
+protected:
+ void paint( QPainter * );
+
+private:
+ bool lookup_pending;
+ QPixmap pm;
+ QString title;
+};
+
+class KonqComboLineEdit : public KLineEdit
+{
+public:
+ KonqComboLineEdit( QWidget *parent=0, const char *name=0 );
+ void setCompletedItems( const QStringList& items );
+};
+
+class KonqComboCompletionBox : public KCompletionBox
+{
+public:
+ KonqComboCompletionBox( QWidget *parent, const char *name = 0 );
+ void setItems( const QStringList& items );
+ void insertStringList( const QStringList & list, int index = -1 );
+};
+
+KonqCombo::KonqCombo( QWidget *parent, const char *name )
+ : KHistoryCombo( parent, name ),
+ m_returnPressed( false ),
+ m_permanent( false ),
+ m_modifier( NoButton ),
+ m_pageSecurity( KonqMainWindow::NotCrypted )
+{
+ setInsertionPolicy( NoInsertion );
+ setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
+
+ Q_ASSERT( s_config );
+
+ KConfigGroupSaver cs( s_config, "Location Bar" );
+ setMaxCount( s_config->readNumEntry("Maximum of URLs in combo", 20 ));
+
+ // We should also connect the completionBox' highlighted signal to
+ // our setEditText() slot, because we're handling the signals ourselves.
+ // But we're lazy and let KCompletionBox do this and simply switch off
+ // handling of signals later.
+ setHandleSignals( true );
+
+ KonqComboLineEdit *edit = new KonqComboLineEdit( this, "combo lineedit" );
+ edit->setHandleSignals( true );
+ edit->setCompletionBox( new KonqComboCompletionBox( edit, "completion box" ) );
+ setLineEdit( edit );
+
+ completionBox()->setTabHandling( true );
+
+ // Make the lineedit consume the Key_Enter event...
+ setTrapReturnKey( true );
+
+ connect( KonqHistoryManager::kself(), SIGNAL(cleared()), SLOT(slotCleared()) );
+ connect( this, SIGNAL(cleared() ), SLOT(slotCleared()) );
+ connect( this, SIGNAL(highlighted( int )), SLOT(slotSetIcon( int )) );
+ connect( this, SIGNAL(activated( const QString& )),
+ SLOT(slotActivated( const QString& )) );
+
+ if ( !kapp->dcopClient()->isAttached() )
+ kapp->dcopClient()->attach();
+}
+
+KonqCombo::~KonqCombo()
+{
+}
+
+void KonqCombo::init( KCompletion *completion )
+{
+ setCompletionObject( completion, false ); //KonqMainWindow handles signals
+ setAutoDeleteCompletionObject( false );
+ setCompletionMode( completion->completionMode() );
+
+ loadItems();
+}
+
+void KonqCombo::setURL( const QString& url )
+{
+ //kdDebug(1202) << "KonqCombo::setURL: " << url << ", returnPressed ? " << m_returnPressed << endl;
+ setTemporary( url );
+
+ if ( m_returnPressed ) { // Really insert...
+ m_returnPressed = false;
+ QByteArray data;
+ QDataStream s( data, IO_WriteOnly );
+ s << url << kapp->dcopClient()->defaultObject();
+ kapp->dcopClient()->send( "konqueror*", "KonquerorIface",
+ "addToCombo(QString,QCString)", data);
+ }
+ // important security consideration: always display the beginning
+ // of the url rather than its end to prevent spoofing attempts.
+ lineEdit()->setCursorPosition( 0 );
+}
+
+void KonqCombo::setTemporary( const QString& text )
+{
+ setTemporary( text, KonqPixmapProvider::self()->pixmapFor(text) );
+}
+
+void KonqCombo::setTemporary( const QString& url, const QPixmap& pix )
+{
+ //kdDebug(1202) << "KonqCombo::setTemporary: " << url << ", temporary = " << temporary << endl;
+
+ // Insert a temporary item when we don't have one yet
+ if ( count() == 0 )
+ insertItem( pix, url, temporary, titleOfURL( url ) );
+ else
+ {
+ if (url != temporaryItem())
+ applyPermanent();
+
+ updateItem( pix, url, temporary, titleOfURL( url ) );
+ }
+
+ setCurrentItem( temporary );
+}
+
+void KonqCombo::removeDuplicates( int index )
+{
+ //kdDebug(1202) << "KonqCombo::removeDuplicates: Starting index = " << index << endl;
+
+ QString url (temporaryItem());
+ if (url.endsWith("/"))
+ url.truncate(url.length()-1);
+
+ // Remove all dupes, if available...
+ for ( int i = index; i < count(); i++ )
+ {
+ QString item (text(i));
+ if (item.endsWith("/"))
+ item.truncate(item.length()-1);
+
+ if ( item == url )
+ removeItem( i );
+ }
+}
+
+// called via DCOP in all instances
+void KonqCombo::insertPermanent( const QString& url )
+{
+ //kdDebug(1202) << "KonqCombo::insertPermanent: URL = " << url << endl;
+ saveState();
+ setTemporary( url );
+ m_permanent = true;
+ restoreState();
+}
+
+// called right before a new (different!) temporary item will be set. So we
+// insert an item that was marked permanent properly at position 1.
+void KonqCombo::applyPermanent()
+{
+ if ( m_permanent && !temporaryItem().isEmpty() ) {
+
+ // Remove as many items as needed to honour maxCount()
+ int index = count();
+ while ( count() >= maxCount() )
+ removeItem( --index );
+
+ QString url (temporaryItem());
+ insertItem( KonqPixmapProvider::self()->pixmapFor( url ), url, 1, titleOfURL( url ) );
+ //kdDebug(1202) << "KonqCombo::applyPermanent: " << url << endl;
+
+ // Remove all duplicates starting from index = 2
+ removeDuplicates( 2 );
+ m_permanent = false;
+ }
+}
+
+void KonqCombo::insertItem( const QString &text, int index, const QString& title )
+{
+ KonqComboListBoxPixmap* item = new KonqComboListBoxPixmap( 0, text, title );
+ listBox()->insertItem( item, index );
+}
+
+void KonqCombo::insertItem( const QPixmap &pixmap, const QString& text, int index, const QString& title )
+{
+ KonqComboListBoxPixmap* item = new KonqComboListBoxPixmap( pixmap, text, title );
+ listBox()->insertItem( item, index );
+}
+
+void KonqCombo::updateItem( const QPixmap& pix, const QString& t, int index, const QString& title )
+{
+ // No need to flicker
+ if (text( index ) == t &&
+ (pixmap(index) && pixmap(index)->serialNumber() == pix.serialNumber()))
+ return;
+
+ // kdDebug(1202) << "KonqCombo::updateItem: item='" << t << "', index='"
+ // << index << "'" << endl;
+
+ // QComboBox::changeItem() doesn't honour the pixmap when
+ // using an editable combobox, so we just remove and insert
+ // ### use QComboBox::changeItem(), once that finally works
+ // Well lets try it now as it seems to work fine for me. We
+ // can always revert :)
+ KonqComboListBoxPixmap* item = new KonqComboListBoxPixmap( pix, t, title );
+ listBox()->changeItem( item, index );
+
+ /*
+ setUpdatesEnabled( false );
+ lineEdit()->setUpdatesEnabled( false );
+
+ removeItem( index );
+ insertItem( pix, t, index );
+
+ setUpdatesEnabled( true );
+ lineEdit()->setUpdatesEnabled( true );
+ update();
+ */
+}
+
+void KonqCombo::saveState()
+{
+ m_cursorPos = cursorPosition();
+ m_currentText = currentText();
+ m_currentIndex = currentItem();
+}
+
+void KonqCombo::restoreState()
+{
+ setTemporary( m_currentText );
+ lineEdit()->setCursorPosition( m_cursorPos );
+}
+
+void KonqCombo::updatePixmaps()
+{
+ saveState();
+
+ setUpdatesEnabled( false );
+ KonqPixmapProvider *prov = KonqPixmapProvider::self();
+ for ( int i = 1; i < count(); i++ ) {
+ updateItem( prov->pixmapFor( text( i ) ), text( i ), i, titleOfURL( text( i ) ) );
+ }
+ setUpdatesEnabled( true );
+ repaint();
+
+ restoreState();
+}
+
+void KonqCombo::loadItems()
+{
+ clear();
+ int i = 0;
+
+ s_config->setGroup( "History" ); // delete the old 2.0.x completion
+ s_config->writeEntry( "CompletionItems", "unused" );
+
+ s_config->setGroup( "Location Bar" );
+ QStringList items = s_config->readPathListEntry( "ComboContents" );
+ QStringList::ConstIterator it = items.begin();
+ QString item;
+ bool first = true;
+ while ( it != items.end() ) {
+ item = *it;
+ if ( !item.isEmpty() ) { // only insert non-empty items
+ if( first ) {
+ insertItem( KonqPixmapProvider::self()->pixmapFor( item, KIcon::SizeSmall ),
+ item, i++, titleOfURL( item ) );
+ }
+ else
+ // icons will be loaded on-demand
+ insertItem( item, i++, titleOfURL( item ) );
+ first = false;
+ }
+ ++it;
+ }
+
+ if ( count() > 0 )
+ m_permanent = true; // we want the first loaded item to stay
+}
+
+void KonqCombo::slotSetIcon( int index )
+{
+ if( pixmap( index ) == NULL )
+ // on-demand icon loading
+ updateItem( KonqPixmapProvider::self()->pixmapFor( text( index ),
+ KIcon::SizeSmall ), text( index ), index,
+ titleOfURL( text( index ) ) );
+ update();
+}
+
+void KonqCombo::popup()
+{
+ for( int i = 0; i < count(); ++i )
+ {
+ if( pixmap( i ) == NULL || pixmap( i )->isNull() )
+ {
+ // on-demand icon loading
+ updateItem( KonqPixmapProvider::self()->pixmapFor( text( i ),
+ KIcon::SizeSmall), text( i ), i, titleOfURL( text( i ) ) );
+ }
+ }
+ KHistoryCombo::popup();
+}
+
+void KonqCombo::saveItems()
+{
+ QStringList items;
+ int i = m_permanent ? 0 : 1;
+
+ for ( ; i < count(); i++ )
+ items.append( text( i ) );
+
+ s_config->setGroup( "Location Bar" );
+ s_config->writePathEntry( "ComboContents", items );
+ KonqPixmapProvider::self()->save( s_config, "ComboIconCache", items );
+
+ s_config->sync();
+}
+
+void KonqCombo::clearTemporary( bool makeCurrent )
+{
+ applyPermanent();
+ changeItem( QString::null, temporary ); // ### default pixmap?
+ if ( makeCurrent )
+ setCurrentItem( temporary );
+}
+
+bool KonqCombo::eventFilter( QObject *o, QEvent *ev )
+{
+ // Handle Ctrl+Del/Backspace etc better than the Qt widget, which always
+ // jumps to the next whitespace.
+ QLineEdit *edit = lineEdit();
+ if ( o == edit ) {
+ int type = ev->type();
+ if ( type == QEvent::KeyPress ) {
+ QKeyEvent *e = static_cast<QKeyEvent *>( ev );
+
+ if ( e->key() == Key_Return || e->key() == Key_Enter ) {
+ m_modifier = e->state();
+ return false;
+ }
+
+ if ( KKey( e ) == KKey( int( KStdAccel::deleteWordBack() ) ) ||
+ KKey( e ) == KKey( int( KStdAccel::deleteWordForward() ) ) ||
+ ((e->state() & ControlButton) &&
+ (e->key() == Key_Left || e->key() == Key_Right) ) ) {
+ selectWord(e);
+ e->accept();
+ return true;
+ }
+ }
+
+ else if ( type == QEvent::MouseButtonDblClick ) {
+ edit->selectAll();
+ return true;
+ }
+ }
+ return KComboBox::eventFilter( o, ev );
+}
+
+void KonqCombo::keyPressEvent( QKeyEvent *e )
+{
+ KHistoryCombo::keyPressEvent( e );
+ // we have to set it as temporary, otherwise we wouldn't get our nice
+ // pixmap. Yes, QComboBox still sucks.
+ if ( KKey( e ) == KKey( int( KStdAccel::rotateUp() ) ) ||
+ KKey( e ) == KKey( int( KStdAccel::rotateDown() ) ) )
+ setTemporary( currentText() );
+}
+
+/*
+ Handle Ctrl+Cursor etc better than the Qt widget, which always
+ jumps to the next whitespace. This code additionally jumps to
+ the next [/#?:], which makes more sense for URLs. The list of
+ chars that will stop the cursor are '/', '.', '?', '#', ':'.
+*/
+void KonqCombo::selectWord(QKeyEvent *e)
+{
+ QLineEdit* edit = lineEdit();
+ QString text = edit->text();
+ int pos = edit->cursorPosition();
+ int pos_old = pos;
+ int count = 0;
+
+ // TODO: make these a parameter when in kdelibs/kdeui...
+ QValueList<QChar> chars;
+ chars << QChar('/') << QChar('.') << QChar('?') << QChar('#') << QChar(':');
+ bool allow_space_break = true;
+
+ if( e->key() == Key_Left || e->key() == Key_Backspace ) {
+ do {
+ pos--;
+ count++;
+ if( allow_space_break && text[pos].isSpace() && count > 1 )
+ break;
+ } while( pos >= 0 && (chars.findIndex(text[pos]) == -1 || count <= 1) );
+
+ if( e->state() & ShiftButton ) {
+ edit->cursorForward(true, 1-count);
+ }
+ else if( e->key() == Key_Backspace ) {
+ edit->cursorForward(false, 1-count);
+ QString text = edit->text();
+ int pos_to_right = edit->text().length() - pos_old;
+ QString cut = text.left(edit->cursorPosition()) + text.right(pos_to_right);
+ edit->setText(cut);
+ edit->setCursorPosition(pos_old-count+1);
+ }
+ else {
+ edit->cursorForward(false, 1-count);
+ }
+ }
+ else if( e->key() == Key_Right || e->key() == Key_Delete ){
+ do {
+ pos++;
+ count++;
+ if( allow_space_break && text[pos].isSpace() )
+ break;
+ } while( pos < (int) text.length() && chars.findIndex(text[pos]) == -1 );
+
+ if( e->state() & ShiftButton ) {
+ edit->cursorForward(true, count+1);
+ }
+ else if( e->key() == Key_Delete ) {
+ edit->cursorForward(false, -count-1);
+ QString text = edit->text();
+ int pos_to_right = text.length() - pos - 1;
+ QString cut = text.left(pos_old) +
+ (pos_to_right > 0 ? text.right(pos_to_right) : QString::null );
+ edit->setText(cut);
+ edit->setCursorPosition(pos_old);
+ }
+ else {
+ edit->cursorForward(false, count+1);
+ }
+ }
+}
+
+void KonqCombo::slotCleared()
+{
+ QByteArray data;
+ QDataStream s( data, IO_WriteOnly );
+ s << kapp->dcopClient()->defaultObject();
+ kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "comboCleared(QCString)", data);
+}
+
+void KonqCombo::removeURL( const QString& url )
+{
+ setUpdatesEnabled( false );
+ lineEdit()->setUpdatesEnabled( false );
+
+ removeFromHistory( url );
+ applyPermanent();
+ setTemporary( currentText() );
+
+ setUpdatesEnabled( true );
+ lineEdit()->setUpdatesEnabled( true );
+ update();
+}
+
+void KonqCombo::mousePressEvent( QMouseEvent *e )
+{
+ m_dragStart = QPoint(); // null QPoint
+
+ if ( e->button() == LeftButton && pixmap( currentItem()) ) {
+ // check if the pixmap was clicked
+ int x = e->pos().x();
+ int x0 = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_ComboBox, this, QStyle::SC_ComboBoxEditField ), this ).x();
+
+ if ( x > x0 + 2 && x < lineEdit()->x() ) {
+ m_dragStart = e->pos();
+ return; // don't call KComboBox::mousePressEvent!
+ }
+ }
+
+ if ( e->button() == LeftButton && m_pageSecurity!=KonqMainWindow::NotCrypted ) {
+ // check if the lock icon was clicked
+ int x = e->pos().x();
+ int x0 = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_ComboBox, this, QStyle::SC_ComboBoxArrow ), this ).x();
+ if ( x < x0 )
+ emit showPageSecurity();
+
+ }
+
+ KComboBox::mousePressEvent( e );
+}
+
+void KonqCombo::mouseMoveEvent( QMouseEvent *e )
+{
+ KComboBox::mouseMoveEvent( e );
+ if ( m_dragStart.isNull() || currentText().isEmpty() )
+ return;
+
+ if ( e->state() & LeftButton &&
+ (e->pos() - m_dragStart).manhattanLength() >
+ KGlobalSettings::dndEventDelay() )
+ {
+ KURL url = KURL::fromPathOrURL( currentText() );
+ if ( url.isValid() )
+ {
+ KURL::List list;
+ list.append( url );
+ KURLDrag *drag = new KURLDrag( list, this );
+ QPixmap pix = KonqPixmapProvider::self()->pixmapFor( currentText(),
+ KIcon::SizeMedium );
+ if ( !pix.isNull() )
+ drag->setPixmap( pix );
+ drag->dragCopy();
+ }
+ }
+}
+
+void KonqCombo::slotActivated( const QString& text )
+{
+ //kdDebug(1202) << "KonqCombo::slotActivated: " << text << endl;
+ applyPermanent();
+ m_returnPressed = true;
+ emit activated( text, m_modifier );
+ m_modifier = NoButton;
+}
+
+void KonqCombo::setConfig( KConfig *kc )
+{
+ s_config = kc;
+}
+
+void KonqCombo::paintEvent( QPaintEvent *pe )
+{
+ QComboBox::paintEvent( pe );
+
+ QLineEdit *edit = lineEdit();
+ QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this, QStyle::SC_ComboBoxEditField );
+ re = QStyle::visualRect(re, this);
+
+ if ( m_pageSecurity!=KonqMainWindow::NotCrypted ) {
+ QColor color(245, 246, 190);
+ bool useColor = hasSufficientContrast(color,edit->paletteForegroundColor());
+
+ QPainter p( this );
+ p.setClipRect( re );
+
+ QPixmap pix = KonqPixmapProvider::self()->pixmapFor( currentText() );
+ if ( useColor ) {
+ p.fillRect( re.x(), re.y(), pix.width() + 4, re.height(), QBrush( color ));
+ p.drawPixmap( re.x() + 2, re.y() + ( re.height() - pix.height() ) / 2, pix );
+ }
+
+ QRect r = edit->geometry();
+ r.setRight( re.right() - pix.width() - 4 );
+ if ( r != edit->geometry() )
+ edit->setGeometry( r );
+
+ if ( useColor)
+ edit->setPaletteBackgroundColor( color );
+
+ pix = SmallIcon( m_pageSecurity==KonqMainWindow::Encrypted ? "encrypted" : "halfencrypted" );
+ p.fillRect( re.right() - pix.width() - 3 , re.y(), pix.width() + 4, re.height(),
+ QBrush( useColor ? color : edit->paletteBackgroundColor() ));
+ p.drawPixmap( re.right() - pix.width() -1 , re.y() + ( re.height() - pix.height() ) / 2, pix );
+ p.setClipping( FALSE );
+ }
+ else {
+ QRect r = edit->geometry();
+ r.setRight( re.right() );
+ if ( r != edit->geometry() )
+ edit->setGeometry( r );
+ edit->setPaletteBackgroundColor( QApplication::palette( edit ).color( QPalette::Active, QColorGroup::Base ) );
+ }
+}
+
+void KonqCombo::setPageSecurity( int pageSecurity )
+{
+ m_pageSecurity = pageSecurity;
+ repaint();
+}
+
+bool KonqCombo::hasSufficientContrast(const QColor &c1, const QColor &c2)
+{
+ // Taken from khtml/misc/helper.cc
+#define HUE_DISTANCE 40
+#define CONTRAST_DISTANCE 10
+
+ int h1, s1, v1, h2, s2, v2;
+ int hdist = -CONTRAST_DISTANCE;
+ c1.hsv(&h1,&s1,&v1);
+ c2.hsv(&h2,&s2,&v2);
+ if(h1!=-1 && h2!=-1) { // grey values have no hue
+ hdist = kAbs(h1-h2);
+ if (hdist > 180) hdist = 360-hdist;
+ if (hdist < HUE_DISTANCE) {
+ hdist -= HUE_DISTANCE;
+ // see if they are high key or low key colours
+ bool hk1 = h1>=45 && h1<=225;
+ bool hk2 = h2>=45 && h2<=225;
+ if (hk1 && hk2)
+ hdist = (5*hdist)/3;
+ else if (!hk1 && !hk2)
+ hdist = (7*hdist)/4;
+ }
+ hdist = kMin(hdist, HUE_DISTANCE*2);
+ }
+ return hdist + (kAbs(s1-s2)*128)/(160+kMin(s1,s2)) + kAbs(v1-v2) > CONTRAST_DISTANCE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+KonqComboListBoxPixmap::KonqComboListBoxPixmap( const QString& text )
+ : QListBoxItem()
+{
+ setText( text );
+ lookup_pending = true;
+}
+
+KonqComboListBoxPixmap::KonqComboListBoxPixmap( const QPixmap & pix, const QString& text, const QString& _title )
+ : QListBoxItem()
+{
+ pm = pix;
+ title = _title;
+ setText( text );
+ lookup_pending = false;
+}
+
+void KonqComboListBoxPixmap::paint( QPainter *painter )
+{
+ if ( lookup_pending ) {
+ title = titleOfURL( text() );
+ if ( !title.isEmpty() )
+ pm = KonqPixmapProvider::self()->pixmapFor( text(), KIcon::SizeSmall );
+ else if ( text().find( "://" ) == -1 ) {
+ title = titleOfURL( "http://"+text() );
+ if ( !title.isEmpty() )
+ pm = KonqPixmapProvider::self()->pixmapFor( "http://"+text(), KIcon::SizeSmall );
+ else
+ pm = KonqPixmapProvider::self()->pixmapFor( text(), KIcon::SizeSmall );
+ }
+ else
+ pm = QPixmap();
+ lookup_pending = false;
+ }
+
+ int itemHeight = height( listBox() );
+ int yPos, pmWidth = 0;
+ const QPixmap *pm = pixmap();
+
+ if ( pm && ! pm->isNull() ) {
+ yPos = ( itemHeight - pm->height() ) / 2;
+ painter->drawPixmap( 3, yPos, *pm );
+ pmWidth = pm->width() + 5;
+ }
+
+ int entryWidth = listBox()->width() - listBox()->style().pixelMetric( QStyle::PM_ScrollBarExtent ) -
+ 2 * listBox()->style().pixelMetric( QStyle::PM_DefaultFrameWidth );
+ int titleWidth = ( entryWidth / 3 ) - 1;
+ int urlWidth = entryWidth - titleWidth - pmWidth - 2;
+
+ if ( !text().isEmpty() ) {
+ QString squeezedText = KStringHandler::rPixelSqueeze( text(), listBox()->fontMetrics(), urlWidth );
+ painter->drawText( pmWidth, 0, urlWidth + pmWidth, itemHeight,
+ Qt::AlignLeft | Qt::AlignTop, squeezedText );
+
+ //painter->setPen( KGlobalSettings::inactiveTextColor() );
+ squeezedText = KStringHandler::rPixelSqueeze( title, listBox()->fontMetrics(), titleWidth );
+ QFont font = painter->font();
+ font.setItalic( true );
+ painter->setFont( font );
+ painter->drawText( entryWidth - titleWidth, 0, titleWidth,
+ itemHeight, Qt::AlignLeft | Qt::AlignTop, squeezedText );
+ }
+}
+
+int KonqComboListBoxPixmap::height( const QListBox* lb ) const
+{
+ int h;
+ if ( text().isEmpty() )
+ h = pm.height();
+ else
+ h = QMAX( pm.height(), lb->fontMetrics().lineSpacing() + 2 );
+ return QMAX( h, QApplication::globalStrut().height() );
+}
+
+int KonqComboListBoxPixmap::width( const QListBox* lb ) const
+{
+ if ( text().isEmpty() )
+ return QMAX( pm.width() + 6, QApplication::globalStrut().width() );
+ return QMAX( pm.width() + lb->fontMetrics().width( text() ) + 6,
+ QApplication::globalStrut().width() );
+}
+
+int KonqComboListBoxPixmap::RTTI = 1003;
+
+int KonqComboListBoxPixmap::rtti() const
+{
+ return RTTI;
+}
+
+bool KonqComboListBoxPixmap::reuse( const QString& newText )
+{
+ if ( text() == newText )
+ return false;
+
+ lookup_pending = true;
+ setText( newText );
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+KonqComboLineEdit::KonqComboLineEdit( QWidget *parent, const char *name )
+ :KLineEdit( parent, name ) {}
+
+void KonqComboLineEdit::setCompletedItems( const QStringList& items )
+{
+ QString txt;
+ KonqComboCompletionBox *completionbox = static_cast<KonqComboCompletionBox*>( completionBox() );
+
+ if ( completionbox && completionbox->isVisible() )
+ // The popup is visible already - do the matching on the initial string,
+ // not on the currently selected one.
+ txt = completionbox->cancelledText();
+ else
+ txt = text();
+
+ if ( !items.isEmpty() && !(items.count() == 1 && txt == items.first()) ) {
+ if ( !completionBox( false ) )
+ setCompletionBox( new KonqComboCompletionBox( this, "completion box" ) );
+
+ if ( completionbox->isVisible() ) {
+ bool wasSelected = completionbox->isSelected( completionbox->currentItem() );
+ const QString currentSelection = completionbox->currentText();
+ completionbox->setItems( items );
+ QListBoxItem* item = completionbox->findItem( currentSelection, Qt::ExactMatch );
+ if( !item || !wasSelected )
+ {
+ wasSelected = false;
+ item = completionbox->item( 0 );
+ }
+ if ( item ) {
+ completionbox->blockSignals( true );
+ completionbox->setCurrentItem( item );
+ completionbox->setSelected( item, wasSelected );
+ completionbox->blockSignals( false );
+ }
+ }
+ else { // completion box not visible yet -> show it
+ if ( !txt.isEmpty() )
+ completionbox->setCancelledText( txt );
+ completionbox->setItems( items );
+ completionbox->popup();
+ }
+
+ if ( autoSuggest() ) {
+ int index = items.first().find( txt );
+ QString newText = items.first().mid( index );
+ setUserSelection( false );
+ setCompletedText( newText, true );
+ }
+ }
+ else
+ if ( completionbox && completionbox->isVisible() )
+ completionbox->hide();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+KonqComboCompletionBox::KonqComboCompletionBox( QWidget *parent, const char *name )
+ :KCompletionBox( parent, name ) {}
+
+void KonqComboCompletionBox::setItems( const QStringList& items )
+{
+ bool block = signalsBlocked();
+ blockSignals( true );
+
+ QListBoxItem* item = firstItem();
+ if ( !item )
+ insertStringList( items );
+ else {
+ //Keep track of whether we need to change anything,
+ //so we can avoid a repaint for identical updates,
+ //to reduce flicker
+ bool dirty = false;
+
+ QStringList::ConstIterator it = items.constBegin();
+ const QStringList::ConstIterator itEnd = items.constEnd();
+
+ for ( ; it != itEnd; ++it) {
+ if ( item ) {
+ const bool changed = ((KonqComboListBoxPixmap*)item)->reuse( *it );
+ dirty = dirty || changed;
+ item = item->next();
+ }
+ else {
+ dirty = true;
+ //Inserting an item is a way of making this dirty
+ insertItem( new KonqComboListBoxPixmap( *it ) );
+ }
+ }
+
+ //If there is an unused item, mark as dirty -> less items now
+ if ( item )
+ dirty = true;
+
+ QListBoxItem* tmp = item;
+ while ( (item = tmp ) ) {
+ tmp = item->next();
+ delete item;
+ }
+
+ if ( dirty )
+ triggerUpdate( false );
+ }
+
+ if ( isVisible() && size().height() != sizeHint().height() )
+ sizeAndPosition();
+
+ blockSignals( block );
+
+ // Trigger d->down_workaround = true within KCompletionBox
+ QStringList dummy;
+ KCompletionBox::insertItems( dummy, 1 );
+}
+
+void KonqComboCompletionBox::insertStringList( const QStringList & list, int index )
+{
+ if ( index < 0 )
+ index = count();
+ for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ insertItem( new KonqComboListBoxPixmap( *it ), index++ );
+}
+
+#include "konq_combo.moc"
diff --git a/konqueror/konq_combo.h b/konqueror/konq_combo.h
new file mode 100644
index 000000000..8775d0c96
--- /dev/null
+++ b/konqueror/konq_combo.h
@@ -0,0 +1,115 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ 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.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,